1 | // Copyright (C) 2014 John Layt <jlayt@kde.org> |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | |
5 | #include "qpagelayout.h" |
6 | |
7 | #include <QtCore/qpoint.h> |
8 | #include <QtCore/qrect.h> |
9 | #include <QtCore/qsize.h> |
10 | |
11 | #include <qdebug.h> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | QT_IMPL_METATYPE_EXTERN(QPageLayout) |
16 | QT_IMPL_METATYPE_EXTERN_TAGGED(QPageLayout::Unit, QPageLayout__Unit) |
17 | QT_IMPL_METATYPE_EXTERN_TAGGED(QPageLayout::Orientation, QPageLayout__Orientation) |
18 | |
19 | // Multiplier for converting units to points. |
20 | Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit) |
21 | { |
22 | switch (unit) { |
23 | case QPageLayout::Millimeter: |
24 | return 2.83464566929; |
25 | case QPageLayout::Point: |
26 | return 1.0; |
27 | case QPageLayout::Inch: |
28 | return 72.0; |
29 | case QPageLayout::Pica: |
30 | return 12; |
31 | case QPageLayout::Didot: |
32 | return 1.065826771; |
33 | case QPageLayout::Cicero: |
34 | return 12.789921252; |
35 | } |
36 | return 1.0; |
37 | } |
38 | |
39 | // Multiplier for converting pixels to points. |
40 | extern qreal qt_pixelMultiplier(int resolution); |
41 | |
42 | QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits) |
43 | { |
44 | // If the size have the same units, or are all 0, then don't need to convert |
45 | if (fromUnits == toUnits || xy.isNull()) |
46 | return xy; |
47 | |
48 | // If converting to points then convert and round to 0 decimal places |
49 | if (toUnits == QPageLayout::Point) { |
50 | const qreal multiplier = qt_pointMultiplier(unit: fromUnits); |
51 | return QPointF(qRound(d: xy.x() * multiplier), |
52 | qRound(d: xy.y() * multiplier)); |
53 | } |
54 | |
55 | // If converting to other units, need to convert to unrounded points first |
56 | QPointF pointXy = (fromUnits == QPageLayout::Point) ? xy : xy * qt_pointMultiplier(unit: fromUnits); |
57 | |
58 | // Then convert from points to required units rounded to 2 decimal places |
59 | const qreal multiplier = qt_pointMultiplier(unit: toUnits); |
60 | return QPointF(qRound(d: pointXy.x() * 100 / multiplier) / 100.0, |
61 | qRound(d: pointXy.y() * 100 / multiplier) / 100.0); |
62 | } |
63 | |
64 | Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits) |
65 | { |
66 | // If the margins have the same units, or are all 0, then don't need to convert |
67 | if (fromUnits == toUnits || margins.isNull()) |
68 | return margins; |
69 | |
70 | // If converting to points then convert and round to 0 decimal places |
71 | if (toUnits == QPageLayout::Point) { |
72 | const qreal multiplier = qt_pointMultiplier(unit: fromUnits); |
73 | return QMarginsF(qRound(d: margins.left() * multiplier), |
74 | qRound(d: margins.top() * multiplier), |
75 | qRound(d: margins.right() * multiplier), |
76 | qRound(d: margins.bottom() * multiplier)); |
77 | } |
78 | |
79 | // If converting to other units, need to convert to unrounded points first |
80 | QMarginsF pointMargins = fromUnits == QPageLayout::Point ? margins : margins * qt_pointMultiplier(unit: fromUnits); |
81 | |
82 | // Then convert from points to required units rounded to 2 decimal places |
83 | const qreal multiplier = qt_pointMultiplier(unit: toUnits); |
84 | return QMarginsF(qRound(d: pointMargins.left() * 100 / multiplier) / 100.0, |
85 | qRound(d: pointMargins.top() * 100 / multiplier) / 100.0, |
86 | qRound(d: pointMargins.right() * 100 / multiplier) / 100.0, |
87 | qRound(d: pointMargins.bottom() * 100 / multiplier) / 100.0); |
88 | } |
89 | |
90 | class QPageLayoutPrivate : public QSharedData |
91 | { |
92 | public: |
93 | |
94 | QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation, |
95 | const QMarginsF &margins, QPageLayout::Unit units, |
96 | const QMarginsF &minMargins); |
97 | ~QPageLayoutPrivate(); |
98 | |
99 | bool operator==(const QPageLayoutPrivate &other) const; |
100 | bool isEquivalentTo(const QPageLayoutPrivate &other) const; |
101 | |
102 | bool isValid() const; |
103 | |
104 | void clampMargins(const QMarginsF &margins); |
105 | |
106 | QMarginsF margins(QPageLayout::Unit units) const; |
107 | QMargins marginsPoints() const; |
108 | QMargins marginsPixels(int resolution) const; |
109 | |
110 | void setDefaultMargins(const QMarginsF &minMargins); |
111 | |
112 | QSizeF paintSize() const; |
113 | |
114 | QRectF fullRect() const; |
115 | QRectF fullRect(QPageLayout::Unit units) const; |
116 | QRect fullRectPoints() const; |
117 | QRect fullRectPixels(int resolution) const; |
118 | |
119 | QRectF paintRect() const; |
120 | |
121 | private: |
122 | friend class QPageLayout; |
123 | |
124 | QSizeF fullSizeUnits(QPageLayout::Unit units) const; |
125 | |
126 | QPageSize m_pageSize; |
127 | QPageLayout::Orientation m_orientation; |
128 | QPageLayout::Mode m_mode; |
129 | QPageLayout::Unit m_units; |
130 | QSizeF m_fullSize; |
131 | QMarginsF m_margins; |
132 | QMarginsF m_minMargins; |
133 | QMarginsF m_maxMargins; |
134 | }; |
135 | |
136 | QPageLayoutPrivate::QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation, |
137 | const QMarginsF &margins, QPageLayout::Unit units, |
138 | const QMarginsF &minMargins) |
139 | : m_pageSize(pageSize), |
140 | m_orientation(orientation), |
141 | m_mode(QPageLayout::StandardMode), |
142 | m_units(units), |
143 | m_margins(margins) |
144 | { |
145 | m_fullSize = fullSizeUnits(units: m_units); |
146 | setDefaultMargins(minMargins); |
147 | } |
148 | |
149 | QPageLayoutPrivate::~QPageLayoutPrivate() |
150 | { |
151 | } |
152 | |
153 | bool QPageLayoutPrivate::operator==(const QPageLayoutPrivate &other) const |
154 | { |
155 | return m_pageSize == other.m_pageSize |
156 | && m_orientation == other.m_orientation |
157 | && m_units == other.m_units |
158 | && m_margins == other.m_margins |
159 | && m_minMargins == other.m_minMargins |
160 | && m_maxMargins == other.m_maxMargins; |
161 | } |
162 | |
163 | bool QPageLayoutPrivate::isEquivalentTo(const QPageLayoutPrivate &other) const |
164 | { |
165 | return m_pageSize.isEquivalentTo(other: other.m_pageSize) |
166 | && m_orientation == other.m_orientation |
167 | && qt_convertMargins(margins: m_margins, fromUnits: m_units, toUnits: QPageLayout::Point) |
168 | == qt_convertMargins(margins: other.m_margins, fromUnits: other.m_units, toUnits: QPageLayout::Point); |
169 | } |
170 | |
171 | bool QPageLayoutPrivate::isValid() const |
172 | { |
173 | return m_pageSize.isValid(); |
174 | } |
175 | |
176 | void QPageLayoutPrivate::clampMargins(const QMarginsF &margins) |
177 | { |
178 | m_margins = QMarginsF(qBound(min: m_minMargins.left(), val: margins.left(), max: m_maxMargins.left()), |
179 | qBound(min: m_minMargins.top(), val: margins.top(), max: m_maxMargins.top()), |
180 | qBound(min: m_minMargins.right(), val: margins.right(), max: m_maxMargins.right()), |
181 | qBound(min: m_minMargins.bottom(), val: margins.bottom(), max: m_maxMargins.bottom())); |
182 | } |
183 | |
184 | QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const |
185 | { |
186 | return qt_convertMargins(margins: m_margins, fromUnits: m_units, toUnits: units); |
187 | } |
188 | |
189 | QMargins QPageLayoutPrivate::marginsPoints() const |
190 | { |
191 | return qt_convertMargins(margins: m_margins, fromUnits: m_units, toUnits: QPageLayout::Point).toMargins(); |
192 | } |
193 | |
194 | QMargins QPageLayoutPrivate::marginsPixels(int resolution) const |
195 | { |
196 | return marginsPoints() / qt_pixelMultiplier(resolution); |
197 | } |
198 | |
199 | void QPageLayoutPrivate::setDefaultMargins(const QMarginsF &minMargins) |
200 | { |
201 | m_minMargins = minMargins; |
202 | m_maxMargins = QMarginsF(qMax(a: m_fullSize.width() - m_minMargins.right(), b: qreal(0)), |
203 | qMax(a: m_fullSize.height() - m_minMargins.bottom(), b: qreal(0)), |
204 | qMax(a: m_fullSize.width() - m_minMargins.left(), b: qreal(0)), |
205 | qMax(a: m_fullSize.height() - m_minMargins.top(), b: qreal(0))); |
206 | if (m_mode == QPageLayout::StandardMode) |
207 | clampMargins(margins: m_margins); |
208 | } |
209 | |
210 | QSizeF QPageLayoutPrivate::fullSizeUnits(QPageLayout::Unit units) const |
211 | { |
212 | QSizeF fullPageSize = m_pageSize.size(units: QPageSize::Unit(units)); |
213 | return m_orientation == QPageLayout::Landscape ? fullPageSize.transposed() : fullPageSize; |
214 | } |
215 | |
216 | QRectF QPageLayoutPrivate::fullRect() const |
217 | { |
218 | return QRectF(QPointF(0, 0), m_fullSize); |
219 | } |
220 | |
221 | QRectF QPageLayoutPrivate::fullRect(QPageLayout::Unit units) const |
222 | { |
223 | return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units)); |
224 | } |
225 | |
226 | QRect QPageLayoutPrivate::fullRectPoints() const |
227 | { |
228 | if (m_orientation == QPageLayout::Landscape) |
229 | return QRect(QPoint(0, 0), m_pageSize.sizePoints().transposed()); |
230 | else |
231 | return QRect(QPoint(0, 0), m_pageSize.sizePoints()); |
232 | } |
233 | |
234 | QRect QPageLayoutPrivate::fullRectPixels(int resolution) const |
235 | { |
236 | if (m_orientation == QPageLayout::Landscape) |
237 | return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution).transposed()); |
238 | else |
239 | return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution)); |
240 | } |
241 | |
242 | QRectF QPageLayoutPrivate::paintRect() const |
243 | { |
244 | return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins; |
245 | } |
246 | |
247 | |
248 | /*! |
249 | \class QPageLayout |
250 | \inmodule QtGui |
251 | \since 5.3 |
252 | \brief Describes the size, orientation and margins of a page. |
253 | |
254 | The QPageLayout class defines the layout of a page in a paged document, with the |
255 | page size, orientation and margins able to be set and the full page and paintable |
256 | page rectangles defined by those attributes able to be queried in a variety of units. |
257 | |
258 | The page size is defined by the QPageSize class which can be queried for page size |
259 | attributes. Note that the QPageSize itself is always defined in a Portrait |
260 | orientation. |
261 | |
262 | The minimum margins can be defined for the layout but normally default to 0. |
263 | When used in conjunction with Qt's printing support the minimum margins |
264 | will reflect the minimum printable area defined by the printer. |
265 | |
266 | In the default StandardMode the current margins and minimum margins are |
267 | always taken into account. The paintable rectangle is the full page |
268 | rectangle less the current margins, and the current margins can only be set |
269 | to values between the minimum margins and the maximum margins allowed by |
270 | the full page size. |
271 | |
272 | In FullPageMode the current margins and minimum margins are not taken |
273 | into account. The paintable rectangle is the full page rectangle, and the |
274 | current margins can be set to any values regardless of the minimum margins |
275 | and page size. |
276 | |
277 | \sa QPageSize |
278 | */ |
279 | |
280 | /*! |
281 | \enum QPageLayout::Unit |
282 | |
283 | This enum type is used to specify the measurement unit for page layout and margins. |
284 | |
285 | \value Millimeter |
286 | \value Point 1/72th of an inch |
287 | \value Inch |
288 | \value Pica 1/72th of a foot, 1/6th of an inch, 12 Points |
289 | \value Didot 1/72th of a French inch, 0.375 mm |
290 | \value Cicero 1/6th of a French inch, 12 Didot, 4.5mm |
291 | */ |
292 | |
293 | /*! |
294 | \enum QPageLayout::Orientation |
295 | |
296 | This enum type defines the page orientation |
297 | |
298 | \value Portrait The page size is used in its default orientation |
299 | \value Landscape The page size is rotated through 90 degrees |
300 | |
301 | Note that some standard page sizes are defined with a width larger than |
302 | their height, hence the orientation is defined relative to the standard |
303 | page size and not using the relative page dimensions. |
304 | */ |
305 | |
306 | /*! |
307 | \enum QPageLayout::Mode |
308 | |
309 | Defines the page layout mode |
310 | |
311 | \value StandardMode Paint Rect includes margins, margins must fall between the minimum and maximum. |
312 | \value FullPageMode Paint Rect excludes margins, margins can be any value and must be managed manually. |
313 | */ |
314 | |
315 | /*! |
316 | Creates an invalid QPageLayout. |
317 | */ |
318 | |
319 | QPageLayout::QPageLayout() |
320 | : QPageLayout(QPageSize(), QPageLayout::Landscape, QMarginsF()) |
321 | { |
322 | } |
323 | |
324 | /*! |
325 | Creates a QPageLayout with the given \a pageSize, \a orientation and |
326 | \a margins in the given \a units. |
327 | |
328 | Optionally define the minimum allowed margins \a minMargins, e.g. the minimum |
329 | margins able to be printed by a physical print device. |
330 | |
331 | The constructed QPageLayout will be in StandardMode. |
332 | |
333 | The \a margins given will be clamped to the minimum margins and the maximum |
334 | margins allowed by the page size. |
335 | */ |
336 | |
337 | QPageLayout::QPageLayout(const QPageSize &pageSize, Orientation orientation, |
338 | const QMarginsF &margins, Unit units, |
339 | const QMarginsF &minMargins) |
340 | : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins)) |
341 | { |
342 | } |
343 | |
344 | /*! |
345 | Copy constructor, copies \a other to this. |
346 | */ |
347 | |
348 | QPageLayout::QPageLayout(const QPageLayout &other) |
349 | : d(other.d) |
350 | { |
351 | } |
352 | |
353 | /*! |
354 | Destroys the page layout. |
355 | */ |
356 | |
357 | QPageLayout::~QPageLayout() |
358 | { |
359 | } |
360 | |
361 | /*! |
362 | Assignment operator, assigns \a other to this. |
363 | */ |
364 | |
365 | QPageLayout &QPageLayout::operator=(const QPageLayout &other) |
366 | { |
367 | d = other.d; |
368 | return *this; |
369 | } |
370 | |
371 | /*! |
372 | \fn void QPageLayout::swap(QPageLayout &other) |
373 | |
374 | Swaps this page layout with \a other. This function is very fast and |
375 | never fails. |
376 | */ |
377 | |
378 | /*! |
379 | \fn QPageLayout &QPageLayout::operator=(QPageLayout &&other) |
380 | |
381 | Move-assigns \a other to this QPageLayout instance, transferring the |
382 | ownership of the managed pointer to this instance. |
383 | */ |
384 | |
385 | /*! |
386 | \fn bool QPageLayout::operator==(const QPageLayout &lhs, const QPageLayout &rhs) |
387 | |
388 | Returns \c true if page layout \a lhs is equal to page layout \a rhs, |
389 | i.e. if all the attributes are exactly equal. |
390 | |
391 | Note that this is a strict equality, especially for page size where the |
392 | QPageSize ID, name and size must exactly match, and the margins where the |
393 | units must match. |
394 | |
395 | \sa QPageLayout::isEquivalentTo() |
396 | */ |
397 | |
398 | /*! |
399 | \fn bool QPageLayout::operator!=(const QPageLayout &lhs, const QPageLayout &rhs) |
400 | |
401 | Returns \c true if page layout \a lhs is not equal to page layout \a rhs, |
402 | i.e. if any of the attributes differ. |
403 | |
404 | Note that this is a strict equality, especially for page size where the |
405 | QPageSize ID, name and size must exactly match, and the margins where the |
406 | units must match. |
407 | |
408 | \sa QPageLayout::isEquivalentTo() |
409 | */ |
410 | |
411 | /*! |
412 | \internal |
413 | */ |
414 | bool QPageLayout::equals(const QPageLayout &other) const |
415 | { |
416 | return d == other.d || *d == *other.d; |
417 | } |
418 | |
419 | |
420 | /*! |
421 | Returns \c true if this page layout is equivalent to the \a other page layout, |
422 | i.e. if the page has the same size, margins and orientation. |
423 | */ |
424 | |
425 | bool QPageLayout::isEquivalentTo(const QPageLayout &other) const |
426 | { |
427 | return d && other.d && d->isEquivalentTo(other: *other.d); |
428 | } |
429 | |
430 | /*! |
431 | Returns \c true if this page layout is valid. |
432 | */ |
433 | |
434 | bool QPageLayout::isValid() const |
435 | { |
436 | return d->isValid(); |
437 | } |
438 | |
439 | /*! |
440 | Sets a page layout mode to \a mode. |
441 | */ |
442 | |
443 | void QPageLayout::setMode(Mode mode) |
444 | { |
445 | d.detach(); |
446 | d->m_mode = mode; |
447 | } |
448 | |
449 | /*! |
450 | Returns the page layout mode. |
451 | */ |
452 | |
453 | QPageLayout::Mode QPageLayout::mode() const |
454 | { |
455 | return d->m_mode; |
456 | } |
457 | |
458 | /*! |
459 | Sets the page size of the page layout to \a pageSize. |
460 | |
461 | Optionally define the minimum allowed margins \a minMargins, e.g. the minimum |
462 | margins able to be printed by a physical print device, otherwise the |
463 | minimum margins will default to 0. |
464 | |
465 | If StandardMode is set then the existing margins will be clamped |
466 | to the new minimum margins and the maximum margins allowed by the page size. |
467 | If FullPageMode is set then the existing margins will be unchanged. |
468 | */ |
469 | |
470 | void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins) |
471 | { |
472 | if (!pageSize.isValid()) |
473 | return; |
474 | d.detach(); |
475 | d->m_pageSize = pageSize; |
476 | d->m_fullSize = d->fullSizeUnits(units: d->m_units); |
477 | d->setDefaultMargins(minMargins); |
478 | } |
479 | |
480 | /*! |
481 | Returns the page size of the page layout. |
482 | |
483 | Note that the QPageSize is always defined in a Portrait orientation. To |
484 | obtain a size that takes the set orientation into account you must use |
485 | fullRect(). |
486 | */ |
487 | |
488 | QPageSize QPageLayout::pageSize() const |
489 | { |
490 | return d->m_pageSize; |
491 | } |
492 | |
493 | /*! |
494 | Sets the page orientation of the page layout to \a orientation. |
495 | |
496 | Changing the orientation does not affect the current margins or |
497 | the minimum margins. |
498 | */ |
499 | |
500 | void QPageLayout::setOrientation(Orientation orientation) |
501 | { |
502 | if (orientation != d->m_orientation) { |
503 | d.detach(); |
504 | d->m_orientation = orientation; |
505 | d->m_fullSize = d->fullSizeUnits(units: d->m_units); |
506 | // Adust the max margins to reflect change in max page size |
507 | const qreal change = d->m_fullSize.width() - d->m_fullSize.height(); |
508 | d->m_maxMargins.setLeft(d->m_maxMargins.left() + change); |
509 | d->m_maxMargins.setRight(d->m_maxMargins.right() + change); |
510 | d->m_maxMargins.setTop(d->m_maxMargins.top() - change); |
511 | d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change); |
512 | } |
513 | } |
514 | |
515 | /*! |
516 | Returns the page orientation of the page layout. |
517 | */ |
518 | |
519 | QPageLayout::Orientation QPageLayout::orientation() const |
520 | { |
521 | return d->m_orientation; |
522 | } |
523 | |
524 | /*! |
525 | Sets the \a units used to define the page layout. |
526 | */ |
527 | |
528 | void QPageLayout::setUnits(Unit units) |
529 | { |
530 | if (units != d->m_units) { |
531 | d.detach(); |
532 | d->m_margins = qt_convertMargins(margins: d->m_margins, fromUnits: d->m_units, toUnits: units); |
533 | d->m_minMargins = qt_convertMargins(margins: d->m_minMargins, fromUnits: d->m_units, toUnits: units); |
534 | d->m_maxMargins = qt_convertMargins(margins: d->m_maxMargins, fromUnits: d->m_units, toUnits: units); |
535 | d->m_units = units; |
536 | d->m_fullSize = d->fullSizeUnits(units: d->m_units); |
537 | } |
538 | } |
539 | |
540 | /*! |
541 | Returns the units the page layout is currently defined in. |
542 | */ |
543 | |
544 | QPageLayout::Unit QPageLayout::units() const |
545 | { |
546 | return d->m_units; |
547 | } |
548 | |
549 | /*! |
550 | Sets the page margins of the page layout to \a margins |
551 | Returns true if the margins were successfully set. |
552 | |
553 | The units used are those currently defined for the layout. To use different |
554 | units then call setUnits() first. |
555 | |
556 | If in the default StandardMode then all the new margins must fall between the |
557 | minimum margins set and the maximum margins allowed by the page size, |
558 | otherwise the margins will not be set. |
559 | |
560 | If in FullPageMode then any margin values will be accepted. |
561 | |
562 | \sa margins(), units() |
563 | */ |
564 | |
565 | bool QPageLayout::setMargins(const QMarginsF &margins) |
566 | { |
567 | if (d->m_mode == FullPageMode) { |
568 | d.detach(); |
569 | d->m_margins = margins; |
570 | return true; |
571 | } else if (margins.left() >= d->m_minMargins.left() |
572 | && margins.right() >= d->m_minMargins.right() |
573 | && margins.top() >= d->m_minMargins.top() |
574 | && margins.bottom() >= d->m_minMargins.bottom() |
575 | && margins.left() <= d->m_maxMargins.left() |
576 | && margins.right() <= d->m_maxMargins.right() |
577 | && margins.top() <= d->m_maxMargins.top() |
578 | && margins.bottom() <= d->m_maxMargins.bottom()) { |
579 | d.detach(); |
580 | d->m_margins = margins; |
581 | return true; |
582 | } |
583 | return false; |
584 | } |
585 | |
586 | /*! |
587 | Sets the left page margin of the page layout to \a leftMargin. |
588 | Returns true if the margin was successfully set. |
589 | |
590 | The units used are those currently defined for the layout. To use different |
591 | units call setUnits() first. |
592 | |
593 | If in the default StandardMode then the new margin must fall between the |
594 | minimum margin set and the maximum margin allowed by the page size, |
595 | otherwise the margin will not be set. |
596 | |
597 | If in FullPageMode then any margin values will be accepted. |
598 | |
599 | \sa setMargins(), margins() |
600 | */ |
601 | |
602 | bool QPageLayout::setLeftMargin(qreal leftMargin) |
603 | { |
604 | if (d->m_mode == FullPageMode |
605 | || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) { |
606 | d.detach(); |
607 | d->m_margins.setLeft(leftMargin); |
608 | return true; |
609 | } |
610 | return false; |
611 | } |
612 | |
613 | /*! |
614 | Sets the right page margin of the page layout to \a rightMargin. |
615 | Returns true if the margin was successfully set. |
616 | |
617 | The units used are those currently defined for the layout. To use different |
618 | units call setUnits() first. |
619 | |
620 | If in the default StandardMode then the new margin must fall between the |
621 | minimum margin set and the maximum margin allowed by the page size, |
622 | otherwise the margin will not be set. |
623 | |
624 | If in FullPageMode then any margin values will be accepted. |
625 | |
626 | \sa setMargins(), margins() |
627 | */ |
628 | |
629 | bool QPageLayout::setRightMargin(qreal rightMargin) |
630 | { |
631 | if (d->m_mode == FullPageMode |
632 | || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) { |
633 | d.detach(); |
634 | d->m_margins.setRight(rightMargin); |
635 | return true; |
636 | } |
637 | return false; |
638 | } |
639 | |
640 | /*! |
641 | Sets the top page margin of the page layout to \a topMargin. |
642 | Returns true if the margin was successfully set. |
643 | |
644 | The units used are those currently defined for the layout. To use different |
645 | units call setUnits() first. |
646 | |
647 | If in the default StandardMode then the new margin must fall between the |
648 | minimum margin set and the maximum margin allowed by the page size, |
649 | otherwise the margin will not be set. |
650 | |
651 | If in FullPageMode then any margin values will be accepted. |
652 | |
653 | \sa setMargins(), margins() |
654 | */ |
655 | |
656 | bool QPageLayout::setTopMargin(qreal topMargin) |
657 | { |
658 | if (d->m_mode == FullPageMode |
659 | || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) { |
660 | d.detach(); |
661 | d->m_margins.setTop(topMargin); |
662 | return true; |
663 | } |
664 | return false; |
665 | } |
666 | |
667 | /*! |
668 | Sets the bottom page margin of the page layout to \a bottomMargin. |
669 | Returns true if the margin was successfully set. |
670 | |
671 | The units used are those currently defined for the layout. To use different |
672 | units call setUnits() first. |
673 | |
674 | If in the default StandardMode then the new margin must fall between the |
675 | minimum margin set and the maximum margin allowed by the page size, |
676 | otherwise the margin will not be set. |
677 | |
678 | If in FullPageMode then any margin values will be accepted. |
679 | |
680 | \sa setMargins(), margins() |
681 | */ |
682 | |
683 | bool QPageLayout::setBottomMargin(qreal bottomMargin) |
684 | { |
685 | if (d->m_mode == FullPageMode |
686 | || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) { |
687 | d.detach(); |
688 | d->m_margins.setBottom(bottomMargin); |
689 | return true; |
690 | } |
691 | return false; |
692 | } |
693 | |
694 | /*! |
695 | Returns the margins of the page layout using the currently set units. |
696 | |
697 | \sa setMargins(), units() |
698 | */ |
699 | |
700 | QMarginsF QPageLayout::margins() const |
701 | { |
702 | return d->m_margins; |
703 | } |
704 | |
705 | /*! |
706 | Returns the margins of the page layout using the requested \a units. |
707 | |
708 | \sa setMargins(), margins() |
709 | */ |
710 | |
711 | QMarginsF QPageLayout::margins(Unit units) const |
712 | { |
713 | return d->margins(units); |
714 | } |
715 | |
716 | /*! |
717 | Returns the margins of the page layout in Postscript Points (1/72 of an inch). |
718 | |
719 | \sa setMargins(), margins() |
720 | */ |
721 | |
722 | QMargins QPageLayout::marginsPoints() const |
723 | { |
724 | return d->marginsPoints(); |
725 | } |
726 | |
727 | /*! |
728 | Returns the margins of the page layout in device pixels for the given \a resolution. |
729 | |
730 | \sa setMargins() |
731 | */ |
732 | |
733 | QMargins QPageLayout::marginsPixels(int resolution) const |
734 | { |
735 | return d->marginsPixels(resolution); |
736 | } |
737 | |
738 | /*! |
739 | Sets the minimum page margins of the page layout to \a minMargins. |
740 | |
741 | It is not recommended to override the default values set for a page size |
742 | as this may be the minimum printable area for a physical print device. |
743 | |
744 | If the StandardMode mode is set then the existing margins will be clamped |
745 | to the new \a minMargins and the maximum allowed by the page size. If the |
746 | FullPageMode is set then the existing margins will be unchanged. |
747 | |
748 | \sa minimumMargins(), setMargins() |
749 | */ |
750 | |
751 | void QPageLayout::setMinimumMargins(const QMarginsF &minMargins) |
752 | { |
753 | d.detach(); |
754 | d->setDefaultMargins(minMargins); |
755 | } |
756 | |
757 | /*! |
758 | Returns the minimum margins of the page layout. |
759 | |
760 | \sa setMinimumMargins(), maximumMargins() |
761 | */ |
762 | |
763 | QMarginsF QPageLayout::minimumMargins() const |
764 | { |
765 | return d->m_minMargins; |
766 | } |
767 | |
768 | /*! |
769 | Returns the maximum margins that would be applied if the page layout was |
770 | in StandardMode. |
771 | |
772 | The maximum margins allowed are calculated as the full size of the page |
773 | minus the minimum margins set. For example, if the page width is 100 points |
774 | and the minimum right margin is 10 points, then the maximum left margin |
775 | will be 90 points. |
776 | |
777 | \sa setMinimumMargins(), minimumMargins() |
778 | */ |
779 | |
780 | QMarginsF QPageLayout::maximumMargins() const |
781 | { |
782 | return d->m_maxMargins; |
783 | } |
784 | |
785 | /*! |
786 | Returns the full page rectangle in the current layout units. |
787 | |
788 | The page rectangle takes into account the page size and page orientation, |
789 | but not the page margins. |
790 | |
791 | \sa paintRect(), units() |
792 | */ |
793 | |
794 | QRectF QPageLayout::fullRect() const |
795 | { |
796 | return isValid() ? d->fullRect() : QRect(); |
797 | } |
798 | |
799 | /*! |
800 | Returns the full page rectangle in the required \a units. |
801 | |
802 | The page rectangle takes into account the page size and page orientation, |
803 | but not the page margins. |
804 | |
805 | \sa paintRect() |
806 | */ |
807 | |
808 | QRectF QPageLayout::fullRect(Unit units) const |
809 | { |
810 | return isValid() ? d->fullRect(units) : QRect(); |
811 | } |
812 | |
813 | /*! |
814 | Returns the full page rectangle in Postscript Points (1/72 of an inch). |
815 | |
816 | The page rectangle takes into account the page size and page orientation, |
817 | but not the page margins. |
818 | |
819 | \sa paintRect() |
820 | */ |
821 | |
822 | QRect QPageLayout::fullRectPoints() const |
823 | { |
824 | return isValid() ? d->fullRectPoints() : QRect(); |
825 | } |
826 | |
827 | /*! |
828 | Returns the full page rectangle in device pixels for the given \a resolution. |
829 | |
830 | The page rectangle takes into account the page size and page orientation, |
831 | but not the page margins. |
832 | |
833 | \sa paintRect() |
834 | */ |
835 | |
836 | QRect QPageLayout::fullRectPixels(int resolution) const |
837 | { |
838 | return isValid() ? d->fullRectPixels(resolution) : QRect(); |
839 | } |
840 | |
841 | /*! |
842 | Returns the page rectangle in the current layout units. |
843 | |
844 | The paintable rectangle takes into account the page size, orientation |
845 | and margins. |
846 | |
847 | If the FullPageMode mode is set then the fullRect() is returned and |
848 | the margins must be manually managed. |
849 | */ |
850 | |
851 | QRectF QPageLayout::paintRect() const |
852 | { |
853 | return isValid() ? d->paintRect() : QRectF(); |
854 | } |
855 | |
856 | /*! |
857 | Returns the page rectangle in the required \a units. |
858 | |
859 | The paintable rectangle takes into account the page size, orientation |
860 | and margins. |
861 | |
862 | If the FullPageMode mode is set then the fullRect() is returned and |
863 | the margins must be manually managed. |
864 | */ |
865 | |
866 | QRectF QPageLayout::paintRect(Unit units) const |
867 | { |
868 | if (!isValid()) |
869 | return QRectF(); |
870 | if (units == d->m_units) |
871 | return d->paintRect(); |
872 | return d->m_mode == FullPageMode ? d->fullRect(units) |
873 | : d->fullRect(units) - d->margins(units); |
874 | } |
875 | |
876 | /*! |
877 | Returns the paintable rectangle in rounded Postscript Points (1/72 of an inch). |
878 | |
879 | The paintable rectangle takes into account the page size, orientation |
880 | and margins. |
881 | |
882 | If the FullPageMode mode is set then the fullRect() is returned and |
883 | the margins must be manually managed. |
884 | */ |
885 | |
886 | QRect QPageLayout::paintRectPoints() const |
887 | { |
888 | if (!isValid()) |
889 | return QRect(); |
890 | return d->m_mode == FullPageMode ? d->fullRectPoints() |
891 | : d->fullRectPoints() - d->marginsPoints(); |
892 | } |
893 | |
894 | /*! |
895 | Returns the paintable rectangle in rounded device pixels for the given \a resolution. |
896 | |
897 | The paintable rectangle takes into account the page size, orientation |
898 | and margins. |
899 | |
900 | If the FullPageMode mode is set then the fullRect() is returned and |
901 | the margins must be manually managed. |
902 | */ |
903 | |
904 | QRect QPageLayout::paintRectPixels(int resolution) const |
905 | { |
906 | if (!isValid()) |
907 | return QRect(); |
908 | return d->m_mode == FullPageMode ? d->fullRectPixels(resolution) |
909 | : d->fullRectPixels(resolution) - d->marginsPixels(resolution); |
910 | } |
911 | |
912 | #ifndef QT_NO_DEBUG_STREAM |
913 | QDebug operator<<(QDebug dbg, const QPageLayout &layout) |
914 | { |
915 | QDebugStateSaver saver(dbg); |
916 | dbg.nospace(); |
917 | dbg.noquote(); |
918 | dbg << "QPageLayout(" ; |
919 | if (layout.isValid()) { |
920 | const QMarginsF margins = layout.margins(); |
921 | dbg << '"' << layout.pageSize().name() << "\", " |
922 | << (layout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape" ) |
923 | << ", l:" << margins.left() << " r:" << margins.right() << " t:" |
924 | << margins.top() << " b:" << margins.bottom() << ' '; |
925 | switch (layout.units()) { |
926 | case QPageLayout::Millimeter: |
927 | dbg << "mm" ; |
928 | break; |
929 | case QPageLayout::Point: |
930 | dbg << "pt" ; |
931 | break; |
932 | case QPageLayout::Inch: |
933 | dbg << "in" ; |
934 | break; |
935 | case QPageLayout::Pica: |
936 | dbg << "pc" ; |
937 | break; |
938 | case QPageLayout::Didot: |
939 | dbg << "DD" ; |
940 | break; |
941 | case QPageLayout::Cicero: |
942 | dbg << "CC" ; |
943 | break; |
944 | } |
945 | } |
946 | dbg << ')'; |
947 | return dbg; |
948 | } |
949 | #endif |
950 | |
951 | QT_END_NAMESPACE |
952 | |