Skip to content

Commit 5cb874c

Browse files
committedAug 22, 2015
More composer porting
1 parent cf22025 commit 5cb874c

File tree

7 files changed

+90
-54
lines changed

7 files changed

+90
-54
lines changed
 

‎src/core/composer/qgscomposeritem.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -709,14 +709,24 @@ void QgsComposerItem::setSceneRect( const QRectF& rectangle )
709709
emit sizeChanged();
710710
}
711711

712-
QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOnly )
712+
QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOnly, const QgsExpressionContext* context )
713713
{
714714
QRectF result = newRect;
715715

716+
//TODO QGIS 3.0
717+
//maintain pre 2.12 API. remove when API break allowed
718+
QScopedPointer< QgsExpressionContext > scopedContext;
719+
const QgsExpressionContext* evalContext = context;
720+
if ( !evalContext )
721+
{
722+
scopedContext.reset( createExpressionContext() );
723+
evalContext = scopedContext.data();
724+
}
725+
716726
//data defined position or size set? if so, update rect with data defined values
717727
QVariant exprVal;
718728
//evaulate width and height first, since they may affect position if non-top-left reference point set
719-
if ( dataDefinedEvaluate( QgsComposerObject::ItemWidth, exprVal ) )
729+
if ( dataDefinedEvaluate( QgsComposerObject::ItemWidth, exprVal, *evalContext ) )
720730
{
721731
bool ok;
722732
double width = exprVal.toDouble( &ok );
@@ -726,7 +736,7 @@ QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOn
726736
result.setWidth( width );
727737
}
728738
}
729-
if ( dataDefinedEvaluate( QgsComposerObject::ItemHeight, exprVal ) )
739+
if ( dataDefinedEvaluate( QgsComposerObject::ItemHeight, exprVal, *evalContext ) )
730740
{
731741
bool ok;
732742
double height = exprVal.toDouble( &ok );
@@ -762,7 +772,7 @@ QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOn
762772
x += rect().width();
763773
}
764774
}
765-
if ( dataDefinedEvaluate( QgsComposerObject::PositionX, exprVal ) )
775+
if ( dataDefinedEvaluate( QgsComposerObject::PositionX, exprVal, *evalContext ) )
766776
{
767777
bool ok;
768778
double positionX = exprVal.toDouble( &ok );
@@ -798,7 +808,7 @@ QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOn
798808
y += rect().height();
799809
}
800810
}
801-
if ( dataDefinedEvaluate( QgsComposerObject::PositionY, exprVal ) )
811+
if ( dataDefinedEvaluate( QgsComposerObject::PositionY, exprVal, *evalContext ) )
802812
{
803813
bool ok;
804814
double positionY = exprVal.toDouble( &ok );
@@ -849,18 +859,7 @@ bool QgsComposerItem::shouldDrawItem() const
849859

850860
QgsExpressionContext* QgsComposerItem::createExpressionContext() const
851861
{
852-
QgsExpressionContext* context = new QgsExpressionContext();
853-
context->appendScope( QgsExpressionContextUtils::globalScope() );
854-
context->appendScope( QgsExpressionContextUtils::projectScope() );
855-
if ( mComposition )
856-
{
857-
context->appendScope( QgsExpressionContextUtils::compositionScope( mComposition ) );
858-
if ( mComposition->atlasComposition().enabled() )
859-
{
860-
context->appendScope( QgsExpressionContextUtils::atlasScope( &mComposition->atlasComposition() ) );
861-
}
862-
}
863-
862+
QgsExpressionContext* context = QgsComposerObject::createExpressionContext();
864863
context->appendScope( QgsExpressionContextUtils::composerItemScope( this ) );
865864
return context;
866865
}

‎src/core/composer/qgscomposeritem.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,7 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
583583
*/
584584
virtual void setCurrentExportLayer( const int layerIdx = -1 ) { mCurrentExportLayer = layerIdx; }
585585

586-
/** Creates an expression context relating to the item's current state. The context includes
587-
* scopes for global, project, composition, atlas and item properties.
588-
* @note added in QGIS 2.12
589-
*/
590-
QgsExpressionContext* createExpressionContext() const;
586+
virtual QgsExpressionContext* createExpressionContext() const override;
591587

592588
public slots:
593589
/** Sets the item rotation

‎src/core/composer/qgscomposerobject.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgscomposerutils.h"
2222
#include "qgscomposerobject.h"
2323
#include "qgsdatadefined.h"
24+
#include "qgsexpressioncontext.h"
2425

2526
#define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
2627

@@ -151,33 +152,24 @@ void QgsComposerObject::refreshDataDefinedProperty( const DataDefinedProperty pr
151152
//nothing to do in base class for now
152153
}
153154

154-
bool QgsComposerObject::dataDefinedEvaluate( const DataDefinedProperty property, QVariant &expressionValue ) const
155+
bool QgsComposerObject::dataDefinedEvaluate( const DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext& context ) const
155156
{
156157
if ( !mComposition )
157158
{
158159
return false;
159160
}
160-
return mComposition->dataDefinedEvaluate( property, expressionValue, &mDataDefinedProperties );
161+
return mComposition->dataDefinedEvaluate( property, expressionValue, context, &mDataDefinedProperties );
161162
}
162163

163164
void QgsComposerObject::prepareDataDefinedExpressions() const
164165
{
165-
//use atlas coverage layer if set
166-
QgsVectorLayer* atlasLayer = 0;
167-
if ( mComposition )
168-
{
169-
QgsAtlasComposition* atlas = &mComposition->atlasComposition();
170-
if ( atlas && atlas->enabled() )
171-
{
172-
atlasLayer = atlas->coverageLayer();
173-
}
174-
}
166+
QScopedPointer< QgsExpressionContext > context( createExpressionContext() );
175167

176168
//prepare all QgsDataDefineds
177169
QMap< DataDefinedProperty, QgsDataDefined* >::const_iterator it = mDataDefinedProperties.constBegin();
178170
if ( it != mDataDefinedProperties.constEnd() )
179171
{
180-
it.value()->prepareExpression( atlasLayer );
172+
it.value()->prepareExpression( *context.data() );
181173
}
182174
}
183175

@@ -200,3 +192,19 @@ QStringList QgsComposerObject::customProperties() const
200192
{
201193
return mCustomProperties.keys();
202194
}
195+
196+
QgsExpressionContext* QgsComposerObject::createExpressionContext() const
197+
{
198+
QgsExpressionContext* context = 0;
199+
if ( mComposition )
200+
{
201+
context = mComposition->createExpressionContext();
202+
}
203+
else
204+
{
205+
context = new QgsExpressionContext();
206+
context->appendScope( QgsExpressionContextUtils::globalScope() );
207+
context->appendScope( QgsExpressionContextUtils::projectScope() );
208+
}
209+
return context;
210+
}

‎src/core/composer/qgscomposerobject.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
class QgsComposition;
2626
class QPainter;
2727
class QgsDataDefined;
28+
class QgsExpressionContext;
2829

2930
/** \ingroup MapComposer
3031
* A base class for objects which belong to a map composition.
@@ -161,6 +162,12 @@ class CORE_EXPORT QgsComposerObject: public QObject
161162
*/
162163
QStringList customProperties() const;
163164

165+
/** Creates an expression context relating to the objects's current state. The context includes
166+
* scopes for global, project and composition properties.
167+
* @note added in QGIS 2.12
168+
*/
169+
virtual QgsExpressionContext* createExpressionContext() const;
170+
164171
public slots:
165172

166173
/** Triggers a redraw for the item*/
@@ -189,9 +196,11 @@ class CORE_EXPORT QgsComposerObject: public QObject
189196
* @returns true if data defined property could be successfully evaluated
190197
* @param property data defined property to evaluate
191198
* @param expressionValue QVariant for storing the evaluated value
199+
* @param context expression context for evaluating expressions. Must have feature and fields set to current
200+
* atlas feature and coverage layer fields prior to calling this method.
192201
* @note this method was added in version 2.5
193202
*/
194-
bool dataDefinedEvaluate( const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue ) const;
203+
bool dataDefinedEvaluate( const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext& context ) const;
195204

196205
signals:
197206
/** Emitted when the item changes. Signifies that the item widgets must update the

‎src/core/composer/qgscomposition.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3062,7 +3062,9 @@ QStringList QgsComposition::customProperties() const
30623062
return mCustomProperties.keys();
30633063
}
30643064

3065-
bool QgsComposition::dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties )
3065+
bool QgsComposition::dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue,
3066+
const QgsExpressionContext& context,
3067+
QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties )
30663068
{
30673069
if ( property == QgsComposerObject::NoProperty || property == QgsComposerObject::AllProperties )
30683070
{
@@ -3092,7 +3094,7 @@ bool QgsComposition::dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty
30923094
}
30933095

30943096
//evaluate data defined property using current atlas context
3095-
QVariant result = dataDefinedValue( property, useFeature ? &currentFeature : 0, layerFields, dataDefinedProperties );
3097+
QVariant result = dataDefinedValue( property, useFeature ? &currentFeature : 0, layerFields, context, dataDefinedProperties );
30963098

30973099
if ( result.isValid() )
30983100
{
@@ -3132,7 +3134,7 @@ bool QgsComposition::dataDefinedActive( const QgsComposerObject::DataDefinedProp
31323134
return dd->isActive();
31333135
}
31343136

3135-
QVariant QgsComposition::dataDefinedValue( QgsComposerObject::DataDefinedProperty property, const QgsFeature *feature, const QgsFields& fields, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
3137+
QVariant QgsComposition::dataDefinedValue( QgsComposerObject::DataDefinedProperty property, const QgsFeature *feature, const QgsFields& fields, const QgsExpressionContext& context, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
31363138
{
31373139
if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
31383140
{
@@ -3168,14 +3170,14 @@ QVariant QgsComposition::dataDefinedValue( QgsComposerObject::DataDefinedPropert
31683170

31693171
if ( !dd->expressionIsPrepared() )
31703172
{
3171-
prepareDataDefinedExpression( dd, dataDefinedProperties );
3173+
prepareDataDefinedExpression( dd, dataDefinedProperties, context );
31723174
}
31733175

31743176
if ( useExpression && dd->expressionIsPrepared() )
31753177
{
31763178
QgsExpression* expr = dd->expression();
31773179

3178-
result = expr->evaluate( feature );
3180+
result = expr->evaluate( &context );
31793181
if ( expr->hasEvalError() )
31803182
{
31813183
QgsDebugMsgLevel( QString( "Evaluate error:" ) + expr->evalErrorString(), 4 );
@@ -3198,34 +3200,42 @@ QVariant QgsComposition::dataDefinedValue( QgsComposerObject::DataDefinedPropert
31983200
return result;
31993201
}
32003202

3201-
void QgsComposition::prepareDataDefinedExpression( QgsDataDefined *dd, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
3203+
void QgsComposition::prepareDataDefinedExpression( QgsDataDefined *dd, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties,
3204+
const QgsExpressionContext& context ) const
32023205
{
3203-
QgsVectorLayer* atlasLayer = 0;
3204-
3205-
if ( mAtlasComposition.enabled() )
3206-
{
3207-
atlasLayer = mAtlasComposition.coverageLayer();
3208-
}
3209-
32103206
//if specific QgsDataDefined passed, prepare it
32113207
//otherwise prepare all QgsDataDefineds
32123208
if ( dd )
32133209
{
3214-
dd->prepareExpression( atlasLayer );
3210+
dd->prepareExpression( context );
32153211
}
32163212
else
32173213
{
32183214
QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->constBegin();
32193215
for ( ; it != dataDefinedProperties->constEnd(); ++it )
32203216
{
3221-
it.value()->prepareExpression( atlasLayer );
3217+
it.value()->prepareExpression( context );
32223218
}
32233219
}
32243220
}
32253221

3222+
QgsExpressionContext* QgsComposition::createExpressionContext() const
3223+
{
3224+
QgsExpressionContext* context = new QgsExpressionContext();
3225+
context->appendScope( QgsExpressionContextUtils::globalScope() );
3226+
context->appendScope( QgsExpressionContextUtils::projectScope() );
3227+
context->appendScope( QgsExpressionContextUtils::compositionScope( this ) );
3228+
if ( mAtlasComposition.enabled() )
3229+
{
3230+
context->appendScope( QgsExpressionContextUtils::atlasScope( &mAtlasComposition ) );
3231+
}
3232+
return context;
3233+
}
3234+
32263235
void QgsComposition::prepareAllDataDefinedExpressions()
32273236
{
3228-
prepareDataDefinedExpression( 0, &mDataDefinedProperties );
3237+
QScopedPointer< QgsExpressionContext > context( createExpressionContext() );
3238+
prepareDataDefinedExpression( 0, &mDataDefinedProperties, *context.data() );
32293239
}
32303240

32313241
void QgsComposition::relativeResizeRect( QRectF& rectToResize, const QRectF& boundsBefore, const QRectF& boundsAfter )

‎src/core/composer/qgscomposition.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,10 +858,13 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
858858
* @returns true if data defined property could be successfully evaluated
859859
* @param property data defined property to evaluate
860860
* @param expressionValue QVariant for storing the evaluated value
861+
* @param context expression context for evaluating expressions. Must have feature and fields set
862+
* to corresponding atlas feature and coverage layer fields prior to calling this method.
861863
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
862864
* @note this method was added in version 2.5
863865
*/
864866
bool dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue,
867+
const QgsExpressionContext& context,
865868
QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties );
866869

867870
/** Returns whether a data defined property has been set and is currently active.
@@ -876,19 +879,29 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
876879
* @param property data defined property to evaluate
877880
* @param feature current atlas feature to evaluate property for
878881
* @param fields fields from atlas layer
882+
* @param context expression context for evaluating expressions (note, must have fields and feature set)
879883
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
880884
* @note this method was added in version 2.5
881885
*/
882886
QVariant dataDefinedValue( QgsComposerObject::DataDefinedProperty property, const QgsFeature *feature, const QgsFields& fields,
887+
const QgsExpressionContext& context,
883888
QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const;
884889

885890

886-
/** Prepares the expression for a data defined property, using the current atlas layer if set.
891+
/** Prepares the expression for a data defined property.
887892
* @param dd data defined to prepare. If no data defined is set, all data defined expressions will be prepared
888893
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
894+
* @param context expression context for expression preparation. Should have fields set to match the current atlas layer if required prior
895+
* to calling this method.
889896
* @note this method was added in version 2.5
890897
*/
891-
void prepareDataDefinedExpression( QgsDataDefined *dd, QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties ) const;
898+
void prepareDataDefinedExpression( QgsDataDefined *dd, QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties, const QgsExpressionContext& context ) const;
899+
900+
/** Creates an expression context relating to the compositions's current state. The context includes
901+
* scopes for global, project, composition and atlas properties.
902+
* @note added in QGIS 2.12
903+
*/
904+
QgsExpressionContext* createExpressionContext() const;
892905

893906
/** Check whether any data defined page settings are active.
894907
* @returns true if any data defined page settings are active.

‎src/core/qgsexpressioncontext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ QgsExpressionContextScope* QgsExpressionContextUtils::atlasScope( const QgsAtlas
676676
{
677677
QgsFeature atlasFeature = atlas->feature();
678678
scope->setFeature( atlasFeature );
679+
scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_feature", QVariant::fromValue( atlasFeature ), true ) );
679680
scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_featureid", atlasFeature.id(), true ) );
680681
}
681682

0 commit comments

Comments
 (0)
Please sign in to comment.