QGIS API Documentation  2.17.0-Master (0497e4a)
qgscomposerobject.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerobject.cpp
3  -------------------
4  begin : July 2014
5  copyright : (C) 2014 by Nyall Dawson,Radim Blazek
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 "qgscomposition.h"
21 #include "qgscomposerutils.h"
22 #include "qgscomposerobject.h"
23 #include "qgsdatadefined.h"
24 
26  : QObject( nullptr )
27  , mComposition( composition )
28 {
29 
30  // data defined strings
31  mDataDefinedNames.insert( QgsComposerObject::TestProperty, QString( "dataDefinedTestProperty" ) );
32 
33  if ( mComposition )
34  {
35  //connect to atlas toggling on/off and coverage layer and feature changes
36  //to update data defined values
37  connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( refreshDataDefinedProperty() ) );
38  connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( refreshDataDefinedProperty() ) );
39  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshDataDefinedProperty() ) );
40  //also, refreshing composition triggers a recalculation of data defined properties
41  connect( mComposition, SIGNAL( refreshItemsTriggered() ), this, SLOT( refreshDataDefinedProperty() ) );
42 
43  //toggling atlas or changing coverage layer requires data defined expressions to be reprepared
44  connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( prepareDataDefinedExpressions() ) );
45  connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( prepareDataDefinedExpressions() ) );
46  }
47 
48 }
49 
51 {
52  qDeleteAll( mDataDefinedProperties );
53 }
54 
56 {
57  if ( elem.isNull() )
58  {
59  return false;
60  }
61 
62  //data defined properties
63  QgsComposerUtils::writeDataDefinedPropertyMap( elem, doc, &mDataDefinedNames, &mDataDefinedProperties );
64 
65  //custom properties
66  mCustomProperties.writeXml( elem, doc );
67 
68  return true;
69 }
70 
71 bool QgsComposerObject::readXML( const QDomElement &itemElem, const QDomDocument &doc )
72 {
73  Q_UNUSED( doc );
74  if ( itemElem.isNull() )
75  {
76  return false;
77  }
78 
79  //data defined properties
80  QgsComposerUtils::readDataDefinedPropertyMap( itemElem, &mDataDefinedNames, &mDataDefinedProperties );
81 
82  //custom properties
83  mCustomProperties.readXml( itemElem );
84 
85  return true;
86 }
87 
89 {
90  if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
91  {
92  //bad property requested, don't return anything
93  return nullptr;
94  }
95 
96  //find corresponding QgsDataDefined and return it
98  if ( it != mDataDefinedProperties.constEnd() )
99  {
100  return it.value();
101  }
102 
103  //could not find matching QgsDataDefined
104  return nullptr;
105 }
106 
107 void QgsComposerObject::setDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property, const bool active, const bool useExpression, const QString &expression, const QString &field )
108 {
109  if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
110  {
111  //bad property requested
112  return;
113  }
114 
115  bool defaultVals = ( !active && !useExpression && expression.isEmpty() && field.isEmpty() );
116 
117  if ( mDataDefinedProperties.contains( property ) )
118  {
120  if ( it != mDataDefinedProperties.constEnd() )
121  {
122  QgsDataDefined* dd = it.value();
123  dd->setActive( active );
124  dd->setExpressionString( expression );
125  dd->setField( field );
126  dd->setUseExpression( useExpression );
127  }
128  }
129  else if ( !defaultVals )
130  {
131  QgsDataDefined* dd = new QgsDataDefined( active, useExpression, expression, field );
132  mDataDefinedProperties.insert( property, dd );
133  }
134 }
135 
137 {
138  //nothing to do in base class for now
139 }
140 
142 {
143  Q_UNUSED( property );
144  Q_UNUSED( context );
145 
146  //nothing to do in base class for now
147 }
148 
150 {
151  if ( !mComposition )
152  {
153  return false;
154  }
155  return mComposition->dataDefinedEvaluate( property, expressionValue, context, &mDataDefinedProperties );
156 }
157 
158 void QgsComposerObject::prepareDataDefinedExpressions() const
159 {
161 
162  //prepare all QgsDataDefineds
164  if ( it != mDataDefinedProperties.constEnd() )
165  {
166  it.value()->prepareExpression( *context.data() );
167  }
168 }
169 
170 void QgsComposerObject::setCustomProperty( const QString& key, const QVariant& value )
171 {
172  mCustomProperties.setValue( key, value );
173 }
174 
175 QVariant QgsComposerObject::customProperty( const QString& key, const QVariant& defaultValue ) const
176 {
177  return mCustomProperties.value( key, defaultValue );
178 }
179 
181 {
182  mCustomProperties.remove( key );
183 }
184 
186 {
187  return mCustomProperties.keys();
188 }
189 
191 {
192  QgsExpressionContext* context = nullptr;
193  if ( mComposition )
194  {
196  }
197  else
198  {
199  context = new QgsExpressionContext();
202  }
203  return context;
204 }
void setActive(bool active)
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
A container class for data source field mapping or expression.
bool contains(const Key &key) const
QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the compositions&#39;s current state.
QStringList customProperties() const
Return list of keys stored in custom properties for the object.
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from XML.
QgsObjectCustomProperties mCustomProperties
Custom properties for object.
const_iterator constBegin() const
static void readDataDefinedPropertyMap(const QDomElement &itemElem, QMap< QgsComposerObject::DataDefinedProperty, QString > *dataDefinedNames, QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined * > *dataDefinedProperties)
Reads all data defined properties from xml.
QMap< QgsComposerObject::DataDefinedProperty, QString > mDataDefinedNames
Map of data defined properties for the item to string name to use when exporting item to xml...
virtual void refreshDataDefinedProperty(const DataDefinedProperty property=AllProperties, const QgsExpressionContext *context=nullptr)
Refreshes a data defined property for the item by reevaluating the property&#39;s value and redrawing the...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Return value for the given key. If the key is not stored, default value will be used.
const_iterator constFind(const Key &key) const
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores item state in DOM element.
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Write store contents to XML.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
static void writeDataDefinedPropertyMap(QDomElement &itemElem, QDomDocument &doc, const QMap< QgsComposerObject::DataDefinedProperty, QString > *dataDefinedNames, const QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined * > *dataDefinedProperties)
Writes data defined properties to xml.
void remove(const QString &key)
Remove a key (entry) from the store.
DataDefinedProperty
Data defined properties for different item types.
QgsComposerObject(QgsComposition *composition)
Constructor.
void setUseExpression(bool use)
Controls if the field or the expression part is active.
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...
QVariant property(const char *name) const
void setField(const QString &field)
Set the field name which this QgsDataDefined represents.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
const_iterator constEnd() const
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext &context=QgsExpressionContext()) const
Evaluate a data defined property and return the calculated value.
void removeCustomProperty(const QString &key)
Remove a custom property from the object.
const T & value() const
virtual void repaint()
Triggers a redraw for the item.
QStringList keys() const
Return list of stored keys.
Graphics scene for map printing.
T * data() const
bool isNull() const
QgsDataDefined * dataDefinedProperty(const DataDefinedProperty property) const
Returns a reference to the data defined settings for one of the item&#39;s data defined properties...
QgsComposition * mComposition
virtual bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
Sets item state from DOM element.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the object.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setDataDefinedProperty(const DataDefinedProperty property, const bool active, const bool useExpression, const QString &expression, const QString &field)
Sets parameters for a data defined property for the item.
QgsAtlasComposition & atlasComposition()
iterator insert(const Key &key, const T &value)
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
void setExpressionString(const QString &expr)
Sets the expression for this QgsDataDefined.
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects&#39; current state.