QGIS API Documentation  3.0.2-Girona (307d082)
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  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
37  {
38  mLayout->removeItem( page );
39  page->deleteLater();
40  }
41 }
42 
44 {
45  if ( !symbol )
46  return;
47 
48  mPageStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
49 
50  for ( QgsLayoutItemPage *page : qgis::as_const( mPages ) )
51  {
52  page->update();
53  }
54 
55 }
56 
58 {
59  mPreviousItemPositions.clear();
60  QList< QgsLayoutItem * > items;
61  mLayout->layoutItems( items );
62 
63  for ( QgsLayoutItem *item : qgis::as_const( items ) )
64  {
65  if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
66  continue;
67 
68  mPreviousItemPositions.insert( item->uuid(), qMakePair( item->page(), item->pagePositionWithUnits() ) );
69  }
70 }
71 
73 {
74  for ( auto it = mPreviousItemPositions.constBegin(); it != mPreviousItemPositions.constEnd(); ++it )
75  {
76  if ( QgsLayoutItem *item = mLayout->itemByUuid( it.key() ) )
77  {
78  if ( !mBlockUndoCommands )
79  item->beginCommand( QString() );
80  item->attemptMove( it.value().second, true, false, it.value().first );
81  if ( !mBlockUndoCommands )
82  item->endCommand();
83  }
84  }
85  mPreviousItemPositions.clear();
86 }
87 
89 {
90  double currentY = 0;
91  QgsLayoutPoint p( 0, 0, mLayout->units() );
92  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
93  {
94  page->attemptMove( p );
95  currentY += mLayout->convertToLayoutUnits( page->pageSize() ).height() + spaceBetweenPages();
96  p.setY( currentY );
97  }
98  mLayout->guides().update();
99  mLayout->updateBounds();
100  emit changed();
101 }
102 
104 {
105  double maxWidth = 0;
106  for ( QgsLayoutItemPage *page : mPages )
107  {
108  maxWidth = std::max( maxWidth, mLayout->convertToLayoutUnits( page->pageSize() ).width() );
109  }
110  return maxWidth;
111 }
112 
114 {
115  double maxArea = 0;
116  QSizeF maxSize;
117  for ( QgsLayoutItemPage *page : mPages )
118  {
119  QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
120  double area = pageSize.width() * pageSize.height();
121  if ( area > maxArea )
122  {
123  maxArea = area;
124  maxSize = pageSize;
125  }
126  }
127  return maxSize;
128 }
129 
131 {
132  QSizeF size;
133  for ( QgsLayoutItemPage *page : mPages )
134  {
135  QSizeF pageSize = mLayout->convertToLayoutUnits( page->pageSize() );
136  if ( !size.isValid() )
137  size = pageSize;
138  else
139  {
140  if ( !qgsDoubleNear( pageSize.width(), size.width(), 0.01 )
141  || !qgsDoubleNear( pageSize.height(), size.height(), 0.01 ) )
142  return false;
143  }
144  }
145  return true;
146 }
147 
149 {
150  int pageNumber = 0;
151  double startNextPageY = 0;
152  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
153  {
154  startNextPageY += page->rect().height() + spaceBetweenPages();
155  if ( startNextPageY > point.y() )
156  break;
157  pageNumber++;
158  }
159 
160  if ( pageNumber > mPages.count() - 1 )
161  pageNumber = mPages.count() - 1;
162  return pageNumber;
163 }
164 
166 {
167  int pageNumber = 0;
168  double startNextPageY = 0;
169  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
170  {
171  startNextPageY += page->rect().height() + spaceBetweenPages();
172  if ( startNextPageY >= point.y() )
173  break;
174  pageNumber++;
175  }
176 
177  if ( startNextPageY >= point.y() )
178  {
179  // found an existing page
180  return pageNumber;
181  }
182 
183  double lastPageHeight = mPages.last()->rect().height();
184  while ( startNextPageY < point.y() )
185  {
186  startNextPageY += lastPageHeight + spaceBetweenPages();
187  if ( startNextPageY >= point.y() )
188  break;
189  pageNumber++;
190  }
191 
192  return pageNumber;
193 }
194 
196 {
197  const QList< QGraphicsItem * > items = mLayout->items( point );
198  for ( QGraphicsItem *item : items )
199  {
200  if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
201  {
202  QgsLayoutItemPage *page = static_cast< QgsLayoutItemPage * >( item );
203  if ( page->mapToScene( page->rect() ).boundingRect().contains( point ) )
204  return page;
205  }
206  }
207  return nullptr;
208 }
209 
211 {
212  QPointF layoutUnitsPos = mLayout->convertToLayoutUnits( position );
213  if ( page > 0 && page < mPages.count() )
214  {
215  layoutUnitsPos.ry() += mPages.at( page )->pos().y();
216  }
217  return layoutUnitsPos;
218 }
219 
221 {
222  double vDelta = 0.0;
223  if ( page > 0 && page < mPages.count() )
224  {
225  vDelta = mLayout->convertFromLayoutUnits( mPages.at( page )->pos().y(), position.units() ).length();
226  }
227 
228  return QgsLayoutPoint( position.x(), position.y() + vDelta, position.units() );
229 }
230 
231 QPointF QgsLayoutPageCollection::positionOnPage( QPointF position ) const
232 {
233  double startCurrentPageY = 0;
234  double startNextPageY = 0;
235  int pageNumber = 0;
236  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
237  {
238  startCurrentPageY = startNextPageY;
239  startNextPageY += page->rect().height() + spaceBetweenPages();
240  if ( startNextPageY > position.y() )
241  break;
242  pageNumber++;
243  }
244 
245  double y;
246  if ( pageNumber == mPages.size() )
247  {
248  //y coordinate is greater then the end of the last page, so return distance between
249  //top of last page and y coordinate
250  y = position.y() - ( startNextPageY - spaceBetweenPages() );
251  }
252  else
253  {
254  //y coordinate is less then the end of the last page
255  y = position.y() - startCurrentPageY;
256  }
257  return QPointF( position.x(), y );
258 }
259 
261 {
262  return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( 10 ) );
263 }
264 
266 {
267  return spaceBetweenPages() / 2;
268 }
269 
271 {
272  if ( !mBlockUndoCommands )
273  mLayout->undoStack()->beginCommand( this, tr( "Resize to Contents" ) );
274 
275  //calculate current bounds
276  QRectF bounds = mLayout->layoutBounds( true, 0.0 );
277 
278  for ( int page = mPages.count() - 1; page > 0; page-- )
279  {
280  deletePage( page );
281  }
282 
283  if ( mPages.empty() )
284  {
285  std::unique_ptr< QgsLayoutItemPage > page = qgis::make_unique< QgsLayoutItemPage >( mLayout );
286  addPage( page.release() );
287  }
288 
289  QgsLayoutItemPage *page = mPages.at( 0 );
290 
291  double marginLeft = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.left(), marginUnits ) );
292  double marginTop = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.top(), marginUnits ) );
293  double marginBottom = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.bottom(), marginUnits ) );
294  double marginRight = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.right(), marginUnits ) );
295 
296  bounds.setWidth( bounds.width() + marginLeft + marginRight );
297  bounds.setHeight( bounds.height() + marginTop + marginBottom );
298 
299  QgsLayoutSize newPageSize = mLayout->convertFromLayoutUnits( bounds.size(), mLayout->units() );
300  page->setPageSize( newPageSize );
301 
302  reflow();
303 
304  //also move all items so that top-left of bounds is at marginLeft, marginTop
305  double diffX = marginLeft - bounds.left();
306  double diffY = marginTop - bounds.top();
307 
308  const QList<QGraphicsItem *> itemList = mLayout->items();
309  for ( QGraphicsItem *item : itemList )
310  {
311  if ( QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
312  {
313  QgsLayoutItemPage *pageItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
314  if ( !pageItem )
315  {
316  layoutItem->beginCommand( tr( "Move Item" ) );
317  layoutItem->attemptMoveBy( diffX, diffY );
318  layoutItem->endCommand();
319  }
320  }
321  }
322 
323  //also move guides
324  mLayout->undoStack()->beginCommand( &mLayout->guides(), tr( "Move Guides" ) );
325  const QList< QgsLayoutGuide * > verticalGuides = mLayout->guides().guides( Qt::Vertical );
326  for ( QgsLayoutGuide *guide : verticalGuides )
327  {
328  guide->setLayoutPosition( guide->layoutPosition() + diffX );
329  }
330  const QList< QgsLayoutGuide * > horizontalGuides = mLayout->guides().guides( Qt::Horizontal );
331  for ( QgsLayoutGuide *guide : horizontalGuides )
332  {
333  guide->setLayoutPosition( guide->layoutPosition() + diffY );
334  }
335  mLayout->undoStack()->endCommand();
336 
337  if ( !mBlockUndoCommands )
338  mLayout->undoStack()->endCommand();
339 }
340 
341 bool QgsLayoutPageCollection::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
342 {
343  QDomElement element = document.createElement( QStringLiteral( "PageCollection" ) );
344 
345  QDomElement pageStyleElem = QgsSymbolLayerUtils::saveSymbol( QString(), mPageStyleSymbol.get(), document, context );
346  element.appendChild( pageStyleElem );
347 
348  for ( const QgsLayoutItemPage *page : mPages )
349  {
350  page->writeXml( element, document, context );
351  }
352 
353  mGuideCollection->writeXml( element, document, context );
354 
355  parentElement.appendChild( element );
356  return true;
357 }
358 
359 bool QgsLayoutPageCollection::readXml( const QDomElement &e, const QDomDocument &document, const QgsReadWriteContext &context )
360 {
361  QDomElement element = e;
362  if ( element.nodeName() != QStringLiteral( "PageCollection" ) )
363  {
364  element = element.firstChildElement( QStringLiteral( "PageCollection" ) );
365  }
366 
367  if ( element.nodeName() != QStringLiteral( "PageCollection" ) )
368  {
369  return false;
370  }
371 
372  mBlockUndoCommands = true;
373 
374  int i = 0;
375  for ( QgsLayoutItemPage *page : qgis::as_const( mPages ) )
376  {
377  emit pageAboutToBeRemoved( i );
378  mLayout->removeItem( page );
379  page->deleteLater();
380  ++i;
381  }
382  mPages.clear();
383 
384  QDomElement pageStyleSymbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
385  if ( !pageStyleSymbolElem.isNull() )
386  {
387  mPageStyleSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( pageStyleSymbolElem, context ) );
388  }
389 
390  QDomNodeList pageList = element.elementsByTagName( QStringLiteral( "LayoutItem" ) );
391  for ( int i = 0; i < pageList.size(); ++i )
392  {
393  QDomElement pageElement = pageList.at( i ).toElement();
394  std::unique_ptr< QgsLayoutItemPage > page( new QgsLayoutItemPage( mLayout ) );
395  page->readXml( pageElement, document, context );
396  page->finalizeRestoreFromXml();
397  mPages.append( page.get() );
398  mLayout->addItem( page.release() );
399  }
400 
401  reflow();
402 
403  mGuideCollection->readXml( element, document, context );
404 
405  mBlockUndoCommands = false;
406  return true;
407 }
408 
410 {
411  return *mGuideCollection;
412 }
413 
415 {
416  return *mGuideCollection;
417 }
418 
420 {
421  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
422  {
423  page->redraw();
424  }
425 }
426 
428 {
429  return mLayout;
430 }
431 
432 QList<QgsLayoutItemPage *> QgsLayoutPageCollection::pages()
433 {
434  return mPages;
435 }
436 
438 {
439  return mPages.count();
440 }
441 
443 {
444  return mPages.value( pageNumber );
445 }
446 
448 {
449  return mPages.value( pageNumber );
450 }
451 
453 {
454  return mPages.indexOf( page );
455 }
456 
457 QList<QgsLayoutItemPage *> QgsLayoutPageCollection::visiblePages( QRectF region ) const
458 {
459  QList<QgsLayoutItemPage *> pages;
460  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
461  {
462  if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
463  pages << page;
464  }
465  return pages;
466 }
467 
468 QList<int> QgsLayoutPageCollection::visiblePageNumbers( QRectF region ) const
469 {
470  QList< int > pages;
471  int p = 0;
472  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
473  {
474  if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
475  pages << p;
476  p++;
477  }
478  return pages;
479 }
480 
482 {
483  //get all items on page
484  const QList<QgsLayoutItem *> items = mLayout->pageCollection()->itemsOnPage( page );
485 
486  //loop through and check for non-paper items
487  for ( QgsLayoutItem *item : items )
488  {
489  //is item a paper item?
490  if ( item->type() != QgsLayoutItemRegistry::LayoutPage )
491  {
492  //item is not a paper item, so we have other items on the page
493  return false;
494  }
495  }
496  //no non-paper items
497  return true;
498 }
499 
500 QList<QgsLayoutItem *> QgsLayoutPageCollection::itemsOnPage( int page ) const
501 {
502  QList<QgsLayoutItem *> itemList;
503  const QList<QGraphicsItem *> graphicsItemList = mLayout->items();
504  for ( QGraphicsItem *graphicsItem : graphicsItemList )
505  {
506  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
507  if ( item && item->page() == page )
508  {
509  itemList.push_back( item );
510  }
511  }
512  return itemList;
513 }
514 
516 {
517  if ( page >= mPages.count() || page < 0 )
518  {
519  //page number out of range, of course we shouldn't export it - stop smoking crack!
520  return false;
521  }
522 
523  QgsLayoutItemPage *pageItem = mPages.at( page );
524  if ( !pageItem->shouldDrawItem() )
525  return false;
526 
527  //check all frame items on page
528  QList<QgsLayoutFrame *> frames;
529  itemsOnPage( frames, page );
530  for ( QgsLayoutFrame *frame : qgis::as_const( frames ) )
531  {
532  if ( frame->hidePageIfEmpty() && frame->isEmpty() )
533  {
534  //frame is set to hide page if empty, and frame is empty, so we don't want to export this page
535  return false;
536  }
537  }
538  return true;
539 }
540 
542 {
543  if ( !mBlockUndoCommands )
544  mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
545  mPages.append( page );
546  mLayout->addItem( page );
547  reflow();
548  if ( !mBlockUndoCommands )
549  mLayout->undoStack()->endCommand();
550 }
551 
553 {
554  if ( mPages.empty() )
555  return nullptr;
556 
557  QgsLayoutItemPage *lastPage = mPages.at( mPages.count() - 1 );
558  std::unique_ptr< QgsLayoutItemPage > newPage = qgis::make_unique< QgsLayoutItemPage >( mLayout );
559  newPage->attemptResize( lastPage->sizeWithUnits() );
560  addPage( newPage.release() );
561  return mPages.at( mPages.count() - 1 );
562 }
563 
565 {
566  if ( !mBlockUndoCommands )
567  {
568  mLayout->undoStack()->beginMacro( tr( "Add Page" ) );
569  mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
570  }
571 
572  if ( beforePage < 0 )
573  beforePage = 0;
574 
576  if ( beforePage >= mPages.count() )
577  {
578  mPages.append( page );
579  }
580  else
581  {
582  mPages.insert( beforePage, page );
583  }
584  mLayout->addItem( page );
585  reflow();
586 
587  // bump up stored page numbers to account
588  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
589  {
590  if ( it.value().first < beforePage )
591  continue;
592 
593  it.value().first = it.value().first + 1;
594  }
595 
597  if ( ! mBlockUndoCommands )
598  {
599  mLayout->undoStack()->endCommand();
600  mLayout->undoStack()->endMacro();
601  }
602 }
603 
605 {
606  if ( pageNumber < 0 || pageNumber >= mPages.count() )
607  return;
608 
609  if ( !mBlockUndoCommands )
610  {
611  mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
612  mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
613  }
614  emit pageAboutToBeRemoved( pageNumber );
616  QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
617  mLayout->removeItem( page );
618  page->deleteLater();
619  reflow();
620 
621  // bump stored page numbers to account
622  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
623  {
624  if ( it.value().first <= pageNumber )
625  continue;
626 
627  it.value().first = it.value().first - 1;
628  }
629 
631  if ( ! mBlockUndoCommands )
632  {
633  mLayout->undoStack()->endCommand();
634  mLayout->undoStack()->endMacro();
635  }
636 }
637 
639 {
640  if ( !mPages.contains( page ) )
641  return;
642 
643  if ( !mBlockUndoCommands )
644  {
645  mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
646  mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
647  }
648  int pageIndex = mPages.indexOf( page );
649  emit pageAboutToBeRemoved( pageIndex );
651  mPages.removeAll( page );
652  page->deleteLater();
653  reflow();
654 
655  // bump stored page numbers to account
656  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
657  {
658  if ( it.value().first <= pageIndex )
659  continue;
660 
661  it.value().first = it.value().first - 1;
662  }
663 
665  if ( !mBlockUndoCommands )
666  {
667  mLayout->undoStack()->endCommand();
668  mLayout->undoStack()->endMacro();
669  }
670 }
671 
673 {
674  if ( !mBlockUndoCommands )
675  {
676  mLayout->undoStack()->beginMacro( tr( "Remove Pages" ) );
677  mLayout->undoStack()->beginCommand( this, tr( "Remove Pages" ) );
678  }
679  for ( int i = mPages.count() - 1; i >= 0; --i )
680  {
681  emit pageAboutToBeRemoved( i );
682  mPages.takeAt( i )->deleteLater();
683  }
684  reflow();
685  if ( !mBlockUndoCommands )
686  {
687  mLayout->undoStack()->endCommand();
688  mLayout->undoStack()->endMacro();
689  }
690 }
691 
693 {
694  mPages.removeAll( page );
695  return page;
696 }
697 
698 void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
699 {
700  QgsStringMap properties;
701  properties.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
702  properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
703  properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "no" ) );
704  properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
705  mPageStyleSymbol.reset( QgsFillSymbol::createSimple( properties ) );
706 }
707 
708 
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.
QList< int > visiblePageNumbers(QRectF region) const
Returns a list of the page numbers which are visible within the specified region (in layout coordinat...
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:381
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:465
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:681
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:1114
QList< QgsLayoutItem * > itemsOnPage(int page) const
Returns a list of layout items on the specified page index.
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 a nullptr if a matching item could n...
Definition: qgslayout.cpp:234
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:1079
double maximumPageWidth() const
Returns the maximum width of pages in the collection.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:479
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:251
double convertToLayoutUnits(const QgsLayoutMeasurement &measurement) const
Converts a measurement into the layout&#39;s native units.
Definition: qgslayout.cpp:325
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.
void endCommand()
Saves final state of an object and pushes the active command to the undo history. ...
QList< QgsLayoutItemPage *> visiblePages(QRectF region) const
Returns a list of the pages which are visible within the specified region (in layout coordinates)...
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
Get a deep copy of this symbol.
Definition: qgssymbol.cpp:1871
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout&#39;s page collection, which stores and manages page items in the layout...
Definition: qgslayout.cpp:455
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(const double length, const QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout&#39;s native units to a specified target unit...
Definition: qgslayout.cpp:340
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:114
void addPage(QgsLayoutItemPage *page)
Adds a page to the collection.
void deletePage(int pageNumber)
Deletes a page from the collection.
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.