QGIS API Documentation  2.12.0-Lyon
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 
25 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
26 
27 #ifndef M_DEG2RAD
28 #define M_DEG2RAD 0.0174532925
29 #endif
30 
32  : QObject( 0 )
33  , mComposition( composition )
34 {
35 
36  // data defined strings
37  mDataDefinedNames.insert( QgsComposerObject::TestProperty, QString( "dataDefinedTestProperty" ) );
38 
39  if ( mComposition )
40  {
41  //connect to atlas toggling on/off and coverage layer and feature changes
42  //to update data defined values
43  connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( refreshDataDefinedProperty() ) );
44  connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( refreshDataDefinedProperty() ) );
45  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshDataDefinedProperty() ) );
46  //also, refreshing composition triggers a recalculation of data defined properties
47  connect( mComposition, SIGNAL( refreshItemsTriggered() ), this, SLOT( refreshDataDefinedProperty() ) );
48 
49  //toggling atlas or changing coverage layer requires data defined expressions to be reprepared
50  connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( prepareDataDefinedExpressions() ) );
51  connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( prepareDataDefinedExpressions() ) );
52  }
53 
54 }
55 
57 {
58  qDeleteAll( mDataDefinedProperties );
59 }
60 
62 {
63  if ( elem.isNull() )
64  {
65  return false;
66  }
67 
68  //data defined properties
69  QgsComposerUtils::writeDataDefinedPropertyMap( elem, doc, &mDataDefinedNames, &mDataDefinedProperties );
70 
71  //custom properties
72  mCustomProperties.writeXml( elem, doc );
73 
74  return true;
75 }
76 
77 bool QgsComposerObject::readXML( const QDomElement &itemElem, const QDomDocument &doc )
78 {
79  Q_UNUSED( doc );
80  if ( itemElem.isNull() )
81  {
82  return false;
83  }
84 
85  //data defined properties
86  QgsComposerUtils::readDataDefinedPropertyMap( itemElem, &mDataDefinedNames, &mDataDefinedProperties );
87 
88  //custom properties
89  mCustomProperties.readXml( itemElem );
90 
91  return true;
92 }
93 
95 {
96  if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
97  {
98  //bad property requested, don't return anything
99  return 0;
100  }
101 
102  //find corresponding QgsDataDefined and return it
104  if ( it != mDataDefinedProperties.constEnd() )
105  {
106  return it.value();
107  }
108 
109  //could not find matching QgsDataDefined
110  return 0;
111 }
112 
113 void QgsComposerObject::setDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property, const bool active, const bool useExpression, const QString &expression, const QString &field )
114 {
115  if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
116  {
117  //bad property requested
118  return;
119  }
120 
121  bool defaultVals = ( !active && !useExpression && expression.isEmpty() && field.isEmpty() );
122 
123  if ( mDataDefinedProperties.contains( property ) )
124  {
126  if ( it != mDataDefinedProperties.constEnd() )
127  {
128  QgsDataDefined* dd = it.value();
129  dd->setActive( active );
130  dd->setExpressionString( expression );
131  dd->setField( field );
132  dd->setUseExpression( useExpression );
133  }
134  }
135  else if ( !defaultVals )
136  {
137  QgsDataDefined* dd = new QgsDataDefined( active, useExpression, expression, field );
138  mDataDefinedProperties.insert( property, dd );
139  }
140 }
141 
143 {
144  //nothing to do in base class for now
145 }
146 
148 {
149  Q_UNUSED( property );
150  Q_UNUSED( context );
151 
152  //nothing to do in base class for now
153 }
154 
155 bool QgsComposerObject::dataDefinedEvaluate( const DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext& context ) const
156 {
157  if ( !mComposition )
158  {
159  return false;
160  }
161  return mComposition->dataDefinedEvaluate( property, expressionValue, context, &mDataDefinedProperties );
162 }
163 
164 void QgsComposerObject::prepareDataDefinedExpressions() const
165 {
167 
168  //prepare all QgsDataDefineds
170  if ( it != mDataDefinedProperties.constEnd() )
171  {
172  it.value()->prepareExpression( *context.data() );
173  }
174 }
175 
176 void QgsComposerObject::setCustomProperty( const QString& key, const QVariant& value )
177 {
178  mCustomProperties.setValue( key, value );
179 }
180 
181 QVariant QgsComposerObject::customProperty( const QString& key, const QVariant& defaultValue ) const
182 {
183  return mCustomProperties.value( key, defaultValue );
184 }
185 
187 {
188  mCustomProperties.remove( key );
189 }
190 
192 {
193  return mCustomProperties.keys();
194 }
195 
197 {
198  QgsExpressionContext* context = 0;
199  if ( mComposition )
200  {
202  }
203  else
204  {
205  context = new QgsExpressionContext();
208  }
209  return context;
210 }
void setActive(bool active)
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores item state in DOM element.
A container class for data source field mapping or expression.
bool contains(const Key &key) const
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...
DataDefinedProperty
Data defined properties for different item types.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:176
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.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
void remove(const QString &key)
Remove a key (entry) from the store.
QgsComposerObject(QgsComposition *composition)
Constructor.
QgsDataDefined * dataDefinedProperty(const DataDefinedProperty property) const
Returns a reference to the data defined settings for one of the item's data defined properties...
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.
void setUseExpression(bool use)
Controls if the field or the expression part is active.
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects's current state.
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...
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...
QStringList keys() const
Return list of stored keys.
bool isEmpty() const
const_iterator constEnd() const
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.
Graphics scene for map printing.
QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the compositions's current state.
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext &context=QgsExpressionContext()) const
Evaluate a data defined property and return the calculated value.
bool isNull() const
QgsComposition * mComposition
void writeXml(QDomNode &parentNode, QDomDocument &doc) const
Write store contents to XML.
virtual void refreshDataDefinedProperty(const DataDefinedProperty property=AllProperties, const QgsExpressionContext *context=0)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
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.
QStringList customProperties() const
Return list of keys stored in custom properties for the object.
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.
iterator find(const Key &key)
const T value(const Key &key) const