Skip to content
Permalink
Browse files

Display variables and functions from contexts in expression builder

  • Loading branch information
nyalldawson committed Aug 22, 2015
1 parent c9c12bc commit bfc8f56ad4ef87409dd677189d7b58dea416f85e
@@ -678,6 +678,12 @@ class QgsComposition : QGraphicsScene
*/
void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext* context = 0 );

/** Creates an expression context relating to the compositions's current state. The context includes
* scopes for global, project, composition and atlas properties.
* @note added in QGIS 2.12
*/
QgsExpressionContext* createExpressionContext() const;

protected:
void init();

@@ -121,6 +121,7 @@ class QgsExpressionContextScope
QVariant variable( const QString& name ) const;

/** Returns a list of variable names contained within the scope.
* @see functionNames()
*/
QStringList variableNames() const;

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

/** Retrieves a list of names of functions contained in the scope.
* @see function()
* @see variableNames()
*/
QStringList functionNames() const;

/** Adds a function to the scope.
* @param name function name
* @param function function to insert. Ownership is transferred to the scope.
@@ -163,7 +171,7 @@ class QgsExpressionContextScope
* @param feature feature for scope
*/
void setFeature( const QgsFeature& feature );

/** Convenience function for setting a fields for the scope. Any existing
* fields set by the scope will be overwritten.
* @param fields fields for scope
@@ -253,11 +261,20 @@ class QgsExpressionContext

/** Returns a list of variables names set by all scopes in the context.
* @returns list of unique variable names
* @see filteredVariableNames
* @see functionNames
* @see hasVariable
* @see variable
*/
QStringList variableNames() const;

/** Returns a filtered list of variables names set by all scopes in the context. The included
* variables are those which should be seen by users.
* @returns filtered list of unique variable names
* @see variableNames
*/
QStringList filteredVariableNames() const;

/** Returns whether a variable is read only, and should not be modifiable by users.
* @param name variable name
* @returns true if variable is read only. Read only status will be taken from last
@@ -272,6 +289,12 @@ class QgsExpressionContext
*/
bool hasFunction( const QString& name ) const;

/** Retrieves a list of function names contained in the context.
* @see function()
* @see variableNames()
*/
QStringList functionNames() const;

/** Fetches a matching function from the context. The function will be fetched
* from the last scope contained within the context which has a matching
* function set.
@@ -297,21 +320,21 @@ class QgsExpressionContext
* context. Ownership of the scope is transferred to the stack.
*/
QgsExpressionContext& operator<< ( QgsExpressionContextScope* scope /Transfer/ );

/** Convenience function for setting a feature for the context. The feature
* will be set within the last scope of the context, so will override any
* existing features within the context.
* @param feature feature for context
*/
void setFeature( const QgsFeature& feature );
void setFeature( const QgsFeature& feature );

/** Convenience function for setting a fields for the context. The fields
* will be set within the last scope of the context, so will override any
* existing fields within the context.
* @param fields fields for context
*/
void setFields( const QgsFields& fields );

};

/** \ingroup core
@@ -378,12 +401,12 @@ class QgsExpressionContextUtils
* For instance, layer name, id and fields.
*/
static QgsExpressionContextScope* layerScope( QgsMapLayer* layer ) /Factory/;

/** Helper function for creating an expression context which contains just a feature and fields
* collection. Generally this method should not be used as the created context does not include
* standard scopes such as the global and project scopes.
*/
static QgsExpressionContext createFeatureBasedContext( const QgsFeature& feature, const QgsFields& fields );
static QgsExpressionContext createFeatureBasedContext( const QgsFeature& feature, const QgsFields& fields );

/** Sets a layer context variable. This variable will be contained within scopes retrieved via
* layerScope().
@@ -8,7 +8,8 @@ class QgsExpressionBuilderDialog : QDialog
%End

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

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

QString expressionText();

/** Returns the expression context for the dialog. The context is used for the expression
* preview result and for populating the list of available functions and variables.
* @see setExpressionContext
* @note added in QGIS 2.12
*/
QgsExpressionContext expressionContext() const;

/** Sets the expression context for the dialog. The context is used for the expression
* preview result and for populating the list of available functions and variables.
* @param context expression context
* @see expressionContext
* @note added in QGIS 2.12
*/
void setExpressionContext( const QgsExpressionContext& context );

/** Sets geometry calculator used in distance/area calculations. */
void setGeomCalculator( const QgsDistanceArea & da );

@@ -100,6 +100,21 @@ class QgsExpressionBuilderWidget : QWidget
/** Sets the expression string for the widget */
void setExpressionText( const QString& expression );

/** Returns the expression context for the widget. The context is used for the expression
* preview result and for populating the list of available functions and variables.
* @see setExpressionContext
* @note added in QGIS 2.12
*/
QgsExpressionContext expressionContext() const;

/** Sets the expression context for the widget. The context is used for the expression
* preview result and for populating the list of available functions and variables.
* @param context expression context
* @see expressionContext
* @note added in QGIS 2.12
*/
void setExpressionContext( const QgsExpressionContext& context );

/** Registers a node item for the expression builder.
* @param group The group the item will be show in the tree view. If the group doesn't exsit it will be created.
* @param label The label that is show to the user for the item in the tree.
@@ -94,8 +94,10 @@ void QgsAtlasCompositionWidget::on_mAtlasFilenameExpressionButton_clicked()
return;
}

QgsExpressionBuilderDialog exprDlg( atlasMap->coverageLayer(), mAtlasFilenamePatternEdit->text(), this );
QScopedPointer<QgsExpressionContext> context( mComposition->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( atlasMap->coverageLayer(), mAtlasFilenamePatternEdit->text(), this, "generic", *context );
exprDlg.setWindowTitle( tr( "Expression based filename" ) );

if ( exprDlg.exec() == QDialog::Accepted )
{
QString expression = exprDlg.expressionText();
@@ -233,8 +235,10 @@ void QgsAtlasCompositionWidget::on_mAtlasFeatureFilterButton_clicked()
return;
}

QgsExpressionBuilderDialog exprDlg( vl, mAtlasFeatureFilterEdit->text(), this );
QScopedPointer<QgsExpressionContext> context( mComposition->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( vl, mAtlasFeatureFilterEdit->text(), this, "generic", *context );
exprDlg.setWindowTitle( tr( "Expression based filter" ) );

if ( exprDlg.exec() == QDialog::Accepted )
{
QString expression = exprDlg.expressionText();
@@ -798,7 +798,8 @@ void QgsComposerAttributeTableWidget::on_mFeatureFilterButton_clicked()
return;
}

QgsExpressionBuilderDialog exprDlg( mComposerTable->sourceLayer(), mFeatureFilterEdit->text(), this );
QScopedPointer<QgsExpressionContext> context( mComposerTable->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( mComposerTable->sourceLayer(), mFeatureFilterEdit->text(), this, "generic", *context );
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
if ( exprDlg.exec() == QDialog::Accepted )
{
@@ -369,7 +369,8 @@ void QgsComposerHtmlWidget::on_mInsertExpressionButton_clicked()

// use the atlas coverage layer, if any
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this );
QScopedPointer<QgsExpressionContext> context( mHtml->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this, "generic", *context );
exprDlg.setWindowTitle( tr( "Insert expression" ) );
if ( exprDlg.exec() == QDialog::Accepted )
{
@@ -152,7 +152,9 @@ void QgsComposerLabelWidget::on_mInsertExpressionButton_clicked()

// use the atlas coverage layer, if any
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this );
QScopedPointer<QgsExpressionContext> context( mComposerLabel->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( coverageLayer, selText, this, "generic", *context );

exprDlg.setWindowTitle( tr( "Insert expression" ) );
if ( exprDlg.exec() == QDialog::Accepted )
{
@@ -464,7 +464,9 @@ void QgsComposerTableWidget::on_mFeatureFilterButton_clicked()
return;
}

QgsExpressionBuilderDialog exprDlg( mComposerTable->vectorLayer(), mFeatureFilterEdit->text(), this );
QScopedPointer<QgsExpressionContext> context( mComposerTable->createExpressionContext() );
QgsExpressionBuilderDialog exprDlg( mComposerTable->vectorLayer(), mFeatureFilterEdit->text(), this, "generic", *context );

exprDlg.setWindowTitle( tr( "Expression based filter" ) );
if ( exprDlg.exec() == QDialog::Accepted )
{
@@ -741,6 +741,12 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
*/
void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext* context = 0 );

/** Creates an expression context relating to the compositions's current state. The context includes
* scopes for global, project, composition and atlas properties.
* @note added in QGIS 2.12
*/
QgsExpressionContext* createExpressionContext() const;

protected:
void init();

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

/** Creates an expression context relating to the compositions's current state. The context includes
* scopes for global, project, composition and atlas properties.
* @note added in QGIS 2.12
*/
QgsExpressionContext* createExpressionContext() const;

/** Check whether any data defined page settings are active.
* @returns true if any data defined page settings are active.
* @note this method was added in version 2.5
@@ -3041,6 +3041,7 @@ QString QgsExpression::group( QString name )
gGroups.insert( "Color", QObject::tr( "Color" ) );
gGroups.insert( "GeometryGroup", QObject::tr( "Geometry" ) );
gGroups.insert( "Record", QObject::tr( "Record" ) );
gGroups.insert( "Variables", QObject::tr( "Variables" ) );
}

//return the translated name for this group. If group does not
@@ -127,6 +127,11 @@ QgsExpression::Function* QgsExpressionContextScope::function( const QString& nam
return mFunctions.contains( name ) ? mFunctions.value( name ) : 0;
}

QStringList QgsExpressionContextScope::functionNames() const
{
return mFunctions.keys();
}

void QgsExpressionContextScope::addFunction( const QString& name, QgsScopedExpressionFunction* function )
{
mFunctions.insert( name, function );
@@ -248,6 +253,22 @@ QStringList QgsExpressionContext::variableNames() const
return names.toSet().toList();
}

QStringList QgsExpressionContext::filteredVariableNames() const
{
QStringList allVariables = variableNames();
QStringList filtered;
Q_FOREACH ( QString variable, allVariables )
{
if ( variable.startsWith( "_" ) )
continue;

filtered << variable;
}

filtered.sort();
return filtered;
}

bool QgsExpressionContext::isReadOnly( const QString& name ) const { Q_UNUSED( name ); return true; }

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

QStringList QgsExpressionContext::functionNames() const
{
QStringList result;
Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
{
result << scope->functionNames();
}
result = result.toSet().toList();
result.sort();
return result;
}

QgsExpression::Function *QgsExpressionContext::function( const QString &name ) const
{
//iterate through stack backwards, so that higher priority variables take precedence
@@ -150,6 +150,7 @@ class CORE_EXPORT QgsExpressionContextScope
QVariant variable( const QString& name ) const;

/** Returns a list of variable names contained within the scope.
* @see functionNames()
*/
QStringList variableNames() const;

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

/** Retrieves a list of names of functions contained in the scope.
* @see function()
* @see variableNames()
*/
QStringList functionNames() const;

/** Adds a function to the scope.
* @param name function name
* @param function function to insert. Ownership is transferred to the scope.
@@ -284,11 +292,20 @@ class CORE_EXPORT QgsExpressionContext

/** Returns a list of variables names set by all scopes in the context.
* @returns list of unique variable names
* @see filteredVariableNames
* @see functionNames
* @see hasVariable
* @see variable
*/
QStringList variableNames() const;

/** Returns a filtered list of variables names set by all scopes in the context. The included
* variables are those which should be seen by users.
* @returns filtered list of unique variable names
* @see variableNames
*/
QStringList filteredVariableNames() const;

/** Returns whether a variable is read only, and should not be modifiable by users.
* @param name variable name
* @returns true if variable is read only. Read only status will be taken from last
@@ -303,6 +320,12 @@ class CORE_EXPORT QgsExpressionContext
*/
bool hasFunction( const QString& name ) const;

/** Retrieves a list of function names contained in the context.
* @see function()
* @see variableNames()
*/
QStringList functionNames() const;

/** Fetches a matching function from the context. The function will be fetched
* from the last scope contained within the context which has a matching
* function set.

0 comments on commit bfc8f56

Please sign in to comment.
You can’t perform that action at this time.