diff options
author | Albert Astals Cid <albert.astals.cid@kdab.com> | 2018-02-14 09:56:21 +0100 |
---|---|---|
committer | Albert Astals Cid <albert.astals.cid@kdab.com> | 2018-03-27 12:02:26 +0000 |
commit | 0fb3d2177867524310eb744dd97fc5e370b0fd11 (patch) | |
tree | a7bbb1a2fafc5b8cf929868fc77937665ef8e0d0 /src/printsupport/dialogs | |
parent | 3d5fd088c38a6831d32958b0f21bdb8b07c3823d (diff) |
cups: Take conflicts for duplex and page size into account
Duplex and Page Size are not shown in the "Advanced" options tag
since they are more important options, this means we were not
taking them into account for ppd conflicts since we never set
their values in the ppd, we do use the new-style cups options for
them when printing
With this patch we add m_pageSizePpdOption and m_duplexPpdOption
to set the values to the ppd struct behind the scenes.
Change-Id: I48bd9fe93d0c08b7b8dd9620a07c56fc79cce13b
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
Diffstat (limited to 'src/printsupport/dialogs')
-rw-r--r-- | src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 63 | ||||
-rw-r--r-- | src/printsupport/dialogs/qpagesetupdialog_unix_p.h | 11 | ||||
-rw-r--r-- | src/printsupport/dialogs/qpagesetupwidget.ui | 3 | ||||
-rw-r--r-- | src/printsupport/dialogs/qprintdialog_unix.cpp | 107 | ||||
-rw-r--r-- | src/printsupport/dialogs/qprintpropertieswidget.ui | 88 |
5 files changed, 219 insertions, 53 deletions
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 7e32f9aa57..177e220c89 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -49,6 +49,7 @@ #include "qpainter.h" #include "qprintdialog.h" +#include "qtextcodec.h" #include "qdialogbuttonbox.h" #include <ui_qpagesetupwidget.h> @@ -235,6 +236,9 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent) m_pagePreview(nullptr), m_printer(nullptr), m_printDevice(nullptr), +#if QT_CONFIG(cups) + m_pageSizePpdOption(nullptr), +#endif m_outputFormat(QPrinter::PdfFormat), m_units(QPageLayout::Point), m_savedUnits(QPageLayout::Point), @@ -391,6 +395,11 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice, m_printer = printer; m_printDevice = printDevice; +#if QT_CONFIG(cups) + // find the PageSize cups option + m_pageSizePpdOption = m_printDevice ? QCUPSSupport::findPpdOption("PageSize", m_printDevice) : nullptr; +#endif + // Initialize the layout to the current QPrinter layout m_pageLayout = m_printer->pageLayout(); @@ -547,15 +556,48 @@ void QPageSetupWidget::revertToSavedValues() m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(m_savedPagesPerSheetLayout); } +#if QT_CONFIG(cups) +bool QPageSetupWidget::hasPpdConflict() const +{ + if (m_pageSizePpdOption) { + if (m_pageSizePpdOption->conflicted) { + const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr); + const int pixmap_size = m_ui.pageSizeCombo->sizeHint().height() * .75; + m_ui.pageSizeWarningLabel->setPixmap(warning.pixmap(pixmap_size, pixmap_size)); + } else { + m_ui.pageSizeWarningLabel->setPixmap(QPixmap()); + } + return m_pageSizePpdOption->conflicted; + } + + return false; +} +#endif + // Updates size/preview after the combobox has been changed. void QPageSetupWidget::pageSizeChanged() { - if (m_blockSignals) - return; - QPageSize pageSize; if (m_ui.pageSizeCombo->currentIndex() != m_realCustomPageSizeIndex) { pageSize = m_ui.pageSizeCombo->currentData().value<QPageSize>(); + +#if QT_CONFIG(cups) + if (m_pageSizePpdOption) { + ppd_file_t *ppd = m_printDevice->property(PDPK_PpdFile).value<ppd_file_t*>(); + QTextCodec *cupsCodec = QTextCodec::codecForName(ppd->lang_encoding); + for (int i = 0; i < m_pageSizePpdOption->num_choices; ++i) { + const ppd_choice_t *choice = &m_pageSizePpdOption->choices[i]; + if (cupsCodec->toUnicode(choice->text) == m_ui.pageSizeCombo->currentText()) { + const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword) + << QString::fromLatin1(choice->choice); + m_printDevice->setProperty(PDPK_PpdOption, values); + emit ppdOptionChanged(); + break; + } + } + } +#endif + } else { QSizeF customSize; if (m_pageLayout.orientation() == QPageLayout::Landscape) @@ -563,7 +605,22 @@ void QPageSetupWidget::pageSizeChanged() else customSize = QSizeF(m_ui.pageWidth->value(), m_ui.pageHeight->value()); pageSize = QPageSize(customSize, QPageSize::Unit(m_units)); + +#if QT_CONFIG(cups) + if (m_pageSizePpdOption) { + const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword) + << QStringLiteral("Custom"); + m_printDevice->setProperty(PDPK_PpdOption, values); + emit ppdOptionChanged(); + } +#endif } + + // We always need to update the m_pageSizePpdOption when the page size changes + // even if it's from inside updateWidget, so do not move up + if (m_blockSignals) + return; + 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())); diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h index bb33a0f587..7bfdaed740 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h @@ -54,6 +54,7 @@ #include <QtPrintSupport/private/qtprintsupportglobal_p.h> #include "qprinter.h" +#include "kernel/qprint_p.h" #include <QtGui/qpagelayout.h> @@ -78,6 +79,13 @@ public: void updateSavedValues(); void revertToSavedValues(); +#if QT_CONFIG(cups) + bool hasPpdConflict() const; + +signals: + void ppdOptionChanged(); +#endif + private slots: void pageSizeChanged(); void pageOrientationChanged(); @@ -100,6 +108,9 @@ private: QPagePreview *m_pagePreview; QPrinter *m_printer; QPrintDevice *m_printDevice; +#if QT_CONFIG(cups) + ppd_option_t *m_pageSizePpdOption; +#endif QPrinter::OutputFormat m_outputFormat; QString m_printerName; QPageLayout m_pageLayout; diff --git a/src/printsupport/dialogs/qpagesetupwidget.ui b/src/printsupport/dialogs/qpagesetupwidget.ui index 960a9dac17..3f24553c76 100644 --- a/src/printsupport/dialogs/qpagesetupwidget.ui +++ b/src/printsupport/dialogs/qpagesetupwidget.ui @@ -99,6 +99,9 @@ </property> </spacer> </item> + <item row="0" column="2"> + <widget class="QLabel" name="pageSizeWarningLabel"/> + </item> </layout> </widget> </item> diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 6a8aa0541a..ebf63ea568 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -138,6 +138,8 @@ private slots: void accept() override; private: + void showEvent(QShowEvent *event) override; + friend class QUnixPrintWidgetPrivate; QPrinter *m_printer; Ui::QPrintPropertiesWidget widget; @@ -151,6 +153,7 @@ private: void setPrinterAdvancedCupsOptions() const; void revertAdvancedOptionsToSavedValues() const; void advancedOptionsUpdateSavedValues() const; + bool anyPpdOptionConflict() const; bool anyAdvancedOptionConflict() const; QPrintDevice *m_currentPrintDevice; @@ -171,6 +174,7 @@ public: void updatePrinter(); private: + friend class QPrintDialog; friend class QPrintDialogPrivate; friend class QUnixPrintWidgetPrivate; QUnixPrintWidgetPrivate *d; @@ -203,6 +207,11 @@ public: void updateWidget(); +#if QT_CONFIG(cups) + void setPpdDuplex(QPrinter::DuplexMode mode); + ppd_option_t *m_duplexPpdOption; +#endif + private: QPrintDialogPrivate *optionsPane; bool filePrintersAdded; @@ -226,6 +235,9 @@ public: #endif void _q_collapseOrExpandDialog(); +#if QT_CONFIG(cups) + void updatePpdDuplexOption(QRadioButton *radio); +#endif void setupPrinter(); void updateWidgets(); @@ -281,7 +293,11 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice * const bool anyWidgetCreated = createAdvancedOptionsWidget(); widget.tabs->setTabEnabled(advancedTabIndex, anyWidgetCreated); - widget.conflictsLabel->setVisible(anyAdvancedOptionConflict()); + + connect(widget.pageSetup, &QPageSetupWidget::ppdOptionChanged, this, [this] { + widget.conflictsLabel->setVisible(anyPpdOptionConflict()); + }); + #else Q_UNUSED(currentPrintDevice) widget.tabs->setTabEnabled(advancedTabIndex, false); @@ -328,7 +344,14 @@ void QPrintPropertiesDialog::reject() void QPrintPropertiesDialog::accept() { #if QT_CONFIG(cups) - if (anyAdvancedOptionConflict()) { + if (widget.pageSetup->hasPpdConflict()) { + widget.tabs->setCurrentWidget(widget.tabPage); + const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Page Setup Conflicts"), + tr("There are conflicts in page setup options. Do you want to fix them?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + if (answer != QMessageBox::No) + return; + } else if (anyAdvancedOptionConflict()) { 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?"), @@ -348,6 +371,14 @@ void QPrintPropertiesDialog::accept() QDialog::accept(); } +void QPrintPropertiesDialog::showEvent(QShowEvent *event) +{ +#if QT_CONFIG(cups) + widget.conflictsLabel->setVisible(anyPpdOptionConflict()); +#endif + QDialog::showEvent(event); +} + #if QT_CONFIG(cups) // Used to store the ppd_option_t for each QComboBox that represents an advanced option @@ -434,7 +465,7 @@ bool QPrintPropertiesDialog::createAdvancedOptionsWidget() const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(option->choices[selectedChoiceIndex].choice); m_currentPrintDevice->setProperty(PDPK_PpdOption, values); - widget.conflictsLabel->setVisible(anyAdvancedOptionConflict()); + widget.conflictsLabel->setVisible(anyPpdOptionConflict()); }); // We need an extra label at the end to show the conflict warning @@ -504,7 +535,7 @@ void QPrintPropertiesDialog::revertAdvancedOptionsToSavedValues() const choicesCb->setCurrentIndex(newComboIndexToSelect); // The currentIndexChanged lambda takes care of resetting the ppd option } - widget.conflictsLabel->setVisible(anyAdvancedOptionConflict()); + widget.conflictsLabel->setVisible(anyPpdOptionConflict()); } void QPrintPropertiesDialog::advancedOptionsUpdateSavedValues() const @@ -513,6 +544,14 @@ void QPrintPropertiesDialog::advancedOptionsUpdateSavedValues() const choicesCb->setProperty(ppdOriginallySelectedChoiceProperty, choicesCb->currentData()); } +bool QPrintPropertiesDialog::anyPpdOptionConflict() const +{ + // we need to execute both since besides returning true/false they update the warning icons + const bool pageSetupConflicts = widget.pageSetup->hasPpdConflict(); + const bool advancedOptionConflicts = anyAdvancedOptionConflict(); + return pageSetupConflicts || advancedOptionConflicts; +} + bool QPrintPropertiesDialog::anyAdvancedOptionConflict() const { const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr); @@ -610,6 +649,12 @@ void QPrintDialogPrivate::init() q, SLOT(_q_togglePageSetCombo(bool))); QObject::connect(collapseButton, SIGNAL(released()), q, SLOT(_q_collapseOrExpandDialog())); + +#if QT_CONFIG(cups) + QObject::connect(options.noDuplex, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.noDuplex); }); + QObject::connect(options.duplexLong, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.duplexLong); }); + QObject::connect(options.duplexShort, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.duplexShort); }); +#endif } // initialize printer options @@ -735,6 +780,19 @@ static bool isValidPagesString(const QString &pagesString) Q_DECL_NOTHROW auto pagesRanges = pageRangesFromString(pagesString); return !pagesRanges.empty(); } + +void QPrintDialogPrivate::updatePpdDuplexOption(QRadioButton *radio) +{ + const bool checked = radio->isChecked(); + if (checked) { + if (radio == options.noDuplex) top->d->setPpdDuplex(QPrinter::DuplexNone); + else if (radio == options.duplexLong) top->d->setPpdDuplex(QPrinter::DuplexLongSide); + else if (radio == options.duplexShort) top->d->setPpdDuplex(QPrinter::DuplexShortSide); + } + const bool conflict = checked && top->d->m_duplexPpdOption && top->d->m_duplexPpdOption->conflicted; + radio->setIcon(conflict ? QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr) : QIcon()); +} + #endif void QPrintDialogPrivate::setupPrinter() @@ -1001,6 +1059,13 @@ void QPrintDialog::accept() QMessageBox::Ok, QMessageBox::Ok); return; } + if (d->top->d->m_duplexPpdOption && d->top->d->m_duplexPpdOption->conflicted) { + const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Duplex Settings Conflicts"), + tr("There are conflicts in duplex settings. Do you want to fix them?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + if (answer != QMessageBox::No) + return; + } #endif d->setupPrinter(); QDialog::accept(); @@ -1022,8 +1087,11 @@ void QPrintDialog::accept() /*! \internal */ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn) - : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0), - filePrintersAdded(false) + : parent(p), propertiesDialog(nullptr), printer(prn), +#if QT_CONFIG(cups) + m_duplexPpdOption(nullptr), +#endif + optionsPane(nullptr), filePrintersAdded(false) { q = nullptr; if (parent) @@ -1113,6 +1181,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) propertiesDialog = nullptr; } +#if QT_CONFIG(cups) + m_duplexPpdOption = nullptr; +#endif + if (filePrintersAdded) { Q_ASSERT(index != printerCount - 2); // separator if (index == printerCount - 1) { // PDF @@ -1147,6 +1219,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) if (optionsPane) optionsPane->selectPrinter(QPrinter::NativeFormat); } + +#if QT_CONFIG(cups) + m_duplexPpdOption = QCUPSSupport::findPpdOption("Duplex", &m_currentPrintDevice); +#endif } void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane) @@ -1242,11 +1318,30 @@ void QUnixPrintWidgetPrivate::setupPrinterProperties() propertiesDialog = new QPrintPropertiesDialog(q->printer(), &m_currentPrintDevice, outputFormat, printerName, q); } +#if QT_CONFIG(cups) +void QUnixPrintWidgetPrivate::setPpdDuplex(QPrinter::DuplexMode mode) +{ + auto values = QStringList{} << QStringLiteral("Duplex"); + if (mode == QPrinter::DuplexNone) values << QStringLiteral("None"); + else if (mode == QPrinter::DuplexLongSide) values << QStringLiteral("DuplexNoTumble"); + else if (mode == QPrinter::DuplexShortSide) values << QStringLiteral("DuplexTumble"); + + m_currentPrintDevice.setProperty(PDPK_PpdOption, values); +} +#endif + void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked() { if (!propertiesDialog) setupPrinterProperties(); propertiesDialog->exec(); + +#if QT_CONFIG(cups) + // update the warning icon on the duplex options if needed + optionsPane->updatePpdDuplexOption(optionsPane->options.noDuplex); + optionsPane->updatePpdDuplexOption(optionsPane->options.duplexLong); + optionsPane->updatePpdDuplexOption(optionsPane->options.duplexShort); +#endif } void QUnixPrintWidgetPrivate::setupPrinter() diff --git a/src/printsupport/dialogs/qprintpropertieswidget.ui b/src/printsupport/dialogs/qprintpropertieswidget.ui index b9d457a507..c2b4836d26 100644 --- a/src/printsupport/dialogs/qprintpropertieswidget.ui +++ b/src/printsupport/dialogs/qprintpropertieswidget.ui @@ -67,54 +67,54 @@ </widget> </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> + <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> <customwidgets> |