Loading files
c730ec352This file is pinned to the selected release. Download the original to open it in your design tool.
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.org/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "graphicsexportdialog.h"
#include "../editorcommandset.h"
#include "../utils/editortoolbox.h"
#include "filedialog.h"
#include "ui_graphicsexportdialog.h"
#include <librepcb/core/export/graphicsexport.h>
#include <librepcb/core/utils/toolbox.h>
#include <librepcb/core/workspace/basecolorscheme.h>
#include <librepcb/core/workspace/colorrole.h>
#include <QtConcurrent>
#include <QtCore>
#include <QtPrintSupport>
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
namespace editor {
/*******************************************************************************
* Constructors / Destructor
******************************************************************************/
GraphicsExportDialog::GraphicsExportDialog(
Mode mode, Output output,
const QList<std::shared_ptr<GraphicsPagePainter>>& pages, int currentPage,
const QString& documentName, int innerLayerCount,
const FilePath& defaultFilePath, const LengthUnit& lengthUnit,
const ColorScheme& colors, const QString& settingsPrefix,
QWidget* parent) noexcept
: QDialog(parent),
mMode(mode),
mOutput(output),
mInputPages(pages),
mCurrentPage(currentPage),
mDefaultFilePath(defaultFilePath),
mColorScheme(colors),
mSettingsPrefix(settingsPrefix),
mSaveAsCallback(&FileDialog::getSaveFileName),
mDefaultSettings(new GraphicsExportSettings()),
mColors(),
mSettingsPrinterName(),
mSettingsPageSize(std::nullopt),
mSettingsDuplexMode(QPrinter::DuplexNone),
mDisableApplySettings(true),
mUi(new Ui::GraphicsExportDialog),
mProgressDialog(new QProgressDialog(tr("Operation in progress..."),
tr("Cancel"), 0, 100, this)),
mPrinterWatcher(new QFutureWatcher<QList<QPrinterInfo>>(this)),
mAvailablePrinters(),
mAvailablePageSizes(),
mPageContentItems(),
mPages(),
mPreview(new GraphicsExport()),
mExport(new GraphicsExport()),
mPathToOpenAfterExport() {
mUi->setupUi(this);
connect(mUi->buttonBoxLeft, &QDialogButtonBox::clicked, this,
[this](QAbstractButton* btn) {
buttonBoxClicked(mUi->buttonBoxLeft->standardButton(btn));
});
connect(mUi->buttonBox, &QDialogButtonBox::clicked, this,
[this](QAbstractButton* btn) {
buttonBoxClicked(mUi->buttonBox->standardButton(btn));
});
// Set window title.
switch (output) {
case Output::Image:
setWindowTitle(tr("Export Image"));
break;
case Output::Pdf:
setWindowTitle(tr("Export PDF"));
break;
default:
setWindowTitle(tr("Print"));
break;
}
// Add all colors.
if (mMode == Mode::Schematic) {
mDefaultSettings->loadColorsFromScheme(&mColorScheme, nullptr);
} else if (mMode == Mode::Board) {
mDefaultSettings->loadColorsFromScheme(nullptr, &mColorScheme,
innerLayerCount);
}
// Open exported files checkbox.
if (output == Output::Print) {
mUi->cbxOpenExportedFiles->hide();
}
// Copy to clipboard button.
if (output == Output::Image) {
QPushButton* btn = new QPushButton(tr("Copy to clipboard"));
btn->setObjectName("btnCopyToClipboard");
btn->setToolTip(
tr("Copy the image to the clipboard instead of saving it as a file."));
// Note: Must have AcceptRole to get a reasonable position on all systems.
mUi->buttonBox->addButton(btn, QDialogButtonBox::AcceptRole);
}
// Printer.
if (output == Output::Print) {
// Start fetching printers asynchronously since it can take some time.
mUi->cbxPrinter->addItem(QIcon(":/img/actions/search.png"),
tr("Looking for printers..."));
connect(mPrinterWatcher.data(),
&QFutureWatcher<QList<QPrinterInfo>>::finished, this,
&GraphicsExportDialog::printersAvailable);
mPrinterWatcher->setFuture(
QtConcurrent::run(&QPrinterInfo::availablePrinters));
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblPrinter);
}
// Duplex.
if (output != Output::Print) {
EditorToolbox::removeFormLayoutRow(*mUi->lblDuplex);
}
// Copies.
if (output != Output::Print) {
EditorToolbox::removeFormLayoutRow(*mUi->lblCopies);
}
// Page size.
if ((output == Output::Pdf) || (output == Output::Print)) {
if (output == Output::Pdf) {
QList<std::optional<QPageSize>> sizes = {
std::nullopt, // Auto size.
QPageSize(QPageSize::A0),
QPageSize(QPageSize::A1),
QPageSize(QPageSize::A2),
QPageSize(QPageSize::A3),
QPageSize(QPageSize::A4),
QPageSize(QPageSize::A5),
QPageSize(QPageSize::A6),
QPageSize(QPageSize::A7),
QPageSize(QPageSize::A8),
QPageSize(QPageSize::A9),
QPageSize(QPageSize::A10),
QPageSize(QPageSize::B0),
QPageSize(QPageSize::B1),
QPageSize(QPageSize::B2),
QPageSize(QPageSize::B3),
QPageSize(QPageSize::B4),
QPageSize(QPageSize::B5),
QPageSize(QPageSize::B6),
QPageSize(QPageSize::B7),
QPageSize(QPageSize::B8),
QPageSize(QPageSize::B9),
QPageSize(QPageSize::B10),
QPageSize(QPageSize::JisB0),
QPageSize(QPageSize::JisB1),
QPageSize(QPageSize::JisB2),
QPageSize(QPageSize::JisB3),
QPageSize(QPageSize::JisB4),
QPageSize(QPageSize::JisB5),
QPageSize(QPageSize::JisB6),
QPageSize(QPageSize::JisB7),
QPageSize(QPageSize::JisB8),
QPageSize(QPageSize::JisB9),
QPageSize(QPageSize::JisB10),
QPageSize(QPageSize::Letter),
QPageSize(QPageSize::Legal),
QPageSize(QPageSize::ExecutiveStandard),
QPageSize(QPageSize::Ledger),
QPageSize(QPageSize::Tabloid),
QPageSize(QPageSize::AnsiC),
QPageSize(QPageSize::AnsiD),
QPageSize(QPageSize::AnsiE),
};
setAvailablePageSizes(sizes);
setPageSize(QPageSize::A4);
}
connect(
mUi->cbxPageSize,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblPageSize);
}
// Orientation.
if ((output == Output::Pdf) || (output == Output::Print)) {
connect(mUi->rbtnOrientationAuto, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnOrientationLandscape, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnOrientationPortrait, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblOrientation);
}
// Resolution.
if (output == Output::Image) {
connect(mUi->spbxResolutionDpi,
static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
&GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblResolution);
}
// Margins.
mUi->edtMarginLeft->configure(lengthUnit, LengthEditBase::Steps::generic(),
mSettingsPrefix % "/margin_left");
mUi->edtMarginTop->configure(lengthUnit, LengthEditBase::Steps::generic(),
mSettingsPrefix % "/margin_top");
mUi->edtMarginRight->configure(lengthUnit, LengthEditBase::Steps::generic(),
mSettingsPrefix % "/margin_right");
mUi->edtMarginBottom->configure(lengthUnit, LengthEditBase::Steps::generic(),
mSettingsPrefix % "/margin_bottom");
connect(mUi->edtMarginLeft, &UnsignedLengthEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
connect(mUi->edtMarginTop, &UnsignedLengthEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
connect(mUi->edtMarginRight, &UnsignedLengthEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
connect(mUi->edtMarginBottom, &UnsignedLengthEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
// Show pin numbers.
if (mMode == Mode::Schematic) {
connect(mUi->cbxShowPinNumbers, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblShowPinNumbers);
}
// Rotation.
connect(mUi->cbxRotate, &QCheckBox::toggled, this,
&GraphicsExportDialog::applySettings);
// Mirror,
connect(mUi->cbxMirror, &QCheckBox::toggled, this,
&GraphicsExportDialog::applySettings);
// Scale.
if ((output == Output::Pdf) || (output == Output::Print)) {
mUi->spbxScaleFactor->setEnabled(!mUi->cbxScaleAuto->isChecked());
connect(mUi->cbxScaleAuto, &QCheckBox::toggled, mUi->spbxScaleFactor,
&UnsignedRatioEdit::setDisabled);
connect(mUi->cbxScaleAuto, &QCheckBox::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->spbxScaleFactor, &UnsignedRatioEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblScale);
}
// Min. line width.
mUi->edtMinLineWidth->configure(lengthUnit, LengthEditBase::Steps::generic(),
mSettingsPrefix % "/min_line_width");
connect(mUi->edtMinLineWidth, &UnsignedLengthEdit::valueChanged, this,
&GraphicsExportDialog::applySettings);
// Black/white.
auto setTabColorsHidden = [this](bool hidden) {
mUi->tabWidget->setTabVisible(mUi->tabWidget->indexOf(mUi->tabColors),
!hidden);
// Also disable/enable the tab to work around a bug:
// https://bugreports.qt.io/browse/QTBUG-101219
mUi->tabWidget->setTabEnabled(mUi->tabWidget->indexOf(mUi->tabColors),
!hidden);
};
setTabColorsHidden(mUi->cbxBlackWhite->isChecked());
connect(mUi->cbxBlackWhite, &QCheckBox::toggled, this, setTabColorsHidden);
connect(mUi->cbxBlackWhite, &QCheckBox::toggled, this,
&GraphicsExportDialog::applySettings);
// Background color.
if (output != Output::Print) {
connect(mUi->rbtnBackgroundNone, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnBackgroundWhite, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnBackgroundBlack, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
} else {
EditorToolbox::removeFormLayoutRow(*mUi->lblBackground);
}
// Colors.
connect(mUi->lstLayerColors, &QListWidget::itemDoubleClicked, this,
&GraphicsExportDialog::layerListItemDoubleClicked);
connect(mUi->lstLayerColors, &QListWidget::itemChanged, this,
&GraphicsExportDialog::applySettings);
// Content.
if (mMode == Mode::Board) {
EditorCommandSet& cmd = EditorCommandSet::instance();
QAction* aNew = cmd.itemNew.createAction(
this, this,
[this]() {
QList<ContentItem> items = getPageContent();
items.append(ContentItem{"", false, false, {}});
setPageContent(items);
if (auto item = mUi->treeContent->topLevelItem(items.count() - 1)) {
mUi->treeContent->editItem(item, 0);
}
},
EditorCommand::ActionFlag::WidgetShortcut);
mUi->treeContent->addAction(aNew);
QAction* aRemove = cmd.remove.createAction(
this, this,
[this]() {
QModelIndexList indices =
mUi->treeContent->selectionModel()->selectedIndexes();
if ((!indices.isEmpty()) && indices.first().isValid() &&
(!indices.first().parent().isValid()) &&
(indices.first().row() >= 0) &&
(indices.first().row() < mPageContentItems.count())) {
QList<ContentItem> items = getPageContent();
items.removeAt(indices.first().row());
setPageContent(items);
}
},
EditorCommand::ActionFlag::WidgetShortcut);
mUi->treeContent->addAction(aRemove);
QAction* aRename = cmd.rename.createAction(
this, this,
[this]() {
foreach (auto item, mUi->treeContent->selectedItems()) {
mUi->treeContent->editItem(item, 0);
}
},
EditorCommand::ActionFlag::WidgetShortcut);
mUi->treeContent->addAction(aRename);
mUi->treeContent->header()->setSectionResizeMode(0, QHeaderView::Stretch);
mUi->treeContent->header()->setSectionResizeMode(
1, QHeaderView::ResizeToContents);
mUi->treeContent->viewport()->installEventFilter(this);
connect(mUi->treeContent, &QTreeWidget::itemChanged, this,
&GraphicsExportDialog::applySettings);
} else {
mUi->tabWidget->removeTab(mUi->tabWidget->indexOf(mUi->tabContent));
}
// Page range.
if (mode == Mode::Schematic) {
mUi->edtPageRange->setPlaceholderText(
QString("%1-%2").arg(1).arg(mInputPages.count()));
mUi->edtPageRange->setEnabled(mUi->rbtnRangeCustom->isChecked());
connect(mUi->rbtnRangeAll, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnRangeCurrent, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnRangeCustom, &QRadioButton::toggled, this,
&GraphicsExportDialog::applySettings);
connect(mUi->rbtnRangeCustom, &QRadioButton::toggled, mUi->edtPageRange,
&QLineEdit::setEnabled);
connect(mUi->edtPageRange, &QLineEdit::textChanged, this,
&GraphicsExportDialog::applySettings);
} else {
mUi->tabWidget->removeTab(mUi->tabWidget->indexOf(mUi->tabPages));
}
// Select first tab.
mUi->tabWidget->setCurrentIndex(0);
// Setup preview.
mUi->previewWidget->setShowPageNumbers(pages.count() > 1);
mUi->previewWidget->setShowResolution(output == Output::Image);
connect(mPreview.data(), &GraphicsExport::previewReady, mUi->previewWidget,
&GraphicsExportWidget::setPageContent);
// Setup export.
mExport->setDocumentName(documentName);
connect(
mExport.data(), &GraphicsExport::succeeded, this,
[this]() {
const bool canceled = mProgressDialog->wasCanceled();
mProgressDialog->reset();
if (!canceled) {
if (mPathToOpenAfterExport.isValid()) {
emit requestOpenFile(mPathToOpenAfterExport);
}
close();
}
},
Qt::QueuedConnection);
connect(
mExport.data(), &GraphicsExport::failed, this,
[this](const QString& msg) {
mProgressDialog->reset();
QMessageBox::critical(this, tr("Error"), msg);
},
Qt::QueuedConnection);
// Setup progress dialog.
mProgressDialog->reset();
mProgressDialog->setWindowModality(Qt::WindowModal);
mProgressDialog->setMinimumDuration(0);
mProgressDialog->setAutoReset(false);
connect(mProgressDialog.data(), &QProgressDialog::canceled, mExport.data(),
&GraphicsExport::cancel);
connect(
mExport.data(), &GraphicsExport::progress, mProgressDialog.data(),
[this](int percent, int page, int total) {
if (mProgressDialog->isVisible()) {
mProgressDialog->setLabelText(
tr("Processing page %1 of %2...").arg(page).arg(total));
mProgressDialog->setValue(percent);
}
},
Qt::QueuedConnection);
// Load settings.
loadDefaultSettings();
syncClientSettings(ClientSettingsAction::Load);
// Apply settings & update preview.
mDisableApplySettings = false;
applySettings();
}
GraphicsExportDialog::~GraphicsExportDialog() noexcept {
syncClientSettings(ClientSettingsAction::Store);
mDisableApplySettings = true;
}
/*******************************************************************************
* General Methods
******************************************************************************/
void GraphicsExportDialog::setSaveAsCallback(SaveAsCallback callback) noexcept {
Q_ASSERT(callback);
mSaveAsCallback = callback;
}
/*******************************************************************************
* Private Methods
******************************************************************************/
void GraphicsExportDialog::loadDefaultSettings() noexcept {
setPageSize(QPageSize::A4);
setOrientation(mDefaultSettings->getOrientation());
setMarginLeft(mDefaultSettings->getMarginLeft());
setMarginTop(mDefaultSettings->getMarginTop());
setMarginRight(mDefaultSettings->getMarginRight());
setMarginBottom(mDefaultSettings->getMarginBottom());
setShowPinNumbers(false);
setRotate(mDefaultSettings->getRotate());
setMirror(mDefaultSettings->getMirror());
setFitToPage(!mDefaultSettings->getScale().has_value());
setScaleFactor(mDefaultSettings->getScale()
? *mDefaultSettings->getScale()
: UnsignedRatio(Ratio::fromPercent(100)));
setDpi(mDefaultSettings->getPixmapDpi());
setBlackWhite(mDefaultSettings->getBlackWhite());
setBackgroundColor(mDefaultSettings->getBackgroundColor());
setMinLineWidth(mDefaultSettings->getMinLineWidth());
setDuplex(QPrinter::DuplexNone);
setOpenExportedFiles(true);
mUi->rbtnRangeAll->setChecked(true);
// Colors.
mColors = mDefaultSettings->getColors();
updateColorsListWidget();
// Page content.
QSet<QString> allColors;
foreach (const auto& pair, mColors) {
allColors.insert(pair.first);
}
QSet<QString> commonColors = {
ColorRole::boardMeasures().getId(),
ColorRole::boardFrames().getId(),
ColorRole::boardOutlines().getId(),
};
QSet<QString> cutOutColors = {
ColorRole::boardHoles().getId(),
ColorRole::boardPlatedCutouts().getId(),
};
QSet<QString> assemblyColors = {
ColorRole::boardGuide().getId(),
ColorRole::boardComments().getId(),
ColorRole::boardDocumentation().getId(),
};
QList<ContentItem> items = {
{
tr("All Layers"),
(mOutput == Output::Image), // Imege export -> single page.
false,
allColors,
},
{
tr("Assembly Top"),
(mOutput != Output::Image), // Multi-page export.
false,
commonColors + cutOutColors + assemblyColors +
QSet<QString>{
ColorRole::boardDocumentationTop().getId(),
ColorRole::boardNamesTop().getId(),
ColorRole::boardValuesTop().getId(),
ColorRole::boardGrabAreasTop().getId(),
ColorRole::boardLegendTop().getId(),
ColorRole::boardSolderPasteTop().getId(),
ColorRole::boardStopMaskTop().getId(),
},
},
{
tr("Assembly Bottom"),
(mOutput != Output::Image), // Multi-page export.
true,
commonColors + cutOutColors + assemblyColors +
QSet<QString>{
ColorRole::boardDocumentationBot().getId(),
ColorRole::boardNamesBot().getId(),
ColorRole::boardValuesBot().getId(),
ColorRole::boardGrabAreasBot().getId(),
ColorRole::boardLegendBot().getId(),
ColorRole::boardSolderPasteBot().getId(),
ColorRole::boardStopMaskBot().getId(),
},
},
{
tr("Drills"),
false,
false,
commonColors + cutOutColors +
QSet<QString>{
ColorRole::boardPads().getId(),
ColorRole::boardVias().getId(),
},
},
{
tr("Copper Top"),
false,
false,
commonColors +
QSet<QString>{
ColorRole::boardPads().getId(),
ColorRole::boardVias().getId(),
ColorRole::boardCopperTop().getId(),
},
},
{
tr("Copper Bottom"),
false,
false,
commonColors +
QSet<QString>{
ColorRole::boardPads().getId(),
ColorRole::boardVias().getId(),
ColorRole::boardCopperBot().getId(),
},
},
};
setPageContent(items);
}
void GraphicsExportDialog::syncClientSettings(
ClientSettingsAction action) noexcept {
try {
QSettings s;
// Window size.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/window_size", size());
} else {
QSize value = s.value(mSettingsPrefix % "/window_size").toSize();
if (!value.isEmpty()) {
resize(value);
}
}
// Printer name.
if (action == ClientSettingsAction::Store) {
QString value = getPrinterName();
if (!value.isEmpty()) {
s.setValue(mSettingsPrefix % "/printer_name", value);
}
} else {
QString value = s.value(mSettingsPrefix % "/printer_name").toString();
if (!value.isEmpty()) {
// WIll be applied later when printers are available.
mSettingsPrinterName = value;
}
}
// Duplex.
QHash<QString, QPrinter::DuplexMode> duplexModeMap = {
{"none", QPrinter::DuplexNone},
{"long_edge", QPrinter::DuplexLongSide},
{"short_edge", QPrinter::DuplexShortSide},
};
if (action == ClientSettingsAction::Store) {
if (mUi->cbxDuplex->count()) {
s.setValue(mSettingsPrefix % "/duplex", duplexModeMap.key(getDuplex()));
}
} else {
QString value = s.value(mSettingsPrefix % "/duplex").toString();
if (duplexModeMap.contains(value)) {
// WIll be applied later when printers are available.
mSettingsDuplexMode = duplexModeMap.value(value);
}
}
// Page size.
if (action == ClientSettingsAction::Store) {
if (mUi->cbxPageSize->count()) {
auto value = getPageSize();
s.setValue(mSettingsPrefix % "/page_size",
value ? value->key() : "auto");
}
} else {
QString value = s.value(mSettingsPrefix % "/page_size").toString();
if (value == "auto") {
mSettingsPageSize = std::nullopt;
setPageSize(std::nullopt);
} else if (!value.isEmpty()) {
for (int i = 0; i < QPageSize::LastPageSize; ++i) {
QPageSize::PageSizeId id = static_cast<QPageSize::PageSizeId>(i);
if (QPageSize::key(id) == value) {
mSettingsPageSize = id;
setPageSize(id);
break;
}
}
}
}
// Orientation.
QHash<QString, GraphicsExportSettings::Orientation> orientationMap = {
{"auto", GraphicsExportSettings::Orientation::Auto},
{"landscape", GraphicsExportSettings::Orientation::Landscape},
{"portrait", GraphicsExportSettings::Orientation::Portrait},
};
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/orientation",
orientationMap.key(getOrientation()));
} else {
QString value = s.value(mSettingsPrefix % "/orientation").toString();
if (orientationMap.contains(value)) {
setOrientation(orientationMap.value(value));
}
}
// Margins.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/margin_left",
getMarginLeft()->toMmString());
s.setValue(mSettingsPrefix % "/margin_top", getMarginTop()->toMmString());
s.setValue(mSettingsPrefix % "/margin_right",
getMarginRight()->toMmString());
s.setValue(mSettingsPrefix % "/margin_bottom",
getMarginBottom()->toMmString());
} else {
QString value = s.value(mSettingsPrefix % "/margin_left").toString();
if (!value.isEmpty()) {
setMarginLeft(UnsignedLength(Length::fromMm(value)));
}
value = s.value(mSettingsPrefix % "/margin_top").toString();
if (!value.isEmpty()) {
setMarginTop(UnsignedLength(Length::fromMm(value)));
}
value = s.value(mSettingsPrefix % "/margin_right").toString();
if (!value.isEmpty()) {
setMarginRight(UnsignedLength(Length::fromMm(value)));
}
value = s.value(mSettingsPrefix % "/margin_bottom").toString();
if (!value.isEmpty()) {
setMarginBottom(UnsignedLength(Length::fromMm(value)));
}
}
// Show pin numbers.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/show_pin_numbers", getShowPinNumbers());
} else {
QVariant value = s.value(mSettingsPrefix % "/show_pin_numbers");
if (!value.isNull()) {
setShowPinNumbers(value.toBool());
}
}
// Rotate.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/rotate", getRotate());
} else {
QVariant value = s.value(mSettingsPrefix % "/rotate");
if (!value.isNull()) {
setRotate(value.toBool());
}
}
// Mirror.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/mirror", getMirror());
} else {
QVariant value = s.value(mSettingsPrefix % "/mirror");
if (!value.isNull()) {
setMirror(value.toBool());
}
}
// Fit to page.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/fit_to_page", getFitToPage());
} else {
QVariant value = s.value(mSettingsPrefix % "/fit_to_page");
if (!value.isNull()) {
setFitToPage(value.toBool());
}
}
// Scale factor.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/scale_factor",
getScaleFactor()->toNormalized());
} else {
const QVariant value = s.value(mSettingsPrefix % "/scale_factor");
const Ratio ratio = Ratio::fromNormalized(value.value<qreal>());
if ((!value.isNull()) && (ratio > 0)) {
setScaleFactor(UnsignedRatio(ratio));
}
}
// DPI.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/dpi", getDpi());
} else {
QVariant value = s.value(mSettingsPrefix % "/dpi");
if ((!value.isNull()) && (value.toInt() > 0)) {
setDpi(value.toInt());
}
}
// Black/white.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/black_white", getBlackWhite());
} else {
QVariant value = s.value(mSettingsPrefix % "/black_white");
if (!value.isNull()) {
setBlackWhite(value.toBool());
}
}
// Background color.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/background_color_v2",
getBackgroundColor().name(QColor::HexArgb));
} else {
const QVariant value = s.value(mSettingsPrefix % "/background_color_v2");
const QColor color = value.value<QColor>();
if ((!value.isNull()) && color.isValid()) {
setBackgroundColor(color);
}
}
// Min. line width.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/min_line_width",
getMinLineWidth()->toMmString());
} else {
QString value = s.value(mSettingsPrefix % "/min_line_width").toString();
if (!value.isEmpty()) {
setMinLineWidth(UnsignedLength(Length::fromMm(value)));
}
}
// Open exported files.
if (action == ClientSettingsAction::Store) {
s.setValue(mSettingsPrefix % "/open_exported_files",
getOpenExportedFiles());
} else {
QVariant value = s.value(mSettingsPrefix % "/open_exported_files");
if (!value.isNull()) {
setOpenExportedFiles(value.toBool());
}
}
// Colors.
if (action == ClientSettingsAction::Store) {
foreach (const auto& pair, mColors) {
s.setValue(mSettingsPrefix % "/color/" % pair.first,
pair.second.name(QColor::HexArgb));
}
} else {
for (auto& pair : mColors) {
QColor value(
s.value(mSettingsPrefix % "/color/" % pair.first).toString());
if (value.isValid()) {
pair.second = value;
}
}
updateColorsListWidget();
}
// Page content items.
if (action == ClientSettingsAction::Store) {
s.beginWriteArray(mSettingsPrefix % "/page_content_v2");
for (int i = 0; i < mPageContentItems.count(); ++i) {
s.setArrayIndex(i);
s.setValue("name", mPageContentItems.at(i).name);
s.setValue("enabled", mPageContentItems.at(i).enabled);
s.setValue("mirror", mPageContentItems.at(i).mirror);
s.setValue("colors",
QVariant::fromValue(QStringList(
Toolbox::sortedQSet(mPageContentItems.at(i).colors))));
}
s.endArray();
} else {
QList<ContentItem> items;
int count = s.beginReadArray(mSettingsPrefix % "/page_content_v2");
for (int i = 0; i < count; ++i) {
s.setArrayIndex(i);
items.append(ContentItem{
s.value("name", QString::number(i + 1)).toString(),
s.value("enabled").toBool(),
s.value("mirror").toBool(),
Toolbox::toSet(s.value("colors").toStringList()),
});
}
s.endArray();
if (!items.isEmpty()) {
setPageContent(items);
}
}
} catch (const Exception& e) {
qCritical() << "Failed to sync graphics export dialog client settings:"
<< e.getMsg();
}
}
void GraphicsExportDialog::buttonBoxClicked(
QDialogButtonBox::StandardButton btn) noexcept {
switch (btn) {
case QDialogButtonBox::Cancel: {
reject();
break;
}
case QDialogButtonBox::RestoreDefaults: {
mDisableApplySettings = true;
loadDefaultSettings();
mDisableApplySettings = false;
applySettings();
break;
}
case QDialogButtonBox::Ok: {
startExport(false); // Print or export to file.
break;
}
default: {
startExport(true); // Copy to clipboard.
break;
}
}
}
void GraphicsExportDialog::printersAvailable() noexcept {
mUi->cbxPrinter->clear();
mAvailablePrinters = mPrinterWatcher->result();
if (mAvailablePrinters.isEmpty()) {
mUi->cbxPrinter->addItem(QIcon(":/img/status/dialog_warning.png"),
tr("No printer found"));
return;
}
int selectedIndex = -1;
foreach (const QPrinterInfo& info, mAvailablePrinters) {
if ((info.printerName() == mSettingsPrinterName) ||
(info.isDefault() && (selectedIndex < 0))) {
selectedIndex = mUi->cbxPrinter->count();
}
QString name = info.printerName();
if (!info.location().isEmpty()) {
name += " (" % info.location() % ")";
}
mUi->cbxPrinter->addItem(QIcon(":/img/actions/print.png"),
info.printerName());
mUi->cbxPrinter->setItemData(
mUi->cbxPrinter->count() - 1,
(info.description() + "\n" + info.makeAndModel()).trimmed(),
Qt::ToolTipRole);
}
mUi->cbxPrinter->setCurrentIndex(qMax(selectedIndex, 0));
printerChanged(mUi->cbxPrinter->currentIndex());
connect(
mUi->cbxPrinter,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &GraphicsExportDialog::printerChanged);
mUi->spbxCopies->setEnabled(true);
}
void GraphicsExportDialog::printerChanged(int index) noexcept {
QPrinterInfo printer = mAvailablePrinters.value(index);
bool wasEmpty = mAvailablePageSizes.isEmpty();
QList<std::optional<QPageSize>> sizes;
foreach (const auto& size, printer.supportedPageSizes()) {
sizes.append(size);
}
setAvailablePageSizes(sizes);
if (wasEmpty) {
if (mSettingsPageSize) {
setPageSize(*mSettingsPageSize);
} else {
setPageSize(printer.defaultPageSize().id());
}
}
QPrinter::DuplexMode selectedDuplexMode =
(mUi->cbxDuplex->count()) ? getDuplex() : mSettingsDuplexMode;
QList<QPrinter::DuplexMode> duplexModes = printer.supportedDuplexModes();
mUi->cbxDuplex->clear();
mUi->cbxDuplex->addItem(tr("One Sided"),
static_cast<int>(QPrinter::DuplexNone));
if (duplexModes.contains(QPrinter::DuplexLongSide)) {
mUi->cbxDuplex->addItem(tr("Long Edge"),
static_cast<int>(QPrinter::DuplexLongSide));
}
if (duplexModes.contains(QPrinter::DuplexShortSide)) {
mUi->cbxDuplex->addItem(tr("Short Edge"),
static_cast<int>(QPrinter::DuplexShortSide));
}
setDuplex(selectedDuplexMode);
mUi->cbxDuplex->setEnabled(mUi->cbxDuplex->count() > 1);
applySettings();
}
void GraphicsExportDialog::setAvailablePageSizes(
QList<std::optional<QPageSize>> sizes) noexcept {
// Sort page sizes.
Toolbox::sortNumeric(
sizes,
[](const QCollator& cmp, const std::optional<QPageSize>& lhs,
const std::optional<QPageSize>& rhs) {
if (lhs && rhs) {
return cmp(lhs->name(), rhs->name());
} else {
return lhs.has_value() < rhs.has_value();
}
},
Qt::CaseInsensitive, false);
std::optional<QPageSize> selectedSize = getPageSize();
mAvailablePageSizes = sizes;
mUi->cbxPageSize->clear();
foreach (const std::optional<QPageSize>& size, sizes) {
mUi->cbxPageSize->addItem(size ? size->name()
: tr("Custom (adjust to content)"));
}
setPageSize(selectedSize ? std::make_optional(selectedSize->id())
: std::nullopt);
}
void GraphicsExportDialog::layerListItemDoubleClicked(
QListWidgetItem* item) noexcept {
Q_ASSERT(item);
QColor color = item->data(Qt::DecorationRole).value<QColor>();
color = QColorDialog::getColor(color, this, QString(),
QColorDialog::ShowAlphaChannel);
if (color.isValid()) {
item->setData(Qt::DecorationRole, color);
}
}
void GraphicsExportDialog::applySettings() noexcept {
if (mDisableApplySettings) {
return;
}
bool isValid = true;
// Check printer name.
if (getPrinterName().isEmpty() && (mOutput == Output::Print)) {
isValid = false;
}
// Build settings.
std::shared_ptr<GraphicsExportSettings> settings =
std::make_shared<GraphicsExportSettings>();
settings->setPageSize(getPageSize());
settings->setPixmapDpi(getDpi());
settings->setOrientation(getOrientation());
settings->setMarginLeft(getMarginLeft());
settings->setMarginTop(getMarginTop());
settings->setMarginRight(getMarginRight());
settings->setMarginBottom(getMarginBottom());
settings->setRotate(getRotate());
settings->setMirror(getMirror());
settings->setScale(getFitToPage() ? std::nullopt
: std::make_optional(getScaleFactor()));
settings->setMinLineWidth(getMinLineWidth());
settings->setBlackWhite(getBlackWhite());
settings->setBackgroundColor(getBackgroundColor());
// Update colors from list widget.
const int colorCount = mColors.count();
for (int i = 0; i < std::min(mUi->lstLayerColors->count(), colorCount); ++i) {
QColor color =
mUi->lstLayerColors->item(i)->data(Qt::DecorationRole).value<QColor>();
mColors[i].second = color;
}
// Remove layers to hide.
QList<std::pair<QString, QColor>> colors = mColors;
if ((mMode == Mode::Schematic) && (!getShowPinNumbers())) {
for (int i = colors.count() - 1; i >= 0; --i) {
if (colors.at(i).first == ColorRole::schematicPinNumbers().getId()) {
colors.removeAt(i);
}
}
}
// Update page content from tree view.
for (int i = 0; i < std::min(mUi->treeContent->topLevelItemCount(),
int(mPageContentItems.count()));
++i) {
const QTreeWidgetItem* node = mUi->treeContent->topLevelItem(i);
ContentItem& item = mPageContentItems[i];
item.name = node->text(0);
item.enabled = (node->checkState(0) == Qt::Checked);
item.mirror = (node->checkState(1) == Qt::Checked);
for (int k = 0; k < std::min(node->childCount(), colorCount); ++k) {
const QTreeWidgetItem* child = node->child(k);
const QString color = mColors.at(k).first;
if (child->checkState(0) == Qt::Checked) {
item.colors.insert(color);
} else {
item.colors.remove(color);
}
}
}
// Build pages.
mPages.clear();
if (mMode == Mode::Schematic) {
QList<int> pageIndices;
if (mUi->rbtnRangeCustom->isChecked()) {
QStringList ranges =
mUi->edtPageRange->text().split(',', Qt::SkipEmptyParts);
foreach (const QString& range, ranges) {
int start = qBound(1, range.split('-').first().trimmed().toInt(),
mInputPages.count());
int end = qBound(1, range.split('-').last().trimmed().toInt(),
mInputPages.count());
for (int i = start; i <= end; ++i) {
pageIndices.append(i - 1);
}
}
} else if (mUi->rbtnRangeCurrent->isChecked() && (mCurrentPage >= 0) &&
(mCurrentPage < mInputPages.count())) {
pageIndices.append(mCurrentPage);
}
if (pageIndices.isEmpty()) {
for (int i = 0; i < mInputPages.count(); ++i) {
pageIndices.append(i);
}
}
settings->setColors(colors);
foreach (int i, pageIndices) {
mPages.append(std::make_pair(mInputPages.at(i), settings));
}
} else if ((mMode == Mode::Board) && (mInputPages.count() == 1)) {
foreach (const ContentItem& item, getPageContent()) {
if (item.enabled) {
QList<std::pair<QString, QColor>> pageColors;
foreach (const auto& pair, colors) {
if (item.colors.contains(pair.first)) {
pageColors.append(pair);
}
}
std::shared_ptr<GraphicsExportSettings> pageSettings =
std::make_shared<GraphicsExportSettings>(*settings);
pageSettings->setMirror(settings->getMirror() ^ item.mirror);
pageSettings->setColors(pageColors);
mPages.append(std::make_pair(mInputPages.at(0), pageSettings));
}
}
}
if (mPages.isEmpty()) {
isValid = false;
}
// Update UI.
mUi->previewWidget->setNumberOfPages(mPages.count());
mUi->lblNoteMultiplePagesSuffix->setVisible((mPages.count() > 1) &&
(mOutput == Output::Image));
if (QAbstractButton* btn = mUi->buttonBox->button(QDialogButtonBox::Ok)) {
btn->setEnabled(isValid);
}
// Update preview.
mPreview->startPreview(mPages);
}
void GraphicsExportDialog::startExport(bool toClipboard) noexcept {
mPathToOpenAfterExport = FilePath();
if (mOutput == Output::Print) {
int copies = mUi->spbxCopies->value();
openProgressDialog();
mExport->startPrint(mPages, getPrinterName(), getDuplex(), copies);
} else if (toClipboard) {
// Copy to clipboard only makes sense for a single page. For that, we use
// the "current page" index as passed to the constructor.
auto pages = mPages;
if ((pages.count() > 1) && (mCurrentPage >= 0) &&
(mCurrentPage < pages.count())) {
pages = {pages.at(mCurrentPage)};
}
openProgressDialog();
mExport->startExport(pages, FilePath());
} else {
const bool isPdf = (mOutput == Output::Pdf);
const QString defaultExtension = isPdf ? "pdf" : "png";
const QStringList extensions = isPdf
? QStringList{"pdf"}
: GraphicsExport::getSupportedImageExtensions();
QString extensionsStr;
foreach (const QString& ext, extensions) {
extensionsStr += "*." % ext % " ";
}
static QHash<QString, QString> sUsedFilePaths;
const QString key = mDefaultFilePath.toStr() % "." % defaultExtension;
QString defaultPath = sUsedFilePaths.value(key, key);
FilePath fp = FilePath(mSaveAsCallback(this, tr("Save as..."), defaultPath,
extensionsStr, nullptr,
QFileDialog::Options()));
if (!fp.isValid()) {
return;
}
if (!extensions.contains(fp.getSuffix().toLower().toUtf8())) {
fp.setPath(fp.toStr() % "." % defaultExtension);
}
if (!isPdf) {
// Strip page number from the file path, if any.
QString tmp = fp.toStr();
tmp.chop(fp.getSuffix().length() + 1);
while ((!tmp.isEmpty()) && (tmp.at(tmp.length() - 1) == '1')) {
tmp.chop(1);
}
fp.setPath(tmp % "." % fp.getSuffix());
}
if (fp.toStr() == key) {
sUsedFilePaths.remove(key);
} else {
sUsedFilePaths[key] = fp.toStr();
}
if (getOpenExportedFiles()) {
if (isPdf) {
mPathToOpenAfterExport = fp;
} else {
mPathToOpenAfterExport = fp.getParentDir();
}
}
openProgressDialog();
mExport->startExport(mPages, fp);
}
}
void GraphicsExportDialog::openProgressDialog() noexcept {
mProgressDialog->setValue(0); // Auto-opens the dialog.
}
bool GraphicsExportDialog::eventFilter(QObject* object,
QEvent* event) noexcept {
if (object == mUi->treeContent->viewport()) {
switch (event->type()) {
case QEvent::Drop: {
// The view will change the order of items, so we have to schedule
// an update of our settings to apply this reordering.
applySettings();
break;
}
default:
break;
}
}
return QDialog::eventFilter(object, event);
}
/*******************************************************************************
* GUI Access Methods
******************************************************************************/
void GraphicsExportDialog::setPageSize(
const std::optional<QPageSize::PageSizeId>& size) noexcept {
for (int i = 0; i < mAvailablePageSizes.count(); ++i) {
std::optional<QPageSize> value = mAvailablePageSizes.at(i);
if (((!size) && (!value)) || (size && value && size == value->id())) {
mUi->cbxPageSize->setCurrentIndex(i);
return;
}
}
}
std::optional<QPageSize> GraphicsExportDialog::getPageSize() const noexcept {
return mAvailablePageSizes.value(mUi->cbxPageSize->currentIndex());
}
void GraphicsExportDialog::setOrientation(
GraphicsExportSettings::Orientation orientation) noexcept {
if (orientation == GraphicsExportSettings::Orientation::Landscape) {
mUi->rbtnOrientationLandscape->setChecked(true);
} else if (orientation == GraphicsExportSettings::Orientation::Portrait) {
mUi->rbtnOrientationPortrait->setChecked(true);
} else {
mUi->rbtnOrientationAuto->setChecked(true);
}
}
GraphicsExportSettings::Orientation GraphicsExportDialog::getOrientation()
const noexcept {
if (mUi->rbtnOrientationLandscape->isChecked()) {
return GraphicsExportSettings::Orientation::Landscape;
} else if (mUi->rbtnOrientationPortrait->isChecked()) {
return GraphicsExportSettings::Orientation::Portrait;
} else {
return GraphicsExportSettings::Orientation::Auto;
}
}
void GraphicsExportDialog::setMarginLeft(
const UnsignedLength& margin) noexcept {
mUi->edtMarginLeft->setValue(margin);
}
UnsignedLength GraphicsExportDialog::getMarginLeft() const noexcept {
return mUi->edtMarginLeft->getValue();
}
void GraphicsExportDialog::setMarginTop(const UnsignedLength& margin) noexcept {
mUi->edtMarginTop->setValue(margin);
}
UnsignedLength GraphicsExportDialog::getMarginTop() const noexcept {
return mUi->edtMarginTop->getValue();
}
void GraphicsExportDialog::setMarginRight(
const UnsignedLength& margin) noexcept {
mUi->edtMarginRight->setValue(margin);
}
UnsignedLength GraphicsExportDialog::getMarginRight() const noexcept {
return mUi->edtMarginRight->getValue();
}
void GraphicsExportDialog::setMarginBottom(
const UnsignedLength& margin) noexcept {
mUi->edtMarginBottom->setValue(margin);
}
UnsignedLength GraphicsExportDialog::getMarginBottom() const noexcept {
return mUi->edtMarginBottom->getValue();
}
void GraphicsExportDialog::setShowPinNumbers(bool show) noexcept {
mUi->cbxShowPinNumbers->setChecked(show);
}
bool GraphicsExportDialog::getShowPinNumbers() const noexcept {
return mUi->cbxShowPinNumbers->isChecked();
}
void GraphicsExportDialog::setRotate(bool rotate) noexcept {
mUi->cbxRotate->setChecked(rotate);
}
bool GraphicsExportDialog::getRotate() const noexcept {
return mUi->cbxRotate->isChecked();
}
void GraphicsExportDialog::setMirror(bool mirror) noexcept {
mUi->cbxMirror->setChecked(mirror);
}
bool GraphicsExportDialog::getMirror() const noexcept {
return mUi->cbxMirror->isChecked();
}
void GraphicsExportDialog::setFitToPage(bool fit) noexcept {
mUi->cbxScaleAuto->setChecked(fit);
}
bool GraphicsExportDialog::getFitToPage() const noexcept {
return mUi->cbxScaleAuto->isChecked();
}
void GraphicsExportDialog::setScaleFactor(
const UnsignedRatio& factor) noexcept {
mUi->spbxScaleFactor->setValue(factor);
}
UnsignedRatio GraphicsExportDialog::getScaleFactor() const noexcept {
return mUi->spbxScaleFactor->getValue();
}
void GraphicsExportDialog::setDpi(int dpi) noexcept {
mUi->spbxResolutionDpi->setValue(dpi);
}
int GraphicsExportDialog::getDpi() const noexcept {
return mUi->spbxResolutionDpi->value();
}
void GraphicsExportDialog::setBlackWhite(bool blackWhite) noexcept {
mUi->cbxBlackWhite->setChecked(blackWhite);
}
bool GraphicsExportDialog::getBlackWhite() const noexcept {
return mUi->cbxBlackWhite->isChecked();
}
void GraphicsExportDialog::setBackgroundColor(const QColor& color) noexcept {
if (color == Qt::white) {
mUi->rbtnBackgroundWhite->setChecked(true);
} else if (color == Qt::black) {
mUi->rbtnBackgroundBlack->setChecked(true);
} else {
mUi->rbtnBackgroundNone->setChecked(true);
}
}
QColor GraphicsExportDialog::getBackgroundColor() const noexcept {
if (mUi->rbtnBackgroundWhite->isChecked()) {
return Qt::white;
} else if (mUi->rbtnBackgroundBlack->isChecked()) {
return Qt::black;
} else {
return Qt::transparent;
}
}
void GraphicsExportDialog::setMinLineWidth(
const UnsignedLength& width) noexcept {
mUi->edtMinLineWidth->setValue(width);
}
UnsignedLength GraphicsExportDialog::getMinLineWidth() const noexcept {
return mUi->edtMinLineWidth->getValue();
}
void GraphicsExportDialog::setPrinterName(const QString& name) noexcept {
for (int i = 0; i < mAvailablePrinters.count(); ++i) {
if (mAvailablePrinters.at(i).printerName() == name) {
mUi->cbxPrinter->setCurrentIndex(i);
return;
}
}
}
QString GraphicsExportDialog::getPrinterName() const noexcept {
return mAvailablePrinters.value(mUi->cbxPrinter->currentIndex())
.printerName();
}
void GraphicsExportDialog::setDuplex(QPrinter::DuplexMode duplex) noexcept {
for (int i = 0; i < mUi->cbxDuplex->count(); ++i) {
if (mUi->cbxDuplex->itemData(i).toInt() == duplex) {
mUi->cbxDuplex->setCurrentIndex(i);
return;
}
}
}
QPrinter::DuplexMode GraphicsExportDialog::getDuplex() const noexcept {
const int intValue = mUi->cbxDuplex->currentData().toInt();
const QSet<int> validValues = {
QPrinter::DuplexNone,
QPrinter::DuplexLongSide,
QPrinter::DuplexShortSide,
};
if (validValues.contains(intValue)) {
return static_cast<QPrinter::DuplexMode>(intValue);
} else {
return QPrinter::DuplexNone;
}
}
void GraphicsExportDialog::setPageContent(
const QList<ContentItem>& items) noexcept {
QSignalBlocker signalBlocker(mUi->treeContent); // Avoid recursion.
mUi->treeContent->clear();
mPageContentItems = items;
foreach (const ContentItem& item, items) {
QTreeWidgetItem* node = new QTreeWidgetItem(mUi->treeContent);
node->setText(0, item.name);
node->setCheckState(0, item.enabled ? Qt::Checked : Qt::Unchecked);
node->setCheckState(1, item.mirror ? Qt::Checked : Qt::Unchecked);
node->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |
Qt::ItemIsEnabled | Qt::ItemIsEditable |
Qt::ItemIsDragEnabled);
foreach (const auto& pair, mColors) {
QTreeWidgetItem* child = new QTreeWidgetItem(node);
const ColorRole* role = mColorScheme.getColors(pair.first).role;
child->setText(0, role ? role->getNameTr() : QString());
child->setCheckState(
0, item.colors.contains(pair.first) ? Qt::Checked : Qt::Unchecked);
}
}
mUi->treeContent->viewport()->update(); // Fix UI flicker.
applySettings(); // Because we disabled updates triggered by the UI.
}
const QList<GraphicsExportDialog::ContentItem>&
GraphicsExportDialog::getPageContent() const noexcept {
return mPageContentItems;
}
void GraphicsExportDialog::setOpenExportedFiles(bool open) noexcept {
mUi->cbxOpenExportedFiles->setChecked(open);
}
bool GraphicsExportDialog::getOpenExportedFiles() const noexcept {
return mUi->cbxOpenExportedFiles->isChecked();
}
void GraphicsExportDialog::updateColorsListWidget() noexcept {
mUi->lstLayerColors->clear();
foreach (const auto& pair, mColors) {
const ColorRole* role = mColorScheme.getColors(pair.first).role;
QListWidgetItem* item =
new QListWidgetItem(role ? role->getNameTr() : QString());
item->setData(Qt::DecorationRole, pair.second);
mUi->lstLayerColors->addItem(item);
}
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace editor
} // namespace librepcb