QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgslayoutpagecollection.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutpagecollection.cpp
3 ----------------------------
4 begin : July 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
19#include "qgsfillsymbol.h"
20#include "qgslayout.h"
21#include "qgslayoutframe.h"
22#include "qgslayoutundostack.h"
23#include "qgsmargins.h"
24#include "qgsreadwritecontext.h"
25#include "qgssymbollayerutils.h"
26
27#include "moc_qgslayoutpagecollection.cpp"
28
30 : QObject( layout )
31 , mLayout( layout )
32 , mGuideCollection( new QgsLayoutGuideCollection( layout, this ) )
33{
34 createDefaultPageStyleSymbol();
35}
36
38{
39 const auto constMPages = mPages;
40 for ( QgsLayoutItemPage *page : constMPages )
41 {
42 mLayout->removeItem( page );
43 page->deleteLater();
44 }
45}
46
48{
49 if ( !symbol )
50 return;
51
52 mPageStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
53
54 for ( QgsLayoutItemPage *page : std::as_const( mPages ) )
55 {
56 page->setPageStyleSymbol( symbol->clone() );
57 page->update();
58 }
59}
60
62{
63 return mPageStyleSymbol.get();
64}
65
67{
68 mPreviousItemPositions.clear();
69 QList< QgsLayoutItem * > items;
70 mLayout->layoutItems( items );
71
72 for ( QgsLayoutItem *item : std::as_const( items ) )
73 {
74 if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
75 continue;
76
77 mPreviousItemPositions.insert( item->uuid(), qMakePair( item->page(), item->pagePositionWithUnits() ) );
78 }
79}
80
82{
83 for ( auto it = mPreviousItemPositions.constBegin(); it != mPreviousItemPositions.constEnd(); ++it )
84 {
85 const QString key { it.key() };
86 if ( QgsLayoutItem *item = mLayout->itemByUuid( key ) )
87 {
88 if ( !mBlockUndoCommands )
89 item->beginCommand( QString() );
90
91 item->attemptMove( it.value().second, true, false, it.value().first );
92
93 // Item might have been deleted
94 if ( mLayout->itemByUuid( key ) )
95 {
96 if ( !mBlockUndoCommands )
97 item->endCommand();
98 }
99 else
100 {
101 item->cancelCommand();
102 }
103 }
104 }
105 mPreviousItemPositions.clear();
106}
107
109{
110 double currentY = 0;
111 QgsLayoutPoint p( 0, 0, mLayout->units() );
112 const auto constMPages = mPages;
113 for ( QgsLayoutItemPage *page : constMPages )
114 {
115 page->attemptMove( p );
116 currentY += mLayout->convertToLayoutUnits( page->pageSize() ).height() + spaceBetweenPages();
117 p.setY( currentY );
118 }
119 mLayout->guides().update();
120 mLayout->updateBounds();
121 emit changed();
122}
123
125{
126 double maxWidth = 0;
127 for ( QgsLayoutItemPage *page : mPages )
128 {
129 maxWidth = std::max( maxWidth, mLayout->convertToLayoutUnits( page->pageSize() ).width() );
130 }
131 return maxWidth;
132}
133
135{
136 double maxArea = 0;
137 QSizeF maxSize;
138 for ( QgsLayoutItemPage *page : mPages )
139 {
140 QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
141 double area = pageSize.width() * pageSize.height();
142 if ( area > maxArea )
143 {
144 maxArea = area;
145 maxSize = pageSize;
146 }
147 }
148 return maxSize;
149}
150
152{
153 QSizeF size;
154 for ( QgsLayoutItemPage *page : mPages )
155 {
156 QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
157 if ( !size.isValid() )
158 size = pageSize;
159 else
160 {
161 if ( !qgsDoubleNear( pageSize.width(), size.width(), 0.01 )
162 || !qgsDoubleNear( pageSize.height(), size.height(), 0.01 ) )
163 return false;
164 }
165 }
166 return true;
167}
168
170{
171 int pageNumber = 0;
172 double startNextPageY = 0;
173 const auto constMPages = mPages;
174 for ( QgsLayoutItemPage *page : constMPages )
175 {
176 startNextPageY += page->rect().height() + spaceBetweenPages();
177 if ( startNextPageY > point.y() )
178 break;
179 pageNumber++;
180 }
181
182 if ( pageNumber > mPages.count() - 1 )
183 pageNumber = mPages.count() - 1;
184 return pageNumber;
185}
186
188{
189 if ( mPages.empty() )
190 return 0;
191
192 int pageNumber = 0;
193 double startNextPageY = 0;
194 const auto constMPages = mPages;
195 for ( QgsLayoutItemPage *page : constMPages )
196 {
197 startNextPageY += page->rect().height() + spaceBetweenPages();
198 if ( startNextPageY >= point.y() )
199 break;
200 pageNumber++;
201 }
202
203 if ( startNextPageY >= point.y() )
204 {
205 // found an existing page
206 return pageNumber;
207 }
208
209 double lastPageHeight = mPages.last()->rect().height();
210 while ( startNextPageY < point.y() )
211 {
212 startNextPageY += lastPageHeight + spaceBetweenPages();
213 if ( startNextPageY >= point.y() )
214 break;
215 pageNumber++;
216 }
217
218 return pageNumber;
219}
220
222{
223 const QList< QGraphicsItem * > items = mLayout->items( point );
224 for ( QGraphicsItem *item : items )
225 {
226 if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
227 {
228 QgsLayoutItemPage *page = static_cast< QgsLayoutItemPage * >( item );
229 if ( page->mapToScene( page->rect() ).boundingRect().contains( point ) )
230 return page;
231 }
232 }
233 return nullptr;
234}
235
237{
238 QPointF layoutUnitsPos = mLayout->convertToLayoutUnits( position );
239 if ( page > 0 && page < mPages.count() )
240 {
241 layoutUnitsPos.ry() += mPages.at( page )->pos().y();
242 }
243 return layoutUnitsPos;
244}
245
247{
248 double vDelta = 0.0;
249 if ( page > 0 && page < mPages.count() )
250 {
251 vDelta = mLayout->convertFromLayoutUnits( mPages.at( page )->pos().y(), position.units() ).length();
252 }
253
254 return QgsLayoutPoint( position.x(), position.y() + vDelta, position.units() );
255}
256
257QPointF QgsLayoutPageCollection::positionOnPage( QPointF position ) const
258{
259 double startCurrentPageY = 0;
260 double startNextPageY = 0;
261 int pageNumber = 0;
262 const auto constMPages = mPages;
263 for ( QgsLayoutItemPage *page : constMPages )
264 {
265 startCurrentPageY = startNextPageY;
266 startNextPageY += page->rect().height() + spaceBetweenPages();
267 if ( startNextPageY > position.y() )
268 break;
269 pageNumber++;
270 }
271
272 double y;
273 if ( pageNumber == mPages.size() )
274 {
275 //y coordinate is greater then the end of the last page, so return distance between
276 //top of last page and y coordinate
277 y = position.y() - ( startNextPageY - spaceBetweenPages() );
278 }
279 else
280 {
281 //y coordinate is less then the end of the last page
282 y = position.y() - startCurrentPageY;
283 }
284 return QPointF( position.x(), y );
285}
286
288{
289 return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( 10 ) );
290}
291
293{
294 return spaceBetweenPages() / 2;
295}
296
298{
299 //calculate current bounds
300 QRectF bounds = mLayout->layoutBounds( true, 0.0 );
301 if ( bounds.isEmpty() )
302 return;
303
304 if ( !mBlockUndoCommands )
305 mLayout->undoStack()->beginCommand( this, tr( "Resize to Contents" ) );
306
307 for ( int page = mPages.count() - 1; page > 0; page-- )
308 {
309 deletePage( page );
310 }
311
312 if ( mPages.empty() )
313 {
314 auto page = std::make_unique< QgsLayoutItemPage >( mLayout );
315 addPage( page.release() );
316 }
317
318 QgsLayoutItemPage *page = mPages.at( 0 );
319
320 double marginLeft = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.left(), marginUnits ) );
321 double marginTop = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.top(), marginUnits ) );
322 double marginBottom = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.bottom(), marginUnits ) );
323 double marginRight = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.right(), marginUnits ) );
324
325 bounds.setWidth( bounds.width() + marginLeft + marginRight );
326 bounds.setHeight( bounds.height() + marginTop + marginBottom );
327
328 QgsLayoutSize newPageSize = mLayout->convertFromLayoutUnits( bounds.size(), mLayout->units() );
329 page->setPageSize( newPageSize );
330
331 reflow();
332
333 //also move all items so that top-left of bounds is at marginLeft, marginTop
334 double diffX = marginLeft - bounds.left();
335 double diffY = marginTop - bounds.top();
336
337 const QList<QGraphicsItem *> itemList = mLayout->items();
338 for ( QGraphicsItem *item : itemList )
339 {
340 if ( QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
341 {
342 QgsLayoutItemPage *pageItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
343 if ( !pageItem )
344 {
345 layoutItem->beginCommand( tr( "Move Item" ) );
346 layoutItem->attemptMoveBy( diffX, diffY );
347 layoutItem->endCommand();
348 }
349 }
350 }
351
352 //also move guides
353 mLayout->undoStack()->beginCommand( &mLayout->guides(), tr( "Move Guides" ) );
354 const QList< QgsLayoutGuide * > verticalGuides = mLayout->guides().guides( Qt::Vertical );
355 for ( QgsLayoutGuide *guide : verticalGuides )
356 {
357 guide->setLayoutPosition( guide->layoutPosition() + diffX );
358 }
359 const QList< QgsLayoutGuide * > horizontalGuides = mLayout->guides().guides( Qt::Horizontal );
360 for ( QgsLayoutGuide *guide : horizontalGuides )
361 {
362 guide->setLayoutPosition( guide->layoutPosition() + diffY );
363 }
364 mLayout->undoStack()->endCommand();
365
366 if ( !mBlockUndoCommands )
367 mLayout->undoStack()->endCommand();
368}
369
370bool QgsLayoutPageCollection::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
371{
372 QDomElement element = document.createElement( QStringLiteral( "PageCollection" ) );
373
374 QDomElement pageStyleElem = QgsSymbolLayerUtils::saveSymbol( QString(), mPageStyleSymbol.get(), document, context );
375 element.appendChild( pageStyleElem );
376
377 for ( const QgsLayoutItemPage *page : mPages )
378 {
379 page->writeXml( element, document, context );
380 }
381
382 mGuideCollection->writeXml( element, document, context );
383
384 parentElement.appendChild( element );
385 return true;
386}
387
388bool QgsLayoutPageCollection::readXml( const QDomElement &e, const QDomDocument &document, const QgsReadWriteContext &context )
389{
390 QDomElement element = e;
391 if ( element.nodeName() != QLatin1String( "PageCollection" ) )
392 {
393 element = element.firstChildElement( QStringLiteral( "PageCollection" ) );
394 }
395
396 if ( element.nodeName() != QLatin1String( "PageCollection" ) )
397 {
398 return false;
399 }
400
401 mBlockUndoCommands = true;
402
403 int i = 0;
404 for ( QgsLayoutItemPage *page : std::as_const( mPages ) )
405 {
406 emit pageAboutToBeRemoved( i );
407 mLayout->removeItem( page );
408 page->deleteLater();
409 ++i;
410 }
411 mPages.clear();
412
413 QDomElement pageStyleSymbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
414 if ( !pageStyleSymbolElem.isNull() )
415 {
416 mPageStyleSymbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( pageStyleSymbolElem, context );
417 }
418
419 QDomNodeList pageList = element.elementsByTagName( QStringLiteral( "LayoutItem" ) );
420 for ( int i = 0; i < pageList.size(); ++i )
421 {
422 QDomElement pageElement = pageList.at( i ).toElement();
423 auto page = std::make_unique<QgsLayoutItemPage>( mLayout );
424 if ( mPageStyleSymbol )
425 page->setPageStyleSymbol( mPageStyleSymbol->clone() );
426 page->readXml( pageElement, document, context );
427 page->finalizeRestoreFromXml();
428 mPages.append( page.get() );
429 mLayout->addItem( page.release() );
430 }
431
432 reflow();
433
434 mGuideCollection->readXml( element, document, context );
435
436 mBlockUndoCommands = false;
437 return true;
438}
439
441{
442 return *mGuideCollection;
443}
444
446{
447 return *mGuideCollection;
448}
449
451{
452 QgsLayoutItemPage *referencePage = page( sourcePage );
453 if ( !referencePage )
454 {
455 return;
456 }
457
458 mLayout->undoStack()->beginCommand( this, tr( "Apply page properties" ) );
459 mBlockUndoCommands = true;
460
461 for ( QgsLayoutItemPage *page : mPages )
462 {
463 if ( page == referencePage )
464 {
465 continue;
466 }
467 page->setPageSize( referencePage->pageSize() );
468 page->setPageStyleSymbol( referencePage->pageStyleSymbol()->clone() );
469 }
470
471 mLayout->undoStack()->endCommand();
472 mBlockUndoCommands = false;
473 mLayout->refresh();
474}
475
477{
478 const auto constMPages = mPages;
479 for ( QgsLayoutItemPage *page : constMPages )
480 {
481 page->redraw();
482 }
483}
484
486{
487 return mLayout;
488}
489
490QList<QgsLayoutItemPage *> QgsLayoutPageCollection::pages()
491{
492 return mPages;
493}
494
496{
497 return mPages.count();
498}
499
501{
502 return mPages.value( pageNumber );
503}
504
506{
507 return mPages.value( pageNumber );
508}
509
511{
512 return mPages.indexOf( page );
513}
514
515QList<QgsLayoutItemPage *> QgsLayoutPageCollection::visiblePages( const QRectF &region ) const
516{
517 QList<QgsLayoutItemPage *> pages;
518 const auto constMPages = mPages;
519 for ( QgsLayoutItemPage *page : constMPages )
520 {
521 if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
522 pages << page;
523 }
524 return pages;
525}
526
527QList<int> QgsLayoutPageCollection::visiblePageNumbers( const QRectF &region ) const
528{
529 QList< int > pages;
530 int p = 0;
531 const auto constMPages = mPages;
532 for ( QgsLayoutItemPage *page : constMPages )
533 {
534 if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
535 pages << p;
536 p++;
537 }
538 return pages;
539}
540
542{
543 //get all items on page
544 const QList<QgsLayoutItem *> items = mLayout->pageCollection()->itemsOnPage( page );
545
546 //loop through and check for non-paper items
547 for ( QgsLayoutItem *item : items )
548 {
549 //is item a paper item?
550 if ( item->type() != QgsLayoutItemRegistry::LayoutPage )
551 {
552 //item is not a paper item, so we have other items on the page
553 return false;
554 }
555 }
556 //no non-paper items
557 return true;
558}
559
560QList<QgsLayoutItem *> QgsLayoutPageCollection::itemsOnPage( int page ) const
561{
562 QList<QgsLayoutItem *> itemList;
563 const QList<QGraphicsItem *> graphicsItemList = mLayout->items();
564 itemList.reserve( graphicsItemList.size() );
565 for ( QGraphicsItem *graphicsItem : graphicsItemList )
566 {
567 QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
568 if ( item && item->page() == page )
569 {
570 itemList.push_back( item );
571 }
572 }
573 return itemList;
574}
575
577{
578 if ( page >= mPages.count() || page < 0 )
579 {
580 //page number out of range, of course we shouldn't export it - stop smoking crack!
581 return false;
582 }
583
584 QgsLayoutItemPage *pageItem = mPages.at( page );
585 if ( !pageItem->shouldDrawItem() )
586 return false;
587
588 //check all frame items on page
589 QList<QgsLayoutFrame *> frames;
590 itemsOnPage( frames, page );
591 for ( QgsLayoutFrame *frame : std::as_const( frames ) )
592 {
593 if ( frame->hidePageIfEmpty() && frame->isEmpty() )
594 {
595 //frame is set to hide page if empty, and frame is empty, so we don't want to export this page
596 return false;
597 }
598 }
599 return true;
600}
601
603{
604 if ( !mBlockUndoCommands )
605 mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
606 mPages.append( page );
607 mLayout->addItem( page );
608 reflow();
609 if ( !mBlockUndoCommands )
610 mLayout->undoStack()->endCommand();
611}
612
614{
615 if ( mPages.empty() )
616 return nullptr;
617
618 QgsLayoutItemPage *lastPage = mPages.at( mPages.count() - 1 );
619 auto newPage = std::make_unique< QgsLayoutItemPage >( mLayout );
620 newPage->attemptResize( lastPage->sizeWithUnits() );
621 addPage( newPage.release() );
622 return mPages.at( mPages.count() - 1 );
623}
624
626{
627 if ( !mBlockUndoCommands )
628 {
629 mLayout->undoStack()->beginMacro( tr( "Add Page" ) );
630 mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
631 }
632
633 if ( beforePage < 0 )
634 beforePage = 0;
635
637 if ( beforePage >= mPages.count() )
638 {
639 mPages.append( page );
640 }
641 else
642 {
643 mPages.insert( beforePage, page );
644 }
645 mLayout->addItem( page );
646 reflow();
647
648 // bump up stored page numbers to account
649 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
650 {
651 if ( it.value().first < beforePage )
652 continue;
653
654 it.value().first = it.value().first + 1;
655 }
656
658 if ( ! mBlockUndoCommands )
659 {
660 mLayout->undoStack()->endCommand();
661 mLayout->undoStack()->endMacro();
662 }
663}
664
666{
667 if ( pageNumber < 0 || pageNumber >= mPages.count() )
668 return;
669
670 if ( !mBlockUndoCommands )
671 {
672 mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
673 mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
674 }
677 QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
678 mLayout->removeItem( page );
679 page->deleteLater();
680 reflow();
681
682 // bump stored page numbers to account
683 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
684 {
685 if ( it.value().first <= pageNumber )
686 continue;
687
688 it.value().first = it.value().first - 1;
689 }
690
692 if ( ! mBlockUndoCommands )
693 {
694 mLayout->undoStack()->endCommand();
695 mLayout->undoStack()->endMacro();
696 }
697}
698
700{
701 if ( !mPages.contains( page ) )
702 return;
703
704 if ( !mBlockUndoCommands )
705 {
706 mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
707 mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
708 }
709 int pageIndex = mPages.indexOf( page );
710 emit pageAboutToBeRemoved( pageIndex );
712 mPages.removeAll( page );
713 page->deleteLater();
714 // remove immediately from scene -- otherwise immediately calculation of layout bounds (such as is done
715 // in reflow) will still consider the page, at least until it's actually deleted at the next event loop
716 mLayout->removeItem( page );
717 reflow();
718
719 // bump stored page numbers to account
720 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
721 {
722 if ( it.value().first <= pageIndex )
723 continue;
724
725 it.value().first = it.value().first - 1;
726 }
727
729 if ( !mBlockUndoCommands )
730 {
731 mLayout->undoStack()->endCommand();
732 mLayout->undoStack()->endMacro();
733 }
734}
735
737{
738 if ( !mBlockUndoCommands )
739 {
740 mLayout->undoStack()->beginMacro( tr( "Remove Pages" ) );
741 mLayout->undoStack()->beginCommand( this, tr( "Remove Pages" ) );
742 }
743 for ( int i = mPages.count() - 1; i >= 0; --i )
744 {
745 emit pageAboutToBeRemoved( i );
746 mPages.takeAt( i )->deleteLater();
747 }
748 reflow();
749 if ( !mBlockUndoCommands )
750 {
751 mLayout->undoStack()->endCommand();
752 mLayout->undoStack()->endMacro();
753 }
754}
755
757{
758 mPages.removeAll( page );
759 return page;
760}
761
762void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
763{
764 QVariantMap properties;
765 properties.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
766 properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
767 properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "no" ) );
768 properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
769 mPageStyleSymbol = QgsFillSymbol::createSimple( properties );
770}
771
LayoutUnit
Layout measurement units.
Definition qgis.h:5203
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Base class for frame items, which form a layout multiframe item.
Stores and manages the snap guides used by a layout.
Contains the configuration for a single snap guide used by a layout.
Item representing the paper in a layout.
QgsLayoutSize pageSize() const
Returns the size of the page.
const QgsFillSymbol * pageStyleSymbol() const
Returns the symbol to use for drawing the page background.
Base class for graphical items within a QgsLayout.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
int page() const
Returns the page the item is currently on, with the first page returning 0.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
QList< int > visiblePageNumbers(const QRectF &region) const
Returns a list of the page numbers which are visible within the specified region (in layout coordinat...
void deletePage(int pageNumber)
Deletes a page from the collection.
bool pageIsEmpty(int page) const
Returns whether a given page index is empty, ie, it contains no items except for the background paper...
bool readXml(const QDomElement &collectionElement, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets the collection's state from a DOM element.
QPointF pagePositionToLayoutPosition(int page, const QgsLayoutPoint &position) const
Converts a position on a page to an absolute position in layout coordinates.
void addPage(QgsLayoutItemPage *page)
Adds a page to the collection.
void changed()
Emitted when pages are added or removed from the collection.
int pageNumberForPoint(QPointF point) const
Returns the page number corresponding to a point in the layout (in layout units).
QgsLayoutItemPage * takePage(QgsLayoutItemPage *page)
Takes a page from the collection, returning ownership of the page to the caller.
QList< QgsLayoutItemPage * > visiblePages(const QRectF &region) const
Returns a list of the pages which are visible within the specified region (in layout coordinates).
Q_DECL_DEPRECATED const QgsFillSymbol * pageStyleSymbol() const
Returns the symbol to use for drawing pages in the collection.
QgsLayoutPageCollection(QgsLayout *layout)
Constructor for QgsLayoutItemPage, with the specified parent layout.
void insertPage(QgsLayoutItemPage *page, int beforePage)
Inserts a page into a specific position in the collection.
void setPageStyleSymbol(QgsFillSymbol *symbol)
Sets the symbol to use for drawing pages in the collection.
void reflow()
Forces the page collection to reflow the arrangement of pages, e.g.
QgsLayoutItemPage * extendByNewPage()
Adds a new page to the end of the collection.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores the collection's state in a DOM element.
QgsLayout * layout() override
Returns the layout the object belongs to.
double spaceBetweenPages() const
Returns the space between pages, in layout units.
QgsLayoutGuideCollection & guides()
Returns a reference to the collection's guide collection, which manages page snap guides.
int predictPageNumberForPoint(QPointF point) const
Returns the theoretical page number corresponding to a point in the layout (in layout units),...
void endPageSizeChange()
Should be called after changing any page item sizes, and preceded by a call to beginPageSizeChange().
QList< QgsLayoutItem * > itemsOnPage(int page) const
Returns a list of layout items on the specified page index.
QList< QgsLayoutItemPage * > pages()
Returns a list of pages in the collection.
void pageAboutToBeRemoved(int pageNumber)
Emitted just before a page is removed from the collection.
int pageCount() const
Returns the number of pages in the collection.
void applyPropertiesToAllOtherPages(int sourcePage)
Apply the source page properties (size & background color) to all other pages.
double maximumPageWidth() const
Returns the maximum width of pages in the collection.
QPointF positionOnPage(QPointF point) const
Returns the position within a page of a point in the layout (in layout units).
void resizeToContents(const QgsMargins &margins, Qgis::LayoutUnit marginUnits)
Resizes the layout to a single page which fits the current contents of the layout.
bool shouldExportPage(int page) const
Returns whether the specified page number should be included in exports of the layouts.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
void redraw()
Triggers a redraw for all pages.
QgsLayoutPoint pagePositionToAbsolute(int page, const QgsLayoutPoint &position) const
Converts a position on a page to an absolute position in (maintaining the units from the input positi...
double pageShadowWidth() const
Returns the size of the page shadow, in layout units.
void clear()
Removes all pages from the collection.
int pageNumber(QgsLayoutItemPage *page) const
Returns the page number for the specified page, or -1 if the page is not contained in the collection.
bool hasUniformPageSizes() const
Returns true if the layout has uniform page sizes, e.g.
void beginPageSizeChange()
Should be called before changing any page item sizes, and followed by a call to endPageSizeChange().
QgsLayoutItemPage * pageAtPoint(QPointF point) const
Returns the page at a specified point (in layout coordinates).
QSizeF maximumPageSize() const
Returns the maximum size of any page in the collection, by area.
Provides a method of storing points, consisting of an x and y coordinate, for use in QGIS layouts.
double x() const
Returns x coordinate of point.
double y() const
Returns y coordinate of point.
Qgis::LayoutUnit units() const
Returns the units for the point.
void setY(const double y)
Sets y coordinate of point.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition qgslayout.h:50
Defines the four margins of a rectangle.
Definition qgsmargins.h:38
double top() const
Returns the top margin.
Definition qgsmargins.h:78
double right() const
Returns the right margin.
Definition qgsmargins.h:84
double bottom() const
Returns the bottom margin.
Definition qgsmargins.h:90
double left() const
Returns the left margin.
Definition qgsmargins.h:72
A container for the context for various read/write operations on objects.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607