QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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"
22 #include <QtCore>
23 
25  : QgsLayoutObject( layout )
26  , mUuid( QUuid::createUuid().toString() )
27 {
28  mLayout->addMultiFrame( this );
29 
30  connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutMultiFrame::handlePageChange );
31 }
32 
34 {
35  deleteFrames();
36 }
37 
39 {
40  Q_UNUSED( frameIndex );
41  return QSizeF( 0, 0 );
42 }
43 
45 {
46  Q_UNUSED( frameIndex );
47  return QSizeF( 0, 0 );
48 }
49 
51 {
52  return yPos;
53 }
54 
55 void QgsLayoutMultiFrame::addFrame( QgsLayoutFrame *frame, bool recalcFrameSizes )
56 {
57  if ( !frame || mFrameItems.contains( frame ) )
58  return;
59 
60  mFrameItems.push_back( frame );
61  frame->mMultiFrame = this;
63  connect( frame, &QgsLayoutFrame::destroyed, this, [this, frame ]
64  {
65  handleFrameRemoval( frame );
66  } );
67  if ( mLayout && !frame->scene() )
68  {
69  mLayout->addLayoutItem( frame );
70  }
71 
72  if ( recalcFrameSizes )
73  {
75  }
76 }
77 
79 {
80  if ( mode != mResizeMode )
81  {
82  mLayout->undoStack()->beginMacro( tr( "Change Resize Mode" ) );
83  mResizeMode = mode;
85  mLayout->undoStack()->endMacro();
86  emit changed();
87  }
88 }
89 
90 QList<QgsLayoutFrame *> QgsLayoutMultiFrame::frames() const
91 {
92  return mFrameItems;
93 }
94 
96 {
97  if ( mFrameItems.empty() )
98  {
99  return;
100  }
101 
102  QSizeF size = totalSize();
103  double totalHeight = size.height();
104 
105  if ( totalHeight < 1 )
106  {
107  return;
108  }
109 
110  if ( mBlockUndoCommands )
111  mLayout->undoStack()->blockCommands( true );
112 
113  double currentY = 0;
114  double currentHeight = 0;
115  QgsLayoutFrame *currentItem = nullptr;
116 
117  for ( int i = 0; i < mFrameItems.size(); ++i )
118  {
119  if ( mResizeMode != RepeatOnEveryPage && currentY >= totalHeight )
120  {
121  if ( mResizeMode == RepeatUntilFinished || mResizeMode == ExtendToNextPage ) //remove unneeded frames in extent mode
122  {
123  bool removingPages = true;
124  for ( int j = mFrameItems.size(); j > i; --j )
125  {
126  int numPagesBefore = mLayout->pageCollection()->pageCount();
127  removeFrame( j - 1, removingPages );
128  //if removing the frame didn't also remove the page, then stop removing pages
129  removingPages = removingPages && ( mLayout->pageCollection()->pageCount() < numPagesBefore );
130  }
131  return;
132  }
133  }
134 
135  currentItem = mFrameItems.value( i );
136  currentHeight = currentItem->rect().height();
138  {
139  currentItem->setContentSection( QRectF( 0, 0, currentItem->rect().width(), currentHeight ) );
140  }
141  else
142  {
143  currentHeight = findNearbyPageBreak( currentY + currentHeight ) - currentY;
144  currentItem->setContentSection( QRectF( 0, currentY, currentItem->rect().width(), currentHeight ) );
145  }
146  currentItem->update();
147  currentY += currentHeight;
148  }
149 
150  //at end of frames but there is still content left. Add other pages if ResizeMode ==
151  if ( mLayout->pageCollection()->pageCount() > 0 && currentItem && mResizeMode != UseExistingFrames )
152  {
153  while ( ( mResizeMode == RepeatOnEveryPage ) || currentY < totalHeight )
154  {
155  //find out on which page the lower left point of the last frame is
156  int page = mLayout->pageCollection()->predictPageNumberForPoint( QPointF( 0, currentItem->pos().y() + currentItem->rect().height() ) ) + 1;
157 
159  {
160  if ( page >= mLayout->pageCollection()->pageCount() )
161  {
162  break;
163  }
164  }
165  else
166  {
167  //add new pages if required
168  for ( int p = mLayout->pageCollection()->pageCount() - 1 ; p < page; ++p )
169  {
170  mLayout->pageCollection()->extendByNewPage();
171  }
172  }
173 
174  double currentPageHeight = mLayout->pageCollection()->page( page )->rect().height();
175 
176  double frameHeight = 0;
177  switch ( mResizeMode )
178  {
179  case RepeatUntilFinished:
180  case RepeatOnEveryPage:
181  {
182  frameHeight = currentItem->rect().height();
183  break;
184  }
185  case ExtendToNextPage:
186  {
187  frameHeight = ( currentY + currentPageHeight ) > totalHeight ? totalHeight - currentY : currentPageHeight;
188  break;
189  }
190 
191  case UseExistingFrames:
192  break;
193  }
194 
195  double newFrameY = mLayout->pageCollection()->page( page )->pos().y();
197  {
198  newFrameY += currentItem->pagePos().y();
199  }
200 
201  //create new frame
202  QgsLayoutFrame *newFrame = createNewFrame( currentItem,
203  QPointF( currentItem->pos().x(), newFrameY ),
204  QSizeF( currentItem->rect().width(), frameHeight ) );
205 
207  {
208  newFrame->setContentSection( QRectF( 0, 0, newFrame->rect().width(), newFrame->rect().height() ) );
209  currentY += frameHeight;
210  }
211  else
212  {
213  double contentHeight = findNearbyPageBreak( currentY + newFrame->rect().height() ) - currentY;
214  newFrame->setContentSection( QRectF( 0, currentY, newFrame->rect().width(), contentHeight ) );
215  currentY += contentHeight;
216  }
217 
218  currentItem = newFrame;
219  }
220  }
221 
222  if ( mBlockUndoCommands )
223  mLayout->undoStack()->blockCommands( false );
224 }
225 
227 {
228  if ( mFrameItems.empty() )
229  {
230  //no frames, nothing to do
231  return;
232  }
233 
234  const QList< QgsLayoutFrame * > frames = mFrameItems;
235  for ( QgsLayoutFrame *frame : frames )
236  {
238  }
239 }
240 
242 {
243 
244 }
245 
246 QgsLayoutFrame *QgsLayoutMultiFrame::createNewFrame( QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size )
247 {
248  if ( !currentFrame )
249  {
250  return nullptr;
251  }
252 
253  QgsLayoutFrame *newFrame = new QgsLayoutFrame( mLayout, this );
254  newFrame->attemptSetSceneRect( QRectF( pos.x(), pos.y(), size.width(), size.height() ) );
255 
256  //copy some settings from the parent frame
257  newFrame->setBackgroundColor( currentFrame->backgroundColor() );
258  newFrame->setBackgroundEnabled( currentFrame->hasBackground() );
259  newFrame->setBlendMode( currentFrame->blendMode() );
260  newFrame->setFrameEnabled( currentFrame->frameEnabled() );
261  newFrame->setFrameStrokeColor( currentFrame->frameStrokeColor() );
262  newFrame->setFrameJoinStyle( currentFrame->frameJoinStyle() );
263  newFrame->setFrameStrokeWidth( currentFrame->frameStrokeWidth() );
264  newFrame->setItemOpacity( currentFrame->itemOpacity() );
265  newFrame->setHideBackgroundIfEmpty( currentFrame->hideBackgroundIfEmpty() );
266 
267  addFrame( newFrame, false );
268 
269  return newFrame;
270 }
271 
273 {
274  return tr( "<Multiframe>" );
275 }
276 
277 QgsAbstractLayoutUndoCommand *QgsLayoutMultiFrame::createCommand( const QString &text, int id, QUndoCommand *parent )
278 {
279  return new QgsLayoutMultiFrameUndoCommand( this, text, id, parent );
280 }
281 
282 void QgsLayoutMultiFrame::beginCommand( const QString &commandText, QgsLayoutMultiFrame::UndoCommand command )
283 {
284  if ( !mLayout )
285  return;
286 
287  mLayout->undoStack()->beginCommand( this, commandText, command );
288 }
289 
291 {
292  if ( mLayout )
293  mLayout->undoStack()->endCommand();
294 }
295 
297 {
298  if ( mLayout )
299  mLayout->undoStack()->cancelCommand();
300 }
301 
303 {
304  for ( int i = 0; i < mFrameUuids.count(); ++i )
305  {
306  QgsLayoutFrame *frame = nullptr;
307  const QString uuid = mFrameUuids.at( i );
308  if ( !uuid.isEmpty() )
309  {
310  QgsLayoutItem *item = mLayout->itemByUuid( uuid, true );
311  frame = qobject_cast< QgsLayoutFrame * >( item );
312  }
313  if ( !frame )
314  {
315  const QString templateUuid = mFrameTemplateUuids.at( i );
316  if ( !templateUuid.isEmpty() )
317  {
318  QgsLayoutItem *item = mLayout->itemByTemplateUuid( templateUuid );
319  frame = qobject_cast< QgsLayoutFrame * >( item );
320  }
321  }
322 
323  if ( frame )
324  {
325  addFrame( frame );
326  }
327  }
328 }
329 
331 {
334 }
335 
336 void QgsLayoutMultiFrame::handleFrameRemoval( QgsLayoutFrame *frame )
337 {
338  if ( mBlockUpdates )
339  return;
340 
341  if ( !frame )
342  {
343  return;
344  }
345  int index = mFrameItems.indexOf( frame );
346  if ( index == -1 )
347  {
348  return;
349  }
350 
351  mFrameItems.removeAt( index );
352  if ( !mFrameItems.isEmpty() )
353  {
354  if ( resizeMode() != QgsLayoutMultiFrame::RepeatOnEveryPage && !mIsRecalculatingSize )
355  {
356  //removing a frame forces the multi frame to UseExistingFrames resize mode
357  //otherwise the frame may not actually be removed, leading to confusing ui behavior
359  emit changed();
361  }
362  }
363 }
364 
365 void QgsLayoutMultiFrame::handlePageChange()
366 {
367  if ( mLayout->pageCollection()->pageCount() < 1 )
368  {
369  return;
370  }
371 
373  {
374  return;
375  }
376 
377  //remove items beginning on non-existing pages
378  for ( int i = mFrameItems.size() - 1; i >= 0; --i )
379  {
380  QgsLayoutFrame *frame = mFrameItems.at( i );
381  int page = mLayout->pageCollection()->predictPageNumberForPoint( frame->pos() );
382  if ( page >= mLayout->pageCollection()->pageCount() )
383  {
384  removeFrame( i );
385  }
386  }
387 
388  if ( !mFrameItems.empty() )
389  {
390  //page number of the last item
391  QgsLayoutFrame *lastFrame = mFrameItems.last();
392  int lastItemPage = mLayout->pageCollection()->predictPageNumberForPoint( lastFrame->pos() );
393 
394  for ( int i = lastItemPage + 1; i < mLayout->pageCollection()->pageCount(); ++i )
395  {
396  //copy last frame to current page
397  std::unique_ptr< QgsLayoutFrame > newFrame = qgis::make_unique< QgsLayoutFrame >( mLayout, this );
398 
399  newFrame->attemptSetSceneRect( QRectF( lastFrame->pos().x(),
400  mLayout->pageCollection()->page( i )->pos().y() + lastFrame->pagePos().y(),
401  lastFrame->rect().width(), lastFrame->rect().height() ) );
402  lastFrame = newFrame.get();
403  addFrame( newFrame.release(), false );
404  }
405  }
406 
408  update();
409 }
410 
411 void QgsLayoutMultiFrame::removeFrame( int i, const bool removeEmptyPages )
412 {
413  if ( i >= mFrameItems.count() )
414  {
415  return;
416  }
417 
418  QgsLayoutFrame *frameItem = mFrameItems.at( i );
419  if ( mLayout )
420  {
421  mIsRecalculatingSize = true;
422  int pageNumber = frameItem->page();
423  //remove item, but don't create undo command
424  mLayout->undoStack()->blockCommands( true );
425  mLayout->removeLayoutItem( frameItem );
426  //if frame was the only item on the page, remove the page
427  if ( removeEmptyPages && mLayout->pageCollection()->pageIsEmpty( pageNumber ) )
428  {
429  mLayout->pageCollection()->deletePage( pageNumber );
430  }
431  mLayout->undoStack()->blockCommands( false );
432  mIsRecalculatingSize = false;
433  }
434  mFrameItems.removeAt( i );
435 }
436 
438 {
439  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
440  {
441  frame->update();
442  }
443 }
444 
446 {
447  mBlockUpdates = true;
448  ResizeMode bkResizeMode = mResizeMode;
450  mLayout->undoStack()->blockCommands( true );
451  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
452  {
453  mLayout->removeLayoutItem( frame );
454  }
455  mLayout->undoStack()->blockCommands( false );
456  mFrameItems.clear();
457  mResizeMode = bkResizeMode;
458  mBlockUpdates = false;
459 }
460 
462 {
463  if ( i < 0 || i >= mFrameItems.size() )
464  {
465  return nullptr;
466  }
467  return mFrameItems.at( i );
468 }
469 
471 {
472  return mFrameItems.indexOf( frame );
473 }
474 
475 bool QgsLayoutMultiFrame::writeXml( QDomElement &parentElement, QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames ) const
476 {
477  QDomElement element = doc.createElement( QStringLiteral( "LayoutMultiFrame" ) );
478  element.setAttribute( QStringLiteral( "resizeMode" ), mResizeMode );
479  element.setAttribute( QStringLiteral( "uuid" ), mUuid );
480  element.setAttribute( QStringLiteral( "templateUuid" ), mUuid );
481  element.setAttribute( QStringLiteral( "type" ), type() );
482 
483  for ( QgsLayoutFrame *frame : mFrameItems )
484  {
485  if ( !frame )
486  continue;
487 
488  QDomElement childItem = doc.createElement( QStringLiteral( "childFrame" ) );
489  childItem.setAttribute( QStringLiteral( "uuid" ), frame->uuid() );
490  childItem.setAttribute( QStringLiteral( "templateUuid" ), frame->uuid() );
491 
492  if ( includeFrames )
493  {
494  frame->writeXml( childItem, doc, context );
495  }
496 
497  element.appendChild( childItem );
498  }
499 
500  writeObjectPropertiesToElement( element, doc, context );
501  writePropertiesToElement( element, doc, context );
502  parentElement.appendChild( element );
503  return true;
504 }
505 
506 bool QgsLayoutMultiFrame::readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames )
507 {
508  if ( element.nodeName() != QStringLiteral( "LayoutMultiFrame" ) )
509  {
510  return false;
511  }
512 
513  mBlockUndoCommands = true;
514  mLayout->undoStack()->blockCommands( true );
515 
516  readObjectPropertiesFromElement( element, doc, context );
517 
518  mUuid = element.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() );
519  mTemplateUuid = element.attribute( QStringLiteral( "templateUuid" ), QUuid::createUuid().toString() );
520  mResizeMode = static_cast< ResizeMode >( element.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() );
521 
522  deleteFrames();
523  mFrameUuids.clear();
524  mFrameTemplateUuids.clear();
525  QDomNodeList elementNodes = element.elementsByTagName( QStringLiteral( "childFrame" ) );
526  for ( int i = 0; i < elementNodes.count(); ++i )
527  {
528  QDomNode elementNode = elementNodes.at( i );
529  if ( !elementNode.isElement() )
530  continue;
531 
532  QDomElement frameElement = elementNode.toElement();
533 
534  QString uuid = frameElement.attribute( QStringLiteral( "uuid" ) );
535  mFrameUuids << uuid;
536  QString templateUuid = frameElement.attribute( QStringLiteral( "templateUuid" ) );
537  mFrameTemplateUuids << templateUuid;
538 
539  if ( includeFrames )
540  {
541  QDomNodeList frameNodes = frameElement.elementsByTagName( QStringLiteral( "LayoutItem" ) );
542  if ( !frameNodes.isEmpty() )
543  {
544  QDomElement frameItemElement = frameNodes.at( 0 ).toElement();
545  std::unique_ptr< QgsLayoutFrame > newFrame = qgis::make_unique< QgsLayoutFrame >( mLayout, this );
546  newFrame->readXml( frameItemElement, doc, context );
547  addFrame( newFrame.release(), false );
548  }
549  }
550  }
551 
552  bool result = readPropertiesFromElement( element, doc, context );
553 
554  mBlockUndoCommands = false;
555  mLayout->undoStack()->blockCommands( false );
556  return result;
557 }
558 
559 bool QgsLayoutMultiFrame::writePropertiesToElement( QDomElement &, QDomDocument &, const QgsReadWriteContext & ) const
560 {
561  return true;
562 }
563 
564 bool QgsLayoutMultiFrame::readPropertiesFromElement( const QDomElement &, const QDomDocument &, const QgsReadWriteContext & )
565 {
566 
567  return true;
568 }
569 
QgsLayoutMultiFrame(QgsLayout *layout)
Construct a new multiframe item, attached to the specified layout.
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.
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.
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.
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.
ResizeMode resizeMode() const
Returns the resize mode for the multiframe.
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.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores the item state in a DOM element.
double itemOpacity() const
Returns the item&#39;s opacity.
QPointF pagePos() const
Returns the item&#39;s position (in layout units) relative to the top left corner of its current page...
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...
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.
QgsLayoutMeasurement frameStrokeWidth() const
Returns the frame&#39;s stroke width.
bool hideBackgroundIfEmpty() const
Returns whether the background and frame stroke should be hidden if this frame is empty...
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.
void setBlendMode(QPainter::CompositionMode mode)
Sets the item&#39;s composition blending mode.
Repeats the same frame on every page.
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.
QPointer< QgsLayout > mLayout
Qt::PenJoinStyle frameJoinStyle() const
Returns the join style used for drawing the item&#39;s frame.
virtual QSizeF minFrameSize(int frameIndex=-1) const
Returns the minimum size for a frames, if desired.
virtual bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores multiframe state within an XML DOM element.
bool hasBackground() const
Returns true if the item has a background.
virtual QString uuid() const
Returns the item identification string.
void setHideBackgroundIfEmpty(bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
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
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false) const
Stores the multiframe state in a DOM element.
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.
virtual bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context)
Sets multiframe state from a DOM element.
int page() const
Returns the page the item is currently on, with the first page returning 0.
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.
void update()
Forces a redraw of all child frames.
virtual int type() const =0
Returns unique multiframe type id.
QColor backgroundColor() const
Returns the background color for this item.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
void removeFrame(int index, bool removeEmptyPages=false)
Removes a frame by index from the multiframe.
QPainter::CompositionMode blendMode() const
Returns the item&#39;s composition blending mode.
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
QString uuid() const
Returns the multiframe identification string.
A base class for objects which belong to a layout.
bool writeObjectPropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores object properties within an XML DOM element.
int frameIndex(QgsLayoutFrame *frame) const
Returns the index of a frame within the multiframe.
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.
QList< QgsLayoutFrame * > frames() const
Returns a list of all child frames for this multiframe.
virtual QString displayName() const
Returns the multiframe display name.
DataDefinedProperty
Data defined properties for different item types.
Base class for frame items, which form a layout multiframe item.
virtual QSizeF fixedFrameSize(int frameIndex=-1) const
Returns the fixed size for a frame, if desired.
bool frameEnabled() const
Returns true if the item includes a frame.
void setItemOpacity(double opacity)
Sets the item&#39;s opacity.
void cancelCommand()
Cancels the current item command and discards it.
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...
QColor frameStrokeColor() const
Returns the frame&#39;s stroke color.