Skip to content
Permalink
Browse files

Add atlas expression context scope to layouts

  • Loading branch information
nyalldawson committed Dec 20, 2017
1 parent 3318bfb commit 5d1d25b36b3d5bc5b1878e043b8f13fb6408cab2
@@ -38,6 +38,8 @@ Constructor for new QgsLayoutAtlas.

virtual QgsLayout *layout();



virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

virtual bool readXml( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );
@@ -35,6 +35,8 @@ Returns the print layout's atlas.

virtual bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );

virtual QgsExpressionContext createExpressionContext() const;


};

@@ -1045,11 +1045,19 @@ with the variables specified.
.. versionadded:: 3.0
%End

static QgsExpressionContextScope *atlasScope( const QgsAtlasComposition *atlas ) /Factory/;
static QgsExpressionContextScope *compositionAtlasScope( const QgsAtlasComposition *atlas ) /Factory/;
%Docstring
Creates a new scope which contains variables and functions relating to a :py:class:`QgsAtlasComposition`.
For instance, current page name and number.

:param atlas: source atlas. If null, a set of default atlas variables will be added to the scope.
%End

static QgsExpressionContextScope *atlasScope( const QgsLayoutAtlas *atlas ) /Factory/;
%Docstring
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
For instance, current page name and number.

:param atlas: source atlas. If null, a set of default atlas variables will be added to the scope.
%End

@@ -52,7 +52,7 @@ QgsExpressionContext QgsDiagramProperties::createExpressionContext() const
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
<< QgsExpressionContextUtils::layerScope( mLayer );

@@ -931,7 +931,7 @@ QString QgsDiagramProperties::showExpressionBuilder( const QString &initialExpre
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
<< QgsExpressionContextUtils::layerScope( mLayer );

@@ -29,7 +29,7 @@ QgsExpressionContext QgsLabelingGui::createExpressionContext() const
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::mapSettingsScope( QgisApp::instance()->mapCanvas()->mapSettings() );

if ( mLayer )
@@ -255,7 +255,7 @@ void QgsLabelPropertyDialog::setDataDefinedValues( QgsVectorLayer *vlayer )
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::mapSettingsScope( QgisApp::instance()->mapCanvas()->mapSettings() )
<< QgsExpressionContextUtils::layerScope( vlayer );
context.setFeature( mCurLabelFeat );
@@ -33,7 +33,7 @@ QgsRenderContext QgsPointMarkerItem::renderContext( QPainter *painter )
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );
if ( mMapCanvas )
{
context << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
@@ -35,7 +35,7 @@ static QList<QgsExpressionContextScope *> _globalProjectAtlasMapLayerScopes( Qgs
QList<QgsExpressionContextScope *> scopes;
scopes << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );
if ( mapCanvas )
{
scopes << QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() )
@@ -130,7 +130,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(

mContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::mapSettingsScope( QgisApp::instance()->mapCanvas()->mapSettings() )
<< QgsExpressionContextUtils::layerScope( mLayer );

@@ -723,7 +723,7 @@ QgsExpressionContext QgsAtlasComposition::createExpressionContext()
expressionContext << QgsExpressionContextUtils::projectScope( mComposition->project() )
<< QgsExpressionContextUtils::compositionScope( mComposition );

expressionContext.appendScope( QgsExpressionContextUtils::atlasScope( this ) );
expressionContext.appendScope( QgsExpressionContextUtils::compositionAtlasScope( this ) );
if ( mCoverageLayer )
expressionContext.lastScope()->setFields( mCoverageLayer->fields() );
if ( mComposition && mComposition->atlasMode() != QgsComposition::AtlasOff )
@@ -3284,7 +3284,7 @@ QgsExpressionContext QgsComposition::createExpressionContext() const
context.appendScope( QgsExpressionContextUtils::compositionScope( this ) );
if ( mAtlasComposition.enabled() )
{
context.appendScope( QgsExpressionContextUtils::atlasScope( &mAtlasComposition ) );
context.appendScope( QgsExpressionContextUtils::compositionAtlasScope( &mAtlasComposition ) );
}
return context;
}
@@ -325,12 +325,6 @@ QgsExpressionContext QgsLayout::createExpressionContext() const
context.appendScope( QgsExpressionContextUtils::globalScope() );
context.appendScope( QgsExpressionContextUtils::projectScope( mProject ) );
context.appendScope( QgsExpressionContextUtils::layoutScope( this ) );
#if 0 //TODO
if ( mAtlasComposition.enabled() )
{
context.appendScope( QgsExpressionContextUtils::atlasScope( &mAtlasComposition ) );
}
#endif
return context;
}

@@ -42,6 +42,11 @@ QgsLayout *QgsLayoutAtlas::layout()
return mLayout;
}

const QgsLayout *QgsLayoutAtlas::layout() const
{
return mLayout.data();
}

bool QgsLayoutAtlas::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & ) const
{
QDomElement atlasElem = document.createElement( QStringLiteral( "Atlas" ) );
@@ -46,6 +46,13 @@ class CORE_EXPORT QgsLayoutAtlas : public QObject, public QgsAbstractLayoutItera

QString stringType() const override;
QgsLayout *layout() override;

/**
* Returns the atlas' layout.
* \note Not available in Python bindings.
*/
const QgsLayout *layout() const SIP_SKIP;

bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;

@@ -29,7 +29,7 @@
#include "qgsfontutils.h"
#include "qgsexpressioncontext.h"
#include "qgsmapsettings.h"
#include "qgscomposermap.h"
#include "qgslayoutitemmap.h"
#include "qgssettings.h"

#include "qgswebview.h"
@@ -69,11 +69,9 @@ QgsLayoutItemLabel::QgsLayoutItemLabel( QgsLayout *layout )

if ( mLayout )
{
#if 0 //TODO
//connect to atlas feature changes
//connect to context feature changes
//to update the expression context
connect( &mLayout->atlasComposition(), &QgsAtlasComposition::featureChanged, this, &QgsLayoutItemLabel::refreshExpressionContext );
#endif
connect( &mLayout->context(), &QgsLayoutContext::changed, this, &QgsLayoutItemLabel::refreshExpressionContext );
}

mWebPage.reset( new QgsWebPage( this ) );
@@ -244,27 +242,18 @@ void QgsLayoutItemLabel::refreshExpressionContext()
if ( !mLayout )
return;

QgsVectorLayer *layer = nullptr;
#if 0 //TODO
if ( mComposition->atlasComposition().enabled() )
{
layer = mComposition->atlasComposition().coverageLayer();
}
#endif

QgsVectorLayer *layer = mLayout->context().layer();
//setup distance area conversion
if ( layer )
{
mDistanceArea->setSourceCrs( layer->crs(), mLayout->project()->transformContext() );
}
else
{
#if 0 //TODO
//set to composition's reference map's crs
QgsLayoutItemMap *referenceMap = mComposition->referenceMap();
QgsLayoutItemMap *referenceMap = mLayout->referenceMap();
if ( referenceMap )
mDistanceArea->setSourceCrs( referenceMap->crs() );
#endif
}
mDistanceArea->setEllipsoid( mLayout->project()->ellipsoid() );
contentChanged();
@@ -44,3 +44,15 @@ bool QgsPrintLayout::readXml( const QDomElement &layoutElement, const QDomDocume
mAtlas->readXml( atlasElem, document, context );
return true;
}

QgsExpressionContext QgsPrintLayout::createExpressionContext() const
{
QgsExpressionContext context = QgsLayout::createExpressionContext();

if ( mAtlas->enabled() )
{
context.appendScope( QgsExpressionContextUtils::atlasScope( mAtlas ) );
}

return context;
}
@@ -45,6 +45,7 @@ class CORE_EXPORT QgsPrintLayout : public QgsLayout

QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context ) override;
QgsExpressionContext createExpressionContext() const override;

private:

@@ -31,6 +31,7 @@
#include "qgsmaplayerlistutils.h"
#include "qgsprocessingcontext.h"
#include "qgsprocessingalgorithm.h"
#include "qgslayoutatlas.h"
#include "qgslayout.h"

#include <QSettings>
@@ -1127,7 +1128,7 @@ void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVa
layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
}

QgsExpressionContextScope *QgsExpressionContextUtils::atlasScope( const QgsAtlasComposition *atlas )
QgsExpressionContextScope *QgsExpressionContextUtils::compositionAtlasScope( const QgsAtlasComposition *atlas )
{
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
if ( !atlas )
@@ -1166,6 +1167,45 @@ QgsExpressionContextScope *QgsExpressionContextUtils::atlasScope( const QgsAtlas
return scope;
}

QgsExpressionContextScope *QgsExpressionContextUtils::atlasScope( const QgsLayoutAtlas *atlas )
{
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
if ( !atlas )
{
//add some dummy atlas variables. This is done so that as in certain contexts we want to show
//users that these variables are available even if they have no current value
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), 0, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true ) );
return scope;
}

//add known atlas variables
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true ) );

if ( atlas->enabled() && atlas->coverageLayer() )
{
scope->setFields( atlas->coverageLayer()->fields() );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
}

if ( atlas->enabled() )
{
QgsFeature atlasFeature = atlas->layout()->context().feature();
scope->setFeature( atlasFeature );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), atlasFeature.id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
}

return scope;
}

QgsExpressionContextScope *QgsExpressionContextUtils::composerItemScope( const QgsComposerItem *composerItem )
{
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Composer Item" ) );
@@ -40,6 +40,7 @@ class QgsProject;
class QgsSymbol;
class QgsProcessingAlgorithm;
class QgsProcessingContext;
class QgsLayoutAtlas;

/**
* \ingroup core
@@ -926,7 +927,14 @@ class CORE_EXPORT QgsExpressionContextUtils
* For instance, current page name and number.
* \param atlas source atlas. If null, a set of default atlas variables will be added to the scope.
*/
static QgsExpressionContextScope *atlasScope( const QgsAtlasComposition *atlas ) SIP_FACTORY;
static QgsExpressionContextScope *compositionAtlasScope( const QgsAtlasComposition *atlas ) SIP_FACTORY;

/**
* Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
* For instance, current page name and number.
* \param atlas source atlas. If null, a set of default atlas variables will be added to the scope.
*/
static QgsExpressionContextScope *atlasScope( const QgsLayoutAtlas *atlas ) SIP_FACTORY;

/**
* Creates a new scope which contains variables and functions relating to a QgsComposerItem.
@@ -635,7 +635,7 @@ void QgsCategorizedSymbolRendererWidget::addCategories()
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr )
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr )
<< QgsExpressionContextUtils::layerScope( mLayer );

expression->prepare( &context );
@@ -1014,7 +1014,7 @@ QgsExpressionContext QgsCategorizedSymbolRendererWidget::createExpressionContext
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );

if ( mContext.mapCanvas() )
{
@@ -178,7 +178,7 @@ void QgsDataDefinedSizeLegendWidget::changeSymbol()
QgsExpressionContext ec;
ec << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );
if ( mMapCanvas )
ec << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() );
context.setExpressionContext( &ec );
@@ -396,7 +396,7 @@ QgsExpressionContext QgsGraduatedSymbolRendererWidget::createExpressionContext()
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );

if ( mContext.mapCanvas() )
{
@@ -38,7 +38,7 @@ QgsExpressionContext QgsHeatmapRendererWidget::createExpressionContext() const
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );

if ( mContext.mapCanvas() )
{
@@ -217,7 +217,7 @@ QgsExpressionContext QgsLayerPropertiesWidget::createExpressionContext() const
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );

if ( mContext.mapCanvas() )
{
@@ -327,7 +327,7 @@ QgsExpressionContext QgsDataDefinedValueDialog::createExpressionContext() const
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );
if ( mContext.mapCanvas() )
{
expContext << QgsExpressionContextUtils::mapSettingsScope( mContext.mapCanvas()->mapSettings() )
@@ -79,7 +79,7 @@ QList<QgsExpressionContextScope *> QgsSymbolWidgetContext::globalProjectAtlasMap
QList<QgsExpressionContextScope *> scopes;
scopes << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::atlasScope( nullptr );
<< QgsExpressionContextUtils::compositionAtlasScope( nullptr );
if ( mMapCanvas )
{
scopes << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )

0 comments on commit 5d1d25b

Please sign in to comment.
You can’t perform that action at this time.