diff options
Diffstat (limited to 'src/printsupport')
37 files changed, 1445 insertions, 337 deletions
diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp index f982da46d9..71b5500bab 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.cpp +++ b/src/printsupport/dialogs/qabstractprintdialog.cpp @@ -471,7 +471,7 @@ void QPrintDialog::done(int result) if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(accepted(QPrinter*)), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); - d->receiverToDisconnectOnClose = 0; + d->receiverToDisconnectOnClose = nullptr; } d->memberToDisconnectOnClose.clear(); } diff --git a/src/printsupport/dialogs/qabstractprintdialog.h b/src/printsupport/dialogs/qabstractprintdialog.h index eb4dc3eb99..3cc89890fc 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.h +++ b/src/printsupport/dialogs/qabstractprintdialog.h @@ -81,7 +81,7 @@ public: Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption) Q_FLAG(PrintDialogOptions) - explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); + explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = nullptr); ~QAbstractPrintDialog(); int exec() override = 0; @@ -108,7 +108,7 @@ public: QPrinter *printer() const; protected: - QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = Q_NULLPTR); + QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = nullptr); private: Q_DISABLE_COPY(QAbstractPrintDialog) diff --git a/src/printsupport/dialogs/qabstractprintdialog_p.h b/src/printsupport/dialogs/qabstractprintdialog_p.h index 2537fcbf80..a17a28f564 100644 --- a/src/printsupport/dialogs/qabstractprintdialog_p.h +++ b/src/printsupport/dialogs/qabstractprintdialog_p.h @@ -69,7 +69,7 @@ class QAbstractPrintDialogPrivate : public QDialogPrivate public: QAbstractPrintDialogPrivate() - : printer(0), pd(0), ownsPrinter(false) + : printer(nullptr), pd(nullptr), ownsPrinter(false) , options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange | QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize), minPage(0), maxPage(INT_MAX) diff --git a/src/printsupport/dialogs/qpagesetupdialog.cpp b/src/printsupport/dialogs/qpagesetupdialog.cpp index 4acac2c5f1..dc0457d20d 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog.cpp @@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE constructor. */ -QPageSetupDialogPrivate::QPageSetupDialogPrivate(QPrinter *prntr) : printer(0), ownsPrinter(false) +QPageSetupDialogPrivate::QPageSetupDialogPrivate(QPrinter *prntr) : printer(nullptr), ownsPrinter(false) { setPrinter(prntr); } @@ -174,7 +174,7 @@ void QPageSetupDialog::done(int result) if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(accepted()), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); - d->receiverToDisconnectOnClose = 0; + d->receiverToDisconnectOnClose = nullptr; } d->memberToDisconnectOnClose.clear(); diff --git a/src/printsupport/dialogs/qpagesetupdialog.h b/src/printsupport/dialogs/qpagesetupdialog.h index 3bd752a413..a7aaa03134 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.h +++ b/src/printsupport/dialogs/qpagesetupdialog.h @@ -57,19 +57,19 @@ class Q_PRINTSUPPORT_EXPORT QPageSetupDialog : public QDialog Q_DECLARE_PRIVATE(QPageSetupDialog) public: - explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); - explicit QPageSetupDialog(QWidget *parent = Q_NULLPTR); + explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = nullptr); + explicit QPageSetupDialog(QWidget *parent = nullptr); ~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_p.h b/src/printsupport/dialogs/qpagesetupdialog_p.h index 6a389b039a..a2b3f8363c 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_p.h @@ -71,7 +71,7 @@ class QPageSetupDialogPrivate : public QDialogPrivate Q_DECLARE_PUBLIC(QPageSetupDialog) public: - QPageSetupDialogPrivate(QPrinter *printer); + explicit QPageSetupDialogPrivate(QPrinter *printer); void setPrinter(QPrinter *newPrinter); diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index b4ad718646..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, @@ -230,16 +232,23 @@ void QUnixPageSetupDialogPrivate::init() QPageSetupWidget::QPageSetupWidget(QWidget *parent) : QWidget(parent), - m_pagePreview(0), - m_printer(0), + 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_ui.preview->setLayout(lay); m_pagePreview = new QPagePreview(m_ui.preview); m_pagePreview->setPagePreviewLayout(1, 1); @@ -261,21 +270,21 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent) initUnits(); initPagesPerSheet(); - connect(m_ui.unitCombo, SIGNAL(activated(int)), this, SLOT(unitChanged())); + connect(m_ui.unitCombo, QOverload<int>::of(&QComboBox::activated), this, &QPageSetupWidget::unitChanged); - connect(m_ui.pageSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pageSizeChanged())); - connect(m_ui.pageWidth, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged())); - connect(m_ui.pageHeight, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged())); + connect(m_ui.pageSizeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pageSizeChanged); + connect(m_ui.pageWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged); + connect(m_ui.pageHeight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged); - connect(m_ui.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(leftMarginChanged(double))); - connect(m_ui.topMargin, SIGNAL(valueChanged(double)), this, SLOT(topMarginChanged(double))); - connect(m_ui.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(rightMarginChanged(double))); - connect(m_ui.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(bottomMarginChanged(double))); + connect(m_ui.leftMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::leftMarginChanged); + connect(m_ui.topMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::topMarginChanged); + connect(m_ui.rightMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::rightMarginChanged); + connect(m_ui.bottomMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::bottomMarginChanged); - connect(m_ui.portrait, SIGNAL(clicked()), this, SLOT(pageOrientationChanged())); - connect(m_ui.landscape, SIGNAL(clicked()), this, SLOT(pageOrientationChanged())); + connect(m_ui.portrait, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged); + connect(m_ui.landscape, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged); - connect(m_ui.pagesPerSheetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pagesPerSheetChanged())); + connect(m_ui.pagesPerSheetCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pagesPerSheetChanged); } // Init the Units combo box @@ -342,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; } @@ -360,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)); } } @@ -372,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) @@ -388,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 @@ -438,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; @@ -471,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); @@ -483,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); @@ -511,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 658f103bea..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 = 0); - explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = 0); + explicit QPageSetupWidget(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 5b81440a3c..bbb12202f0 100644 --- a/src/printsupport/dialogs/qprintdialog.h +++ b/src/printsupport/dialogs/qprintdialog.h @@ -59,15 +59,15 @@ class Q_PRINTSUPPORT_EXPORT QPrintDialog : public QAbstractPrintDialog Q_PROPERTY(PrintDialogOptions options READ options WRITE setOptions) public: - explicit QPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); - explicit QPrintDialog(QWidget *parent = Q_NULLPTR); + explicit QPrintDialog(QPrinter *printer, QWidget *parent = nullptr); + 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 a05c9ac83a..caab7867dc 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 = 0); + 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; @@ -149,7 +167,7 @@ class QUnixPrintWidget : public QWidget Q_OBJECT public: - explicit QUnixPrintWidget(QPrinter *printer, QWidget *parent = 0); + explicit QUnixPrintWidget(QPrinter *printer, QWidget *parent = nullptr); ~QUnixPrintWidget(); void updatePrinter(); @@ -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,24 +347,53 @@ 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); - this->setLayout(lay); QWidget *content = new QWidget(this); widget.setupUi(content); m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); lay->addWidget(content); lay->addWidget(m_buttons); - connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); - connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + 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 } @@ -265,25 +401,66 @@ QPrintPropertiesDialog::~QPrintPropertiesDialog() { } -void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p) +void QPrintPropertiesDialog::setupPrinter() const { - widget.pageSetup->setPrinter(p); +#if QT_CONFIG(cups) + QCUPSSupport::clearCupsOptions(m_printer); +#endif + + 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(); } //////////////////////////////////////////////////////////////////////////////// @@ -298,7 +475,7 @@ void QPrintPropertiesDialog::selectPrinter(QPrinter::OutputFormat outputFormat, */ QPrintDialogPrivate::QPrintDialogPrivate() - : top(0), bottom(0), buttons(0), collapseButton(0) + : top(nullptr), bottom(nullptr), buttons(nullptr), collapseButton(nullptr) { initResources(); } @@ -324,6 +501,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); @@ -338,7 +518,6 @@ void QPrintDialogPrivate::init() printButton->setDefault(true); QVBoxLayout *lay = new QVBoxLayout(q); - q->setLayout(lay); lay->addWidget(top); lay->addWidget(bottom); lay->addWidget(buttons); @@ -366,6 +545,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 @@ -390,13 +574,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 +} + +#if QT_CONFIG(cups) +static std::vector<std::pair<int, int>> pageRangesFromString(const QString &pagesString) Q_DECL_NOTHROW +{ + 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; } -void QPrintDialogPrivate::applyPrinterProperties() +static bool isValidPagesString(const QString &pagesString) Q_DECL_NOTHROW { - // apply printer options to property dialog - top->d->applyPrinterProperties(); + if (pagesString.isEmpty()) + return false; + + auto pagesRanges = pageRangesFromString(pagesString); + return !pagesRanges.empty(); } +#endif void QPrintDialogPrivate::setupPrinter() { @@ -416,7 +681,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 @@ -442,6 +712,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 @@ -610,7 +890,7 @@ QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent) Constructs a print dialog with the given \a parent. */ QPrintDialog::QPrintDialog(QWidget *parent) - : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent) + : QAbstractPrintDialog(*(new QPrintDialogPrivate), nullptr, parent) { Q_D(QPrintDialog); d->init(); @@ -638,6 +918,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(); } @@ -658,10 +948,10 @@ void QPrintDialog::accept() /*! \internal */ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn) - : parent(p), propertiesDialog(0), printer(prn), optionsPane(0), - filePrintersAdded(false), propertiesDialogShown(false) + : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0), + filePrintersAdded(false) { - q = 0; + q = nullptr; if (parent) q = qobject_cast<QAbstractPrintDialog*> (parent->parent()); @@ -746,8 +1036,7 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) // Reset properties dialog when printer is changed if (propertiesDialog){ delete propertiesDialog; - propertiesDialog = 0; - propertiesDialogShown = false; + propertiesDialog = nullptr; } if (filePrintersAdded) { @@ -762,14 +1051,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()); @@ -792,7 +1087,7 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked() QString filename = widget.filename->text(); #if QT_CONFIG(filedialog) filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename, - QString(), 0, QFileDialog::DontConfirmOverwrite); + QString(), nullptr, QFileDialog::DontConfirmOverwrite); #else filename.clear(); #endif @@ -802,48 +1097,6 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked() } } -void QUnixPrintWidgetPrivate::applyPrinterProperties() -{ - if (printer == 0) - 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() { @@ -876,7 +1129,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,21 +1152,20 @@ bool QUnixPrintWidgetPrivate::checkFields() void QUnixPrintWidgetPrivate::setupPrinterProperties() { - if (propertiesDialog) - delete propertiesDialog; + 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() @@ -921,15 +1173,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 = 0; - propertiesDialogShown = false; - } else - // properties dialog was shown and accepted - propertiesDialogShown = true; } void QUnixPrintWidgetPrivate::setupPrinter() @@ -954,8 +1197,7 @@ void QUnixPrintWidgetPrivate::setupPrinter() if (!propertiesDialog) setupPrinterProperties(); - if (propertiesDialog->result() == QDialog::Accepted || !propertiesDialogShown) - propertiesDialog->setupPrinter(); + propertiesDialog->setupPrinter(); } /*! \internal @@ -963,7 +1205,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 @@ -985,6 +1261,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 dbcbaf3ce5..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 0; } + 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('%'))) { @@ -115,21 +115,21 @@ class LineEdit : public QLineEdit { Q_OBJECT public: - LineEdit(QWidget* parent = 0) + LineEdit(QWidget* parent = nullptr) : QLineEdit(parent) { setContextMenuPolicy(Qt::NoContextMenu); - connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed())); + connect(this, &LineEdit::returnPressed, this, &LineEdit::handleReturnPressed); } 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); @@ -152,7 +152,7 @@ class QPrintPreviewDialogPrivate : public QDialogPrivate Q_DECLARE_PUBLIC(QPrintPreviewDialog) public: QPrintPreviewDialogPrivate() - : printDialog(0), ownPrinter(false), + : printDialog(nullptr), ownPrinter(false), initialized(false) {} // private slots @@ -167,7 +167,7 @@ public: void _q_previewChanged(); void _q_zoomFactorChanged(); - void init(QPrinter *printer = 0); + void init(QPrinter *printer = nullptr); void populateScene(); void layoutPages(); void setupActions(); @@ -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); @@ -736,7 +736,7 @@ void QPrintPreviewDialog::done(int result) if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(finished(int)), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); - d->receiverToDisconnectOnClose = 0; + d->receiverToDisconnectOnClose = nullptr; } d->memberToDisconnectOnClose.clear(); } diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h index 3b8f8a1171..53fede7e83 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.h +++ b/src/printsupport/dialogs/qprintpreviewdialog.h @@ -58,8 +58,8 @@ class Q_PRINTSUPPORT_EXPORT QPrintPreviewDialog : public QDialog Q_DECLARE_PRIVATE(QPrintPreviewDialog) public: - explicit QPrintPreviewDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); - explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR, + explicit QPrintPreviewDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewDialog(); @@ -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 48ab71eea4..7e8e1707b2 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -43,36 +43,45 @@ 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); } } +void QCUPSSupport::clearCupsOptions(QPrinter *printer) +{ + setCupsOptions(printer, QStringList()); +} + static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, const QTime holdUntilTime) { switch (jobHold) { @@ -96,7 +105,7 @@ static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, if (holdUntilTime < localDateTime.time()) localDateTime = localDateTime.addDays(1); localDateTime.setTime(holdUntilTime); - return localDateTime.toUTC().time().toString(QStringLiteral("HH:mm")); + return localDateTime.toUTC().time().toString(QStringViewLiteral("HH:mm")); } // else fall through: Q_FALLTHROUGH(); @@ -107,32 +116,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) @@ -148,21 +182,44 @@ static inline QString bannerPageToString(const QCUPSSupport::BannerPage bannerPa } Q_UNREACHABLE(); 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 +234,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..9a71483bb9 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,9 @@ 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 clearCupsOptions(QPrinter *printer); static void setJobHold(QPrinter *printer, const JobHoldUntil jobHold = NoHold, const QTime &holdUntilTime = QTime()); static void setJobBilling(QPrinter *printer, const QString &jobBilling = QString()); @@ -135,6 +142,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/qpaintengine_preview.cpp b/src/printsupport/kernel/qpaintengine_preview.cpp index 4c00333097..7179249677 100644 --- a/src/printsupport/kernel/qpaintengine_preview.cpp +++ b/src/printsupport/kernel/qpaintengine_preview.cpp @@ -69,8 +69,8 @@ QPreviewPaintEngine::QPreviewPaintEngine() : QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients)) { Q_D(QPreviewPaintEngine); - d->proxy_print_engine = 0; - d->proxy_paint_engine = 0; + d->proxy_print_engine = nullptr; + d->proxy_paint_engine = nullptr; } QPreviewPaintEngine::~QPreviewPaintEngine() @@ -102,8 +102,8 @@ bool QPreviewPaintEngine::end() Q_D(QPreviewPaintEngine); delete d->painter; - d->painter = 0; - d->engine = 0; + d->painter = nullptr; + d->engine = nullptr; d->state = QPrinter::Idle; return true; } 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/qplatformprintersupport.cpp b/src/printsupport/kernel/qplatformprintersupport.cpp index 388dd5ff8e..a25dc6d45c 100644 --- a/src/printsupport/kernel/qplatformprintersupport.cpp +++ b/src/printsupport/kernel/qplatformprintersupport.cpp @@ -70,12 +70,12 @@ QPlatformPrinterSupport::~QPlatformPrinterSupport() QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode, const QString &) { - return 0; + return nullptr; } QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode) { - return 0; + return nullptr; } QPrintDevice QPlatformPrinterSupport::createPrintDevice(QPlatformPrintDevice *device) @@ -89,11 +89,6 @@ QPrintDevice QPlatformPrinterSupport::createPrintDevice(const QString &id) return QPrintDevice(); } -QPrintDevice QPlatformPrinterSupport::createDefaultPrintDevice() -{ - return createPrintDevice(defaultPrintDeviceId()); -} - QStringList QPlatformPrinterSupport::availablePrintDeviceIds() const { return QStringList(); diff --git a/src/printsupport/kernel/qplatformprintersupport.h b/src/printsupport/kernel/qplatformprintersupport.h index 6a4246adc0..413c1067c2 100644 --- a/src/printsupport/kernel/qplatformprintersupport.h +++ b/src/printsupport/kernel/qplatformprintersupport.h @@ -76,7 +76,6 @@ public: virtual QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode); virtual QPrintDevice createPrintDevice(const QString &id); - virtual QPrintDevice createDefaultPrintDevice(); virtual QStringList availablePrintDeviceIds() const; virtual QString defaultPrintDeviceId() const; diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp index a80f369040..9a7656f7d6 100644 --- a/src/printsupport/kernel/qplatformprintplugin.cpp +++ b/src/printsupport/kernel/qplatformprintplugin.cpp @@ -60,12 +60,12 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin() { } -static QPlatformPrinterSupport *printerSupport = 0; +static QPlatformPrinterSupport *printerSupport = nullptr; static void cleanupPrinterSupport() { delete printerSupport; - printerSupport = 0; + printerSupport = nullptr; } /*! 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 278bb044e1..0230ebddc8 100644 --- a/src/printsupport/kernel/qprintengine_pdf.cpp +++ b/src/printsupport/kernel/qprintengine_pdf.cpp @@ -58,10 +58,12 @@ QT_BEGIN_NAMESPACE -QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m) +QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m, QPdfEngine::PdfVersion version) : QPdfEngine(*new QPdfPrintEnginePrivate(m)) { state = QPrinter::Idle; + + setPdfVersion(version); } QPdfPrintEngine::QPdfPrintEngine(QPdfPrintEnginePrivate &p) @@ -372,14 +374,14 @@ 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); #endif fd = -1; delete outDevice; - outDevice = 0; + outDevice = nullptr; } } diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h index b964885bbf..bb01a2e9e1 100644 --- a/src/printsupport/kernel/qprintengine_pdf_p.h +++ b/src/printsupport/kernel/qprintengine_pdf_p.h @@ -83,22 +83,22 @@ class Q_PRINTSUPPORT_EXPORT QPdfPrintEngine : public QPdfEngine, public QPrintEn { Q_DECLARE_PRIVATE(QPdfPrintEngine) public: - QPdfPrintEngine(QPrinter::PrinterMode m); + QPdfPrintEngine(QPrinter::PrinterMode m, QPdfEngine::PdfVersion version = QPdfEngine::Version_1_4); 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 e2138512cc..8a2cdcb34f 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -132,7 +132,7 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI { // Default to PdfFormat outputFormat = QPrinter::PdfFormat; - QPlatformPrinterSupport *ps = 0; + QPlatformPrinterSupport *ps = nullptr; QString printerName; // Only set NativeFormat if we have a valid plugin and printer to use @@ -149,7 +149,8 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI printEngine = ps->createNativePrintEngine(printerMode, printerName); paintEngine = ps->createPaintEngine(printEngine, printerMode); } else { - QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode); + const auto pdfEngineVersion = (pdfVersion == QPrinter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b); + QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode, pdfEngineVersion); paintEngine = pdfEngine; printEngine = pdfEngine; } @@ -230,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) { @@ -247,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) { @@ -265,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); @@ -276,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); @@ -293,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>(); } @@ -686,7 +687,37 @@ QPrinter::OutputFormat QPrinter::outputFormat() const return d->outputFormat; } +/*! + \since 5.10 + + Sets the PDF version for this printer to \a version. + + If \a version is the same value as currently set then no change will be made. +*/ +void QPrinter::setPdfVersion(PdfVersion version) +{ + Q_D(QPrinter); + + if (d->pdfVersion == version) + return; + + d->pdfVersion = version; + if (d->outputFormat == QPrinter::PdfFormat) { + d->changeEngines(d->outputFormat, QPrinterInfo()); + } +} + +/*! + \since 5.10 + + Returns the PDF version for this printer. The default is \c PdfVersion_1_4. +*/ +QPrinter::PdfVersion QPrinter::pdfVersion() const +{ + Q_D(const QPrinter); + return d->pdfVersion; +} /*! \internal */ diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h index 33a2d4dbc8..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 }; @@ -134,6 +134,9 @@ public: void setOutputFormat(OutputFormat format); OutputFormat outputFormat() const; + void setPdfVersion(PdfVersion version); + PdfVersion pdfVersion() const; + void setPrinterName(const QString &); QString printerName() const; @@ -167,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; @@ -234,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); @@ -249,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/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h index 603eaf7409..6ced466236 100644 --- a/src/printsupport/kernel/qprinter_p.h +++ b/src/printsupport/kernel/qprinter_p.h @@ -75,7 +75,8 @@ class Q_PRINTSUPPORT_EXPORT QPrinterPrivate Q_DECLARE_PUBLIC(QPrinter) public: QPrinterPrivate(QPrinter *printer) - : printEngine(0), + : pdfVersion(QPrinter::PdfVersion_1_4), + printEngine(0), paintEngine(0), realPrintEngine(0), realPaintEngine(0), @@ -107,6 +108,7 @@ public: QPrinter::PrinterMode printerMode; QPrinter::OutputFormat outputFormat; + QPrinter::PdfVersion pdfVersion; QPrintEngine *printEngine; QPaintEngine *paintEngine; 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 00f2d64df2..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)); @@ -104,9 +125,16 @@ void QCupsJobWidget::initJobHold() m_ui.jobHoldComboBox->addItem(tr("Weekend (Saturday to Sunday)"), QVariant::fromValue(QCUPSSupport::Weekend)); m_ui.jobHoldComboBox->addItem(tr("Specific Time"), QVariant::fromValue(QCUPSSupport::SpecificTime)); - connect(m_ui.jobHoldComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleJobHoldTime())); + connect(m_ui.jobHoldComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QCupsJobWidget::toggleJobHoldTime); + + QCUPSSupport::JobHoldUntilWithTime jobHoldWithTime; - setJobHold(QCUPSSupport::NoHold, QTime()); + 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 7d3c15938f..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 = 0); + 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 b28e693612..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; @@ -145,7 +145,7 @@ class GraphicsView : public QGraphicsView { Q_OBJECT public: - GraphicsView(QWidget* parent = 0) + GraphicsView(QWidget* parent = nullptr) : QGraphicsView(parent) { #ifdef Q_OS_MAC @@ -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(); @@ -179,7 +179,7 @@ class QPrintPreviewWidgetPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QPrintPreviewWidget) public: QPrintPreviewWidgetPrivate() - : scene(0), curPage(1), + : scene(nullptr), curPage(1), viewMode(QPrintPreviewWidget::SinglePageView), zoomMode(QPrintPreviewWidget::FitInView), zoomFactor(1), initialized(false), fitting(true) @@ -324,8 +324,7 @@ void QPrintPreviewWidgetPrivate::init() scene->setBackgroundBrush(Qt::gray); graphicsView->setScene(scene); - QVBoxLayout *layout = new QVBoxLayout; - q->setLayout(layout); + QVBoxLayout *layout = new QVBoxLayout(q); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(graphicsView); } diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h index 8735d06072..f11d686602 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.h +++ b/src/printsupport/widgets/qprintpreviewwidget.h @@ -69,9 +69,9 @@ public: FitInView }; - explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = Q_NULLPTR, + explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); - explicit QPrintPreviewWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewWidget(); qreal zoomFactor() const; @@ -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(); |