File 0014-CUPS-Enable-printing-arbitrary-pages-and-page-ranges.patch of Package libqt5-qtbase.18762
From 608301d4c81ce65804a088aaebbd5433a56d69d7 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
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 <andy.shaw@qt.io>
---
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
{