Skip to content

Commit

Permalink
Allow expression contexts to specify a list of highlighted functions
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
nyalldawson committed Sep 21, 2018
1 parent 5cf0433 commit 8e1c437
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 7 deletions.
36 changes: 33 additions & 3 deletions python/core/auto_generated/qgsexpressioncontext.sip.in
Expand Up @@ -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 );
Expand All @@ -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 );
Expand Down
13 changes: 13 additions & 0 deletions src/core/qgsexpressioncontext.cpp
Expand Up @@ -237,6 +237,7 @@ QgsExpressionContext::QgsExpressionContext( const QgsExpressionContext &other )
mStack << new QgsExpressionContextScope( *scope );
}
mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
}

Expand All @@ -250,6 +251,7 @@ QgsExpressionContext &QgsExpressionContext::operator=( QgsExpressionContext &&ot
other.mStack.clear();

mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
}
return *this;
Expand All @@ -264,6 +266,7 @@ QgsExpressionContext &QgsExpressionContext::operator=( const QgsExpressionContex
mStack << new QgsExpressionContextScope( *scope );
}
mHighlightedVariables = other.mHighlightedVariables;
mHighlightedFunctions = other.mHighlightedFunctions;
mCachedValues = other.mCachedValues;
return *this;
}
Expand Down Expand Up @@ -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
Expand Down
29 changes: 27 additions & 2 deletions src/core/qgsexpressioncontext.h
Expand Up @@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsexpressionbuilderwidget.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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() ) );
}
}

Expand Down
22 changes: 22 additions & 0 deletions tests/src/core/testqgsexpressioncontext.cpp
Expand Up @@ -44,6 +44,7 @@ class TestQgsExpressionContext : public QObject
void setFeature();
void setFields();
void takeScopes();
void highlighted();

void globalScope();
void projectScope();
Expand Down Expand Up @@ -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" );
Expand Down

0 comments on commit 8e1c437

Please sign in to comment.