Skip to content

Commit be5aeac

Browse files
committedJul 5, 2014
[composer] Initial framework for data defined properties in compositions and composer items. Funded by Canton of Neuchâtel, Switzerland
1 parent 51408e1 commit be5aeac

File tree

8 files changed

+794
-11
lines changed

8 files changed

+794
-11
lines changed
 

‎python/core/composer/qgscomposeritem.sip

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,36 @@ class QgsComposerItem : QObject, QGraphicsRectItem
133133
LowerRight
134134
};
135135

136+
/** Data defined properties for different item types
137+
*/
138+
enum DataDefinedProperty
139+
{
140+
NoProperty = 0, /*< no property */
141+
AllProperties, /*< all properties for item */
142+
//composer page properties
143+
PresetPaperSize, /*< preset paper size for composition */
144+
PaperWidth, /*< paper width */
145+
PaperHeight, /*< paper height */
146+
NumPages, /*< number of pages in composition */
147+
PaperOrientation, /*< paper orientation */
148+
//general composer item properties
149+
PageNumber, /*< page number for item placement */
150+
PositionX, /*< x position on page */
151+
PositionY, /*< y position on page */
152+
ItemWidth, /*< width of item */
153+
ItemHeight, /*< height of item */
154+
ItemRotation, /*< rotation of item */
155+
Transparency, /*< item transparency */
156+
BlendMode, /*< item blend mode */
157+
//composer map
158+
MapRotation, /*< map rotation */
159+
MapScale, /*< map scale */
160+
MapXMin, /*< map extent x minimum */
161+
MapYMin, /*< map extent y minimum */
162+
MapXMax, /*< map extent x maximum */
163+
MapYMax /*< map extent y maximum */
164+
};
165+
136166
/**Constructor
137167
@param composition parent composition
138168
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
@@ -481,22 +511,47 @@ class QgsComposerItem : QObject, QGraphicsRectItem
481511
*/
482512
void setCurrentExportLayer( int layerIdx = -1 );
483513

514+
/**Returns a reference to the data defined settings for one of the item's data defined properties.
515+
* @param property data defined property to return
516+
* @note this method was added in version 2.5
517+
*/
518+
QgsDataDefined* dataDefinedProperty( DataDefinedProperty property );
519+
520+
/**Sets parameters for a data defined property for the item
521+
* @param property data defined property to set
522+
* @param active true if data defined property is active, false if it is disabled
523+
* @param useExpression true if the expression should be used
524+
* @param expression expression for data defined property
525+
* @field field name if the data defined property should take its value from a field
526+
* @note this method was added in version 2.5
527+
*/
528+
void setDataDefinedProperty( DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
529+
484530
public slots:
485531
/**Sets the item rotation
486532
* @deprecated Use setItemRotation( double rotation ) instead
487533
*/
488534
virtual void setRotation( double r );
489535

490536
/**Sets the item rotation
491-
@param r item rotation in degrees
492-
@param adjustPosition set to true if item should be shifted so that rotation occurs
493-
around item center. If false, rotation occurs around item origin
494-
@note this method was added in version 2.1
537+
* @param r item rotation in degrees
538+
* @param adjustPosition set to true if item should be shifted so that rotation occurs
539+
* around item center. If false, rotation occurs around item origin
540+
* @note this method was added in version 2.1
495541
*/
496542
virtual void setItemRotation( double r, bool adjustPosition = false );
497543

498544
void repaint();
499545

546+
/**Refreshes a data defined property for the item by reevaluating the property's value
547+
* and redrawing the item with this new value.
548+
* @param property data defined property to refresh. If property is set to
549+
* QgsComposerItem::AllProperties then all data defined properties for the item will be
550+
* refreshed.
551+
* @note this method was added in version 2.5
552+
*/
553+
virtual void refreshDataDefinedProperty( DataDefinedProperty property = AllProperties );
554+
500555
protected:
501556

502557
//event handlers
@@ -582,6 +637,14 @@ class QgsComposerItem : QObject, QGraphicsRectItem
582637
void deleteVAlignSnapItem();
583638
void deleteAlignItems();
584639

640+
/**Evaluate a data defined property and return the calculated value
641+
* @returns true if data defined property could be successfully evaluated
642+
* @param property data defined property to evaluate
643+
* @param expressionValue QVariant for storing the evaluated value
644+
* @note this method was added in version 2.5
645+
*/
646+
bool dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue );
647+
585648
signals:
586649
/**Is emitted on item rotation change*/
587650
void itemRotationChanged( double newRotation );

‎python/core/composer/qgscomposition.sip

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,22 @@ class QgsComposition : QGraphicsScene
444444
@note added in version 2.4*/
445445
QList< QgsPaperItem* > pages();
446446

447+
/**Returns a reference to the data defined settings for one of the composition's data defined properties.
448+
* @param property data defined property to return
449+
* @note this method was added in version 2.5
450+
*/
451+
QgsDataDefined* dataDefinedProperty( QgsComposerItem::DataDefinedProperty property );
452+
453+
/**Sets parameters for a data defined property for the composition
454+
* @param property data defined property to set
455+
* @param active true if data defined property is active, false if it is disabled
456+
* @param useExpression true if the expression should be used
457+
* @param expression expression for data defined property
458+
* @field field name if the data defined property should take its value from a field
459+
* @note this method was added in version 2.5
460+
*/
461+
void setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
462+
447463
public slots:
448464
/**Casts object to the proper subclass type and calls corresponding itemAdded signal*/
449465
void sendItemAddedSignal( QgsComposerItem* item );
@@ -463,6 +479,15 @@ class QgsComposition : QGraphicsScene
463479
* @note added in version 2.3*/
464480
void setSelectedItem( QgsComposerItem* item );
465481

482+
/**Refreshes a data defined property for the composition by reevaluating the property's value
483+
* and redrawing the composition with this new value.
484+
* @param property data defined property to refresh. If property is set to
485+
* QgsComposerItem::AllProperties then all data defined properties for the composition will be
486+
* refreshed.
487+
* @note this method was added in version 2.5
488+
*/
489+
void refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property = QgsComposerItem::AllProperties );
490+
466491
protected:
467492
void init();
468493

‎src/app/composer/qgscomposeritemwidget.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#include "qgscomposeritemwidget.h"
1919
#include "qgscomposeritem.h"
2020
#include "qgscomposermap.h"
21+
#include "qgsatlascomposition.h"
2122
#include "qgscomposition.h"
2223
#include "qgspoint.h"
24+
#include "qgsdatadefinedbutton.h"
2325
#include <QColorDialog>
2426
#include <QPen>
2527

@@ -36,6 +38,44 @@ QgsComposerItemBaseWidget::~QgsComposerItemBaseWidget()
3638

3739
}
3840

41+
void QgsComposerItemBaseWidget::updateDataDefinedProperty()
42+
{
43+
//match data defined button to item's data defined property
44+
QgsDataDefinedButton* ddButton = dynamic_cast<QgsDataDefinedButton*>( sender() );
45+
if ( !ddButton )
46+
{
47+
return;
48+
}
49+
QgsComposerItem::DataDefinedProperty property = ddPropertyForWidget( ddButton );
50+
if ( property == QgsComposerItem::NoProperty )
51+
{
52+
return;
53+
}
54+
55+
//set the data defined property and refresh the item
56+
setDataDefinedProperty( ddButton, property );
57+
mItem->refreshDataDefinedProperty( property );
58+
}
59+
60+
void QgsComposerItemBaseWidget::setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p )
61+
{
62+
if ( !mItem )
63+
{
64+
return;
65+
}
66+
67+
const QMap< QString, QString >& map = ddBtn->definedProperty();
68+
mItem->setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
69+
}
70+
71+
QgsComposerItem::DataDefinedProperty QgsComposerItemBaseWidget::ddPropertyForWidget( QgsDataDefinedButton *widget )
72+
{
73+
Q_UNUSED( widget );
74+
75+
//base implementation, return no property
76+
return QgsComposerItem::NoProperty;
77+
}
78+
3979
QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
4080
{
4181
if ( !mItem )
@@ -98,6 +138,17 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*
98138

99139
connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpnBx, SLOT( setValue( int ) ) );
100140
connect( mTransparencySpnBx, SIGNAL( valueChanged( int ) ), mTransparencySlider, SLOT( setValue( int ) ) );
141+
142+
//connect atlas signals to data defined buttons
143+
QgsAtlasComposition* atlas = atlasComposition();
144+
if ( atlas )
145+
{
146+
//repopulate data defined buttons if atlas layer changes
147+
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
148+
this, SLOT( populateDataDefinedButtons() ) );
149+
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( populateDataDefinedButtons() ) );
150+
}
151+
101152
}
102153

103154
QgsComposerItemWidget::QgsComposerItemWidget(): QgsComposerItemBaseWidget( 0, 0 )
@@ -449,6 +500,20 @@ void QgsComposerItemWidget::setValuesForGuiNonPositionElements()
449500
mItemRotationSpinBox->blockSignals( false );
450501
}
451502

503+
void QgsComposerItemWidget::populateDataDefinedButtons()
504+
{
505+
//QgsVectorLayer* vl = atlasCoverageLayer();
506+
507+
//block signals from data defined buttons
508+
509+
//initialise buttons to use atlas coverage layer
510+
511+
//initial state of controls - disable related controls when dd buttons are active
512+
513+
//unblock signals from data defined buttons
514+
515+
}
516+
452517
void QgsComposerItemWidget::setValuesForGuiElements()
453518
{
454519
if ( !mItem )
@@ -463,6 +528,7 @@ void QgsComposerItemWidget::setValuesForGuiElements()
463528

464529
setValuesForGuiPositionElements();
465530
setValuesForGuiNonPositionElements();
531+
populateDataDefinedButtons();
466532
}
467533

468534
void QgsComposerItemWidget::on_mBlendModeCombo_currentIndexChanged( int index )

‎src/app/composer/qgscomposeritemwidget.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
class QgsComposerItem;
2525
class QgsAtlasComposition;
26+
class QgsDataDefinedButton;
2627

2728
/**A base class for property widgets for composer items. All composer item widgets should inherit from
2829
* this base class.
@@ -34,7 +35,17 @@ class QgsComposerItemBaseWidget: public QWidget
3435
QgsComposerItemBaseWidget( QWidget* parent, QgsComposerItem* item );
3536
~QgsComposerItemBaseWidget();
3637

38+
protected slots:
39+
/**Must be called when a data defined button changes*/
40+
void updateDataDefinedProperty();
41+
3742
protected:
43+
/**Sets a data defined property for the item from its current data defined button settings*/
44+
void setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p );
45+
46+
/**Returns the data defined property corresponding to a data defined button widget*/
47+
virtual QgsComposerItem::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton* widget );
48+
3849
/**Returns the current atlas coverage layer (if set)*/
3950
QgsVectorLayer* atlasCoverageLayer() const;
4051

@@ -108,6 +119,10 @@ class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsCo
108119
//sets the values for all non-position related elements
109120
void setValuesForGuiNonPositionElements();
110121

122+
protected slots:
123+
/**Initializes data defined buttons to current atlas coverage layer*/
124+
void populateDataDefinedButtons();
125+
111126
private:
112127
QgsComposerItemWidget();
113128
// void changeItemTransparency( int value );

‎src/core/composer/qgscomposeritem.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "qgscomposition.h"
3131
#include "qgscomposeritem.h"
3232
#include "qgscomposerframe.h"
33+
#include "qgsdatadefined.h"
3334

3435
#include <limits>
3536
#include "qgsapplication.h"
@@ -117,6 +118,23 @@ void QgsComposerItem::init( bool manageZValue )
117118
// Setup composer effect
118119
mEffect = new QgsComposerEffect();
119120
setGraphicsEffect( mEffect );
121+
122+
// data defined strings
123+
124+
if ( mComposition )
125+
{
126+
//connect to atlas toggling on/off and coverage layer and feature changes
127+
//to update data defined values
128+
connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( refreshDataDefinedProperty() ) );
129+
connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( refreshDataDefinedProperty() ) );
130+
connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshDataDefinedProperty() ) );
131+
//also, refreshing composition triggers a recalculation of data defined properties
132+
connect( mComposition, SIGNAL( refreshItemsTriggered() ), this, SLOT( refreshDataDefinedProperty() ) );
133+
134+
//toggling atlas or changing coverage layer requires data defined expressions to be reprepared
135+
connect( &mComposition->atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( prepareDataDefinedExpressions() ) );
136+
connect( &mComposition->atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( prepareDataDefinedExpressions() ) );
137+
}
120138
}
121139

122140
QgsComposerItem::~QgsComposerItem()
@@ -128,6 +146,11 @@ QgsComposerItem::~QgsComposerItem()
128146

129147
delete mBoundingResizeRectangle;
130148
delete mEffect;
149+
150+
//clear pointers to QgsDataDefined objects
151+
//TODO - probably leaky. Check same code within labelling and fix.
152+
mDataDefinedProperties.clear();
153+
131154
deleteAlignItems();
132155
}
133156

@@ -226,6 +249,12 @@ bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) cons
226249
//transparency
227250
composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) );
228251

252+
//data defined properties
253+
if ( mComposition )
254+
{
255+
mComposition->writeDataDefinedPropertyMap( composerItemElem, doc, &mDataDefinedNames, &mDataDefinedProperties );
256+
}
257+
229258
itemElem.appendChild( composerItemElem );
230259

231260
return true;
@@ -369,6 +398,12 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument&
369398
//transparency
370399
setTransparency( itemElem.attribute( "transparency" , "0" ).toInt() );
371400

401+
//data defined properties
402+
if ( mComposition )
403+
{
404+
mComposition->readDataDefinedPropertyMap( itemElem, &mDataDefinedNames, &mDataDefinedProperties );
405+
}
406+
372407
return true;
373408
}
374409

@@ -1170,11 +1205,49 @@ void QgsComposerItem::deleteAlignItems()
11701205
deleteVAlignSnapItem();
11711206
}
11721207

1208+
bool QgsComposerItem::dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue )
1209+
{
1210+
if ( !mComposition )
1211+
{
1212+
return false;
1213+
}
1214+
return mComposition->dataDefinedEvaluate( property, expressionValue, &mDataDefinedProperties );
1215+
}
1216+
1217+
void QgsComposerItem::prepareDataDefinedExpressions() const
1218+
{
1219+
//use atlas coverage layer if set
1220+
QgsVectorLayer* atlasLayer = 0;
1221+
if ( mComposition )
1222+
{
1223+
QgsAtlasComposition* atlas = &mComposition->atlasComposition();
1224+
if ( atlas && atlas->enabled() )
1225+
{
1226+
atlasLayer = atlas->coverageLayer();
1227+
}
1228+
}
1229+
1230+
//prepare all QgsDataDefineds
1231+
QMap< DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.constBegin();
1232+
if ( it != mDataDefinedProperties.constEnd() )
1233+
{
1234+
it.value()->prepareExpression( atlasLayer );
1235+
}
1236+
}
1237+
11731238
void QgsComposerItem::repaint()
11741239
{
11751240
update();
11761241
}
11771242

1243+
void QgsComposerItem::refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property )
1244+
{
1245+
//update data defined properties and redraw item to match
1246+
1247+
1248+
update();
1249+
}
1250+
11781251
void QgsComposerItem::setId( const QString& id )
11791252
{
11801253
setToolTip( id );
@@ -1186,3 +1259,51 @@ void QgsComposerItem::setIsGroupMember( bool isGroupMember )
11861259
mIsGroupMember = isGroupMember;
11871260
setFlag( QGraphicsItem::ItemIsSelectable, !isGroupMember ); //item in groups cannot be selected
11881261
}
1262+
1263+
QgsDataDefined *QgsComposerItem::dataDefinedProperty( QgsComposerItem::DataDefinedProperty property )
1264+
{
1265+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
1266+
{
1267+
//bad property requested, don't return anything
1268+
return 0;
1269+
}
1270+
1271+
//find corresponding QgsDataDefined and return it
1272+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.find( property );
1273+
if ( it != mDataDefinedProperties.constEnd() )
1274+
{
1275+
return it.value();
1276+
}
1277+
1278+
//could not find matching QgsDataDefined
1279+
return 0;
1280+
}
1281+
1282+
void QgsComposerItem::setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field )
1283+
{
1284+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
1285+
{
1286+
//bad property requested
1287+
return;
1288+
}
1289+
1290+
bool defaultVals = ( !active && !useExpression && expression.isEmpty() && field.isEmpty() );
1291+
1292+
if ( mDataDefinedProperties.contains( property ) )
1293+
{
1294+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.find( property );
1295+
if ( it != mDataDefinedProperties.constEnd() )
1296+
{
1297+
QgsDataDefined* dd = it.value();
1298+
dd->setActive( active );
1299+
dd->setUseExpression( useExpression );
1300+
dd->setExpressionString( expression );
1301+
dd->setField( field );
1302+
}
1303+
}
1304+
else if ( !defaultVals )
1305+
{
1306+
QgsDataDefined* dd = new QgsDataDefined( active, useExpression, expression, field );
1307+
mDataDefinedProperties.insert( property, dd );
1308+
}
1309+
}

‎src/core/composer/qgscomposeritem.h

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
#include <QGraphicsRectItem>
2424
#include <QObject>
2525

26-
class QgsComposition;
2726
class QWidget;
2827
class QDomDocument;
2928
class QDomElement;
3029
class QGraphicsLineItem;
3130
class QgsComposerItemGroup;
31+
class QgsDataDefined;
32+
class QgsComposition;
3233

3334
/** \ingroup MapComposer
3435
* A item that forms part of a map composition.
@@ -87,6 +88,36 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
8788
LowerRight
8889
};
8990

91+
/** Data defined properties for different item types
92+
*/
93+
enum DataDefinedProperty
94+
{
95+
NoProperty = 0, /*< no property */
96+
AllProperties, /*< all properties for item */
97+
//composer page properties
98+
PresetPaperSize, /*< preset paper size for composition */
99+
PaperWidth, /*< paper width */
100+
PaperHeight, /*< paper height */
101+
NumPages, /*< number of pages in composition */
102+
PaperOrientation, /*< paper orientation */
103+
//general composer item properties
104+
PageNumber, /*< page number for item placement */
105+
PositionX, /*< x position on page */
106+
PositionY, /*< y position on page */
107+
ItemWidth, /*< width of item */
108+
ItemHeight, /*< height of item */
109+
ItemRotation, /*< rotation of item */
110+
Transparency, /*< item transparency */
111+
BlendMode, /*< item blend mode */
112+
//composer map
113+
MapRotation, /*< map rotation */
114+
MapScale, /*< map scale */
115+
MapXMin, /*< map extent x minimum */
116+
MapYMin, /*< map extent y minimum */
117+
MapXMax, /*< map extent x maximum */
118+
MapYMax /*< map extent y maximum */
119+
};
120+
90121
/**Constructor
91122
@param composition parent composition
92123
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
@@ -436,22 +467,47 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
436467
*/
437468
virtual void setCurrentExportLayer( int layerIdx = -1 ) { mCurrentExportLayer = layerIdx; }
438469

470+
/**Returns a reference to the data defined settings for one of the item's data defined properties.
471+
* @param property data defined property to return
472+
* @note this method was added in version 2.5
473+
*/
474+
QgsDataDefined* dataDefinedProperty( DataDefinedProperty property );
475+
476+
/**Sets parameters for a data defined property for the item
477+
* @param property data defined property to set
478+
* @param active true if data defined property is active, false if it is disabled
479+
* @param useExpression true if the expression should be used
480+
* @param expression expression for data defined property
481+
* @field field name if the data defined property should take its value from a field
482+
* @note this method was added in version 2.5
483+
*/
484+
void setDataDefinedProperty( DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
485+
439486
public slots:
440487
/**Sets the item rotation
441488
* @deprecated Use setItemRotation( double rotation ) instead
442489
*/
443490
virtual void setRotation( double r );
444491

445492
/**Sets the item rotation
446-
@param r item rotation in degrees
447-
@param adjustPosition set to true if item should be shifted so that rotation occurs
448-
around item center. If false, rotation occurs around item origin
449-
@note this method was added in version 2.1
493+
* @param r item rotation in degrees
494+
* @param adjustPosition set to true if item should be shifted so that rotation occurs
495+
* around item center. If false, rotation occurs around item origin
496+
* @note this method was added in version 2.1
450497
*/
451498
virtual void setItemRotation( double r, bool adjustPosition = false );
452499

453500
void repaint();
454501

502+
/**Refreshes a data defined property for the item by reevaluating the property's value
503+
* and redrawing the item with this new value.
504+
* @param property data defined property to refresh. If property is set to
505+
* QgsComposerItem::AllProperties then all data defined properties for the item will be
506+
* refreshed.
507+
* @note this method was added in version 2.5
508+
*/
509+
virtual void refreshDataDefinedProperty( DataDefinedProperty property = AllProperties );
510+
455511
protected:
456512

457513
QgsComposition* mComposition;
@@ -506,6 +562,9 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
506562
@note: this member was added in version 2.4*/
507563
int mCurrentExportLayer;
508564

565+
/**Map of data defined properties for the item to string name to use when exporting item to xml*/
566+
QMap< QgsComposerItem::DataDefinedProperty, QString > mDataDefinedNames;
567+
509568
/**Draw selection boxes around item*/
510569
virtual void drawSelectionBoxes( QPainter* p );
511570

@@ -582,6 +641,14 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
582641
void deleteVAlignSnapItem();
583642
void deleteAlignItems();
584643

644+
/**Evaluate a data defined property and return the calculated value
645+
* @returns true if data defined property could be successfully evaluated
646+
* @param property data defined property to evaluate
647+
* @param expressionValue QVariant for storing the evaluated value
648+
* @note this method was added in version 2.5
649+
*/
650+
bool dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue );
651+
585652
signals:
586653
/**Is emitted on item rotation change*/
587654
void itemRotationChanged( double newRotation );
@@ -593,6 +660,13 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
593660
* @note: this function was introduced in version 2.2
594661
*/
595662
void frameChanged();
663+
664+
private slots:
665+
/**Prepares all composer item data defined expressions using the current atlas coverage layer if set.
666+
* @note this method was added in version 2.5
667+
*/
668+
void prepareDataDefinedExpressions() const;
669+
596670
private:
597671
// id (not unique)
598672
QString mId;
@@ -601,6 +675,9 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
601675
// name (temporary when loaded from template)
602676
QString mTemplateUuid;
603677

678+
/**Map of current data defined properties*/
679+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* > mDataDefinedProperties;
680+
604681
void init( bool manageZValue );
605682

606683
friend class QgsComposerItemGroup; // to access mTemplateUuid

‎src/core/composer/qgscomposition.cpp

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "qgsexpression.h"
4040
#include "qgssymbolv2.h"
4141
#include "qgssymbollayerv2utils.h"
42+
#include "qgsdatadefined.h"
4243

4344
#include <QDomDocument>
4445
#include <QDomElement>
@@ -96,6 +97,19 @@ void QgsComposition::init()
9697
mAtlasMode = QgsComposition::AtlasOff;
9798
mPreventCursorChange = false;
9899

100+
//data defined strings
101+
102+
//connect to atlas toggling on/off and coverage layer and feature changes
103+
//to update data defined values
104+
connect( &mAtlasComposition, SIGNAL( toggled( bool ) ), this, SLOT( refreshDataDefinedProperty() ) );
105+
connect( &mAtlasComposition, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( refreshDataDefinedProperty() ) );
106+
connect( &mAtlasComposition, SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshDataDefinedProperty() ) );
107+
//also, refreshing composition triggers a recalculation of data defined properties
108+
connect( this, SIGNAL( refreshItemsTriggered() ), this, SLOT( refreshDataDefinedProperty() ) );
109+
//toggling atlas or changing coverage layer requires data defined expressions to be reprepared
110+
connect( &mAtlasComposition, SIGNAL( toggled( bool ) ), this, SLOT( prepareAllDataDefinedExpressions() ) );
111+
connect( &mAtlasComposition, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( prepareAllDataDefinedExpressions() ) );
112+
99113
setBackgroundBrush( QColor( 215, 215, 215 ) );
100114
createDefaultPageStyleSymbol();
101115

@@ -157,6 +171,10 @@ QgsComposition::~QgsComposition()
157171
removePaperItems();
158172
deleteAndRemoveMultiFrames();
159173

174+
// clear pointers to QgsDataDefined objects
175+
//TODO - should be qDeleteAll? Check original label code too for same leak.
176+
mDataDefinedProperties.clear();
177+
160178
// make sure that all composer items are removed before
161179
// this class is deconstructed - to avoid segfaults
162180
// when composer items access in destructor composition that isn't valid anymore
@@ -192,6 +210,12 @@ void QgsComposition::setSelectedItem( QgsComposerItem *item )
192210
emit selectedItemChanged( item );
193211
}
194212

213+
void QgsComposition::refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property )
214+
{
215+
//updates data defined properties and redraws composition to match
216+
217+
}
218+
195219
QRectF QgsComposition::compositionBounds() const
196220
{
197221
//start with an empty rectangle
@@ -692,6 +716,9 @@ bool QgsComposition::writeXML( QDomElement& composerElem, QDomDocument& doc )
692716
}
693717
composerElem.appendChild( compositionElem );
694718

719+
//data defined properties
720+
writeDataDefinedPropertyMap( compositionElem, doc, &mDataDefinedNames, &mDataDefinedProperties );
721+
695722
return true;
696723
}
697724

@@ -757,6 +784,9 @@ bool QgsComposition::readXML( const QDomElement& compositionElem, const QDomDocu
757784

758785
mGenerateWorldFile = compositionElem.attribute( "generateWorldFile", "0" ).toInt() == 1 ? true : false;
759786

787+
//data defined properties
788+
readDataDefinedPropertyMap( compositionElem, &mDataDefinedNames, &mDataDefinedProperties );
789+
760790
updatePaperItems();
761791

762792
updateBounds();
@@ -2688,6 +2718,296 @@ bool QgsComposition::setAtlasMode( QgsComposition::AtlasMode mode )
26882718
return true;
26892719
}
26902720

2721+
QgsDataDefined *QgsComposition::dataDefinedProperty( QgsComposerItem::DataDefinedProperty property )
2722+
{
2723+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
2724+
{
2725+
//invalid property
2726+
return 0;
2727+
}
2728+
2729+
//find matching QgsDataDefined for property
2730+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.find( property );
2731+
if ( it != mDataDefinedProperties.constEnd() )
2732+
{
2733+
return it.value();
2734+
}
2735+
2736+
//not found
2737+
return 0;
2738+
}
2739+
2740+
void QgsComposition::setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field )
2741+
{
2742+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
2743+
{
2744+
//invalid property
2745+
return;
2746+
}
2747+
2748+
bool defaultVals = ( !active && !useExpression && expression.isEmpty() && field.isEmpty() );
2749+
2750+
if ( mDataDefinedProperties.contains( property ) )
2751+
{
2752+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.find( property );
2753+
if ( it != mDataDefinedProperties.constEnd() )
2754+
{
2755+
QgsDataDefined* dd = it.value();
2756+
dd->setActive( active );
2757+
dd->setUseExpression( useExpression );
2758+
dd->setExpressionString( expression );
2759+
dd->setField( field );
2760+
}
2761+
}
2762+
else if ( !defaultVals )
2763+
{
2764+
QgsDataDefined* dd = new QgsDataDefined( active, useExpression, expression, field );
2765+
mDataDefinedProperties.insert( property, dd );
2766+
}
2767+
}
2768+
2769+
bool QgsComposition::dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue, QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties )
2770+
{
2771+
if ( property == QgsComposerItem::NoProperty || property == QgsComposerItem::AllProperties )
2772+
{
2773+
//invalid property
2774+
return false;
2775+
}
2776+
2777+
//null passed-around QVariant
2778+
expressionValue.clear();
2779+
2780+
//get fields and feature from atlas
2781+
const QgsFeature* currentFeature = 0;
2782+
const QgsFields* layerFields = 0;
2783+
if ( mAtlasComposition.enabled() )
2784+
{
2785+
QgsVectorLayer* atlasLayer = mAtlasComposition.coverageLayer();
2786+
if ( atlasLayer )
2787+
{
2788+
layerFields = &atlasLayer->pendingFields();
2789+
}
2790+
if ( mAtlasMode != QgsComposition::AtlasOff )
2791+
{
2792+
currentFeature = mAtlasComposition.currentFeature();
2793+
}
2794+
}
2795+
2796+
//evaluate data defined property using current atlas context
2797+
QVariant result = dataDefinedValue( property, currentFeature, layerFields, dataDefinedProperties );
2798+
2799+
if ( result.isValid() )
2800+
{
2801+
expressionValue = result;
2802+
return true;
2803+
}
2804+
2805+
return false;
2806+
}
2807+
2808+
void QgsComposition::readDataDefinedPropertyMap( const QDomElement &itemElem, QMap<QgsComposerItem::DataDefinedProperty, QString> *dataDefinedNames, QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
2809+
{
2810+
QMap<QgsComposerItem::DataDefinedProperty, QString>::const_iterator i = dataDefinedNames->constBegin();
2811+
for ( ; i != dataDefinedNames->constEnd(); ++i )
2812+
{
2813+
QString elemName = i.value();
2814+
QDomNodeList ddNodeList = itemElem.elementsByTagName( elemName );
2815+
if ( ddNodeList.size() > 0 )
2816+
{
2817+
QDomElement ddElem = ddNodeList.at( 0 ).toElement();
2818+
readDataDefinedProperty( i.key(), ddElem, dataDefinedProperties );
2819+
}
2820+
}
2821+
}
2822+
2823+
void QgsComposition::readDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, const QDomElement &ddElem, QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
2824+
{
2825+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
2826+
{
2827+
//invalid property
2828+
return;
2829+
}
2830+
2831+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->constFind( property );
2832+
2833+
QgsDataDefined* dd = 0;
2834+
if ( it != dataDefinedProperties->constEnd() )
2835+
{
2836+
dd = it.value();
2837+
}
2838+
else
2839+
{
2840+
//QgsDataDefined for property doesn't currently exist, need to add new
2841+
dd = new QgsDataDefined( );
2842+
dataDefinedProperties->insert( property, dd );
2843+
}
2844+
2845+
//set values for QgsDataDefined
2846+
QString active = ddElem.attribute( "active" );
2847+
if ( active.compare( "true", Qt::CaseInsensitive ) == 0 )
2848+
{
2849+
dd->setActive( true );
2850+
}
2851+
else
2852+
{
2853+
dd->setActive( false );
2854+
}
2855+
QString useExpr = ddElem.attribute( "useExpr" );
2856+
if ( useExpr.compare( "true", Qt::CaseInsensitive ) == 0 )
2857+
{
2858+
dd->setUseExpression( true );
2859+
}
2860+
else
2861+
{
2862+
dd->setUseExpression( false );
2863+
}
2864+
dd->setField( ddElem.attribute( "field" ) );
2865+
dd->setExpressionString( ddElem.attribute( "expr" ) );
2866+
}
2867+
2868+
void QgsComposition::writeDataDefinedPropertyMap( QDomElement &itemElem, QDomDocument &doc, const QMap<QgsComposerItem::DataDefinedProperty, QString> *dataDefinedNames, const QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
2869+
{
2870+
QMap<QgsComposerItem::DataDefinedProperty, QString >::const_iterator i = dataDefinedNames->constBegin();
2871+
for ( ; i != dataDefinedNames->constEnd(); ++i )
2872+
{
2873+
QString newElemName = i.value();
2874+
2875+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->find( i.key() );
2876+
if ( it != dataDefinedProperties->constEnd() )
2877+
{
2878+
QgsDataDefined* dd = it.value();
2879+
if ( dd )
2880+
{
2881+
bool active = dd->isActive();
2882+
bool useExpr = dd->useExpression();
2883+
QString expr = dd->expressionString();
2884+
QString field = dd->field();
2885+
2886+
bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
2887+
2888+
if ( !defaultVals )
2889+
{
2890+
QDomElement ddElem = doc.createElement( newElemName );
2891+
if ( active )
2892+
{
2893+
ddElem.setAttribute( "active", "true" );
2894+
}
2895+
else
2896+
{
2897+
ddElem.setAttribute( "active", "false" );
2898+
}
2899+
if ( useExpr )
2900+
{
2901+
ddElem.setAttribute( "useExpr", "true" );
2902+
}
2903+
else
2904+
{
2905+
ddElem.setAttribute( "useExpr", "false" );
2906+
}
2907+
ddElem.setAttribute( "expr", expr );
2908+
ddElem.setAttribute( "field", field );
2909+
itemElem.appendChild( ddElem );
2910+
}
2911+
}
2912+
}
2913+
}
2914+
}
2915+
2916+
QVariant QgsComposition::dataDefinedValue( QgsComposerItem::DataDefinedProperty property, const QgsFeature *feature, const QgsFields *fields, QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties )
2917+
{
2918+
if ( property == QgsComposerItem::AllProperties || property == QgsComposerItem::NoProperty )
2919+
{
2920+
//invalid property
2921+
return QVariant();
2922+
}
2923+
if ( !dataDefinedProperties->contains( property ) )
2924+
{
2925+
//missing property
2926+
return QVariant();
2927+
}
2928+
2929+
QgsDataDefined* dd = 0;
2930+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->find( property );
2931+
if ( it != dataDefinedProperties->constEnd() )
2932+
{
2933+
dd = it.value();
2934+
}
2935+
if ( !dd )
2936+
{
2937+
return QVariant();
2938+
}
2939+
2940+
if ( !dd->isActive() )
2941+
{
2942+
return QVariant();
2943+
}
2944+
2945+
QVariant result = QVariant();
2946+
bool useExpression = dd->useExpression();
2947+
QString field = dd->field();
2948+
2949+
if ( !dd->expressionIsPrepared() )
2950+
{
2951+
prepareDataDefinedExpression( dd, dataDefinedProperties );
2952+
}
2953+
2954+
if ( useExpression && dd->expressionIsPrepared() )
2955+
{
2956+
QgsExpression* expr = dd->expression();
2957+
2958+
result = expr->evaluate( feature );
2959+
if ( expr->hasEvalError() )
2960+
{
2961+
QgsDebugMsgLevel( QString( "Evaluate error:" ) + expr->evalErrorString(), 4 );
2962+
return QVariant();
2963+
}
2964+
}
2965+
else if ( !useExpression && !field.isEmpty() && fields )
2966+
{
2967+
if ( !feature )
2968+
{
2969+
return QVariant();
2970+
}
2971+
// use direct attribute access instead of evaluating "field" expression (much faster)
2972+
int indx = fields->indexFromName( field );
2973+
if ( indx != -1 )
2974+
{
2975+
result = feature->attribute( indx );
2976+
}
2977+
}
2978+
return result;
2979+
}
2980+
2981+
void QgsComposition::prepareDataDefinedExpression( QgsDataDefined *dd, QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
2982+
{
2983+
QgsVectorLayer* atlasLayer = 0;
2984+
2985+
if ( mAtlasComposition.enabled() )
2986+
{
2987+
atlasLayer = mAtlasComposition.coverageLayer();
2988+
}
2989+
2990+
//if specific QgsDataDefined passed, prepare it
2991+
//otherwise prepare all QgsDataDefineds
2992+
if ( dd )
2993+
{
2994+
dd->prepareExpression( atlasLayer );
2995+
}
2996+
else
2997+
{
2998+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->constBegin();
2999+
for ( ; it != dataDefinedProperties->constEnd(); ++it )
3000+
{
3001+
it.value()->prepareExpression( atlasLayer );
3002+
}
3003+
}
3004+
}
3005+
3006+
void QgsComposition::prepareAllDataDefinedExpressions()
3007+
{
3008+
prepareDataDefinedExpression( 0, &mDataDefinedProperties );
3009+
}
3010+
26913011
void QgsComposition::relativeResizeRect( QRectF& rectToResize, const QRectF& boundsBefore, const QRectF& boundsAfter )
26923012
{
26933013
//linearly scale rectToResize relative to the scaling from boundsBefore to boundsAfter

‎src/core/composer/qgscomposition.h

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#ifndef QGSCOMPOSITION_H
1717
#define QGSCOMPOSITION_H
1818

19-
#include "qgscomposeritem.h"
2019
#include <memory>
2120

2221
#include <QDomDocument>
@@ -33,6 +32,7 @@
3332
#include "qgscomposeritemcommand.h"
3433
#include "qgsatlascomposition.h"
3534
#include "qgspaperitem.h"
35+
#include "qgscomposeritem.h"
3636

3737
class QgisApp;
3838
class QgsComposerFrame;
@@ -56,6 +56,7 @@ class QgsComposerMultiFrameCommand;
5656
class QgsVectorLayer;
5757
class QgsComposer;
5858
class QgsFillSymbolV2;
59+
class QgsDataDefined;
5960

6061
/** \ingroup MapComposer
6162
* Graphics scene for map printing. The class manages the paper item which always
@@ -504,6 +505,22 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
504505
@note added in version 2.4*/
505506
QList< QgsPaperItem* > pages() { return mPages; }
506507

508+
/**Returns a reference to the data defined settings for one of the composition's data defined properties.
509+
* @param property data defined property to return
510+
* @note this method was added in version 2.5
511+
*/
512+
QgsDataDefined* dataDefinedProperty( QgsComposerItem::DataDefinedProperty property );
513+
514+
/**Sets parameters for a data defined property for the composition
515+
* @param property data defined property to set
516+
* @param active true if data defined property is active, false if it is disabled
517+
* @param useExpression true if the expression should be used
518+
* @param expression expression for data defined property
519+
* @field field name if the data defined property should take its value from a field
520+
* @note this method was added in version 2.5
521+
*/
522+
void setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
523+
507524
public slots:
508525
/**Casts object to the proper subclass type and calls corresponding itemAdded signal*/
509526
void sendItemAddedSignal( QgsComposerItem* item );
@@ -523,6 +540,15 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
523540
* @note added in version 2.3*/
524541
void setSelectedItem( QgsComposerItem* item );
525542

543+
/**Refreshes a data defined property for the composition by reevaluating the property's value
544+
* and redrawing the composition with this new value.
545+
* @param property data defined property to refresh. If property is set to
546+
* QgsComposerItem::AllProperties then all data defined properties for the composition will be
547+
* refreshed.
548+
* @note this method was added in version 2.5
549+
*/
550+
void refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property = QgsComposerItem::AllProperties );
551+
526552
protected:
527553
void init();
528554

@@ -592,6 +618,13 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
592618

593619
QgsComposition::AtlasMode mAtlasMode;
594620

621+
bool mPreventCursorChange;
622+
623+
/**Map of data defined properties for the composition to string name to use when exporting composition to xml*/
624+
QMap< QgsComposerItem::DataDefinedProperty, QString > mDataDefinedNames;
625+
/**Map of current data defined properties to QgsDataDefined for the composition*/
626+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* > mDataDefinedProperties;
627+
595628
QgsComposition(); //default constructor is forbidden
596629

597630
/**Calculates the bounds of all non-gui items in the composition. Ignores snap lines and mouse handles*/
@@ -625,7 +658,68 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
625658
//tries to return the current QGraphicsView attached to the composition
626659
QGraphicsView* graphicsView() const;
627660

628-
bool mPreventCursorChange;
661+
/**Evaluate a data defined property and return the calculated value
662+
* @returns true if data defined property could be successfully evaluated
663+
* @param property data defined property to evaluate
664+
* @param expressionValue QVariant for storing the evaluated value
665+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
666+
* @note this method was added in version 2.5
667+
*/
668+
bool dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue,
669+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties );
670+
671+
/**Reads all data defined properties from xml
672+
* @param itemElem dom element containing data defined properties
673+
* @param dataDefinedNames map of data defined property to name used within xml
674+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined in which to store properties from xml
675+
* @note this method was added in version 2.5
676+
*/
677+
void readDataDefinedPropertyMap( const QDomElement &itemElem,
678+
QMap< QgsComposerItem::DataDefinedProperty, QString >* dataDefinedNames,
679+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties
680+
) const;
681+
682+
/**Reads a single data defined property from xml DOM element
683+
* @param property data defined property to read
684+
* @param ddElem dom element containing settings for data defined property
685+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined in which to store properties from xml
686+
* @note this method was added in version 2.5
687+
*/
688+
void readDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, const QDomElement &ddElem,
689+
QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties ) const;
690+
691+
/**Writes data defined properties to xml
692+
* @param itemElem DOM element in which to store data defined properties
693+
* @param doc DOM document
694+
* @param dataDefinedNames map of data defined property to name used within xml
695+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined for storing in xml
696+
* @note this method was added in version 2.5
697+
*/
698+
void writeDataDefinedPropertyMap( QDomElement &itemElem, QDomDocument &doc,
699+
const QMap< QgsComposerItem::DataDefinedProperty, QString >* dataDefinedNames,
700+
const QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties ) const;
701+
702+
/**Evaluates a data defined property and returns the calculated value.
703+
* @param property data defined property to evaluate
704+
* @param feature current atlas feature to evaluate property for
705+
* @param fields fields from atlas layer
706+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
707+
* @note this method was added in version 2.5
708+
*/
709+
QVariant dataDefinedValue( QgsComposerItem::DataDefinedProperty property, const QgsFeature *feature, const QgsFields *fields,
710+
QMap<QgsComposerItem::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties );
711+
712+
713+
/**Prepares the expression for a data defined property, using the current atlas layer if set.
714+
* @param dd data defined to prepare. If no data defined is set, all data defined expressions will be prepared
715+
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
716+
* @note this method was added in version 2.5
717+
*/
718+
void prepareDataDefinedExpression( QgsDataDefined *dd, QMap< QgsComposerItem::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties ) const;
719+
720+
private slots:
721+
/*Prepares all data defined expressions*/
722+
void prepareAllDataDefinedExpressions();
629723

630724
signals:
631725
void paperSizeChanged();
@@ -662,6 +756,8 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
662756

663757
/**Is emitted when the composition has an updated status bar message for the composer window*/
664758
void statusMsgChanged( QString message );
759+
760+
friend class QgsComposerItem; //for accessing dataDefinedEvaluate, readDataDefinedPropertyMap and writeDataDefinedPropertyMap
665761
};
666762

667763
template<class T> void QgsComposition::composerItems( QList<T*>& itemList )

0 commit comments

Comments
 (0)
Please sign in to comment.