Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expressions - Add a referencedExpressions method #59442

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading