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