Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Ensure expression context is available to expression builders
called from field expression widgets
  • Loading branch information
nyalldawson committed Aug 22, 2015
1 parent 1c1e574 commit be26c61
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 20 deletions.
12 changes: 12 additions & 0 deletions python/gui/qgsfieldexpressionwidget.sip
Expand Up @@ -49,6 +49,18 @@ class QgsFieldExpressionWidget : QWidget
//! Returns the currently used layer
QgsVectorLayer* layer() const;

//! Callback function for retrieving the expression context for the expression
//typedef QgsExpressionContext( *ExpressionContextCallback )( const void* context );

/** Register callback function for retrieving the expression context for the expression
* @param fnGetExpressionContext call back function, will be called when the widget requires
* the current expression context
* @param context context for callback function
* @note added in QGIS 2.12
* @note not available in Python bindings
*/
//void registerGetExpressionContextCallback( ExpressionContextCallback fnGetExpressionContext, const void* context );

signals:
//! the signal is emitted when the currently selected field changes
void fieldChanged( QString fieldName );
Expand Down
14 changes: 14 additions & 0 deletions src/app/composer/qgsatlascompositionwidget.cpp
Expand Up @@ -25,6 +25,18 @@
#include "qgsexpressionbuilderdialog.h"
#include "qgscomposermap.h"

static QgsExpressionContext _getExpressionContext( const void* context )
{
const QgsComposition* composition = ( const QgsComposition* ) context;
if ( !composition )
{
return QgsExpressionContext();
}

QScopedPointer< QgsExpressionContext > expContext( composition->createExpressionContext() );
return QgsExpressionContext( *expContext );
}

QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsComposition* c ):
QWidget( parent ), mComposition( c )
{
Expand All @@ -42,6 +54,8 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
// connect to updates
connect( &mComposition->atlasComposition(), SIGNAL( parameterChanged() ), this, SLOT( updateGuiElements() ) );

mPageNameWidget->registerGetExpressionContextCallback( &_getExpressionContext, mComposition );

updateGuiElements();
}

Expand Down
23 changes: 19 additions & 4 deletions src/app/composer/qgsattributeselectiondialog.cpp
Expand Up @@ -90,19 +90,34 @@ void QgsComposerColumnAlignmentDelegate::updateEditorGeometry( QWidget* editor,

// QgsComposerColumnSourceDelegate

QgsComposerColumnSourceDelegate::QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject* parent ) : QItemDelegate( parent ),
mVectorLayer( vlayer )
QgsComposerColumnSourceDelegate::QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject* parent, const QgsComposerObject* composerObject )
: QItemDelegate( parent )
, mVectorLayer( vlayer )
, mComposerObject( composerObject )
{

}

static QgsExpressionContext _getExpressionContext( const void* context )
{
const QgsComposerObject* object = ( const QgsComposerObject* ) context;
if ( !object )
{
return QgsExpressionContext();
}

QScopedPointer< QgsExpressionContext > expContext( object->createExpressionContext() );
return QgsExpressionContext( *expContext );
}

QWidget* QgsComposerColumnSourceDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
Q_UNUSED( option );
Q_UNUSED( index );

QgsFieldExpressionWidget *fieldExpression = new QgsFieldExpressionWidget( parent );
fieldExpression->setLayer( mVectorLayer );
fieldExpression->registerGetExpressionContextCallback( &_getExpressionContext, mComposerObject );

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

mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView );
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView, mComposerTable );
mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
Expand Down Expand Up @@ -336,7 +351,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
mColumnsTableView->setModel( mColumnModelV1 );
mColumnsTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );

mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView );
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView, mComposerTableV1 );
mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
Expand Down
4 changes: 3 additions & 1 deletion src/app/composer/qgsattributeselectiondialog.h
Expand Up @@ -34,6 +34,7 @@ class QgsComposerAttributeTableColumnModelV2;
class QgsComposerTableSortColumnsProxyModel;
class QgsComposerTableSortColumnsProxyModelV2;
class QgsComposerTableAvailableSortProxyModelV2;
class QgsComposerObject;

// QgsComposerColumnAlignmentDelegate

Expand All @@ -60,7 +61,7 @@ class QgsComposerColumnSourceDelegate : public QItemDelegate
Q_OBJECT

public:
QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject *parent = 0 );
QgsComposerColumnSourceDelegate( QgsVectorLayer* vlayer, QObject *parent = 0, const QgsComposerObject* composerObject = 0 );
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
void setEditorData( QWidget *editor, const QModelIndex &index ) const override;
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override;
Expand All @@ -69,6 +70,7 @@ class QgsComposerColumnSourceDelegate : public QItemDelegate
void commitAndCloseEditor();
private:
QgsVectorLayer* mVectorLayer;
const QgsComposerObject* mComposerObject;
};

// QgsComposerColumnWidthDelegate
Expand Down
15 changes: 15 additions & 0 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -61,6 +61,19 @@ class QgsAttributeTableDock : public QDockWidget
}
};

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
: QDialog( parent, flags )
, mDock( 0 )
Expand Down Expand Up @@ -222,6 +235,8 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
break;
}

mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );

mFieldModel = new QgsFieldModel();
mFieldModel->setLayer( mLayer );
mFieldCombo->setModel( mFieldModel );
Expand Down
15 changes: 14 additions & 1 deletion src/app/qgsdiagramproperties.cpp
Expand Up @@ -36,11 +36,23 @@
#include <QMessageBox>
#include <QSettings>

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* parent )
: QWidget( parent )
{
mLayer = layer;

if ( !layer )
{
return;
Expand All @@ -55,6 +67,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* pare
connect( mEnableDiagramsCheckBox, SIGNAL( toggled( bool ) ), mDiagramFrame, SLOT( setEnabled( bool ) ) );

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

mBackgroundColorButton->setColorDialogTitle( tr( "Select background color" ) );
mBackgroundColorButton->setAllowAlpha( true );
Expand Down
28 changes: 15 additions & 13 deletions src/app/qgslabelinggui.cpp
Expand Up @@ -38,6 +38,18 @@
#include <QCheckBox>
#include <QSettings>

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, QWidget* parent )
: QWidget( parent )
Expand All @@ -58,6 +70,9 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
return;

setupUi( this );

mFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );

mFontSizeUnitWidget->setUnits( QStringList() << tr( "Points" ) << tr( "Map unit" ), 1 );
mBufferUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit );
mShapeSizeUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit );
Expand Down Expand Up @@ -872,19 +887,6 @@ void QgsLabelingGui::setDataDefinedProperty( const QgsDataDefinedButton* ddBtn,
lyr.setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
}

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

void QgsLabelingGui::populateDataDefinedButtons( QgsPalLayerSettings& s )
{
Q_FOREACH ( QgsDataDefinedButton* button, findChildren< QgsDataDefinedButton* >() )
Expand Down
17 changes: 17 additions & 0 deletions src/app/qgsstatisticalsummarydockwidget.cpp
Expand Up @@ -38,12 +38,29 @@ QList< QgsStatisticalSummary::Statistic > QgsStatisticalSummaryDockWidget::mDisp

#define MISSING_VALUES -1

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsStatisticalSummaryDockWidget* widget = ( const QgsStatisticalSummaryDockWidget* ) context;
if ( widget )
{
expContext << QgsExpressionContextUtils::layerScope( widget->layer() );
}

return expContext;
}

QgsStatisticalSummaryDockWidget::QgsStatisticalSummaryDockWidget( QWidget *parent )
: QDockWidget( parent )
, mLayer( 0 )
{
setupUi( this );

mFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, this );

mLayerComboBox->setFilters( QgsMapLayerProxyModel::VectorLayer );
mFieldExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );

Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsstatisticalsummarydockwidget.h
Expand Up @@ -38,6 +38,11 @@ class APP_EXPORT QgsStatisticalSummaryDockWidget : public QDockWidget, private U
QgsStatisticalSummaryDockWidget( QWidget *parent = 0 );
~QgsStatisticalSummaryDockWidget();

/** Returns the currently active layer for the widget
* @note added in QGIS 2.12
*/
QgsVectorLayer* layer() const { return mLayer; }

public slots:

/** Recalculates the displayed statistics
Expand Down
15 changes: 15 additions & 0 deletions src/gui/editorwidgets/qgsrelationreferenceconfigdlg.cpp
Expand Up @@ -22,12 +22,27 @@
#include "qgsvectorlayer.h"
#include "qgsexpressionbuilderdialog.h"

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

QgsRelationReferenceConfigDlg::QgsRelationReferenceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
: QgsEditorConfigWidget( vl, fieldIdx, parent )
, mReferencedLayer( 0 )
{
setupUi( this );

mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, vl );

connect( mComboRelation, SIGNAL( currentIndexChanged( int ) ), this, SLOT( relationChanged( int ) ) );

foreach ( const QgsRelation& relation, vl->referencingRelations( fieldIdx ) )
Expand Down
12 changes: 11 additions & 1 deletion src/gui/qgsfieldexpressionwidget.cpp
Expand Up @@ -26,6 +26,8 @@ QgsFieldExpressionWidget::QgsFieldExpressionWidget( QWidget *parent )
: QWidget( parent )
, mExpressionDialogTitle( tr( "Expression dialog" ) )
, mDa( 0 )
, mExpressionContextCallback( 0 )
, mExpressionContextCallbackContext( 0 )
{
QHBoxLayout* layout = new QHBoxLayout( this );
layout->setContentsMargins( 0, 0, 0, 0 );
Expand Down Expand Up @@ -127,6 +129,12 @@ QgsVectorLayer *QgsFieldExpressionWidget::layer() const
return mFieldProxyModel->sourceFieldModel()->layer();
}

void QgsFieldExpressionWidget::registerGetExpressionContextCallback( QgsFieldExpressionWidget::ExpressionContextCallback fnGetExpressionContext, const void *context )
{
mExpressionContextCallback = fnGetExpressionContext;
mExpressionContextCallbackContext = context;
}

void QgsFieldExpressionWidget::setLayer( QgsMapLayer *layer )
{
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
Expand Down Expand Up @@ -180,7 +188,9 @@ void QgsFieldExpressionWidget::editExpression()
QString currentExpression = currentText();
QgsVectorLayer* vl = layer();

QgsExpressionBuilderDialog dlg( vl, currentExpression );
QgsExpressionContext context = mExpressionContextCallback ? mExpressionContextCallback( mExpressionContextCallbackContext ) : *mExpressionContext;

QgsExpressionBuilderDialog dlg( vl, currentExpression, this, "generic", context );
if ( !mDa.isNull() )
{
dlg.setGeomCalculator( *mDa );
Expand Down
14 changes: 14 additions & 0 deletions src/gui/qgsfieldexpressionwidget.h
Expand Up @@ -88,6 +88,18 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
//! Returns the currently used layer
QgsVectorLayer* layer() const;

//! Callback function for retrieving the expression context for the expression
typedef QgsExpressionContext( *ExpressionContextCallback )( const void* context );

/** Register callback function for retrieving the expression context for the expression
* @param fnGetExpressionContext call back function, will be called when the widget requires
* the current expression context
* @param context context for callback function
* @note added in QGIS 2.12
* @note not available in Python bindings
*/
void registerGetExpressionContextCallback( ExpressionContextCallback fnGetExpressionContext, const void* context );

signals:
//! the signal is emitted when the currently selected field changes
void fieldChanged( QString fieldName );
Expand Down Expand Up @@ -138,6 +150,8 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
QString mExpressionDialogTitle;
QSharedPointer<const QgsDistanceArea> mDa;
QScopedPointer< QgsExpressionContext > mExpressionContext;
ExpressionContextCallback mExpressionContextCallback;
const void* mExpressionContextCallbackContext;
};

#endif // QGSFIELDEXPRESSIONWIDGET_H
15 changes: 15 additions & 0 deletions src/gui/symbology-ng/qgscategorizedsymbolrendererv2widget.cpp
Expand Up @@ -370,6 +370,19 @@ QgsRendererV2Widget* QgsCategorizedSymbolRendererV2Widget::create( QgsVectorLaye
return new QgsCategorizedSymbolRendererV2Widget( layer, style, renderer );
}

static QgsExpressionContext _getExpressionContext( const void* context )
{
QgsExpressionContext expContext;
expContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();

const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );

return expContext;
}

QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
: QgsRendererV2Widget( layer, style )
, mRenderer( 0 )
Expand Down Expand Up @@ -451,6 +464,8 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );

btnAdvanced->setMenu( advMenu );

mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, layer );
}

QgsCategorizedSymbolRendererV2Widget::~QgsCategorizedSymbolRendererV2Widget()
Expand Down

0 comments on commit be26c61

Please sign in to comment.