QGIS API Documentation 4.1.0-Master (60fea48833c)
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 <QString>
28
29#include "moc_qgslayoutpagecollection.cpp"
30
31using namespace Qt::StringLiterals;
32
34 : QObject( layout )
35 , mLayout( layout )
36 , mGuideCollection( new QgsLayoutGuideCollection( layout, this ) )
37{
38 createDefaultPageStyleSymbol();
39}
40
42{
43 const auto constMPages = mPages;
44 for ( QgsLayoutItemPage *page : constMPages )
45 {
46 mLayout->removeItem( page );
47 page->deleteLater();
48 }
49}
50
52{
53 if ( !symbol )
54 return;
55
56 mPageStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
57
58 for ( QgsLayoutItemPage *page : std::as_const( mPages ) )
59 {
60 page->setPageStyleSymbol( symbol->clone() );
61 page->update();
62 }
63}
64
66{
67 return mPageStyleSymbol.get();
68}
69
71{
72 mPreviousItemPositions.clear();
73 QList< QgsLayoutItem * > items;
74 mLayout->layoutItems( items );
75
76 for ( QgsLayoutItem *item : std::as_const( items ) )
77 {
78 if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
79 continue;
80
81 mPreviousItemPositions.insert( item->uuid(), qMakePair( item->page(), item->pagePositionWithUnits() ) );
82 }
83}
84
86{
87 for ( auto it = mPreviousItemPositions.constBegin(); it != mPreviousItemPositions.constEnd(); ++it )
88 {
89 const QString key { it.key() };
90 if ( QgsLayoutItem *item = mLayout->itemByUuid( key ) )
91 {
92 if ( !mBlockUndoCommands )
93 item->beginCommand( QString() );
94
95 item->attemptMove( it.value().second, true, false, it.value().first );
96
97 // Item might have been deleted
98 if ( mLayout->itemByUuid( key ) )
99 {
100 if ( !mBlockUndoCommands )
101 item->endCommand();
102 }
103 else
104 {
105 item->cancelCommand();
106 }
107 }
108 }
109 mPreviousItemPositions.clear();
110}
111
113{
114 double currentY = 0;
115 QgsLayoutPoint p( 0, 0, mLayout->units() );
116 const auto constMPages = mPages;
117 for ( QgsLayoutItemPage *page : constMPages )
118 {
119 page->attemptMove( p );
120 currentY += mLayout->convertToLayoutUnits( page->pageSize() ).height() + spaceBetweenPages();
121 p.setY( currentY );
122 }
123 mLayout->guides().update();
124 mLayout->updateBounds();
125 emit changed();
126}
127
129{
130 double maxWidth = 0;
131 for ( QgsLayoutItemPage *page : mPages )
132 {
133 maxWidth = std::max( maxWidth, mLayout->convertToLayoutUnits( page->pageSize() ).width() );
134 }
135 return maxWidth;
136}
137
139{
140 double maxArea = 0;
141 QSizeF maxSize;
142 for ( QgsLayoutItemPage *page : mPages )
143 {
144 QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
145 double area = pageSize.width() * pageSize.height();
146 if ( area > maxArea )
147 {
148 maxArea = area;
149 maxSize = pageSize;
150 }
151 }
152 return maxSize;
153}
154
156{
157 QSizeF size;
158 for ( QgsLayoutItemPage *page : mPages )
159 {
160 QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
161 if ( !size.isValid() )
162 size = pageSize;
163 else
164 {
165 if ( !qgsDoubleNear( pageSize.width(), size.width(), 0.01 ) || !qgsDoubleNear( pageSize.height(), size.height(), 0.01 ) )
166 return false;
167 }
168 }
169 return true;
170}
171
173{
174 int pageNumber = 0;
175 double startNextPageY = 0;
176 const auto constMPages = mPages;
177 for ( QgsLayoutItemPage *page : constMPages )
178 {
179 startNextPageY += page->rect().height() + spaceBetweenPages();
180 if ( startNextPageY > point.y() )
181 break;
182 pageNumber++;
183 }
184
185 if ( pageNumber > mPages.count() - 1 )
186 pageNumber = mPages.count() - 1;
187 return pageNumber;
188}
189
191{
192 if ( mPages.empty() )
193 return 0;
194
195 int pageNumber = 0;
196 double startNextPageY = 0;
197 const auto constMPages = mPages;
198 for ( QgsLayoutItemPage *page : constMPages )
199 {
200 startNextPageY += page->rect().height() + spaceBetweenPages();
201 if ( startNextPageY >= point.y() )
202 break;
203 pageNumber++;
204 }
205
206 if ( startNextPageY >= point.y() )
207 {
208 // found an existing page
209 return pageNumber;
210 }
211
212 double lastPageHeight = mPages.last()->rect().height();
213 while ( startNextPageY < point.y() )
214 {
215 startNextPageY += lastPageHeight + spaceBetweenPages();
216 if ( startNextPageY >= point.y() )
217 break;
218 pageNumber++;
219 }
220
221 return pageNumber;
222}
223
225{
226 const QList< QGraphicsItem * > items = mLayout->items( point );
227 for ( QGraphicsItem *item : items )
228 {
229 if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
230 {
231 QgsLayoutItemPage *page = static_cast< QgsLayoutItemPage * >( item );
232 if ( page->mapToScene( page->rect() ).boundingRect().contains( point ) )
233 return page;
234 }
235 }
236 return nullptr;
237}
238
240{
241 QPointF layoutUnitsPos = mLayout->convertToLayoutUnits( position );
242 if ( page > 0 && page < mPages.count() )
243 {
244 layoutUnitsPos.ry() += mPages.at( page )->pos().y();
245 }
246 return layoutUnitsPos;
247}
248
250{
251 double vDelta = 0.0;
252 if ( page > 0 && page < mPages.count() )
253 {
254 vDelta = mLayout->convertFromLayoutUnits( mPages.at( page )->pos().y(), position.units() ).length();
255 }
256
257 return QgsLayoutPoint( position.x(), position.y() + vDelta, position.units() );
258}
259
260QPointF QgsLayoutPageCollection::positionOnPage( QPointF position ) const
261{
262 double startCurrentPageY = 0;
263 double startNextPageY = 0;
264 int pageNumber = 0;
265 const auto constMPages = mPages;
266 for ( QgsLayoutItemPage *page : constMPages )
267 {
268 startCurrentPageY = startNextPageY;
269 startNextPageY += page->rect().height() + spaceBetweenPages();
270 if ( startNextPageY > position.y() )
271 break;
272 pageNumber++;
273 }
274
275 double y;
276 if ( pageNumber == mPages.size() )
277 {
278 //y coordinate is greater then the end of the last page, so return distance between
279 //top of last page and y coordinate
280 y = position.y() - ( startNextPageY - spaceBetweenPages() );
281 }
282 else
283 {
284 //y coordinate is less then the end of the last page
285 y = position.y() - startCurrentPageY;
286 }
287 return QPointF( position.x(), y );
288}
289
291{
292 return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( 10 ) );
293}
294
296{
297 return spaceBetweenPages() / 2;
298}
299
301{
302 //calculate current bounds
303 QRectF bounds = mLayout->layoutBounds( true, 0.0 );
304 if ( bounds.isEmpty() )
305 return;
306
307 if ( !mBlockUndoCommands )
308 mLayout->undoStack()->beginCommand( this, tr( "Resize to Contents" ) );
309
310 for ( int page = mPages.count() - 1; page > 0; page-- )
311 {
312 deletePage( page );
313 }
314
315 if ( mPages.empty() )
316 {
317 auto page = std::make_unique< QgsLayoutItemPage >( mLayout );
318 addPage( page.release() );
319 }
320
321 QgsLayoutItemPage *page = mPages.at( 0 );
322
323 double marginLeft = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.left(), marginUnits ) );
324 double marginTop = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.top(), marginUnits ) );
325 double marginBottom = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.bottom(), marginUnits ) );
326 double marginRight = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.right(), marginUnits ) );
327
328 bounds.setWidth( bounds.width() + marginLeft + marginRight );
329 bounds.setHeight( bounds.height() + marginTop + marginBottom );
330
331 QgsLayoutSize newPageSize = mLayout->convertFromLayoutUnits( bounds.size(), mLayout->units() );
332 page->setPageSize( newPageSize );
333
334 reflow();
335
336 //also move all items so that top-left of bounds is at marginLeft, marginTop
337 double diffX = marginLeft - bounds.left();
338 double diffY = marginTop - bounds.top();
339
340 const QList<QGraphicsItem *> itemList = mLayout->items();
341 for ( QGraphicsItem *item : itemList )
342 {
343 if ( QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
344 {
345 QgsLayoutItemPage *pageItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
346 if ( !pageItem )
347 {
348 layoutItem->beginCommand( tr( "Move Item" ) );
349 layoutItem->attemptMoveBy( diffX, diffY );
350 layoutItem->endCommand();
351 }
352 }
353 }
354
355 //also move guides
356 mLayout->undoStack()->beginCommand( &mLayout->guides(), tr( "Move Guides" ) );
357 const QList< QgsLayoutGuide * > verticalGuides = mLayout->guides().guides( Qt::Vertical );
358 for ( QgsLayoutGuide *guide : verticalGuides )
359 {
360 guide->setLayoutPosition( guide->layoutPosition() + diffX );
361 }
362 const QList< QgsLayoutGuide * > horizontalGuides = mLayout->guides().guides( Qt::Horizontal );
363 for ( QgsLayoutGuide *guide : horizontalGuides )
364 {
365 guide->setLayoutPosition( guide->layoutPosition() + diffY );
366 }
367 mLayout->undoStack()->endCommand();
368
369 if ( !mBlockUndoCommands )
370 mLayout->undoStack()->endCommand();
371}
372
373bool QgsLayoutPageCollection::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
374{
375 QDomElement element = document.createElement( u"PageCollection"_s );
376
377 QDomElement pageStyleElem = QgsSymbolLayerUtils::saveSymbol( QString(), mPageStyleSymbol.get(), document, context );
378 element.appendChild( pageStyleElem );
379
380 for ( const QgsLayoutItemPage *page : mPages )
381 {
382 page->writeXml( element, document, context );
383 }
384
385 mGuideCollection->writeXml( element, document, context );
386
387 parentElement.appendChild( element );
388 return true;
389}
390
391bool QgsLayoutPageCollection::readXml( const QDomElement &e, const QDomDocument &document, const QgsReadWriteContext &context )
392{
393 QDomElement element = e;
394 if ( element.nodeName() != "PageCollection"_L1 )
395 {
396 element = element.firstChildElement( u"PageCollection"_s );
397 }
398
399 if ( element.nodeName() != "PageCollection"_L1 )
400 {
401 return false;
402 }
403
404 mBlockUndoCommands = true;
405
406 int i = 0;
407 for ( QgsLayoutItemPage *page : std::as_const( mPages ) )
408 {
409 emit pageAboutToBeRemoved( i );
410 mLayout->removeItem( page );
411 page->deleteLater();
412 ++i;
413 }
414 mPages.clear();
415
416 QDomElement pageStyleSymbolElem = element.firstChildElement( u"symbol"_s );
417 if ( !pageStyleSymbolElem.isNull() )
418 {
419 mPageStyleSymbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( pageStyleSymbolElem, context );
420 }
421
422 QDomNodeList pageList = element.elementsByTagName( u"LayoutItem"_s );
423 for ( int i = 0; i < pageList.size(); ++i )
424 {
425 QDomElement pageElement = pageList.at( i ).toElement();
426 auto page = std::make_unique<QgsLayoutItemPage>( mLayout );
427 if ( mPageStyleSymbol )
428 page->setPageStyleSymbol( mPageStyleSymbol->clone() );
429 page->readXml( pageElement, document, context );
430 page->finalizeRestoreFromXml();
431 mPages.append( page.get() );
432 mLayout->addItem( page.release() );
433 }
434
435 reflow();
436
437 mGuideCollection->readXml( element, document, context );
438
439 mBlockUndoCommands = false;
440 return true;
441}
442
444{
445 return *mGuideCollection;
446}
447
449{
450 return *mGuideCollection;
451}
452
454{
455 QgsLayoutItemPage *referencePage = page( sourcePage );
456 if ( !referencePage )
457 {
458 return;
459 }
460
461 mLayout->undoStack()->beginCommand( this, tr( "Apply page properties" ) );
462 mBlockUndoCommands = true;
463
464 for ( QgsLayoutItemPage *page : mPages )
465 {
466 if ( page == referencePage )
467 {
468 continue;
469 }
470 page->setPageSize( referencePage->pageSize() );
471 page->setPageStyleSymbol( referencePage->pageStyleSymbol()->clone() );
472 }
473
474 mLayout->undoStack()->endCommand();
475 mBlockUndoCommands = false;
476 mLayout->refresh();
477}
478
480{
481 const auto constMPages = mPages;
482 for ( QgsLayoutItemPage *page : constMPages )
483 {
484 page->redraw();
485 }
486}
487
489{
490 return mLayout;
491}
492
493QList<QgsLayoutItemPage *> QgsLayoutPageCollection::pages()
494{
495 return mPages;
496}
497
499{
500 return mPages.count();
501}
502
504{
505 return mPages.value( pageNumber );
506}
507
509{
510 return mPages.value( pageNumber );
511}
512
514{
515 return mPages.indexOf( page );
516}
517
518QList<QgsLayoutItemPage *> QgsLayoutPageCollection::visiblePages( const QRectF &region ) const
519{
520 QList<QgsLayoutItemPage *> pages;
521 const auto constMPages = mPages;
522 for ( QgsLayoutItemPage *page : constMPages )
523 {
524 if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
525 pages << page;
526 }
527 return pages;
528}
529
530QList<int> QgsLayoutPageCollection::visiblePageNumbers( const QRectF &region ) const
531{
532 QList< int > pages;
533 int p = 0;
534 const auto constMPages = mPages;
535 for ( QgsLayoutItemPage *page : constMPages )
536 {
537 if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
538 pages << p;
539 p++;
540 }
541 return pages;
542}
543
545{
546 //get all items on page
547 const QList<QgsLayoutItem *> items = mLayout->pageCollection()->itemsOnPage( page );
548
549 //loop through and check for non-paper items
550 for ( QgsLayoutItem *item : items )
551 {
552 //is item a paper item?
553 if ( item->type() != QgsLayoutItemRegistry::LayoutPage )
554 {
555 //item is not a paper item, so we have other items on the page
556 return false;
557 }
558 }
559 //no non-paper items
560 return true;
561}
562
563QList<QgsLayoutItem *> QgsLayoutPageCollection::itemsOnPage( int page ) const
564{
565 QList<QgsLayoutItem *> itemList;
566 const QList<QGraphicsItem *> graphicsItemList = mLayout->items();
567 itemList.reserve( graphicsItemList.size() );
568 for ( QGraphicsItem *graphicsItem : graphicsItemList )
569 {
570 QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
571 if ( item && item->page() == page )
572 {
573 itemList.push_back( item );
574 }
575 }
576 return itemList;
577}
578
580{
581 if ( page >= mPages.count() || page < 0 )
582 {
583 //page number out of range, of course we shouldn't export it - stop smoking crack!
584 return false;
585 }
586
587 QgsLayoutItemPage *pageItem = mPages.at( page );
588 if ( !pageItem->shouldDrawItem() )
589 return false;
590
591 //check all frame items on page
592 QList<QgsLayoutFrame *> frames;
593 itemsOnPage( frames, page );
594 for ( QgsLayoutFrame *frame : std::as_const( frames ) )
595 {
596 if ( frame->hidePageIfEmpty() && frame->isEmpty() )
597 {
598 //frame is set to hide page if empty, and frame is empty, so we don't want to export this page
599 return false;
600 }
601 }
602 return true;
603}
604
606{
607 if ( !mBlockUndoCommands )
608 mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
609 mPages.append( page );
610 mLayout->addItem( page );
611 reflow();
612 if ( !mBlockUndoCommands )
613 mLayout->undoStack()->endCommand();
614}
615
617{
618 if ( mPages.empty() )
619 return nullptr;
620
621 QgsLayoutItemPage *lastPage = mPages.at( mPages.count() - 1 );
622 auto newPage = std::make_unique< QgsLayoutItemPage >( mLayout );
623 newPage->attemptResize( lastPage->sizeWithUnits() );
624 addPage( newPage.release() );
625 return mPages.at( mPages.count() - 1 );
626}
627
629{
630 if ( !mBlockUndoCommands )
631 {
632 mLayout->undoStack()->beginMacro( tr( "Add Page" ) );
633 mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
634 }
635
636 if ( beforePage < 0 )
637 beforePage = 0;
638
640 if ( beforePage >= mPages.count() )
641 {
642 mPages.append( page );
643 }
644 else
645 {
646 mPages.insert( beforePage, page );
647 }
648 mLayout->addItem( page );
649 reflow();
650
651 // bump up stored page numbers to account
652 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
653 {
654 if ( it.value().first < beforePage )
655 continue;
656
657 it.value().first = it.value().first + 1;
658 }
659
661 if ( !mBlockUndoCommands )
662 {
663 mLayout->undoStack()->endCommand();
664 mLayout->undoStack()->endMacro();
665 }
666}
667
669{
670 if ( pageNumber < 0 || pageNumber >= mPages.count() )
671 return;
672
673 if ( !mBlockUndoCommands )
674 {
675 mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
676 mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
677 }
680 QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
681 mLayout->removeItem( page );
682 page->deleteLater();
683 reflow();
684
685 // bump stored page numbers to account
686 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
687 {
688 if ( it.value().first <= pageNumber )
689 continue;
690
691 it.value().first = it.value().first - 1;
692 }
693
695 if ( !mBlockUndoCommands )
696 {
697 mLayout->undoStack()->endCommand();
698 mLayout->undoStack()->endMacro();
699 }
700}
701
703{
704 if ( !mPages.contains( page ) )
705 return;
706
707 if ( !mBlockUndoCommands )
708 {
709 mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
710 mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
711 }
712 int pageIndex = mPages.indexOf( page );
713 emit pageAboutToBeRemoved( pageIndex );
715 mPages.removeAll( page );
716 page->deleteLater();
717 // remove immediately from scene -- otherwise immediately calculation of layout bounds (such as is done
718 // in reflow) will still consider the page, at least until it's actually deleted at the next event loop
719 mLayout->removeItem( page );
720 reflow();
721
722 // bump stored page numbers to account
723 for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it ) // clazy:exclude=detaching-member
724 {
725 if ( it.value().first <= pageIndex )
726 continue;
727
728 it.value().first = it.value().first - 1;
729 }
730
732 if ( !mBlockUndoCommands )
733 {
734 mLayout->undoStack()->endCommand();
735 mLayout->undoStack()->endMacro();
736 }
737}
738
740{
741 if ( !mBlockUndoCommands )
742 {
743 mLayout->undoStack()->beginMacro( tr( "Remove Pages" ) );
744 mLayout->undoStack()->beginCommand( this, tr( "Remove Pages" ) );
745 }
746 for ( int i = mPages.count() - 1; i >= 0; --i )
747 {
748 emit pageAboutToBeRemoved( i );
749 mPages.takeAt( i )->deleteLater();
750 }
751 reflow();
752 if ( !mBlockUndoCommands )
753 {
754 mLayout->undoStack()->endCommand();
755 mLayout->undoStack()->endMacro();
756 }
757}
758
760{
761 mPages.removeAll( page );
762 return page;
763}
764
765void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
766{
767 QVariantMap properties;
768 properties.insert( u"color"_s, u"white"_s );
769 properties.insert( u"style"_s, u"solid"_s );
770 properties.insert( u"style_border"_s, u"no"_s );
771 properties.insert( u"joinstyle"_s, u"miter"_s );
772 mPageStyleSymbol = QgsFillSymbol::createSimple( properties );
773}
LayoutUnit
Layout measurement units.
Definition qgis.h:5360
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:40
double top() const
Returns the top margin.
Definition qgsmargins.h:76
double right() const
Returns the right margin.
Definition qgsmargins.h:82
double bottom() const
Returns the bottom margin.
Definition qgsmargins.h:88
double left() const
Returns the left margin.
Definition qgsmargins.h:70
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:6975