QGIS API Documentation  3.25.0-Master (10b47c2603)
qgslayoutmultiframe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutmultiframe.cpp
3  -----------------------
4  begin : October 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgslayoutmultiframe.h"
18 #include "qgslayoutframe.h"
19 #include "qgslayout.h"
21 #include "qgslayoutundostack.h"
23 #include <QUuid>
24 
26  : QgsLayoutObject( layout )
27  , mUuid( QUuid::createUuid().toString() )
28 {
29  mLayout->addMultiFrame( this );
30 
31  connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutMultiFrame::handlePageChange );
32 }
33 
35 {
36  deleteFrames();
37 }
38 
39 QSizeF QgsLayoutMultiFrame::fixedFrameSize( const int frameIndex ) const
40 {
41  Q_UNUSED( frameIndex )
42  return QSizeF( 0, 0 );
43 }
44 
45 QSizeF QgsLayoutMultiFrame::minFrameSize( const int frameIndex ) const
46 {
47  Q_UNUSED( frameIndex )
48  return QSizeF( 0, 0 );
49 }
50 
52 {
53  return yPos;
54 }
55 
56 void QgsLayoutMultiFrame::addFrame( QgsLayoutFrame *frame, bool recalcFrameSizes )
57 {
58  if ( !frame || mFrameItems.contains( frame ) )
59  return;
60 
61  mFrameItems.push_back( frame );
62  frame->mMultiFrame = this;
64  connect( frame, &QgsLayoutFrame::destroyed, this, [this, frame ]
65  {
66  handleFrameRemoval( frame );
67  } );
68  if ( mLayout && !frame->scene() )
69  {
70  mLayout->addLayoutItem( frame );
71  }
72 
73  if ( recalcFrameSizes )
74  {
76  }
77 }
78 
80 {
81  if ( mode != mResizeMode )
82  {
83  mLayout->undoStack()->beginMacro( tr( "Change Resize Mode" ) );
84  mResizeMode = mode;
86  mLayout->undoStack()->endMacro();
87  emit changed();
88  }
89 }
90 
91 QList<QgsLayoutFrame *> QgsLayoutMultiFrame::frames() const
92 {
93  return mFrameItems;
94 }
95 
97 {
98  if ( mFrameItems.empty() )
99  {
100  return;
101  }
102 
103  QSizeF size = totalSize();
104  double totalHeight = size.height();
105 
106  if ( totalHeight < 1 )
107  {
108  return;
109  }
110 
111  if ( mBlockUndoCommands )
112  mLayout->undoStack()->blockCommands( true );
113 
114  double currentY = 0;
115  double currentHeight = 0;
116  QgsLayoutFrame *currentItem = nullptr;
117 
118  for ( int i = 0; i < mFrameItems.size(); ++i )
119  {
120  if ( mResizeMode != RepeatOnEveryPage && currentY >= totalHeight )
121  {
122  if ( mResizeMode == RepeatUntilFinished || mResizeMode == ExtendToNextPage ) //remove unneeded frames in extent mode
123  {
124  bool removingPages = true;
125  for ( int j = mFrameItems.size(); j > i; --j )
126  {
127  int numPagesBefore = mLayout->pageCollection()->pageCount();
128  removeFrame( j - 1, removingPages );
129  //if removing the frame didn't also remove the page, then stop removing pages
130  removingPages = removingPages && ( mLayout->pageCollection()->pageCount() < numPagesBefore );
131  }
132  return;
133  }
134  }
135 
136  currentItem = mFrameItems.value( i );
137  currentHeight = currentItem->rect().height();
139  {
140  currentItem->setContentSection( QRectF( 0, 0, currentItem->rect().width(), currentHeight ) );
141  }
142  else
143  {
144  currentHeight = findNearbyPageBreak( currentY + currentHeight ) - currentY;
145  currentItem->setContentSection( QRectF( 0, currentY, currentItem->rect().width(), currentHeight ) );
146  }
147  currentItem->update();
148  currentY += currentHeight;
149  }
150 
151  //at end of frames but there is still content left. Add other pages if ResizeMode ==
152  if ( mLayout->pageCollection()->pageCount() > 0 && currentItem && mResizeMode != UseExistingFrames )
153  {
154  while ( ( mResizeMode == RepeatOnEveryPage ) || currentY < totalHeight )
155  {
156  //find out on which page the lower left point of the last frame is
157  int page = mLayout->pageCollection()->predictPageNumberForPoint( QPointF( 0, currentItem->pos().y() + currentItem->rect().height() ) ) + 1;
158 
160  {
161  if ( page >= mLayout->pageCollection()->pageCount() )
162  {
163  break;
164  }
165  }
166  else
167  {
168  //add new pages if required
169  for ( int p = mLayout->pageCollection()->pageCount() - 1 ; p < page; ++p )
170  {
171  mLayout->pageCollection()->extendByNewPage();
172  }
173  }
174 
175  double currentPageHeight = mLayout->pageCollection()->page( page )->rect().height();
176 
177  double frameHeight = 0;
178  switch ( mResizeMode )
179  {
180  case RepeatUntilFinished:
181  case RepeatOnEveryPage:
182  {
183  frameHeight = currentItem->rect().height();
184  break;
185  }
186  case ExtendToNextPage:
187  {
188  frameHeight = ( currentY + currentPageHeight ) > totalHeight ? totalHeight - currentY : currentPageHeight;
189  break;
190  }
191 
192  case UseExistingFrames:
193  break;
194  }
195 
196  double newFrameY = mLayout->pageCollection()->page( page )->pos().y();
198  {
199  newFrameY += currentItem->pagePos().y();
200  }
201 
202  //create new frame
203  QgsLayoutFrame *newFrame = createNewFrame( currentItem,
204  QPointF( currentItem->pos().x(), newFrameY ),
205  QSizeF( currentItem->rect().width(), frameHeight ) );
206 
208  {
209  newFrame->setContentSection( QRectF( 0, 0, newFrame->rect().width(), newFrame->rect().height() ) );
210  currentY += frameHeight;
211  }
212  else
213  {
214  double contentHeight = findNearbyPageBreak( currentY + newFrame->rect().height() ) - currentY;
215  newFrame->setContentSection( QRectF( 0, currentY, newFrame->rect().width(), contentHeight ) );
216  currentY += contentHeight;
217  }
218 
219  currentItem = newFrame;
220  }
221  }
222 
223  if ( mBlockUndoCommands )
224  mLayout->undoStack()->blockCommands( false );
225 }
226 
228 {
229  if ( mFrameItems.empty() )
230  {
231  //no frames, nothing to do
232  return;
233  }
234 
235  const QList< QgsLayoutFrame * > frames = mFrameItems;
236  for ( QgsLayoutFrame *frame : frames )
237  {
239  }
240 }
241 
243 {
244 
245 }
246 
247 QgsLayoutFrame *QgsLayoutMultiFrame::createNewFrame( QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size )
248 {
249  if ( !currentFrame )
250  {
251  return nullptr;
252  }
253 
254  QgsLayoutFrame *newFrame = new QgsLayoutFrame( mLayout, this );
255  newFrame->attemptSetSceneRect( QRectF( pos.x(), pos.y(), size.width(), size.height() ) );
256 
257  //copy some settings from the parent frame
258  newFrame->setBackgroundColor( currentFrame->backgroundColor() );
259  newFrame->setBackgroundEnabled( currentFrame->hasBackground() );
260  newFrame->setBlendMode( currentFrame->blendMode() );
261  newFrame->setFrameEnabled( currentFrame->frameEnabled() );
262  newFrame->setFrameStrokeColor( currentFrame->frameStrokeColor() );
263  newFrame->setFrameJoinStyle( currentFrame->frameJoinStyle() );
264  newFrame->setFrameStrokeWidth( currentFrame->frameStrokeWidth() );
265  newFrame->setItemOpacity( currentFrame->itemOpacity() );
266  newFrame->setHideBackgroundIfEmpty( currentFrame->hideBackgroundIfEmpty() );
267 
268  addFrame( newFrame, false );
269 
270  return newFrame;
271 }
272 
274 {
275  return tr( "<Multiframe>" );
276 }
277 
278 QgsAbstractLayoutUndoCommand *QgsLayoutMultiFrame::createCommand( const QString &text, int id, QUndoCommand *parent )
279 {
280  return new QgsLayoutMultiFrameUndoCommand( this, text, id, parent );
281 }
282 
284 {
287  return context;
288 }
289 
290 void QgsLayoutMultiFrame::beginCommand( const QString &commandText, QgsLayoutMultiFrame::UndoCommand command )
291 {
292  if ( !mLayout )
293  return;
294 
295  mLayout->undoStack()->beginCommand( this, commandText, command );
296 }
297 
299 {
300  if ( mLayout )
301  mLayout->undoStack()->endCommand();
302 }
303 
305 {
306  if ( mLayout )
307  mLayout->undoStack()->cancelCommand();
308 }
309 
311 {
312  for ( int i = 0; i < mFrameUuids.count(); ++i )
313  {
314  QgsLayoutFrame *frame = nullptr;
315  const QString uuid = mFrameUuids.at( i );
316  if ( !uuid.isEmpty() )
317  {
318  QgsLayoutItem *item = mLayout->itemByUuid( uuid, true );
319  frame = qobject_cast< QgsLayoutFrame * >( item );
320  }
321  if ( !frame )
322  {
323  const QString templateUuid = mFrameTemplateUuids.at( i );
324  if ( !templateUuid.isEmpty() )
325  {
326  QgsLayoutItem *item = mLayout->itemByTemplateUuid( templateUuid );
327  frame = qobject_cast< QgsLayoutFrame * >( item );
328  }
329  }
330 
331  if ( frame )
332  {
333  addFrame( frame );
334  }
335  }
336 }
337 
339 {
342 }
343 
344 void QgsLayoutMultiFrame::handleFrameRemoval( QgsLayoutFrame *frame )
345 {
346  if ( mBlockUpdates )
347  return;
348 
349  if ( !frame )
350  {
351  return;
352  }
353  int index = mFrameItems.indexOf( frame );
354  if ( index == -1 )
355  {
356  return;
357  }
358 
359  mFrameItems.removeAt( index );
360  if ( !mFrameItems.isEmpty() )
361  {
362  if ( resizeMode() != QgsLayoutMultiFrame::RepeatOnEveryPage && !mIsRecalculatingSize )
363  {
364  //removing a frame forces the multi frame to UseExistingFrames resize mode
365  //otherwise the frame may not actually be removed, leading to confusing ui behavior
367  emit changed();
369  }
370  }
371 }
372 
373 void QgsLayoutMultiFrame::handlePageChange()
374 {
375  if ( mLayout->pageCollection()->pageCount() < 1 )
376  {
377  return;
378  }
379 
381  {
382  return;
383  }
384 
385  //remove items beginning on non-existing pages
386  for ( int i = mFrameItems.size() - 1; i >= 0; --i )
387  {
388  QgsLayoutFrame *frame = mFrameItems.at( i );
389  int page = mLayout->pageCollection()->predictPageNumberForPoint( frame->pos() );
390  if ( page >= mLayout->pageCollection()->pageCount() )
391  {
392  removeFrame( i );
393  }
394  }
395 
396  if ( !mFrameItems.empty() )
397  {
398  //page number of the last item
399  QgsLayoutFrame *lastFrame = mFrameItems.last();
400  int lastItemPage = mLayout->pageCollection()->predictPageNumberForPoint( lastFrame->pos() );
401 
402  for ( int i = lastItemPage + 1; i < mLayout->pageCollection()->pageCount(); ++i )
403  {
404  //copy last frame to current page
405  std::unique_ptr< QgsLayoutFrame > newFrame = std::make_unique< QgsLayoutFrame >( mLayout, this );
406 
407  newFrame->attemptSetSceneRect( QRectF( lastFrame->pos().x(),
408  mLayout->pageCollection()->page( i )->pos().y() + lastFrame->pagePos().y(),
409  lastFrame->rect().width(), lastFrame->rect().height() ) );
410  lastFrame = newFrame.get();
411  addFrame( newFrame.release(), false );
412  }
413  }
414 
416  update();
417 }
418 
419 void QgsLayoutMultiFrame::removeFrame( int i, const bool removeEmptyPages )
420 {
421  if ( i >= mFrameItems.count() )
422  {
423  return;
424  }
425 
426  QgsLayoutFrame *frameItem = mFrameItems.at( i );
427  if ( mLayout )
428  {
429  mIsRecalculatingSize = true;
430  int pageNumber = frameItem->page();
431  //remove item, but don't create undo command
432  mLayout->undoStack()->blockCommands( true );
433  mLayout->removeLayoutItem( frameItem );
434  //if frame was the only item on the page, remove the page
435  if ( removeEmptyPages && mLayout->pageCollection()->pageIsEmpty( pageNumber ) )
436  {
437  mLayout->pageCollection()->deletePage( pageNumber );
438  }
439  mLayout->undoStack()->blockCommands( false );
440  mIsRecalculatingSize = false;
441  }
442 
443  if ( i >= mFrameItems.count() )
444  {
445  return;
446  }
447 
448  mFrameItems.removeAt( i );
449 }
450 
452 {
453  for ( QgsLayoutFrame *frame : std::as_const( mFrameItems ) )
454  {
455  frame->update();
456  }
457 }
458 
460 {
461  mBlockUpdates = true;
462  ResizeMode bkResizeMode = mResizeMode;
464  mLayout->undoStack()->blockCommands( true );
465  for ( QgsLayoutFrame *frame : std::as_const( mFrameItems ) )
466  {
467  mLayout->removeLayoutItem( frame );
468  }
469  mLayout->undoStack()->blockCommands( false );
470  mFrameItems.clear();
471  mResizeMode = bkResizeMode;
472  mBlockUpdates = false;
473 }
474 
476 {
477  if ( i < 0 || i >= mFrameItems.size() )
478  {
479  return nullptr;
480  }
481  return mFrameItems.at( i );
482 }
483 
485 {
486  return mFrameItems.indexOf( frame );
487 }
488 
489 bool QgsLayoutMultiFrame::writeXml( QDomElement &parentElement, QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames ) const
490 {
491  QDomElement element = doc.createElement( QStringLiteral( "LayoutMultiFrame" ) );
492  element.setAttribute( QStringLiteral( "resizeMode" ), mResizeMode );
493  element.setAttribute( QStringLiteral( "uuid" ), mUuid );
494  element.setAttribute( QStringLiteral( "templateUuid" ), mUuid );
495  element.setAttribute( QStringLiteral( "type" ), type() );
496 
497  for ( QgsLayoutFrame *frame : mFrameItems )
498  {
499  if ( !frame )
500  continue;
501 
502  QDomElement childItem = doc.createElement( QStringLiteral( "childFrame" ) );
503  childItem.setAttribute( QStringLiteral( "uuid" ), frame->uuid() );
504  childItem.setAttribute( QStringLiteral( "templateUuid" ), frame->uuid() );
505 
506  if ( includeFrames )
507  {
508  frame->writeXml( childItem, doc, context );
509  }
510 
511  element.appendChild( childItem );
512  }
513 
514  writeObjectPropertiesToElement( element, doc, context );
515  writePropertiesToElement( element, doc, context );
516  parentElement.appendChild( element );
517  return true;
518 }
519 
520 bool QgsLayoutMultiFrame::readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames )
521 {
522  if ( element.nodeName() != QLatin1String( "LayoutMultiFrame" ) )
523  {
524  return false;
525  }
526 
527  mBlockUndoCommands = true;
528  mLayout->undoStack()->blockCommands( true );
529 
530  readObjectPropertiesFromElement( element, doc, context );
531 
532  mUuid = element.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() );
533  mTemplateUuid = element.attribute( QStringLiteral( "templateUuid" ), QUuid::createUuid().toString() );
534  mResizeMode = static_cast< ResizeMode >( element.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() );
535 
536  deleteFrames();
537  mFrameUuids.clear();
538  mFrameTemplateUuids.clear();
539  QDomNodeList elementNodes = element.elementsByTagName( QStringLiteral( "childFrame" ) );
540  for ( int i = 0; i < elementNodes.count(); ++i )
541  {
542  QDomNode elementNode = elementNodes.at( i );
543  if ( !elementNode.isElement() )
544  continue;
545 
546  QDomElement frameElement = elementNode.toElement();
547 
548  QString uuid = frameElement.attribute( QStringLiteral( "uuid" ) );
549  mFrameUuids << uuid;
550  QString templateUuid = frameElement.attribute( QStringLiteral( "templateUuid" ) );
551  mFrameTemplateUuids << templateUuid;
552 
553  if ( includeFrames )
554  {
555  QDomNodeList frameNodes = frameElement.elementsByTagName( QStringLiteral( "LayoutItem" ) );
556  if ( !frameNodes.isEmpty() )
557  {
558  QDomElement frameItemElement = frameNodes.at( 0 ).toElement();
559  std::unique_ptr< QgsLayoutFrame > newFrame = std::make_unique< QgsLayoutFrame >( mLayout, this );
560  newFrame->readXml( frameItemElement, doc, context );
561  addFrame( newFrame.release(), false );
562  }
563  }
564  }
565 
566  bool result = readPropertiesFromElement( element, doc, context );
567 
568  mBlockUndoCommands = false;
569  mLayout->undoStack()->blockCommands( false );
570  return result;
571 }
572 
573 bool QgsLayoutMultiFrame::writePropertiesToElement( QDomElement &, QDomDocument &, const QgsReadWriteContext & ) const
574 {
575  return true;
576 }
577 
578 bool QgsLayoutMultiFrame::readPropertiesFromElement( const QDomElement &, const QDomDocument &, const QgsReadWriteContext & )
579 {
580 
581  return true;
582 }
583 
Base class for commands to undo/redo layout and layout object changes.
static QgsExpressionContextScope * multiFrameScope(const QgsLayoutMultiFrame *frame)
Creates a new scope which contains variables and functions relating to a QgsLayoutMultiFrame.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Base class for frame items, which form a layout multiframe item.
void setContentSection(const QRectF &section)
Sets the visible part of the multiframe's content which is visible within this frame (relative to the...
bool hideBackgroundIfEmpty() const
Returns whether the background and frame stroke should be hidden if this frame is empty.
void setHideBackgroundIfEmpty(bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
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.
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
void setBackgroundColor(const QColor &color)
Sets the background color for this item.
QgsLayoutMeasurement frameStrokeWidth() const
Returns the frame's stroke width.
double itemOpacity() const
Returns the item's opacity.
void setItemOpacity(double opacity)
Sets the item's opacity.
void refreshItemSize()
Refreshes an item's size by rechecking it against any possible item fixed or minimum sizes.
int page() const
Returns the page the item is currently on, with the first page returning 0.
QColor backgroundColor() const
Returns the background color for this item.
void setFrameStrokeColor(const QColor &color)
Sets the frame stroke color.
void setFrameJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the item's frame.
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QPointF pagePos() const
Returns the item's position (in layout units) relative to the top left corner of its current page.
void setBlendMode(QPainter::CompositionMode mode)
Sets the item's composition blending mode.
bool frameEnabled() const
Returns true if the item includes a frame.
bool hasBackground() const
Returns true if the item has a background.
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
QColor frameStrokeColor() const
Returns the frame's stroke color.
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
Qt::PenJoinStyle frameJoinStyle() const
Returns the join style used for drawing the item's frame.
virtual bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores multiframe state within an XML DOM element.
void setResizeMode(ResizeMode mode)
Sets the resize mode for the multiframe, and recalculates frame sizes to match.
virtual QSizeF totalSize() const =0
Returns the total size of the multiframe's content, in layout units.
virtual void addFrame(QgsLayoutFrame *frame, bool recalcFrameSizes=true)
Adds a frame to the multiframe.
QgsLayoutMultiFrame(QgsLayout *layout)
Construct a new multiframe item, attached to the specified layout.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false) const
Stores the multiframe state in a DOM element.
virtual void finalizeRestoreFromXml()
Called after all pending items have been restored from XML.
QgsAbstractLayoutUndoCommand * createCommand(const QString &text, int id, QUndoCommand *parent=nullptr) override
Creates a new layout undo command with the specified text and parent.
bool readXml(const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false)
Sets the item state from a DOM element.
void deleteFrames()
Removes and deletes all child frames.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
virtual QSizeF fixedFrameSize(int frameIndex=-1) const
Returns the fixed size for a frame, if desired.
void removeFrame(int index, bool removeEmptyPages=false)
Removes a frame by index from the multiframe.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QList< QgsLayoutFrame * > mFrameItems
void cancelCommand()
Cancels the current item command and discards it.
virtual int type() const =0
Returns unique multiframe type id.
ResizeMode resizeMode() const
Returns the resize mode for the multiframe.
virtual QSizeF minFrameSize(int frameIndex=-1) const
Returns the minimum size for a frames, if desired.
virtual double findNearbyPageBreak(double yPos)
Finds the optimal position to break a frame at.
QString uuid() const
Returns the multiframe identification string.
ResizeMode
Specifies the behavior for creating new frames to fit the multiframe's content.
@ UseExistingFrames
Don't automatically create new frames, just use existing frames.
@ RepeatOnEveryPage
Repeats the same frame on every page.
@ ExtendToNextPage
Creates new full page frames on the following page(s) until the entire multiframe content is visible.
void refresh() override
Refreshes the multiframe, causing a recalculation of any property overrides.
void endCommand()
Completes the current item command and push it onto the layout's undo stack.
QgsLayoutFrame * createNewFrame(QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size)
Creates a new frame and adds it to the multi frame and layout.
void beginCommand(const QString &commandText, UndoCommand command=UndoNone)
Starts new undo command for this item.
QList< QgsLayoutFrame * > frames() const
Returns a list of all child frames for this multiframe.
virtual void recalculateFrameSizes()
Recalculates the portion of the multiframe item which is shown in each of its component frames.
void update()
Forces a redraw of all child frames.
int frameIndex(QgsLayoutFrame *frame) const
Returns the index of a frame within the multiframe.
void recalculateFrameRects()
Forces a recalculation of all the associated frame's scene rectangles.
virtual bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context)
Sets multiframe state from a DOM element.
virtual QString displayName() const
Returns the multiframe display name.
UndoCommand
Multiframe item undo commands, used for collapsing undo commands.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the multi frame by reevaluating the property's value and redraw...
A base class for objects which belong to a layout.
bool readObjectPropertiesFromElement(const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context)
Sets object properties from a DOM element.
void changed()
Emitted when the object's properties change.
virtual void refresh()
Refreshes the object, causing a recalculation of any property overrides.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects' current state.
bool writeObjectPropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores object properties within an XML DOM element.
void changed()
Emitted when pages are added or removed from the collection.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
The class is used as a container of context for various read/write operations on other objects.