QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgslayoutframe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutframe.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 "qgslayoutframe.h"
17 #include "qgslayoutmultiframe.h"
18 #include "qgslayoutitemregistry.h"
19 #include "qgslayout.h"
21 
23  : QgsLayoutItem( layout )
24  , mMultiFrame( multiFrame )
25  , mMultiFrameUuid( multiFrame ? multiFrame->uuid() : QString() )
26 {
27 
28  //default to no background
29  setBackgroundEnabled( false );
30 
31  if ( multiFrame )
32  {
33  //repaint frame when multiframe content changes
34  connect( multiFrame, &QgsLayoutMultiFrame::contentsChanged, this, [ = ]
35  {
36  update();
37  } );
38 
39  //force recalculation of rect, so that multiframe specified sizes can be applied
41  }
42 }
43 
45 {
46  return new QgsLayoutFrame( layout, nullptr );
47 }
48 
50 {
51  return mMultiFrame;
52 }
53 
55 {
56  if ( !mMultiFrame )
57  return QgsLayoutSize();
58 
59  //calculate index of frame
60  int frameIndex = mMultiFrame->frameIndex( const_cast< QgsLayoutFrame * >( this ) );
61  //check minimum size
62  return QgsLayoutSize( mMultiFrame->minFrameSize( frameIndex ), QgsUnitTypes::LayoutMillimeters );
63 }
64 
66 {
67  if ( !mMultiFrame )
68  return QgsLayoutSize();
69 
70  //calculate index of frame
71  int frameIndex = mMultiFrame->frameIndex( const_cast< QgsLayoutFrame * >( this ) );
72  //check fixed size
73  return QgsLayoutSize( mMultiFrame->fixedFrameSize( frameIndex ), QgsUnitTypes::LayoutMillimeters );
74 }
75 
77 {
79 }
80 
81 QIcon QgsLayoutFrame::icon() const
82 {
83  if ( mMultiFrame )
84  return mMultiFrame->icon();
85  else
86  return QIcon();
87 }
88 
89 void QgsLayoutFrame::setHidePageIfEmpty( const bool hidePageIfEmpty )
90 {
91  mHidePageIfEmpty = hidePageIfEmpty;
92 }
93 
94 void QgsLayoutFrame::setHideBackgroundIfEmpty( const bool hideBackgroundIfEmpty )
95 {
96  if ( hideBackgroundIfEmpty == mHideBackgroundIfEmpty )
97  {
98  return;
99  }
100 
101  mHideBackgroundIfEmpty = hideBackgroundIfEmpty;
102  update();
103 }
104 
106 {
107  if ( !mMultiFrame )
108  {
109  return true;
110  }
111 
112  double multiFrameHeight = mMultiFrame->totalSize().height();
113  if ( multiFrameHeight <= mSection.top() )
114  {
115  //multiframe height is less than top of this frame's visible portion
116  return true;
117  }
118 
119  return false;
120 
121 }
122 
124 {
125  if ( !mMultiFrame )
127 
128  //start with multiframe's context
129  QgsExpressionContext context = mMultiFrame->createExpressionContext();
130 
131  //add frame's individual context
133 
134  return context;
135 }
136 
138 {
140 }
141 
143 {
144  if ( !id().isEmpty() )
145  {
146  return id();
147  }
148 
149  if ( mMultiFrame )
150  {
151  return mMultiFrame->displayName();
152  }
153 
154  return tr( "<Frame>" );
155 }
156 
158 {
159  if ( mMultiFrame )
160  mMultiFrame->handleFrameRemoval( this );
161 
163 }
164 
166 {
167  if ( mMultiFrame )
168  {
169  //calculate index of frame
170  int frameIndex = mMultiFrame->frameIndex( this );
171  Q_ASSERT_X( frameIndex >= 0, "QgsLayoutFrame::draw", "Invalid frame index for frame" );
172  mMultiFrame->render( context, mSection, frameIndex );
173  }
174 }
175 
177 {
178  if ( !isEmpty() || !mHideBackgroundIfEmpty )
179  {
180  QgsLayoutItem::drawFrame( context );
181  }
182 }
183 
185 {
186  if ( !isEmpty() || !mHideBackgroundIfEmpty )
187  {
189  }
190 }
191 
192 bool QgsLayoutFrame::writePropertiesToElement( QDomElement &parentElement, QDomDocument &, const QgsReadWriteContext & ) const
193 {
194  parentElement.setAttribute( QStringLiteral( "multiFrame" ), mMultiFrameUuid );
195  parentElement.setAttribute( QStringLiteral( "multiFrameTemplateUuid" ), mMultiFrameUuid );
196  parentElement.setAttribute( QStringLiteral( "sectionX" ), QString::number( mSection.x() ) );
197  parentElement.setAttribute( QStringLiteral( "sectionY" ), QString::number( mSection.y() ) );
198  parentElement.setAttribute( QStringLiteral( "sectionWidth" ), QString::number( mSection.width() ) );
199  parentElement.setAttribute( QStringLiteral( "sectionHeight" ), QString::number( mSection.height() ) );
200  parentElement.setAttribute( QStringLiteral( "hidePageIfEmpty" ), mHidePageIfEmpty );
201  parentElement.setAttribute( QStringLiteral( "hideBackgroundIfEmpty" ), mHideBackgroundIfEmpty );
202  return true;
203 }
204 
205 bool QgsLayoutFrame::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext & )
206 {
207  double x = itemElem.attribute( QStringLiteral( "sectionX" ) ).toDouble();
208  double y = itemElem.attribute( QStringLiteral( "sectionY" ) ).toDouble();
209  double width = itemElem.attribute( QStringLiteral( "sectionWidth" ) ).toDouble();
210  double height = itemElem.attribute( QStringLiteral( "sectionHeight" ) ).toDouble();
211  mSection = QRectF( x, y, width, height );
212  mHidePageIfEmpty = itemElem.attribute( QStringLiteral( "hidePageIfEmpty" ), QStringLiteral( "0" ) ).toInt();
213  mHideBackgroundIfEmpty = itemElem.attribute( QStringLiteral( "hideBackgroundIfEmpty" ), QStringLiteral( "0" ) ).toInt();
214 
215  mMultiFrameUuid = itemElem.attribute( QStringLiteral( "multiFrame" ) );
216  if ( mMultiFrameUuid.isEmpty( ) )
217  {
218  mMultiFrameUuid = itemElem.attribute( QStringLiteral( "multiFrameTemplateUuid" ) );
219  }
220  mMultiFrame = mLayout->multiFrameByUuid( mMultiFrameUuid );
221  return true;
222 }
QgsLayoutItem::cleanup
virtual void cleanup()
Called just before a batch of items are deleted, allowing them to run cleanup tasks.
Definition: qgslayoutitem.cpp:99
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsLayoutItem::id
QString id() const
Returns the item's ID name.
Definition: qgslayoutitem.h:357
QgsLayoutObject::layout
const QgsLayout * layout() const
Returns the layout the object is attached to.
Definition: qgslayoutobject.cpp:126
qgsexpressioncontextutils.h
QgsLayoutMultiFrame::totalSize
virtual QSizeF totalSize() const =0
Returns the total size of the multiframe's content, in layout units.
QgsLayoutMultiFrame::createExpressionContext
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgslayoutmultiframe.cpp:283
QgsLayoutItem::refreshItemSize
void refreshItemSize()
Refreshes an item's size by rechecking it against any possible item fixed or minimum sizes.
Definition: qgslayoutitem.cpp:1268
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsLayoutFrame::setHideBackgroundIfEmpty
void setHideBackgroundIfEmpty(bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
Definition: qgslayoutframe.cpp:94
QgsLayoutFrame::hidePageIfEmpty
bool hidePageIfEmpty() const
Returns whether the page should be hidden (ie, not included in layout exports) if this frame is empty...
Definition: qgslayoutframe.h:83
QgsLayoutFrame::QgsLayoutFrame
QgsLayoutFrame(QgsLayout *layout, QgsLayoutMultiFrame *multiFrame)
Constructor for QgsLayoutFrame, with the specified parent layout and belonging to a multiFrame.
Definition: qgslayoutframe.cpp:22
QgsLayoutFrame::writePropertiesToElement
bool writePropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
Definition: qgslayoutframe.cpp:192
QgsLayoutItemRenderContext
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:45
qgslayoutmultiframe.h
QgsLayoutFrame::fixedSize
QgsLayoutSize fixedSize() const override
Returns the fixed size of the item, if applicable, or an empty size if item can be freely resized.
Definition: qgslayoutframe.cpp:65
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsExpressionContextUtils::layoutItemScope
static QgsExpressionContextScope * layoutItemScope(const QgsLayoutItem *item)
Creates a new scope which contains variables and functions relating to a QgsLayoutItem.
Definition: qgsexpressioncontextutils.cpp:619
QgsLayoutItem::drawFrame
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
Definition: qgslayoutitem.cpp:1220
QgsLayoutMultiFrame
Abstract base class for layout items with the ability to distribute the content to several frames (Qg...
Definition: qgslayoutmultiframe.h:49
QgsLayoutFrame::hideBackgroundIfEmpty
bool hideBackgroundIfEmpty() const
Returns whether the background and frame stroke should be hidden if this frame is empty.
Definition: qgslayoutframe.h:97
QgsLayoutFrame::isEmpty
bool isEmpty() const
Returns whether the frame is empty.
Definition: qgslayoutframe.cpp:105
QgsLayoutMultiFrame::icon
virtual QIcon icon() const
Returns the item's icon.
Definition: qgslayoutmultiframe.h:154
qgslayoutframe.h
QgsLayoutItem::drawBackground
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
Definition: qgslayoutitem.cpp:1236
QgsLayoutFrame::draw
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
Definition: qgslayoutframe.cpp:165
QgsLayoutItem::ExportLayerBehavior
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
Definition: qgslayoutitem.h:428
QgsLayoutFrame
Base class for frame items, which form a layout multiframe item.
Definition: qgslayoutframe.h:32
QgsLayoutFrame::setHidePageIfEmpty
void setHidePageIfEmpty(bool hidePageIfEmpty)
Sets whether the page should be hidden (ie, not included in layout exports) if this frame is empty.
Definition: qgslayoutframe.cpp:89
QgsLayoutFrame::type
int type() const override
Definition: qgslayoutframe.cpp:76
QgsLayoutFrame::createExpressionContext
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgslayoutframe.cpp:123
QgsLayoutItem::setBackgroundEnabled
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
Definition: qgslayoutitem.cpp:886
QgsLayoutFrame::create
static QgsLayoutFrame * create(QgsLayout *layout)
Creates a new QgsLayoutFrame belonging to the specified layout.
Definition: qgslayoutframe.cpp:44
QgsLayoutMultiFrame::minFrameSize
virtual QSizeF minFrameSize(int frameIndex=-1) const
Returns the minimum size for a frames, if desired.
Definition: qgslayoutmultiframe.cpp:45
QgsLayoutFrame::cleanup
void cleanup() override
Called just before a batch of items are deleted, allowing them to run cleanup tasks.
Definition: qgslayoutframe.cpp:157
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:113
QgsLayoutMultiFrame::contentsChanged
void contentsChanged()
Emitted when the contents of the multi frame have changed and the frames must be redrawn.
QgsLayoutMultiFrame::render
virtual void render(QgsLayoutItemRenderContext &context, const QRectF &renderExtent, int frameIndex)=0
Renders a portion of the multiframe's content into a render context.
qgslayout.h
QgsExpressionContext::appendScope
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Definition: qgsexpressioncontext.cpp:490
QgsLayoutFrame::drawFrame
void drawFrame(QgsRenderContext &context) override
Draws the frame around the item.
Definition: qgslayoutframe.cpp:176
QgsLayoutFrame::displayName
QString displayName() const override
Gets item display name.
Definition: qgslayoutframe.cpp:142
QgsLayoutObject::mLayout
QPointer< QgsLayout > mLayout
Definition: qgslayoutobject.h:343
QgsLayout
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
QgsLayoutFrame::minimumSize
QgsLayoutSize minimumSize() const override
Returns the minimum allowed size of the item, if applicable, or an empty size if item can be freely r...
Definition: qgslayoutframe.cpp:54
QgsLayoutFrame::drawBackground
void drawBackground(QgsRenderContext &context) override
Draws the background for the item.
Definition: qgslayoutframe.cpp:184
QgsLayoutMultiFrame::fixedFrameSize
virtual QSizeF fixedFrameSize(int frameIndex=-1) const
Returns the fixed size for a frame, if desired.
Definition: qgslayoutmultiframe.cpp:39
QgsLayoutSize
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:41
QgsLayoutFrame::readPropertiesFromElement
bool readPropertiesFromElement(const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
Definition: qgslayoutframe.cpp:205
QgsUnitTypes::LayoutMillimeters
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:182
QgsLayoutItemRegistry::LayoutFrame
@ LayoutFrame
Frame item, part of a QgsLayoutMultiFrame object.
Definition: qgslayoutitemregistry.h:325
QgsLayoutMultiFrame::frameIndex
int frameIndex(QgsLayoutFrame *frame) const
Returns the index of a frame within the multiframe.
Definition: qgslayoutmultiframe.cpp:478
qgslayoutitemregistry.h
QgsLayoutItem::CanGroupWithItemsOfSameType
@ CanGroupWithItemsOfSameType
Item can only be placed on layers with other items of the same type, but multiple items of this type ...
Definition: qgslayoutitem.h:430
QgsLayoutMultiFrame::displayName
virtual QString displayName() const
Returns the multiframe display name.
Definition: qgslayoutmultiframe.cpp:273
QgsLayoutItem::createExpressionContext
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgslayoutitem.cpp:1158
QgsLayoutFrame::exportLayerBehavior
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
Definition: qgslayoutframe.cpp:137
QgsLayoutFrame::multiFrame
QgsLayoutMultiFrame * multiFrame() const
Returns the parent multiframe for the frame.
Definition: qgslayoutframe.cpp:49
QgsLayoutFrame::icon
QIcon icon() const override
Returns the item's icon.
Definition: qgslayoutframe.cpp:81