Skip to content
Permalink
Browse files

Add method for specifying variable description when adding to contexts

And use this description in expression builders when it's set.
  • Loading branch information
nyalldawson committed Jul 7, 2017
1 parent 534844f commit 35e16b2f315801250729260e429a5a67d8c4d49d
@@ -1116,6 +1116,8 @@ version instead.
- QgsExpression::Node::referencedColumns() returns QSet<QString> instead of QStringList
- `QgsExpression::Node` was renamed to `QgsExpressionNode`
- `QgsExpression::Function` was renamed to `QgsExpressionFunction`
- variableHelpText() no longer returns a formatted HTML string. It now just returns the plain text help string. Use formatVariableHelp()
to obtain the formatted version.


QgsExpression::Function {#qgis_api_break_3_0_QgsExpression_Function}
@@ -464,10 +464,11 @@ return index of the function in Functions array
Returns the help text for a specified function.
\param name function name
.. seealso:: variableHelpText()
.. seealso:: formatVariableHelp()
:rtype: str
%End

static QString variableHelpText( const QString &variableName, bool showValue = true, const QVariant &value = QVariant() );
static QString variableHelpText( const QString &variableName );
%Docstring
Returns the help text for a specified variable.
\param variableName name of variable
@@ -478,6 +479,18 @@ return index of the function in Functions array
:rtype: str
%End

static QString formatVariableHelp( const QString &description, bool showValue = true, const QVariant &value = QVariant() );
%Docstring
Returns formatted help text for a variable.
\param description translated description of variable
\param showValue set to true to include current value of variable in help text
\param value current value of variable to show in help text
.. seealso:: helpText()
.. seealso:: variableHelpText()
.. versionadded:: 3.0
:rtype: str
%End

static QString group( const QString &group );
%Docstring
Returns the translated name for a function group.
@@ -92,13 +92,14 @@ class QgsExpressionContextScope
struct StaticVariable
{

StaticVariable( const QString &name = QString(), const QVariant &value = QVariant(), bool readOnly = false, bool isStatic = false );
StaticVariable( const QString &name = QString(), const QVariant &value = QVariant(), bool readOnly = false, bool isStatic = false, const QString &description = QString() );
%Docstring
Constructor for StaticVariable.
\param name variable name (should be unique within the QgsExpressionContextScope)
\param value initial variable value
\param readOnly true if variable should not be editable by users
\param isStatic true if the variable will not change during the lifteime of an iterator.
\param description optional translated description of variable, for use in expression builder widgets
%End

QString name;
@@ -119,6 +120,11 @@ True if variable should not be editable by users
bool isStatic;
%Docstring
A static variable can be cached for the lifetime of a context
%End

QString description;
%Docstring
Translated description of variable, for use within expression builder widgets.
%End
};

@@ -224,6 +230,15 @@ A static variable can be cached for the lifetime of a context
:rtype: bool
%End

QString description( const QString &name ) const;
%Docstring
Returns the translated description for the variable with the specified ``name``
(if set).

.. versionadded:: 3.0
:rtype: str
%End

int variableCount() const;
%Docstring
Returns the count of variables contained within the scope.
@@ -475,6 +490,17 @@ class QgsExpressionContext
:rtype: bool
%End

QString description( const QString &name ) const;
%Docstring
Returns a translated description string for the variable with specified ``name``.

If no specific description has been provided for the variable, the value from
QgsExpression.variableHelpText() will be returned.

.. versionadded:: 3.0
:rtype: str
%End

bool hasFunction( const QString &name ) const;
%Docstring
Checks whether a specified function is contained in the context.
@@ -690,10 +690,15 @@ void QgsExpression::initVariableHelp()
sVariableHelpTexts.insert( QStringLiteral( "algorithm_id" ), QCoreApplication::translate( "algorithm_id", "Unique ID for algorithm." ) );
}

QString QgsExpression::variableHelpText( const QString &variableName, bool showValue, const QVariant &value )
QString QgsExpression::variableHelpText( const QString &variableName )
{
QgsExpression::initVariableHelp();
QString text = sVariableHelpTexts.contains( variableName ) ? QStringLiteral( "<p>%1</p>" ).arg( sVariableHelpTexts.value( variableName ) ) : QString();
return sVariableHelpTexts.value( variableName, QString() );
}

QString QgsExpression::formatVariableHelp( const QString &description, bool showValue, const QVariant &value )
{
QString text = !description.isEmpty() ? QStringLiteral( "<p>%1</p>" ).arg( description ) : QString();
if ( showValue )
{
QString valueString;
@@ -424,6 +424,7 @@ class CORE_EXPORT QgsExpression
/** Returns the help text for a specified function.
* \param name function name
* \see variableHelpText()
* \see formatVariableHelp()
*/
static QString helpText( QString name );

@@ -434,7 +435,18 @@ class CORE_EXPORT QgsExpression
* \see helpText()
* \since QGIS 2.12
*/
static QString variableHelpText( const QString &variableName, bool showValue = true, const QVariant &value = QVariant() );
static QString variableHelpText( const QString &variableName );

/**
* Returns formatted help text for a variable.
* \param description translated description of variable
* \param showValue set to true to include current value of variable in help text
* \param value current value of variable to show in help text
* \see helpText()
* \see variableHelpText()
* \since QGIS 3.0
*/
static QString formatVariableHelp( const QString &description, bool showValue = true, const QVariant &value = QVariant() );

/** Returns the translated name for a function group.
* \param group untranslated group name
@@ -188,6 +188,11 @@ bool QgsExpressionContextScope::isStatic( const QString &name ) const
return hasVariable( name ) ? mVariables.value( name ).isStatic : false;
}

QString QgsExpressionContextScope::description( const QString &name ) const
{
return hasVariable( name ) ? mVariables.value( name ).description : QString();
}

bool QgsExpressionContextScope::hasFunction( const QString &name ) const
{
return mFunctions.contains( name );
@@ -404,6 +409,12 @@ bool QgsExpressionContext::isReadOnly( const QString &name ) const
return false;
}

QString QgsExpressionContext::description( const QString &name ) const
{
const QgsExpressionContextScope *scope = activeScopeForVariable( name );
return ( scope && !scope->description( name ).isEmpty() ) ? scope->description( name ) : QgsExpression::variableHelpText( name );
}

bool QgsExpressionContext::hasFunction( const QString &name ) const
{
Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
@@ -133,12 +133,14 @@ class CORE_EXPORT QgsExpressionContextScope
* \param value initial variable value
* \param readOnly true if variable should not be editable by users
* \param isStatic true if the variable will not change during the lifteime of an iterator.
* \param description optional translated description of variable, for use in expression builder widgets
*/
StaticVariable( const QString &name = QString(), const QVariant &value = QVariant(), bool readOnly = false, bool isStatic = false )
StaticVariable( const QString &name = QString(), const QVariant &value = QVariant(), bool readOnly = false, bool isStatic = false, const QString &description = QString() )
: name( name )
, value( value )
, readOnly( readOnly )
, isStatic( isStatic )
, description( description )
{}

//! Variable name
@@ -152,6 +154,9 @@ class CORE_EXPORT QgsExpressionContextScope

//! A static variable can be cached for the lifetime of a context
bool isStatic;

//! Translated description of variable, for use within expression builder widgets.
QString description;
};

/** Constructor for QgsExpressionContextScope
@@ -238,6 +243,14 @@ class CORE_EXPORT QgsExpressionContextScope
*/
bool isStatic( const QString &name ) const;

/**
* Returns the translated description for the variable with the specified \a name
* (if set).
*
* \since QGIS 3.0
*/
QString description( const QString &name ) const;

/** Returns the count of variables contained within the scope.
*/
int variableCount() const { return mVariables.count(); }
@@ -463,6 +476,16 @@ class CORE_EXPORT QgsExpressionContext
*/
bool isReadOnly( const QString &name ) const;

/**
* Returns a translated description string for the variable with specified \a name.
*
* If no specific description has been provided for the variable, the value from
* QgsExpression::variableHelpText() will be returned.
*
* \since QGIS 3.0
*/
QString description( const QString &name ) const;

/** Checks whether a specified function is contained in the context.
* \param name function name
* \returns true if context provides a matching function
@@ -587,7 +587,7 @@ void QgsExpressionBuilderWidget::loadExpressionContext()
Q_FOREACH ( const QString &variable, variableNames )
{
registerItem( QStringLiteral( "Variables" ), variable, " @" + variable + ' ',
QgsExpression::variableHelpText( variable, true, mExpressionContext.variable( variable ) ),
QgsExpression::formatVariableHelp( mExpressionContext.description( variable ), true, mExpressionContext.variable( variable ) ),
QgsExpressionItem::ExpressionNode,
mExpressionContext.isHighlightedVariable( variable ) );
}
@@ -52,6 +52,7 @@ class TestQgsExpressionContext : public QObject
void cache();

void valuesAsMap();
void description();

private:

@@ -163,6 +164,7 @@ void TestQgsExpressionContext::contextScope()
QVERIFY( !scope.variable( "test" ).isValid() );
QCOMPARE( scope.variableNames().length(), 0 );
QCOMPARE( scope.variableCount(), 0 );
QVERIFY( scope.description( "test" ).isEmpty() );

scope.setVariable( QStringLiteral( "test" ), 5 );
QVERIFY( scope.hasVariable( "test" ) );
@@ -171,15 +173,19 @@ void TestQgsExpressionContext::contextScope()
QCOMPARE( scope.variableNames().length(), 1 );
QCOMPARE( scope.variableCount(), 1 );
QCOMPARE( scope.variableNames().at( 0 ), QString( "test" ) );
QVERIFY( scope.description( "test" ).isEmpty() );

scope.addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "readonly" ), QStringLiteral( "readonly_test" ), true ) );
scope.addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "readonly" ), QStringLiteral( "readonly_test" ), true, false, QStringLiteral( "readonly variable" ) ) );
QVERIFY( scope.isReadOnly( "readonly" ) );
QCOMPARE( scope.description( "readonly" ), QStringLiteral( "readonly variable" ) );
scope.addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notreadonly" ), QStringLiteral( "not_readonly_test" ), false ) );
QVERIFY( !scope.isReadOnly( "notreadonly" ) );

//updating a read only variable should remain read only
scope.setVariable( QStringLiteral( "readonly" ), "newvalue" );
QVERIFY( scope.isReadOnly( "readonly" ) );
// and keep its description
QCOMPARE( scope.description( "readonly" ), QStringLiteral( "readonly variable" ) );

//test retrieving filtered variable names
scope.setVariable( QStringLiteral( "_hidden_" ), "hidden" );
@@ -245,6 +251,7 @@ void TestQgsExpressionContext::contextStack()
QCOMPARE( context.scopeCount(), 0 );
QVERIFY( !context.scope( 0 ) );
QVERIFY( !context.lastScope() );
QVERIFY( context.description( "test" ).isEmpty() );

//add a scope to the context
QgsExpressionContextScope *testScope = new QgsExpressionContextScope();
@@ -305,10 +312,13 @@ void TestQgsExpressionContext::contextStack()
QCOMPARE( scopes.at( 0 ), scope1 );
QCOMPARE( scopes.at( 1 ), scope2 );

QVERIFY( context.description( "readonly" ).isEmpty() );

//check isReadOnly
scope2->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "readonly" ), 5, true ) );
scope2->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "readonly" ), 5, true, false, QStringLiteral( "readonly variable" ) ) );
QVERIFY( context.isReadOnly( "readonly" ) );
QVERIFY( !context.isReadOnly( "test" ) );
QCOMPARE( context.description( "readonly" ), QStringLiteral( "readonly variable" ) );

// Check scopes can be popped
delete context.popScope();
@@ -735,5 +745,20 @@ void TestQgsExpressionContext::valuesAsMap()
QCOMPARE( m.value( "v3" ).toString(), QString( "t3" ) );
}

void TestQgsExpressionContext::description()
{
// test that description falls back to default values if not set
QgsExpressionContext context;
QgsExpressionContextScope *scope = new QgsExpressionContextScope();
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_title" ) ) );
context << scope;
QCOMPARE( context.description( "project_title" ), QgsExpression::variableHelpText( "project_title" ) );
// but if set, use that
scope = new QgsExpressionContextScope();
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_title" ), QVariant(), true, true, QStringLiteral( "my desc" ) ) );
context << scope;
QCOMPARE( context.description( "project_title" ), QStringLiteral( "my desc" ) );
}

QGSTEST_MAIN( TestQgsExpressionContext )
#include "testqgsexpressioncontext.moc"

0 comments on commit 35e16b2

Please sign in to comment.
You can’t perform that action at this time.