Skip to content

Commit

Permalink
Allow adding sources to processing expression context
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Nov 23, 2017
1 parent 3a576d8 commit 851adb0
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 7 deletions.
4 changes: 3 additions & 1 deletion python/core/processing/qgsprocessingalgorithm.sip
Expand Up @@ -326,10 +326,12 @@ class QgsProcessingAlgorithm
%End

QgsExpressionContext createExpressionContext( const QVariantMap &parameters,
QgsProcessingContext &context ) const;
QgsProcessingContext &context, QgsProcessingFeatureSource *source = 0 ) const;
%Docstring
Creates an expression context relating to the algorithm. This can be called by algorithms
to create a new expression context ready for evaluating expressions within the algorithm.
Optionally, a ``source`` can be specified which will be used to populate the context if it
implements the QgsExpressionContextGenerator interface.
:rtype: QgsExpressionContext
%End

Expand Down
6 changes: 6 additions & 0 deletions python/core/processing/qgsprocessingutils.sip
Expand Up @@ -274,6 +274,12 @@ class QgsProcessingFeatureSource : QgsFeatureSource
virtual QVariant maximumValue( int fieldIndex ) const;


QgsFeatureSource *source() const;
%Docstring
Access the underlying original ``source``.
:rtype: QgsFeatureSource
%End

};


Expand Down
1 change: 1 addition & 0 deletions python/core/qgsexpressioncontext.sip
Expand Up @@ -562,6 +562,7 @@ Constructor for QgsExpressionContext
%End



void setFeature( const QgsFeature &feature );
%Docstring
Convenience function for setting a feature for the context. The feature
Expand Down
24 changes: 19 additions & 5 deletions src/core/processing/qgsprocessingalgorithm.cpp
Expand Up @@ -124,16 +124,30 @@ QWidget *QgsProcessingAlgorithm::createCustomParametersWidget( QWidget * ) const
}

QgsExpressionContext QgsProcessingAlgorithm::createExpressionContext( const QVariantMap &parameters,
QgsProcessingContext &context ) const
QgsProcessingContext &context, QgsProcessingFeatureSource *source ) const
{
// start with context's expression context
QgsExpressionContext c = context.expressionContext();
if ( c.scopeCount() == 0 )

// If there's a source capable of generating a context scope, use it
if ( source )
{
//empty scope, populate with initial scopes
c << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( context.project() );
QgsExpressionContextGenerator *generator = dynamic_cast<QgsExpressionContextGenerator *>( source->source() );
if ( generator )
{
const auto &scopes = generator->createExpressionContext().takeScopes();
for ( QgsExpressionContextScope *scope : scopes )
c << scope;
}
}
else

if ( c.scopeCount() == 0 )
{
//empty scope, populate with initial scopes
c << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( context.project() );
}

c << QgsExpressionContextUtils::processingAlgorithmScope( this, parameters, context );
return c;
Expand Down
4 changes: 3 additions & 1 deletion src/core/processing/qgsprocessingalgorithm.h
Expand Up @@ -339,9 +339,11 @@ class CORE_EXPORT QgsProcessingAlgorithm
/**
* Creates an expression context relating to the algorithm. This can be called by algorithms
* to create a new expression context ready for evaluating expressions within the algorithm.
* Optionally, a \a source can be specified which will be used to populate the context if it
* implements the QgsExpressionContextGenerator interface.
*/
QgsExpressionContext createExpressionContext( const QVariantMap &parameters,
QgsProcessingContext &context ) const;
QgsProcessingContext &context, QgsProcessingFeatureSource *source = nullptr ) const;

/**
* Checks whether the coordinate reference systems for the specified set of \a parameters
Expand Down
5 changes: 5 additions & 0 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -695,3 +695,8 @@ QVariant QgsProcessingFeatureSource::maximumValue( int fieldIndex ) const
{
return mSource->maximumValue( fieldIndex );
}

QgsFeatureSource *QgsProcessingFeatureSource::source() const
{
return mSource;
}
5 changes: 5 additions & 0 deletions src/core/processing/qgsprocessingutils.h
Expand Up @@ -317,6 +317,11 @@ class CORE_EXPORT QgsProcessingFeatureSource : public QgsFeatureSource
QVariant minimumValue( int fieldIndex ) const override;
QVariant maximumValue( int fieldIndex ) const override;

/**
* Access the underlying original \a source.
*/
QgsFeatureSource *source() const;

private:

QgsFeatureSource *mSource = nullptr;
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsexpressioncontext.cpp
Expand Up @@ -474,6 +474,13 @@ QgsExpressionContextScope *QgsExpressionContext::popScope()
return nullptr;
}

QList<QgsExpressionContextScope *> QgsExpressionContext::takeScopes()
{
QList<QgsExpressionContextScope *> stack = mStack;
mStack.clear();
return stack;
}

QgsExpressionContext &QgsExpressionContext::operator<<( QgsExpressionContextScope *scope )
{
mStack.append( scope );
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsexpressioncontext.h
Expand Up @@ -581,6 +581,16 @@ class CORE_EXPORT QgsExpressionContext
*/
QgsExpressionContextScope *popScope();

/**
* Return all scopes from this context and remove them, leaving this context without
* any context.
* Ownership is transferred to the caller.
*
* \since QGIS 3.0
* \note Not available in Python
*/
QList<QgsExpressionContextScope *> takeScopes() SIP_SKIP;

/**
* Appends a scope to the end of the context. This scope will override
* any matching variables or functions provided by existing scopes within the
Expand Down

0 comments on commit 851adb0

Please sign in to comment.