diff options
-rw-r--r-- | src/gui/painting/painting.pri | 2 | ||||
-rw-r--r-- | src/gui/painting/qpagelayout.cpp | 971 | ||||
-rw-r--r-- | src/gui/painting/qpagelayout.h | 155 | ||||
-rw-r--r-- | tests/auto/gui/painting/painting.pro | 1 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpagelayout/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpagelayout/qpagelayout.pro | 9 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp | 277 |
7 files changed, 1416 insertions, 0 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 8a51c3f379..ed45b8ea17 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -19,6 +19,7 @@ HEADERS += \ painting/qoutlinemapper_p.h \ painting/qpagedpaintdevice.h \ painting/qpagedpaintdevice_p.h \ + painting/qpagelayout.h \ painting/qpagesize.h \ painting/qpaintdevice.h \ painting/qpaintengine.h \ @@ -67,6 +68,7 @@ SOURCES += \ painting/qmemrotate.cpp \ painting/qoutlinemapper.cpp \ painting/qpagedpaintdevice.cpp \ + painting/qpagelayout.cpp \ painting/qpagesize.cpp \ painting/qpaintdevice.cpp \ painting/qpaintengine.cpp \ diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp new file mode 100644 index 0000000000..7ae117e423 --- /dev/null +++ b/src/gui/painting/qpagelayout.cpp @@ -0,0 +1,971 @@ +/**************************************************************************** +** +** Copyright (C) 2014 John Layt <jlayt@kde.org> +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qpagelayout.h" + +#include <QtCore/qpoint.h> +#include <QtCore/qrect.h> +#include <QtCore/qsize.h> + +#include <qdebug.h> + +QT_BEGIN_NAMESPACE + +static qreal qt_clamp(qreal value, qreal min, qreal max) +{ + return qMin(qMax(value, min), max); +} + +// Multiplier for converting units to points. +Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit) +{ + switch (unit) { + case QPageLayout::Millimeter: + return 2.83464566929; + case QPageLayout::Point: + return 1.0; + case QPageLayout::Inch: + return 72.0; + case QPageLayout::Pica: + return 12; + case QPageLayout::Didot: + return 1.065826771; + case QPageLayout::Cicero: + return 12.789921252; + } + return 1.0; +} + +// Multiplier for converting pixels to points. +extern qreal qt_pixelMultiplier(int resolution); + +QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits) +{ + // If the size have the same units, or are all 0, then don't need to convert + if (fromUnits == toUnits || xy.isNull()) + return xy; + + // If converting to points then convert and round to 0 decimal places + if (toUnits == QPageLayout::Point) { + const qreal multiplier = qt_pointMultiplier(fromUnits); + return QPointF(qRound(xy.x() * multiplier), + qRound(xy.y() * multiplier)); + } + + // If converting to other units, need to convert to unrounded points first + QPointF pointXy = (fromUnits == QPageLayout::Point) ? xy : xy * qt_pointMultiplier(fromUnits); + + // Then convert from points to required units rounded to 2 decimal places + const qreal multiplier = qt_pointMultiplier(toUnits); + return QPointF(qRound(pointXy.x() * 100 / multiplier) / 100.0, + qRound(pointXy.y() * 100 / multiplier) / 100.0); +} + +Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits) +{ + // If the margins have the same units, or are all 0, then don't need to convert + if (fromUnits == toUnits || margins.isNull()) + return margins; + + // If converting to points then convert and round to 0 decimal places + if (toUnits == QPageLayout::Point) { + const qreal multiplier = qt_pointMultiplier(fromUnits); + return QMarginsF(qRound(margins.left() * multiplier), + qRound(margins.top() * multiplier), + qRound(margins.right() * multiplier), + qRound(margins.bottom() * multiplier)); + } + + // If converting to other units, need to convert to unrounded points first + QMarginsF pointMargins = fromUnits == QPageLayout::Point ? margins : margins * qt_pointMultiplier(fromUnits); + + // Then convert from points to required units rounded to 2 decimal places + const qreal multiplier = qt_pointMultiplier(toUnits); + return QMarginsF(qRound(pointMargins.left() * 100 / multiplier) / 100.0, + qRound(pointMargins.top() * 100 / multiplier) / 100.0, + qRound(pointMargins.right() * 100 / multiplier) / 100.0, + qRound(pointMargins.bottom() * 100 / multiplier) / 100.0); +} + +class QPageLayoutPrivate : public QSharedData +{ +public: + + QPageLayoutPrivate(); + QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation, + const QMarginsF &margins, QPageLayout::Unit units, + const QMarginsF &minMargins); + ~QPageLayoutPrivate(); + + bool operator==(const QPageLayoutPrivate &other) const; + bool isEquivalentTo(const QPageLayoutPrivate &other) const; + + bool isValid() const; + + void clampMargins(const QMarginsF &margins); + + QMarginsF margins(QPageLayout::Unit units) const; + QMargins marginsPoints() const; + QMargins marginsPixels(int resolution) const; + + void setDefaultMargins(const QMarginsF &minMargins); + + QSizeF paintSize() const; + + QRectF fullRect() const; + QRectF fullRect(QPageLayout::Unit units) const; + QRect fullRectPoints() const; + QRect fullRectPixels(int resolution) const; + + QRectF paintRect() const; + +private: + friend class QPageLayout; + + QSizeF fullSizeUnits(QPageLayout::Unit units) const; + + QPageSize m_pageSize; + QPageLayout::Orientation m_orientation; + QPageLayout::Mode m_mode; + QPageLayout::Unit m_units; + QSizeF m_fullSize; + QMarginsF m_margins; + QMarginsF m_minMargins; + QMarginsF m_maxMargins; +}; + +QPageLayoutPrivate::QPageLayoutPrivate() + : m_orientation(QPageLayout::Landscape), + m_mode(QPageLayout::StandardMode) +{ +} + +QPageLayoutPrivate::QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation, + const QMarginsF &margins, QPageLayout::Unit units, + const QMarginsF &minMargins) + : m_pageSize(pageSize), + m_orientation(orientation), + m_mode(QPageLayout::StandardMode), + m_units(units), + m_margins(margins) +{ + m_fullSize = fullSizeUnits(m_units); + setDefaultMargins(minMargins); +} + +QPageLayoutPrivate::~QPageLayoutPrivate() +{ +} + +bool QPageLayoutPrivate::operator==(const QPageLayoutPrivate &other) const +{ + return m_pageSize == other.m_pageSize + && m_orientation == other.m_orientation + && m_units == other.m_units + && m_margins == other.m_margins + && m_minMargins == other.m_minMargins + && m_maxMargins == other.m_maxMargins; +} + +bool QPageLayoutPrivate::isEquivalentTo(const QPageLayoutPrivate &other) const +{ + return m_pageSize.isEquivalentTo(other.m_pageSize) + && m_orientation == other.m_orientation + && qt_convertMargins(m_margins, m_units, QPageLayout::Point) + == qt_convertMargins(other.m_margins, other.m_units, QPageLayout::Point); +} + +bool QPageLayoutPrivate::isValid() const +{ + return m_pageSize.isValid(); +} + +void QPageLayoutPrivate::clampMargins(const QMarginsF &margins) +{ + m_margins = QMarginsF(qt_clamp(margins.left(), m_minMargins.left(), m_maxMargins.left()), + qt_clamp(margins.top(), m_minMargins.top(), m_maxMargins.top()), + qt_clamp(margins.right(), m_minMargins.right(), m_maxMargins.right()), + qt_clamp(margins.bottom(), m_minMargins.bottom(), m_maxMargins.bottom())); +} + +QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const +{ + return qt_convertMargins(m_margins, m_units, units); +} + +QMargins QPageLayoutPrivate::marginsPoints() const +{ + return qt_convertMargins(m_margins, m_units, QPageLayout::Point).toMargins(); +} + +QMargins QPageLayoutPrivate::marginsPixels(int resolution) const +{ + return marginsPoints() / qt_pixelMultiplier(resolution); +} + +void QPageLayoutPrivate::setDefaultMargins(const QMarginsF &minMargins) +{ + m_minMargins = minMargins; + m_maxMargins = QMarginsF(m_fullSize.width() - m_minMargins.right(), + m_fullSize.height() - m_minMargins.bottom(), + m_fullSize.width() - m_minMargins.left(), + m_fullSize.height() - m_minMargins.top()); + if (m_mode == QPageLayout::StandardMode) + clampMargins(m_margins); +} + +QSizeF QPageLayoutPrivate::fullSizeUnits(QPageLayout::Unit units) const +{ + QSizeF fullPageSize = m_pageSize.size(QPageSize::Unit(units)); + return m_orientation == QPageLayout::Landscape ? fullPageSize.transposed() : fullPageSize; +} + +QRectF QPageLayoutPrivate::fullRect() const +{ + return QRectF(QPointF(0, 0), m_fullSize); +} + +QRectF QPageLayoutPrivate::fullRect(QPageLayout::Unit units) const +{ + return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units)); +} + +QRect QPageLayoutPrivate::fullRectPoints() const +{ + if (m_orientation == QPageLayout::Landscape) + return QRect(QPoint(0, 0), m_pageSize.sizePoints().transposed()); + else + return QRect(QPoint(0, 0), m_pageSize.sizePoints()); +} + +QRect QPageLayoutPrivate::fullRectPixels(int resolution) const +{ + if (m_orientation == QPageLayout::Landscape) + return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution).transposed()); + else + return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution)); +} + +QRectF QPageLayoutPrivate::paintRect() const +{ + return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins; +} + + +/*! + \class QPageLayout + \inmodule QtGui + \since 5.3 + \brief Describes the size, orientation and margins of a page. + + The QPageLayout class defines the layout of a page in a paged document, with the + page size, orientation and margins able to be set and the full page and paintable + page rectangles defined by those attributes able to be queried in a variety of units. + + The page size is defined by the QPageSize class which can be queried for page size + attributes. Note that the QPageSize itself is always defined in a Portrait + orientation. + + The minimum margins can be defined for the layout but normally default to 0. + When used in conjunction with Qt's printing support the minimum margins + will reflect the minimum printable area defined by the printer. + + In the default StandardMode the current margins and minimum margins are + always taken into account. The paintable rectangle is the full page + rectangle less the current margins, and the current margins can only be set + to values between the minimum margins and the maximum margins allowed by + the full page size. + + In FullPageMode the current margins and minimum margins are not taken + into account. The paintable rectangle is the full page rectangle, and the + current margins can be set to any values regardless of the minimum margins + and page size. + + \sa QPageSize +*/ + +/*! + \enum QPageLayout::Unit + + This enum type is used to specify the measurement unit for page layout and margins. + + \value Millimeter + \value Point 1/72th of an inch + \value Inch + \value Pica 1/72th of a foot, 1/6th of an inch, 12 Points + \value Didot 1/72th of a French inch, 0.375 mm + \value Cicero 1/6th of a French inch, 12 Didot, 4.5mm +*/ + +/*! + \enum QPageLayout::Orientation + + This enum type defines the page orientation + + \value Portrait The page size is used in its default orientation + \value Landscape The page size is rotated through 90 degrees + + Note that some standard page sizes are defined with a width larger than + their height, hence the orientation is defined relative to the standard + page size and not using the relative page dimensions. +*/ + +/*! + \enum QPageLayout::Mode + + Defines the page layout mode + + \value StandardMode Paint Rect includes margins, margins must fall between the minimum and maximum. + \value FullPageMode Paint Rect excludes margins, margins can be any value and must be managed manually. +*/ + +/*! + Creates an invalid QPageLayout. +*/ + +QPageLayout::QPageLayout() + : d(new QPageLayoutPrivate()) +{ +} + +/*! + Creates a QPageLayout with the given \a pageSize, \a orientation and + \a margins in the given \a units. + + Optionally define the minimum allowed margins \a minMargins, e.g. the minimum + margins able to be printed by a physical print device. + + The constructed QPageLayout will be in StandardMode. + + The \a margins given will be clamped to the minimum margins and the maximum + margins allowed by the page size. +*/ + +QPageLayout::QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation, + const QMarginsF &margins, QPageLayout::Unit units, + const QMarginsF &minMargins) + : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins)) +{ +} + +/*! + Copy constructor, copies \a other to this. +*/ + +QPageLayout::QPageLayout(const QPageLayout &other) + : d(other.d) +{ +} + +/*! + Destroys the page layout. +*/ + +QPageLayout::~QPageLayout() +{ +} + +/*! + Assignment operator, assigns \a other to this. +*/ + +QPageLayout &QPageLayout::operator=(const QPageLayout &other) +{ + d = other.d; + return *this; +} + +/*! + \fn void QPageLayout::swap(QPageLayout &other) + + Swaps this page layout with \a other. This function is very fast and + never fails. +*/ + +/*! + \fn QPageLayout &QPageLayout::operator=(QPageLayout &&other) + + Move-assigns \a other to this QPageLayout instance, transferring the + ownership of the managed pointer to this instance. +*/ + +/*! + Returns \c true if this page layout is equal to the \a other page layout, + i.e. if all the attributes are exactly equal. + + Note that this is a strict equality, especially for page size where the + QPageSize ID, name and size must exactly match, and the margins where the + units must match. + + \sa isEquivalentTo() +*/ + +bool QPageLayout::operator==(const QPageLayout &other) const +{ + if (d && other.d) + return (*d == *other.d); + return (d == other.d); +} + +/*! + Returns \c true if this page layout is equivalent to the \a other page layout, + i.e. if the page has the same size, margins and orientation. +*/ + +bool QPageLayout::isEquivalentTo(const QPageLayout &other) const +{ + return d && other.d && d->isEquivalentTo(*other.d); +} + +/*! + Returns \c true if this page layout is valid. +*/ + +bool QPageLayout::isValid() const +{ + return d->isValid(); +} + +/*! + Sets a page layout mode to \a mode. +*/ + +void QPageLayout::setMode(QPageLayout::Mode mode) +{ + d->m_mode = mode; +} + +/*! + Returns the page layout mode. +*/ + +QPageLayout::Mode QPageLayout::mode() const +{ + return d->m_mode; +} + +/*! + Sets the page size of the page layout to \a pageSize. + + Optionally define the minimum allowed margins \a minMargins, e.g. the minimum + margins able to be printed by a physical print device, otherwise the + minimum margins will default to 0. + + If StandardMode is set then the existing margins will be clamped + to the new minimum margins and the maximum margins allowed by the page size. + If FullPageMode is set then the existing margins will be unchanged. +*/ + +void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins) +{ + if (!pageSize.isValid()) + return; + d->m_pageSize = pageSize; + d->m_fullSize = d->fullSizeUnits(d->m_units); + d->setDefaultMargins(minMargins); +} + +/*! + Returns the page size of the page layout. + + Note that the QPageSize is always defined in a Portrait orientation. To + obtain a size that takes the set orientation into account you must use + fullRect(). +*/ + +QPageSize QPageLayout::pageSize() const +{ + return d->m_pageSize; +} + +/*! + Sets the page orientation of the page layout to \a orientation. + + Changing the orientation does not affect the current margins or + the minimum margins. +*/ + +void QPageLayout::setOrientation(QPageLayout::Orientation orientation) +{ + if (orientation != d->m_orientation) { + d->m_orientation = orientation; + d->m_fullSize = d->fullSizeUnits(d->m_units); + // Adust the max margins to reflect change in max page size + const qreal change = d->m_fullSize.width() - d->m_fullSize.height(); + d->m_maxMargins.setLeft(d->m_maxMargins.left() + change); + d->m_maxMargins.setRight(d->m_maxMargins.right() + change); + d->m_maxMargins.setTop(d->m_maxMargins.top() - change); + d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change); + } +} + +/*! + Returns the page orientation of the page layout. +*/ + +QPageLayout::Orientation QPageLayout::orientation() const +{ + return d->m_orientation; +} + +/*! + Sets the \a units used to define the page layout. +*/ + +void QPageLayout::setUnits(QPageLayout::Unit units) +{ + if (units != d->m_units) { + d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units); + d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units); + d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units); + d->m_units = units; + d->m_fullSize = d->fullSizeUnits(d->m_units); + } +} + +/*! + Returns the units the page layout is currently defined in. +*/ + +QPageLayout::Unit QPageLayout::units() const +{ + return d->m_units; +} + +/*! + Sets the page margins of the page layout to \a margins + Returns true if the margins were successfully set. + + The units used are those currently defined for the layout. To use different + units then call setUnits() first. + + If in the default StandardMode then all the new margins must fall between the + minimum margins set and the maximum margins allowed by the page size, + otherwise the margins will not be set. + + If in FullPageMode then any margin values will be accepted. + + \sa margins(), units() +*/ + +bool QPageLayout::setMargins(const QMarginsF &margins) +{ + if (d->m_mode == QPageLayout::FullPageMode) { + d->m_margins = margins; + return true; + } else if (margins.left() >= d->m_minMargins.left() + && margins.right() >= d->m_minMargins.right() + && margins.top() >= d->m_minMargins.top() + && margins.bottom() >= d->m_minMargins.bottom() + && margins.left() <= d->m_maxMargins.left() + && margins.right() <= d->m_maxMargins.right() + && margins.top() <= d->m_maxMargins.top() + && margins.bottom() <= d->m_maxMargins.bottom()) { + d->m_margins = margins; + return true; + } + return false; +} + +/*! + Sets the left page margin of the page layout to \a leftMargin. + Returns true if the margin was successfully set. + + The units used are those currently defined for the layout. To use different + units call setUnits() first. + + If in the default StandardMode then the new margin must fall between the + minimum margin set and the maximum margin allowed by the page size, + otherwise the margin will not be set. + + If in FullPageMode then any margin values will be accepted. + + \sa setMargins(), margins() +*/ + +bool QPageLayout::setLeftMargin(qreal leftMargin) +{ + if (d->m_mode == QPageLayout::FullPageMode + || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) { + d->m_margins.setLeft(leftMargin); + return true; + } + return false; +} + +/*! + Sets the right page margin of the page layout to \a rightMargin. + Returns true if the margin was successfully set. + + The units used are those currently defined for the layout. To use different + units call setUnits() first. + + If in the default StandardMode then the new margin must fall between the + minimum margin set and the maximum margin allowed by the page size, + otherwise the margin will not be set. + + If in FullPageMode then any margin values will be accepted. + + \sa setMargins(), margins() +*/ + +bool QPageLayout::setRightMargin(qreal rightMargin) +{ + if (d->m_mode == QPageLayout::FullPageMode + || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) { + d->m_margins.setRight(rightMargin); + return true; + } + return false; +} + +/*! + Sets the top page margin of the page layout to \a topMargin. + Returns true if the margin was successfully set. + + The units used are those currently defined for the layout. To use different + units call setUnits() first. + + If in the default StandardMode then the new margin must fall between the + minimum margin set and the maximum margin allowed by the page size, + otherwise the margin will not be set. + + If in FullPageMode then any margin values will be accepted. + + \sa setMargins(), margins() +*/ + +bool QPageLayout::setTopMargin(qreal topMargin) +{ + if (d->m_mode == QPageLayout::FullPageMode + || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) { + d->m_margins.setTop(topMargin); + return true; + } + return false; +} + +/*! + Sets the bottom page margin of the page layout to \a bottomMargin. + Returns true if the margin was successfully set. + + The units used are those currently defined for the layout. To use different + units call setUnits() first. + + If in the default StandardMode then the new margin must fall between the + minimum margin set and the maximum margin allowed by the page size, + otherwise the margin will not be set. + + If in FullPageMode then any margin values will be accepted. + + \sa setMargins(), margins() +*/ + +bool QPageLayout::setBottomMargin(qreal bottomMargin) +{ + if (d->m_mode == QPageLayout::FullPageMode + || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) { + d->m_margins.setBottom(bottomMargin); + return true; + } + return false; +} + +/*! + Returns the margins of the page layout using the currently set units. + + \sa setMargins(), units() +*/ + +QMarginsF QPageLayout::margins() const +{ + return d->m_margins; +} + +/*! + Returns the margins of the page layout using the requested \a units. + + \sa setMargins(), margins() +*/ + +QMarginsF QPageLayout::margins(QPageLayout::Unit units) const +{ + return d->margins(units); +} + +/*! + Returns the margins of the page layout in Postscript Points (1/72 of an inch). + + \sa setMargins(), margins() +*/ + +QMargins QPageLayout::marginsPoints() const +{ + return d->marginsPoints(); +} + +/*! + Returns the margins of the page layout in device pixels for the given \a resolution. + + \sa setMargins() +*/ + +QMargins QPageLayout::marginsPixels(int resolution) const +{ + return d->marginsPixels(resolution); +} + +/*! + Sets the minimum page margins of the page layout to \a minMargins. + + It is not recommended to override the default values set for a page size + as this may be the minimum printable area for a physical print device. + + If the StandardMode mode is set then the existing margins will be clamped + to the new \a minMargins and the maximum allowed by the page size. If the + FullPageMode is set then the existing margins will be unchanged. + + \sa minimumMargins(), setMargins() +*/ + +void QPageLayout::setMinimumMargins(const QMarginsF &minMargins) +{ + d->setDefaultMargins(minMargins); +} + +/*! + Returns the minimum margins of the page layout. + + \sa setMinimumMargins(), maximumMargins() +*/ + +QMarginsF QPageLayout::minimumMargins() const +{ + return d->m_minMargins; +} + +/*! + Returns the maximum margins that would be applied if the page layout was + in StandardMode. + + The maximum margins allowed are calculated as the full size of the page + minus the minimum margins set. For example, if the page width is 100 points + and the minimum right margin is 10 points, then the maximum left margin + will be 90 points. + + \sa setMinimumMargins(), minimumMargins() +*/ + +QMarginsF QPageLayout::maximumMargins() const +{ + return d->m_maxMargins; +} + +/*! + Returns the full page rectangle in the current layout units. + + The page rectangle takes into account the page size and page orientation, + but not the page margins. + + \sa paintRect(), units() +*/ + +QRectF QPageLayout::fullRect() const +{ + return isValid() ? d->fullRect() : QRect(); +} + +/*! + Returns the full page rectangle in the required \a units. + + The page rectangle takes into account the page size and page orientation, + but not the page margins. + + \sa paintRect() +*/ + +QRectF QPageLayout::fullRect(QPageLayout::Unit units) const +{ + return isValid() ? d->fullRect(units) : QRect(); +} + +/*! + Returns the full page rectangle in Postscript Points (1/72 of an inch). + + The page rectangle takes into account the page size and page orientation, + but not the page margins. + + \sa paintRect() +*/ + +QRect QPageLayout::fullRectPoints() const +{ + return isValid() ? d->fullRectPoints() : QRect(); +} + +/*! + Returns the full page rectangle in device pixels for the given \a resolution. + + The page rectangle takes into account the page size and page orientation, + but not the page margins. + + \sa paintRect() +*/ + +QRect QPageLayout::fullRectPixels(int resolution) const +{ + return isValid() ? d->fullRectPixels(resolution) : QRect(); +} + +/*! + Returns the page rectangle in the current layout units. + + The paintable rectangle takes into account the page size, orientation + and margins. + + If the FullPageMode mode is set then the fullRect() is returned and + the margins must be manually managed. +*/ + +QRectF QPageLayout::paintRect() const +{ + return isValid() ? d->paintRect() : QRectF(); +} + +/*! + Returns the page rectangle in the required \a units. + + The paintable rectangle takes into account the page size, orientation + and margins. + + If the FullPageMode mode is set then the fullRect() is returned and + the margins must be manually managed. +*/ + +QRectF QPageLayout::paintRect(QPageLayout::Unit units) const +{ + if (!isValid()) + return QRectF(); + if (units == d->m_units) + return d->paintRect(); + return d->m_mode == QPageLayout::FullPageMode ? d->fullRect(units) + : d->fullRect(units) - d->margins(units); +} + +/*! + Returns the paintable rectangle in rounded Postscript Points (1/72 of an inch). + + The paintable rectangle takes into account the page size, orientation + and margins. + + If the FullPageMode mode is set then the fullRect() is returned and + the margins must be manually managed. +*/ + +QRect QPageLayout::paintRectPoints() const +{ + if (!isValid()) + return QRect(); + return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPoints() + : d->fullRectPoints() - d->marginsPoints(); +} + +/*! + Returns the paintable rectangle in rounded device pixels for the given \a resolution. + + The paintable rectangle takes into account the page size, orientation + and margins. + + If the FullPageMode mode is set then the fullRect() is returned and + the margins must be manually managed. +*/ + +QRect QPageLayout::paintRectPixels(int resolution) const +{ + if (!isValid()) + return QRect(); + return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPixels(resolution) + : d->fullRectPixels(resolution) - d->marginsPixels(resolution); +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QPageLayout &layout) +{ + if (layout.isValid()) { + QString output = QStringLiteral("QPageLayout(%1, %2, l:%3 r:%4 t:%5 b:%6 %7)"); + QString units; + switch (layout.units()) { + case QPageLayout::Millimeter: + units = QStringLiteral("mm"); + break; + case QPageLayout::Point: + units = QStringLiteral("pt"); + break; + case QPageLayout::Inch: + units = QStringLiteral("in"); + break; + case QPageLayout::Pica: + units = QStringLiteral("pc"); + break; + case QPageLayout::Didot: + units = QStringLiteral("DD"); + break; + case QPageLayout::Cicero: + units = QStringLiteral("CC"); + break; + } + output = output.arg(layout.pageSize().name()) + .arg(layout.orientation() == QPageLayout::Portrait ? QStringLiteral("Portrait") : QStringLiteral("Landscape")) + .arg(layout.margins().left()) + .arg(layout.margins().right()) + .arg(layout.margins().top()) + .arg(layout.margins().bottom()) + .arg(units); + dbg.nospace() << output; + } else { + dbg.nospace() << QStringLiteral("QPageLayout()"); + } + return dbg.space(); +} +#endif + +QT_END_NAMESPACE diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h new file mode 100644 index 0000000000..86e430e311 --- /dev/null +++ b/src/gui/painting/qpagelayout.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2014 John Layt <jlayt@kde.org> +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAGELAYOUT_H +#define QPAGELAYOUT_H + +#include <QtCore/qsharedpointer.h> +#include <QtCore/qstring.h> +#include <QtCore/qmargins.h> + +#include <QtGui/qpagesize.h> + +QT_BEGIN_NAMESPACE + +class QPageLayoutPrivate; +class QMarginsF; + +class Q_GUI_EXPORT QPageLayout +{ +public: + + // NOTE: Must keep in sync with QPageSize::Unit and QPrinter::Unit + enum Unit { + Millimeter, + Point, + Inch, + Pica, + Didot, + Cicero + }; + + // NOTE: Must keep in sync with QPrinter::Orientation + enum Orientation { + Portrait, + Landscape + }; + + enum Mode { + StandardMode, // Paint Rect includes margins + FullPageMode // Paint Rect excludes margins + }; + + QPageLayout(); + QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation, + const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point, + const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0)); + QPageLayout(const QPageLayout &other); + ~QPageLayout(); + + QPageLayout &operator=(const QPageLayout &other); + #ifdef Q_COMPILER_RVALUE_REFS + QPageLayout &operator=(QPageLayout &&other) { swap(other); return *this; } +#endif + + void swap(QPageLayout &other) { d.swap(other.d); } + + bool operator==(const QPageLayout &other) const; + bool isEquivalentTo(const QPageLayout &other) const; + + bool isValid() const; + + void setMode(QPageLayout::Mode mode); + QPageLayout::Mode mode() const; + + void setPageSize(const QPageSize &pageSize, + const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0)); + QPageSize pageSize() const; + + void setOrientation(QPageLayout::Orientation orientation); + QPageLayout::Orientation orientation() const; + + void setUnits(QPageLayout::Unit units); + QPageLayout::Unit units() const; + + bool setMargins(const QMarginsF &margins); + bool setLeftMargin(qreal leftMargin); + bool setRightMargin(qreal rightMargin); + bool setTopMargin(qreal topMargin); + bool setBottomMargin(qreal bottomMargin); + + QMarginsF margins() const; + QMarginsF margins(QPageLayout::Unit units) const; + QMargins marginsPoints() const; + QMargins marginsPixels(int resolution) const; + + void setMinimumMargins(const QMarginsF &minMargins); + QMarginsF minimumMargins() const; + QMarginsF maximumMargins() const; + + QRectF fullRect() const; + QRectF fullRect(QPageLayout::Unit units) const; + QRect fullRectPoints() const; + QRect fullRectPixels(int resolution) const; + + QRectF paintRect() const; + QRectF paintRect(QPageLayout::Unit units) const; + QRect paintRectPoints() const; + QRect paintRectPixels(int resolution) const; + +private: + friend class QPageLayoutPrivate; + QSharedDataPointer<QPageLayoutPrivate> d; +}; + +Q_DECLARE_SHARED(QPageLayout) + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageLayout &pageLayout); +#endif + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QPageLayout) +Q_DECLARE_METATYPE(QPageLayout::Unit) +Q_DECLARE_METATYPE(QPageLayout::Orientation) + +#endif // QPAGELAYOUT_H diff --git a/tests/auto/gui/painting/painting.pro b/tests/auto/gui/painting/painting.pro index 8dfb4ba93c..f448419b7b 100644 --- a/tests/auto/gui/painting/painting.pro +++ b/tests/auto/gui/painting/painting.pro @@ -5,6 +5,7 @@ SUBDIRS=\ qcolor \ qbrush \ qregion \ + qpagelayout \ qpagesize \ qpainter \ qpathclipper \ diff --git a/tests/auto/gui/painting/qpagelayout/.gitignore b/tests/auto/gui/painting/qpagelayout/.gitignore new file mode 100644 index 0000000000..7c7dcd262b --- /dev/null +++ b/tests/auto/gui/painting/qpagelayout/.gitignore @@ -0,0 +1 @@ +tst_qpagelayout diff --git a/tests/auto/gui/painting/qpagelayout/qpagelayout.pro b/tests/auto/gui/painting/qpagelayout/qpagelayout.pro new file mode 100644 index 0000000000..38a1064357 --- /dev/null +++ b/tests/auto/gui/painting/qpagelayout/qpagelayout.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +CONFIG += parallel_test +TARGET = tst_qpagelayout +SOURCES += tst_qpagelayout.cpp + +QT += gui-private testlib + +DEFINES += QT_USE_USING_NAMESPACE +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp new file mode 100644 index 0000000000..30d25f00d2 --- /dev/null +++ b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2014 John Layt <jlayt@kde.org> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtGui/qpagelayout.h> + +class tst_QPageLayout : public QObject +{ + Q_OBJECT + +private slots: + void invalid(); + void basics(); + void setGetMargins(); +}; + +void tst_QPageLayout::invalid() +{ + // Invalid + QPageLayout invalid = QPageLayout(); + QCOMPARE(invalid.isValid(), false); + invalid = QPageLayout(QPageSize(), QPageLayout::Portrait, QMarginsF()); + QCOMPARE(invalid.isValid(), false); +} + +void tst_QPageLayout::basics() +{ + // Simple A4, no margins + QPageLayout simple = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.isValid(), true); + QCOMPARE(simple.pageSize().id(), QPageSize::A4); + QCOMPARE(simple.orientation(), QPageLayout::Portrait); + QCOMPARE(simple.margins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.margins(QPageLayout::Millimeter), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.marginsPoints(), QMargins(0, 0, 0, 0)); + QCOMPARE(simple.marginsPixels(72), QMargins(0, 0, 0, 0)); + QCOMPARE(simple.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.maximumMargins(), QMarginsF(595, 842, 595, 842)); + QCOMPARE(simple.fullRect(), QRectF(0, 0, 595, 842)); + QCOMPARE(simple.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 210, 297)); + QCOMPARE(simple.fullRectPoints(), QRect(0, 0, 595, 842)); + QCOMPARE(simple.fullRectPixels(72), QRect(0, 0, 595, 842)); + QCOMPARE(simple.paintRect(), QRectF(0, 0, 595, 842)); + QCOMPARE(simple.paintRect(QPageLayout::Millimeter), QRectF(0, 0, 210, 297)); + QCOMPARE(simple.paintRectPoints(), QRect(0, 0, 595, 842)); + QCOMPARE(simple.paintRectPixels(72), QRect(0, 0, 595, 842)); + + // Change orientation + simple.setOrientation(QPageLayout::Landscape); + QCOMPARE(simple.orientation(), QPageLayout::Landscape); + QCOMPARE(simple.margins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.maximumMargins(), QMarginsF(842, 595, 842, 595)); + QCOMPARE(simple.fullRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(simple.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(simple.fullRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(simple.fullRectPixels(72), QRect(0, 0, 842, 595)); + QCOMPARE(simple.paintRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(simple.paintRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(simple.paintRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(simple.paintRectPixels(72), QRect(0, 0, 842, 595)); + + // Change mode + QCOMPARE(simple.mode(), QPageLayout::StandardMode); + simple.setMode(QPageLayout::FullPageMode); + QCOMPARE(simple.mode(), QPageLayout::FullPageMode); + QCOMPARE(simple.orientation(), QPageLayout::Landscape); + QCOMPARE(simple.margins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(simple.maximumMargins(), QMarginsF(842, 595, 842, 595)); + QCOMPARE(simple.fullRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(simple.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(simple.fullRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(simple.fullRectPixels(72), QRect(0, 0, 842, 595)); + QCOMPARE(simple.paintRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(simple.paintRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(simple.paintRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(simple.paintRectPixels(72), QRect(0, 0, 842, 595)); + + // A4, 10pt margins + QPageLayout tenpoint = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10)); + QCOMPARE(tenpoint.isValid(), true); + QCOMPARE(tenpoint.margins(), QMarginsF(10, 10, 10, 10)); + QCOMPARE(tenpoint.margins(QPageLayout::Millimeter), QMarginsF(3.53, 3.53, 3.53, 3.53)); + QCOMPARE(tenpoint.marginsPoints(), QMargins(10, 10, 10, 10)); + QCOMPARE(tenpoint.marginsPixels(72), QMargins(10, 10, 10, 10)); + QCOMPARE(tenpoint.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(tenpoint.maximumMargins(), QMarginsF(595, 842, 595, 842)); + QCOMPARE(tenpoint.fullRect(), QRectF(0, 0, 595, 842)); + QCOMPARE(tenpoint.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 210, 297)); + QCOMPARE(tenpoint.fullRectPoints(), QRect(0, 0, 595, 842)); + QCOMPARE(tenpoint.fullRectPixels(72), QRect(0, 0, 595, 842)); + QCOMPARE(tenpoint.paintRect(), QRectF(10, 10, 575, 822)); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter), QRectF(3.53, 3.53, 202.94, 289.94)); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).x(), 3.53); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).y(), 3.53); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).width(), 202.94); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).height(), 289.94); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).left(), 3.53); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).right(), 206.47); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).top(), 3.53); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter).bottom(), 293.47); + QCOMPARE(tenpoint.paintRectPoints(), QRect(10, 10, 575, 822)); + QCOMPARE(tenpoint.paintRectPixels(72), QRect(10, 10, 575, 822)); + + // Change orientation + tenpoint.setOrientation(QPageLayout::Landscape); + QCOMPARE(tenpoint.orientation(), QPageLayout::Landscape); + QCOMPARE(tenpoint.margins(), QMarginsF(10, 10, 10, 10)); + QCOMPARE(tenpoint.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(tenpoint.maximumMargins(), QMarginsF(842, 595, 842, 595)); + QCOMPARE(tenpoint.fullRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(tenpoint.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(tenpoint.fullRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(tenpoint.fullRectPixels(72), QRect(0, 0, 842, 595)); + QCOMPARE(tenpoint.paintRect(), QRectF(10, 10, 822, 575)); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter), QRectF(3.53, 3.53, 289.94, 202.94)); + QCOMPARE(tenpoint.paintRectPoints(), QRect(10, 10, 822, 575)); + QCOMPARE(tenpoint.paintRectPixels(72), QRect(10, 10, 822, 575)); + + // Change mode + QCOMPARE(tenpoint.mode(), QPageLayout::StandardMode); + tenpoint.setMode(QPageLayout::FullPageMode); + QCOMPARE(tenpoint.mode(), QPageLayout::FullPageMode); + QCOMPARE(tenpoint.orientation(), QPageLayout::Landscape); + QCOMPARE(tenpoint.margins(), QMarginsF(10, 10, 10, 10)); + QCOMPARE(tenpoint.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(tenpoint.maximumMargins(), QMarginsF(842, 595, 842, 595)); + QCOMPARE(tenpoint.fullRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(tenpoint.fullRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(tenpoint.fullRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(tenpoint.fullRectPixels(72), QRect(0, 0, 842, 595)); + QCOMPARE(tenpoint.paintRect(), QRectF(0, 0, 842, 595)); + QCOMPARE(tenpoint.paintRect(QPageLayout::Millimeter), QRectF(0, 0, 297, 210)); + QCOMPARE(tenpoint.paintRectPoints(), QRect(0, 0, 842, 595)); + QCOMPARE(tenpoint.paintRectPixels(72), QRect(0, 0, 842, 595)); +} + +void tst_QPageLayout::setGetMargins() +{ + // A4, 20pt margins + QMarginsF margins = QMarginsF(10, 10, 10, 10); + QMarginsF min = QMarginsF(10, 10, 10, 10); + QMarginsF max = QMarginsF(585, 832, 585, 832); + QPageLayout change = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, margins, QPageLayout::Point, min); + QCOMPARE(change.isValid(), true); + QCOMPARE(change.margins(), margins); + QCOMPARE(change.margins(QPageLayout::Millimeter), QMarginsF(3.53, 3.53, 3.53, 3.53)); + QCOMPARE(change.marginsPoints(), QMargins(10, 10, 10, 10)); + QCOMPARE(change.marginsPixels(72), QMargins(10, 10, 10, 10)); + QCOMPARE(change.minimumMargins(), min); + QCOMPARE(change.maximumMargins(), max); + + // Set magins within min/max ok + margins = QMarginsF(20, 20, 20, 20); + change.setMargins(margins); + QCOMPARE(change.margins(QPageLayout::Millimeter), QMarginsF(7.06, 7.06, 7.06, 7.06)); + QCOMPARE(change.marginsPoints(), QMargins(20, 20, 20, 20)); + QCOMPARE(change.marginsPixels(72), QMargins(20, 20, 20, 20)); + QCOMPARE(change.margins(), margins); + + // Set margins all below min is rejected + change.setMargins(QMarginsF(0, 0, 0, 0)); + QCOMPARE(change.margins(), margins); + + // Set margins all above max is rejected + change.setMargins(QMarginsF(1000, 1000, 1000, 1000)); + QCOMPARE(change.margins(), margins); + + // Only 1 wrong, set still rejects + change.setMargins(QMarginsF(50, 50, 50, 0)); + QCOMPARE(change.margins(), margins); + + // Set page size resets min/max, clamps existing margins + change.setMargins(change.maximumMargins()); + change.setPageSize(QPageSize(QPageSize::A5)); + QCOMPARE(change.margins(), QMarginsF(420, 595, 420, 595)); + QCOMPARE(change.minimumMargins(), QMarginsF(0, 0, 0, 0)); + QCOMPARE(change.maximumMargins(), QMarginsF(420, 595, 420, 595)); + + // Set page size, sets min/max, clamps existing margins + margins = QMarginsF(20, 500, 20, 500); + change.setMargins(margins); + QCOMPARE(change.margins(), margins); + min = QMarginsF(30, 30, 30, 30); + max = QMarginsF(267, 390, 267, 390); + change.setPageSize(QPageSize(QPageSize::A6)); + change.setMinimumMargins(min); + QCOMPARE(change.margins(), QMarginsF(30, 390, 30, 390)); + QCOMPARE(change.minimumMargins(), min); + QCOMPARE(change.maximumMargins(), max); + + // A4, 20pt margins + margins = QMarginsF(20, 20, 20, 20); + min = QMarginsF(10, 10, 10, 10); + max = QMarginsF(585, 832, 585, 832); + QPageLayout fullPage = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, margins, QPageLayout::Point, min); + fullPage.setMode(QPageLayout::FullPageMode); + QCOMPARE(fullPage.isValid(), true); + QCOMPARE(fullPage.margins(), margins); + QCOMPARE(fullPage.minimumMargins(), min); + QCOMPARE(fullPage.maximumMargins(), max); + + // Set margins within min/max ok + margins = QMarginsF(50, 50, 50, 50); + fullPage.setMargins(margins); + QCOMPARE(fullPage.margins(), margins); + + // Set margins all below min is accepted + margins = QMarginsF(0, 0, 0, 0); + fullPage.setMargins(margins); + QCOMPARE(fullPage.margins(), margins); + + // Set margins all above max is rejected + margins = QMarginsF(1000, 1000, 1000, 1000); + fullPage.setMargins(margins); + QCOMPARE(fullPage.margins(), margins); + + // Only 1 wrong, set still accepts + margins = QMarginsF(50, 50, 50, 0); + fullPage.setMargins(margins); + QCOMPARE(fullPage.margins(), margins); + + // Set page size, sets min/max, clamps existing margins + margins = QMarginsF(20, 500, 20, 500); + fullPage.setMargins(margins); + QCOMPARE(fullPage.margins(), margins); + min = QMarginsF(30, 30, 30, 30); + max = QMarginsF(267, 390, 267, 390); + fullPage.setPageSize(QPageSize(QPageSize::A6)); + fullPage.setMinimumMargins(min); + QCOMPARE(fullPage.margins(), margins); + QCOMPARE(fullPage.minimumMargins(), min); + QCOMPARE(fullPage.maximumMargins(), max); +} + +QTEST_APPLESS_MAIN(tst_QPageLayout) + +#include "tst_qpagelayout.moc" |