Expression context fixes:

- Fix python API break in QgsExpression::Function
- Add convenience methods for retrieving feature/fields from a
context
This commit is contained in:
Nyall Dawson 2015-09-05 22:03:16 +10:00
parent 86115435f5
commit 1c079ead02
6 changed files with 47 additions and 4 deletions

View File

@ -290,8 +290,9 @@ class QgsExpression
* @param context context expression is being evaluated against
* @param parent parent expression
* @returns result of function
* @note named funcV2 in Python bindings. Will be renamed to func to replace deprecated method in QGIS 3.0.
*/
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) /PyName=funcV2/;
virtual bool handlesNull() const;
};

View File

@ -346,16 +346,28 @@ class QgsExpressionContext
* will be set within the last scope of the context, so will override any
* existing features within the context.
* @param feature feature for context
* @see feature()
*/
void setFeature( const QgsFeature& feature );
/** Convenience function for retrieving the feature for the context, if set.
* @see setFeature
*/
QgsFeature feature() const;
/** Convenience function for setting a fields for the context. The fields
* will be set within the last scope of the context, so will override any
* existing fields within the context.
* @param fields fields for context
* @see fields()
*/
void setFields( const QgsFields& fields );
/** Convenience function for retrieving the fields for the context, if set.
* @see setFields
*/
QgsFields fields() const;
};
/** \ingroup core

View File

@ -399,7 +399,9 @@ class CORE_EXPORT QgsExpression
* @param context context expression is being evaluated against
* @param parent parent expression
* @returns result of function
* @note named funcV2 in Python bindings. Will be renamed to func to replace deprecated method in QGIS 3.0.
*/
//TODO QGIS 3.0 - rename python method
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
bool operator==( const Function& other ) const

View File

@ -350,6 +350,11 @@ void QgsExpressionContext::setFeature( const QgsFeature &feature )
mStack.last()->setFeature( feature );
}
QgsFeature QgsExpressionContext::feature() const
{
return qvariant_cast<QgsFeature>( variable( QgsExpressionContext::EXPR_FEATURE ) );
}
void QgsExpressionContext::setFields( const QgsFields &fields )
{
if ( mStack.isEmpty() )
@ -358,6 +363,11 @@ void QgsExpressionContext::setFields( const QgsFields &fields )
mStack.last()->setFields( fields );
}
QgsFields QgsExpressionContext::fields() const
{
return qvariant_cast<QgsFields>( variable( QgsExpressionContext::EXPR_FIELDS ) );
}
//
// QgsExpressionContextUtils

View File

@ -378,16 +378,28 @@ class CORE_EXPORT QgsExpressionContext
* will be set within the last scope of the context, so will override any
* existing features within the context.
* @param feature feature for context
* @see feature()
*/
void setFeature( const QgsFeature& feature );
/** Convenience function for retrieving the feature for the context, if set.
* @see setFeature
*/
QgsFeature feature() const;
/** Convenience function for setting a fields for the context. The fields
* will be set within the last scope of the context, so will override any
* existing fields within the context.
* @param fields fields for context
* @see fields()
*/
void setFields( const QgsFields& fields );
/** Convenience function for retrieving the fields for the context, if set.
* @see setFields
*/
QgsFields fields() const;
static const QString EXPR_FIELDS;
static const QString EXPR_FEATURE;

View File

@ -411,11 +411,13 @@ void TestQgsExpressionContext::setFeature()
//test setting a feature in a context with no scopes
QgsExpressionContext emptyContext;
QVERIFY( !emptyContext.feature().isValid() );
emptyContext.setFeature( feature );
//setFeature should have created a scope
QCOMPARE( emptyContext.scopeCount(), 1 );
QVERIFY( emptyContext.hasVariable( QgsExpressionContext::EXPR_FEATURE ) );
QCOMPARE(( qvariant_cast<QgsFeature>( emptyContext.variable( QgsExpressionContext::EXPR_FEATURE ) ) ).id(), 50LL );
QCOMPARE( emptyContext.feature(), feature() );
QgsExpressionContext contextWithScope;
contextWithScope << new QgsExpressionContextScope();
@ -423,6 +425,7 @@ void TestQgsExpressionContext::setFeature()
QCOMPARE( contextWithScope.scopeCount(), 1 );
QVERIFY( contextWithScope.hasVariable( QgsExpressionContext::EXPR_FEATURE ) );
QCOMPARE(( qvariant_cast<QgsFeature>( contextWithScope.variable( QgsExpressionContext::EXPR_FEATURE ) ) ).id(), 50LL );
QCOMPARE( contextWithScope.feature(), feature() );
}
void TestQgsExpressionContext::setFields()
@ -438,11 +441,13 @@ void TestQgsExpressionContext::setFields()
//test setting a fields in a context with no scopes
QgsExpressionContext emptyContext;
QVERIFY( emptyContext.fields().isEmpty() );
emptyContext.setFields( fields );
//setFeature should have created a scope
QCOMPARE( emptyContext.scopeCount(), 1 );
QVERIFY( emptyContext.hasVariable( QgsExpressionContext::EXPR_FIELDS ) );
QCOMPARE(( qvariant_cast<QgsFields>( emptyContext.variable( QgsExpressionContext::EXPR_FIELDS ) ) ).at( 0 ).name(), QString( "testfield" ) );
QCOMPARE( emptyContext.fields().at( 0 ).name(), QString( "testfield" ) );
QgsExpressionContext contextWithScope;
contextWithScope << new QgsExpressionContextScope();
@ -450,6 +455,7 @@ void TestQgsExpressionContext::setFields()
QCOMPARE( contextWithScope.scopeCount(), 1 );
QVERIFY( contextWithScope.hasVariable( QgsExpressionContext::EXPR_FIELDS ) );
QCOMPARE(( qvariant_cast<QgsFields>( contextWithScope.variable( QgsExpressionContext::EXPR_FIELDS ) ) ).at( 0 ).name(), QString( "testfield" ) );
QCOMPARE( contextWithScope.fields().at( 0 ).name(), QString( "testfield" ) );
}
void TestQgsExpressionContext::globalScope()