summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/painting/painting.pri3
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp1
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h7
-rw-r--r--src/gui/painting/qrangecollection.cpp281
-rw-r--r--src/gui/painting/qrangecollection.h78
-rw-r--r--src/gui/painting/qrangecollection_p.h76
-rw-r--r--src/gui/text/qtextdocument.cpp8
8 files changed, 448 insertions, 7 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index ae86e5edf2..eaf24bc658 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -186,6 +186,7 @@ qt_add_module(Gui
painting/qplatformbackingstore.cpp painting/qplatformbackingstore.h
painting/qpolygon.cpp painting/qpolygon.h
painting/qpolygonclipper_p.h
+ painting/qrangecollection.cpp painting/qrangecollection.h painting/qrangecollection_p.h
painting/qrasterdefs_p.h
painting/qrasterizer.cpp painting/qrasterizer_p.h
painting/qrbtree_p.h
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 21a40540c4..4d32c592d1 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -49,6 +49,8 @@ HEADERS += \
painting/qpen.h \
painting/qpolygon.h \
painting/qpolygonclipper_p.h \
+ painting/qrangecollection.h \
+ painting/qrangecollection_p.h \
painting/qrasterdefs_p.h \
painting/qrasterizer_p.h \
painting/qrbtree_p.h \
@@ -99,6 +101,7 @@ SOURCES += \
painting/qpdfwriter.cpp \
painting/qpen.cpp \
painting/qpolygon.cpp \
+ painting/qrangecollection.cpp \
painting/qrasterizer.cpp \
painting/qregion.cpp \
painting/qstroker.cpp \
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 3fdd0206b7..e6d3a38427 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -80,6 +80,7 @@ class QDummyPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate()
{
+ delete rangeCollection;
}
/*!
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index 3a43bd7828..1717727be4 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -53,6 +53,7 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <qpagedpaintdevice.h>
+#include <qrangecollection.h>
QT_BEGIN_NAMESPACE
@@ -60,8 +61,7 @@ class Q_GUI_EXPORT QPagedPaintDevicePrivate
{
public:
QPagedPaintDevicePrivate()
- : fromPage(0),
- toPage(0),
+ : rangeCollection(new QRangeCollection),
pageOrderAscending(true),
printSelectionOnly(false)
{
@@ -83,8 +83,7 @@ public:
static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
// These are currently required to keep QPrinter functionality working in QTextDocument::print()
- int fromPage;
- int toPage;
+ QRangeCollection *rangeCollection;
bool pageOrderAscending;
bool printSelectionOnly;
};
diff --git a/src/gui/painting/qrangecollection.cpp b/src/gui/painting/qrangecollection.cpp
new file mode 100644
index 0000000000..9acb36a000
--- /dev/null
+++ b/src/gui/painting/qrangecollection.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qrangecollection.h"
+#include "qrangecollection_p.h"
+
+#include <QtCore/qstack.h>
+
+QT_BEGIN_NAMESPACE
+
+void QRangeCollectionPrivate::mergeIntervals()
+{
+ const int count = intervals.count();
+
+ if (count <= 0)
+ return;
+
+ std::sort(intervals.begin(), intervals.end());
+
+ QStack<QPair<int, int>> stack;
+ stack.push(intervals[0]);
+
+ for (int i = 1; i < count; i++) {
+ QPair<int, int> &top = stack.top();
+
+ if (top.second < intervals[i].first)
+ stack.push(intervals[i]);
+ else if (top.second < intervals[i].second)
+ top.second = intervals[i].second;
+ }
+
+ std::sort(intervals.begin(), intervals.end());
+
+ intervals = stack;
+}
+
+/*!
+ \class QRangeCollection
+ \brief The QRangeCollection class represents a collection of decimal intervals.
+ \inmodule QtGui
+ \ingroup painting
+ \since 6.0
+
+ QRangeCollection manages a set of decimal intervals.
+
+ Use QPrinter::rangeCollection() to access the collection of page ranges
+ associated with a QPrinter.
+*/
+
+QRangeCollection::QRangeCollection()
+ : d_ptr(new QRangeCollectionPrivate(this))
+{
+}
+
+/*!
+ Destroys the collection.
+*/
+QRangeCollection::~QRangeCollection()
+{
+}
+
+/*!
+ Inserts a single number into the collection.
+ */
+void QRangeCollection::addPage(int pageNumber)
+{
+ Q_D(QRangeCollection);
+ if (pageNumber <= 0) {
+ qWarning("QRangeCollection::addPage: 'pageNumber' must be greater than 0");
+ return;
+ }
+ d->intervals.append(qMakePair(pageNumber, pageNumber));
+ d->mergeIntervals();
+}
+
+/*!
+ Inserts a range into the collection.
+ */
+void QRangeCollection::addRange(int from, int to)
+{
+ Q_D(QRangeCollection);
+ if (from <= 0 || to <= 0) {
+ qWarning("QRangeCollection::addRange: 'from' and 'to' must be greater than 0");
+ return;
+ }
+ if (to < from) {
+ qWarning("QRangeCollection::addRange: 'from' must be less than or equal to 'to'");
+ std::swap(from, to);
+ }
+ d->intervals.append(qMakePair(from, to));
+ d->mergeIntervals();
+}
+
+/*!
+ Returns a list with the values of the ranges used in this collection.
+ */
+QList<QPair<int, int>> QRangeCollection::toList() const
+{
+ Q_D(const QRangeCollection);
+ return d->intervals.toList();
+}
+
+/*!
+ * Removes all ranges from this collection.
+ */
+void QRangeCollection::clear()
+{
+ Q_D(QRangeCollection);
+ d->intervals.clear();
+}
+
+/*!
+ Constructs the range collection from a string representation.
+
+ \code
+ QPrinter printer;
+ printer->rangeCollection()->parse("1-3,6-7");
+ \endcode
+ */
+bool QRangeCollection::parse(const QString &ranges)
+{
+ Q_D(QRangeCollection);
+ const QStringList items = ranges.split(',');
+ for (const QString &item : items) {
+ if (item.isEmpty()) {
+ d->intervals.clear();
+ return false;
+ }
+
+ if (item.contains(QLatin1Char('-'))) {
+ const QStringList rangeItems = item.split('-');
+ if (rangeItems.count() != 2) {
+ d->intervals.clear();
+ return false;
+ }
+
+ bool ok;
+ const int number1 = rangeItems[0].toInt(&ok);
+ if (!ok) {
+ d->intervals.clear();
+ return false;
+ }
+
+ const int number2 = rangeItems[1].toInt(&ok);
+ if (!ok) {
+ d->intervals.clear();
+ return false;
+ }
+
+ if (number1 < 1 || number2 < 1 || number2 < number1) {
+ d->intervals.clear();
+ return false;
+ }
+
+ d->intervals.append(qMakePair(number1, number2));
+
+ } else {
+ bool ok;
+ const int number = item.toInt(&ok);
+ if (!ok) {
+ d->intervals.clear();
+ return false;
+ }
+
+ if (number < 1) {
+ d->intervals.clear();
+ return false;
+ }
+
+ d->intervals.append(qMakePair(number, number));
+ }
+ }
+
+ d->mergeIntervals();
+ return true;
+}
+
+/*!
+ Returns the string representation of the ranges in the collection.
+ */
+QString QRangeCollection::toString() const
+{
+ Q_D(const QRangeCollection);
+ QString result;
+
+ for (const QPair<int, int> &pair : d->intervals) {
+ 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;
+}
+
+/*!
+ Returns \c true if the collection contains an occurrence
+ or a bounding range of \a pageNumber; otherwise returns
+ \c false.
+ */
+bool QRangeCollection::contains(int pageNumber) const
+{
+ Q_D(const QRangeCollection);
+ for (const QPair<int, int> &pair : d->intervals) {
+ if (pair.first <= pageNumber && pair.second >= pageNumber)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns \c true if the collection is empty; otherwise returns \c false.
+*/
+bool QRangeCollection::isEmpty() const
+{
+ Q_D(const QRangeCollection);
+ return d->intervals.isEmpty();
+}
+
+/*!
+ Returns the index of the first page covered by the range collection.
+*/
+int QRangeCollection::firstPage() const
+{
+ Q_D(const QRangeCollection);
+ if (d->intervals.isEmpty())
+ return 0;
+ return d->intervals.first().first;
+}
+
+/*!
+ Returns the index of the last page covered by the range collection.
+*/
+int QRangeCollection::lastPage() const
+{
+ Q_D(const QRangeCollection);
+ if (d->intervals.isEmpty())
+ return 0;
+ return d->intervals.last().second;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qrangecollection.h b/src/gui/painting/qrangecollection.h
new file mode 100644
index 0000000000..310adaab05
--- /dev/null
+++ b/src/gui/painting/qrangecollection.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRANGECOLLECTION_H
+#define QRANGECOLLECTION_H
+
+#include <QtGui/qtguiglobal.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class QRangeCollectionPrivate;
+
+class Q_GUI_EXPORT QRangeCollection
+{
+ Q_DECLARE_PRIVATE(QRangeCollection)
+public:
+ explicit QRangeCollection();
+ ~QRangeCollection();
+
+ void addPage(int pageNumber);
+ void addRange(int from, int to);
+ QList<QPair<int, int>> toList() const;
+ void clear();
+
+ bool parse(const QString &ranges);
+ QString toString() const;
+
+ bool contains(const int pageNumber) const;
+ bool isEmpty() const;
+ int firstPage() const;
+ int lastPage() const;
+
+private:
+ QScopedPointer<QRangeCollectionPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QRANGECOLLECTION_H
diff --git a/src/gui/painting/qrangecollection_p.h b/src/gui/painting/qrangecollection_p.h
new file mode 100644
index 0000000000..9f930c18d3
--- /dev/null
+++ b/src/gui/painting/qrangecollection_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRANGECOLLECTION_P_H
+#define QRANGECOLLECTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtGui/private/qtguiglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QRangeCollectionPrivate
+{
+ Q_DECLARE_PUBLIC(QRangeCollection)
+public:
+ QRangeCollectionPrivate(QRangeCollection *rangeCollection)
+ : q_ptr(rangeCollection)
+ {
+ }
+
+ void mergeIntervals();
+
+ QVector<QPair<int, int>> intervals;
+ QRangeCollection *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QRANGECOLLECTION_P_H
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 2b712c54b0..be95e2177d 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1928,8 +1928,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
clonedDoc->setPageSize(body.size());
}
- int fromPage = pd->fromPage;
- int toPage = pd->toPage;
+ QRangeCollection *rangeCollection = pd->rangeCollection;
+ int fromPage = rangeCollection->firstPage();
+ int toPage = rangeCollection->lastPage();
if (fromPage == 0 && toPage == 0) {
fromPage = 1;
@@ -1955,7 +1956,8 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
int page = fromPage;
while (true) {
- printPage(page, &p, doc, body, pageNumberPos);
+ if (rangeCollection->isEmpty() || rangeCollection->contains(page))
+ printPage(page, &p, doc, body, pageNumberPos);
if (page == toPage)
break;