diff options
Diffstat (limited to 'src/printsupport')
27 files changed, 1334 insertions, 263 deletions
diff --git a/src/printsupport/dialogs/qpagesetupdialog.h b/src/printsupport/dialogs/qpagesetupdialog.h index 70517dc844..a7aaa03134 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.h +++ b/src/printsupport/dialogs/qpagesetupdialog.h @@ -62,14 +62,14 @@ public: ~QPageSetupDialog(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - void setVisible(bool visible) Q_DECL_OVERRIDE; + void setVisible(bool visible) override; #endif - int exec() Q_DECL_OVERRIDE; + int exec() override; using QDialog::open; void open(QObject *receiver, const char *member); - void done(int result) Q_DECL_OVERRIDE; + void done(int result) override; QPrinter *printer(); }; diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index ee7bc62491..7e32f9aa57 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE +extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits); + // Disabled until we have support for papersources on unix // #define PSD_ENABLE_PAPERSOURCE @@ -117,7 +119,7 @@ public: } protected: - void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE + void paintEvent(QPaintEvent *) override { QSize pageSize = m_pageLayout.fullRectPoints().size(); QSizeF scaledSize = pageSize.scaled(width() - 10, height() - 10, Qt::KeepAspectRatio); @@ -210,7 +212,7 @@ void QUnixPageSetupDialogPrivate::init() Q_Q(QPageSetupDialog); widget = new QPageSetupWidget(q); - widget->setPrinter(printer); + widget->setPrinter(printer, nullptr, printer->outputFormat(), printer->printerName()); QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, @@ -232,12 +234,20 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent) : QWidget(parent), m_pagePreview(nullptr), m_printer(nullptr), + m_printDevice(nullptr), m_outputFormat(QPrinter::PdfFormat), m_units(QPageLayout::Point), - m_blockSignals(false) + m_savedUnits(QPageLayout::Point), + m_savedPagesPerSheet(-1), + m_savedPagesPerSheetLayout(-1), + m_blockSignals(false), + m_realCustomPageSizeIndex(-1) { m_ui.setupUi(this); + if (!QMetaType::hasRegisteredComparators<QPageSize>()) + QMetaType::registerEqualsComparator<QPageSize>(); + QVBoxLayout *lay = new QVBoxLayout(m_ui.preview); m_pagePreview = new QPagePreview(m_ui.preview); m_pagePreview->setPagePreviewLayout(1, 1); @@ -341,15 +351,18 @@ void QPageSetupWidget::initPageSizes() m_ui.pageSizeCombo->clear(); + m_realCustomPageSizeIndex = -1; + if (m_outputFormat == QPrinter::NativeFormat && !m_printerName.isEmpty()) { QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); if (ps) { QPrintDevice printDevice = ps->createPrintDevice(m_printerName); const auto pageSizes = printDevice.supportedPageSizes(); for (const QPageSize &pageSize : pageSizes) - m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize.id())); + m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize)); if (m_ui.pageSizeCombo->count() > 0 && printDevice.supportsCustomPageSizes()) { - m_ui.pageSizeCombo->addItem(tr("Custom"), QVariant::fromValue(QPageSize::Custom)); + m_ui.pageSizeCombo->addItem(tr("Custom")); + m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1; m_blockSignals = false; return; } @@ -359,10 +372,11 @@ void QPageSetupWidget::initPageSizes() // If PdfFormat or no available printer page sizes, populate with all page sizes for (int id = 0; id < QPageSize::LastPageSize; ++id) { if (QPageSize::PageSizeId(id) == QPageSize::Custom) { - m_ui.pageSizeCombo->addItem(tr("Custom"), QVariant::fromValue(QPageSize::Custom)); + m_ui.pageSizeCombo->addItem(tr("Custom")); + m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1; } else { QPageSize pageSize = QPageSize(QPageSize::PageSizeId(id)); - m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize.id())); + m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize)); } } @@ -371,12 +385,21 @@ void QPageSetupWidget::initPageSizes() // Set the dialog to use the given QPrinter // Usually only called on first creation -void QPageSetupWidget::setPrinter(QPrinter *printer) +void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName) { m_printer = printer; + m_printDevice = printDevice; // Initialize the layout to the current QPrinter layout m_pageLayout = m_printer->pageLayout(); + + if (printDevice) { + const QPageSize pageSize = printDevice->defaultPageSize(); + const QMarginsF printable = printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution()); + m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units())); + } + // Assume if margins are Points then is by default, so set to locale default units if (m_pageLayout.units() == QPageLayout::Point) { if (QLocale().measurementSystem() == QLocale::MetricSystem) @@ -387,18 +410,11 @@ void QPageSetupWidget::setPrinter(QPrinter *printer) m_units = m_pageLayout.units(); m_pagePreview->setPageLayout(m_pageLayout); - // Then update the widget with the current printer details - selectPrinter(m_printer->outputFormat(), m_printer->printerName()); -} - -// The printer selected in the QPrintDialog has been changed, update the widget to reflect this -// Note the QPrinter is not updated at this time in case the user presses the Cancel button in QPrintDialog -void QPageSetupWidget::selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName) -{ m_outputFormat = outputFormat; m_printerName = printerName; initPageSizes(); updateWidget(); + updateSavedValues(); } // Update the widget with the current settings @@ -437,7 +453,9 @@ void QPageSetupWidget::updateWidget() m_ui.unitCombo->setCurrentIndex(m_ui.unitCombo->findData(QVariant::fromValue(m_units))); - m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(m_pageLayout.pageSize().id()))); + const bool isCustom = m_ui.pageSizeCombo->currentIndex() == m_realCustomPageSizeIndex && m_realCustomPageSizeIndex != -1; + if (!isCustom) + m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(m_pageLayout.pageSize()))); QMarginsF min; QMarginsF max; @@ -470,8 +488,6 @@ void QPageSetupWidget::updateWidget() m_ui.bottomMargin->setMaximum(max.bottom()); m_ui.bottomMargin->setValue(m_pageLayout.margins().bottom()); - bool isCustom = m_ui.pageSizeCombo->currentData().value<QPageSize::PageSizeId>() == QPageSize::Custom; - m_ui.pageWidth->setSuffix(suffix); m_ui.pageWidth->setValue(m_pageLayout.fullRect(m_units).width()); m_ui.pageWidth->setEnabled(isCustom); @@ -482,6 +498,7 @@ void QPageSetupWidget::updateWidget() m_ui.pageHeight->setEnabled(isCustom); m_ui.heightLabel->setEnabled(isCustom); + m_ui.portrait->setChecked(m_pageLayout.orientation() == QPageLayout::Portrait); m_ui.landscape->setChecked(m_pageLayout.orientation() == QPageLayout::Landscape); m_ui.pagesPerSheetButtonGroup->setEnabled(m_outputFormat == QPrinter::NativeFormat); @@ -510,25 +527,46 @@ void QPageSetupWidget::setupPrinter() const #endif } +void QPageSetupWidget::updateSavedValues() +{ + m_savedUnits = m_units; + m_savedPageLayout = m_pageLayout; + m_savedPagesPerSheet = m_ui.pagesPerSheetCombo->currentIndex(); + m_savedPagesPerSheetLayout = m_ui.pagesPerSheetLayoutCombo->currentIndex(); +} + +void QPageSetupWidget::revertToSavedValues() +{ + m_units = m_savedUnits; + m_pageLayout = m_savedPageLayout; + m_pagePreview->setPageLayout(m_pageLayout); + + updateWidget(); + + m_ui.pagesPerSheetCombo->setCurrentIndex(m_savedPagesPerSheet); + m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(m_savedPagesPerSheetLayout); +} + // Updates size/preview after the combobox has been changed. void QPageSetupWidget::pageSizeChanged() { if (m_blockSignals) return; - QPageSize::PageSizeId id = m_ui.pageSizeCombo->currentData().value<QPageSize::PageSizeId>(); - if (id != QPageSize::Custom) { - // TODO Set layout margin min/max to printer custom min/max - m_pageLayout.setPageSize(QPageSize(id)); + QPageSize pageSize; + if (m_ui.pageSizeCombo->currentIndex() != m_realCustomPageSizeIndex) { + pageSize = m_ui.pageSizeCombo->currentData().value<QPageSize>(); } else { QSizeF customSize; if (m_pageLayout.orientation() == QPageLayout::Landscape) customSize = QSizeF(m_ui.pageHeight->value(), m_ui.pageWidth->value()); else customSize = QSizeF(m_ui.pageWidth->value(), m_ui.pageHeight->value()); - // TODO Set layout margin min/max to printer min/max for page size - m_pageLayout.setPageSize(QPageSize(customSize, QPageSize::Unit(m_units))); + pageSize = QPageSize(customSize, QPageSize::Unit(m_units)); } + const QMarginsF printable = m_printDevice ? m_printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution()) + : QMarginsF(); + m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units())); m_pagePreview->setPageLayout(m_pageLayout); updateWidget(); diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h index 4322b34690..bb33a0f587 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h @@ -64,17 +64,19 @@ QT_REQUIRE_CONFIG(printdialog); QT_BEGIN_NAMESPACE class QPrinter; +class QPrintDevice; class QPagePreview; class QPageSetupWidget : public QWidget { Q_OBJECT public: explicit QPageSetupWidget(QWidget *parent = nullptr); - explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = nullptr); - void setPrinter(QPrinter *printer); - void selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName); + void setPrinter(QPrinter *printer, QPrintDevice *printDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName); void setupPrinter() const; + void updateSavedValues(); + void revertToSavedValues(); private slots: void pageSizeChanged(); @@ -97,11 +99,17 @@ private: Ui::QPageSetupWidget m_ui; QPagePreview *m_pagePreview; QPrinter *m_printer; + QPrintDevice *m_printDevice; QPrinter::OutputFormat m_outputFormat; QString m_printerName; QPageLayout m_pageLayout; + QPageLayout m_savedPageLayout; QPageLayout::Unit m_units; + QPageLayout::Unit m_savedUnits; + int m_savedPagesPerSheet; + int m_savedPagesPerSheetLayout; bool m_blockSignals; + int m_realCustomPageSizeIndex; }; QT_END_NAMESPACE diff --git a/src/printsupport/dialogs/qprintdialog.h b/src/printsupport/dialogs/qprintdialog.h index bbddc296e9..bbb12202f0 100644 --- a/src/printsupport/dialogs/qprintdialog.h +++ b/src/printsupport/dialogs/qprintdialog.h @@ -63,11 +63,11 @@ public: explicit QPrintDialog(QWidget *parent = nullptr); ~QPrintDialog(); - int exec() Q_DECL_OVERRIDE; + int exec() override; #if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) - virtual void accept() Q_DECL_OVERRIDE; + virtual void accept() override; #endif - void done(int result) Q_DECL_OVERRIDE; + void done(int result) override; void setOption(PrintDialogOption option, bool on = true); bool testOption(PrintDialogOption option) const; @@ -75,7 +75,7 @@ public: PrintDialogOptions options() const; #if defined(Q_OS_UNIX) || defined(Q_OS_WIN) - void setVisible(bool visible) Q_DECL_OVERRIDE; + void setVisible(bool visible) override; #endif using QDialog::open; diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 0b36dec003..2cc5bfbb8c 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -48,7 +48,9 @@ #if QT_CONFIG(filedialog) #include "qfiledialog.h" #endif +#include <QtCore/qdebug.h> #include <QtCore/qdir.h> +#include <QtCore/qtextcodec.h> #include <QtGui/qevent.h> #if QT_CONFIG(filesystemmodel) #include <QtWidgets/qfilesystemmodel.h> @@ -108,6 +110,11 @@ Print dialog class declarations allow editing of Page and Advanced tabs. Layout in qprintpropertieswidget.ui + + QPPDOptionsModel: Holds the PPD Options for the printer. + + QPPDOptionsEditor: Edits the PPD Options for the printer. + */ static void initResources() @@ -124,22 +131,33 @@ class QPrintPropertiesDialog : public QDialog { Q_OBJECT public: - QPrintPropertiesDialog(QAbstractPrintDialog *parent = nullptr); + QPrintPropertiesDialog(QPrinter *printer, QPrintDevice *currentPrintDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName, + QAbstractPrintDialog *parent); ~QPrintPropertiesDialog(); - void selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName); - - /// copy printer properties to the widget - void applyPrinterProperties(QPrinter *p); void setupPrinter() const; + void showEvent(QShowEvent *event) override; + +private slots: + void reject() override; + void accept() override; + private: friend class QUnixPrintWidgetPrivate; + QPrinter *m_printer; Ui::QPrintPropertiesWidget widget; QDialogButtonBox *m_buttons; #if QT_CONFIG(cupsjobwidget) QCupsJobWidget *m_jobOptions; #endif + +#if QT_CONFIG(cups) + void setCupsOptionsFromItems(QOptionTreeItem *parent) const; + + QPPDOptionsModel *m_cupsOptionsModel; +#endif }; class QUnixPrintWidgetPrivate; @@ -168,8 +186,6 @@ public: QUnixPrintWidgetPrivate(QUnixPrintWidget *q, QPrinter *prn); ~QUnixPrintWidgetPrivate(); - /// copy printer properties to the widget - void applyPrinterProperties(); bool checkFields(); void setupPrinter(); void setOptionsPane(QPrintDialogPrivate *pane); @@ -191,7 +207,6 @@ public: private: QPrintDialogPrivate *optionsPane; bool filePrintersAdded; - bool propertiesDialogShown; }; class QPrintDialogPrivate : public QAbstractPrintDialogPrivate @@ -203,8 +218,6 @@ public: ~QPrintDialogPrivate(); void init(); - /// copy printer properties to the widget - void applyPrinterProperties(); void selectPrinter(const QPrinter::OutputFormat outputFormat); @@ -217,7 +230,7 @@ public: void setupPrinter(); void updateWidgets(); - virtual void setTabs(const QList<QWidget*> &tabs) Q_DECL_OVERRIDE; + virtual void setTabs(const QList<QWidget*> &tabs) override; Ui::QPrintSettingsOutput options; QUnixPrintWidget *top; @@ -227,6 +240,100 @@ public: QPrinter::OutputFormat printerOutputFormat; }; +#if QT_CONFIG(cups) +class QOptionTreeItem +{ +public: + enum ItemType { Root, Group, Option, Choice }; + + QOptionTreeItem(ItemType t, int i, const void *p, QOptionTreeItem *pi) + : type(t), + index(i), + ptr(p), + parentItem(pi) {} + + ~QOptionTreeItem() { + qDeleteAll(childItems); + } + + ItemType type; + int index; + const void *ptr; + QOptionTreeItem *parentItem; + QList<QOptionTreeItem*> childItems; +}; + +class QOptionTreeItemOption : public QOptionTreeItem +{ +public: + QOptionTreeItemOption (int i, const void *p, QOptionTreeItem *pi) + : QOptionTreeItem(Option, i, p, pi) + { + } + + // These indices are related to ppd_option_t::choices not to childItems + int selected; + int originallySelected; +}; + +class QPPDOptionsModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *parent); + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + + void setCupsOptionsFromItems(QPrinter *printer) const; + void reject(); + void updateSavedValues(); + void revertToSavedValues(); + + QPrintDevice *currentPrintDevice() const; + QTextCodec *cupsCodec() const; + + void emitConflictsChanged(); + bool hasConflicts() const; + +signals: + void hasConflictsChanged(bool conflicts); + +private: + void parseGroups(QOptionTreeItem *parent); + void parseOptions(QOptionTreeItem *parent); + void parseChoices(QOptionTreeItemOption *parent); + + void setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const; + void reject(QOptionTreeItem *item); + void updateSavedValues(QOptionTreeItem *item); + void revertToSavedValues(QOptionTreeItem *item); + void emitDataChanged(QOptionTreeItem *item, const QModelIndex &itemIndex, bool *conflictsFound); + bool hasConflicts(QOptionTreeItem *item) const; + + QPrintDevice *m_currentPrintDevice; + QTextCodec *m_cupsCodec; + QOptionTreeItem *m_rootItem; +}; + +class QPPDOptionsEditor : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit QPPDOptionsEditor(QObject *parent) : QStyledItemDelegate(parent) {} + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; +}; + +#endif //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -240,8 +347,11 @@ public: */ -QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent) +QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice *currentPrintDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName, + QAbstractPrintDialog *parent) : QDialog(parent) + , m_printer(printer) { setWindowTitle(tr("Printer Properties")); QVBoxLayout *lay = new QVBoxLayout(this); @@ -254,9 +364,36 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent) connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QPrintPropertiesDialog::accept); connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QPrintPropertiesDialog::reject); + widget.pageSetup->setPrinter(printer, currentPrintDevice, outputFormat, printerName); + #if QT_CONFIG(cupsjobwidget) - m_jobOptions = new QCupsJobWidget(); - widget.tabs->addTab(m_jobOptions, tr("Job Options")); + m_jobOptions = new QCupsJobWidget(printer, currentPrintDevice); + widget.tabs->insertTab(1, m_jobOptions, tr("Job Options")); +#endif + + const int advancedTabIndex = widget.tabs->indexOf(widget.cupsPropertiesPage); +#if QT_CONFIG(cups) + m_cupsOptionsModel = new QPPDOptionsModel(currentPrintDevice, this); + + widget.treeView->setItemDelegate(new QPPDOptionsEditor(this)); + + if (m_cupsOptionsModel->rowCount() > 0) { + widget.treeView->setModel(m_cupsOptionsModel); + + for (int i = 0; i < m_cupsOptionsModel->rowCount(); ++i) + widget.treeView->expand(m_cupsOptionsModel->index(i, 0)); + + widget.tabs->setTabEnabled(advancedTabIndex, true); + } else { + widget.treeView->setModel(nullptr); + widget.tabs->setTabEnabled(advancedTabIndex, false); + } + + widget.conflictsLabel->setVisible(m_cupsOptionsModel->hasConflicts()); + connect(m_cupsOptionsModel, &QPPDOptionsModel::hasConflictsChanged, widget.conflictsLabel, &QLabel::setVisible); +#else + Q_UNUSED(currentPrintDevice) + widget.tabs->setTabEnabled(advancedTabIndex, false); #endif } @@ -264,25 +401,62 @@ QPrintPropertiesDialog::~QPrintPropertiesDialog() { } -void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p) +void QPrintPropertiesDialog::setupPrinter() const { - widget.pageSetup->setPrinter(p); + widget.pageSetup->setupPrinter(); #if QT_CONFIG(cupsjobwidget) - m_jobOptions->setPrinter(p); + m_jobOptions->setupPrinter(); +#endif + +#if QT_CONFIG(cups) + // Set Color by default, that will change if the "ColorModel" property is available + m_printer->setColorMode(QPrinter::Color); + + m_cupsOptionsModel->setCupsOptionsFromItems(m_printer); #endif } -void QPrintPropertiesDialog::setupPrinter() const +void QPrintPropertiesDialog::showEvent(QShowEvent *event) { - widget.pageSetup->setupPrinter(); + widget.treeView->resizeColumnToContents(0); + QDialog::showEvent(event); +} + +void QPrintPropertiesDialog::reject() +{ + widget.pageSetup->revertToSavedValues(); + #if QT_CONFIG(cupsjobwidget) - m_jobOptions->setupPrinter(); + m_jobOptions->revertToSavedValues(); +#endif + +#if QT_CONFIG(cups) + m_cupsOptionsModel->revertToSavedValues(); #endif + QDialog::reject(); } -void QPrintPropertiesDialog::selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName) +void QPrintPropertiesDialog::accept() { - widget.pageSetup->selectPrinter(outputFormat, printerName); +#if QT_CONFIG(cups) + if (m_cupsOptionsModel->hasConflicts()) { + widget.tabs->setCurrentWidget(widget.cupsPropertiesPage); + const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Advanced Option Conflicts"), + tr("There are conflicts in some advanced options. Do you want to fix them?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + if (answer != QMessageBox::No) + return; + } + m_cupsOptionsModel->updateSavedValues(); +#endif + +#if QT_CONFIG(cupsjobwidget) + m_jobOptions->updateSavedValues(); +#endif + + widget.pageSetup->updateSavedValues(); + + QDialog::accept(); } //////////////////////////////////////////////////////////////////////////////// @@ -323,6 +497,9 @@ void QPrintDialogPrivate::init() options.pageSetCombo->addItem(tr("All Pages"), QVariant::fromValue(QCUPSSupport::AllPages)); options.pageSetCombo->addItem(tr("Odd Pages"), QVariant::fromValue(QCUPSSupport::OddPages)); options.pageSetCombo->addItem(tr("Even Pages"), QVariant::fromValue(QCUPSSupport::EvenPages)); +#else + for (int i = options.pagesLayout->count() - 1; i >= 0; --i) + delete options.pagesLayout->itemAt(i)->widget(); #endif top->d->setOptionsPane(this); @@ -364,6 +541,11 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma QPrinter *p = q->printer(); printerOutputFormat = outputFormat; + // printer supports duplex mode? + const auto supportedDuplexMode = top->d->m_currentPrintDevice.supportedDuplexModes(); + options.duplexLong->setEnabled(supportedDuplexMode.contains(QPrint::DuplexLongSide)); + options.duplexShort->setEnabled(supportedDuplexMode.contains(QPrint::DuplexShortSide)); + if (p->colorMode() == QPrinter::Color) options.color->setChecked(true); else @@ -388,13 +570,94 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma options.pageSetCombo->setEnabled(false); else options.pageSetCombo->setEnabled(true); + +#if QT_CONFIG(cups) + // Disable color options on main dialog if not printing to file, it will be handled by CUPS advanced dialog + options.colorMode->setVisible(outputFormat == QPrinter::PdfFormat); +#endif } -void QPrintDialogPrivate::applyPrinterProperties() +#if QT_CONFIG(cups) +static std::vector<std::pair<int, int>> pageRangesFromString(const QString &pagesString) Q_DECL_NOTHROW { - // apply printer options to property dialog - top->d->applyPrinterProperties(); + std::vector<std::pair<int, int>> result; + const QStringList items = pagesString.split(','); + for (const QString item : items) { + if (item.isEmpty()) + return {}; + + if (item.contains(QLatin1Char('-'))) { + const QStringList rangeItems = item.split('-'); + if (rangeItems.count() != 2) + return {}; + + bool ok; + const int number1 = rangeItems[0].toInt(&ok); + if (!ok) + return {}; + + const int number2 = rangeItems[1].toInt(&ok); + if (!ok) + return {}; + + if (number1 < 1 || number2 < 1 || number2 < number1) + return {}; + + result.push_back(std::make_pair(number1, number2)); + + } else { + bool ok; + const int number = item.toInt(&ok); + if (!ok) + return {}; + + if (number < 1) + return {}; + + result.push_back(std::make_pair(number, number)); + } + } + + // check no range intersects with the next + std::sort(result.begin(), result.end(), + [](const std::pair<int, int> &it1, const std::pair<int, int> &it2) { return it1.first < it2.first; }); + int previousSecond = -1; + for (auto pair : result) { + if (pair.first <= previousSecond) + return {}; + + previousSecond = pair.second; + } + + return result; +} + +static QString stringFromPageRanges(const std::vector<std::pair<int, int>> &pageRanges) Q_DECL_NOTHROW +{ + QString result; + + for (auto pair : pageRanges) { + if (!result.isEmpty()) + result += QLatin1Char(','); + + if (pair.first == pair.second) + result += QString::number(pair.first); + else + result += QStringLiteral("%1-%2").arg(pair.first).arg(pair.second); + } + + return result; +} + +static bool isValidPagesString(const QString &pagesString) Q_DECL_NOTHROW +{ + if (pagesString.isEmpty()) + return false; + + auto pagesRanges = pageRangesFromString(pagesString); + return !pagesRanges.empty(); } +#endif void QPrintDialogPrivate::setupPrinter() { @@ -414,7 +677,12 @@ void QPrintDialogPrivate::setupPrinter() p->setDuplex(QPrinter::DuplexShortSide); } - p->setColorMode(options.color->isChecked() ? QPrinter::Color : QPrinter::GrayScale); +#if QT_CONFIG(cups) + // When printing to a device the colorMode will be set by the advanced panel + if (p->outputFormat() == QPrinter::PdfFormat) +#endif + p->setColorMode(options.color->isChecked() ? QPrinter::Color : QPrinter::GrayScale); + p->setPageOrder(options.reverse->isChecked() ? QPrinter::LastPageFirst : QPrinter::FirstPageFirst); // print range @@ -440,6 +708,16 @@ void QPrintDialogPrivate::setupPrinter() } #if QT_CONFIG(cups) + if (options.pagesRadioButton->isChecked()) { + auto pageRanges = pageRangesFromString(options.pagesLineEdit->text()); + + p->setPrintRange(QPrinter::AllPages); + p->setFromTo(0, 0); + + // server-side page filtering + QCUPSSupport::setPageRange(p, stringFromPageRanges(pageRanges)); + } + // page set if (p->printRange() == QPrinter::AllPages || p->printRange() == QPrinter::PageRange) { //If the application is selecting pages and the first page number is even then need to adjust the odd-even accordingly @@ -636,6 +914,16 @@ int QPrintDialog::exec() void QPrintDialog::accept() { Q_D(QPrintDialog); +#if QT_CONFIG(cups) + if (d->options.pagesRadioButton->isChecked() && !isValidPagesString(d->options.pagesLineEdit->text())) { + QMessageBox::critical(this, tr("Invalid Pages Definition"), + tr("%1 does not follow the correct syntax. Please use ',' to separate " + "ranges and pages, '-' to define ranges and make sure ranges do " + "not intersect with each other.").arg(d->options.pagesLineEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + return; + } +#endif d->setupPrinter(); QDialog::accept(); } @@ -657,9 +945,9 @@ void QPrintDialog::accept() */ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn) : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0), - filePrintersAdded(false), propertiesDialogShown(false) + filePrintersAdded(false) { - q = 0; + q = nullptr; if (parent) q = qobject_cast<QAbstractPrintDialog*> (parent->parent()); @@ -745,7 +1033,6 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) if (propertiesDialog){ delete propertiesDialog; propertiesDialog = nullptr; - propertiesDialogShown = false; } if (filePrintersAdded) { @@ -760,14 +1047,20 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) widget.lOutput->setEnabled(true); if (optionsPane) optionsPane->selectPrinter(QPrinter::PdfFormat); + printer->setOutputFormat(QPrinter::PdfFormat); + m_currentPrintDevice = QPrintDevice(); return; } } if (printer) { + printer->setOutputFormat(QPrinter::NativeFormat); + QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); if (ps) m_currentPrintDevice = ps->createPrintDevice(widget.printers->itemText(index)); + else + m_currentPrintDevice = QPrintDevice(); printer->setPrinterName(m_currentPrintDevice.id()); @@ -800,48 +1093,6 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked() } } -void QUnixPrintWidgetPrivate::applyPrinterProperties() -{ - if (printer == nullptr) - return; - if (printer->outputFileName().isEmpty()) { - QString home = QDir::homePath(); - QString cur = QDir::currentPath(); - if (home.at(home.length()-1) != QLatin1Char('/')) - home += QLatin1Char('/'); - if (!cur.isEmpty() && cur.at(cur.length()-1) != QLatin1Char('/')) - cur += QLatin1Char('/'); - if (!cur.startsWith(home)) - cur = home; - if (QGuiApplication::platformName() == QLatin1String("xcb")) { - if (printer->docName().isEmpty()) { - cur += QLatin1String("print.pdf"); - } else { - QRegExp re(QString::fromLatin1("(.*)\\.\\S+")); - if (re.exactMatch(printer->docName())) - cur += re.cap(1); - else - cur += printer->docName(); - cur += QLatin1String(".pdf"); - } - } // xcb - - widget.filename->setText(cur); - } - else - widget.filename->setText( printer->outputFileName() ); - QString printerName = printer->printerName(); - if (!printerName.isEmpty()) { - const int i = widget.printers->findText(printerName); - if (i >= 0) - widget.printers->setCurrentIndex(i); - } - // PDF printer not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget - - if (propertiesDialog) - propertiesDialog->applyPrinterProperties(printer); -} - #if QT_CONFIG(messagebox) bool QUnixPrintWidgetPrivate::checkFields() { @@ -874,7 +1125,7 @@ bool QUnixPrintWidgetPrivate::checkFields() } #if QT_CONFIG(cups) - if (propertiesDialogShown) { + if (propertiesDialog) { QCUPSSupport::PagesPerSheet pagesPerSheet = propertiesDialog->widget.pageSetup->m_ui.pagesPerSheetCombo ->currentData().value<QCUPSSupport::PagesPerSheet>(); @@ -899,18 +1150,18 @@ void QUnixPrintWidgetPrivate::setupPrinterProperties() { delete propertiesDialog; - propertiesDialog = new QPrintPropertiesDialog(q); - propertiesDialog->setResult(QDialog::Rejected); - propertiesDialogShown = false; - - propertiesDialog->applyPrinterProperties(q->printer()); + QPrinter::OutputFormat outputFormat; + QString printerName; if (q->isOptionEnabled(QPrintDialog::PrintToFile) && (widget.printers->currentIndex() == widget.printers->count() - 1)) {// PDF - propertiesDialog->selectPrinter(QPrinter::PdfFormat, QString()); + outputFormat = QPrinter::PdfFormat; + } else { + outputFormat = QPrinter::NativeFormat; + printerName = widget.printers->currentText(); } - else - propertiesDialog->selectPrinter(QPrinter::NativeFormat, widget.printers->currentText()); + + propertiesDialog = new QPrintPropertiesDialog(q->printer(), &m_currentPrintDevice, outputFormat, printerName, q); } void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked() @@ -918,15 +1169,6 @@ void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked() if (!propertiesDialog) setupPrinterProperties(); propertiesDialog->exec(); - if (!propertiesDialogShown && propertiesDialog->result() == QDialog::Rejected) { - // If properties dialog was rejected the dialog is deleted and - // the properties are set to defaults when printer is setup - delete propertiesDialog; - propertiesDialog = nullptr; - propertiesDialogShown = false; - } else - // properties dialog was shown and accepted - propertiesDialogShown = true; } void QUnixPrintWidgetPrivate::setupPrinter() @@ -951,8 +1193,7 @@ void QUnixPrintWidgetPrivate::setupPrinter() if (!propertiesDialog) setupPrinterProperties(); - if (propertiesDialog->result() == QDialog::Accepted || !propertiesDialogShown) - propertiesDialog->setupPrinter(); + propertiesDialog->setupPrinter(); } /*! \internal @@ -960,7 +1201,41 @@ void QUnixPrintWidgetPrivate::setupPrinter() QUnixPrintWidget::QUnixPrintWidget(QPrinter *printer, QWidget *parent) : QWidget(parent), d(new QUnixPrintWidgetPrivate(this, printer)) { - d->applyPrinterProperties(); + if (printer == nullptr) + return; + if (printer->outputFileName().isEmpty()) { + QString home = QDir::homePath(); + QString cur = QDir::currentPath(); + if (!home.endsWith(QLatin1Char('/'))) + home += QLatin1Char('/'); + if (!cur.startsWith(home)) + cur = home; + else if (!cur.endsWith(QLatin1Char('/'))) + cur += QLatin1Char('/'); + if (QGuiApplication::platformName() == QStringLiteral("xcb")) { + if (printer->docName().isEmpty()) { + cur += QStringLiteral("print.pdf"); + } else { + const QRegExp re(QStringLiteral("(.*)\\.\\S+")); + if (re.exactMatch(printer->docName())) + cur += re.cap(1); + else + cur += printer->docName(); + cur += QStringLiteral(".pdf"); + } + } // xcb + + d->widget.filename->setText(cur); + } + else + d->widget.filename->setText(printer->outputFileName()); + const QString printerName = printer->printerName(); + if (!printerName.isEmpty()) { + const int i = d->widget.printers->findText(printerName); + if (i >= 0) + d->widget.printers->setCurrentIndex(i); + } + // PDF printer not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget } /*! \internal @@ -982,6 +1257,437 @@ void QUnixPrintWidget::updatePrinter() //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +/* + + QPPDOptionsModel + + Holds the PPD Options for the printer. + +*/ + +#if QT_CONFIG(cups) + +static bool isBlacklistedGroup(ppd_group_t *group) Q_DECL_NOTHROW +{ + return qstrcmp(group->name, "InstallableOptions") == 0; +}; + +QPPDOptionsModel::QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *parent) + : QAbstractItemModel(parent) + , m_currentPrintDevice(currentPrintDevice) + , m_cupsCodec(nullptr) +{ + ppd_file_t *ppd = m_currentPrintDevice->property(PDPK_PpdFile).value<ppd_file_t*>(); + m_rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, nullptr); + + if (ppd) { + m_cupsCodec = QTextCodec::codecForName(ppd->lang_encoding); + for (int i = 0; i < ppd->num_groups; ++i) { + if (!isBlacklistedGroup(&ppd->groups[i])) { + QOptionTreeItem *group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppd->groups[i], m_rootItem); + m_rootItem->childItems.append(group); + parseGroups(group); // parse possible subgroups + parseOptions(group); // parse options + } + } + } + + if (!m_cupsCodec) + m_cupsCodec = QTextCodec::codecForLocale(); +} + +int QPPDOptionsModel::columnCount(const QModelIndex &) const +{ + return 2; +} + +int QPPDOptionsModel::rowCount(const QModelIndex &parent) const +{ + QOptionTreeItem *itm; + if (!parent.isValid()) + itm = m_rootItem; + else + itm = static_cast<QOptionTreeItem*>(parent.internalPointer()); + + if (itm->type == QOptionTreeItem::Option) + return 0; + + return itm->childItems.count(); +} + +QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer()); + + switch (role) { + case Qt::FontRole: { + if (itm->type == QOptionTreeItem::Group){ + QFont font; + font.setBold(true); + return QVariant(font); + } + return QVariant(); + } + break; + + case Qt::DisplayRole: { + if (index.column() == 0) { + if (itm->type == QOptionTreeItem::Option) { + const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr); + return m_cupsCodec->toUnicode(option->text); + } else if (itm->type == QOptionTreeItem::Group) { + const ppd_group_t *group = static_cast<const ppd_group_t*>(itm->ptr); + return m_cupsCodec->toUnicode(group->text); + } + } else if (itm->type == QOptionTreeItem::Option) { + QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm); + const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr); + if (itmOption->selected > -1) + return m_cupsCodec->toUnicode(option->choices[itmOption->selected].text); + } + + return QVariant(); + } + break; + + case Qt::DecorationRole: { + if (itm->type == QOptionTreeItem::Option && index.column() == 1) { + const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr); + if (option->conflicted) { + const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr); + if (!warning.isNull()) + return warning; + + qWarning() << "Current application style returned a null icon for SP_MessageBoxWarning."; + return QColor(Qt::red); + } + } + return QVariant(); + } + break; + + } + + return QVariant(); +} + +QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex &parent) const +{ + QOptionTreeItem *itm; + if (!parent.isValid()) + itm = m_rootItem; + else + itm = static_cast<QOptionTreeItem*>(parent.internalPointer()); + + return createIndex(row, column, itm->childItems.at(row)); +} + + +QModelIndex QPPDOptionsModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer()); + + if (itm->parentItem && itm->parentItem != m_rootItem) + return createIndex(itm->parentItem->index, 0, itm->parentItem); + + return QModelIndex(); +} + +Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid() || static_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Group) + return Qt::ItemIsEnabled; + + if (index.column() == 1) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QPrintDevice *QPPDOptionsModel::currentPrintDevice() const +{ + return m_currentPrintDevice; +} + +QTextCodec *QPPDOptionsModel::cupsCodec() const +{ + return m_cupsCodec; +} + +void QPPDOptionsModel::setCupsOptionsFromItems(QPrinter *printer) const +{ + setCupsOptionsFromItems(printer, m_rootItem); +} + +void QPPDOptionsModel::setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const +{ + for (QOptionTreeItem *itm : qAsConst(parent->childItems)) { + if (itm->type == QOptionTreeItem::Option) { + QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm); + const ppd_option_t *opt = static_cast<const ppd_option_t*>(itm->ptr); + + if (qstrcmp(opt->keyword, "ColorModel") == 0) + printer->setColorMode(qstrcmp(opt->choices[itmOption->selected].choice, "Gray") == 0 ? QPrinter::GrayScale : QPrinter::Color); + + if (qstrcmp(opt->defchoice, opt->choices[itmOption->selected].choice) != 0) { + QCUPSSupport::setCupsOption(printer, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); + } + } else { + setCupsOptionsFromItems(printer, itm); + } + } +} + +void QPPDOptionsModel::parseGroups(QOptionTreeItem *parent) +{ + const ppd_group_t *group = static_cast<const ppd_group_t*>(parent->ptr); + + if (group) { + for (int i = 0; i < group->num_subgroups; ++i) { + if (!isBlacklistedGroup(&group->subgroups[i])) { + QOptionTreeItem *subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], parent); + parent->childItems.append(subgroup); + parseGroups(subgroup); // parse possible subgroups + parseOptions(subgroup); // parse options + } + } + } +} + +static bool isBlacklistedOption(const char *keyword) Q_DECL_NOTHROW +{ + // We already let the user set these options elsewhere + const char *cupsOptionBlacklist[] = { + "Collate", + "Copies", + "OutputOrder", + "PageRegion", + "PageSize", + "Duplex" // handled by the main dialog + }; + auto equals = [](const char *keyword) { + return [keyword](const char *candidate) { + return qstrcmp(keyword, candidate) == 0; + }; + }; + return std::any_of(std::begin(cupsOptionBlacklist), std::end(cupsOptionBlacklist), equals(keyword)); +}; + +void QPPDOptionsModel::parseOptions(QOptionTreeItem *parent) +{ + const ppd_group_t *group = static_cast<const ppd_group_t*>(parent->ptr); + for (int i = 0; i < group->num_options; ++i) { + if (!isBlacklistedOption(group->options[i].keyword)) { + QOptionTreeItemOption *opt = new QOptionTreeItemOption(i, &group->options[i], parent); + parseChoices(opt); + + // Don't show options that are actually not options at all + // because they don't give the user any choice + if (opt->childItems.count() > 1) + parent->childItems.append(opt); + else + delete opt; + } + } +} + +void QPPDOptionsModel::parseChoices(QOptionTreeItemOption *parent) +{ + const ppd_option_t *option = static_cast<const ppd_option_t*>(parent->ptr); + bool marked = false; + for (int i = 0; i < option->num_choices; ++i) { + const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(option->choices[i].choice); + if (!m_currentPrintDevice->isFeatureAvailable(PDPK_PpdChoiceIsInstallableConflict, values)) { + QOptionTreeItem *choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], parent); + if (static_cast<int>(option->choices[i].marked) == 1) { + parent->selected = i; + marked = true; + } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) { + parent->selected = i; + } + parent->originallySelected = parent->selected; + parent->childItems.append(choice); + } + } +} + +bool QPPDOptionsModel::hasConflicts() const +{ + return hasConflicts(m_rootItem); +} + +bool QPPDOptionsModel::hasConflicts(QOptionTreeItem *item) const +{ + if (item->type == QOptionTreeItem::Option) { + const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr); + return option->conflicted; + } + + for (QOptionTreeItem *child : qAsConst(item->childItems)) { + if (hasConflicts(child)) + return true; + } + + return false; +} + +void QPPDOptionsModel::emitConflictsChanged() +{ + bool conflictsFound = false; + emitDataChanged(m_rootItem, QModelIndex(), &conflictsFound); + + emit hasConflictsChanged(conflictsFound); +} + +void QPPDOptionsModel::emitDataChanged(QOptionTreeItem *item, const QModelIndex &itemIndex, bool *conflictsFound) +{ + if (item->type == QOptionTreeItem::Option) { + // We just emit DecorationRole dataChanged for all the leaves + // and let the view requery the value + const QModelIndex secondColItem = index(itemIndex.row(), 1, itemIndex.parent()); + emit dataChanged(secondColItem, secondColItem, QVector<int>() << Qt::DecorationRole); + + if (conflictsFound && *conflictsFound == false) { + const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr); + if (option->conflicted && conflictsFound) + *conflictsFound = true; + } + } + + for (int i = 0; i < item->childItems.count(); ++i) { + QOptionTreeItem *child = item->childItems.at(i); + emitDataChanged(child, index(i, 0, itemIndex), conflictsFound); + } +} + +QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return QVariant(tr("Name")); + case 1: + return QVariant(tr("Value")); + } + + return QVariant(); +} + +void QPPDOptionsModel::revertToSavedValues() +{ + revertToSavedValues(m_rootItem); + emitConflictsChanged(); +} + +void QPPDOptionsModel::revertToSavedValues(QOptionTreeItem *item) +{ + if (item->type == QOptionTreeItem::Option) { + QOptionTreeItemOption *itemOption = static_cast<QOptionTreeItemOption *>(item); + + const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr); + const char *choice = itemOption->originallySelected != -1 ? option->choices[itemOption->originallySelected].choice + : option->defchoice; + const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(choice); + m_currentPrintDevice->setProperty(PDPK_PpdOption, values); + itemOption->selected = itemOption->originallySelected; + } + + for (QOptionTreeItem *child : qAsConst(item->childItems)) + revertToSavedValues(child); +} + +void QPPDOptionsModel::updateSavedValues() +{ + updateSavedValues(m_rootItem); +} + +void QPPDOptionsModel::updateSavedValues(QOptionTreeItem *item) +{ + if (item->type == QOptionTreeItem::Option) { + QOptionTreeItemOption *itemOption = static_cast<QOptionTreeItemOption *>(item); + itemOption->originallySelected = itemOption->selected; + } + + for (QOptionTreeItem *child : qAsConst(item->childItems)) + updateSavedValues(child); +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/* + + QPPDOptionsEditor + + Edits the PPD Options for the printer. + +*/ + +QWidget *QPPDOptionsEditor::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + + if (index.column() == 1 && static_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Option) + return new QComboBox(parent); + + return nullptr; +} + +void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if (index.column() != 1) + return; + + QComboBox *cb = static_cast<QComboBox*>(editor); + QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer()); + + if (itm->selected == -1) + cb->addItem(QString()); + + const QPPDOptionsModel *m = static_cast<const QPPDOptionsModel*>(index.model()); + for (auto *childItem : qAsConst(itm->childItems)) { + const ppd_choice_t *choice = static_cast<const ppd_choice_t*>(childItem->ptr); + cb->addItem(m->cupsCodec()->toUnicode(choice->text), childItem->index); + if (childItem->index == itm->selected) + cb->setCurrentIndex(cb->count() - 1); + } +} + +void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QComboBox *cb = static_cast<QComboBox*>(editor); + QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer()); + + // We can't use cb->currentIndex() to know the index of the option in the choices[] array + // because some of them may not be present in the list because they conflict with the + // installable options so use the index passed on addItem + const int selectedChoiceIndex = cb->currentData().toInt(); + + if (itm->selected == selectedChoiceIndex || selectedChoiceIndex < 0) + return; + + const ppd_option_t *opt = static_cast<const ppd_option_t*>(itm->ptr); + QPPDOptionsModel *m = static_cast<QPPDOptionsModel*>(model); + + const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[selectedChoiceIndex].choice); + m->currentPrintDevice()->setProperty(PDPK_PpdOption, values); + itm->selected = selectedChoiceIndex; + + m->emitConflictsChanged(); +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#endif // QT_CONFIG(cups) #endif // defined (Q_OS_UNIX) QT_END_NAMESPACE diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index 906cb19043..a4f721fbc8 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -79,7 +79,7 @@ class QPrintPreviewMainWindow : public QMainWindow { public: QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {} - QMenu *createPopupMenu() Q_DECL_OVERRIDE { return nullptr; } + QMenu *createPopupMenu() override { return nullptr; } }; class ZoomFactorValidator : public QDoubleValidator @@ -90,7 +90,7 @@ public: ZoomFactorValidator(qreal bottom, qreal top, int decimals, QObject *parent) : QDoubleValidator(bottom, top, decimals, parent) {} - State validate(QString &input, int &pos) const Q_DECL_OVERRIDE + State validate(QString &input, int &pos) const override { bool replacePercent = false; if (input.endsWith(QLatin1Char('%'))) { @@ -123,13 +123,13 @@ public: } protected: - void focusInEvent(QFocusEvent *e) Q_DECL_OVERRIDE + void focusInEvent(QFocusEvent *e) override { origText = text(); QLineEdit::focusInEvent(e); } - void focusOutEvent(QFocusEvent *e) Q_DECL_OVERRIDE + void focusOutEvent(QFocusEvent *e) override { if (isModified() && !hasAcceptableInput()) setText(origText); @@ -484,7 +484,7 @@ void QPrintPreviewDialogPrivate::updatePageNumLabel() int numPages = preview->pageCount(); int maxChars = QString::number(numPages).length(); pageNumLabel->setText(QString::fromLatin1("/ %1").arg(numPages)); - int cyphersWidth = q->fontMetrics().width(QString().fill(QLatin1Char('8'), maxChars)); + int cyphersWidth = q->fontMetrics().horizontalAdvance(QString().fill(QLatin1Char('8'), maxChars)); int maxWidth = pageNumEdit->minimumSizeHint().width() + cyphersWidth; pageNumEdit->setMinimumWidth(maxWidth); pageNumEdit->setMaximumWidth(maxWidth); diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h index bacafcb734..53fede7e83 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.h +++ b/src/printsupport/dialogs/qprintpreviewdialog.h @@ -68,8 +68,8 @@ public: QPrinter *printer(); - void setVisible(bool visible) Q_DECL_OVERRIDE; - void done(int result) Q_DECL_OVERRIDE; + void setVisible(bool visible) override; + void done(int result) override; Q_SIGNALS: void paintRequested(QPrinter *printer); diff --git a/src/printsupport/dialogs/qprintpropertieswidget.ui b/src/printsupport/dialogs/qprintpropertieswidget.ui index 66d7b80fcd..d8e526139b 100644 --- a/src/printsupport/dialogs/qprintpropertieswidget.ui +++ b/src/printsupport/dialogs/qprintpropertieswidget.ui @@ -14,7 +14,16 @@ <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout_4"> - <property name="margin"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> <number>0</number> </property> <item> @@ -32,6 +41,64 @@ </item> </layout> </widget> + <widget class="QWidget" name="cupsPropertiesPage"> + <attribute name="title"> + <string>Advanced</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTreeView" name="treeView"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="conflictsLabel"> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>165</red> + <green>167</green> + <blue>169</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="text"> + <string>There are conflicts in some options. Please fix them.</string> + </property> + </widget> + </item> + </layout> + </widget> </widget> </item> </layout> diff --git a/src/printsupport/dialogs/qprintsettingsoutput.ui b/src/printsupport/dialogs/qprintsettingsoutput.ui index 0fa34ab27f..290111a98c 100644 --- a/src/printsupport/dialogs/qprintsettingsoutput.ui +++ b/src/printsupport/dialogs/qprintsettingsoutput.ui @@ -6,15 +6,24 @@ <rect> <x>0</x> <y>0</y> - <width>426</width> - <height>187</height> + <width>432</width> + <height>251</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="margin"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> <number>0</number> </property> <item> @@ -42,7 +51,16 @@ <property name="spacing"> <number>4</number> </property> - <property name="margin"> + <property name="leftMargin"> + <number>6</number> + </property> + <property name="topMargin"> + <number>6</number> + </property> + <property name="rightMargin"> + <number>6</number> + </property> + <property name="bottomMargin"> <number>6</number> </property> <item> @@ -60,7 +78,16 @@ <property name="spacing"> <number>6</number> </property> - <property name="margin"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> <number>0</number> </property> <item> @@ -119,6 +146,27 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="pagesLayout"> + <item> + <widget class="QRadioButton" name="pagesRadioButton"> + <property name="text"> + <string>Pages</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="pagesLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Specify pages or ranges separated by commas. Ranges are specified by two numbers separated by a hyphen. E.g: 3,5-7,9 prints pages 3, 5, 6, 7 and 9.</string> + </property> + </widget> + </item> + </layout> + </item> + <item> <widget class="QRadioButton" name="printCurrentPage"> <property name="text"> <string>Current Page</string> @@ -361,12 +409,12 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>76</x> - <y>59</y> + <x>89</x> + <y>113</y> </hint> <hint type="destinationlabel"> - <x>122</x> - <y>57</y> + <x>182</x> + <y>113</y> </hint> </hints> </connection> @@ -377,12 +425,28 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>69</x> - <y>67</y> + <x>82</x> + <y>113</y> + </hint> + <hint type="destinationlabel"> + <x>267</x> + <y>113</y> + </hint> + </hints> + </connection> + <connection> + <sender>pagesRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>pagesLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>58</x> + <y>132</y> </hint> <hint type="destinationlabel"> - <x>215</x> - <y>67</y> + <x>163</x> + <y>128</y> </hint> </hints> </connection> diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index b9e162abe9..be170ed619 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -43,33 +43,37 @@ QT_BEGIN_NAMESPACE -QStringList QCUPSSupport::cupsOptionsList(QPrinter *printer) +static QStringList cupsOptionsList(QPrinter *printer) Q_DECL_NOTHROW { return printer->printEngine()->property(PPK_CupsOptions).toStringList(); } -void QCUPSSupport::setCupsOptions(QPrinter *printer, const QStringList &cupsOptions) +void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions) Q_DECL_NOTHROW { printer->printEngine()->setProperty(PPK_CupsOptions, QVariant(cupsOptions)); } -void QCUPSSupport::setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value) +void QCUPSSupport::setCupsOption(QPrinter *printer, const QString &option, const QString &value) { + QStringList cupsOptions = cupsOptionsList(printer); if (cupsOptions.contains(option)) { cupsOptions.replace(cupsOptions.indexOf(option) + 1, value); } else { cupsOptions.append(option); cupsOptions.append(value); } + setCupsOptions(printer, cupsOptions); } -void QCUPSSupport::clearCupsOption(QStringList &cupsOptions, const QString &option) +void QCUPSSupport::clearCupsOption(QPrinter *printer, const QString &option) { + QStringList cupsOptions = cupsOptionsList(printer); // ### use const_iterator once QList::erase takes them const QStringList::iterator it = std::find(cupsOptions.begin(), cupsOptions.end(), option); if (it != cupsOptions.end()) { Q_ASSERT(it + 1 < cupsOptions.end()); cupsOptions.erase(it, it+1); + setCupsOptions(printer, cupsOptions); } } @@ -107,32 +111,57 @@ static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, return QString(); } +QCUPSSupport::JobHoldUntilWithTime QCUPSSupport::parseJobHoldUntil(const QString &jobHoldUntil) +{ + if (jobHoldUntil == QLatin1String("indefinite")) { + return { QCUPSSupport::Indefinite, QTime() }; + } else if (jobHoldUntil == QLatin1String("day-time")) { + return { QCUPSSupport::DayTime, QTime() }; + } else if (jobHoldUntil == QLatin1String("night")) { + return { QCUPSSupport::Night, QTime() }; + } else if (jobHoldUntil == QLatin1String("second-shift")) { + return { QCUPSSupport::SecondShift, QTime() }; + } else if (jobHoldUntil == QLatin1String("third-shift")) { + return { QCUPSSupport::ThirdShift, QTime() }; + } else if (jobHoldUntil == QLatin1String("weekend")) { + return { QCUPSSupport::Weekend, QTime() }; + } + + + QTime parsedTime = QTime::fromString(jobHoldUntil, QStringLiteral("h:m:s")); + if (!parsedTime.isValid()) + parsedTime = QTime::fromString(jobHoldUntil, QStringLiteral("h:m")); + if (parsedTime.isValid()) { + // CUPS time is in UTC, user expects local time, so get the equivalent + QDateTime dateTimeUtc = QDateTime::currentDateTimeUtc(); + dateTimeUtc.setTime(parsedTime); + return { QCUPSSupport::SpecificTime, dateTimeUtc.toLocalTime().time() }; + } + + return { QCUPSSupport::NoHold, QTime() }; +} + + void QCUPSSupport::setJobHold(QPrinter *printer, const JobHoldUntil jobHold, const QTime &holdUntilTime) { - QStringList cupsOptions = cupsOptionsList(printer); const QString jobHoldUntilArgument = jobHoldToString(jobHold, holdUntilTime); if (!jobHoldUntilArgument.isEmpty()) { - setCupsOption(cupsOptions, + setCupsOption(printer, QStringLiteral("job-hold-until"), jobHoldUntilArgument); } else { - clearCupsOption(cupsOptions, QStringLiteral("job-hold-until")); + clearCupsOption(printer, QStringLiteral("job-hold-until")); } - setCupsOptions(printer, cupsOptions); } void QCUPSSupport::setJobBilling(QPrinter *printer, const QString &jobBilling) { - QStringList cupsOptions = cupsOptionsList(printer); - setCupsOption(cupsOptions, QStringLiteral("job-billing"), jobBilling); - setCupsOptions(printer, cupsOptions); + setCupsOption(printer, QStringLiteral("job-billing"), jobBilling); } void QCUPSSupport::setJobPriority(QPrinter *printer, int priority) { - QStringList cupsOptions = cupsOptionsList(printer); - setCupsOption(cupsOptions, QStringLiteral("job-priority"), QString::number(priority)); - setCupsOptions(printer, cupsOptions); + setCupsOption(printer, QStringLiteral("job-priority"), QString::number(priority)); } static inline QString bannerPageToString(const QCUPSSupport::BannerPage bannerPage) @@ -150,19 +179,42 @@ static inline QString bannerPageToString(const QCUPSSupport::BannerPage bannerPa return QString(); } +static inline QCUPSSupport::BannerPage stringToBannerPage(const QString &bannerPage) +{ + if (bannerPage == QLatin1String("none")) return QCUPSSupport::NoBanner; + else if (bannerPage == QLatin1String("standard")) return QCUPSSupport::Standard; + else if (bannerPage == QLatin1String("unclassified")) return QCUPSSupport::Unclassified; + else if (bannerPage == QLatin1String("confidential")) return QCUPSSupport::Confidential; + else if (bannerPage == QLatin1String("classified")) return QCUPSSupport::Classified; + else if (bannerPage == QLatin1String("secret")) return QCUPSSupport::Secret; + else if (bannerPage == QLatin1String("topsecret")) return QCUPSSupport::TopSecret; + + return QCUPSSupport::NoBanner; +} + +QCUPSSupport::JobSheets QCUPSSupport::parseJobSheets(const QString &jobSheets) +{ + JobSheets result; + + const QStringList parts = jobSheets.split(QLatin1Char(',')); + if (parts.count() == 2) { + result.startBannerPage = stringToBannerPage(parts[0]); + result.endBannerPage = stringToBannerPage(parts[1]); + } + + return result; +} + void QCUPSSupport::setBannerPages(QPrinter *printer, const BannerPage startBannerPage, const BannerPage endBannerPage) { - QStringList cupsOptions = cupsOptionsList(printer); const QString startBanner = bannerPageToString(startBannerPage); const QString endBanner = bannerPageToString(endBannerPage); - setCupsOption(cupsOptions, QStringLiteral("job-sheets"), startBanner + QLatin1Char(',') + endBanner); - setCupsOptions(printer, cupsOptions); + setCupsOption(printer, QStringLiteral("job-sheets"), startBanner + QLatin1Char(',') + endBanner); } void QCUPSSupport::setPageSet(QPrinter *printer, const PageSet pageSet) { - QStringList cupsOptions = cupsOptionsList(printer); QString pageSetString; switch (pageSet) { @@ -177,29 +229,29 @@ void QCUPSSupport::setPageSet(QPrinter *printer, const PageSet pageSet) break; } - setCupsOption(cupsOptions, QStringLiteral("page-set"), pageSetString); - setCupsOptions(printer, cupsOptions); + setCupsOption(printer, QStringLiteral("page-set"), pageSetString); } void QCUPSSupport::setPagesPerSheetLayout(QPrinter *printer, const PagesPerSheet pagesPerSheet, const PagesPerSheetLayout pagesPerSheetLayout) { - QStringList cupsOptions = cupsOptionsList(printer); // WARNING: the following trick (with a [2]-extent) only works as // WARNING: long as there's only one two-digit number in the list // WARNING: and it is the last one (before the "\0")! static const char pagesPerSheetData[][2] = { "1", "2", "4", "6", "9", {'1', '6'}, "\0" }; static const char pageLayoutData[][5] = {"lrtb", "lrbt", "rlbt", "rltb", "btlr", "btrl", "tblr", "tbrl"}; - setCupsOption(cupsOptions, QStringLiteral("number-up"), QLatin1String(pagesPerSheetData[pagesPerSheet])); - setCupsOption(cupsOptions, QStringLiteral("number-up-layout"), QLatin1String(pageLayoutData[pagesPerSheetLayout])); - setCupsOptions(printer, cupsOptions); + setCupsOption(printer, QStringLiteral("number-up"), QLatin1String(pagesPerSheetData[pagesPerSheet])); + setCupsOption(printer, QStringLiteral("number-up-layout"), QLatin1String(pageLayoutData[pagesPerSheetLayout])); } void QCUPSSupport::setPageRange(QPrinter *printer, int pageFrom, int pageTo) { - QStringList cupsOptions = cupsOptionsList(printer); - setCupsOption(cupsOptions, QStringLiteral("page-ranges"), QStringLiteral("%1-%2").arg(pageFrom).arg(pageTo)); - setCupsOptions(printer, cupsOptions); + setPageRange(printer, QStringLiteral("%1-%2").arg(pageFrom).arg(pageTo)); +} + +void QCUPSSupport::setPageRange(QPrinter *printer, const QString &pageRange) +{ + setCupsOption(printer, QStringLiteral("page-ranges"), pageRange); } QT_END_NAMESPACE diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index 780115e350..da2b087d5b 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -67,6 +67,14 @@ QT_BEGIN_NAMESPACE // removed from the dialogs. #define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00) +#define PDPK_PpdFile QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase) +#define PDPK_PpdOption QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 1) +#define PDPK_CupsJobPriority QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 2) +#define PDPK_CupsJobSheets QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 3) +#define PDPK_CupsJobBilling QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 4) +#define PDPK_CupsJobHoldUntil QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 5) +#define PDPK_PpdChoiceIsInstallableConflict QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 6) + class Q_PRINTSUPPORT_EXPORT QCUPSSupport { public: @@ -122,10 +130,8 @@ public: TopToBottomRightToLeft }; - static QStringList cupsOptionsList(QPrinter *printer); - static void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions); - static void setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value); - static void clearCupsOption(QStringList &cupsOptions, const QString &option); + static void setCupsOption(QPrinter *printer, const QString &option, const QString &value); + static void clearCupsOption(QPrinter *printer, const QString &option); static void setJobHold(QPrinter *printer, const JobHoldUntil jobHold = NoHold, const QTime &holdUntilTime = QTime()); static void setJobBilling(QPrinter *printer, const QString &jobBilling = QString()); @@ -135,6 +141,27 @@ public: static void setPagesPerSheetLayout(QPrinter *printer, const PagesPerSheet pagesPerSheet, const PagesPerSheetLayout pagesPerSheetLayout); static void setPageRange(QPrinter *printer, int pageFrom, int pageTo); + static void setPageRange(QPrinter *printer, const QString &pageRange); + + struct JobSheets + { + JobSheets(BannerPage s = NoBanner, BannerPage e = NoBanner) + : startBannerPage(s), endBannerPage(e) {} + + BannerPage startBannerPage; + BannerPage endBannerPage; + }; + static JobSheets parseJobSheets(const QString &jobSheets); + + struct JobHoldUntilWithTime + { + JobHoldUntilWithTime(JobHoldUntil jh = NoHold, const QTime &t = QTime()) + : jobHold(jh), time(t) {} + + JobHoldUntil jobHold; + QTime time; + }; + static JobHoldUntilWithTime parseJobHoldUntil(const QString &jobHoldUntil); }; Q_DECLARE_TYPEINFO(QCUPSSupport::JobHoldUntil, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(QCUPSSupport::BannerPage, Q_PRIMITIVE_TYPE); diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index cae5c2f522..410051df2a 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -306,15 +306,12 @@ void QAlphaPaintEngine::flushAndInit(bool init) d->m_alphargn = d->m_alphargn.intersected(QRect(0, 0, d->m_pdev->width(), d->m_pdev->height())); // just use the bounding rect if it's a complex region.. - QVector<QRect> rects = d->m_alphargn.rects(); - if (rects.size() > 10) { + if (d->m_alphargn.rectCount() > 10) { QRect br = d->m_alphargn.boundingRect(); d->m_alphargn = QRegion(br); - rects.clear(); - rects.append(br); } - d->m_cliprgn = d->m_alphargn; + const auto oldAlphaRegion = d->m_cliprgn = d->m_alphargn; // now replay the QPicture ++d->m_pass; // we are now doing pass #2 @@ -336,7 +333,7 @@ void QAlphaPaintEngine::flushAndInit(bool init) d->resetState(painter()); // fill in the alpha images - for (const auto &rect : qAsConst(rects)) + for (const auto &rect : oldAlphaRegion) d->drawAlphaImage(rect); d->m_alphargn = QRegion(); diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index e2d4a08de3..8dba402a6e 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -167,7 +167,7 @@ QList<QPageSize> QPlatformPrintDevice::supportedPageSizes() const { if (!m_havePageSizes) loadPageSizes(); - return m_pageSizes.toList(); + return m_pageSizes; } QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) const @@ -293,7 +293,7 @@ QList<int> QPlatformPrintDevice::supportedResolutions() const { if (!m_haveResolutions) loadResolutions(); - return m_resolutions.toList(); + return m_resolutions; } void QPlatformPrintDevice::loadInputSlots() const @@ -313,11 +313,11 @@ QPrint::InputSlot QPlatformPrintDevice::defaultInputSlot() const return input; } -QList<QPrint::InputSlot> QPlatformPrintDevice::supportedInputSlots() const +QVector<QPrint::InputSlot> QPlatformPrintDevice::supportedInputSlots() const { if (!m_haveInputSlots) loadInputSlots(); - return m_inputSlots.toList(); + return m_inputSlots; } void QPlatformPrintDevice::loadOutputBins() const @@ -337,11 +337,11 @@ QPrint::OutputBin QPlatformPrintDevice::defaultOutputBin() const return output; } -QList<QPrint::OutputBin> QPlatformPrintDevice::supportedOutputBins() const +QVector<QPrint::OutputBin> QPlatformPrintDevice::supportedOutputBins() const { if (!m_haveOutputBins) loadOutputBins(); - return m_outputBins.toList(); + return m_outputBins; } void QPlatformPrintDevice::loadDuplexModes() const @@ -353,11 +353,11 @@ QPrint::DuplexMode QPlatformPrintDevice::defaultDuplexMode() const return QPrint::DuplexNone; } -QList<QPrint::DuplexMode> QPlatformPrintDevice::supportedDuplexModes() const +QVector<QPrint::DuplexMode> QPlatformPrintDevice::supportedDuplexModes() const { if (!m_haveDuplexModes) loadDuplexModes(); - return m_duplexModes.toList(); + return m_duplexModes; } void QPlatformPrintDevice::loadColorModes() const @@ -369,11 +369,11 @@ QPrint::ColorMode QPlatformPrintDevice::defaultColorMode() const return QPrint::GrayScale; } -QList<QPrint::ColorMode> QPlatformPrintDevice::supportedColorModes() const +QVector<QPrint::ColorMode> QPlatformPrintDevice::supportedColorModes() const { if (!m_haveColorModes) loadColorModes(); - return m_colorModes.toList(); + return m_colorModes; } #ifndef QT_NO_MIMETYPE @@ -381,11 +381,34 @@ void QPlatformPrintDevice::loadMimeTypes() const { } +QVariant QPlatformPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) const +{ + Q_UNUSED(key) + + return QVariant(); +} + +bool QPlatformPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key, const QVariant &value) +{ + Q_UNUSED(key) + Q_UNUSED(value) + + return false; +} + +bool QPlatformPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key, const QVariant ¶ms) const +{ + Q_UNUSED(key) + Q_UNUSED(params) + + return false; +} + QList<QMimeType> QPlatformPrintDevice::supportedMimeTypes() const { if (!m_haveMimeTypes) loadMimeTypes(); - return m_mimeTypes.toList(); + return m_mimeTypes; } #endif // QT_NO_MIMETYPE diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h index 44a3a966f4..a988518547 100644 --- a/src/printsupport/kernel/qplatformprintdevice.h +++ b/src/printsupport/kernel/qplatformprintdevice.h @@ -53,11 +53,14 @@ #include <QtPrintSupport/qtprintsupportglobal.h> #include <private/qprint_p.h> +#include <private/qprintdevice_p.h> +#include <QtCore/qvariant.h> #include <QtCore/qvector.h> #include <QtCore/qmimetype.h> #include <QtGui/qpagelayout.h> + QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER @@ -107,16 +110,20 @@ public: virtual QList<int> supportedResolutions() const; virtual QPrint::InputSlot defaultInputSlot() const; - virtual QList<QPrint::InputSlot> supportedInputSlots() const; + virtual QVector<QPrint::InputSlot> supportedInputSlots() const; virtual QPrint::OutputBin defaultOutputBin() const; - virtual QList<QPrint::OutputBin> supportedOutputBins() const; + virtual QVector<QPrint::OutputBin> supportedOutputBins() const; virtual QPrint::DuplexMode defaultDuplexMode() const; - virtual QList<QPrint::DuplexMode> supportedDuplexModes() const; + virtual QVector<QPrint::DuplexMode> supportedDuplexModes() const; virtual QPrint::ColorMode defaultColorMode() const; - virtual QList<QPrint::ColorMode> supportedColorModes() const; + virtual QVector<QPrint::ColorMode> supportedColorModes() const; + + virtual QVariant property(QPrintDevice::PrintDevicePropertyKey key) const; + virtual bool setProperty(QPrintDevice::PrintDevicePropertyKey key, const QVariant &value); + virtual bool isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key, const QVariant ¶ms) const; #ifndef QT_NO_MIMETYPE virtual QList<QMimeType> supportedMimeTypes() const; @@ -149,7 +156,7 @@ protected: bool m_supportsCollateCopies; mutable bool m_havePageSizes; - mutable QVector<QPageSize> m_pageSizes; + mutable QList<QPageSize> m_pageSizes; bool m_supportsCustomPageSizes; @@ -157,7 +164,7 @@ protected: QSize m_maximumPhysicalPageSize; mutable bool m_haveResolutions; - mutable QVector<int> m_resolutions; + mutable QList<int> m_resolutions; mutable bool m_haveInputSlots; mutable QVector<QPrint::InputSlot> m_inputSlots; @@ -173,7 +180,7 @@ protected: #ifndef QT_NO_MIMETYPE mutable bool m_haveMimeTypes; - mutable QVector<QMimeType> m_mimeTypes; + mutable QList<QMimeType> m_mimeTypes; #endif }; diff --git a/src/printsupport/kernel/qprint_p.h b/src/printsupport/kernel/qprint_p.h index 280c2d7608..4956775461 100644 --- a/src/printsupport/kernel/qprint_p.h +++ b/src/printsupport/kernel/qprint_p.h @@ -59,6 +59,7 @@ #if (defined Q_OS_MACOS) || (defined Q_OS_UNIX && QT_CONFIG(cups)) #include <cups/ppd.h> // Use for type defs only, don't want to actually link in main module +Q_DECLARE_METATYPE(ppd_file_t *) #endif QT_BEGIN_NAMESPACE diff --git a/src/printsupport/kernel/qprintdevice.cpp b/src/printsupport/kernel/qprintdevice.cpp index 26799a6f13..50fc14169d 100644 --- a/src/printsupport/kernel/qprintdevice.cpp +++ b/src/printsupport/kernel/qprintdevice.cpp @@ -210,9 +210,9 @@ QPrint::InputSlot QPrintDevice::defaultInputSlot() const return isValid() ? d->defaultInputSlot() : QPrint::InputSlot(); } -QList<QPrint::InputSlot> QPrintDevice::supportedInputSlots() const +QVector<QPrint::InputSlot> QPrintDevice::supportedInputSlots() const { - return isValid() ? d->supportedInputSlots() : QList<QPrint::InputSlot>(); + return isValid() ? d->supportedInputSlots() : QVector<QPrint::InputSlot>{}; } QPrint::OutputBin QPrintDevice::defaultOutputBin() const @@ -220,9 +220,9 @@ QPrint::OutputBin QPrintDevice::defaultOutputBin() const return isValid() ? d->defaultOutputBin() : QPrint::OutputBin(); } -QList<QPrint::OutputBin> QPrintDevice::supportedOutputBins() const +QVector<QPrint::OutputBin> QPrintDevice::supportedOutputBins() const { - return isValid() ? d->supportedOutputBins() : QList<QPrint::OutputBin>(); + return isValid() ? d->supportedOutputBins() : QVector<QPrint::OutputBin>{}; } QPrint::DuplexMode QPrintDevice::defaultDuplexMode() const @@ -230,9 +230,9 @@ QPrint::DuplexMode QPrintDevice::defaultDuplexMode() const return isValid() ? d->defaultDuplexMode() : QPrint::DuplexNone; } -QList<QPrint::DuplexMode> QPrintDevice::supportedDuplexModes() const +QVector<QPrint::DuplexMode> QPrintDevice::supportedDuplexModes() const { - return isValid() ? d->supportedDuplexModes() : QList<QPrint::DuplexMode>(); + return isValid() ? d->supportedDuplexModes() : QVector<QPrint::DuplexMode>{}; } QPrint::ColorMode QPrintDevice::defaultColorMode() const @@ -240,9 +240,24 @@ QPrint::ColorMode QPrintDevice::defaultColorMode() const return isValid() ? d->defaultColorMode() : QPrint::GrayScale; } -QList<QPrint::ColorMode> QPrintDevice::supportedColorModes() const +QVector<QPrint::ColorMode> QPrintDevice::supportedColorModes() const { - return isValid() ? d->supportedColorModes() : QList<QPrint::ColorMode>(); + return isValid() ? d->supportedColorModes() : QVector<QPrint::ColorMode>{}; +} + +QVariant QPrintDevice::property(PrintDevicePropertyKey key) const +{ + return isValid() ? d->property(key) : QVariant(); +} + +bool QPrintDevice::setProperty(PrintDevicePropertyKey key, const QVariant &value) +{ + return isValid() ? d->setProperty(key, value) : false; +} + +bool QPrintDevice::isFeatureAvailable(PrintDevicePropertyKey key, const QVariant ¶ms) const +{ + return isValid() ? d->isFeatureAvailable(key, params) : false; } #ifndef QT_NO_MIMETYPE diff --git a/src/printsupport/kernel/qprintdevice_p.h b/src/printsupport/kernel/qprintdevice_p.h index 1e0d3983e9..562ccd2057 100644 --- a/src/printsupport/kernel/qprintdevice_p.h +++ b/src/printsupport/kernel/qprintdevice_p.h @@ -120,16 +120,24 @@ public: QList<int> supportedResolutions() const; QPrint::InputSlot defaultInputSlot() const; - QList<QPrint::InputSlot> supportedInputSlots() const; + QVector<QPrint::InputSlot> supportedInputSlots() const; QPrint::OutputBin defaultOutputBin() const; - QList<QPrint::OutputBin> supportedOutputBins() const; + QVector<QPrint::OutputBin> supportedOutputBins() const; QPrint::DuplexMode defaultDuplexMode() const; - QList<QPrint::DuplexMode> supportedDuplexModes() const; + QVector<QPrint::DuplexMode> supportedDuplexModes() const; QPrint::ColorMode defaultColorMode() const; - QList<QPrint::ColorMode> supportedColorModes() const; + QVector<QPrint::ColorMode> supportedColorModes() const; + + enum PrintDevicePropertyKey { + PDPK_CustomBase = 0xff00 + }; + + QVariant property(PrintDevicePropertyKey key) const; + bool setProperty(PrintDevicePropertyKey key, const QVariant &value); + bool isFeatureAvailable(PrintDevicePropertyKey key, const QVariant ¶ms) const; #ifndef QT_NO_MIMETYPE QList<QMimeType> supportedMimeTypes() const; diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp index 873e146eec..0230ebddc8 100644 --- a/src/printsupport/kernel/qprintengine_pdf.cpp +++ b/src/printsupport/kernel/qprintengine_pdf.cpp @@ -374,7 +374,7 @@ void QPdfPrintEnginePrivate::closePrintDevice() if (outDevice) { outDevice->close(); if (fd >= 0) - #if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 + #if defined(Q_OS_WIN) && defined(Q_CC_MSVC) ::_close(fd); #else ::close(fd); diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h index e9e81bdf68..bb01a2e9e1 100644 --- a/src/printsupport/kernel/qprintengine_pdf_p.h +++ b/src/printsupport/kernel/qprintengine_pdf_p.h @@ -87,18 +87,18 @@ public: virtual ~QPdfPrintEngine(); // reimplementations QPaintEngine - bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE; - bool end() Q_DECL_OVERRIDE; + bool begin(QPaintDevice *pdev) override; + bool end() override; // end reimplementations QPaintEngine // reimplementations QPrintEngine - bool abort() Q_DECL_OVERRIDE {return false;} - QPrinter::PrinterState printerState() const Q_DECL_OVERRIDE {return state;} + bool abort() override {return false;} + QPrinter::PrinterState printerState() const override {return state;} - bool newPage() Q_DECL_OVERRIDE; - int metric(QPaintDevice::PaintDeviceMetric) const Q_DECL_OVERRIDE; - virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value) Q_DECL_OVERRIDE; - virtual QVariant property(PrintEnginePropertyKey key) const Q_DECL_OVERRIDE; + bool newPage() override; + int metric(QPaintDevice::PaintDeviceMetric) const override; + virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value) override; + virtual QVariant property(PrintEnginePropertyKey key) const override; // end reimplementations QPrintEngine QPrinter::PrinterState state; diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index b479ecacb1..a943d24cb1 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -1024,7 +1024,7 @@ bool QWin32PrintEnginePrivate::resetDC() return hdc != 0; } -static int indexOfId(const QList<QPrint::InputSlot> &inputSlots, QPrint::InputSlotId id) +static int indexOfId(const QVector<QPrint::InputSlot> &inputSlots, QPrint::InputSlotId id) { for (int i = 0; i < inputSlots.size(); ++i) { if (inputSlots.at(i).id == id) @@ -1033,7 +1033,7 @@ static int indexOfId(const QList<QPrint::InputSlot> &inputSlots, QPrint::InputSl return -1; } -static int indexOfWindowsId(const QList<QPrint::InputSlot> &inputSlots, int windowsId) +static int indexOfWindowsId(const QVector<QPrint::InputSlot> &inputSlots, int windowsId) { for (int i = 0; i < inputSlots.size(); ++i) { if (inputSlots.at(i).windowsId == windowsId) @@ -1210,7 +1210,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & case PPK_PaperSource: { if (!d->devMode) break; - const QList<QPrint::InputSlot> inputSlots = d->m_printDevice.supportedInputSlots(); + const auto inputSlots = d->m_printDevice.supportedInputSlots(); const int paperSource = value.toInt(); const int index = paperSource >= DMBIN_USER ? indexOfWindowsId(inputSlots, paperSource) : indexOfId(inputSlots, QPrint::InputSlotId(paperSource)); @@ -1465,7 +1465,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (d->devMode->dmDefaultSource >= DMBIN_USER) { value = int(d->devMode->dmDefaultSource); } else { - const QList<QPrint::InputSlot> inputSlots = d->m_printDevice.supportedInputSlots(); + const auto inputSlots = d->m_printDevice.supportedInputSlots(); const int index = indexOfWindowsId(inputSlots, d->devMode->dmDefaultSource); value = index >= 0 ? inputSlots.at(index).id : QPrint::Auto; } diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index d439fcbbbc..8a2cdcb34f 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -231,7 +231,7 @@ public: virtual ~QPrinterPagedPaintDevicePrivate() {} - bool setPageLayout(const QPageLayout &newPageLayout) Q_DECL_OVERRIDE + bool setPageLayout(const QPageLayout &newPageLayout) override { if (pd->paintEngine->type() != QPaintEngine::Pdf && pd->printEngine->printerState() == QPrinter::Active) { @@ -248,7 +248,7 @@ public: return pageLayout().isEquivalentTo(newPageLayout); } - bool setPageSize(const QPageSize &pageSize) Q_DECL_OVERRIDE + bool setPageSize(const QPageSize &pageSize) override { if (pd->paintEngine->type() != QPaintEngine::Pdf && pd->printEngine->printerState() == QPrinter::Active) { @@ -266,7 +266,7 @@ public: return pageLayout().pageSize().isEquivalentTo(pageSize); } - bool setPageOrientation(QPageLayout::Orientation orientation) Q_DECL_OVERRIDE + bool setPageOrientation(QPageLayout::Orientation orientation) override { // Set the print engine value pd->setProperty(QPrintEngine::PPK_Orientation, orientation); @@ -277,12 +277,12 @@ public: return pageLayout().orientation() == orientation; } - bool setPageMargins(const QMarginsF &margins) Q_DECL_OVERRIDE + bool setPageMargins(const QMarginsF &margins) override { return setPageMargins(margins, pageLayout().units()); } - bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) Q_DECL_OVERRIDE + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override { // Try to set print engine margins QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(margins, units); @@ -294,7 +294,7 @@ public: return pageLayout().margins() == margins && pageLayout().units() == units; } - QPageLayout pageLayout() const Q_DECL_OVERRIDE + QPageLayout pageLayout() const override { return pd->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>(); } diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h index bfe2d346ae..28dca78a63 100644 --- a/src/printsupport/kernel/qprinter.h +++ b/src/printsupport/kernel/qprinter.h @@ -72,7 +72,7 @@ public: explicit QPrinter(const QPrinterInfo& printer, PrinterMode mode = ScreenResolution); ~QPrinter(); - int devType() const Q_DECL_OVERRIDE; + int devType() const override; enum Orientation { Portrait, Landscape }; @@ -170,10 +170,10 @@ public: void setOrientation(Orientation); Orientation orientation() const; - void setPageSize(PageSize) Q_DECL_OVERRIDE; + void setPageSize(PageSize) override; PageSize pageSize() const; - void setPageSizeMM(const QSizeF &size) Q_DECL_OVERRIDE; + void setPageSizeMM(const QSizeF &size) override; void setPaperSize(PaperSize); PaperSize paperSize() const; @@ -237,12 +237,12 @@ public: QString printerSelectionOption() const; void setPrinterSelectionOption(const QString &); - bool newPage() Q_DECL_OVERRIDE; + bool newPage() override; bool abort(); PrinterState printerState() const; - QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; + QPaintEngine *paintEngine() const override; QPrintEngine *printEngine() const; void setFromTo(int fromPage, int toPage); @@ -252,13 +252,13 @@ public: void setPrintRange(PrintRange range); PrintRange printRange() const; - void setMargins(const Margins &m) Q_DECL_OVERRIDE; + void setMargins(const Margins &m) override; void setPageMargins(qreal left, qreal top, qreal right, qreal bottom, Unit unit); void getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, Unit unit) const; protected: - int metric(PaintDeviceMetric) const Q_DECL_OVERRIDE; + int metric(PaintDeviceMetric) const override; void setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine); private: diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp index d271e069ad..49a0c9ece4 100644 --- a/src/printsupport/kernel/qprinterinfo.cpp +++ b/src/printsupport/kernel/qprinterinfo.cpp @@ -380,7 +380,7 @@ QList<QPrinter::DuplexMode> QPrinterInfo::supportedDuplexModes() const { Q_D(const QPrinterInfo); QList<QPrinter::DuplexMode> list; - const QList<QPrint::DuplexMode> supportedDuplexModes = d->m_printDevice.supportedDuplexModes(); + const auto supportedDuplexModes = d->m_printDevice.supportedDuplexModes(); list.reserve(supportedDuplexModes.size()); for (QPrint::DuplexMode mode : supportedDuplexModes) list << QPrinter::DuplexMode(mode); diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index 39acac020c..dcdb933f73 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -52,6 +52,8 @@ #include <QPrinter> #include <QPrintEngine> +#include <kernel/qprintdevice_p.h> + QT_BEGIN_NAMESPACE /*! @@ -64,25 +66,23 @@ QT_BEGIN_NAMESPACE \inmodule QtPrintSupport */ -QCupsJobWidget::QCupsJobWidget(QWidget *parent) - : QWidget(parent) +QCupsJobWidget::QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWidget *parent) + : QWidget(parent), + m_printer(printer), + m_printDevice(printDevice) { m_ui.setupUi(this); //set all the default values - //TODO restore last used values initJobHold(); initJobBilling(); initJobPriority(); initBannerPages(); -} -QCupsJobWidget::~QCupsJobWidget() -{ + updateSavedValues(); } -void QCupsJobWidget::setPrinter(QPrinter *printer) +QCupsJobWidget::~QCupsJobWidget() { - m_printer = printer; } void QCupsJobWidget::setupPrinter() @@ -93,6 +93,27 @@ void QCupsJobWidget::setupPrinter() QCUPSSupport::setBannerPages(m_printer, startBannerPage(), endBannerPage()); } +void QCupsJobWidget::updateSavedValues() +{ + m_savedJobHoldWithTime = { jobHold(), jobHoldTime() }; + m_savedJobBilling = jobBilling(); + m_savedPriority = jobPriority(); + m_savedJobSheets = { startBannerPage(), endBannerPage() }; +} + +void QCupsJobWidget::revertToSavedValues() +{ + setJobHold(m_savedJobHoldWithTime.jobHold, m_savedJobHoldWithTime.time); + toggleJobHoldTime(); + + setJobBilling(m_savedJobBilling); + + setJobPriority(m_savedPriority); + + setStartBannerPage(m_savedJobSheets.startBannerPage); + setEndBannerPage(m_savedJobSheets.endBannerPage); +} + void QCupsJobWidget::initJobHold() { m_ui.jobHoldComboBox->addItem(tr("Print Immediately"), QVariant::fromValue(QCUPSSupport::NoHold)); @@ -106,7 +127,14 @@ void QCupsJobWidget::initJobHold() connect(m_ui.jobHoldComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QCupsJobWidget::toggleJobHoldTime); - setJobHold(QCUPSSupport::NoHold, QTime()); + QCUPSSupport::JobHoldUntilWithTime jobHoldWithTime; + + if (m_printDevice) { + const QString jobHoldUntilString = m_printDevice->property(PDPK_CupsJobHoldUntil).toString(); + jobHoldWithTime = QCUPSSupport::parseJobHoldUntil(jobHoldUntilString); + } + + setJobHold(jobHoldWithTime.jobHold, jobHoldWithTime.time); toggleJobHoldTime(); } @@ -140,12 +168,16 @@ QTime QCupsJobWidget::jobHoldTime() const void QCupsJobWidget::initJobBilling() { - setJobBilling(QString()); + QString jobBilling; + if (m_printDevice) + jobBilling = m_printDevice->property(PDPK_CupsJobBilling).toString(); + + setJobBilling(jobBilling); } void QCupsJobWidget::setJobBilling(const QString &jobBilling) { - m_ui.jobBillingLineEdit->insert(jobBilling); + m_ui.jobBillingLineEdit->setText(jobBilling); } QString QCupsJobWidget::jobBilling() const @@ -155,7 +187,18 @@ QString QCupsJobWidget::jobBilling() const void QCupsJobWidget::initJobPriority() { - setJobPriority(50); + int priority = -1; + if (m_printDevice) { + bool ok; + priority = m_printDevice->property(PDPK_CupsJobPriority).toInt(&ok); + if (!ok) + priority = -1; + } + + if (priority < 0 || priority > 100) + priority = 50; + + setJobPriority(priority); } void QCupsJobWidget::setJobPriority(int jobPriority) @@ -186,8 +229,15 @@ void QCupsJobWidget::initBannerPages() m_ui.endBannerPageCombo->addItem(tr("Secret", "CUPS Banner page"), QVariant::fromValue(QCUPSSupport::Secret)); m_ui.endBannerPageCombo->addItem(tr("Top Secret", "CUPS Banner page"), QVariant::fromValue(QCUPSSupport::TopSecret)); - setStartBannerPage(QCUPSSupport::NoBanner); - setEndBannerPage(QCUPSSupport::NoBanner); + QCUPSSupport::JobSheets jobSheets; + + if (m_printDevice) { + const QString jobSheetsString = m_printDevice->property(PDPK_CupsJobSheets).toString(); + jobSheets = QCUPSSupport::parseJobSheets(jobSheetsString); + } + + setStartBannerPage(jobSheets.startBannerPage); + setEndBannerPage(jobSheets.endBannerPage); } void QCupsJobWidget::setStartBannerPage(const QCUPSSupport::BannerPage bannerPage) diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index d66a472509..4b6b047e26 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -65,16 +65,18 @@ QT_BEGIN_NAMESPACE class QString; class QTime; class QPrinter; +class QPrintDevice; class QCupsJobWidget : public QWidget { Q_OBJECT public: - explicit QCupsJobWidget(QWidget *parent = nullptr); + explicit QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWidget *parent = nullptr); ~QCupsJobWidget(); - void setPrinter(QPrinter *printer); void setupPrinter(); + void updateSavedValues(); + void revertToSavedValues(); private Q_SLOTS: void toggleJobHoldTime(); @@ -103,8 +105,14 @@ private: void initBannerPages(); QPrinter *m_printer; + QPrintDevice *m_printDevice; Ui::QCupsJobWidget m_ui; + QCUPSSupport::JobHoldUntilWithTime m_savedJobHoldWithTime; + QString m_savedJobBilling; + int m_savedPriority; + QCUPSSupport::JobSheets m_savedJobSheets; + Q_DISABLE_COPY(QCupsJobWidget) }; diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp index dc07517397..92370be2bd 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.cpp +++ b/src/printsupport/widgets/qprintpreviewwidget.cpp @@ -64,13 +64,13 @@ public: setCacheMode(DeviceCoordinateCache); } - QRectF boundingRect() const Q_DECL_OVERRIDE + QRectF boundingRect() const override { return brect; } inline int pageNumber() const { return pageNum; } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override; private: int pageNum; @@ -156,7 +156,7 @@ signals: void resized(); protected: - void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE + void resizeEvent(QResizeEvent* e) override { { const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, QTBUG-14517 @@ -165,7 +165,7 @@ protected: emit resized(); } - void showEvent(QShowEvent* e) Q_DECL_OVERRIDE + void showEvent(QShowEvent* e) override { QGraphicsView::showEvent(e); emit resized(); diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h index d45cc1a9fb..f11d686602 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.h +++ b/src/printsupport/widgets/qprintpreviewwidget.h @@ -80,7 +80,7 @@ public: ZoomMode zoomMode() const; int currentPage() const; int pageCount() const; - void setVisible(bool visible) Q_DECL_OVERRIDE; + void setVisible(bool visible) override; public Q_SLOTS: void print(); |