Skip to content

Commit bfc8f56

Browse files
committedAug 22, 2015
Display variables and functions from contexts in expression builder
1 parent c9c12bc commit bfc8f56

18 files changed

+245
-30
lines changed
 

‎python/core/composer/qgscomposition.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,12 @@ class QgsComposition : QGraphicsScene
678678
*/
679679
void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext* context = 0 );
680680

681+
/** Creates an expression context relating to the compositions's current state. The context includes
682+
* scopes for global, project, composition and atlas properties.
683+
* @note added in QGIS 2.12
684+
*/
685+
QgsExpressionContext* createExpressionContext() const;
686+
681687
protected:
682688
void init();
683689

‎python/core/qgsexpressioncontext.sip

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class QgsExpressionContextScope
121121
QVariant variable( const QString& name ) const;
122122

123123
/** Returns a list of variable names contained within the scope.
124+
* @see functionNames()
124125
*/
125126
QStringList variableNames() const;
126127

@@ -147,10 +148,17 @@ class QgsExpressionContextScope
147148
* @param name function name
148149
* @returns function, or null if matching function could not be found
149150
* @see hasFunction()
151+
* @see functionNames()
150152
* @see variable()
151153
*/
152154
QgsExpression::Function* function( const QString &name ) const;
153155

156+
/** Retrieves a list of names of functions contained in the scope.
157+
* @see function()
158+
* @see variableNames()
159+
*/
160+
QStringList functionNames() const;
161+
154162
/** Adds a function to the scope.
155163
* @param name function name
156164
* @param function function to insert. Ownership is transferred to the scope.
@@ -163,7 +171,7 @@ class QgsExpressionContextScope
163171
* @param feature feature for scope
164172
*/
165173
void setFeature( const QgsFeature& feature );
166-
174+
167175
/** Convenience function for setting a fields for the scope. Any existing
168176
* fields set by the scope will be overwritten.
169177
* @param fields fields for scope
@@ -253,11 +261,20 @@ class QgsExpressionContext
253261

254262
/** Returns a list of variables names set by all scopes in the context.
255263
* @returns list of unique variable names
264+
* @see filteredVariableNames
265+
* @see functionNames
256266
* @see hasVariable
257267
* @see variable
258268
*/
259269
QStringList variableNames() const;
260270

271+
/** Returns a filtered list of variables names set by all scopes in the context. The included
272+
* variables are those which should be seen by users.
273+
* @returns filtered list of unique variable names
274+
* @see variableNames
275+
*/
276+
QStringList filteredVariableNames() const;
277+
261278
/** Returns whether a variable is read only, and should not be modifiable by users.
262279
* @param name variable name
263280
* @returns true if variable is read only. Read only status will be taken from last
@@ -272,6 +289,12 @@ class QgsExpressionContext
272289
*/
273290
bool hasFunction( const QString& name ) const;
274291

292+
/** Retrieves a list of function names contained in the context.
293+
* @see function()
294+
* @see variableNames()
295+
*/
296+
QStringList functionNames() const;
297+
275298
/** Fetches a matching function from the context. The function will be fetched
276299
* from the last scope contained within the context which has a matching
277300
* function set.
@@ -297,21 +320,21 @@ class QgsExpressionContext
297320
* context. Ownership of the scope is transferred to the stack.
298321
*/
299322
QgsExpressionContext& operator<< ( QgsExpressionContextScope* scope /Transfer/ );
300-
323+
301324
/** Convenience function for setting a feature for the context. The feature
302325
* will be set within the last scope of the context, so will override any
303326
* existing features within the context.
304327
* @param feature feature for context
305328
*/
306-
void setFeature( const QgsFeature& feature );
329+
void setFeature( const QgsFeature& feature );
307330

308331
/** Convenience function for setting a fields for the context. The fields
309332
* will be set within the last scope of the context, so will override any
310333
* existing fields within the context.
311334
* @param fields fields for context
312335
*/
313336
void setFields( const QgsFields& fields );
314-
337+
315338
};
316339

317340
/** \ingroup core
@@ -378,12 +401,12 @@ class QgsExpressionContextUtils
378401
* For instance, layer name, id and fields.
379402
*/
380403
static QgsExpressionContextScope* layerScope( QgsMapLayer* layer ) /Factory/;
381-
404+
382405
/** Helper function for creating an expression context which contains just a feature and fields
383406
* collection. Generally this method should not be used as the created context does not include
384407
* standard scopes such as the global and project scopes.
385408
*/
386-
static QgsExpressionContext createFeatureBasedContext( const QgsFeature& feature, const QgsFields& fields );
409+
static QgsExpressionContext createFeatureBasedContext( const QgsFeature& feature, const QgsFields& fields );
387410

388411
/** Sets a layer context variable. This variable will be contained within scopes retrieved via
389412
* layerScope().

‎python/gui/qgsexpressionbuilderdialog.sip

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class QgsExpressionBuilderDialog : QDialog
88
%End
99

1010
public:
11-
QgsExpressionBuilderDialog( QgsVectorLayer* layer, QString startText = QString(), QWidget* parent /TransferThis/ = NULL, QString key = "generic" );
11+
QgsExpressionBuilderDialog( QgsVectorLayer* layer, QString startText = QString(), QWidget* parent /TransferThis/ = NULL, QString key = "generic",
12+
const QgsExpressionContext& context = QgsExpressionContext() );
1213

1314
/** The builder widget that is used by the dialog */
1415
QgsExpressionBuilderWidget* expressionBuilder();
@@ -17,6 +18,21 @@ class QgsExpressionBuilderDialog : QDialog
1718

1819
QString expressionText();
1920

21+
/** Returns the expression context for the dialog. The context is used for the expression
22+
* preview result and for populating the list of available functions and variables.
23+
* @see setExpressionContext
24+
* @note added in QGIS 2.12
25+
*/
26+
QgsExpressionContext expressionContext() const;
27+
28+
/** Sets the expression context for the dialog. The context is used for the expression
29+
* preview result and for populating the list of available functions and variables.
30+
* @param context expression context
31+
* @see expressionContext
32+
* @note added in QGIS 2.12
33+
*/
34+
void setExpressionContext( const QgsExpressionContext& context );
35+
2036
/** Sets geometry calculator used in distance/area calculations. */
2137
void setGeomCalculator( const QgsDistanceArea & da );
2238

‎python/gui/qgsexpressionbuilderwidget.sip

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ class QgsExpressionBuilderWidget : QWidget
100100
/** Sets the expression string for the widget */
101101
void setExpressionText( const QString& expression );
102102

103+
/** Returns the expression context for the widget. The context is used for the expression
104+
* preview result and for populating the list of available functions and variables.
105+
* @see setExpressionContext
106+
* @note added in QGIS 2.12
107+
*/
108+
QgsExpressionContext expressionContext() const;
109+
110+
/** Sets the expression context for the widget. The context is used for the expression
111+
* preview result and for populating the list of available functions and variables.
112+
* @param context expression context
113+
* @see expressionContext
114+
* @note added in QGIS 2.12
115+
*/
116+
void setExpressionContext( const QgsExpressionContext& context );
117+
103118
/** Registers a node item for the expression builder.
104119
* @param group The group the item will be show in the tree view. If the group doesn't exsit it will be created.
105120
* @param label The label that is show to the user for the item in the tree.

‎src/app/composer/qgsatlascompositionwidget.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ void QgsAtlasCompositionWidget::on_mAtlasFilenameExpressionButton_clicked()
9494
return;
9595
}
9696

97-
QgsExpressionBuilderDialog exprDlg( atlasMap->coverageLayer(), mAtlasFilenamePatternEdit->text(), this );
97+
QScopedPointer<QgsExpressionContext> context( mComposition->createExpressionContext() );
98+
QgsExpressionBuilderDialog exprDlg( atlasMap->coverageLayer(), mAtlasFilenamePatternEdit->text(), this, "generic", *context );
9899
exprDlg.setWindowTitle( tr( "Expression based filename" ) );
100+
99101
if ( exprDlg.exec() == QDialog::Accepted )
100102
{
101103
QString expression = exprDlg.expressionText();
@@ -233,8 +235,10 @@ void QgsAtlasCompositionWidget::on_mAtlasFeatureFilterButton_clicked()
233235
return;
234236
}
235237

236-
QgsExpressionBuilderDialog exprDlg( vl, mAtlasFeatureFilterEdit->text(), this );
238+
QScopedPointer<QgsExpressionContext> context( mComposition->createExpressionContext() );
239+
QgsExpressionBuilderDialog exprDlg( vl, mAtlasFeatureFilterEdit->text(), this, "generic", *context );
237240
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
241+
238242
if ( exprDlg.exec() == QDialog::Accepted )
239243
{
240244
QString expression = exprDlg.expressionText();

‎src/app/composer/qgscomposerattributetablewidget.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,8 @@ void QgsComposerAttributeTableWidget::on_mFeatureFilterButton_clicked()
798798
return;
799799
}
800800

801-
QgsExpressionBuilderDialog exprDlg( mComposerTable->sourceLayer(), mFeatureFilterEdit->text(), this );
801+
QScopedPointer<QgsExpressionContext> context( mComposerTable->createExpressionContext() );
802+
QgsExpressionBuilderDialog exprDlg( mComposerTable->sourceLayer(), mFeatureFilterEdit->text(), this, "generic", *context );
802803
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
803804
if ( exprDlg.exec() == QDialog::Accepted )
804805
{

‎src/app/composer/qgscomposerhtmlwidget.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ void QgsComposerHtmlWidget::on_mInsertExpressionButton_clicked()
369369

370370
// use the atlas coverage layer, if any
371371
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
372-
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this );
372+
QScopedPointer<QgsExpressionContext> context( mHtml->createExpressionContext() );
373+
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this, "generic", *context );
373374
exprDlg.setWindowTitle( tr( "Insert expression" ) );
374375
if ( exprDlg.exec() == QDialog::Accepted )
375376
{

‎src/app/composer/qgscomposerlabelwidget.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ void QgsComposerLabelWidget::on_mInsertExpressionButton_clicked()
152152

153153
// use the atlas coverage layer, if any
154154
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
155-
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this );
155+
QScopedPointer<QgsExpressionContext> context( mComposerLabel->createExpressionContext() );
156+
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this, "generic", *context );
157+
156158
exprDlg.setWindowTitle( tr( "Insert expression" ) );
157159
if ( exprDlg.exec() == QDialog::Accepted )
158160
{

‎src/app/composer/qgscomposertablewidget.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,9 @@ void QgsComposerTableWidget::on_mFeatureFilterButton_clicked()
464464
return;
465465
}
466466

467-
QgsExpressionBuilderDialog exprDlg( mComposerTable->vectorLayer(), mFeatureFilterEdit->text(), this );
467+
QScopedPointer<QgsExpressionContext> context( mComposerTable->createExpressionContext() );
468+
QgsExpressionBuilderDialog exprDlg( mComposerTable->vectorLayer(), mFeatureFilterEdit->text(), this, "generic", *context );
469+
468470
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
469471
if ( exprDlg.exec() == QDialog::Accepted )
470472
{

‎src/core/composer/qgscomposition.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,12 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
741741
*/
742742
void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext* context = 0 );
743743

744+
/** Creates an expression context relating to the compositions's current state. The context includes
745+
* scopes for global, project, composition and atlas properties.
746+
* @note added in QGIS 2.12
747+
*/
748+
QgsExpressionContext* createExpressionContext() const;
749+
744750
protected:
745751
void init();
746752

@@ -900,12 +906,6 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
900906
*/
901907
void prepareDataDefinedExpression( QgsDataDefined *dd, QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties, const QgsExpressionContext& context ) const;
902908

903-
/** Creates an expression context relating to the compositions's current state. The context includes
904-
* scopes for global, project, composition and atlas properties.
905-
* @note added in QGIS 2.12
906-
*/
907-
QgsExpressionContext* createExpressionContext() const;
908-
909909
/** Check whether any data defined page settings are active.
910910
* @returns true if any data defined page settings are active.
911911
* @note this method was added in version 2.5

‎src/core/qgsexpression.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,7 @@ QString QgsExpression::group( QString name )
30413041
gGroups.insert( "Color", QObject::tr( "Color" ) );
30423042
gGroups.insert( "GeometryGroup", QObject::tr( "Geometry" ) );
30433043
gGroups.insert( "Record", QObject::tr( "Record" ) );
3044+
gGroups.insert( "Variables", QObject::tr( "Variables" ) );
30443045
}
30453046

30463047
//return the translated name for this group. If group does not

‎src/core/qgsexpressioncontext.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ QgsExpression::Function* QgsExpressionContextScope::function( const QString& nam
127127
return mFunctions.contains( name ) ? mFunctions.value( name ) : 0;
128128
}
129129

130+
QStringList QgsExpressionContextScope::functionNames() const
131+
{
132+
return mFunctions.keys();
133+
}
134+
130135
void QgsExpressionContextScope::addFunction( const QString& name, QgsScopedExpressionFunction* function )
131136
{
132137
mFunctions.insert( name, function );
@@ -248,6 +253,22 @@ QStringList QgsExpressionContext::variableNames() const
248253
return names.toSet().toList();
249254
}
250255

256+
QStringList QgsExpressionContext::filteredVariableNames() const
257+
{
258+
QStringList allVariables = variableNames();
259+
QStringList filtered;
260+
Q_FOREACH ( QString variable, allVariables )
261+
{
262+
if ( variable.startsWith( "_" ) )
263+
continue;
264+
265+
filtered << variable;
266+
}
267+
268+
filtered.sort();
269+
return filtered;
270+
}
271+
251272
bool QgsExpressionContext::isReadOnly( const QString& name ) const { Q_UNUSED( name ); return true; }
252273

253274
bool QgsExpressionContext::hasFunction( const QString &name ) const
@@ -260,6 +281,18 @@ bool QgsExpressionContext::hasFunction( const QString &name ) const
260281
return false;
261282
}
262283

284+
QStringList QgsExpressionContext::functionNames() const
285+
{
286+
QStringList result;
287+
Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
288+
{
289+
result << scope->functionNames();
290+
}
291+
result = result.toSet().toList();
292+
result.sort();
293+
return result;
294+
}
295+
263296
QgsExpression::Function *QgsExpressionContext::function( const QString &name ) const
264297
{
265298
//iterate through stack backwards, so that higher priority variables take precedence

‎src/core/qgsexpressioncontext.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class CORE_EXPORT QgsExpressionContextScope
150150
QVariant variable( const QString& name ) const;
151151

152152
/** Returns a list of variable names contained within the scope.
153+
* @see functionNames()
153154
*/
154155
QStringList variableNames() const;
155156

@@ -176,10 +177,17 @@ class CORE_EXPORT QgsExpressionContextScope
176177
* @param name function name
177178
* @returns function, or null if matching function could not be found
178179
* @see hasFunction()
180+
* @see functionNames()
179181
* @see variable()
180182
*/
181183
QgsExpression::Function* function( const QString &name ) const;
182184

185+
/** Retrieves a list of names of functions contained in the scope.
186+
* @see function()
187+
* @see variableNames()
188+
*/
189+
QStringList functionNames() const;
190+
183191
/** Adds a function to the scope.
184192
* @param name function name
185193
* @param function function to insert. Ownership is transferred to the scope.
@@ -284,11 +292,20 @@ class CORE_EXPORT QgsExpressionContext
284292

285293
/** Returns a list of variables names set by all scopes in the context.
286294
* @returns list of unique variable names
295+
* @see filteredVariableNames
296+
* @see functionNames
287297
* @see hasVariable
288298
* @see variable
289299
*/
290300
QStringList variableNames() const;
291301

302+
/** Returns a filtered list of variables names set by all scopes in the context. The included
303+
* variables are those which should be seen by users.
304+
* @returns filtered list of unique variable names
305+
* @see variableNames
306+
*/
307+
QStringList filteredVariableNames() const;
308+
292309
/** Returns whether a variable is read only, and should not be modifiable by users.
293310
* @param name variable name
294311
* @returns true if variable is read only. Read only status will be taken from last
@@ -303,6 +320,12 @@ class CORE_EXPORT QgsExpressionContext
303320
*/
304321
bool hasFunction( const QString& name ) const;
305322

323+
/** Retrieves a list of function names contained in the context.
324+
* @see function()
325+
* @see variableNames()
326+
*/
327+
QStringList functionNames() const;
328+
306329
/** Fetches a matching function from the context. The function will be fetched
307330
* from the last scope contained within the context which has a matching
308331
* function set.

0 commit comments

Comments
 (0)
Please sign in to comment.