QGIS API Documentation  3.2.0-Bonn (bc43194)
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  if ( mPages.empty() )
168  return 0;
169 
170  int pageNumber = 0;
171  double startNextPageY = 0;
172  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
173  {
174  startNextPageY += page->rect().height() + spaceBetweenPages();
175  if ( startNextPageY >= point.y() )
176  break;
177  pageNumber++;
178  }
179 
180  if ( startNextPageY >= point.y() )
181  {
182  // found an existing page
183  return pageNumber;
184  }
185 
186  double lastPageHeight = mPages.last()->rect().height();
187  while ( startNextPageY < point.y() )
188  {
189  startNextPageY += lastPageHeight + spaceBetweenPages();
190  if ( startNextPageY >= point.y() )
191  break;
192  pageNumber++;
193  }
194 
195  return pageNumber;
196 }
197 
199 {
200  const QList< QGraphicsItem * > items = mLayout->items( point );
201  for ( QGraphicsItem *item : items )
202  {
203  if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
204  {
205  QgsLayoutItemPage *page = static_cast< QgsLayoutItemPage * >( item );
206  if ( page->mapToScene( page->rect() ).boundingRect().contains( point ) )
207  return page;
208  }
209  }
210  return nullptr;
211 }
212 
214 {
215  QPointF layoutUnitsPos = mLayout->convertToLayoutUnits( position );
216  if ( page > 0 && page < mPages.count() )
217  {
218  layoutUnitsPos.ry() += mPages.at( page )->pos().y();
219  }
220  return layoutUnitsPos;
221 }
222 
224 {
225  double vDelta = 0.0;
226  if ( page > 0 && page < mPages.count() )
227  {
228  vDelta = mLayout->convertFromLayoutUnits( mPages.at( page )->pos().y(), position.units() ).length();
229  }
230 
231  return QgsLayoutPoint( position.x(), position.y() + vDelta, position.units() );
232 }
233 
234 QPointF QgsLayoutPageCollection::positionOnPage( QPointF position ) const
235 {
236  double startCurrentPageY = 0;
237  double startNextPageY = 0;
238  int pageNumber = 0;
239  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
240  {
241  startCurrentPageY = startNextPageY;
242  startNextPageY += page->rect().height() + spaceBetweenPages();
243  if ( startNextPageY > position.y() )
244  break;
245  pageNumber++;
246  }
247 
248  double y;
249  if ( pageNumber == mPages.size() )
250  {
251  //y coordinate is greater then the end of the last page, so return distance between
252  //top of last page and y coordinate
253  y = position.y() - ( startNextPageY - spaceBetweenPages() );
254  }
255  else
256  {
257  //y coordinate is less then the end of the last page
258  y = position.y() - startCurrentPageY;
259  }
260  return QPointF( position.x(), y );
261 }
262 
264 {
265  return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( 10 ) );
266 }
267 
269 {
270  return spaceBetweenPages() / 2;
271 }
272 
274 {
275  if ( !mBlockUndoCommands )
276  mLayout->undoStack()->beginCommand( this, tr( "Resize to Contents" ) );
277 
278  //calculate current bounds
279  QRectF bounds = mLayout->layoutBounds( true, 0.0 );
280 
281  for ( int page = mPages.count() - 1; page > 0; page-- )
282  {
283  deletePage( page );
284  }
285 
286  if ( mPages.empty() )
287  {
288  std::unique_ptr< QgsLayoutItemPage > page = qgis::make_unique< QgsLayoutItemPage >( mLayout );
289  addPage( page.release() );
290  }
291 
292  QgsLayoutItemPage *page = mPages.at( 0 );
293 
294  double marginLeft = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.left(), marginUnits ) );
295  double marginTop = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.top(), marginUnits ) );
296  double marginBottom = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.bottom(), marginUnits ) );
297  double marginRight = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.right(), marginUnits ) );
298 
299  bounds.setWidth( bounds.width() + marginLeft + marginRight );
300  bounds.setHeight( bounds.height() + marginTop + marginBottom );
301 
302  QgsLayoutSize newPageSize = mLayout->convertFromLayoutUnits( bounds.size(), mLayout->units() );
303  page->setPageSize( newPageSize );
304 
305  reflow();
306 
307  //also move all items so that top-left of bounds is at marginLeft, marginTop
308  double diffX = marginLeft - bounds.left();
309  double diffY = marginTop - bounds.top();
310 
311  const QList<QGraphicsItem *> itemList = mLayout->items();
312  for ( QGraphicsItem *item : itemList )
313  {
314  if ( QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
315  {
316  QgsLayoutItemPage *pageItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
317  if ( !pageItem )
318  {
319  layoutItem->beginCommand( tr( "Move Item" ) );
320  layoutItem->attemptMoveBy( diffX, diffY );
321  layoutItem->endCommand();
322  }
323  }
324  }
325 
326  //also move guides
327  mLayout->undoStack()->beginCommand( &mLayout->guides(), tr( "Move Guides" ) );
328  const QList< QgsLayoutGuide * > verticalGuides = mLayout->guides().guides( Qt::Vertical );
329  for ( QgsLayoutGuide *guide : verticalGuides )
330  {
331  guide->setLayoutPosition( guide->layoutPosition() + diffX );
332  }
333  const QList< QgsLayoutGuide * > horizontalGuides = mLayout->guides().guides( Qt::Horizontal );
334  for ( QgsLayoutGuide *guide : horizontalGuides )
335  {
336  guide->setLayoutPosition( guide->layoutPosition() + diffY );
337  }
338  mLayout->undoStack()->endCommand();
339 
340  if ( !mBlockUndoCommands )
341  mLayout->undoStack()->endCommand();
342 }
343 
344 bool QgsLayoutPageCollection::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
345 {
346  QDomElement element = document.createElement( QStringLiteral( "PageCollection" ) );
347 
348  QDomElement pageStyleElem = QgsSymbolLayerUtils::saveSymbol( QString(), mPageStyleSymbol.get(), document, context );
349  element.appendChild( pageStyleElem );
350 
351  for ( const QgsLayoutItemPage *page : mPages )
352  {
353  page->writeXml( element, document, context );
354  }
355 
356  mGuideCollection->writeXml( element, document, context );
357 
358  parentElement.appendChild( element );
359  return true;
360 }
361 
362 bool QgsLayoutPageCollection::readXml( const QDomElement &e, const QDomDocument &document, const QgsReadWriteContext &context )
363 {
364  QDomElement element = e;
365  if ( element.nodeName() != QStringLiteral( "PageCollection" ) )
366  {
367  element = element.firstChildElement( QStringLiteral( "PageCollection" ) );
368  }
369 
370  if ( element.nodeName() != QStringLiteral( "PageCollection" ) )
371  {
372  return false;
373  }
374 
375  mBlockUndoCommands = true;
376 
377  int i = 0;
378  for ( QgsLayoutItemPage *page : qgis::as_const( mPages ) )
379  {
380  emit pageAboutToBeRemoved( i );
381  mLayout->removeItem( page );
382  page->deleteLater();
383  ++i;
384  }
385  mPages.clear();
386 
387  QDomElement pageStyleSymbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
388  if ( !pageStyleSymbolElem.isNull() )
389  {
390  mPageStyleSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( pageStyleSymbolElem, context ) );
391  }
392 
393  QDomNodeList pageList = element.elementsByTagName( QStringLiteral( "LayoutItem" ) );
394  for ( int i = 0; i < pageList.size(); ++i )
395  {
396  QDomElement pageElement = pageList.at( i ).toElement();
397  std::unique_ptr< QgsLayoutItemPage > page( new QgsLayoutItemPage( mLayout ) );
398  page->readXml( pageElement, document, context );
399  page->finalizeRestoreFromXml();
400  mPages.append( page.get() );
401  mLayout->addItem( page.release() );
402  }
403 
404  reflow();
405 
406  mGuideCollection->readXml( element, document, context );
407 
408  mBlockUndoCommands = false;
409  return true;
410 }
411 
413 {
414  return *mGuideCollection;
415 }
416 
418 {
419  return *mGuideCollection;
420 }
421 
423 {
424  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
425  {
426  page->redraw();
427  }
428 }
429 
431 {
432  return mLayout;
433 }
434 
435 QList<QgsLayoutItemPage *> QgsLayoutPageCollection::pages()
436 {
437  return mPages;
438 }
439 
441 {
442  return mPages.count();
443 }
444 
446 {
447  return mPages.value( pageNumber );
448 }
449 
451 {
452  return mPages.value( pageNumber );
453 }
454 
456 {
457  return mPages.indexOf( page );
458 }
459 
460 QList<QgsLayoutItemPage *> QgsLayoutPageCollection::visiblePages( QRectF region ) const
461 {
462  QList<QgsLayoutItemPage *> pages;
463  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
464  {
465  if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
466  pages << page;
467  }
468  return pages;
469 }
470 
471 QList<int> QgsLayoutPageCollection::visiblePageNumbers( QRectF region ) const
472 {
473  QList< int > pages;
474  int p = 0;
475  Q_FOREACH ( QgsLayoutItemPage *page, mPages )
476  {
477  if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
478  pages << p;
479  p++;
480  }
481  return pages;
482 }
483 
485 {
486  //get all items on page
487  const QList<QgsLayoutItem *> items = mLayout->pageCollection()->itemsOnPage( page );
488 
489  //loop through and check for non-paper items
490  for ( QgsLayoutItem *item : items )
491  {
492  //is item a paper item?
493  if ( item->type() != QgsLayoutItemRegistry::LayoutPage )
494  {
495  //item is not a paper item, so we have other items on the page
496  return false;
497  }
498  }
499  //no non-paper items
500  return true;
501 }
502 
503 QList<QgsLayoutItem *> QgsLayoutPageCollection::itemsOnPage( int page ) const
504 {
505  QList<QgsLayoutItem *> itemList;
506  const QList<QGraphicsItem *> graphicsItemList = mLayout->items();
507  for ( QGraphicsItem *graphicsItem : graphicsItemList )
508  {
509  QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
510  if ( item && item->page() == page )
511  {
512  itemList.push_back( item );
513  }
514  }
515  return itemList;
516 }
517 
519 {
520  if ( page >= mPages.count() || page < 0 )
521  {
522  //page number out of range, of course we shouldn't export it - stop smoking crack!
523  return false;
524  }
525 
526  QgsLayoutItemPage *pageItem = mPages.at( page );
527  if ( !pageItem->shouldDrawItem() )
528  return false;
529 
530  //check all frame items on page
531  QList<QgsLayoutFrame *> frames;
532  itemsOnPage( frames, page );
533  for ( QgsLayoutFrame *frame : qgis::as_const( frames ) )
534  {
535  if ( frame->hidePageIfEmpty() && frame->isEmpty() )
536  {
537  //frame is set to hide page if empty, and frame is empty, so we don't want to export this page
538  return false;
539  }
540  }
541  return true;
542 }
543 
545 {
546  if ( !mBlockUndoCommands )
547  mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
548  mPages.append( page );
549  mLayout->addItem( page );
550  reflow();
551  if ( !mBlockUndoCommands )
552  mLayout->undoStack()->endCommand();
553 }
554 
556 {
557  if ( mPages.empty() )
558  return nullptr;
559 
560  QgsLayoutItemPage *lastPage = mPages.at( mPages.count() - 1 );
561  std::unique_ptr< QgsLayoutItemPage > newPage = qgis::make_unique< QgsLayoutItemPage >( mLayout );
562  newPage->attemptResize( lastPage->sizeWithUnits() );
563  addPage( newPage.release() );
564  return mPages.at( mPages.count() - 1 );
565 }
566 
568 {
569  if ( !mBlockUndoCommands )
570  {
571  mLayout->undoStack()->beginMacro( tr( "Add Page" ) );
572  mLayout->undoStack()->beginCommand( this, tr( "Add Page" ) );
573  }
574 
575  if ( beforePage < 0 )
576  beforePage = 0;
577 
579  if ( beforePage >= mPages.count() )
580  {
581  mPages.append( page );
582  }
583  else
584  {
585  mPages.insert( beforePage, page );
586  }
587  mLayout->addItem( page );
588  reflow();
589 
590  // bump up stored page numbers to account
591  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
592  {
593  if ( it.value().first < beforePage )
594  continue;
595 
596  it.value().first = it.value().first + 1;
597  }
598 
600  if ( ! mBlockUndoCommands )
601  {
602  mLayout->undoStack()->endCommand();
603  mLayout->undoStack()->endMacro();
604  }
605 }
606 
608 {
609  if ( pageNumber < 0 || pageNumber >= mPages.count() )
610  return;
611 
612  if ( !mBlockUndoCommands )
613  {
614  mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
615  mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
616  }
617  emit pageAboutToBeRemoved( pageNumber );
619  QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
620  mLayout->removeItem( page );
621  page->deleteLater();
622  reflow();
623 
624  // bump stored page numbers to account
625  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
626  {
627  if ( it.value().first <= pageNumber )
628  continue;
629 
630  it.value().first = it.value().first - 1;
631  }
632 
634  if ( ! mBlockUndoCommands )
635  {
636  mLayout->undoStack()->endCommand();
637  mLayout->undoStack()->endMacro();
638  }
639 }
640 
642 {
643  if ( !mPages.contains( page ) )
644  return;
645 
646  if ( !mBlockUndoCommands )
647  {
648  mLayout->undoStack()->beginMacro( tr( "Remove Page" ) );
649  mLayout->undoStack()->beginCommand( this, tr( "Remove Page" ) );
650  }
651  int pageIndex = mPages.indexOf( page );
652  emit pageAboutToBeRemoved( pageIndex );
654  mPages.removeAll( page );
655  page->deleteLater();
656  reflow();
657 
658  // bump stored page numbers to account
659  for ( auto it = mPreviousItemPositions.begin(); it != mPreviousItemPositions.end(); ++it )
660  {
661  if ( it.value().first <= pageIndex )
662  continue;
663 
664  it.value().first = it.value().first - 1;
665  }
666 
668  if ( !mBlockUndoCommands )
669  {
670  mLayout->undoStack()->endCommand();
671  mLayout->undoStack()->endMacro();
672  }
673 }
674 
676 {
677  if ( !mBlockUndoCommands )
678  {
679  mLayout->undoStack()->beginMacro( tr( "Remove Pages" ) );
680  mLayout->undoStack()->beginCommand( this, tr( "Remove Pages" ) );
681  }
682  for ( int i = mPages.count() - 1; i >= 0; --i )
683  {
684  emit pageAboutToBeRemoved( i );
685  mPages.takeAt( i )->deleteLater();
686  }
687  reflow();
688  if ( !mBlockUndoCommands )
689  {
690  mLayout->undoStack()->endCommand();
691  mLayout->undoStack()->endMacro();
692  }
693 }
694 
696 {
697  mPages.removeAll( page );
698  return page;
699 }
700 
701 void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
702 {
703  QgsStringMap properties;
704  properties.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
705  properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
706  properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "no" ) );
707  properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
708  mPageStyleSymbol.reset( QgsFillSymbol::createSimple( properties ) );
709 }
710 
711 
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:1109
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:251
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:501
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
Gets a deep copy of this symbol.
Definition: qgssymbol.cpp:1866
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(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: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.