QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgslayoutobject.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutobject.cpp
3  -------------------
4  begin : June 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <QPainter>
19 
20 #include "qgslayout.h"
21 #include "qgslayoutrendercontext.h"
22 #include "qgslayoutreportcontext.h"
23 #include "qgslayoutobject.h"
24 #include "qgsfeedback.h"
26 
27 
28 QgsPropertiesDefinition QgsLayoutObject::sPropertyDefinitions;
29 
30 void QgsLayoutObject::initPropertyDefinitions()
31 {
32  if ( !sPropertyDefinitions.isEmpty() )
33  return;
34 
35  sPropertyDefinitions = QgsPropertiesDefinition
36  {
37  { QgsLayoutObject::TestProperty, QgsPropertyDefinition( "dataDefinedProperty", QgsPropertyDefinition::DataTypeString, "invalid property", QString() ) },
38  {
39  QgsLayoutObject::PresetPaperSize, QgsPropertyDefinition( "dataDefinedPaperSize", QgsPropertyDefinition::DataTypeString, QObject::tr( "Paper size" ), QObject::tr( "string " ) + QLatin1String( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
40  "|<b>B5</b>|<b>B4</b>|<b>B3</b>|<b>B2</b>|<b>B1</b>|<b>B0</b>"
41  "|<b>Legal</b>|<b>Ansi A</b>|<b>Ansi B</b>|<b>Ansi C</b>|<b>Ansi D</b>|<b>Ansi E</b>"
42  "|<b>Arch A</b>|<b>Arch B</b>|<b>Arch C</b>|<b>Arch D</b>|<b>Arch E</b>|<b>Arch E1</b>]"
43  ) )
44  },
45  { QgsLayoutObject::PaperWidth, QgsPropertyDefinition( "dataDefinedPaperWidth", QObject::tr( "Page width" ), QgsPropertyDefinition::DoublePositive ) },
46  { QgsLayoutObject::PaperHeight, QgsPropertyDefinition( "dataDefinedPaperHeight", QObject::tr( "Page height" ), QgsPropertyDefinition::DoublePositive ) },
47  { QgsLayoutObject::NumPages, QgsPropertyDefinition( "dataDefinedNumPages", QObject::tr( "Number of pages" ), QgsPropertyDefinition::IntegerPositive ) },
48  { QgsLayoutObject::PaperOrientation, QgsPropertyDefinition( "dataDefinedPaperOrientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "string " ) + QLatin1String( "[<b>portrait</b>|<b>landscape</b>]" ) ) },
49  { QgsLayoutObject::PageNumber, QgsPropertyDefinition( "dataDefinedPageNumber", QObject::tr( "Page number" ), QgsPropertyDefinition::IntegerPositive ) },
50  { QgsLayoutObject::PositionX, QgsPropertyDefinition( "dataDefinedPositionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double ) },
51  { QgsLayoutObject::PositionY, QgsPropertyDefinition( "dataDefinedPositionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double ) },
52  { QgsLayoutObject::ItemWidth, QgsPropertyDefinition( "dataDefinedWidth", QObject::tr( "Width" ), QgsPropertyDefinition::DoublePositive ) },
53  { QgsLayoutObject::ItemHeight, QgsPropertyDefinition( "dataDefinedHeight", QObject::tr( "Height" ), QgsPropertyDefinition::DoublePositive ) },
54  { QgsLayoutObject::ItemRotation, QgsPropertyDefinition( "dataDefinedRotation", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation ) },
55  { QgsLayoutObject::Transparency, QgsPropertyDefinition( "dataDefinedTransparency", QObject::tr( "Transparency" ), QgsPropertyDefinition::Opacity ) },
56  { QgsLayoutObject::Opacity, QgsPropertyDefinition( "dataDefinedOpacity", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity ) },
57  { QgsLayoutObject::BlendMode, QgsPropertyDefinition( "dataDefinedBlendMode", QObject::tr( "Blend mode" ), QgsPropertyDefinition::BlendMode ) },
58  { QgsLayoutObject::ExcludeFromExports, QgsPropertyDefinition( "dataDefinedExcludeExports", QObject::tr( "Exclude item from exports" ), QgsPropertyDefinition::Boolean ) },
59  { QgsLayoutObject::FrameColor, QgsPropertyDefinition( "dataDefinedFrameColor", QObject::tr( "Frame color" ), QgsPropertyDefinition::ColorWithAlpha ) },
60  { QgsLayoutObject::BackgroundColor, QgsPropertyDefinition( "dataDefinedBackgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha ) },
61  { QgsLayoutObject::MapRotation, QgsPropertyDefinition( "dataDefinedMapRotation", QObject::tr( "Map rotation" ), QgsPropertyDefinition::Rotation ) },
62  { QgsLayoutObject::MapScale, QgsPropertyDefinition( "dataDefinedMapScale", QObject::tr( "Map scale" ), QgsPropertyDefinition::DoublePositive ) },
63  { QgsLayoutObject::MapXMin, QgsPropertyDefinition( "dataDefinedMapXMin", QObject::tr( "Extent minimum X" ), QgsPropertyDefinition::Double ) },
64  { QgsLayoutObject::MapYMin, QgsPropertyDefinition( "dataDefinedMapYMin", QObject::tr( "Extent minimum Y" ), QgsPropertyDefinition::Double ) },
65  { QgsLayoutObject::MapXMax, QgsPropertyDefinition( "dataDefinedMapXMax", QObject::tr( "Extent maximum X" ), QgsPropertyDefinition::Double ) },
66  { QgsLayoutObject::MapYMax, QgsPropertyDefinition( "dataDefinedMapYMax", QObject::tr( "Extent maximum Y" ), QgsPropertyDefinition::Double ) },
67  { QgsLayoutObject::MapLabelMargin, QgsPropertyDefinition( "dataDefinedMapLabelMargin", QObject::tr( "Label margin" ), QgsPropertyDefinition::DoublePositive ) },
68  { QgsLayoutObject::MapAtlasMargin, QgsPropertyDefinition( "dataDefinedMapAtlasMargin", QObject::tr( "Atlas margin" ), QgsPropertyDefinition::DoublePositive ) },
69  { QgsLayoutObject::MapLayers, QgsPropertyDefinition( "dataDefinedMapLayers", QgsPropertyDefinition::DataTypeString, QObject::tr( "Map Layers" ), tr( "list of map layer names separated by | characters" ) ) },
70  { QgsLayoutObject::MapStylePreset, QgsPropertyDefinition( "dataDefinedMapStylePreset", QgsPropertyDefinition::DataTypeString, QObject::tr( "Map theme" ), tr( "name of an existing map theme (case-sensitive)" ) ) },
71  { QgsLayoutObject::MapGridEnabled, QgsPropertyDefinition( "dataDefinedMapGridEnabled", QObject::tr( "Grid enabled" ), QgsPropertyDefinition::Boolean ) },
72  { QgsLayoutObject::MapGridIntervalX, QgsPropertyDefinition( "dataDefinedMapGridIntervalX", QObject::tr( "Grid interval X" ), QgsPropertyDefinition::DoublePositive ) },
73  { QgsLayoutObject::MapGridIntervalY, QgsPropertyDefinition( "dataDefinedMapGridIntervalY", QObject::tr( "Grid interval Y" ), QgsPropertyDefinition::DoublePositive ) },
74  { QgsLayoutObject::MapGridOffsetX, QgsPropertyDefinition( "dataDefinedMapGridOffsetX", QObject::tr( "Grid offset X" ), QgsPropertyDefinition::Double ) },
75  { QgsLayoutObject::MapGridOffsetY, QgsPropertyDefinition( "dataDefinedMapGridOffsetY", QObject::tr( "Grid offset Y" ), QgsPropertyDefinition::Double ) },
76  { QgsLayoutObject::MapGridFrameSize, QgsPropertyDefinition( "dataDefinedMapGridFrameSize", QObject::tr( "Grid frame size" ), QgsPropertyDefinition::DoublePositive ) },
77  { QgsLayoutObject::MapGridFrameLineThickness, QgsPropertyDefinition( "dataDefinedMapGridFrameLineThickness", QObject::tr( "Grid frame line thickness" ), QgsPropertyDefinition::DoublePositive ) },
78  { QgsLayoutObject::MapGridCrossSize, QgsPropertyDefinition( "dataDefinedMapGridCrossSize", QObject::tr( "Grid cross size" ), QgsPropertyDefinition::DoublePositive ) },
79  { QgsLayoutObject::MapGridFrameMargin, QgsPropertyDefinition( "dataDefinedMapGridFrameMargin", QObject::tr( "Grid frame margin" ), QgsPropertyDefinition::DoublePositive ) },
80  { QgsLayoutObject::MapGridLabelDistance, QgsPropertyDefinition( "dataDefinedMapGridLabelDistance", QObject::tr( "Grid label distance" ), QgsPropertyDefinition::DoublePositive ) },
81  { QgsLayoutObject::PictureSource, QgsPropertyDefinition( "dataDefinedSource", QObject::tr( "Picture source (URL)" ), QgsPropertyDefinition::String ) },
82  { QgsLayoutObject::SourceUrl, QgsPropertyDefinition( "dataDefinedSourceUrl", QObject::tr( "Source URL" ), QgsPropertyDefinition::String ) },
83  { QgsLayoutObject::PictureSvgBackgroundColor, QgsPropertyDefinition( "dataDefinedSvgBackgroundColor", QObject::tr( "SVG background color" ), QgsPropertyDefinition::ColorWithAlpha ) },
84  { QgsLayoutObject::PictureSvgStrokeColor, QgsPropertyDefinition( "dataDefinedSvgStrokeColor", QObject::tr( "SVG stroke color" ), QgsPropertyDefinition::ColorWithAlpha ) },
85  { QgsLayoutObject::PictureSvgStrokeWidth, QgsPropertyDefinition( "dataDefinedSvgStrokeWidth", QObject::tr( "SVG stroke width" ), QgsPropertyDefinition::StrokeWidth ) },
86  { QgsLayoutObject::LegendTitle, QgsPropertyDefinition( "dataDefinedLegendTitle", QObject::tr( "Legend title" ), QgsPropertyDefinition::String ) },
87  { QgsLayoutObject::LegendColumnCount, QgsPropertyDefinition( "dataDefinedLegendColumns", QObject::tr( "Number of columns" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) },
88  { QgsLayoutObject::ScalebarFillColor, QgsPropertyDefinition( "dataDefinedScalebarFill", QObject::tr( "Fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
89  { QgsLayoutObject::ScalebarFillColor2, QgsPropertyDefinition( "dataDefinedScalebarFill2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
90  { QgsLayoutObject::ScalebarLineColor, QgsPropertyDefinition( "dataDefinedScalebarLineColor", QObject::tr( "Line color" ), QgsPropertyDefinition::ColorWithAlpha ) },
91  { QgsLayoutObject::ScalebarLineWidth, QgsPropertyDefinition( "dataDefinedScalebarLineWidth", QObject::tr( "Line width" ), QgsPropertyDefinition::StrokeWidth ) },
92  { QgsLayoutObject::AttributeTableSourceLayer, QgsPropertyDefinition( "dataDefinedAttributeTableSourceLayer", QObject::tr( "Table source layer" ), QgsPropertyDefinition::String ) },
93  };
94 }
95 
97 {
98  QgsLayoutObject::initPropertyDefinitions();
99  return sPropertyDefinitions;
100 }
101 
103  : QObject( nullptr )
104  , mLayout( layout )
105 {
106  initPropertyDefinitions();
107 
108  if ( mLayout )
109  {
111  connect( &mLayout->reportContext(), &QgsLayoutReportContext::changed, this, &QgsLayoutObject::refresh );
112  }
113 }
114 
116 {
117  return mLayout.data();
118 }
119 
121 {
122  return mLayout.data();
123 }
124 
125 void QgsLayoutObject::setCustomProperty( const QString &key, const QVariant &value )
126 {
127  mCustomProperties.setValue( key, value );
128 }
129 
130 QVariant QgsLayoutObject::customProperty( const QString &key, const QVariant &defaultValue ) const
131 {
132  return mCustomProperties.value( key, defaultValue );
133 }
134 
135 void QgsLayoutObject::removeCustomProperty( const QString &key )
136 {
137  mCustomProperties.remove( key );
138 }
139 
141 {
142  return mCustomProperties.keys();
143 }
144 
146 {
147  if ( mLayout )
148  {
149  return mLayout->createExpressionContext();
150  }
151  else
152  {
154  }
155 }
156 
157 bool QgsLayoutObject::writeObjectPropertiesToElement( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & ) const
158 {
159  if ( parentElement.isNull() )
160  {
161  return false;
162  }
163 
164  //create object element
165  QDomElement objectElement = document.createElement( QStringLiteral( "LayoutObject" ) );
166 
167  QDomElement ddPropsElement = document.createElement( QStringLiteral( "dataDefinedProperties" ) );
168  mDataDefinedProperties.writeXml( ddPropsElement, sPropertyDefinitions );
169  objectElement.appendChild( ddPropsElement );
170 
171  //custom properties
172  mCustomProperties.writeXml( objectElement, document );
173 
174  parentElement.appendChild( objectElement );
175  return true;
176 }
177 
178 bool QgsLayoutObject::readObjectPropertiesFromElement( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext & )
179 {
180  Q_UNUSED( document )
181  if ( parentElement.isNull() )
182  {
183  return false;
184  }
185 
186  QDomNodeList objectNodeList = parentElement.elementsByTagName( QStringLiteral( "LayoutObject" ) );
187  if ( objectNodeList.size() < 1 )
188  {
189  return false;
190  }
191  QDomElement objectElement = objectNodeList.at( 0 ).toElement();
192 
193  QDomNode propsNode = objectElement.namedItem( QStringLiteral( "dataDefinedProperties" ) );
194  if ( !propsNode.isNull() )
195  {
196  mDataDefinedProperties.readXml( propsNode.toElement(), sPropertyDefinitions );
197  }
198 
199  //custom properties
200  mCustomProperties.readXml( objectElement );
201 
202  return true;
203 }
The class is used as a container of context for various read/write operations on other objects...
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects&#39; current state.
Positive integer values (including 0)
Definition: qgsproperty.h:55
bool readObjectPropertiesFromElement(const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context)
Sets object properties from a DOM element.
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from XML.
Paper width (deprecated)
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
Layer and style map theme.
QgsObjectCustomProperties mCustomProperties
Custom properties for object.
Exclude item from exports.
void changed()
Emitted certain settings in the context is changed, e.g.
Y position on page.
Non-zero positive integer values.
Definition: qgsproperty.h:56
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the object.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns value for the given key. If the key is not stored, default value will be used.
Color with alpha channel.
Definition: qgsproperty.h:64
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Write store contents to XML.
Positive double value (including 0)
Definition: qgsproperty.h:58
void remove(const QString &key)
Remove a key (entry) from the store.
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:60
Map extent x minimum.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the layout object property definitions.
Any string value.
Definition: qgsproperty.h:61
Dummy property with no effect on item.
Number of pages in composition (deprecated)
Attribute table source layer.
Map grid frame line thickness.
QStringList customProperties() const
Returns list of keys stored in custom properties for the object.
X position on page.
void setValue(const QString &key, const QVariant &value)
Add an entry to the store. If the entry with the keys exists already, it will be overwritten.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
Scalebar secondary fill color.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
Map extent x maximum.
Item transparency (deprecated)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QPointer< QgsLayout > mLayout
Page number for item placement.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
QStringList keys() const
Returns list of stored keys.
Double value (including negative values)
Definition: qgsproperty.h:57
Definition for a property.
Definition: qgsproperty.h:46
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
Map extent y maximum.
bool writeObjectPropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores object properties within an XML DOM element.
void removeCustomProperty(const QString &key)
Remove a custom property from the object.
Property requires a string value.
Definition: qgsproperty.h:91
Map extent y minimum.
void refreshed()
Emitted when the layout has been refreshed and items should also be refreshed and updated...
Preset paper size for composition.
Paper height (deprecated)
QgsLayoutObject(QgsLayout *layout)
Constructor for QgsLayoutObject, with the specified parent layout.
virtual void refresh()
Refreshes the object, causing a recalculation of any property overrides.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.