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