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 %End
QgsExpressionContext createExpressionContext( const QVariantMap &parameters, QgsExpressionContext createExpressionContext( const QVariantMap &parameters,
QgsProcessingContext &context ) const; QgsProcessingContext &context, QgsProcessingFeatureSource *source = 0 ) const;
%Docstring %Docstring
Creates an expression context relating to the algorithm. This can be called by algorithms 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. 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 :rtype: QgsExpressionContext
%End %End

View File

@ -274,6 +274,12 @@ class QgsProcessingFeatureSource : QgsFeatureSource
virtual QVariant maximumValue( int fieldIndex ) const; 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 %End
void setFeature( const QgsFeature &feature ); void setFeature( const QgsFeature &feature );
%Docstring %Docstring
Convenience function for setting a feature for the context. The feature Convenience function for setting a feature for the context. The feature

View File

@ -124,10 +124,24 @@ QWidget *QgsProcessingAlgorithm::createCustomParametersWidget( QWidget * ) const
} }
QgsExpressionContext QgsProcessingAlgorithm::createExpressionContext( const QVariantMap &parameters, QgsExpressionContext QgsProcessingAlgorithm::createExpressionContext( const QVariantMap &parameters,
QgsProcessingContext &context ) const QgsProcessingContext &context, QgsProcessingFeatureSource *source ) const
{ {
// start with context's expression context // start with context's expression context
QgsExpressionContext c = context.expressionContext(); QgsExpressionContext c = context.expressionContext();
// If there's a source capable of generating a context scope, use it
if ( source )
{
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 ) if ( c.scopeCount() == 0 )
{ {
//empty scope, populate with initial scopes //empty scope, populate with initial scopes

View File

@ -339,9 +339,11 @@ class CORE_EXPORT QgsProcessingAlgorithm
/** /**
* Creates an expression context relating to the algorithm. This can be called by algorithms * 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. * 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, 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 * 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 ); 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 minimumValue( int fieldIndex ) const override;
QVariant maximumValue( int fieldIndex ) const override; QVariant maximumValue( int fieldIndex ) const override;
/**
* Access the underlying original \a source.
*/
QgsFeatureSource *source() const;
private: private:
QgsFeatureSource *mSource = nullptr; QgsFeatureSource *mSource = nullptr;

View File

@ -474,6 +474,13 @@ QgsExpressionContextScope *QgsExpressionContext::popScope()
return nullptr; return nullptr;
} }
QList<QgsExpressionContextScope *> QgsExpressionContext::takeScopes()
{
QList<QgsExpressionContextScope *> stack = mStack;
mStack.clear();
return stack;
}
QgsExpressionContext &QgsExpressionContext::operator<<( QgsExpressionContextScope *scope ) QgsExpressionContext &QgsExpressionContext::operator<<( QgsExpressionContextScope *scope )
{ {
mStack.append( scope ); mStack.append( scope );

View File

@ -581,6 +581,16 @@ class CORE_EXPORT QgsExpressionContext
*/ */
QgsExpressionContextScope *popScope(); 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 * Appends a scope to the end of the context. This scope will override
* any matching variables or functions provided by existing scopes within the * any matching variables or functions provided by existing scopes within the