Skip to content

Commit

Permalink
Single parameter version of represent_value
Browse files Browse the repository at this point in the history
Becuase `represent_value("fieldname")` is much shorter to write and in 98%
there is no need to specify the name separately as
`represent_value("fieldname", 'fieldname')`.
  • Loading branch information
m-kuhn committed Sep 29, 2017
1 parent b238103 commit a97d846
Show file tree
Hide file tree
Showing 13 changed files with 353 additions and 290 deletions.
5 changes: 3 additions & 2 deletions python/core/expression/qgsexpressionfunction.sip
Original file line number Diff line number Diff line change
Expand Up @@ -239,17 +239,18 @@ The help text for the function.
:rtype: str
%End

virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) = 0;
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;
%Docstring
Returns result of evaluating the function.
\param values list of values passed to the function
\param context context expression is being evaluated against
\param parent parent expression
\param node expression node
:return: result of function
:rtype: QVariant
%End

virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent );
virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );
%Docstring
:rtype: QVariant
%End
Expand Down
2 changes: 1 addition & 1 deletion python/core/qgsexpressioncontext.sip
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class QgsScopedExpressionFunction : QgsExpressionFunction
.. versionadded:: 3.0
%End

virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) = 0;
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;

virtual QgsScopedExpressionFunction *clone() const = 0 /Factory/;
%Docstring
Expand Down
7 changes: 4 additions & 3 deletions resources/function_help/json/represent_value
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"type": "function",
"description": "Returns the configured representation value for a field value. It depends on the configured widget type. Often, this is useful for 'Value Map' widgets.",
"arguments": [
{"arg":"fieldName", "description": "The field name for which the widget configuration should be loaded."},
{"arg":"value", "description": "The value which should be resolved. Most likely a field." }
{"arg":"value", "description": "The value which should be resolved. Most likely a field." },
{"arg":"fieldName", "description": "The field name for which the widget configuration should be loaded. (Optional)"}
],
"examples": [
{ "expression":"represent_value('field_with_value_map', \"field_with_value_map\")", "returns":"Description for value"}
{ "expression":"represent_value(\"field_with_value_map\")", "returns":"Description for value"},
{ "expression":"represent_value('static value', 'field_name')", "returns":"Description for static value"}
]
}
10 changes: 8 additions & 2 deletions src/core/expression/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,15 @@ bool QgsExpression::isValid() const
return d->mRootNode;
}

bool QgsExpression::hasParserError() const { return !d->mParserErrorString.isNull(); }
bool QgsExpression::hasParserError() const
{
return !d->mParserErrorString.isNull();
}

QString QgsExpression::parserErrorString() const { return d->mParserErrorString; }
QString QgsExpression::parserErrorString() const
{
return d->mParserErrorString;
}

QSet<QString> QgsExpression::referencedColumns() const
{
Expand Down
554 changes: 298 additions & 256 deletions src/core/expression/qgsexpressionfunction.cpp

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions src/core/expression/qgsexpressionfunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CORE_EXPORT QgsExpressionFunction

/** Function definition for evaluation against an expression context, using a list of values as parameters to the function.
*/
typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) SIP_SKIP;
typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) SIP_SKIP;

/** \ingroup core
* Represents a single parameter passed to a function.
Expand Down Expand Up @@ -271,11 +271,12 @@ class CORE_EXPORT QgsExpressionFunction
* \param values list of values passed to the function
* \param context context expression is being evaluated against
* \param parent parent expression
* \param node expression node
* \returns result of function
*/
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) = 0;
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;

virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent );
virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );

bool operator==( const QgsExpressionFunction &other ) const;

Expand Down Expand Up @@ -402,9 +403,9 @@ class QgsStaticExpressionFunction : public QgsExpressionFunction
* \param parent parent expression
* \returns result of function
*/
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) override
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
{
return mFnc ? mFnc( values, context, parent ) : QVariant();
return mFnc ? mFnc( values, context, parent, node ) : QVariant();
}

virtual QStringList aliases() const override;
Expand Down Expand Up @@ -471,9 +472,9 @@ class QgsWithVariableExpressionFunction : public QgsExpressionFunction

bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;

QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent ) override;
QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;

QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) override;
QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;

bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;

Expand Down
2 changes: 1 addition & 1 deletion src/core/expression/qgsexpressionnodeimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ QVariant QgsExpressionNodeFunction::evalNode( QgsExpression *parent, const QgsEx
QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
QgsExpressionFunction *fd = context && context->hasFunction( name ) ? context->function( name ) : QgsExpression::QgsExpression::Functions()[mFnIndex];

QVariant res = fd->run( mArgs, context, parent );
QVariant res = fd->run( mArgs, context, parent, this );
ENSURE_NO_EVAL_ERROR;

// everything went fine
Expand Down
1 change: 0 additions & 1 deletion src/core/expression/qgsexpressionnodeimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ class CORE_EXPORT QgsExpressionNodeFunction : public QgsExpressionNode
private:
int mFnIndex;
NodeList *mArgs = nullptr;

};

/** \ingroup core
Expand Down
8 changes: 4 additions & 4 deletions src/core/qgsexpressioncontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ class GetNamedProjectColor : public QgsScopedExpressionFunction
}
}

QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression * ) override
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
QString colorName = values.at( 0 ).toString().toLower();
if ( mColors.contains( colorName ) )
Expand Down Expand Up @@ -657,7 +657,7 @@ class GetComposerItemVariables : public QgsScopedExpressionFunction
, mComposition( c )
{}

QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression * ) override
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
if ( !mComposition )
return QVariant();
Expand Down Expand Up @@ -692,7 +692,7 @@ class GetLayerVisibility : public QgsScopedExpressionFunction
, mLayers( layers )
{}

QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression * ) override
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
if ( mLayers.isEmpty() )
{
Expand Down Expand Up @@ -729,7 +729,7 @@ class GetProcessingParameterValue : public QgsScopedExpressionFunction
, mParams( params )
{}

QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression * ) override
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
return mParams.value( values.at( 0 ).toString() );
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsexpressioncontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpressionFunction
, mReferencedColumns( referencedColumns )
{}

virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) override = 0;
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override = 0;

/** Returns a clone of the function.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,8 +777,8 @@ void qgisFunctionWrapper( sqlite3_context *ctxt, int nArgs, sqlite3_value **args
};
}

QgsExpression parentExpr( QLatin1String( "" ) );
QVariant ret = foo->func( variants, &qgisFunctionExpressionContext, &parentExpr );
QgsExpression parentExpr = QgsExpression( QString() );
QVariant ret = foo->func( variants, &qgisFunctionExpressionContext, &parentExpr, nullptr );
if ( parentExpr.hasEvalError() )
{
QByteArray ba = parentExpr.evalErrorString().toUtf8();
Expand Down
17 changes: 15 additions & 2 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ class TestQgsExpression: public QObject

// Usage on a value map
QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mPointsLayer ) );
QgsExpression expression( "represent_value('Pilots', \"Pilots\")" );
QgsExpression expression( "represent_value(\"Pilots\", 'Pilots')" );
if ( expression.hasParserError() )
qDebug() << expression.parserErrorString();
Q_ASSERT( !expression.hasParserError() );
Expand All @@ -401,7 +401,7 @@ class TestQgsExpression: public QObject
QCOMPARE( expression.evaluate( &context ).toString(), QStringLiteral( "one" ) );

// Usage on a simple string
QgsExpression expression2( "represent_value('Class', \"Class\")" );
QgsExpression expression2( "represent_value(\"Class\", 'Class')" );
if ( expression2.hasParserError() )
qDebug() << expression2.parserErrorString();
Q_ASSERT( !expression2.hasParserError() );
Expand All @@ -412,6 +412,19 @@ class TestQgsExpression: public QObject
mPointsLayer->getFeatures( QgsFeatureRequest().setFilterExpression( "Class = 'Jet'" ) ).nextFeature( feature );
context.setFeature( feature );
QCOMPARE( expression2.evaluate( &context ).toString(), QStringLiteral( "Jet" ) );

// Test with implicit field name discovery
QgsExpression expression3( "represent_value(\"Pilots\")" );
if ( expression3.hasParserError() )
qDebug() << expression.parserErrorString();
Q_ASSERT( !expression3.hasParserError() );
if ( expression3.hasEvalError() )
qDebug() << expression3.evalErrorString();
Q_ASSERT( !expression3.hasEvalError() );
expression3.prepare( &context );
mPointsLayer->getFeatures( QgsFeatureRequest().setFilterExpression( "Pilots = 1" ) ).nextFeature( feature );
context.setFeature( feature );
QCOMPARE( expression.evaluate( &context ).toString(), QStringLiteral( "one" ) );
}

void evaluation_data()
Expand Down
16 changes: 8 additions & 8 deletions tests/src/core/testqgsexpressioncontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class TestQgsExpressionContext : public QObject
GetTestValueFunction()
: QgsScopedExpressionFunction( QStringLiteral( "get_test_value" ), 1, QStringLiteral( "test" ) ) {}

virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression * ) override
virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
return 42;
}
Expand All @@ -80,7 +80,7 @@ class TestQgsExpressionContext : public QObject
GetTestValueFunction2()
: QgsScopedExpressionFunction( QStringLiteral( "get_test_value" ), 1, QStringLiteral( "test" ) ) {}

virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression * ) override
virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
return 43;
}
Expand All @@ -99,7 +99,7 @@ class TestQgsExpressionContext : public QObject
, mVal( v )
{}

virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression * ) override
virtual QVariant func( const QVariantList &, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
{
if ( !mVal )
return QVariant();
Expand Down Expand Up @@ -228,7 +228,7 @@ void TestQgsExpressionContext::contextScopeFunctions()
QVERIFY( scope.hasFunction( "get_test_value" ) );
QVERIFY( scope.function( "get_test_value" ) );
QgsExpressionContext temp;
QCOMPARE( scope.function( "get_test_value" )->func( QVariantList(), &temp, 0 ).toInt(), 42 );
QCOMPARE( scope.function( "get_test_value" )->func( QVariantList(), &temp, 0, nullptr ).toInt(), 42 );

//test functionNames
scope.addFunction( QStringLiteral( "get_test_value2" ), new GetTestValueFunction() );
Expand Down Expand Up @@ -371,27 +371,27 @@ void TestQgsExpressionContext::contextStackFunctions()
QVERIFY( context.hasFunction( "get_test_value" ) );
QVERIFY( context.function( "get_test_value" ) );
QgsExpressionContext temp;
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0 ).toInt(), 42 );
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0, nullptr ).toInt(), 42 );

//add a second scope, should override the first
context << new QgsExpressionContextScope();
//test without setting function first...
QVERIFY( context.hasFunction( "get_test_value" ) );
QVERIFY( context.function( "get_test_value" ) );
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0 ).toInt(), 42 );
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0, nullptr ).toInt(), 42 );

//then set the variable so it overrides
QgsExpressionContextScope *scope2 = context.scope( 1 );
scope2->addFunction( QStringLiteral( "get_test_value" ), new GetTestValueFunction2() );
QVERIFY( context.hasFunction( "get_test_value" ) );
QVERIFY( context.function( "get_test_value" ) );
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0 ).toInt(), 43 );
QCOMPARE( context.function( "get_test_value" )->func( QVariantList(), &temp, 0, nullptr ).toInt(), 43 );

//make sure stack falls back to earlier contexts
scope2->addFunction( QStringLiteral( "get_test_value2" ), new GetTestValueFunction() );
QVERIFY( context.hasFunction( "get_test_value2" ) );
QVERIFY( context.function( "get_test_value2" ) );
QCOMPARE( context.function( "get_test_value2" )->func( QVariantList(), &temp, 0 ).toInt(), 42 );
QCOMPARE( context.function( "get_test_value2" )->func( QVariantList(), &temp, 0, nullptr ).toInt(), 42 );

//test functionNames
QStringList names = context.functionNames();
Expand Down

0 comments on commit a97d846

Please sign in to comment.