Skip to content

Commit

Permalink
Expressions - Add a referencedExpressions method
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Nov 14, 2024
1 parent 3958320 commit 1030270
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 8 deletions.
1 change: 1 addition & 0 deletions python/PyQt6/core/auto_additions/qgsexpression.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
QgsExpression.quoteFieldExpression = staticmethod(QgsExpression.quoteFieldExpression)
QgsExpression.checkExpression = staticmethod(QgsExpression.checkExpression)
QgsExpression.replaceExpressionText = staticmethod(QgsExpression.replaceExpressionText)
QgsExpression.referencedExpressions = staticmethod(QgsExpression.referencedExpressions)
QgsExpression.evaluateToDouble = staticmethod(QgsExpression.evaluateToDouble)
QgsExpression.registerFunction = staticmethod(QgsExpression.registerFunction)
QgsExpression.unregisterFunction = staticmethod(QgsExpression.unregisterFunction)
Expand Down
12 changes: 10 additions & 2 deletions python/PyQt6/core/auto_generated/expression/qgsexpression.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,6 @@ variables from the expression context ("project_distance_units") to determine di
This function replaces each expression between [% and %]
in the string with the result of its evaluation with the specified context

Additional substitutions can be passed through the substitutionMap parameter

:param action: The source string in which placeholders should be replaced.
:param context: Expression context
:param distanceArea: Optional :py:class:`QgsDistanceArea`. If specified, the :py:class:`QgsDistanceArea` is used for distance
Expand All @@ -441,6 +439,16 @@ This function returns variables in each expression between [% and %].
:param text: The source string in which variables should be searched.

.. versionadded:: 3.2
%End

static QStringList referencedExpressions( const QString &text );
%Docstring
This function returns expressions found between [% and %].
Expressions returned are guaranteed to be valid QGIS expressions.

:param text: The source string in which expressions should be searched.

.. versionadded:: 3.42
%End

static double evaluateToDouble( const QString &text, double fallbackValue );
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_additions/qgsexpression.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
QgsExpression.quoteFieldExpression = staticmethod(QgsExpression.quoteFieldExpression)
QgsExpression.checkExpression = staticmethod(QgsExpression.checkExpression)
QgsExpression.replaceExpressionText = staticmethod(QgsExpression.replaceExpressionText)
QgsExpression.referencedExpressions = staticmethod(QgsExpression.referencedExpressions)
QgsExpression.evaluateToDouble = staticmethod(QgsExpression.evaluateToDouble)
QgsExpression.registerFunction = staticmethod(QgsExpression.registerFunction)
QgsExpression.unregisterFunction = staticmethod(QgsExpression.unregisterFunction)
Expand Down
12 changes: 10 additions & 2 deletions python/core/auto_generated/expression/qgsexpression.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,6 @@ variables from the expression context ("project_distance_units") to determine di
This function replaces each expression between [% and %]
in the string with the result of its evaluation with the specified context

Additional substitutions can be passed through the substitutionMap parameter

:param action: The source string in which placeholders should be replaced.
:param context: Expression context
:param distanceArea: Optional :py:class:`QgsDistanceArea`. If specified, the :py:class:`QgsDistanceArea` is used for distance
Expand All @@ -441,6 +439,16 @@ This function returns variables in each expression between [% and %].
:param text: The source string in which variables should be searched.

.. versionadded:: 3.2
%End

static QStringList referencedExpressions( const QString &text );
%Docstring
This function returns expressions found between [% and %].
Expressions returned are guaranteed to be valid QGIS expressions.

:param text: The source string in which expressions should be searched.

.. versionadded:: 3.42
%End

static double evaluateToDouble( const QString &text, double fallbackValue );
Expand Down
18 changes: 15 additions & 3 deletions src/core/expression/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,19 @@ QString QgsExpression::replaceExpressionText( const QString &action, const QgsEx
QSet<QString> QgsExpression::referencedVariables( const QString &text )
{
QSet<QString> variables;
const QStringList expressions = QgsExpression::referencedExpressions( text );
for ( const QString &expression : expressions )
{
QgsExpression exp( expression );
variables.unite( exp.referencedVariables() );
}

return variables;
}

QStringList QgsExpression::referencedExpressions( const QString &text )
{
QStringList expressions;
int index = 0;
while ( index < text.size() )
{
Expand All @@ -527,11 +540,10 @@ QSet<QString> QgsExpression::referencedVariables( const QString &text )
index = match.capturedStart() + match.capturedLength();
QString to_replace = match.captured( 1 ).trimmed();

QgsExpression exp( to_replace );
variables.unite( exp.referencedVariables() );
expressions.append( to_replace );
}

return variables;
return expressions;
}

double QgsExpression::evaluateToDouble( const QString &text, const double fallbackValue )
Expand Down
11 changes: 10 additions & 1 deletion src/core/expression/qgsexpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,6 @@ class CORE_EXPORT QgsExpression
* This function replaces each expression between [% and %]
* in the string with the result of its evaluation with the specified context
*
* Additional substitutions can be passed through the substitutionMap parameter
* \param action The source string in which placeholders should be replaced.
* \param context Expression context
* \param distanceArea Optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance
Expand All @@ -569,6 +568,16 @@ class CORE_EXPORT QgsExpression
*/
static QSet<QString> referencedVariables( const QString &text );

/**
* This function returns expressions found between [% and %].
* Expressions returned are guaranteed to be valid QGIS expressions.
*
* \param text The source string in which expressions should be searched.
*
* \since QGIS 3.42
*/
static QStringList referencedExpressions( const QString &text );

/**
* Attempts to evaluate a text string as an expression to a resultant double
* value.
Expand Down
21 changes: 21 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5453,6 +5453,27 @@ class TestQgsExpression: public QObject
QCOMPARE( zustaendigkeitskataster->dataProvider()->featureCount(), 4l );
}

void testReferencedExpressions_data()
{
QTest::addColumn<QString>( "input" );
QTest::addColumn<QStringList>( "expected" );
QTest::newRow( "no exp" ) << "some text" << QStringList();
QTest::newRow( "simple exp" ) << "some text [% 1 + 2 %]" << ( QStringList() << QStringLiteral( "1 + 2" ) );
QTest::newRow( "multiple exp" ) << "some [% 3+ 7 %] text [% 1 + 2 %]" << ( QStringList() << QStringLiteral( "3+ 7" ) << QStringLiteral( "1 + 2" ) );
QTest::newRow( "complex" ) << "some [%map('a', 1, 'b', 2)['a']%] text [%map('a', 1, 'b', 2)['b']%]" << ( QStringList() << QStringLiteral( "map('a', 1, 'b', 2)['a']" ) << QStringLiteral( "map('a', 1, 'b', 2)['b']" ) );
QTest::newRow( "complex2" ) << "some [% 'my text]' %] text" << ( QStringList() << QStringLiteral( "'my text]'" ) );
QTest::newRow( "newline 1" ) << "some \n [% 1 + 2 %] \n text" << ( QStringList() << QStringLiteral( "1 + 2" ) );
QTest::newRow( "newline 2" ) << "some [% \n 1 \n + \n 2 %] \n text" << ( QStringList() << QStringLiteral( "\n 1 \n + \n 2" ) );
QTest::newRow( "field values" ) << "[% \"string_field\" %] - [% \"non_null_int\" %] - [% \"null_int\" %]" << ( QStringList() << QStringLiteral( "\"string_field\"" ) << QStringLiteral( "\"non_null_int\"" ) << QStringLiteral( "\"null_int\"" ) );
}

void testReferencedExpressions()
{
QFETCH( QString, input );
QFETCH( QStringList, expected );
QCOMPARE( QgsExpression::referencedExpressions( input ), expected );
}

void testReplaceExpressionText_data()
{
QTest::addColumn<QString>( "input" );
Expand Down

0 comments on commit 1030270

Please sign in to comment.