From 2bb1c8a31bd936cf6ffda63f3f0839181a460a01 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 13 Aug 2015 10:10:26 +1000 Subject: [PATCH] Start on implementing contexts for render operations --- python/core/qgsmapsettings.sip | 13 +++++++++++++ src/core/composer/qgscomposermap.cpp | 4 ++++ src/core/qgsmapsettings.h | 15 +++++++++++++++ src/core/qgsrendercontext.cpp | 1 + src/core/qgsrendercontext.h | 25 +++++++++++++++++++++++++ src/core/qgsvectorlayerrenderer.cpp | 7 +++++++ 6 files changed, 65 insertions(+) diff --git a/python/core/qgsmapsettings.sip b/python/core/qgsmapsettings.sip index f7af8766e31..4cc4711546a 100644 --- a/python/core/qgsmapsettings.sip +++ b/python/core/qgsmapsettings.sip @@ -118,6 +118,19 @@ class QgsMapSettings //! Return the calculated scale of the map double scale() const; + /** Sets the expression context. This context is used for all expression evaluation + * associated with this map settings. + * @see expressionContext() + * @note added in QGIS 2.12 + */ + void setExpressionContext( const QgsExpressionContext& context ); + + /** Gets the expression context. This context should be used for all expression evaluation + * associated with this map settings. + * @see setExpressionContext() + * @note added in QGIS 2.12 + */ + const QgsExpressionContext& expressionContext() const; // -- utility functions -- diff --git a/src/core/composer/qgscomposermap.cpp b/src/core/composer/qgscomposermap.cpp index d3cc41a6f89..14ade12cf5a 100644 --- a/src/core/composer/qgscomposermap.cpp +++ b/src/core/composer/qgscomposermap.cpp @@ -232,6 +232,10 @@ QgsMapSettings QgsComposerMap::mapSettings( const QgsRectangle& extent, const QS jobMapSettings.setFlag( QgsMapSettings::UseRenderingOptimization, false ); } + QgsExpressionContext* context = createExpressionContext(); + jobMapSettings.setExpressionContext( *context ); + delete context; + //update $map variable. Use QgsComposerItem's id since that is user-definable QgsExpression::setSpecialColumn( "$map", QgsComposerItem::id() ); diff --git a/src/core/qgsmapsettings.h b/src/core/qgsmapsettings.h index 3873ed88e28..0032924971f 100644 --- a/src/core/qgsmapsettings.h +++ b/src/core/qgsmapsettings.h @@ -26,6 +26,7 @@ #include "qgsmaptopixel.h" #include "qgsrectangle.h" #include "qgsscalecalculator.h" +#include "qgsexpressioncontext.h" class QPainter; @@ -164,6 +165,19 @@ class CORE_EXPORT QgsMapSettings //! Return the calculated scale of the map double scale() const; + /** Sets the expression context. This context is used for all expression evaluation + * associated with this map settings. + * @see expressionContext() + * @note added in QGIS 2.12 + */ + void setExpressionContext( const QgsExpressionContext& context ) { mExpressionContext = context; } + + /** Gets the expression context. This context should be used for all expression evaluation + * associated with this map settings. + * @see setExpressionContext() + * @note added in QGIS 2.12 + */ + const QgsExpressionContext& expressionContext() const { return mExpressionContext; } // -- utility functions -- @@ -240,6 +254,7 @@ class CORE_EXPORT QgsMapSettings QStringList mLayers; QMap mLayerStyleOverrides; + QgsExpressionContext mExpressionContext; bool mProjectionsEnabled; QgsCoordinateReferenceSystem mDestCRS; diff --git a/src/core/qgsrendercontext.cpp b/src/core/qgsrendercontext.cpp index a9dbd4f0cf8..c3d0ea8e0dd 100644 --- a/src/core/qgsrendercontext.cpp +++ b/src/core/qgsrendercontext.cpp @@ -56,6 +56,7 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings& mapSet ctx.setRasterScaleFactor( 1.0 ); ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm ctx.setRendererScale( mapSettings.scale() ); + ctx.setExpressionContext( mapSettings.expressionContext() ); //this flag is only for stopping during the current rendering progress, //so must be false at every new render operation diff --git a/src/core/qgsrendercontext.h b/src/core/qgsrendercontext.h index fd423e2999e..44f89f8d968 100644 --- a/src/core/qgsrendercontext.h +++ b/src/core/qgsrendercontext.h @@ -24,6 +24,7 @@ #include "qgsmaptopixel.h" #include "qgsrectangle.h" #include "qgsvectorsimplifymethod.h" +#include "qgsexpressioncontext.h" class QPainter; @@ -118,6 +119,27 @@ class CORE_EXPORT QgsRenderContext const QgsVectorSimplifyMethod& vectorSimplifyMethod() const { return mVectorSimplifyMethod; } void setVectorSimplifyMethod( const QgsVectorSimplifyMethod& simplifyMethod ) { mVectorSimplifyMethod = simplifyMethod; } + /** Sets the expression context. This context is used for all expression evaluation + * associated with this render context. + * @see expressionContext() + * @note added in QGIS 2.12 + */ + void setExpressionContext( const QgsExpressionContext& context ) { mExpressionContext = context; } + + /** Gets the expression context. This context should be used for all expression evaluation + * associated with this render context. + * @see setExpressionContext() + * @note added in QGIS 2.12 + */ + QgsExpressionContext& expressionContext() { return mExpressionContext; } + + /** Gets the expression context (const version). This context should be used for all expression evaluation + * associated with this render context. + * @see setExpressionContext() + * @note added in QGIS 2.12 + */ + const QgsExpressionContext& expressionContext() const { return mExpressionContext; } + private: /** Painter for rendering operations*/ @@ -165,6 +187,9 @@ class CORE_EXPORT QgsRenderContext /** Simplification object which holds the information about how to simplify the features for fast rendering */ QgsVectorSimplifyMethod mVectorSimplifyMethod; + + /** Expression context */ + QgsExpressionContext mExpressionContext; }; #endif diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp index feb2c32bef7..8dbbca0d36a 100644 --- a/src/core/qgsvectorlayerrenderer.cpp +++ b/src/core/qgsvectorlayerrenderer.cpp @@ -92,6 +92,8 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender mRendererV2->setVertexMarkerAppearance( mVertexMarkerStyle, mVertexMarkerSize ); } + mContext.expressionContext() << QgsExpressionContextUtils::layerScope( layer ); + mAttrNames = mRendererV2->usedAttributes(); //register label and diagram layer to the labeling engine @@ -280,6 +282,8 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit ) break; } + mContext.expressionContext().setFeature( fet ); + bool sel = mContext.showSelection() && mSelectedFeatureIds.contains( fet.id() ); bool drawMarker = ( mDrawVertexMarkers && mContext.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) ); @@ -364,6 +368,7 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit ) if ( mContext.labelingEngine() ) { + mContext.expressionContext().setFeature( fet ); if ( mLabeling ) { mContext.labelingEngine()->registerFeature( mLayerID, fet, mContext ); @@ -420,6 +425,8 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit ) // maybe vertex markers should be drawn only during the last pass... bool drawMarker = ( mDrawVertexMarkers && mContext.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) ); + mContext.expressionContext().setFeature( *fit ); + try { mRendererV2->renderFeature( *fit, mContext, layer, sel, drawMarker );