Allow adding sources to processing expression context

This commit is contained in:
Matthias Kuhn 2017-11-22 17:46:30 +01:00
parent 3a576d80b2
commit 851adb0a3d
9 changed files with 59 additions and 7 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -695,3 +695,8 @@ QVariant QgsProcessingFeatureSource::maximumValue( int fieldIndex ) const
{
return mSource->maximumValue( fieldIndex );
}
QgsFeatureSource *QgsProcessingFeatureSource::source() const
{
return mSource;
}

View File

@ -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;

View File

@ -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 );

View File

@ -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