Hello community, here is the log from the commit of package libqt5-qtbase for openSUSE:Factory checked in at 2018-02-03 15:38:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqt5-qtbase (Old) and /work/SRC/openSUSE:Factory/.libqt5-qtbase.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5-qtbase" Sat Feb 3 15:38:02 2018 rev:73 rq:572065 version:5.10.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libqt5-qtbase/libqt5-qtbase.changes 2018-01-02 16:32:55.053895202 +0100 +++ /work/SRC/openSUSE:Factory/.libqt5-qtbase.new/libqt5-qtbase.changes 2018-02-03 15:38:04.249790773 +0100 @@ -1,0 +2,47 @@ +Fri Feb 2 08:10:28 UTC 2018 - [email protected] + +- Add 0001-QSimpleDrag-Fix-mouse-release-coords-for-delayed-eve.patch + to fix a bug causing the wrong desktop icon to look hovered + after dragging an icon on the desktop in plasma (QTBUG-66103). + +------------------------------------------------------------------- +Fri Jan 26 11:21:54 UTC 2018 - [email protected] + +- Moved 0001-Avoid-providing-bad-pixelDeltas-on-X11.patch to use a patch + number in the 1000-1999 range since it was approved in the 5.9 branch + upstream. + +------------------------------------------------------------------- +Fri Jan 26 10:08:04 UTC 2018 - [email protected] + +- Add 0001-Avoid-providing-bad-pixelDeltas-on-X11.patch to avoid using + the hardcoded resolution that libinput is giving as a real pixel + delta (QTBUG-59261). + +------------------------------------------------------------------- +Tue Jan 25 10:13:15 UTC 2018 - [email protected] + +- Add patches to fix the custom page size handling in the print dialog as + well as other printer issues (QTBUG-58733, boo#994809): + * 0002-CUPS-Use-default-cups-job-priority-instead-of-50.patch + * 0003-QPageSetupWidget-setPrinter-Use-printdevice-default-paper-size.patch + * 0004-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch + * 0005-CUPS-Refactor-the-code-a-bit.patch + * 0006-Refactor-QPPDOptionsModel-a-bit.patch + * 0007-CUPS-Fix-advanced-options-cancel-of-the-print-properties-dialog.patch + * 0008-CUPS-Fix-conflict-handling.patch + * 0009-CUPS-Use-printer-job-sheets-as-default-instead-of-none-none.patch + * 0010-CUPS-Use-printer-job-billing-as-default-instead-of-the-empty-string.patch + * 0011-CUPS-Use-printer-job-hold-until-as-default-instead-of-the-nohold.patch + * 0012-Unix-Fix-usability-of-the-print-properties-dialog.patch + * 0013-cups-Dont-show-InstallableOptions-in-the-advanced-properties-tab.patch + * 0014-CUPS-Enable-printing-arbitrary-pages-and-page-ranges.patch + * 0015-CUPS-Dont-show-choices-that-conflict-with-the-printer-installed-options.patch + * 0016-CUPS-Rework-set-clearCupsOption-API.patch + * 0017-Cups-Print-Dialog-Change-the-message-box-titles-to-C.patch + * 0018-Fix-build-due-to-missing-QDebug-include.patch + +- Dropped 0001-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch + which is now included in the previous patchset with order 0004. + +------------------------------------------------------------------- Old: ---- 0001-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch New: ---- 0001-Avoid-providing-bad-pixelDeltas-on-X11.patch 0001-QSimpleDrag-Fix-mouse-release-coords-for-delayed-eve.patch 0002-CUPS-Use-default-cups-job-priority-instead-of-50.patch 0003-QPageSetupWidget-setPrinter-Use-printdevice-default-paper-size.patch 0004-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch 0005-CUPS-Refactor-the-code-a-bit.patch 0006-Refactor-QPPDOptionsModel-a-bit.patch 0007-CUPS-Fix-advanced-options-cancel-of-the-print-properties-dialog.patch 0008-CUPS-Fix-conflict-handling.patch 0009-CUPS-Use-printer-job-sheets-as-default-instead-of-none-none.patch 0010-CUPS-Use-printer-job-billing-as-default-instead-of-the-empty-string.patch 0011-CUPS-Use-printer-job-hold-until-as-default-instead-of-the-nohold.patch 0012-Unix-Fix-usability-of-the-print-properties-dialog.patch 0013-cups-Dont-show-InstallableOptions-in-the-advanced-properties-tab.patch 0014-CUPS-Enable-printing-arbitrary-pages-and-page-ranges.patch 0015-CUPS-Dont-show-choices-that-conflict-with-the-printer-installed-options.patch 0016-CUPS-Rework-set-clearCupsOption-API.patch 0017-Cups-Print-Dialog-Change-the-message-box-titles-to-C.patch 0018-Fix-build-due-to-missing-QDebug-include.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqt5-qtbase.spec ++++++ --- /var/tmp/diff_new_pack.zfUq9n/_old 2018-02-03 15:38:06.249697361 +0100 +++ /var/tmp/diff_new_pack.zfUq9n/_new 2018-02-03 15:38:06.253697174 +0100 @@ -67,6 +67,8 @@ Patch17: qapplication-emit-palettechanged.patch # patches 1000- 2000 and above from upstream 5.10 branch # Patch1000: 0001-xcb-verify-if-xrandr-present-before-using-xcb_randr-.patch +Patch1001: 0001-Avoid-providing-bad-pixelDeltas-on-X11.patch +Patch1002: 0001-QSimpleDrag-Fix-mouse-release-coords-for-delayed-eve.patch # patches 2000-3000 and above from upstream 5.11/dev branch # Patch2000: 0001-Remove-QPrintDialogPrivate-applyPrinterProperties-no.patch Patch2001: 0002-Remove-QUnixPrintWidgetPrivate-applyPrinterPropertie.patch @@ -79,7 +81,23 @@ Patch2008: 0009-QPlatformPrintDevice-use-QVector-not-QList-in-the-AP.patch Patch2009: 0010-Reintroduce-the-Advanced-tab-in-the-QPrintProperties.patch Patch2010: 0011-QtPrintSupport-Fix-build.patch -Patch2011: 0001-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch +Patch2012: 0002-CUPS-Use-default-cups-job-priority-instead-of-50.patch +Patch2013: 0003-QPageSetupWidget-setPrinter-Use-printdevice-default-paper-size.patch +Patch2014: 0004-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch +Patch2015: 0005-CUPS-Refactor-the-code-a-bit.patch +Patch2016: 0006-Refactor-QPPDOptionsModel-a-bit.patch +Patch2017: 0007-CUPS-Fix-advanced-options-cancel-of-the-print-properties-dialog.patch +Patch2018: 0008-CUPS-Fix-conflict-handling.patch +Patch2019: 0009-CUPS-Use-printer-job-sheets-as-default-instead-of-none-none.patch +Patch2020: 0010-CUPS-Use-printer-job-billing-as-default-instead-of-the-empty-string.patch +Patch2021: 0011-CUPS-Use-printer-job-hold-until-as-default-instead-of-the-nohold.patch +Patch2022: 0012-Unix-Fix-usability-of-the-print-properties-dialog.patch +Patch2023: 0013-cups-Dont-show-InstallableOptions-in-the-advanced-properties-tab.patch +Patch2024: 0014-CUPS-Enable-printing-arbitrary-pages-and-page-ranges.patch +Patch2025: 0015-CUPS-Dont-show-choices-that-conflict-with-the-printer-installed-options.patch +Patch2026: 0016-CUPS-Rework-set-clearCupsOption-API.patch +Patch2027: 0017-Cups-Print-Dialog-Change-the-message-box-titles-to-C.patch +Patch2028: 0018-Fix-build-due-to-missing-QDebug-include.patch BuildRequires: alsa-devel BuildRequires: cups-devel BuildRequires: double-conversion-devel @@ -172,6 +190,8 @@ %patch15 -p1 %patch17 -p1 %patch1000 -p1 +%patch1001 -p1 +%patch1002 -p1 %patch2000 -p1 %patch2001 -p1 %patch2002 -p1 @@ -183,7 +203,23 @@ %patch2008 -p1 %patch2009 -p1 %patch2010 -p1 -%patch2011 -p1 +%patch2012 -p1 +%patch2013 -p1 +%patch2014 -p1 +%patch2015 -p1 +%patch2016 -p1 +%patch2017 -p1 +%patch2018 -p1 +%patch2019 -p1 +%patch2020 -p1 +%patch2021 -p1 +%patch2022 -p1 +%patch2023 -p1 +%patch2024 -p1 +%patch2025 -p1 +%patch2026 -p1 +%patch2027 -p1 +%patch2028 -p1 # be sure not to use them rm -rf src/3rdparty/{libjpeg,freetype,zlib} ++++++ 0001-Avoid-providing-bad-pixelDeltas-on-X11.patch ++++++ >From d196036024697a75868c1f1626525710495ca428 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <[email protected]> Date: Thu, 23 Nov 2017 14:25:04 +0100 Subject: [PATCH] Avoid providing bad pixelDeltas on X11 With libinput we now get a hardcoded resolution that is unrelated to the hardware. So avoid using that as a real pixel delta and document pixel deltas as being driver specific and unreliable on X11. Task-number: QTBUG-59261 Change-Id: I9fe86d80e7ccd290ed2e4091d7eafa52cb537d34 Reviewed-by: David Edmundson <[email protected]> Reviewed-by: Marco Martin <[email protected]> Reviewed-by: Gatis Paeglis <[email protected]> --- src/gui/kernel/qevent.cpp | 1 + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 06d52aa..c68f9af 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -971,6 +971,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, \li scrolling is about to begin, but the distance did not yet change (Qt::ScrollBegin), \li or scrolling has ended and the distance did not change anymore (Qt::ScrollEnd). \endlist + \note On X11 this value is driver specific and unreliable, use angleDelta() instead */ /*! diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d1d97af..94f543f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -953,10 +953,12 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin double delta = scrollingDevice.lastScrollPosition.y() - value; scrollingDevice.lastScrollPosition.setY(value); angleDelta.setY((delta / scrollingDevice.verticalIncrement) * 120); - // We do not set "pixel" delta if it is only measured in ticks. - if (scrollingDevice.verticalIncrement > 1) + // With most drivers the increment is 1 for wheels. + // For libinput it is hardcoded to a useless 15. + // For a proper touchpad driver it should be in the same order of magnitude as 120 + if (scrollingDevice.verticalIncrement > 15) rawDelta.setY(delta); - else if (scrollingDevice.verticalIncrement < -1) + else if (scrollingDevice.verticalIncrement < -15) rawDelta.setY(-delta); } } @@ -965,10 +967,10 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin double delta = scrollingDevice.lastScrollPosition.x() - value; scrollingDevice.lastScrollPosition.setX(value); angleDelta.setX((delta / scrollingDevice.horizontalIncrement) * 120); - // We do not set "pixel" delta if it is only measured in ticks. - if (scrollingDevice.horizontalIncrement > 1) + // See comment under vertical + if (scrollingDevice.horizontalIncrement > 15) rawDelta.setX(delta); - else if (scrollingDevice.horizontalIncrement < -1) + else if (scrollingDevice.horizontalIncrement < -15) rawDelta.setX(-delta); } } -- 2.7.4 ++++++ 0001-QSimpleDrag-Fix-mouse-release-coords-for-delayed-eve.patch ++++++ >From 4a7771f206d4b29be549d3827c36a46679d90de6 Mon Sep 17 00:00:00 2001 From: Eike Hein <[email protected]> Date: Sun, 7 Jan 2018 13:02:01 +0900 Subject: [PATCH] QSimpleDrag: Fix mouse release coords for delayed event transmission On platforms such as XCB, the drag cursor pixmap is shown via a window (a QShapedPixmapWindow) under the cursor. The mouse button release event at the end of the drag is received in this QXcbWindow, but intercepted by an event filter that QSimpleDrag installs on the QApplication. It then resends it unmodified(!) after the drag has ended and the drag pixmap window destroyed, causing it to be delivered to the new top-level window. The local coordinates in the unmodified QMouseEvent are local to the drag pixmap window and don't match the window it is delayed-transmitted to. This ends up having fatal, user-visible effects particularly in Qt Quick: QQuickWindow synthesizes a hover event once per frame using the last received mouse coordinates, here: the release posted by QSimpleDrag. This is done to update the hover event state for items under the cursor when the mouse hasn't moved (e.g. QQuickMouseArea:: containsMouse). The bogus event coordinates in the release event then usually end up causing an item near the top-left of the QQuickWindow to assume it is hovered (because drag pixmap windows tend to be small), even when the mouse cursor is actually far away from it at the end of the drag. This shows up e.g. in the Plasma 5 desktop, where dragging an icon on the desktop will cause the icon at the top-left of the screen (if any) to switch to hovered state, as the release coordinates on the drag pixmap window (showing a dragged icon) fall into the geometry of the top-left icon. QSimpleDrag contains a topLevelAt() function to find the top-level window under the global cursor coordinates that is not the drag pixmap window. This is used by the drop event delivery code. This patch uses this function to find the relevant top-level window, then asks it to map the global cusor coordinates to its local coordinate system, then synthesizes a new QMouseEvent with local coordinates computed in this fashion. As a result the window now gets a release event with coordinates that make sense and are correct. Task-number: QTBUG-66103 Change-Id: I04ebe6ccd4a991fdd4b540ff0227973ea8896a9d Reviewed-by: Eike Hein <[email protected]> Reviewed-by: Shawn Rutledge <[email protected]> --- src/gui/kernel/qsimpledrag.cpp | 32 +++++++++++++++++++++++++++----- src/gui/kernel/qsimpledrag_p.h | 6 +++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index a1e25dc53c..87d3ba5915 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -58,6 +58,7 @@ #include <QtCore/QEventLoop> #include <QtCore/QDebug> +#include <QtCore/QLoggingCategory> #include <private/qguiapplication_p.h> #include <private/qdnd_p.h> @@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DRAGANDDROP +Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd") + static QWindow* topLevelAt(const QPoint &pos) { QWindowList list = QGuiApplication::topLevelWindows(); @@ -94,10 +97,10 @@ static QWindow* topLevelAt(const QPoint &pos) */ QBasicDrag::QBasicDrag() : - m_restoreCursor(false), m_eventLoop(0), + m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr), m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), - m_drag(0), m_drag_icon_window(0), m_useCompositing(true), - m_screen(Q_NULLPTR) + m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true), + m_screen(nullptr) { } @@ -161,6 +164,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e) return true; // Eat all mouse move events } case QEvent::MouseButtonRelease: + { disableEventFilter(); if (canDrop()) { QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window); @@ -169,8 +173,25 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e) cancel(); } exitDndEventLoop(); - QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e))); + + // If a QShapedPixmapWindow (drag feedback) is being dragged along, the + // mouse event's localPos() will be relative to that, which is useless. + // We want a position relative to the window where the drag ends, if possible (?). + // If there is no such window (belonging to this Qt application), + // make the event relative to the window where the drag started. (QTBUG-66103) + const QMouseEvent *release = static_cast<QMouseEvent *>(e); + const QWindow *releaseWindow = topLevelAt(release->globalPos()); + qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_current_window << "globalPos" << release->globalPos(); + if (!releaseWindow) + releaseWindow = m_current_window; + QPoint releaseWindowPos = (releaseWindow ? releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos()); + QMouseEvent *newRelease = new QMouseEvent(release->type(), + releaseWindowPos, releaseWindowPos, release->screenPos(), + release->button(), release->buttons(), + release->modifiers(), release->source()); + QCoreApplication::postEvent(o, newRelease); return true; // defer mouse release events until drag event loop has returned + } case QEvent::MouseButtonDblClick: case QEvent::Wheel: return true; @@ -349,7 +370,7 @@ static inline QPoint fromNativeGlobalPixels(const QPoint &point) into account. */ -QSimpleDrag::QSimpleDrag() : m_current_window(0) +QSimpleDrag::QSimpleDrag() { } @@ -373,6 +394,7 @@ void QSimpleDrag::startDrag() updateCursor(Qt::IgnoreAction); } setExecutedDropAction(Qt::IgnoreAction); + qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << QCursor::pos() << "can drop?" << canDrop(); } void QSimpleDrag::cancel() diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h index 0b8a0bc703..bbd7f7f4bb 100644 --- a/src/gui/kernel/qsimpledrag_p.h +++ b/src/gui/kernel/qsimpledrag_p.h @@ -105,6 +105,9 @@ protected: QDrag *drag() const { return m_drag; } +protected: + QWindow *m_current_window; + private: void enableEventFilter(); void disableEventFilter(); @@ -132,9 +135,6 @@ protected: virtual void cancel() Q_DECL_OVERRIDE; virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE; virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE; - -private: - QWindow *m_current_window; }; #endif // QT_NO_DRAGANDDROP -- 2.16.1 ++++++ 0002-CUPS-Use-default-cups-job-priority-instead-of-50.patch ++++++ >From ad77a2447e8cc828dadd268c72428556e3cc8a84 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 6 Dec 2017 10:19:13 +0100 Subject: [PATCH 1/1] CUPS: Use default cups job-priority instead of 50 This also reads the job-priority from lpoptions if set there for the particular printer Change-Id: I75d983c377d2135a0b0d3e028829a7384a5e1897 Reviewed-by: Laurent Montel <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 2 ++ src/printsupport/dialogs/qprintdialog_unix.cpp | 2 +- src/printsupport/kernel/qcups_p.h | 5 +++-- src/printsupport/widgets/qcupsjobwidget.cpp | 20 +++++++++++++++++--- src/printsupport/widgets/qcupsjobwidget_p.h | 4 +++- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 021d040..56976a6 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -427,6 +427,8 @@ QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) con { if (key == PDPK_PpdFile) return QVariant::fromValue<ppd_file_t *>(m_ppd); + else if (key == PDPK_CupsJobPriority) + return printerOption(QStringLiteral("job-priority")); return QVariant(); } diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 9ad9fa3..020894c 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -333,7 +333,7 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice * widget.pageSetup->setPrinter(printer, outputFormat, printerName); #if QT_CONFIG(cupsjobwidget) - m_jobOptions = new QCupsJobWidget(printer); + m_jobOptions = new QCupsJobWidget(printer, currentPrintDevice); widget.tabs->insertTab(1, m_jobOptions, tr("Job Options")); #endif diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index b67390c..3abccf2 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -67,8 +67,9 @@ 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_PpdFile QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase) +#define PDPK_PpdOption QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 1) +#define PDPK_CupsJobPriority QPrintDevice::PrintDevicePropertyKey(QPrintDevice::PDPK_CustomBase + 2) class Q_PRINTSUPPORT_EXPORT QCUPSSupport { diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index 8fb07c8..f21e229 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,9 +66,10 @@ QT_BEGIN_NAMESPACE \inmodule QtPrintSupport */ -QCupsJobWidget::QCupsJobWidget(QPrinter *printer, QWidget *parent) +QCupsJobWidget::QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWidget *parent) : QWidget(parent), - m_printer(printer) + m_printer(printer), + m_printDevice(printDevice) { m_ui.setupUi(this); //set all the default values @@ -151,7 +154,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) diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index 2aca6bc..dcec27a 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -65,13 +65,14 @@ QT_BEGIN_NAMESPACE class QString; class QTime; class QPrinter; +class QPrintDevice; class QCupsJobWidget : public QWidget { Q_OBJECT public: - explicit QCupsJobWidget(QPrinter *printer, QWidget *parent = nullptr); + explicit QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWidget *parent = nullptr); ~QCupsJobWidget(); void setupPrinter(); @@ -102,6 +103,7 @@ private: void initBannerPages(); QPrinter *m_printer; + QPrintDevice *m_printDevice; Ui::QCupsJobWidget m_ui; Q_DISABLE_COPY(QCupsJobWidget) -- 2.7.4 ++++++ 0003-QPageSetupWidget-setPrinter-Use-printdevice-default-paper-size.patch ++++++ >From ff67dedaaff2dc68571ca9c8c6c6eeaaf084eae4 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 6 Dec 2017 15:27:05 +0100 Subject: [PATCH 1/1] QPageSetupWidget::setPrinter: Use printdevice default paper size This means that actually the paper size set on system settings (or lpoptions) is used instead of A4 Change-Id: I2dd86fd9ba210a335773430328b0ba2d3343395f Reviewed-by: Frederik Gladhorn <[email protected]> --- src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 9 +++++++-- src/printsupport/dialogs/qpagesetupdialog_unix_p.h | 4 +++- src/printsupport/dialogs/qprintdialog_unix.cpp | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 49c0184..6f3bb0d 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -210,7 +210,7 @@ void QUnixPageSetupDialogPrivate::init() Q_Q(QPageSetupDialog); widget = new QPageSetupWidget(q); - widget->setPrinter(printer, printer->outputFormat(), printer->printerName()); + widget->setPrinter(printer, nullptr, printer->outputFormat(), printer->printerName()); QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, @@ -371,12 +371,17 @@ void QPageSetupWidget::initPageSizes() // Set the dialog to use the given QPrinter // Usually only called on first creation -void QPageSetupWidget::setPrinter(QPrinter *printer, QPrinter::OutputFormat outputFormat, const QString &printerName) +void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName) { m_printer = printer; // Initialize the layout to the current QPrinter layout m_pageLayout = m_printer->pageLayout(); + + if (printDevice) + m_pageLayout.setPageSize(printDevice->defaultPageSize()); + // 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) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h index 44aca80..574569d 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h @@ -64,6 +64,7 @@ QT_REQUIRE_CONFIG(printdialog); QT_BEGIN_NAMESPACE class QPrinter; +class QPrintDevice; class QPagePreview; class QPageSetupWidget : public QWidget { @@ -71,7 +72,8 @@ class QPageSetupWidget : public QWidget { explicit QPageSetupWidget(QWidget *parent = 0); explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = 0); - void setPrinter(QPrinter *printer, QPrinter::OutputFormat outputFormat, const QString &printerName); + void setPrinter(QPrinter *printer, QPrintDevice *printDevice, + QPrinter::OutputFormat outputFormat, const QString &printerName); void setupPrinter() const; private slots: diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 020894c..22076bf 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -330,7 +330,7 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice * connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); - widget.pageSetup->setPrinter(printer, outputFormat, printerName); + widget.pageSetup->setPrinter(printer, currentPrintDevice, outputFormat, printerName); #if QT_CONFIG(cupsjobwidget) m_jobOptions = new QCupsJobWidget(printer, currentPrintDevice); -- 2.7.4 ++++++ 0001-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch -> 0004-Fix-custom-page-size-handling-in-the-Unix-print-dial.patch ++++++ ++++++ 0005-CUPS-Refactor-the-code-a-bit.patch ++++++ >From d7330140190686f805be9fcd1ac968e3768f0754 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 21 Dec 2017 16:27:02 +0100 Subject: [PATCH 1/1] CUPS: Refactor the code a bit Move the selected and selDescription members to a subclass of QOptionTreeItem since it's only ever used for Option type nodes of the tree Change-Id: Ic99841c4e04a3afcff0950f72abf12977850f6d3 Reviewed-by: Michael Weghorn <[email protected]> Reviewed-by: Renato Araujo Oliveira Filho <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 44 ++++++++++++++++---------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 22076bf..6a7e679 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -247,8 +247,6 @@ public: index(i), ptr(p), description(desc), - selected(-1), - selDescription(nullptr), parentItem(pi) {} ~QOptionTreeItem() { @@ -259,12 +257,22 @@ public: int index; const void *ptr; const char *description; - int selected; - const char *selDescription; QOptionTreeItem *parentItem; QList<QOptionTreeItem*> childItems; }; +class QOptionTreeItemOption : public QOptionTreeItem +{ +public: + QOptionTreeItemOption (int i, const void *p, const char *desc, QOptionTreeItem *pi) + : QOptionTreeItem(Option, i, p, desc, pi) + { + } + + int selected; + const char *selDescription; +}; + class QPPDOptionsModel : public QAbstractItemModel { Q_OBJECT @@ -285,7 +293,7 @@ public: QOptionTreeItem *rootItem; void parseGroups(QOptionTreeItem *parent); void parseOptions(QOptionTreeItem *parent); - void parseChoices(QOptionTreeItem *parent); + void parseChoices(QOptionTreeItemOption *parent); }; class QPPDOptionsEditor : public QStyledItemDelegate @@ -387,10 +395,11 @@ void QPrintPropertiesDialog::setCupsOptionsFromItems(QOptionTreeItem *parent) co { 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->defchoice, opt->choices[itm->selected].choice) != 0) { + if (qstrcmp(opt->defchoice, opt->choices[itmOption->selected].choice) != 0) { QStringList cupsOptions = QCUPSSupport::cupsOptionsList(m_printer); - QCUPSSupport::setCupsOption(cupsOptions, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itm->selected].choice)); + QCUPSSupport::setCupsOption(cupsOptions, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); QCUPSSupport::setCupsOptions(m_printer, cupsOptions); } } else { @@ -1153,12 +1162,15 @@ QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const break; case Qt::DisplayRole: { - if (index.column() == 0) + if (index.column() == 0) { return cupsCodec->toUnicode(itm->description); - else if (itm->type == QOptionTreeItem::Option && itm->selected > -1) - return cupsCodec->toUnicode(itm->selDescription); - else - return QVariant(); + } else if (itm->type == QOptionTreeItem::Option) { + QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm); + if (itmOption->selected > -1) + return cupsCodec->toUnicode(itmOption->selDescription); + } + + return QVariant(); } break; @@ -1240,14 +1252,14 @@ 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)) { - QOptionTreeItem *opt = new QOptionTreeItem(QOptionTreeItem::Option, i, &group->options[i], group->options[i].text, parent); + QOptionTreeItemOption *opt = new QOptionTreeItemOption(i, &group->options[i], group->options[i].text, parent); parent->childItems.append(opt); parseChoices(opt); } } } -void QPPDOptionsModel::parseChoices(QOptionTreeItem *parent) +void QPPDOptionsModel::parseChoices(QOptionTreeItemOption *parent) { const ppd_option_t *option = static_cast<const ppd_option_t*>(parent->ptr); bool marked = false; @@ -1307,7 +1319,7 @@ void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) return; QComboBox *cb = static_cast<QComboBox*>(editor); - QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer()); + QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer()); if (itm->selected == -1) cb->addItem(QString()); @@ -1323,7 +1335,7 @@ void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *cb = static_cast<QComboBox*>(editor); - QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer()); + QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer()); if (itm->selected == cb->currentIndex()) return; -- 2.7.4 ++++++ 0006-Refactor-QPPDOptionsModel-a-bit.patch ++++++ >From 030d815eb8c5b6506178141da391594482c2e733 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 28 Dec 2017 14:46:32 +0100 Subject: [PATCH] Refactor QPPDOptionsModel a bit Make the members private and add getters Make some other functions also private Move setCupsOptionsFromItems from QPrintPropertiesDialog to QPPDOptionsModel Change-Id: Ibb555a6e6be53550f30c159c3ad611d55e2a767a Reviewed-by: Kevin Ottens <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 95 ++++++++++++++++---------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 63d23cc..a9745d7 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -288,12 +288,21 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - QPrintDevice *m_currentPrintDevice; - QTextCodec *cupsCodec; - QOptionTreeItem *rootItem; + void setCupsOptionsFromItems(QPrinter *printer) const; + + QPrintDevice *currentPrintDevice() const; + QTextCodec *cupsCodec() const; + +private: void parseGroups(QOptionTreeItem *parent); void parseOptions(QOptionTreeItem *parent); void parseChoices(QOptionTreeItemOption *parent); + + void setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const; + + QPrintDevice *m_currentPrintDevice; + QTextCodec *m_cupsCodec; + QOptionTreeItem *m_rootItem; }; class QPPDOptionsEditor : public QStyledItemDelegate @@ -380,7 +389,7 @@ void QPrintPropertiesDialog::setupPrinter() const #endif #if QT_CONFIG(cups) - setCupsOptionsFromItems(m_cupsOptionsModel->rootItem); + m_cupsOptionsModel->setCupsOptionsFromItems(m_printer); #endif } @@ -390,25 +399,6 @@ void QPrintPropertiesDialog::showEvent(QShowEvent *event) QDialog::showEvent(event); } -#if QT_CONFIG(cups) -void QPrintPropertiesDialog::setCupsOptionsFromItems(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->defchoice, opt->choices[itmOption->selected].choice) != 0) { - QStringList cupsOptions = QCUPSSupport::cupsOptionsList(m_printer); - QCUPSSupport::setCupsOption(cupsOptions, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); - QCUPSSupport::setCupsOptions(m_printer, cupsOptions); - } - } else { - setCupsOptionsFromItems(itm); - } - } -} -#endif - //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -1107,22 +1097,23 @@ void QUnixPrintWidget::updatePrinter() 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*>(); - rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0); + m_rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0); if (ppd) { - cupsCodec = QTextCodec::codecForName(ppd->lang_encoding); + m_cupsCodec = QTextCodec::codecForName(ppd->lang_encoding); for (int i = 0; i < ppd->num_groups; ++i) { - QOptionTreeItem *group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppd->groups[i], ppd->groups[i].text, rootItem); - rootItem->childItems.append(group); + QOptionTreeItem *group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppd->groups[i], ppd->groups[i].text, m_rootItem); + m_rootItem->childItems.append(group); parseGroups(group); // parse possible subgroups parseOptions(group); // parse options } } - if (!cupsCodec) - cupsCodec = QTextCodec::codecForLocale(); + if (!m_cupsCodec) + m_cupsCodec = QTextCodec::codecForLocale(); } int QPPDOptionsModel::columnCount(const QModelIndex &) const @@ -1134,7 +1125,7 @@ int QPPDOptionsModel::rowCount(const QModelIndex &parent) const { QOptionTreeItem *itm; if (!parent.isValid()) - itm = rootItem; + itm = m_rootItem; else itm = static_cast<QOptionTreeItem*>(parent.internalPointer()); @@ -1164,11 +1155,11 @@ QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: { if (index.column() == 0) { - return cupsCodec->toUnicode(itm->description); + return m_cupsCodec->toUnicode(itm->description); } else if (itm->type == QOptionTreeItem::Option) { QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm); if (itmOption->selected > -1) - return cupsCodec->toUnicode(itmOption->selDescription); + return m_cupsCodec->toUnicode(itmOption->selDescription); } return QVariant(); @@ -1184,7 +1175,7 @@ QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex &pare { QOptionTreeItem *itm; if (!parent.isValid()) - itm = rootItem; + itm = m_rootItem; else itm = static_cast<QOptionTreeItem*>(parent.internalPointer()); @@ -1199,7 +1190,7 @@ QModelIndex QPPDOptionsModel::parent(const QModelIndex &index) const QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer()); - if (itm->parentItem && itm->parentItem != rootItem) + if (itm->parentItem && itm->parentItem != m_rootItem) return createIndex(itm->parentItem->index, 0, itm->parentItem); return QModelIndex(); @@ -1216,6 +1207,38 @@ Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex &index) const 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->defchoice, opt->choices[itmOption->selected].choice) != 0) { + QStringList cupsOptions = QCUPSSupport::cupsOptionsList(printer); + QCUPSSupport::setCupsOption(cupsOptions, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); + QCUPSSupport::setCupsOptions(printer, cupsOptions); + } + } else { + setCupsOptionsFromItems(printer, itm); + } + } +} + void QPPDOptionsModel::parseGroups(QOptionTreeItem *parent) { const ppd_group_t *group = static_cast<const ppd_group_t*>(parent->ptr); @@ -1327,7 +1350,7 @@ void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) const QPPDOptionsModel *m = static_cast<const QPPDOptionsModel*>(index.model()); for (auto *childItem : qAsConst(itm->childItems)) - cb->addItem(m->cupsCodec->toUnicode(childItem->description)); + cb->addItem(m->cupsCodec()->toUnicode(childItem->description)); if (itm->selected > -1) cb->setCurrentIndex(itm->selected); @@ -1345,7 +1368,7 @@ void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, QPPDOptionsModel *m = static_cast<QPPDOptionsModel*>(model); const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[cb->currentIndex()].choice); - if (m->m_currentPrintDevice->setProperty(PDPK_PpdOption, values)) { + if (m->currentPrintDevice()->setProperty(PDPK_PpdOption, values)) { itm->selected = cb->currentIndex(); itm->selDescription = static_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text; } -- 2.7.4 ++++++ 0007-CUPS-Fix-advanced-options-cancel-of-the-print-properties-dialog.patch ++++++ >From 6efbd4381ade816515bbde59f9d31df0241e1340 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 21 Dec 2017 16:37:14 +0100 Subject: [PATCH] CUPS: Fix advanced options cancel of the print properties dialog When the user changes the advanced settings we call setProperty PDPK_PpdOption so if the user cancels we need to set them back to what they were originally Change-Id: Idd0cb413fb1e68dd28cf66f7f66f7e0afb38393e Reviewed-by: Michael Weghorn <[email protected]> Reviewed-by: Kevin Ottens <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index a9745d7..3b1c492 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -139,6 +139,9 @@ public: void showEvent(QShowEvent *event) override; +private slots: + void reject() override; + private: friend class QUnixPrintWidgetPrivate; QPrinter *m_printer; @@ -270,6 +273,7 @@ public: } int selected; + int originallySelected; const char *selDescription; }; @@ -289,6 +293,7 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; void setCupsOptionsFromItems(QPrinter *printer) const; + void reject(); QPrintDevice *currentPrintDevice() const; QTextCodec *cupsCodec() const; @@ -299,6 +304,7 @@ private: void parseChoices(QOptionTreeItemOption *parent); void setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const; + void reject(QOptionTreeItem *item); QPrintDevice *m_currentPrintDevice; QTextCodec *m_cupsCodec; @@ -399,6 +405,14 @@ void QPrintPropertiesDialog::showEvent(QShowEvent *event) QDialog::showEvent(event); } +void QPrintPropertiesDialog::reject() +{ +#if QT_CONFIG(cups) + m_cupsOptionsModel->reject(); +#endif + QDialog::reject(); +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -1297,6 +1311,7 @@ void QPPDOptionsModel::parseChoices(QOptionTreeItemOption *parent) parent->selected = i; parent->selDescription = option->choices[i].text; } + parent->originallySelected = parent->selected; parent->childItems.append(choice); } } @@ -1316,6 +1331,27 @@ QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) co return QVariant(); } +void QPPDOptionsModel::reject() +{ + reject(m_rootItem); +} + +void QPPDOptionsModel::reject(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); + } + + for (QOptionTreeItem *child : qAsConst(item->childItems)) + reject(child); +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -- 2.7.4 ++++++ 0008-CUPS-Fix-conflict-handling.patch ++++++ >From 5e2f583a67c75c1c03e213467bb56207e5084279 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 21 Dec 2017 16:55:42 +0100 Subject: [PATCH] CUPS: Fix conflict handling The previous code assumed that ppdMarkOption returning non zero (i.e. it has conflicts) also meant that the option wasn't applied at the ppd level, but it actually is. What we need to do is after calling ppdMarkOption parse the tree again looking to see if any option is conflicting and mark it as such in the UI. Change-Id: I836f1902d14dc8c176bb06776471cbf4ed11786f Reviewed-by: Andy Shaw <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 6 +- src/printsupport/dialogs/qprintdialog_unix.cpp | 101 ++++++++++++++++++++- src/printsupport/dialogs/qprintpropertieswidget.ui | 65 +++++++++++-- 3 files changed, 160 insertions(+), 12 deletions(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 8aed8c5..9c4b699 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -443,8 +443,10 @@ bool QPpdPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key, cons { if (key == PDPK_PpdOption) { const QStringList values = value.toStringList(); - if (values.count() == 2) - return ppdMarkOption(m_ppd, values[0].toLatin1(), values[1].toLatin1()) == 0; + if (values.count() == 2) { + ppdMarkOption(m_ppd, values[0].toLatin1(), values[1].toLatin1()); + return true; + } } return false; diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 3b1c492..fcb53f4 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -141,6 +141,7 @@ public: private slots: void reject() override; + void accept() override; private: friend class QUnixPrintWidgetPrivate; @@ -298,6 +299,12 @@ public: 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); @@ -305,6 +312,8 @@ private: void setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const; void reject(QOptionTreeItem *item); + void emitDataChanged(QOptionTreeItem *item, const QModelIndex &itemIndex, bool *conflictsFound); + bool hasConflicts(QOptionTreeItem *item) const; QPrintDevice *m_currentPrintDevice; QTextCodec *m_cupsCodec; @@ -377,6 +386,9 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice * 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); @@ -413,6 +425,21 @@ void QPrintPropertiesDialog::reject() QDialog::reject(); } +void QPrintPropertiesDialog::accept() +{ +#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; + } +#endif + QDialog::accept(); +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -1180,6 +1207,22 @@ QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const } 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(); @@ -1316,6 +1359,55 @@ void QPPDOptionsModel::parseChoices(QOptionTreeItemOption *parent) } } +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) @@ -1404,10 +1496,11 @@ void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, QPPDOptionsModel *m = static_cast<QPPDOptionsModel*>(model); const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[cb->currentIndex()].choice); - if (m->currentPrintDevice()->setProperty(PDPK_PpdOption, values)) { - itm->selected = cb->currentIndex(); - itm->selDescription = static_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text; - } + m->currentPrintDevice()->setProperty(PDPK_PpdOption, values); + itm->selected = cb->currentIndex(); + itm->selDescription = static_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text; + + m->emitConflictsChanged(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/printsupport/dialogs/qprintpropertieswidget.ui b/src/printsupport/dialogs/qprintpropertieswidget.ui index 0e56fb3..d8e5261 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,18 +41,62 @@ </item> </layout> </widget> - <widget class="QWidget" name="cupsPropertiesPage" > - <attribute name="title" > + <widget class="QWidget" name="cupsPropertiesPage"> + <attribute name="title"> <string>Advanced</string> </attribute> - <layout class="QHBoxLayout" name="horizontalLayout_2" > + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QTreeView" name="treeView" > - <property name="alternatingRowColors" > + <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> -- 2.7.4 ++++++ 0009-CUPS-Use-printer-job-sheets-as-default-instead-of-none-none.patch ++++++ >From 83538a360e246ac2242977015e4a374a9f0e21b8 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 6 Dec 2017 11:28:55 +0100 Subject: [PATCH] CUPS: Use printer job-sheets as default instead of none,none This also reads the job-sheets from lpoptions if set there for the particular printer Change-Id: I35aff103261ef58492779071d866e8a15ac78607 Reviewed-by: Laurent Montel <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 2 ++ src/printsupport/kernel/qcups.cpp | 26 +++++++++++++++++++++++ src/printsupport/kernel/qcups_p.h | 8 +++++++ src/printsupport/widgets/qcupsjobwidget.cpp | 11 ++++++++-- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 56976a6..e11d301 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -429,6 +429,8 @@ QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) con return QVariant::fromValue<ppd_file_t *>(m_ppd); else if (key == PDPK_CupsJobPriority) return printerOption(QStringLiteral("job-priority")); + else if (key == PDPK_CupsJobSheets) + return printerOption(QStringLiteral("job-sheets")); return QVariant(); } diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index b9e162a..aa1cdff 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -150,6 +150,32 @@ static inline QString bannerPageToString(const QCUPSSupport::BannerPage bannerPa return QString(); } +static inline QCUPSSupport::BannerPage stringToBannerPage(const QString &bannerPage) +{ + if (bannerPage == QLatin1String("none")) return QCUPSSupport::NoBanner; + else if (bannerPage == QLatin1String("standard")) return QCUPSSupport::Standard; + else if (bannerPage == QLatin1String("unclassified")) return QCUPSSupport::Unclassified; + else if (bannerPage == QLatin1String("confidential")) return QCUPSSupport::Confidential; + else if (bannerPage == QLatin1String("classified")) return QCUPSSupport::Classified; + else if (bannerPage == QLatin1String("secret")) return QCUPSSupport::Secret; + else if (bannerPage == QLatin1String("topsecret")) return QCUPSSupport::TopSecret; + + return QCUPSSupport::NoBanner; +} + +QCUPSSupport::JobSheets QCUPSSupport::parseJobSheets(const QString &jobSheets) +{ + JobSheets result; + + const QStringList parts = jobSheets.split(QLatin1Char(',')); + if (parts.count() == 2) { + result.startBannerPage = stringToBannerPage(parts[0]); + result.endBannerPage = stringToBannerPage(parts[1]); + } + + return result; +} + void QCUPSSupport::setBannerPages(QPrinter *printer, const BannerPage startBannerPage, const BannerPage endBannerPage) { QStringList cupsOptions = cupsOptionsList(printer); diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index 3abccf2..906a548 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE #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) class Q_PRINTSUPPORT_EXPORT QCUPSSupport { @@ -139,6 +140,13 @@ public: static void setPagesPerSheetLayout(QPrinter *printer, const PagesPerSheet pagesPerSheet, const PagesPerSheetLayout pagesPerSheetLayout); static void setPageRange(QPrinter *printer, int pageFrom, int pageTo); + + struct JobSheets + { + BannerPage startBannerPage = QCUPSSupport::NoBanner; + BannerPage endBannerPage = QCUPSSupport::NoBanner; + }; + static JobSheets parseJobSheets(const QString &jobSheets); }; Q_DECLARE_TYPEINFO(QCUPSSupport::JobHoldUntil, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(QCUPSSupport::BannerPage, Q_PRIMITIVE_TYPE); diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index f21e229..4535f75 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -196,8 +196,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) -- 2.7.4 ++++++ 0010-CUPS-Use-printer-job-billing-as-default-instead-of-the-empty-string.patch ++++++ >From 2831fa76655c614ed3df0816401514950e79b5e6 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 6 Dec 2017 12:00:00 +0100 Subject: [PATCH] CUPS: Use printer job-billing as default instead of the empty string This also reads the job-billing from lpoptions if set there for the particular printer Change-Id: Ia4a6961de504005b8dcd9209da0624e9ae9ef7e4 Reviewed-by: Laurent Montel <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 2 ++ src/printsupport/kernel/qcups_p.h | 1 + src/printsupport/widgets/qcupsjobwidget.cpp | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index e11d301..0fd6f5f 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -431,6 +431,8 @@ QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) con return printerOption(QStringLiteral("job-priority")); else if (key == PDPK_CupsJobSheets) return printerOption(QStringLiteral("job-sheets")); + else if (key == PDPK_CupsJobBilling) + return printerOption(QStringLiteral("job-billing")); return QVariant(); } diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index 906a548..c6bbacc 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE #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) class Q_PRINTSUPPORT_EXPORT QCUPSSupport { diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index 4535f75..adaaff8 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -139,7 +139,11 @@ 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) -- 2.7.4 ++++++ 0011-CUPS-Use-printer-job-hold-until-as-default-instead-of-the-nohold.patch ++++++ >From 414a703036db6d5b4b1f48b85d8c3b4702f869ec Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 6 Dec 2017 13:00:30 +0100 Subject: [PATCH] CUPS: Use printer job-hold-until as default instead of the nohold This also reads the job-hold-until from lpoptions if set there for the particular printer Change-Id: Ic60fef675ab9f4760cd99ee9ac417b0478459681 Reviewed-by: Frederik Gladhorn <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 2 ++ src/printsupport/kernel/qcups.cpp | 31 +++++++++++++++++++++++ src/printsupport/kernel/qcups_p.h | 18 +++++++++---- src/printsupport/widgets/qcupsjobwidget.cpp | 10 ++++++-- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 0fd6f5f..14c14fa 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -433,6 +433,8 @@ QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) con return printerOption(QStringLiteral("job-sheets")); else if (key == PDPK_CupsJobBilling) return printerOption(QStringLiteral("job-billing")); + else if (key == PDPK_CupsJobHoldUntil) + return printerOption(QStringLiteral("job-hold-until")); return QVariant(); } diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index aa1cdff..50c6953 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -107,6 +107,37 @@ 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); diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index c6bbacc..afddfdb 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -67,11 +67,12 @@ 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_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) class Q_PRINTSUPPORT_EXPORT QCUPSSupport { @@ -148,6 +149,13 @@ public: BannerPage endBannerPage = QCUPSSupport::NoBanner; }; static JobSheets parseJobSheets(const QString &jobSheets); + + struct JobHoldUntilWithTime + { + 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/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index adaaff8..5d026d4 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -73,7 +73,6 @@ QCupsJobWidget::QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWi { m_ui.setupUi(this); //set all the default values - //TODO restore last used values initJobHold(); initJobBilling(); initJobPriority(); @@ -105,7 +104,14 @@ void QCupsJobWidget::initJobHold() connect(m_ui.jobHoldComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleJobHoldTime())); - setJobHold(QCUPSSupport::NoHold, QTime()); + QCUPSSupport::JobHoldUntilWithTime jobHoldWithTime; + + if (m_printDevice) { + const QString jobHoldUntilString = m_printDevice->property(PDPK_CupsJobHoldUntil).toString(); + jobHoldWithTime = QCUPSSupport::parseJobHoldUntil(jobHoldUntilString); + } + + setJobHold(jobHoldWithTime.jobHold, jobHoldWithTime.time); toggleJobHoldTime(); } -- 2.7.4 ++++++ 0012-Unix-Fix-usability-of-the-print-properties-dialog.patch ++++++ >From d94ccf310a9ca01593750a34f743ec652f6a344e Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 27 Dec 2017 11:12:19 +0100 Subject: [PATCH 1/1] Unix: Fix usability of the print properties dialog Previous behavior: * Open, change setting, cancel, open again, setting was as originally (i.e. unchanged) * Open, change setting, accept, open, change setting, cancel, open again, the setting would be as before pressing cancel * Open, change setting, accept, open, press cancel without changing anything, print, the initially changed setting is not applied New behavior: * Pressing cancel just cancels the changes since you opened the dialog, everything you accepted previously stays correctly selected Change-Id: I483647504682f26d3d21c5229cc6530bf14fe519 Reviewed-by: Andy Shaw <[email protected]> Reviewed-by: Frederik Gladhorn <[email protected]> --- src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 25 +++++ src/printsupport/dialogs/qpagesetupdialog_unix_p.h | 6 ++ src/printsupport/dialogs/qprintdialog_unix.cpp | 107 +++++++++++++-------- src/printsupport/kernel/qcups_p.h | 10 +- src/printsupport/widgets/qcupsjobwidget.cpp | 25 ++++- src/printsupport/widgets/qcupsjobwidget_p.h | 7 ++ 6 files changed, 136 insertions(+), 44 deletions(-) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 4086212..2063408 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -234,6 +234,9 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent) m_printer(0), m_outputFormat(QPrinter::PdfFormat), m_units(QPageLayout::Point), + m_savedUnits(QPageLayout::Point), + m_savedPagesPerSheet(-1), + m_savedPagesPerSheetLayout(-1), m_blockSignals(false), m_realCustomPageSizeIndex(-1) { @@ -404,6 +407,7 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice, m_printerName = printerName; initPageSizes(); updateWidget(); + updateSavedValues(); } // Update the widget with the current settings @@ -487,6 +491,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); @@ -515,6 +520,26 @@ 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() { diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h index 0b9723e..82c22c3 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h @@ -75,6 +75,8 @@ public: void setPrinter(QPrinter *printer, QPrintDevice *printDevice, QPrinter::OutputFormat outputFormat, const QString &printerName); void setupPrinter() const; + void updateSavedValues(); + void revertToSavedValues(); private slots: void pageSizeChanged(); @@ -100,7 +102,11 @@ private: 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; }; diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index a3ba7be..29000bf 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -207,7 +207,6 @@ public: private: QPrintDialogPrivate *optionsPane; bool filePrintersAdded; - bool propertiesDialogShown; }; class QPrintDialogPrivate : public QAbstractPrintDialogPrivate @@ -247,11 +246,10 @@ class QOptionTreeItem public: enum ItemType { Root, Group, Option, Choice }; - QOptionTreeItem(ItemType t, int i, const void *p, const char *desc, QOptionTreeItem *pi) + QOptionTreeItem(ItemType t, int i, const void *p, QOptionTreeItem *pi) : type(t), index(i), ptr(p), - description(desc), parentItem(pi) {} ~QOptionTreeItem() { @@ -261,7 +259,6 @@ public: ItemType type; int index; const void *ptr; - const char *description; QOptionTreeItem *parentItem; QList<QOptionTreeItem*> childItems; }; @@ -269,14 +266,13 @@ public: class QOptionTreeItemOption : public QOptionTreeItem { public: - QOptionTreeItemOption (int i, const void *p, const char *desc, QOptionTreeItem *pi) - : QOptionTreeItem(Option, i, p, desc, pi) + QOptionTreeItemOption (int i, const void *p, QOptionTreeItem *pi) + : QOptionTreeItem(Option, i, p, pi) { } int selected; int originallySelected; - const char *selDescription; }; class QPPDOptionsModel : public QAbstractItemModel @@ -296,6 +292,8 @@ public: void setCupsOptionsFromItems(QPrinter *printer) const; void reject(); + void updateSavedValues(); + void revertToSavedValues(); QPrintDevice *currentPrintDevice() const; QTextCodec *cupsCodec() const; @@ -313,6 +311,8 @@ private: 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; @@ -420,8 +420,14 @@ void QPrintPropertiesDialog::showEvent(QShowEvent *event) void QPrintPropertiesDialog::reject() { + widget.pageSetup->revertToSavedValues(); + +#if QT_CONFIG(cupsjobwidget) + m_jobOptions->revertToSavedValues(); +#endif + #if QT_CONFIG(cups) - m_cupsOptionsModel->reject(); + m_cupsOptionsModel->revertToSavedValues(); #endif QDialog::reject(); } @@ -437,7 +443,15 @@ void QPrintPropertiesDialog::accept() if (answer != QMessageBox::No) return; } + m_cupsOptionsModel->updateSavedValues(); +#endif + +#if QT_CONFIG(cupsjobwidget) + m_jobOptions->updateSavedValues(); #endif + + widget.pageSetup->updateSavedValues(); + QDialog::accept(); } @@ -812,9 +826,9 @@ void QPrintDialog::accept() */ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn) : parent(p), propertiesDialog(0), printer(prn), optionsPane(0), - filePrintersAdded(false), propertiesDialogShown(false) + filePrintersAdded(false) { - q = 0; + q = 0; if (parent) q = qobject_cast<QAbstractPrintDialog*> (parent->parent()); @@ -900,7 +914,6 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) if (propertiesDialog){ delete propertiesDialog; propertiesDialog = nullptr; - propertiesDialogShown = false; } if (filePrintersAdded) { @@ -993,7 +1006,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>(); @@ -1030,8 +1043,6 @@ void QUnixPrintWidgetPrivate::setupPrinterProperties() } propertiesDialog = new QPrintPropertiesDialog(q->printer(), &m_currentPrintDevice, outputFormat, printerName, q); - propertiesDialog->setResult(QDialog::Rejected); - propertiesDialogShown = false; } void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked() @@ -1039,15 +1050,6 @@ void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked() if (!propertiesDialog) setupPrinterProperties(); propertiesDialog->exec(); - if (!propertiesDialogShown && propertiesDialog->result() == QDialog::Rejected) { - // If properties dialog was rejected the dialog is deleted and - // the properties are set to defaults when printer is setup - delete propertiesDialog; - propertiesDialog = nullptr; - propertiesDialogShown = false; - } else - // properties dialog was shown and accepted - propertiesDialogShown = true; } void QUnixPrintWidgetPrivate::setupPrinter() @@ -1072,8 +1074,7 @@ void QUnixPrintWidgetPrivate::setupPrinter() if (!propertiesDialog) setupPrinterProperties(); - if (propertiesDialog->result() == QDialog::Accepted || !propertiesDialogShown) - propertiesDialog->setupPrinter(); + propertiesDialog->setupPrinter(); } /*! \internal @@ -1153,12 +1154,12 @@ QPPDOptionsModel::QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *pa , m_cupsCodec(nullptr) { ppd_file_t *ppd = m_currentPrintDevice->property(PDPK_PpdFile).value<ppd_file_t*>(); - m_rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0); + 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) { - QOptionTreeItem *group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppd->groups[i], ppd->groups[i].text, m_rootItem); + 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 @@ -1208,11 +1209,18 @@ QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: { if (index.column() == 0) { - return m_cupsCodec->toUnicode(itm->description); + 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(itmOption->selDescription); + return m_cupsCodec->toUnicode(option->choices[itmOption->selected].text); } return QVariant(); @@ -1314,7 +1322,7 @@ void QPPDOptionsModel::parseGroups(QOptionTreeItem *parent) if (group) { for (int i = 0; i < group->num_subgroups; ++i) { - QOptionTreeItem *subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], group->subgroups[i].text, parent); + QOptionTreeItem *subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], parent); parent->childItems.append(subgroup); parseGroups(subgroup); // parse possible subgroups parseOptions(subgroup); // parse options @@ -1346,7 +1354,7 @@ 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], group->options[i].text, parent); + QOptionTreeItemOption *opt = new QOptionTreeItemOption(i, &group->options[i], parent); parent->childItems.append(opt); parseChoices(opt); } @@ -1358,14 +1366,12 @@ 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) { - QOptionTreeItem *choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], option->choices[i].text, parent); + QOptionTreeItem *choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], parent); if (static_cast<int>(option->choices[i].marked) == 1) { parent->selected = i; - parent->selDescription = option->choices[i].text; marked = true; } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) { parent->selected = i; - parent->selDescription = option->choices[i].text; } parent->originallySelected = parent->selected; parent->childItems.append(choice); @@ -1436,12 +1442,13 @@ QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) co return QVariant(); } -void QPPDOptionsModel::reject() +void QPPDOptionsModel::revertToSavedValues() { - reject(m_rootItem); + revertToSavedValues(m_rootItem); + emitConflictsChanged(); } -void QPPDOptionsModel::reject(QOptionTreeItem *item) +void QPPDOptionsModel::revertToSavedValues(QOptionTreeItem *item) { if (item->type == QOptionTreeItem::Option) { QOptionTreeItemOption *itemOption = static_cast<QOptionTreeItemOption *>(item); @@ -1451,10 +1458,27 @@ void QPPDOptionsModel::reject(QOptionTreeItem *item) : 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)) - reject(child); + 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); } //////////////////////////////////////////////////////////////////////////////// @@ -1490,8 +1514,10 @@ void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) cb->addItem(QString()); const QPPDOptionsModel *m = static_cast<const QPPDOptionsModel*>(index.model()); - for (auto *childItem : qAsConst(itm->childItems)) - cb->addItem(m->cupsCodec()->toUnicode(childItem->description)); + 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)); + } if (itm->selected > -1) cb->setCurrentIndex(itm->selected); @@ -1511,7 +1537,6 @@ void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[cb->currentIndex()].choice); m->currentPrintDevice()->setProperty(PDPK_PpdOption, values); itm->selected = cb->currentIndex(); - itm->selDescription = static_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text; m->emitConflictsChanged(); } diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index afddfdb..4b27632 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -145,13 +145,19 @@ public: struct JobSheets { - BannerPage startBannerPage = QCUPSSupport::NoBanner; - BannerPage endBannerPage = QCUPSSupport::NoBanner; + 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; }; diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index 7525d7f..dcdb933 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -77,6 +77,8 @@ QCupsJobWidget::QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWi initJobBilling(); initJobPriority(); initBannerPages(); + + updateSavedValues(); } QCupsJobWidget::~QCupsJobWidget() @@ -91,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)); @@ -154,7 +177,7 @@ void QCupsJobWidget::initJobBilling() void QCupsJobWidget::setJobBilling(const QString &jobBilling) { - m_ui.jobBillingLineEdit->insert(jobBilling); + m_ui.jobBillingLineEdit->setText(jobBilling); } QString QCupsJobWidget::jobBilling() const diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index dcec27a..4b6b047 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -75,6 +75,8 @@ public: explicit QCupsJobWidget(QPrinter *printer, QPrintDevice *printDevice, QWidget *parent = nullptr); ~QCupsJobWidget(); void setupPrinter(); + void updateSavedValues(); + void revertToSavedValues(); private Q_SLOTS: void toggleJobHoldTime(); @@ -106,6 +108,11 @@ private: 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) }; -- 2.7.4 ++++++ 0013-cups-Dont-show-InstallableOptions-in-the-advanced-properties-tab.patch ++++++ >From bf59032d704f1163befc05e258a7f65887626add Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Wed, 27 Dec 2017 15:13:33 +0100 Subject: [PATCH 1/1] cups: Don't show InstallableOptions in the advanced properties According to CUPS maintainer it is recommended to not show them[1]. GTK and Libreoffice behave like that. [1] https://lists.cups.org/pipermail/cups/2015-September/027124.html Change-Id: I82614003490554d41e38a125d44e3a599c2e7342 Reviewed-by: Andy Shaw <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 29000bf..3a89c9e 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -1148,6 +1148,11 @@ void QUnixPrintWidget::updatePrinter() #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) @@ -1159,10 +1164,12 @@ QPPDOptionsModel::QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *pa if (ppd) { m_cupsCodec = QTextCodec::codecForName(ppd->lang_encoding); for (int i = 0; i < ppd->num_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 (!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 + } } } @@ -1322,10 +1329,12 @@ void QPPDOptionsModel::parseGroups(QOptionTreeItem *parent) if (group) { for (int i = 0; i < group->num_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 + 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 + } } } } -- 2.7.4 ++++++ 0014-CUPS-Enable-printing-arbitrary-pages-and-page-ranges.patch ++++++ >From 608301d4c81ce65804a088aaebbd5433a56d69d7 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 28 Dec 2017 11:22:32 +0100 Subject: [PATCH] CUPS: Enable printing arbitrary pages and page ranges Task-number: QTBUG-1311 Change-Id: I8e09def0e0d8c1404d3ee86845d98a30c23b6485 Reviewed-by: Andy Shaw <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 104 +++++++++++++++++++++++ src/printsupport/dialogs/qprintsettingsoutput.ui | 90 +++++++++++++++++--- src/printsupport/kernel/qcups.cpp | 7 +- src/printsupport/kernel/qcups_p.h | 1 + 4 files changed, 188 insertions(+), 14 deletions(-) Index: qtbase-opensource-src-5.9.4/src/printsupport/dialogs/qprintdialog_unix.cpp =================================================================== --- qtbase-opensource-src-5.9.4.orig/src/printsupport/dialogs/qprintdialog_unix.cpp +++ qtbase-opensource-src-5.9.4/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -493,6 +493,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); @@ -561,6 +564,87 @@ void QPrintDialogPrivate::selectPrinter( options.pageSetCombo->setEnabled(true); } +#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(), [](std::pair<int, int> it1, std::pair<int, int> it2) { return it1.first < it2.first; }); + int previousSecond = -1; + for (auto pair : result) { + if (pair.first <= previousSecond) + return {}; + + previousSecond = pair.second; + } + + return result; +} + +static QString stringFromPageRanges(const std::vector<std::pair<int, int>> &pageRanges) Q_DECL_NOTHROW +{ + QString result; + + for (auto pair : pageRanges) { + if (!result.isEmpty()) + result += QLatin1Char(','); + + if (pair.first == pair.second) + result += QString::number(pair.first); + else + result += QStringLiteral("%1-%2").arg(pair.first).arg(pair.second); + } + + return result; +} + +static bool isValidPagesString(const QString &pagesString) Q_DECL_NOTHROW +{ + if (pagesString.isEmpty()) + return false; + + auto pagesRanges = pageRangesFromString(pagesString); + return !pagesRanges.empty(); +} +#endif + void QPrintDialogPrivate::setupPrinter() { // First setup the requested OutputFormat, Printer and Page Size first @@ -605,6 +689,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 @@ -801,6 +895,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(); } Index: qtbase-opensource-src-5.9.4/src/printsupport/dialogs/qprintsettingsoutput.ui =================================================================== --- qtbase-opensource-src-5.9.4.orig/src/printsupport/dialogs/qprintsettingsoutput.ui +++ qtbase-opensource-src-5.9.4/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> Index: qtbase-opensource-src-5.9.4/src/printsupport/kernel/qcups.cpp =================================================================== --- qtbase-opensource-src-5.9.4.orig/src/printsupport/kernel/qcups.cpp +++ qtbase-opensource-src-5.9.4/src/printsupport/kernel/qcups.cpp @@ -254,8 +254,13 @@ void QCUPSSupport::setPagesPerSheetLayou void QCUPSSupport::setPageRange(QPrinter *printer, int pageFrom, int pageTo) { + setPageRange(printer, QStringLiteral("%1-%2").arg(pageFrom).arg(pageTo)); +} + +void QCUPSSupport::setPageRange(QPrinter *printer, const QString &pageRange) +{ QStringList cupsOptions = cupsOptionsList(printer); - setCupsOption(cupsOptions, QStringLiteral("page-ranges"), QStringLiteral("%1-%2").arg(pageFrom).arg(pageTo)); + setCupsOption(cupsOptions, QStringLiteral("page-ranges"), pageRange); setCupsOptions(printer, cupsOptions); } Index: qtbase-opensource-src-5.9.4/src/printsupport/kernel/qcups_p.h =================================================================== --- qtbase-opensource-src-5.9.4.orig/src/printsupport/kernel/qcups_p.h +++ qtbase-opensource-src-5.9.4/src/printsupport/kernel/qcups_p.h @@ -142,6 +142,7 @@ 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 { ++++++ 0015-CUPS-Dont-show-choices-that-conflict-with-the-printer-installed-options.patch ++++++ >From c45947aeefa1a83eda767edca4fd4c6f9404d3ff Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Fri, 29 Dec 2017 15:18:52 +0100 Subject: [PATCH] CUPS: Don't show choices that conflict with the printer installed options Some options only make sense if the printer has installed some extensions, e.g. we should not shown "Staple" options if the Stapler addon is not installed, so with this change we use ppdInstallableConflict to know whether an option should be shown to the user or not. Change-Id: I5733e1ac8b667c26b292aeafc90a10c155b751a4 Reviewed-by: Andy Shaw <[email protected]> --- src/plugins/printsupport/cups/qppdprintdevice.cpp | 15 +++++++- src/plugins/printsupport/cups/qppdprintdevice.h | 1 + src/printsupport/dialogs/qprintdialog_unix.cpp | 46 +++++++++++++++-------- src/printsupport/kernel/qcups_p.h | 1 + src/printsupport/kernel/qplatformprintdevice.cpp | 8 ++++ src/printsupport/kernel/qplatformprintdevice.h | 1 + src/printsupport/kernel/qprintdevice.cpp | 5 +++ src/printsupport/kernel/qprintdevice_p.h | 1 + 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 9c4b699..340b1a1 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -436,7 +436,7 @@ QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) con else if (key == PDPK_CupsJobHoldUntil) return printerOption(QStringLiteral("job-hold-until")); - return QVariant(); + return QPlatformPrintDevice::property(key); } bool QPpdPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key, const QVariant &value) @@ -449,7 +449,18 @@ bool QPpdPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key, cons } } - return false; + return QPlatformPrintDevice::setProperty(key, value); +} + +bool QPpdPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key, const QVariant ¶ms) const +{ + if (key == PDPK_PpdChoiceIsInstallableConflict) { + const QStringList values = params.toStringList(); + if (values.count() == 2) + return ppdInstallableConflict(m_ppd, values[0].toLatin1(), values[1].toLatin1()); + } + + return QPlatformPrintDevice::isFeatureAvailable(key, params); } #ifndef QT_NO_MIMETYPE diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index 2e4dd3a..9867083 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -91,6 +91,7 @@ public: QVariant property(QPrintDevice::PrintDevicePropertyKey key) const Q_DECL_OVERRIDE; bool setProperty(QPrintDevice::PrintDevicePropertyKey key, const QVariant &value) Q_DECL_OVERRIDE; + bool isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key, const QVariant ¶ms) const Q_DECL_OVERRIDE; protected: void loadPageSizes() const Q_DECL_OVERRIDE; diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index ab38c24..22d7dd1 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -271,6 +271,7 @@ public: { } + // These indices are related to ppd_option_t::choices not to childItems int selected; int originallySelected; }; @@ -1466,8 +1467,14 @@ void QPPDOptionsModel::parseOptions(QOptionTreeItem *parent) for (int i = 0; i < group->num_options; ++i) { if (!isBlacklistedOption(group->options[i].keyword)) { QOptionTreeItemOption *opt = new QOptionTreeItemOption(i, &group->options[i], parent); - parent->childItems.append(opt); 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; } } } @@ -1477,15 +1484,18 @@ 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) { - 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; + 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); } - parent->originallySelected = parent->selected; - parent->childItems.append(choice); } } @@ -1627,11 +1637,10 @@ void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) 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)); + cb->addItem(m->cupsCodec()->toUnicode(choice->text), childItem->index); + if (childItem->index == itm->selected) + cb->setCurrentIndex(cb->count() - 1); } - - if (itm->selected > -1) - cb->setCurrentIndex(itm->selected); } void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const @@ -1639,15 +1648,20 @@ void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, QComboBox *cb = static_cast<QComboBox*>(editor); QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer()); - if (itm->selected == cb->currentIndex()) + // 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[cb->currentIndex()].choice); + const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[selectedChoiceIndex].choice); m->currentPrintDevice()->setProperty(PDPK_PpdOption, values); - itm->selected = cb->currentIndex(); + itm->selected = selectedChoiceIndex; m->emitConflictsChanged(); } diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index 0afa7fa..da2b087 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE #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 { diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index 2f76156..8dba402 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -396,6 +396,14 @@ bool QPlatformPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key, 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) diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h index 8af7646..a988518 100644 --- a/src/printsupport/kernel/qplatformprintdevice.h +++ b/src/printsupport/kernel/qplatformprintdevice.h @@ -123,6 +123,7 @@ public: 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; diff --git a/src/printsupport/kernel/qprintdevice.cpp b/src/printsupport/kernel/qprintdevice.cpp index 2bc6906..50fc141 100644 --- a/src/printsupport/kernel/qprintdevice.cpp +++ b/src/printsupport/kernel/qprintdevice.cpp @@ -255,6 +255,11 @@ 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 QList<QMimeType> QPrintDevice::supportedMimeTypes() const { diff --git a/src/printsupport/kernel/qprintdevice_p.h b/src/printsupport/kernel/qprintdevice_p.h index 3dff2e5..562ccd2 100644 --- a/src/printsupport/kernel/qprintdevice_p.h +++ b/src/printsupport/kernel/qprintdevice_p.h @@ -137,6 +137,7 @@ public: 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; -- 2.7.4 ++++++ 0016-CUPS-Rework-set-clearCupsOption-API.patch ++++++ >From e35878bf57f4107fa1a49a8a4d552ea5ce1b53a9 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <[email protected]> Date: Thu, 28 Dec 2017 17:51:43 +0100 Subject: [PATCH 1/1] CUPS: Rework set/clearCupsOption API Previously it was a bit awkward to use, you had to do QStringList cupsOptions = QCUPSSupport::cupsOptionsList(printer); QCUPSSupport::setCupsOption(cupsOptions, option, value); QCUPSSupport::setCupsOptions(printer, cupsOptions); now you simply have to do QCUPSSupport::setCupsOption(printer, option, value); Change-Id: Id31583f1ec72644791d82776debbae5583a2be54 Reviewed-by: Andy Shaw <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 4 +-- src/printsupport/kernel/qcups.cpp | 44 ++++++++++---------------- src/printsupport/kernel/qcups_p.h | 6 ++-- 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 47e2fa5..ab38c24 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -1417,9 +1417,7 @@ void QPPDOptionsModel::setCupsOptionsFromItems(QPrinter *printer, QOptionTreeIte QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm); const ppd_option_t *opt = static_cast<const ppd_option_t*>(itm->ptr); if (qstrcmp(opt->defchoice, opt->choices[itmOption->selected].choice) != 0) { - QStringList cupsOptions = QCUPSSupport::cupsOptionsList(printer); - QCUPSSupport::setCupsOption(cupsOptions, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); - QCUPSSupport::setCupsOptions(printer, cupsOptions); + QCUPSSupport::setCupsOption(printer, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice)); } } else { setCupsOptionsFromItems(printer, itm); diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index 115ecb0..be170ed 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -43,33 +43,37 @@ QT_BEGIN_NAMESPACE -QStringList QCUPSSupport::cupsOptionsList(QPrinter *printer) +static QStringList cupsOptionsList(QPrinter *printer) Q_DECL_NOTHROW { return printer->printEngine()->property(PPK_CupsOptions).toStringList(); } -void QCUPSSupport::setCupsOptions(QPrinter *printer, const QStringList &cupsOptions) +void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions) Q_DECL_NOTHROW { printer->printEngine()->setProperty(PPK_CupsOptions, QVariant(cupsOptions)); } -void QCUPSSupport::setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value) +void QCUPSSupport::setCupsOption(QPrinter *printer, const QString &option, const QString &value) { + QStringList cupsOptions = cupsOptionsList(printer); if (cupsOptions.contains(option)) { cupsOptions.replace(cupsOptions.indexOf(option) + 1, value); } else { cupsOptions.append(option); cupsOptions.append(value); } + setCupsOptions(printer, cupsOptions); } -void QCUPSSupport::clearCupsOption(QStringList &cupsOptions, const QString &option) +void QCUPSSupport::clearCupsOption(QPrinter *printer, const QString &option) { + QStringList cupsOptions = cupsOptionsList(printer); // ### use const_iterator once QList::erase takes them const QStringList::iterator it = std::find(cupsOptions.begin(), cupsOptions.end(), option); if (it != cupsOptions.end()) { Q_ASSERT(it + 1 < cupsOptions.end()); cupsOptions.erase(it, it+1); + setCupsOptions(printer, cupsOptions); } } @@ -140,30 +144,24 @@ QCUPSSupport::JobHoldUntilWithTime QCUPSSupport::parseJobHoldUntil(const QString 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) @@ -209,17 +207,14 @@ QCUPSSupport::JobSheets QCUPSSupport::parseJobSheets(const QString &jobSheets) 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) { @@ -234,22 +229,19 @@ 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) @@ -259,9 +251,7 @@ void QCUPSSupport::setPageRange(QPrinter *printer, int pageFrom, int pageTo) void QCUPSSupport::setPageRange(QPrinter *printer, const QString &pageRange) { - QStringList cupsOptions = cupsOptionsList(printer); - setCupsOption(cupsOptions, QStringLiteral("page-ranges"), pageRange); - setCupsOptions(printer, cupsOptions); + 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 a5af4bc..0afa7fa 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -129,10 +129,8 @@ public: TopToBottomRightToLeft }; - static QStringList cupsOptionsList(QPrinter *printer); - static void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions); - static void setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value); - static void clearCupsOption(QStringList &cupsOptions, const QString &option); + static void setCupsOption(QPrinter *printer, const QString &option, const QString &value); + static void clearCupsOption(QPrinter *printer, const QString &option); static void setJobHold(QPrinter *printer, const JobHoldUntil jobHold = NoHold, const QTime &holdUntilTime = QTime()); static void setJobBilling(QPrinter *printer, const QString &jobBilling = QString()); -- 2.7.4 ++++++ 0017-Cups-Print-Dialog-Change-the-message-box-titles-to-C.patch ++++++ >From 6e4a330d615e5d35931658023a30cc375bcfd0e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <[email protected]> Date: Wed, 17 Jan 2018 11:42:58 +0100 Subject: [PATCH] Cups Print Dialog: Change the message box titles to Caps Amends 608301d4c81ce65804a088aaebbd5433a56d69d7. Task-number: QTBUG-1311 Change-Id: I01cd60f0676f4e0501d411151492b4f867653053 Reviewed-by: Albert Astals Cid <[email protected]> Reviewed-by: Andy Shaw <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index cac3e9ebcb..2cc5bfbb8c 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -441,7 +441,7 @@ void QPrintPropertiesDialog::accept() #if QT_CONFIG(cups) if (m_cupsOptionsModel->hasConflicts()) { widget.tabs->setCurrentWidget(widget.cupsPropertiesPage); - const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Advanced option conflicts"), + 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) @@ -916,7 +916,7 @@ 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"), + 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()), -- 2.15.1 ++++++ 0018-Fix-build-due-to-missing-QDebug-include.patch ++++++ >From a79d9da8e0bbc69053d00dd1ff1dd55c47258291 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9rgio=20Martins?= <[email protected]> Date: Mon, 8 Jan 2018 15:58:57 +0000 Subject: [PATCH] Fix build due to missing QDebug include The build just passes on Qt CI by chance. Change-Id: I3bfef12b48df22fa64d92af9cd345bfc984c9923 Reviewed-by: David Faure <[email protected]> --- src/printsupport/dialogs/qprintdialog_unix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index fcb53f4..02d6903 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -48,6 +48,7 @@ #if QT_CONFIG(filedialog) #include "qfiledialog.h" #endif +#include <QtCore/qdebug.h> #include <QtCore/qdir.h> #include <QtCore/qtextcodec.h> #include <QtGui/qevent.h> -- 2.7.4
