Allow expression contexts to specify a list of highlighted functions

as well as just variable names

In some cases contexts may provide specific functions of use
to that context, or more generally there may be functions we want
to highlight for a particular expression builder (e.g. highlighting
to_dms in the grid annotation builder)
This commit is contained in:
Nyall Dawson 2018-09-21 09:35:37 +10:00
parent 5cf04334d7
commit 8e1c437e02
5 changed files with 97 additions and 7 deletions

View File

@ -424,13 +424,13 @@ contained by the context.
bool isHighlightedVariable( const QString &name ) const;
%Docstring
Returns true if the specified variable name is intended to be highlighted to the
Returns true if the specified variable ``name`` is intended to be highlighted to the
user. This is used by the expression builder to more prominently display the
variable.
:param name: variable name
.. seealso:: :py:func:`setHighlightedVariables`
.. seealso:: :py:func:`isHighlightedFunction`
%End
void setHighlightedVariables( const QStringList &variableNames );
@ -441,6 +441,36 @@ is used by the expression builder to more prominently display these variables.
:param variableNames: variable names to highlight
.. seealso:: :py:func:`isHighlightedVariable`
.. seealso:: :py:func:`setHighlightedFunctions`
%End
bool isHighlightedFunction( const QString &name ) const;
%Docstring
Returns true if the specified function ``name`` is intended to be highlighted to the
user. This is used by the expression builder to more prominently display the
function.
.. seealso:: :py:func:`setHighlightedFunctions`
.. seealso:: :py:func:`isHighlightedVariable`
.. versionadded:: 3.4
%End
void setHighlightedFunctions( const QStringList &names );
%Docstring
Sets the list of function ``names`` intended to be highlighted to the user. This
is used by the expression builder to more prominently display these functions.
Note that these function names may include standard functions which are not functions
specific to this context, and these standard functions will also be highlighted to users.
.. seealso:: :py:func:`isHighlightedFunction`
.. seealso:: :py:func:`setHighlightedVariables`
.. versionadded:: 3.4
%End
QgsExpressionContextScope *activeScopeForVariable( const QString &name );

View File

@ -237,6 +237,7 @@ QgsExpressionContext::QgsExpressionContext( const QgsExpressionContext &other )
mStack << new QgsExpressionContextScope( *scope );
}
mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
}
@ -250,6 +251,7 @@ QgsExpressionContext &QgsExpressionContext::operator=( QgsExpressionContext &&ot
other.mStack.clear();
mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
}
return *this;
@ -264,6 +266,7 @@ QgsExpressionContext &QgsExpressionContext::operator=( const QgsExpressionContex
mStack << new QgsExpressionContextScope( *scope );
}
mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
return *this;
}
@ -311,6 +314,16 @@ void QgsExpressionContext::setHighlightedVariables( const QStringList &variableN
mHighlightedVariables = variableNames;
}
bool QgsExpressionContext::isHighlightedFunction( const QString &name ) const
{
return mHighlightedFunctions.contains( name );
}
void QgsExpressionContext::setHighlightedFunctions( const QStringList &names )
{
mHighlightedFunctions = names;
}
const QgsExpressionContextScope *QgsExpressionContext::activeScopeForVariable( const QString &name ) const
{
//iterate through stack backwards, so that higher priority variables take precedence

View File

@ -425,11 +425,11 @@ class CORE_EXPORT QgsExpressionContext
QVariantMap variablesToMap() const;
/**
* Returns true if the specified variable name is intended to be highlighted to the
* Returns true if the specified variable \a name is intended to be highlighted to the
* user. This is used by the expression builder to more prominently display the
* variable.
* \param name variable name
* \see setHighlightedVariables()
* \see isHighlightedFunction()
*/
bool isHighlightedVariable( const QString &name ) const;
@ -438,9 +438,33 @@ class CORE_EXPORT QgsExpressionContext
* is used by the expression builder to more prominently display these variables.
* \param variableNames variable names to highlight
* \see isHighlightedVariable()
* \see setHighlightedFunctions()
*/
void setHighlightedVariables( const QStringList &variableNames );
/**
* Returns true if the specified function \a name is intended to be highlighted to the
* user. This is used by the expression builder to more prominently display the
* function.
* \see setHighlightedFunctions()
* \see isHighlightedVariable()
* \since QGIS 3.4
*/
bool isHighlightedFunction( const QString &name ) const;
/**
* Sets the list of function \a names intended to be highlighted to the user. This
* is used by the expression builder to more prominently display these functions.
*
* Note that these function names may include standard functions which are not functions
* specific to this context, and these standard functions will also be highlighted to users.
*
* \see isHighlightedFunction()
* \see setHighlightedVariables()
* \since QGIS 3.4
*/
void setHighlightedFunctions( const QStringList &names );
/**
* Returns the currently active scope from the context for a specified variable name.
* As scopes later in the stack override earlier contexts, this will be the last matching
@ -714,6 +738,7 @@ class CORE_EXPORT QgsExpressionContext
QList< QgsExpressionContextScope * > mStack;
QStringList mHighlightedVariables;
QStringList mHighlightedFunctions;
// Cache is mutable because we want to be able to add cached values to const contexts
mutable QMap< QString, QVariant > mCachedValues;

View File

@ -577,7 +577,7 @@ void QgsExpressionBuilderWidget::updateFunctionTree()
name += '(';
else if ( !name.startsWith( '$' ) )
name += QLatin1String( "()" );
registerItemForAllGroups( func->groups(), func->name(), ' ' + name + ' ', func->helpText() );
registerItemForAllGroups( func->groups(), func->name(), ' ' + name + ' ', func->helpText(), QgsExpressionItem::ExpressionNode, mExpressionContext.isHighlightedFunction( func->name() ) );
}
// load relation names
@ -721,7 +721,7 @@ void QgsExpressionBuilderWidget::loadExpressionContext()
continue;
if ( func->params() != 0 )
name += '(';
registerItemForAllGroups( func->groups(), func->name(), ' ' + name + ' ', func->helpText() );
registerItemForAllGroups( func->groups(), func->name(), ' ' + name + ' ', func->helpText(), QgsExpressionItem::ExpressionNode, mExpressionContext.isHighlightedFunction( func->name() ) );
}
}

View File

@ -44,6 +44,7 @@ class TestQgsExpressionContext : public QObject
void setFeature();
void setFields();
void takeScopes();
void highlighted();
void globalScope();
void projectScope();
@ -542,6 +543,27 @@ void TestQgsExpressionContext::takeScopes()
QVERIFY( !context.variable( "test_project" ).isValid() );
}
void TestQgsExpressionContext::highlighted()
{
QgsExpressionContext context;
QVERIFY( !context.isHighlightedFunction( QStringLiteral( "x" ) ) );
QVERIFY( !context.isHighlightedVariable( QStringLiteral( "x" ) ) );
context.setHighlightedFunctions( QStringList() << QStringLiteral( "x" ) << QStringLiteral( "y" ) );
QVERIFY( context.isHighlightedFunction( QStringLiteral( "x" ) ) );
QVERIFY( context.isHighlightedFunction( QStringLiteral( "y" ) ) );
QVERIFY( !context.isHighlightedFunction( QStringLiteral( "z" ) ) );
QVERIFY( !context.isHighlightedVariable( QStringLiteral( "x" ) ) );
context.setHighlightedVariables( QStringList() << QStringLiteral( "a" ) << QStringLiteral( "b" ) );
QVERIFY( context.isHighlightedVariable( QStringLiteral( "a" ) ) );
QVERIFY( context.isHighlightedVariable( QStringLiteral( "b" ) ) );
QVERIFY( !context.isHighlightedVariable( QStringLiteral( "c" ) ) );
QVERIFY( !context.isHighlightedFunction( QStringLiteral( "a" ) ) );
context.setHighlightedFunctions( QStringList() );
context.setHighlightedVariables( QStringList() );
QVERIFY( !context.isHighlightedFunction( QStringLiteral( "x" ) ) );
QVERIFY( !context.isHighlightedVariable( QStringLiteral( "a" ) ) );
}
void TestQgsExpressionContext::globalScope()
{
QgsExpressionContextUtils::setGlobalVariable( QStringLiteral( "test" ), "testval" );