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>bb10
parent
8bf36025f5
commit
b14b1c99f8
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ SUBDIRS=\
|
|||
qbrush \
|
||||
qregion \
|
||||
qpagelayout \
|
||||
qpageranges \
|
||||
qpagesize \
|
||||
qpainter \
|
||||
qpathclipper \
|
||||
qpdfwriter \
|
||||
qpen \
|
||||
qpaintengine \
|
||||
qrangecollection \
|
||||
qtransform \
|
||||
qpolygon \
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_qpageranges
|
||||
|
||||
QT += testlib gui-private core-private
|
||||
|
||||
SOURCES += 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"
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_qrangecollection
|
||||
|
||||
QT += testlib gui-private core-private
|
||||
|
||||
SOURCES += tst_qrangecollection.cpp
|
||||
|
|
@ -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"
|
||||
Loading…
Reference in New Issue