summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-02 21:39:34 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-08 11:49:54 +0100
commitb14b1c99f8d122c7988cd6e59b0f3fef15923da4 (patch)
treec876d2428f7be32a73a1d066fa2d703b59708a1e
parent8bf36025f5602e3067448941ee4d0ccca3928a40 (diff)
Rename QRangeCollection to QPageRanges, make it a proper value type
The type is specific about printing, so give it a name in line with QPageLayout and QPageSize. As per API review comment, it's not clear why this type should not be a regular, copyable and movable value type. It stores a list of intervals. Give it value-type semantics, as an implicitly shared class. Convert the parse method into a static factory function. Add a Range type and use it instead of the semantic-free QPair. Move QPrinter getter into QPagedPainteDevice, make it return a copy rather than a pointer, and add a setter. Extend test case to cover all members and more merge cases. Fix bugs found that way. Fixes: QTBUG-88113 Change-Id: If17ea4d410d49f16b097e88b7979db5d72add820 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--src/gui/.prev_CMakeLists.txt2
-rw-r--r--src/gui/CMakeLists.txt2
-rw-r--r--src/gui/painting/painting.pri6
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp30
-rw-r--r--src/gui/painting/qpagedpaintdevice.h6
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h6
-rw-r--r--src/gui/painting/qpageranges.cpp365
-rw-r--r--src/gui/painting/qpageranges.h (renamed from src/gui/painting/qrangecollection.h)68
-rw-r--r--src/gui/painting/qpageranges_p.h (renamed from src/gui/painting/qrangecollection_p.h)17
-rw-r--r--src/gui/painting/qrangecollection.cpp285
-rw-r--r--src/gui/text/qtextdocument.cpp10
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp12
-rw-r--r--src/printsupport/kernel/qprinter.cpp27
-rw-r--r--src/printsupport/kernel/qprinter.h4
-rw-r--r--tests/auto/gui/painting/CMakeLists.txt2
-rw-r--r--tests/auto/gui/painting/painting.pro2
-rw-r--r--tests/auto/gui/painting/qpageranges/CMakeLists.txt (renamed from tests/auto/gui/painting/qrangecollection/CMakeLists.txt)8
-rw-r--r--tests/auto/gui/painting/qpageranges/qpageranges.pro6
-rw-r--r--tests/auto/gui/painting/qpageranges/tst_qpageranges.cpp183
-rw-r--r--tests/auto/gui/painting/qrangecollection/qrangecollection.pro6
-rw-r--r--tests/auto/gui/painting/qrangecollection/tst_qrangecollection.cpp75
21 files changed, 674 insertions, 448 deletions
diff --git a/src/gui/.prev_CMakeLists.txt b/src/gui/.prev_CMakeLists.txt
index f86e2bd89f..d61adbb619 100644
--- a/src/gui/.prev_CMakeLists.txt
+++ b/src/gui/.prev_CMakeLists.txt
@@ -124,6 +124,7 @@ qt_internal_add_module(Gui
painting/qoutlinemapper.cpp painting/qoutlinemapper_p.h
painting/qpagedpaintdevice.cpp painting/qpagedpaintdevice.h painting/qpagedpaintdevice_p.h
painting/qpagelayout.cpp painting/qpagelayout.h
+ painting/qpageranges.cpp painting/qpageranges.h painting/qpageranges_p.h
painting/qpagesize.cpp painting/qpagesize.h
painting/qpaintdevice.cpp painting/qpaintdevice.h
painting/qpaintengine.cpp painting/qpaintengine.h painting/qpaintengine_p.h
@@ -140,7 +141,6 @@ qt_internal_add_module(Gui
painting/qpixellayout.cpp painting/qpixellayout_p.h
painting/qplatformbackingstore.cpp painting/qplatformbackingstore.h
painting/qpolygon.cpp painting/qpolygon.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/CMakeLists.txt b/src/gui/CMakeLists.txt
index 1d4d44894b..6cd7429f79 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -175,6 +175,7 @@ qt_internal_add_module(Gui
painting/qoutlinemapper.cpp painting/qoutlinemapper_p.h
painting/qpagedpaintdevice.cpp painting/qpagedpaintdevice.h painting/qpagedpaintdevice_p.h
painting/qpagelayout.cpp painting/qpagelayout.h
+ painting/qpageranges.cpp painting/qpageranges.h painting/qpageranges_p.h
painting/qpagesize.cpp painting/qpagesize.h
painting/qpaintdevice.cpp painting/qpaintdevice.h
painting/qpaintengine.cpp painting/qpaintengine.h painting/qpaintengine_p.h
@@ -191,7 +192,6 @@ qt_internal_add_module(Gui
painting/qpixellayout.cpp painting/qpixellayout_p.h
painting/qplatformbackingstore.cpp painting/qplatformbackingstore.h
painting/qpolygon.cpp painting/qpolygon.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 ccd67e12b3..1262b1775c 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -31,6 +31,8 @@ HEADERS += \
painting/qpagedpaintdevice.h \
painting/qpagedpaintdevice_p.h \
painting/qpagelayout.h \
+ painting/qpageranges.h \
+ painting/qpageranges_p.h \
painting/qpagesize.h \
painting/qpaintdevice.h \
painting/qpaintengine.h \
@@ -49,8 +51,6 @@ HEADERS += \
painting/qpen.h \
painting/qpixellayout_p.h \
painting/qpolygon.h \
- painting/qrangecollection.h \
- painting/qrangecollection_p.h \
painting/qrasterdefs_p.h \
painting/qrasterizer_p.h \
painting/qrbtree_p.h \
@@ -88,6 +88,7 @@ SOURCES += \
painting/qoutlinemapper.cpp \
painting/qpagedpaintdevice.cpp \
painting/qpagelayout.cpp \
+ painting/qpageranges.cpp \
painting/qpagesize.cpp \
painting/qpaintdevice.cpp \
painting/qpaintengine.cpp \
@@ -102,7 +103,6 @@ SOURCES += \
painting/qpen.cpp \
painting/qpixellayout.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 9d09fb6f04..1e32f2c2bc 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -42,10 +42,8 @@
QT_BEGIN_NAMESPACE
-QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate()
-{
- delete rangeCollection;
-}
+
+QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate() = default;
/*!
\class QPagedPaintDevice
@@ -213,4 +211,26 @@ QPageLayout QPagedPaintDevice::pageLayout() const
return d->pageLayout();
}
+/*!
+ \since 6.0
+
+ Returns the page ranges associated with this device.
+
+ \sa QPageRanges, QPrinter::fromPage(), QPrinter::toPage()
+*/
+QPageRanges QPagedPaintDevice::pageRanges() const
+{
+ return d->pageRanges;
+}
+
+/*!
+ \since 6.0
+
+ Sets the page ranges for this device to \a ranges.
+*/
+void QPagedPaintDevice::setPageRanges(const QPageRanges &ranges)
+{
+ d->pageRanges = ranges;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index ab304250c9..dedff446b8 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -43,6 +43,7 @@
#include <QtGui/qtguiglobal.h>
#include <QtGui/qpaintdevice.h>
#include <QtGui/qpagelayout.h>
+#include <QtGui/qpageranges.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +69,9 @@ public:
virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Millimeter);
QPageLayout pageLayout() const;
+ virtual void setPageRanges(const QPageRanges &ranges);
+ QPageRanges pageRanges() const;
+
protected:
QPagedPaintDevice(QPagedPaintDevicePrivate *dd);
QPagedPaintDevicePrivate *dd();
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index 1717727be4..4099846de5 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -53,7 +53,6 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <qpagedpaintdevice.h>
-#include <qrangecollection.h>
QT_BEGIN_NAMESPACE
@@ -61,8 +60,7 @@ class Q_GUI_EXPORT QPagedPaintDevicePrivate
{
public:
QPagedPaintDevicePrivate()
- : rangeCollection(new QRangeCollection),
- pageOrderAscending(true),
+ : pageOrderAscending(true),
printSelectionOnly(false)
{
}
@@ -83,7 +81,7 @@ public:
static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
// These are currently required to keep QPrinter functionality working in QTextDocument::print()
- QRangeCollection *rangeCollection;
+ QPageRanges pageRanges;
bool pageOrderAscending;
bool printSelectionOnly;
};
diff --git a/src/gui/painting/qpageranges.cpp b/src/gui/painting/qpageranges.cpp
new file mode 100644
index 0000000000..0d66014d83
--- /dev/null
+++ b/src/gui/painting/qpageranges.cpp
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** 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 "qpageranges.h"
+#include "qpageranges_p.h"
+
+#include <QtCore/qstack.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+void QPageRangesPrivate::mergeIntervals()
+{
+ const int count = intervals.count();
+
+ if (count <= 1)
+ return;
+
+ std::sort(intervals.begin(), intervals.end());
+
+ QStack<QPageRanges::Range> stack;
+ stack.push(intervals[0]);
+
+ for (int i = 1; i < count; ++i) {
+ QPageRanges::Range &top = stack.top();
+
+ if (top.to < intervals[i].from - 1)
+ stack.push(intervals[i]);
+ else if (top.to < intervals[i].to)
+ top.to = intervals[i].to;
+ }
+
+ intervals = stack;
+}
+
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPageRangesPrivate)
+
+/*!
+ \class QPageRanges
+ \brief The QPageRanges class represents a collection of page ranges.
+ \inmodule QtGui
+ \ingroup painting
+ \ingroup printing
+ \ingroup shared
+ \since 6.0
+
+ Use QPagedPaintDevice::pageRanges() to access the collection of page ranges
+ associated with a paged device.
+*/
+
+/*!
+ Constructs an empty QPageRanges object.
+*/
+QPageRanges::QPageRanges() = default;
+
+/*!
+ Constructs a QPageRanges object by copying \a other.
+*/
+QPageRanges::QPageRanges(const QPageRanges &other) noexcept = default;
+
+/*!
+ \fn QPageRanges::QPageRanges(QPageRanges &&other)
+
+ Constructs a QPageRanges object by moving from \a other.
+*/
+
+/*!
+ Destroys the page ranges.
+*/
+QPageRanges::~QPageRanges() = default;
+
+/*!
+ Assigns \a other to this QPageRanges object.
+*/
+QPageRanges &QPageRanges::operator=(const QPageRanges &other) noexcept = default;
+
+/*!
+ \fn QPageRanges &QPageRanges::operator=(QPageRanges &&other)
+ Moves \a other into this QPageRanges object.
+*/
+
+/*!
+ Adds the single page \a pageNumber to the ranges.
+
+ \note Page numbers start with 1. Attempts to add page numbers
+ smaller than 1 will be ignored with a warning.
+*/
+void QPageRanges::addPage(int pageNumber)
+{
+ if (pageNumber <= 0) {
+ qWarning("QPageRanges::addPage: 'pageNumber' must be greater than 0");
+ return;
+ }
+
+ detach();
+ d->intervals.append({ pageNumber, pageNumber });
+ d->mergeIntervals();
+}
+
+/*!
+ Adds the range specified with \a from and \a to to the ranges.
+
+ \note Page numbers start with 1. Attempts to add page numbers
+ smaller than 1 will be ignored with a warning.
+*/
+void QPageRanges::addRange(int from, int to)
+{
+ if (from <= 0 || to <= 0) {
+ qWarning("QPageRanges::addRange: 'from' and 'to' must be greater than 0");
+ return;
+ }
+ if (to < from)
+ std::swap(from, to);
+
+ detach();
+ d->intervals.append({from, to});
+ d->mergeIntervals();
+}
+
+/*!
+ Returns a list with the values of the ranges.
+*/
+QList<QPageRanges::Range> QPageRanges::toRangeList() const
+{
+ if (d)
+ return d->intervals;
+ return QList<QPageRanges::Range>{};
+}
+
+/*!
+ Removes all page ranges.
+*/
+void QPageRanges::clear()
+{
+ d.reset();
+}
+
+/*!
+ Constructs and returns a QPageRanges object populated with the
+ \a ranges from the string representation.
+
+ \code
+ QPrinter printer;
+ QPageRanges ranges = QPageRanges::fromString("1-3,6-7");
+ printer.setPageRanges(ranges);
+ \endcode
+
+ In case of parsing error, returns an empty QPageRanges object.
+
+ \sa isEmpty()
+*/
+QPageRanges QPageRanges::fromString(const QString &ranges)
+{
+ QList<Range> intervals;
+ const QStringList items = ranges.split(u',');
+ for (const QString &item : items) {
+ if (item.isEmpty())
+ return QPageRanges();
+
+ if (item.contains(QLatin1Char('-'))) {
+ const QStringList rangeItems = item.split(u'-');
+ if (rangeItems.count() != 2)
+ return QPageRanges();
+
+ bool ok;
+ const int number1 = rangeItems[0].toInt(&ok);
+ if (!ok)
+ return QPageRanges();
+
+ const int number2 = rangeItems[1].toInt(&ok);
+ if (!ok)
+ return QPageRanges();
+
+ if (number1 < 1 || number2 < 1 || number2 < number1)
+ return QPageRanges();
+
+ intervals.append({number1, number2});
+
+ } else {
+ bool ok;
+ const int number = item.toInt(&ok);
+ if (!ok)
+ return QPageRanges();
+
+ if (number < 1)
+ return QPageRanges();
+
+ intervals.append({number, number});
+ }
+ }
+
+ QPageRanges newRanges;
+ newRanges.d.reset(new QPageRangesPrivate);
+ newRanges.d->intervals = intervals;
+ newRanges.d->mergeIntervals();
+ return newRanges;
+}
+
+/*!
+ Returns the string representation of the page ranges.
+*/
+QString QPageRanges::toString() const
+{
+ if (!d)
+ return QString();
+
+ QString result;
+ for (const Range &range : d->intervals) {
+ if (!result.isEmpty())
+ result += QLatin1Char(',');
+
+ if (range.from == range.to)
+ result += QString::number(range.from);
+ else
+ result += QStringLiteral("%1-%2").arg(range.from).arg(range.to);
+ }
+
+ return result;
+}
+
+/*!
+ \fn bool QPageRanges::contains(int pageNumber) const
+
+ Returns \c true if the ranges include the page \a pageNumber;
+ otherwise returns \c false.
+*/
+bool QPageRanges::contains(int pageNumber) const
+{
+ if (!d)
+ return false;
+
+ for (const Range &range : d->intervals) {
+ if (range.from <= pageNumber && range.to >= pageNumber)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns \c true if the ranges are empty; otherwise returns \c false.
+*/
+bool QPageRanges::isEmpty() const
+{
+ return !d || d->intervals.isEmpty();
+}
+
+/*!
+ Returns the index of the first page covered by the page ranges,
+ or 0 if the page ranges are empty.
+*/
+int QPageRanges::firstPage() const
+{
+ if (isEmpty())
+ return 0;
+ return d->intervals.first().from;
+}
+
+/*!
+ Returns the index of the last page covered by the page ranges,
+ or 0 if the page ranges are empty.
+*/
+int QPageRanges::lastPage() const
+{
+ if (isEmpty())
+ return 0;
+ return d->intervals.last().to;
+}
+
+/*!
+ \internal
+*/
+bool QPageRanges::isEqual(const QPageRanges &other) const noexcept
+{
+ if (d == other.d)
+ return true;
+ if (!d || !other.d)
+ return false;
+ return d->intervals == other.d->intervals;
+}
+
+/*!
+ \internal
+*/
+void QPageRanges::detach()
+{
+ if (d)
+ d.detach();
+ else
+ d.reset(new QPageRangesPrivate);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPageRanges &pageRanges)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg.noquote();
+ dbg << "QPageRanges(" << pageRanges.toString() << ")";
+
+ return dbg;
+}
+#endif
+
+/*!
+ \struct QPageRanges::Range
+ \brief The QPageRanges::Range struct holds the \c from and \c to endpoints of a range.
+
+ \sa QPageRanges::toRangeList()
+*/
+
+/*!
+ \variable QPageRanges::Range::from
+ \brief the lower endpoint of the range
+*/
+
+/*!
+ \variable QPageRanges::Range::to
+ \brief the upper endpoint of the range
+*/
+
+/*!
+ \fn bool QPageRanges::Range::contains(int pageNumber) const
+
+ Returns \c true if \a pageNumber is within the interval \c{[from, to]};
+ otherwise returns \c false.
+*/
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qrangecollection.h b/src/gui/painting/qpageranges.h
index b63ceb6b74..481fee109b 100644
--- a/src/gui/painting/qrangecollection.h
+++ b/src/gui/painting/qpageranges.h
@@ -37,42 +37,82 @@
**
****************************************************************************/
-#ifndef QRANGECOLLECTION_H
-#define QRANGECOLLECTION_H
+#ifndef QPAGERANGES_H
+#define QPAGERANGES_H
#include <QtGui/qtguiglobal.h>
+#include <QtCore/qstring.h>
#include <QtCore/qlist.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qscopedpointer.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
QT_BEGIN_NAMESPACE
-class QRangeCollectionPrivate;
+class QDebug;
+class QPageRangesPrivate;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QPageRangesPrivate, Q_GUI_EXPORT)
-class Q_GUI_EXPORT QRangeCollection
+class Q_GUI_EXPORT QPageRanges
{
- Q_DECLARE_PRIVATE(QRangeCollection)
public:
- explicit QRangeCollection();
- ~QRangeCollection();
+ QPageRanges();
+ ~QPageRanges();
+
+ QPageRanges(const QPageRanges &other) noexcept;
+ QPageRanges &operator=(const QPageRanges &other) noexcept;
+
+ QPageRanges(QPageRanges &&other) noexcept = default;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QPageRanges)
+ void swap(QPageRanges &other) noexcept
+ { qSwap(d, other.d); }
+
+ friend bool operator==(const QPageRanges &lhs, const QPageRanges &rhs) noexcept
+ { return lhs.isEqual(rhs); }
+ friend bool operator!=(const QPageRanges &lhs, const QPageRanges &rhs) noexcept
+ { return !lhs.isEqual(rhs); }
+
+ struct Range {
+ int from = -1;
+ int to = -1;
+ bool contains(int pageNumber) const noexcept
+ { return from <= pageNumber && to >= pageNumber; }
+ friend bool operator==(Range lhs, Range rhs) noexcept
+ { return lhs.from == rhs.from && lhs.to == rhs.to; }
+ friend bool operator!=(Range lhs, Range rhs) noexcept
+ { return !(lhs == rhs); }
+ friend bool operator<(Range lhs, Range rhs) noexcept
+ { return lhs.from < rhs.from || (!(rhs.from < lhs.from) && lhs.to < rhs.to); }
+ };
void addPage(int pageNumber);
void addRange(int from, int to);
- QList<QPair<int, int>> toList() const;
+ QList<Range> toRangeList() const;
void clear();
- bool parse(const QString &ranges);
QString toString() const;
+ static QPageRanges fromString(const QString &ranges);
- bool contains(const int pageNumber) const;
+ bool contains(int pageNumber) const;
bool isEmpty() const;
int firstPage() const;
int lastPage() const;
private:
- QScopedPointer<QRangeCollectionPrivate> d_ptr;
+ bool isEqual(const QPageRanges &other) const noexcept;
+ void detach();
+
+ QExplicitlySharedDataPointer<QPageRangesPrivate> d;
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageRanges &pageRanges);
+#endif
+
+Q_DECLARE_SHARED(QPageRanges)
+Q_DECLARE_TYPEINFO(QPageRanges::Range, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
-#endif // QRANGECOLLECTION_H
+Q_DECLARE_METATYPE(QPageRanges)
+
+#endif // QPAGERANGES_H
diff --git a/src/gui/painting/qrangecollection_p.h b/src/gui/painting/qpageranges_p.h
index 39a52f2a6b..82b03224f3 100644
--- a/src/gui/painting/qrangecollection_p.h
+++ b/src/gui/painting/qpageranges_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QRANGECOLLECTION_P_H
-#define QRANGECOLLECTION_P_H
+#ifndef QPAGERANGES_P_H
+#define QPAGERANGES_P_H
//
// W A R N I N G
@@ -56,21 +56,14 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QRangeCollectionPrivate
+class QPageRangesPrivate : public QSharedData
{
- Q_DECLARE_PUBLIC(QRangeCollection)
public:
- QRangeCollectionPrivate(QRangeCollection *rangeCollection)
- : q_ptr(rangeCollection)
- {
- }
-
void mergeIntervals();
- QList<QPair<int, int>> intervals;
- QRangeCollection *q_ptr;
+ QList<QPageRanges::Range> intervals;
};
QT_END_NAMESPACE
-#endif // QRANGECOLLECTION_P_H
+#endif // QPAGERANGES_P_H
diff --git a/src/gui/painting/qrangecollection.cpp b/src/gui/painting/qrangecollection.cpp
deleted file mode 100644
index 8f212a1b08..0000000000
--- a/src/gui/painting/qrangecollection.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/****************************************************************************
-**
-** 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 \a pageNumber 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 specified with \a from and \a to 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 of \a ranges.
-
- \code
- QPrinter printer;
- printer->rangeCollection()->parse("1-3,6-7");
- \endcode
-
- Returns \c true on success.
- */
-bool QRangeCollection::parse(const QString &ranges)
-{
- Q_D(QRangeCollection);
- const QStringList items = ranges.split(u',');
- for (const QString &item : items) {
- if (item.isEmpty()) {
- d->intervals.clear();
- return false;
- }
-
- if (item.contains(QLatin1Char('-'))) {
- const QStringList rangeItems = item.split(u'-');
- 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;
-}
-
-/*!
- \fn bool QRangeCollection::contains(const int pageNumber) const
-
- 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/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 0c5872a2f2..50f56b9a99 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1916,8 +1916,6 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
bool documentPaginated = d->pageSize.isValid() && !d->pageSize.isNull()
&& d->pageSize.height() != INT_MAX;
- QPagedPaintDevicePrivate *pd = QPagedPaintDevicePrivate::get(printer);
-
// ### set page size to paginated size?
QMarginsF m = printer->pageLayout().margins(QPageLayout::Millimeter);
if (!documentPaginated && m.left() == 0. && m.right() == 0. && m.top() == 0. && m.bottom() == 0.) {
@@ -2003,9 +2001,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
clonedDoc->setPageSize(body.size());
}
- QRangeCollection *rangeCollection = pd->rangeCollection;
- int fromPage = rangeCollection->firstPage();
- int toPage = rangeCollection->lastPage();
+ const QPageRanges pageRanges = printer->pageRanges();
+ int fromPage = pageRanges.firstPage();
+ int toPage = pageRanges.lastPage();
if (fromPage == 0 && toPage == 0) {
fromPage = 1;
@@ -2031,7 +2029,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
int page = fromPage;
while (true) {
- if (rangeCollection->isEmpty() || rangeCollection->contains(page))
+ if (pageRanges.isEmpty() || pageRanges.contains(page))
printPage(page, &p, doc, body, pageNumberPos);
if (page == toPage)
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 847edf2c49..6cd5ccb880 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -59,7 +59,6 @@
#include <QtWidgets/qstyleditemdelegate.h>
#include <QtWidgets/qformlayout.h>
#include <QtPrintSupport/qprinter.h>
-#include <QtGui/qrangecollection.h>
#include <qpa/qplatformprintplugin.h>
#include <qpa/qplatformprintersupport.h>
@@ -818,11 +817,14 @@ void QPrintDialogPrivate::setupPrinter()
#if QT_CONFIG(cups)
if (options.pagesRadioButton->isChecked()) {
- p->setPrintRange(QPrinter::PageRange);
- p->rangeCollection()->parse(options.pagesLineEdit->text());
+ const QPageRanges ranges = QPageRanges::fromString(options.pagesLineEdit->text());
+ if (!ranges.isEmpty()) {
+ p->setPrintRange(QPrinter::PageRange);
+ p->setPageRanges(ranges);
+ }
// server-side page filtering
- QCUPSSupport::setPageRange(p, p->rangeCollection()->toString());
+ QCUPSSupport::setPageRange(p, ranges.toString());
}
// page set
@@ -1022,7 +1024,7 @@ void QPrintDialog::accept()
{
Q_D(QPrintDialog);
#if QT_CONFIG(cups)
- if (d->options.pagesRadioButton->isChecked() && printer()->rangeCollection()->isEmpty()) {
+ if (d->options.pagesRadioButton->isChecked() && printer()->pageRanges().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 ec5b868ea5..d320accad0 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -49,7 +49,6 @@
#include "qlist.h"
#include <qcoreapplication.h>
#include <qfileinfo.h>
-#include <QtGui/qrangecollection.h>
#include <private/qpagedpaintdevice_p.h>
@@ -1393,12 +1392,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(), rangeCollection()
+ \sa setFromTo(), toPage(), pageRanges()
*/
int QPrinter::fromPage() const
{
- return d->rangeCollection->firstPage();
+ return d->pageRanges.firstPage();
}
/*!
@@ -1417,12 +1416,12 @@ int QPrinter::fromPage() const
The programmer is responsible for reading this setting and
printing accordingly.
- \sa setFromTo(), fromPage(), rangeCollection()
+ \sa setFromTo(), fromPage(), pageRanges()
*/
int QPrinter::toPage() const
{
- return d->rangeCollection->lastPage();
+ return d->pageRanges.lastPage();
}
/*!
@@ -1439,25 +1438,13 @@ 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(), rangeCollection()
+ \sa fromPage(), toPage(), pageRanges()
*/
void QPrinter::setFromTo(int from, int 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;
+ d->pageRanges.clear();
+ d->pageRanges.addRange(from, to);
}
/*!
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
index 62545f7807..253460ce72 100644
--- a/src/printsupport/kernel/qprinter.h
+++ b/src/printsupport/kernel/qprinter.h
@@ -44,7 +44,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/qpagedpaintdevice.h>
-#include <QtGui/qpagelayout.h>
QT_BEGIN_NAMESPACE
@@ -56,7 +55,6 @@ QT_BEGIN_NAMESPACE
#endif
class QPrinterPrivate;
-class QRangeCollection;
class QPaintEngine;
class QPrintEngine;
class QPrinterInfo;
@@ -201,8 +199,6 @@ public:
int fromPage() const;
int toPage() const;
- QRangeCollection *rangeCollection();
-
void setPrintRange(PrintRange range);
PrintRange printRange() const;
diff --git a/tests/auto/gui/painting/CMakeLists.txt b/tests/auto/gui/painting/CMakeLists.txt
index 682fc487c2..4f933139ca 100644
--- a/tests/auto/gui/painting/CMakeLists.txt
+++ b/tests/auto/gui/painting/CMakeLists.txt
@@ -6,12 +6,12 @@ add_subdirectory(qcolor)
add_subdirectory(qbrush)
add_subdirectory(qregion)
add_subdirectory(qpagelayout)
+add_subdirectory(qpageranges)
add_subdirectory(qpagesize)
add_subdirectory(qpainter)
add_subdirectory(qpdfwriter)
add_subdirectory(qpen)
add_subdirectory(qpaintengine)
-add_subdirectory(qrangecollection)
add_subdirectory(qtransform)
add_subdirectory(qpolygon)
# QTBUG-87669 # special case
diff --git a/tests/auto/gui/painting/painting.pro b/tests/auto/gui/painting/painting.pro
index f99fc6c4e8..9c24b8e5ed 100644
--- a/tests/auto/gui/painting/painting.pro
+++ b/tests/auto/gui/painting/painting.pro
@@ -7,13 +7,13 @@ SUBDIRS=\
qbrush \
qregion \
qpagelayout \
+ qpageranges \
qpagesize \
qpainter \
qpathclipper \
qpdfwriter \
qpen \
qpaintengine \
- qrangecollection \
qtransform \
qpolygon \
diff --git a/tests/auto/gui/painting/qrangecollection/CMakeLists.txt b/tests/auto/gui/painting/qpageranges/CMakeLists.txt
index d4aa7986a7..660d4b4336 100644
--- a/tests/auto/gui/painting/qrangecollection/CMakeLists.txt
+++ b/tests/auto/gui/painting/qpageranges/CMakeLists.txt
@@ -1,12 +1,12 @@
-# Generated from qrangecollection.pro.
+# Generated from qpageranges.pro.
#####################################################################
-## tst_qrangecollection Test:
+## tst_qpageranges Test:
#####################################################################
-qt_internal_add_test(tst_qrangecollection
+qt_internal_add_test(tst_qpageranges
SOURCES
- tst_qrangecollection.cpp
+ tst_qpageranges.cpp
PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::Gui
diff --git a/tests/auto/gui/painting/qpageranges/qpageranges.pro b/tests/auto/gui/painting/qpageranges/qpageranges.pro
new file mode 100644
index 0000000000..9062a58ea3
--- /dev/null
+++ b/tests/auto/gui/painting/qpageranges/qpageranges.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qpageranges
+
+QT += testlib gui-private core-private
+
+SOURCES += tst_qpageranges.cpp
diff --git a/tests/auto/gui/painting/qpageranges/tst_qpageranges.cpp b/tests/auto/gui/painting/qpageranges/tst_qpageranges.cpp
new file mode 100644
index 0000000000..953f1c472a
--- /dev/null
+++ b/tests/auto/gui/painting/qpageranges/tst_qpageranges.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <qpageranges.h>
+
+typedef QList<QPageRanges::Range> PageRangeList;
+
+class tst_QPageRanges : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void basics();
+
+ void addPage_data();
+ void addPage();
+
+ void addRange_data();
+ void addRange();
+
+ void fromToString_data();
+ void fromToString();
+};
+
+void tst_QPageRanges::basics()
+{
+ QPageRanges empty;
+ QVERIFY(empty.isEmpty());
+ QVERIFY(!empty.contains(0));
+ QCOMPARE(empty.firstPage(), 0);
+ QCOMPARE(empty.lastPage(), 0);
+
+ QPageRanges single;
+ single.addPage(1);
+
+ QVERIFY(!single.isEmpty());
+ QVERIFY(single.contains(1));
+ QCOMPARE(single.firstPage(), 1);
+ QCOMPARE(single.firstPage(), 1);
+
+ QPageRanges copy(single);
+ QCOMPARE(copy, single);
+
+ QPageRanges moved(std::move(copy));
+ QCOMPARE(moved, single);
+ QVERIFY(copy.isEmpty());
+
+ single.clear();
+ QVERIFY(single.isEmpty());
+ QVERIFY(!moved.isEmpty());
+}
+
+void tst_QPageRanges::addPage_data()
+{
+ QTest::addColumn<QList<int>>("pageNumbers");
+ QTest::addColumn<PageRangeList>("expected");
+
+ QTest::newRow("single") << QList<int>{5} << PageRangeList{{5, 5}};
+ QTest::newRow("duplicate") << QList<int>{5, 5} << PageRangeList{{5, 5}};
+ QTest::newRow("adjacent") << QList<int>{5, 6, 7} << PageRangeList{{5, 7}};
+ QTest::newRow("separate") << QList<int>{1, 3, 5} << PageRangeList{{1, 1}, {3, 3}, {5, 5}};
+ QTest::newRow("unsorted") << QList<int>{5, 3, 4, 1} << PageRangeList{{1, 1}, {3, 5}};
+ QTest::newRow("invalid") << QList<int>{-1} << PageRangeList{};
+}
+
+void tst_QPageRanges::addPage()
+{
+ QFETCH(QList<int>, pageNumbers);
+ QFETCH(PageRangeList, expected);
+
+ QPageRanges result;
+ for (int pageNumber : qAsConst(pageNumbers)) {
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QTest::ignoreMessage(QtWarningMsg, "QPageRanges::addPage: 'pageNumber' must be greater than 0");
+ result.addPage(pageNumber);
+ }
+
+ QCOMPARE(result.toRangeList(), expected);
+}
+
+void tst_QPageRanges::addRange_data()
+{
+ QTest::addColumn<PageRangeList>("ranges");
+ QTest::addColumn<PageRangeList>("expected");
+
+ QTest::newRow("single") << PageRangeList{{5, 5}}
+ << PageRangeList{{5, 5}};
+ QTest::newRow("duplicate") << PageRangeList{{5, 5}, {5, 5}}
+ << PageRangeList{{5, 5}};
+ QTest::newRow("adjacent") << PageRangeList{{1, 3}, {4, 6}, {7, 10}}
+ << PageRangeList{{1, 10}};
+ QTest::newRow("separate") << PageRangeList{{1, 2}, {4, 5}, {7, 8}}
+ << PageRangeList{{1, 2}, {4, 5}, {7, 8}};
+ QTest::newRow("overlap") << PageRangeList{{1, 5}, {4, 8}, {8, 10}}
+ << PageRangeList{{1, 10}};
+ QTest::newRow("included") << PageRangeList{{1, 5}, {2, 3}, {8, 9}, {7, 10}}
+ << PageRangeList{{1, 5}, {7, 10}};
+ QTest::newRow("unsorted") << PageRangeList{{7, 8}, {1, 4}, {9, 10}}
+ << PageRangeList{{1, 4}, {7, 10}};
+ QTest::newRow("flipped") << PageRangeList{{5, 1}}
+ << PageRangeList{{1, 5}};
+ QTest::newRow("invalid1") << PageRangeList{{-1, 2}}
+ << PageRangeList{};
+ QTest::newRow("invalid2") << PageRangeList{{0, -1}}
+ << PageRangeList{};
+}
+
+void tst_QPageRanges::addRange()
+{
+ QFETCH(PageRangeList, ranges);
+ QFETCH(PageRangeList, expected);
+
+ QPageRanges result;
+ for (const auto &range : qAsConst(ranges)) {
+ const QByteArrayView testdata(QTest::currentDataTag());
+ if (testdata.startsWith("invalid"))
+ QTest::ignoreMessage(QtWarningMsg, "QPageRanges::addRange: 'from' and 'to' must be greater than 0");
+
+ result.addRange(range.from, range.to);
+ }
+
+ QCOMPARE(result.toRangeList(), expected);
+}
+
+void tst_QPageRanges::fromToString_data()
+{
+ QTest::addColumn<QString>("fromString");
+ QTest::addColumn<PageRangeList>("rangeList");
+ QTest::addColumn<QString>("toString");
+
+ QTest::newRow("invalid") << QString(",-8")
+ << PageRangeList{}
+ << QString();
+
+ QTest::newRow("overlapping") << QString("1-3,5-9,6-7,8-11")
+ << PageRangeList{{1, 3}, {5, 11}}
+ << QString("1-3,5-11");
+
+ QTest::newRow("spacy") << QString("1 -2, 3- 4 ,\t5-6\t,7 - 8 ,\n9 - 10")
+ << PageRangeList{{1, 10}}
+ << QString("1-10");
+}
+
+void tst_QPageRanges::fromToString()
+{
+ QFETCH(QString, fromString);
+ QFETCH(PageRangeList, rangeList);
+ QFETCH(QString, toString);
+
+ QPageRanges ranges = QPageRanges::fromString(fromString);
+ QCOMPARE(ranges.toRangeList(), rangeList);
+ QCOMPARE(ranges.toString(), toString);
+}
+
+QTEST_APPLESS_MAIN(tst_QPageRanges)
+
+#include "tst_qpageranges.moc"
diff --git a/tests/auto/gui/painting/qrangecollection/qrangecollection.pro b/tests/auto/gui/painting/qrangecollection/qrangecollection.pro
deleted file mode 100644
index 782e8ee59c..0000000000
--- a/tests/auto/gui/painting/qrangecollection/qrangecollection.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qrangecollection
-
-QT += testlib gui-private core-private
-
-SOURCES += tst_qrangecollection.cpp
diff --git a/tests/auto/gui/painting/qrangecollection/tst_qrangecollection.cpp b/tests/auto/gui/painting/qrangecollection/tst_qrangecollection.cpp
deleted file mode 100644
index 826b2fe38b..0000000000
--- a/tests/auto/gui/painting/qrangecollection/tst_qrangecollection.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** 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-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qrangecollection.h>
-
-typedef QList<QPair<int, int>> PageRangeList;
-
-class tst_QRangeCollection : public QObject
-{
- Q_OBJECT
-
-private slots:
- void parseFromString_data();
- void parseFromString();
-};
-
-void tst_QRangeCollection::parseFromString_data()
-{
- QTest::addColumn<QString>("rangeString");
- QTest::addColumn<QList<QPair<int, int>>>("rangeList");
-
- QList<QPair<int, int>> invalid;
- QTest::newRow("invalid") << QString(",-8")
- << invalid;
-
- QList<QPair<int, int>> overlapping;
- overlapping << qMakePair(1, 3)
- << qMakePair(5, 11);
- QTest::newRow("overlapping") << QString("1-3,5-9,6-7,8-11")
- << overlapping;
-}
-
-void tst_QRangeCollection::parseFromString()
-{
- QFETCH(QString, rangeString);
- QFETCH(PageRangeList, rangeList);
-
- QRangeCollection rangeCollection;
- rangeCollection.parse(rangeString);
- QList<QPair<int, int>> result = rangeCollection.toList();
- QCOMPARE(result.length(), rangeList.length());
- for (const QPair<int, int> &pair : result) {
- QVERIFY(rangeList.contains(pair));
- }
-}
-
-QTEST_APPLESS_MAIN(tst_QRangeCollection)
-
-#include "tst_qrangecollection.moc"