QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 <QtCore>
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 
40 {
41  Q_UNUSED( frameIndex )
42  return QSizeF( 0, 0 );
43 }
44 
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 = qgis::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  mFrameItems.removeAt( i );
443 }
444 
446 {
447  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
448  {
449  frame->update();
450  }
451 }
452 
454 {
455  mBlockUpdates = true;
456  ResizeMode bkResizeMode = mResizeMode;
458  mLayout->undoStack()->blockCommands( true );
459  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
460  {
461  mLayout->removeLayoutItem( frame );
462  }
463  mLayout->undoStack()->blockCommands( false );
464  mFrameItems.clear();
465  mResizeMode = bkResizeMode;
466  mBlockUpdates = false;
467 }
468 
470 {
471  if ( i < 0 || i >= mFrameItems.size() )
472  {
473  return nullptr;
474  }
475  return mFrameItems.at( i );
476 }
477 
479 {
480  return mFrameItems.indexOf( frame );
481 }
482 
483 bool QgsLayoutMultiFrame::writeXml( QDomElement &parentElement, QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames ) const
484 {
485  QDomElement element = doc.createElement( QStringLiteral( "LayoutMultiFrame" ) );
486  element.setAttribute( QStringLiteral( "resizeMode" ), mResizeMode );
487  element.setAttribute( QStringLiteral( "uuid" ), mUuid );
488  element.setAttribute( QStringLiteral( "templateUuid" ), mUuid );
489  element.setAttribute( QStringLiteral( "type" ), type() );
490 
491  for ( QgsLayoutFrame *frame : mFrameItems )
492  {
493  if ( !frame )
494  continue;
495 
496  QDomElement childItem = doc.createElement( QStringLiteral( "childFrame" ) );
497  childItem.setAttribute( QStringLiteral( "uuid" ), frame->uuid() );
498  childItem.setAttribute( QStringLiteral( "templateUuid" ), frame->uuid() );
499 
500  if ( includeFrames )
501  {
502  frame->writeXml( childItem, doc, context );
503  }
504 
505  element.appendChild( childItem );
506  }
507 
508  writeObjectPropertiesToElement( element, doc, context );
509  writePropertiesToElement( element, doc, context );
510  parentElement.appendChild( element );
511  return true;
512 }
513 
514 bool QgsLayoutMultiFrame::readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames )
515 {
516  if ( element.nodeName() != QStringLiteral( "LayoutMultiFrame" ) )
517  {
518  return false;
519  }
520 
521  mBlockUndoCommands = true;
522  mLayout->undoStack()->blockCommands( true );
523 
524  readObjectPropertiesFromElement( element, doc, context );
525 
526  mUuid = element.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() );
527  mTemplateUuid = element.attribute( QStringLiteral( "templateUuid" ), QUuid::createUuid().toString() );
528  mResizeMode = static_cast< ResizeMode >( element.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() );
529 
530  deleteFrames();
531  mFrameUuids.clear();
532  mFrameTemplateUuids.clear();
533  QDomNodeList elementNodes = element.elementsByTagName( QStringLiteral( "childFrame" ) );
534  for ( int i = 0; i < elementNodes.count(); ++i )
535  {
536  QDomNode elementNode = elementNodes.at( i );
537  if ( !elementNode.isElement() )
538  continue;
539 
540  QDomElement frameElement = elementNode.toElement();
541 
542  QString uuid = frameElement.attribute( QStringLiteral( "uuid" ) );
543  mFrameUuids << uuid;
544  QString templateUuid = frameElement.attribute( QStringLiteral( "templateUuid" ) );
545  mFrameTemplateUuids << templateUuid;
546 
547  if ( includeFrames )
548  {
549  QDomNodeList frameNodes = frameElement.elementsByTagName( QStringLiteral( "LayoutItem" ) );
550  if ( !frameNodes.isEmpty() )
551  {
552  QDomElement frameItemElement = frameNodes.at( 0 ).toElement();
553  std::unique_ptr< QgsLayoutFrame > newFrame = qgis::make_unique< QgsLayoutFrame >( mLayout, this );
554  newFrame->readXml( frameItemElement, doc, context );
555  addFrame( newFrame.release(), false );
556  }
557  }
558  }
559 
560  bool result = readPropertiesFromElement( element, doc, context );
561 
562  mBlockUndoCommands = false;
563  mLayout->undoStack()->blockCommands( false );
564  return result;
565 }
566 
567 bool QgsLayoutMultiFrame::writePropertiesToElement( QDomElement &, QDomDocument &, const QgsReadWriteContext & ) const
568 {
569  return true;
570 }
571 
572 bool QgsLayoutMultiFrame::readPropertiesFromElement( const QDomElement &, const QDomDocument &, const QgsReadWriteContext & )
573 {
574 
575  return true;
576 }
577 
QgsLayoutMultiFrame(QgsLayout *layout)
Construct a new multiframe item, attached to the specified layout.
QString uuid() const
Returns the multiframe identification string.
The class is used as a container of context for various read/write operations on other objects...
virtual QSizeF totalSize() const =0
Returns the total size of the multiframe&#39;s content, in layout units.
void refresh() override
Refreshes the multiframe, causing a recalculation of any property overrides.
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects&#39; current state.
virtual QSizeF minFrameSize(int frameIndex=-1) const
Returns the minimum size for a frames, if desired.
Base class for graphical items within a QgsLayout.
bool readObjectPropertiesFromElement(const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context)
Sets object properties from a DOM element.
Base class for commands to undo/redo layout and layout object changes.
int frameIndex(QgsLayoutFrame *frame) const
Returns the index of a frame within the multiframe.
virtual bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores multiframe state within an XML DOM element.
bool readXml(const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false)
Sets the item state from a DOM element.
QgsLayoutFrame * createNewFrame(QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size)
Creates a new frame and adds it to the multi frame and layout.
QList< QgsLayoutFrame * > frames() const
Returns a list of all child frames for this multiframe.
bool frameEnabled() const
Returns true if the item includes a frame.
Don&#39;t automatically create new frames, just use existing frames.
void beginCommand(const QString &commandText, UndoCommand command=UndoNone)
Starts new undo command for this item.
void deleteFrames()
Removes and deletes all child frames.
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
QList< QgsLayoutFrame * > mFrameItems
void changed()
Emitted when pages are added or removed from the collection.
void setFrameStrokeColor(const QColor &color)
Sets the frame stroke color.
void recalculateFrameRects()
Forces a recalculation of all the associated frame&#39;s scene rectangles.
Creates new full page frames on the following page(s) until the entire multiframe content is visible...
void setContentSection(const QRectF &section)
Sets the visible part of the multiframe&#39;s content which is visible within this frame (relative to the...
QgsLayoutMeasurement frameStrokeWidth() const
Returns the frame&#39;s stroke width.
void refreshItemSize()
Refreshes an item&#39;s size by rechecking it against any possible item fixed or minimum sizes...
void sizePositionChanged()
Emitted when the item&#39;s size or position changes.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores the item state in a DOM element.
static QgsExpressionContextScope * multiFrameScope(const QgsLayoutMultiFrame *frame)
Creates a new scope which contains variables and functions relating to a QgsLayoutMultiFrame.
QgsAbstractLayoutUndoCommand * createCommand(const QString &text, int id, QUndoCommand *parent=nullptr) override
Creates a new layout undo command with the specified text and parent.
void setFrameJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the item&#39;s frame.
bool hasBackground() const
Returns true if the item has a background.
void setBlendMode(QPainter::CompositionMode mode)
Sets the item&#39;s composition blending mode.
Repeats the same frame on every page.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item&#39;s position and size to match the passed rect in layout coordinates...
void setResizeMode(ResizeMode mode)
Sets the resize mode for the multiframe, and recalculates frame sizes to match.
QColor backgroundColor() const
Returns the background color for this item.
QPointer< QgsLayout > mLayout
void setHideBackgroundIfEmpty(bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
int page() const
Returns the page the item is currently on, with the first page returning 0.
double itemOpacity() const
Returns the item&#39;s opacity.
QPainter::CompositionMode blendMode() const
Returns the item&#39;s composition blending mode.
virtual void finalizeRestoreFromXml()
Called after all pending items have been restored from XML.
void endCommand()
Completes the current item command and push it onto the layout&#39;s undo stack.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
QColor frameStrokeColor() const
Returns the frame&#39;s stroke color.
virtual void recalculateFrameSizes()
Recalculates the portion of the multiframe item which is shown in each of its component frames...
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
virtual bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context)
Sets multiframe state from a DOM element.
QPointF pagePos() const
Returns the item&#39;s position (in layout units) relative to the top left corner of its current page...
bool writeObjectPropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores object properties within an XML DOM element.
virtual QString displayName() const
Returns the multiframe display name.
ResizeMode
Specifies the behavior for creating new frames to fit the multiframe&#39;s content.
virtual double findNearbyPageBreak(double yPos)
Finds the optimal position to break a frame at.
virtual QSizeF fixedFrameSize(int frameIndex=-1) const
Returns the fixed size for a frame, if desired.
Qt::PenJoinStyle frameJoinStyle() const
Returns the join style used for drawing the item&#39;s frame.
void update()
Forces a redraw of all child frames.
ResizeMode resizeMode() const
Returns the resize mode for the multiframe.
virtual int type() const =0
Returns unique multiframe type id.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
virtual QString uuid() const
Returns the item identification string.
void removeFrame(int index, bool removeEmptyPages=false)
Removes a frame by index from the multiframe.
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false) const
Stores the multiframe state in a DOM element.
A base class for objects which belong to a layout.
bool hideBackgroundIfEmpty() const
Returns whether the background and frame stroke should be hidden if this frame is empty...
UndoCommand
Multiframe item undo commands, used for collapsing undo commands.
virtual void addFrame(QgsLayoutFrame *frame, bool recalcFrameSizes=true)
Adds a frame to the multiframe.
virtual void refresh()
Refreshes the object, causing a recalculation of any property overrides.
void changed()
Emitted when the object&#39;s properties change.
DataDefinedProperty
Data defined properties for different item types.
Base class for frame items, which form a layout multiframe item.
void setItemOpacity(double opacity)
Sets the item&#39;s opacity.
void cancelCommand()
Cancels the current item command and discards it.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setBackgroundColor(const QColor &color)
Sets the background color for this item.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the multi frame by reevaluating the property&#39;s value and redraw...