Skip to content

Commit 3984e90

Browse files
author
Hugo Mercier
authoredApr 27, 2018
Merge pull request #6513 from pblottiere/executesql_params
[FEATURE][needs-docs] Add parameters to 'Execute SQL' algorithm
2 parents 9ce21e4 + 2324706 commit 3984e90

13 files changed

+397
-6
lines changed
 

‎python/core/expression/qgsexpression.sip.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,15 @@ Additional substitutions can be passed through the substitutionMap parameter
369369
and area conversion
370370

371371
.. versionadded:: 2.12
372+
%End
373+
374+
static QSet<QString> referencedVariables( const QString &text );
375+
%Docstring
376+
This function returns variables in each expression between [% and %].
377+
378+
:param text: The source string in which variables should be searched.
379+
380+
.. versionadded:: 3.2
372381
%End
373382

374383
static double evaluateToDouble( const QString &text, const double fallbackValue );

‎python/core/processing/models/qgsprocessingmodelchildparametersource.sip.in

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Source for the value of a parameter for a child algorithm within a model.
2929
ChildOutput,
3030
StaticValue,
3131
Expression,
32+
ExpressionText,
3233
};
3334

3435
QgsProcessingModelChildParameterSource();
@@ -49,6 +50,8 @@ Returns a new QgsProcessingModelChildParameterSource which takes its value from
4950
.. seealso:: :py:func:`fromChildOutput`
5051

5152
.. seealso:: :py:func:`fromExpression`
53+
54+
.. seealso:: :py:func:`fromExpressionText`
5255
%End
5356

5457
static QgsProcessingModelChildParameterSource fromModelParameter( const QString &parameterName );
@@ -60,6 +63,8 @@ Returns a new QgsProcessingModelChildParameterSource which takes its value from
6063
.. seealso:: :py:func:`fromChildOutput`
6164

6265
.. seealso:: :py:func:`fromExpression`
66+
67+
.. seealso:: :py:func:`fromExpressionText`
6368
%End
6469

6570
static QgsProcessingModelChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
@@ -71,6 +76,8 @@ Returns a new QgsProcessingModelChildParameterSource which takes its value from
7176
.. seealso:: :py:func:`fromModelParameter`
7277

7378
.. seealso:: :py:func:`fromExpression`
79+
80+
.. seealso:: :py:func:`fromExpressionText`
7481
%End
7582

7683
static QgsProcessingModelChildParameterSource fromExpression( const QString &expression );
@@ -85,6 +92,29 @@ executed by the model.
8592
.. seealso:: :py:func:`fromChildOutput`
8693

8794
.. seealso:: :py:func:`fromModelParameter`
95+
96+
.. seealso:: :py:func:`fromExpressionText`
97+
98+
.. versionadded:: 3.2
99+
%End
100+
101+
static QgsProcessingModelChildParameterSource fromExpressionText( const QString &text );
102+
%Docstring
103+
Returns a new QgsProcessingModelChildParameterSource which takes its
104+
value from a text with expressions. Expressions are evaluated just before
105+
the child algorithm executes, and can use functions available
106+
in its expression context to include results calculated from the child
107+
algorithms already executed by the model.
108+
109+
.. seealso:: :py:func:`fromStaticValue`
110+
111+
.. seealso:: :py:func:`fromChildOutput`
112+
113+
.. seealso:: :py:func:`fromModelParameter`
114+
115+
.. seealso:: :py:func:`fromExpression`
116+
117+
.. versionadded:: 3.2
88118
%End
89119

90120
Source source() const;
@@ -171,6 +201,29 @@ in its expression context to include results calculated from the child algorithm
171201
executed by the model.
172202

173203
.. seealso:: :py:func:`expression`
204+
%End
205+
206+
QString expressionText() const;
207+
%Docstring
208+
Returns the source's text with expressions. This is only used when the
209+
source() is ExpressionText.
210+
211+
.. seealso:: :py:func:`setExpressionText`
212+
213+
.. versionadded:: 3.2
214+
%End
215+
216+
void setExpressionText( const QString &text );
217+
%Docstring
218+
Sets the source's text containing expressions. Calling this will also
219+
change the source() to ExpressionText. Expressions are evaluated just
220+
before the child algorithm executes, and can use functions available
221+
in its expression context to include results calculated from the child
222+
algorithms already executed by the model.
223+
224+
.. seealso:: :py:func:`expressionText`
225+
226+
.. versionadded:: 3.2
174227
%End
175228

176229
QVariant toVariant() const;

‎python/gui/qgsfieldexpressionwidget.sip.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ only when editing in the line edit is finished (focus lost, enter key pressed).
3636
void setExpressionDialogTitle( const QString &title );
3737
%Docstring
3838
define the title used in the expression dialog
39+
%End
40+
41+
void appendScope( QgsExpressionContextScope *scope /Transfer/ );
42+
%Docstring
43+
Appends a scope to the current expression context.
44+
45+
:param scope: The scope to add.
46+
47+
.. versionadded:: 3.2
3948
%End
4049

4150
const QString expressionDialogTitle();

‎python/plugins/processing/algs/qgis/ExecuteSQL.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
QgsWkbTypes,
3131
QgsProcessingAlgorithm,
3232
QgsProcessingParameterMultipleLayers,
33+
QgsProcessingParameterDefinition,
34+
QgsExpression,
3335
QgsProcessingParameterString,
3436
QgsProcessingParameterEnum,
3537
QgsProcessingParameterCrs,
@@ -40,6 +42,21 @@
4042
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
4143

4244

45+
class ParameterExecuteSql(QgsProcessingParameterDefinition):
46+
47+
def __init__(self, name='', description=''):
48+
super().__init__(name, description)
49+
self.setMetadata({
50+
'widget_wrapper': 'processing.algs.qgis.ui.ExecuteSQLWidget.ExecuteSQLWidgetWrapper'
51+
})
52+
53+
def type(self):
54+
return 'execute_sql'
55+
56+
def clone(self):
57+
return ParameterExecuteSql(self.name(), self.description())
58+
59+
4360
class ExecuteSQL(QgisAlgorithm):
4461

4562
""" This algorithm allows executing an SQL query on a set of input
@@ -71,9 +88,7 @@ def initAlgorithm(self, config=None):
7188
description=self.tr('Additional input datasources (called input1, .., inputN in the query)'),
7289
optional=True))
7390

74-
self.addParameter(QgsProcessingParameterString(name=self.INPUT_QUERY,
75-
description=self.tr('SQL query'),
76-
multiLine=True))
91+
self.addParameter(ParameterExecuteSql(name=self.INPUT_QUERY, description=self.tr('SQL query')))
7792

7893
self.addParameter(QgsProcessingParameterString(name=self.INPUT_UID_FIELD,
7994
description=self.tr('Unique identifier field'), optional=True))
@@ -120,13 +135,15 @@ def processAlgorithm(self, parameters, context, feedback):
120135
raise QgsProcessingException(
121136
self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
122137
else:
123-
df.setQuery(query)
138+
localContext = self.createExpressionContext(parameters, context)
139+
expandedQuery = QgsExpression.replaceExpressionText(query, localContext)
140+
df.setQuery(expandedQuery)
124141

125142
if uid_field:
126143
df.setUid(uid_field)
127144

128145
if geometry_type == 1: # no geometry
129-
df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
146+
df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
130147
else:
131148
if geometry_field:
132149
df.setGeometryField(geometry_field)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
ExecuteSQLWidget.py
6+
---------------------
7+
Date : November 2017
8+
Copyright : (C) 2017 by Paul Blottiere
9+
Email : blottiere dot paul at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Paul Blottiere'
21+
__date__ = 'November 2018'
22+
__copyright__ = '(C) 2018, Paul Blottiere'
23+
24+
# This will get replaced with a git SHA1 when you do a git archive
25+
26+
__revision__ = '$Format:%H$'
27+
28+
import os
29+
30+
from qgis.PyQt import uic
31+
from qgis.PyQt.QtWidgets import QTreeWidgetItem
32+
from qgis.PyQt.QtCore import Qt
33+
34+
from qgis.core import (QgsApplication,
35+
QgsExpressionContextScope,
36+
QgsProcessingParameterString,
37+
QgsProcessingParameterNumber,
38+
QgsExpression,
39+
QgsProcessingModelChildParameterSource,
40+
QgsProcessingParameterFile,
41+
QgsProcessingParameterField,
42+
QgsProcessingOutputString,
43+
QgsProcessingParameterExpression,
44+
QgsProcessingOutputFile)
45+
46+
from qgis.gui import QgsFieldExpressionWidget
47+
48+
from processing.gui.wrappers import (WidgetWrapper,
49+
dialogTypes,
50+
DIALOG_MODELER)
51+
52+
pluginPath = os.path.dirname(__file__)
53+
WIDGET, BASE = uic.loadUiType(os.path.join(pluginPath, 'ExecuteSQLWidgetBase.ui'))
54+
55+
56+
class ExecuteSQLWidget(BASE, WIDGET):
57+
58+
def __init__(self, dialog):
59+
super(ExecuteSQLWidget, self).__init__(None)
60+
self.setupUi(self)
61+
self.dialog = dialog
62+
self.dialogType = dialogTypes[dialog.__class__.__name__]
63+
64+
self.mExpressionWidget = QgsFieldExpressionWidget()
65+
66+
# add model parameters in context scope if called from modeler
67+
if self.dialogType == DIALOG_MODELER:
68+
strings = dialog.getAvailableValuesOfType(
69+
[QgsProcessingParameterString, QgsProcessingParameterNumber], [])
70+
model_params = [dialog.resolveValueDescription(s) for s in strings]
71+
72+
scope = QgsExpressionContextScope()
73+
for param in model_params:
74+
var = QgsExpressionContextScope.StaticVariable(param)
75+
scope.addVariable(var)
76+
77+
self.mExpressionWidget.appendScope(scope)
78+
79+
self.mHLayout.insertWidget(0, self.mExpressionWidget)
80+
81+
self.mInsert.clicked.connect(self.insert)
82+
83+
def insert(self):
84+
if self.mExpressionWidget.currentText():
85+
exp = '[% {} %]'.format(self.mExpressionWidget.currentText())
86+
self.mText.insertPlainText(exp)
87+
88+
def setValue(self, value):
89+
text = value
90+
91+
if self.dialogType == DIALOG_MODELER:
92+
if isinstance(value, list):
93+
for v in value:
94+
if isinstance(v, QgsProcessingModelChildParameterSource) \
95+
and v.source() == QgsProcessingModelChildParameterSource.ExpressionText:
96+
text = v.expressionText()
97+
98+
self.mText.setPlainText(text)
99+
100+
def value(self):
101+
value = self.mText.toPlainText()
102+
103+
if self.dialogType == DIALOG_MODELER:
104+
expression_values = self._expressionValues(value)
105+
if len(expression_values) > 1:
106+
value = expression_values
107+
108+
return value
109+
110+
def _expressionValues(self, text):
111+
strings = self.dialog.getAvailableValuesOfType(
112+
[QgsProcessingParameterString, QgsProcessingParameterNumber], [])
113+
model_params = [(self.dialog.resolveValueDescription(s), s) for s in strings]
114+
115+
variables = QgsExpression.referencedVariables(text)
116+
expression_values = []
117+
expression_values.append(QgsProcessingModelChildParameterSource.fromExpressionText(text))
118+
119+
for k, v in model_params:
120+
if k in variables:
121+
expression_values.append(v)
122+
123+
return expression_values
124+
125+
126+
class ExecuteSQLWidgetWrapper(WidgetWrapper):
127+
128+
def createWidget(self):
129+
return ExecuteSQLWidget(self.dialog)
130+
131+
def setValue(self, value):
132+
self.widget.setValue(value)
133+
134+
def value(self):
135+
return self.widget.value()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>Form</class>
4+
<widget class="QWidget" name="Form">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>400</width>
10+
<height>300</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="3" column="0" rowspan="2" colspan="2">
18+
<layout class="QVBoxLayout" name="verticalLayout">
19+
<property name="topMargin">
20+
<number>10</number>
21+
</property>
22+
<item>
23+
<widget class="QPlainTextEdit" name="mText"/>
24+
</item>
25+
<item>
26+
<layout class="QHBoxLayout" name="mHLayout">
27+
<property name="spacing">
28+
<number>6</number>
29+
</property>
30+
<property name="topMargin">
31+
<number>0</number>
32+
</property>
33+
<item>
34+
<widget class="QPushButton" name="mInsert">
35+
<property name="text">
36+
<string>Insert</string>
37+
</property>
38+
</widget>
39+
</item>
40+
</layout>
41+
</item>
42+
</layout>
43+
</item>
44+
</layout>
45+
</widget>
46+
<resources/>
47+
<connections/>
48+
</ui>

‎src/core/expression/qgsexpression.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,28 @@ QString QgsExpression::replaceExpressionText( const QString &action, const QgsEx
477477
return expr_action;
478478
}
479479

480+
QSet<QString> QgsExpression::referencedVariables( const QString &text )
481+
{
482+
QSet<QString> variables;
483+
int index = 0;
484+
while ( index < text.size() )
485+
{
486+
QRegExp rx = QRegExp( "\\[%([^\\]]+)%\\]" );
487+
488+
int pos = rx.indexIn( text, index );
489+
if ( pos < 0 )
490+
break;
491+
492+
index = pos + rx.matchedLength();
493+
QString to_replace = rx.cap( 1 ).trimmed();
494+
495+
QgsExpression exp( to_replace );
496+
variables.unite( exp.referencedVariables() );
497+
}
498+
499+
return variables;
500+
}
501+
480502
double QgsExpression::evaluateToDouble( const QString &text, const double fallbackValue )
481503
{
482504
bool ok;

‎src/core/expression/qgsexpression.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,15 @@ class CORE_EXPORT QgsExpression
400400
static QString replaceExpressionText( const QString &action, const QgsExpressionContext *context,
401401
const QgsDistanceArea *distanceArea = nullptr );
402402

403+
/**
404+
* This function returns variables in each expression between [% and %].
405+
*
406+
* \param text The source string in which variables should be searched.
407+
*
408+
* \since QGIS 3.2
409+
*/
410+
static QSet<QString> referencedVariables( const QString &text );
411+
403412
/**
404413
* Attempts to evaluate a text string as an expression to a resultant double
405414
* value.

‎src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm( const QgsP
9696

9797
QgsProcessingModelChildParameterSources paramSources = child.parameterSources().value( def->name() );
9898

99+
QString expressionText;
99100
QVariantList paramParts;
100101
Q_FOREACH ( const QgsProcessingModelChildParameterSource &source, paramSources )
101102
{
@@ -122,9 +123,19 @@ QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm( const QgsP
122123
paramParts << exp.evaluate( &expressionContext );
123124
break;
124125
}
126+
case QgsProcessingModelChildParameterSource::ExpressionText:
127+
{
128+
expressionText = QgsExpression::replaceExpressionText( source.expressionText(), &expressionContext );
129+
break;
130+
}
125131
}
126132
}
127-
if ( paramParts.count() == 1 )
133+
134+
if ( ! expressionText.isEmpty() )
135+
{
136+
childParams.insert( def->name(), expressionText );
137+
}
138+
else if ( paramParts.count() == 1 )
128139
childParams.insert( def->name(), paramParts.at( 0 ) );
129140
else
130141
childParams.insert( def->name(), paramParts );
@@ -464,6 +475,7 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
464475
}
465476

466477
case QgsProcessingModelChildParameterSource::Expression:
478+
case QgsProcessingModelChildParameterSource::ExpressionText:
467479
case QgsProcessingModelChildParameterSource::StaticValue:
468480
continue;
469481
};
@@ -508,6 +520,7 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
508520
}
509521

510522
case QgsProcessingModelChildParameterSource::Expression:
523+
case QgsProcessingModelChildParameterSource::ExpressionText:
511524
case QgsProcessingModelChildParameterSource::StaticValue:
512525
continue;
513526

@@ -555,6 +568,7 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
555568
}
556569

557570
case QgsProcessingModelChildParameterSource::Expression:
571+
case QgsProcessingModelChildParameterSource::ExpressionText:
558572
case QgsProcessingModelChildParameterSource::StaticValue:
559573
continue;
560574

‎src/core/processing/models/qgsprocessingmodelchildparametersource.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ bool QgsProcessingModelChildParameterSource::operator==( const QgsProcessingMode
3434
return mParameterName == other.mParameterName;
3535
case Expression:
3636
return mExpression == other.mExpression;
37+
case ExpressionText:
38+
return mExpressionText == other.mExpressionText;
3739
}
3840
return false;
3941
}
@@ -71,6 +73,14 @@ QgsProcessingModelChildParameterSource QgsProcessingModelChildParameterSource::f
7173
return src;
7274
}
7375

76+
QgsProcessingModelChildParameterSource QgsProcessingModelChildParameterSource::fromExpressionText( const QString &text )
77+
{
78+
QgsProcessingModelChildParameterSource src;
79+
src.mSource = ExpressionText;
80+
src.mExpressionText = text;
81+
return src;
82+
}
83+
7484
QgsProcessingModelChildParameterSource::Source QgsProcessingModelChildParameterSource::source() const
7585
{
7686
return mSource;
@@ -98,6 +108,10 @@ QVariant QgsProcessingModelChildParameterSource::toVariant() const
98108
case Expression:
99109
map.insert( QStringLiteral( "expression" ), mExpression );
100110
break;
111+
112+
case ExpressionText:
113+
map.insert( QStringLiteral( "expression_text" ), mExpressionText );
114+
break;
101115
}
102116
return map;
103117
}
@@ -123,6 +137,10 @@ bool QgsProcessingModelChildParameterSource::loadVariant( const QVariantMap &map
123137
case Expression:
124138
mExpression = map.value( QStringLiteral( "expression" ) ).toString();
125139
break;
140+
141+
case ExpressionText:
142+
mExpressionText = map.value( QStringLiteral( "expression_text" ) ).toString();
143+
break;
126144
}
127145
return true;
128146
}
@@ -142,6 +160,9 @@ QString QgsProcessingModelChildParameterSource::asPythonCode() const
142160

143161
case Expression:
144162
return QStringLiteral( "QgsExpression('%1').evaluate()" ).arg( mExpression );
163+
164+
case ExpressionText:
165+
return mExpressionText;
145166
}
146167
return QString();
147168
}

‎src/core/processing/models/qgsprocessingmodelchildparametersource.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
3939
ChildOutput, //!< Parameter value is taken from an output generated by a child algorithm
4040
StaticValue, //!< Parameter value is a static value
4141
Expression, //!< Parameter value is taken from an expression, evaluated just before the algorithm runs
42+
ExpressionText, //!< Parameter value is taken from a text with expressions, evaluated just before the algorithm runs
4243
};
4344

4445
/**
@@ -58,6 +59,7 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
5859
* \see fromModelParameter()
5960
* \see fromChildOutput()
6061
* \see fromExpression()
62+
* \see fromExpressionText()
6163
*/
6264
static QgsProcessingModelChildParameterSource fromStaticValue( const QVariant &value );
6365

@@ -66,6 +68,7 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
6668
* \see fromStaticValue()
6769
* \see fromChildOutput()
6870
* \see fromExpression()
71+
* \see fromExpressionText()
6972
*/
7073
static QgsProcessingModelChildParameterSource fromModelParameter( const QString &parameterName );
7174

@@ -74,6 +77,7 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
7477
* \see fromStaticValue()
7578
* \see fromModelParameter()
7679
* \see fromExpression()
80+
* \see fromExpressionText()
7781
*/
7882
static QgsProcessingModelChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
7983

@@ -85,9 +89,25 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
8589
* \see fromStaticValue()
8690
* \see fromChildOutput()
8791
* \see fromModelParameter()
92+
* \see fromExpressionText()
93+
* \since QGIS 3.2
8894
*/
8995
static QgsProcessingModelChildParameterSource fromExpression( const QString &expression );
9096

97+
/**
98+
* Returns a new QgsProcessingModelChildParameterSource which takes its
99+
* value from a text with expressions. Expressions are evaluated just before
100+
* the child algorithm executes, and can use functions available
101+
* in its expression context to include results calculated from the child
102+
* algorithms already executed by the model.
103+
* \see fromStaticValue()
104+
* \see fromChildOutput()
105+
* \see fromModelParameter()
106+
* \see fromExpression()
107+
* \since QGIS 3.2
108+
*/
109+
static QgsProcessingModelChildParameterSource fromExpressionText( const QString &text );
110+
91111
/**
92112
* Returns the parameter value's source.
93113
*/
@@ -160,6 +180,25 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
160180
*/
161181
void setExpression( const QString &expression ) { mExpression = expression; mSource = Expression; }
162182

183+
/**
184+
* Returns the source's text with expressions. This is only used when the
185+
* source() is ExpressionText.
186+
* \see setExpressionText()
187+
* \since QGIS 3.2
188+
*/
189+
QString expressionText() const { return mExpressionText; }
190+
191+
/**
192+
* Sets the source's text containing expressions. Calling this will also
193+
* change the source() to ExpressionText. Expressions are evaluated just
194+
* before the child algorithm executes, and can use functions available
195+
* in its expression context to include results calculated from the child
196+
* algorithms already executed by the model.
197+
* \see expressionText()
198+
* \since QGIS 3.2
199+
*/
200+
void setExpressionText( const QString &text ) { mExpressionText = text; mSource = ExpressionText; }
201+
163202
/**
164203
* Saves this source to a QVariant.
165204
* \see loadVariant()
@@ -185,6 +224,7 @@ class CORE_EXPORT QgsProcessingModelChildParameterSource
185224
QString mChildId;
186225
QString mOutputName;
187226
QString mExpression;
227+
QString mExpressionText;
188228

189229
};
190230

‎src/gui/qgsfieldexpressionwidget.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,8 @@ bool QgsFieldExpressionWidget::isExpressionValid( const QString &expressionStr )
346346
expression.prepare( &mExpressionContext );
347347
return !expression.hasParserError();
348348
}
349+
350+
void QgsFieldExpressionWidget::appendScope( QgsExpressionContextScope *scope )
351+
{
352+
mExpressionContext.appendScope( scope );
353+
}

‎src/gui/qgsfieldexpressionwidget.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
6060
//! define the title used in the expression dialog
6161
void setExpressionDialogTitle( const QString &title );
6262

63+
/**
64+
* Appends a scope to the current expression context.
65+
*
66+
* \param scope The scope to add.
67+
*
68+
* \since QGIS 3.2
69+
*/
70+
void appendScope( QgsExpressionContextScope *scope SIP_TRANSFER );
71+
6372
//! return the title used for the expression dialog
6473
const QString expressionDialogTitle() { return mExpressionDialogTitle; }
6574

0 commit comments

Comments
 (0)
Please sign in to comment.