Skip to content

Commit be26c61

Browse files
committedAug 22, 2015
Ensure expression context is available to expression builders
called from field expression widgets
1 parent 1c1e574 commit be26c61

16 files changed

+213
-20
lines changed
 

‎python/gui/qgsfieldexpressionwidget.sip

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ class QgsFieldExpressionWidget : QWidget
4949
//! Returns the currently used layer
5050
QgsVectorLayer* layer() const;
5151

52+
//! Callback function for retrieving the expression context for the expression
53+
//typedef QgsExpressionContext( *ExpressionContextCallback )( const void* context );
54+
55+
/** Register callback function for retrieving the expression context for the expression
56+
* @param fnGetExpressionContext call back function, will be called when the widget requires
57+
* the current expression context
58+
* @param context context for callback function
59+
* @note added in QGIS 2.12
60+
* @note not available in Python bindings
61+
*/
62+
//void registerGetExpressionContextCallback( ExpressionContextCallback fnGetExpressionContext, const void* context );
63+
5264
signals:
5365
//! the signal is emitted when the currently selected field changes
5466
void fieldChanged( QString fieldName );

‎src/app/composer/qgsatlascompositionwidget.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@
2525
#include "qgsexpressionbuilderdialog.h"
2626
#include "qgscomposermap.h"
2727

28+
static QgsExpressionContext _getExpressionContext( const void* context )
29+
{
30+
const QgsComposition* composition = ( const QgsComposition* ) context;
31+
if ( !composition )
32+
{
33+
return QgsExpressionContext();
34+
}
35+
36+
QScopedPointer< QgsExpressionContext > expContext( composition->createExpressionContext() );
37+
return QgsExpressionContext( *expContext );
38+
}
39+
2840
QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsComposition* c ):
2941
QWidget( parent ), mComposition( c )
3042
{
@@ -42,6 +54,8 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
4254
// connect to updates
4355
connect( &mComposition->atlasComposition(), SIGNAL( parameterChanged() ), this, SLOT( updateGuiElements() ) );
4456

57+
mPageNameWidget->registerGetExpressionContextCallback( &_getExpressionContext, mComposition );
58+
4559
updateGuiElements();
4660
}
4761

‎src/app/composer/qgsattributeselectiondialog.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,34 @@ void QgsComposerColumnAlignmentDelegate::updateEditorGeometry( QWidget* editor,
9090

9191
// QgsComposerColumnSourceDelegate
9292

93-
QgsComposerColumnSourceDelegate::QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject* parent ) : QItemDelegate( parent ),
94-
mVectorLayer( vlayer )
93+
QgsComposerColumnSourceDelegate::QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject* parent, const QgsComposerObject* composerObject )
94+
: QItemDelegate( parent )
95+
, mVectorLayer( vlayer )
96+
, mComposerObject( composerObject )
9597
{
9698

9799
}
98100

101+
static QgsExpressionContext _getExpressionContext( const void* context )
102+
{
103+
const QgsComposerObject* object = ( const QgsComposerObject* ) context;
104+
if ( !object )
105+
{
106+
return QgsExpressionContext();
107+
}
108+
109+
QScopedPointer< QgsExpressionContext > expContext( object->createExpressionContext() );
110+
return QgsExpressionContext( *expContext );
111+
}
112+
99113
QWidget* QgsComposerColumnSourceDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
100114
{
101115
Q_UNUSED( option );
102116
Q_UNUSED( index );
103117

104118
QgsFieldExpressionWidget *fieldExpression = new QgsFieldExpressionWidget( parent );
105119
fieldExpression->setLayer( mVectorLayer );
120+
fieldExpression->registerGetExpressionContextCallback( &_getExpressionContext, mComposerObject );
106121

107122
//listen out for field changes
108123
connect( fieldExpression, SIGNAL( fieldChanged( QString ) ), this, SLOT( commitAndCloseEditor() ) );
@@ -281,7 +296,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
281296
mColumnsTableView->setModel( mColumnModel );
282297
mColumnsTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
283298

284-
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView );
299+
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView, mComposerTable );
285300
mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
286301
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
287302
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
@@ -336,7 +351,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
336351
mColumnsTableView->setModel( mColumnModelV1 );
337352
mColumnsTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
338353

339-
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView );
354+
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView, mComposerTableV1 );
340355
mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
341356
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
342357
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );

‎src/app/composer/qgsattributeselectiondialog.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class QgsComposerAttributeTableColumnModelV2;
3434
class QgsComposerTableSortColumnsProxyModel;
3535
class QgsComposerTableSortColumnsProxyModelV2;
3636
class QgsComposerTableAvailableSortProxyModelV2;
37+
class QgsComposerObject;
3738

3839
// QgsComposerColumnAlignmentDelegate
3940

@@ -60,7 +61,7 @@ class QgsComposerColumnSourceDelegate : public QItemDelegate
6061
Q_OBJECT
6162

6263
public:
63-
QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject *parent = 0 );
64+
QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject *parent = 0, const QgsComposerObject* composerObject = 0 );
6465
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
6566
void setEditorData( QWidget *editor, const QModelIndex &index ) const override;
6667
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override;
@@ -69,6 +70,7 @@ class QgsComposerColumnSourceDelegate : public QItemDelegate
6970
void commitAndCloseEditor();
7071
private:
7172
QgsVectorLayer* mVectorLayer;
73+
const QgsComposerObject* mComposerObject;
7274
};
7375

7476
// QgsComposerColumnWidthDelegate

‎src/app/qgsattributetabledialog.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ class QgsAttributeTableDock : public QDockWidget
6161
}
6262
};
6363

64+
static QgsExpressionContext _getExpressionContext( const void* context )
65+
{
66+
QgsExpressionContext expContext;
67+
expContext << QgsExpressionContextUtils::globalScope()
68+
<< QgsExpressionContextUtils::projectScope();
69+
70+
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
71+
if ( layer )
72+
expContext << QgsExpressionContextUtils::layerScope( layer );
73+
74+
return expContext;
75+
}
76+
6477
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
6578
: QDialog( parent, flags )
6679
, mDock( 0 )
@@ -222,6 +235,8 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
222235
break;
223236
}
224237

238+
mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );
239+
225240
mFieldModel = new QgsFieldModel();
226241
mFieldModel->setLayer( mLayer );
227242
mFieldCombo->setModel( mFieldModel );

‎src/app/qgsdiagramproperties.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,23 @@
3636
#include <QMessageBox>
3737
#include <QSettings>
3838

39+
static QgsExpressionContext _getExpressionContext( const void* context )
40+
{
41+
QgsExpressionContext expContext;
42+
expContext << QgsExpressionContextUtils::globalScope()
43+
<< QgsExpressionContextUtils::projectScope();
44+
45+
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
46+
if ( layer )
47+
expContext << QgsExpressionContextUtils::layerScope( layer );
48+
49+
return expContext;
50+
}
51+
3952
QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* parent )
4053
: QWidget( parent )
4154
{
4255
mLayer = layer;
43-
4456
if ( !layer )
4557
{
4658
return;
@@ -55,6 +67,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* pare
5567
connect( mEnableDiagramsCheckBox, SIGNAL( toggled( bool ) ), mDiagramFrame, SLOT( setEnabled( bool ) ) );
5668

5769
mScaleRangeWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
70+
mSizeFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );
5871

5972
mBackgroundColorButton->setColorDialogTitle( tr( "Select background color" ) );
6073
mBackgroundColorButton->setAllowAlpha( true );

‎src/app/qgslabelinggui.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@
3838
#include <QCheckBox>
3939
#include <QSettings>
4040

41+
static QgsExpressionContext _getExpressionContext( const void* context )
42+
{
43+
QgsExpressionContext expContext;
44+
expContext << QgsExpressionContextUtils::globalScope()
45+
<< QgsExpressionContextUtils::projectScope();
46+
47+
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
48+
if ( layer )
49+
expContext << QgsExpressionContextUtils::layerScope( layer );
50+
51+
return expContext;
52+
}
4153

4254
QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, QWidget* parent )
4355
: QWidget( parent )
@@ -58,6 +70,9 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
5870
return;
5971

6072
setupUi( this );
73+
74+
mFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );
75+
6176
mFontSizeUnitWidget->setUnits( QStringList() << tr( "Points" ) << tr( "Map unit" ), 1 );
6277
mBufferUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit );
6378
mShapeSizeUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit );
@@ -872,19 +887,6 @@ void QgsLabelingGui::setDataDefinedProperty( const QgsDataDefinedButton* ddBtn,
872887
lyr.setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
873888
}
874889

875-
static QgsExpressionContext _getExpressionContext( const void* context )
876-
{
877-
QgsExpressionContext expContext;
878-
expContext << QgsExpressionContextUtils::globalScope()
879-
<< QgsExpressionContextUtils::projectScope();
880-
881-
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
882-
if ( layer )
883-
expContext << QgsExpressionContextUtils::layerScope( layer );
884-
885-
return expContext;
886-
}
887-
888890
void QgsLabelingGui::populateDataDefinedButtons( QgsPalLayerSettings& s )
889891
{
890892
Q_FOREACH ( QgsDataDefinedButton* button, findChildren< QgsDataDefinedButton* >() )

‎src/app/qgsstatisticalsummarydockwidget.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,29 @@ QList< QgsStatisticalSummary::Statistic > QgsStatisticalSummaryDockWidget::mDisp
3838

3939
#define MISSING_VALUES -1
4040

41+
static QgsExpressionContext _getExpressionContext( const void* context )
42+
{
43+
QgsExpressionContext expContext;
44+
expContext << QgsExpressionContextUtils::globalScope()
45+
<< QgsExpressionContextUtils::projectScope();
46+
47+
const QgsStatisticalSummaryDockWidget* widget = ( const QgsStatisticalSummaryDockWidget* ) context;
48+
if ( widget )
49+
{
50+
expContext << QgsExpressionContextUtils::layerScope( widget->layer() );
51+
}
52+
53+
return expContext;
54+
}
55+
4156
QgsStatisticalSummaryDockWidget::QgsStatisticalSummaryDockWidget( QWidget *parent )
4257
: QDockWidget( parent )
4358
, mLayer( 0 )
4459
{
4560
setupUi( this );
4661

62+
mFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, this );
63+
4764
mLayerComboBox->setFilters( QgsMapLayerProxyModel::VectorLayer );
4865
mFieldExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
4966

‎src/app/qgsstatisticalsummarydockwidget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class APP_EXPORT QgsStatisticalSummaryDockWidget : public QDockWidget, private U
3838
QgsStatisticalSummaryDockWidget( QWidget *parent = 0 );
3939
~QgsStatisticalSummaryDockWidget();
4040

41+
/** Returns the currently active layer for the widget
42+
* @note added in QGIS 2.12
43+
*/
44+
QgsVectorLayer* layer() const { return mLayer; }
45+
4146
public slots:
4247

4348
/** Recalculates the displayed statistics

‎src/gui/editorwidgets/qgsrelationreferenceconfigdlg.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,27 @@
2222
#include "qgsvectorlayer.h"
2323
#include "qgsexpressionbuilderdialog.h"
2424

25+
static QgsExpressionContext _getExpressionContext( const void* context )
26+
{
27+
QgsExpressionContext expContext;
28+
expContext << QgsExpressionContextUtils::globalScope()
29+
<< QgsExpressionContextUtils::projectScope();
30+
31+
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
32+
if ( layer )
33+
expContext << QgsExpressionContextUtils::layerScope( layer );
34+
35+
return expContext;
36+
}
2537

2638
QgsRelationReferenceConfigDlg::QgsRelationReferenceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
2739
: QgsEditorConfigWidget( vl, fieldIdx, parent )
2840
, mReferencedLayer( 0 )
2941
{
3042
setupUi( this );
43+
44+
mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, vl );
45+
3146
connect( mComboRelation, SIGNAL( currentIndexChanged( int ) ), this, SLOT( relationChanged( int ) ) );
3247

3348
foreach ( const QgsRelation& relation, vl->referencingRelations( fieldIdx ) )

‎src/gui/qgsfieldexpressionwidget.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ QgsFieldExpressionWidget::QgsFieldExpressionWidget( QWidget *parent )
2626
: QWidget( parent )
2727
, mExpressionDialogTitle( tr( "Expression dialog" ) )
2828
, mDa( 0 )
29+
, mExpressionContextCallback( 0 )
30+
, mExpressionContextCallbackContext( 0 )
2931
{
3032
QHBoxLayout* layout = new QHBoxLayout( this );
3133
layout->setContentsMargins( 0, 0, 0, 0 );
@@ -127,6 +129,12 @@ QgsVectorLayer *QgsFieldExpressionWidget::layer() const
127129
return mFieldProxyModel->sourceFieldModel()->layer();
128130
}
129131

132+
void QgsFieldExpressionWidget::registerGetExpressionContextCallback( QgsFieldExpressionWidget::ExpressionContextCallback fnGetExpressionContext, const void *context )
133+
{
134+
mExpressionContextCallback = fnGetExpressionContext;
135+
mExpressionContextCallbackContext = context;
136+
}
137+
130138
void QgsFieldExpressionWidget::setLayer( QgsMapLayer *layer )
131139
{
132140
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
@@ -180,7 +188,9 @@ void QgsFieldExpressionWidget::editExpression()
180188
QString currentExpression = currentText();
181189
QgsVectorLayer* vl = layer();
182190

183-
QgsExpressionBuilderDialog dlg( vl, currentExpression );
191+
QgsExpressionContext context = mExpressionContextCallback ? mExpressionContextCallback( mExpressionContextCallbackContext ) : *mExpressionContext;
192+
193+
QgsExpressionBuilderDialog dlg( vl, currentExpression, this, "generic", context );
184194
if ( !mDa.isNull() )
185195
{
186196
dlg.setGeomCalculator( *mDa );

‎src/gui/qgsfieldexpressionwidget.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
8888
//! Returns the currently used layer
8989
QgsVectorLayer* layer() const;
9090

91+
//! Callback function for retrieving the expression context for the expression
92+
typedef QgsExpressionContext( *ExpressionContextCallback )( const void* context );
93+
94+
/** Register callback function for retrieving the expression context for the expression
95+
* @param fnGetExpressionContext call back function, will be called when the widget requires
96+
* the current expression context
97+
* @param context context for callback function
98+
* @note added in QGIS 2.12
99+
* @note not available in Python bindings
100+
*/
101+
void registerGetExpressionContextCallback( ExpressionContextCallback fnGetExpressionContext, const void* context );
102+
91103
signals:
92104
//! the signal is emitted when the currently selected field changes
93105
void fieldChanged( QString fieldName );
@@ -138,6 +150,8 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
138150
QString mExpressionDialogTitle;
139151
QSharedPointer<const QgsDistanceArea> mDa;
140152
QScopedPointer< QgsExpressionContext > mExpressionContext;
153+
ExpressionContextCallback mExpressionContextCallback;
154+
const void* mExpressionContextCallbackContext;
141155
};
142156

143157
#endif // QGSFIELDEXPRESSIONWIDGET_H

‎src/gui/symbology-ng/qgscategorizedsymbolrendererv2widget.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,19 @@ QgsRendererV2Widget* QgsCategorizedSymbolRendererV2Widget::create( QgsVectorLaye
370370
return new QgsCategorizedSymbolRendererV2Widget( layer, style, renderer );
371371
}
372372

373+
static QgsExpressionContext _getExpressionContext( const void* context )
374+
{
375+
QgsExpressionContext expContext;
376+
expContext << QgsExpressionContextUtils::globalScope()
377+
<< QgsExpressionContextUtils::projectScope();
378+
379+
const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
380+
if ( layer )
381+
expContext << QgsExpressionContextUtils::layerScope( layer );
382+
383+
return expContext;
384+
}
385+
373386
QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
374387
: QgsRendererV2Widget( layer, style )
375388
, mRenderer( 0 )
@@ -451,6 +464,8 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
451464
advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );
452465

453466
btnAdvanced->setMenu( advMenu );
467+
468+
mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, layer );
454469
}
455470

456471
QgsCategorizedSymbolRendererV2Widget::~QgsCategorizedSymbolRendererV2Widget()

0 commit comments

Comments
 (0)