From 926a0886d1961a3f384d3e6c36919e6dd8055dce Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Mon, 8 Apr 2019 13:25:54 +0200 Subject: Support multiple page ranges in QPrinter Add a new QRangeCollection type to store and manage multiple page ranges. This moves out the parser and validator logic from the platform dependent (UNIX) dialog and makes it publicly available from QPrinter. This improves the usability of QPrinter in those applications which doesn't use print dialog to configure printer. (e.g.: QTextDocument, QWebEnginePage) Change-Id: I0be5a8a64781c411f83b96a24f216605a84958e5 Reviewed-by: Qt CI Bot Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Leena Miettinen --- src/printsupport/dialogs/qprintdialog_unix.cpp | 90 ++------------------------ src/printsupport/kernel/qprinter.cpp | 31 +++++---- src/printsupport/kernel/qprinter.h | 3 + 3 files changed, 28 insertions(+), 96 deletions(-) (limited to 'src/printsupport') diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index a59d8bbb4a..cc6694d471 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -745,85 +746,6 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma } #if QT_CONFIG(cups) -static std::vector> pageRangesFromString(const QString &pagesString) noexcept -{ - std::vector> result; - const QStringList items = pagesString.split(','); - for (const QString &item : items) { - if (item.isEmpty()) - return {}; - - if (item.contains(QLatin1Char('-'))) { - const QStringList rangeItems = item.split('-'); - if (rangeItems.count() != 2) - return {}; - - bool ok; - const int number1 = rangeItems[0].toInt(&ok); - if (!ok) - return {}; - - const int number2 = rangeItems[1].toInt(&ok); - if (!ok) - return {}; - - if (number1 < 1 || number2 < 1 || number2 < number1) - return {}; - - result.push_back(std::make_pair(number1, number2)); - - } else { - bool ok; - const int number = item.toInt(&ok); - if (!ok) - return {}; - - if (number < 1) - return {}; - - result.push_back(std::make_pair(number, number)); - } - } - - // check no range intersects with the next - std::sort(result.begin(), result.end(), - [](const std::pair &it1, const std::pair &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> &pageRanges) noexcept -{ - 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) noexcept -{ - if (pagesString.isEmpty()) - return false; - - auto pagesRanges = pageRangesFromString(pagesString); - return !pagesRanges.empty(); -} void QPrintDialogPrivate::updatePpdDuplexOption(QRadioButton *radio) { @@ -894,13 +816,11 @@ 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); + p->setPrintRange(QPrinter::PageRange); + p->rangeCollection()->parse(options.pagesLineEdit->text()); // server-side page filtering - QCUPSSupport::setPageRange(p, stringFromPageRanges(pageRanges)); + QCUPSSupport::setPageRange(p, p->rangeCollection()->toString()); } // page set @@ -1100,7 +1020,7 @@ void QPrintDialog::accept() { Q_D(QPrintDialog); #if QT_CONFIG(cups) - if (d->options.pagesRadioButton->isChecked() && !isValidPagesString(d->options.pagesLineEdit->text())) { + if (d->options.pagesRadioButton->isChecked() && printer()->rangeCollection()->isEmpty()) { 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 " diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index fbf5e5c2ba..25855d6da7 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -49,6 +49,7 @@ #include "qlist.h" #include #include +#include #include @@ -1981,12 +1982,12 @@ void QPrinter::setPrinterSelectionOption(const QString &option) \note If fromPage() and toPage() both return 0, this indicates that \e{the whole document will be printed}. - \sa setFromTo(), toPage() + \sa setFromTo(), toPage(), rangeCollection() */ int QPrinter::fromPage() const { - return d->fromPage; + return d->rangeCollection->firstPage(); } /*! @@ -2005,12 +2006,12 @@ int QPrinter::fromPage() const The programmer is responsible for reading this setting and printing accordingly. - \sa setFromTo(), fromPage() + \sa setFromTo(), fromPage(), rangeCollection() */ int QPrinter::toPage() const { - return d->toPage; + return d->rangeCollection->lastPage(); } /*! @@ -2027,17 +2028,25 @@ int QPrinter::toPage() const This function is mostly used to set a default value that the user can override in the print dialog when you call setup(). - \sa fromPage(), toPage() + \sa fromPage(), toPage(), rangeCollection() */ void QPrinter::setFromTo(int from, int to) { - if (from > to) { - qWarning("QPrinter::setFromTo: 'from' must be less than or equal to 'to'"); - from = to; - } - d->fromPage = from; - d->toPage = to; + d->rangeCollection->clear(); + d->rangeCollection->addRange(from, to); +} + +/*! + \since 6.0 + + Returns the range collection associated with this device. + + \sa QRangeCollection, fromPage(), toPage() +*/ +QRangeCollection *QPrinter::rangeCollection() +{ + return d->rangeCollection; } /*! diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h index 28dca78a63..e606ceba47 100644 --- a/src/printsupport/kernel/qprinter.h +++ b/src/printsupport/kernel/qprinter.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE #endif class QPrinterPrivate; +class QRangeCollection; class QPaintEngine; class QPrintEngine; class QPrinterInfo; @@ -249,6 +250,8 @@ public: int fromPage() const; int toPage() const; + QRangeCollection *rangeCollection(); + void setPrintRange(PrintRange range); PrintRange printRange() const; -- cgit v1.2.3