Skip to content

Commit 56fda9e

Browse files
committedJul 19, 2016
Make sure variable editor widgets always show current variables
On behalf of Faunalia, sponsored by ENEL (cherry-picked from c7ffdfa)
1 parent 8f2eb81 commit 56fda9e

19 files changed

+161
-19
lines changed
 

‎python/core/composer/qgscomposition.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,4 +900,9 @@ class QgsComposition : QGraphicsScene
900900

901901
/** Is emitted when the composition has an updated status bar message for the composer window*/
902902
void statusMsgChanged( QString message );
903+
904+
/** Emitted whenever the expression variables stored in the composition have been changed.
905+
* @note added in QGIS 3.0
906+
*/
907+
void variablesChanged();
903908
};

‎python/core/qgsapplication.sip

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,23 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv)
379379
bool x11EventFilter ( XEvent * event );
380380
%End
381381

382+
public slots:
383+
384+
/** Causes the application instance to emit the settingsChanged() signal. This should
385+
* be called whenever global, application-wide settings are altered to advise listeners
386+
* that they may need to update their state.
387+
* @see settingsChanged()
388+
* @note added in QGIS 3.0
389+
*/
390+
void emitSettingsChanged();
391+
382392
signals:
383393
//! @note not available in python bindings
384394
// void preNotify( QObject * receiver, QEvent * event, bool * done );
395+
396+
/** Emitted whenever any global, application-wide settings are changed.
397+
* @note added in QGIS 3.0
398+
* @see emitSettingsChanged()
399+
*/
400+
void settingsChanged();
385401
};

‎python/core/qgsproject.sip

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ class QgsProject : QObject
391391
//! Emitted when the list of layer which are excluded from map identification changes
392392
void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers );
393393

394+
/** Emitted whenever the expression variables stored in the project have been changed.
395+
* @note added in QGIS 3.0
396+
*/
397+
void variablesChanged();
398+
394399
public slots:
395400

396401
/**
@@ -402,6 +407,13 @@ class QgsProject : QObject
402407
*/
403408
void setDirty( bool b = true );
404409

410+
/** Causes the project to emit the variablesChanged() signal. This should
411+
* be called whenever expression variables related to the project are changed.
412+
* @see variablesChanged()
413+
* @note added in QGIS 3.0
414+
*/
415+
void emitVariablesChanged();
416+
405417
private:
406418

407419
QgsProject(); // private 'cause it's a singleton

‎src/app/composer/qgscomposeritemwidget.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "qgspoint.h"
2424
#include "qgsdatadefinedbutton.h"
2525
#include "qgsexpressioncontext.h"
26+
#include "qgsproject.h"
2627
#include <QColorDialog>
2728
#include <QPen>
2829

@@ -109,6 +110,14 @@ QgsVectorLayer* QgsComposerItemBaseWidget::atlasCoverageLayer() const
109110

110111
//QgsComposerItemWidget
111112

113+
void QgsComposerItemWidget::updateVariables()
114+
{
115+
QgsExpressionContext* context = mItem->createExpressionContext();
116+
mVariableEditor->setContext( context );
117+
mVariableEditor->setEditableScopeIndex( context->scopeCount() - 1 );
118+
delete context;
119+
}
120+
112121
QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem* item )
113122
: QgsComposerItemBaseWidget( parent, item )
114123
, mItem( item )
@@ -141,12 +150,17 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*
141150

142151
connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpnBx, SLOT( setValue( int ) ) );
143152

144-
QgsExpressionContext* context = mItem->createExpressionContext();
145-
mVariableEditor->setContext( context );
146-
mVariableEditor->setEditableScopeIndex( context->scopeCount() - 1 );
147-
delete context;
148-
153+
updateVariables();
149154
connect( mVariableEditor, SIGNAL( scopeChanged() ), this, SLOT( variablesChanged() ) );
155+
// listen out for variable edits
156+
QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
157+
if ( app )
158+
{
159+
connect( app, SIGNAL( settingsChanged() ), this, SLOT( updateVariables() ) );
160+
}
161+
connect( QgsProject::instance(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
162+
if ( mItem->composition() )
163+
connect( mItem->composition(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
150164

151165
//connect atlas signals to data defined buttons
152166
QgsAtlasComposition* atlas = atlasComposition();

‎src/app/composer/qgscomposeritemwidget.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsCo
142142
private slots:
143143

144144
void variablesChanged();
145-
146-
145+
void updateVariables();
147146
};
148147

149148
#endif //QGSCOMPOSERITEMWIDGET_H

‎src/app/composer/qgscompositionwidget.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "qgssymbolv2selectordialog.h"
2424
#include "qgssymbollayerv2utils.h"
2525
#include "qgsexpressioncontext.h"
26+
#include "qgsproject.h"
2627
#include <QColorDialog>
2728
#include <QWidget>
2829
#include <QPrinter> //for screen resolution
@@ -45,13 +46,15 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
4546
//read with/height from composition and find suitable entries to display
4647
displayCompositionWidthHeight();
4748

48-
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::globalScope() );
49-
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::projectScope() );
50-
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::compositionScope( mComposition ) );
51-
mVariableEditor->reloadContext();
52-
mVariableEditor->setEditableScopeIndex( 2 );
53-
49+
updateVariables();
5450
connect( mVariableEditor, SIGNAL( scopeChanged() ), this, SLOT( variablesChanged() ) );
51+
// listen out for variable edits
52+
QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
53+
if ( app )
54+
{
55+
connect( app, SIGNAL( settingsChanged() ), this, SLOT( updateVariables() ) );
56+
}
57+
connect( QgsProject::instance(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
5558

5659
if ( mComposition )
5760
{
@@ -209,6 +212,16 @@ void QgsCompositionWidget::resizeMarginsChanged()
209212
mLeftMarginSpinBox->value() );
210213
}
211214

215+
void QgsCompositionWidget::updateVariables()
216+
{
217+
QgsExpressionContext context;
218+
context << QgsExpressionContextUtils::globalScope()
219+
<< QgsExpressionContextUtils::projectScope()
220+
<< QgsExpressionContextUtils::compositionScope( mComposition );
221+
mVariableEditor->setContext( &context );
222+
mVariableEditor->setEditableScopeIndex( 2 );
223+
}
224+
212225
void QgsCompositionWidget::setDataDefinedProperty( const QgsDataDefinedButton* ddBtn, QgsComposerObject::DataDefinedProperty property )
213226
{
214227
if ( !mComposition )

‎src/app/composer/qgscompositionwidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
8484

8585
void resizeMarginsChanged();
8686

87+
void updateVariables();
88+
8789
private:
8890
QgsComposition* mComposition;
8991
QMap<QString, QgsCompositionPaper> mPaperMap;

‎src/app/qgsoptions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,12 @@ void QgsOptions::saveOptions()
14801480
}
14811481

14821482
saveDefaultDatumTransformations();
1483+
1484+
QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
1485+
if ( app )
1486+
{
1487+
app->emitSettingsChanged();
1488+
}
14831489
}
14841490

14851491
void QgsOptions::rejectOptions()

‎src/app/qgsprojectproperties.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,7 @@ void QgsProjectProperties::apply()
11871187

11881188
//save variables
11891189
QgsExpressionContextUtils::setProjectVariables( mVariableEditor->variablesInActiveScope() );
1190+
QgsProject::instance()->emitVariablesChanged();
11901191

11911192
emit refresh();
11921193
}

‎src/core/composer/qgscomposition.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,8 @@ bool QgsComposition::readXML( const QDomElement& compositionElem, const QDomDocu
10681068

10691069
updateBounds();
10701070

1071+
emit variablesChanged();
1072+
10711073
return true;
10721074
}
10731075

@@ -3505,6 +3507,9 @@ void QgsComposition::setDataDefinedProperty( const QgsComposerObject::DataDefine
35053507
void QgsComposition::setCustomProperty( const QString& key, const QVariant& value )
35063508
{
35073509
mCustomProperties.setValue( key, value );
3510+
3511+
if ( key.startsWith( "variable" ) )
3512+
emit variablesChanged();
35083513
}
35093514

35103515
QVariant QgsComposition::customProperty( const QString& key, const QVariant& defaultValue ) const

‎src/core/composer/qgscomposition.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,11 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
11461146
/** Is emitted when the composition has an updated status bar message for the composer window*/
11471147
void statusMsgChanged( const QString& message );
11481148

1149+
/** Emitted whenever the expression variables stored in the composition have been changed.
1150+
* @note added in QGIS 3.0
1151+
*/
1152+
void variablesChanged();
1153+
11491154
friend class QgsComposerObject; //for accessing dataDefinedEvaluate, readDataDefinedPropertyMap and writeDataDefinedPropertyMap
11501155
friend class QgsComposerModel; //for accessing updateZValues (should not be public)
11511156
friend class TestQgsComposition;

‎src/core/qgsapplication.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,3 +1371,8 @@ void QgsApplication::setMaxThreads( int maxThreads )
13711371
QgsDebugMsg( QString( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
13721372
}
13731373

1374+
void QgsApplication::emitSettingsChanged()
1375+
{
1376+
emit settingsChanged();
1377+
}
1378+

‎src/core/qgsapplication.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,26 @@ class CORE_EXPORT QgsApplication : public QApplication
364364
}
365365
#endif
366366

367+
public slots:
368+
369+
/** Causes the application instance to emit the settingsChanged() signal. This should
370+
* be called whenever global, application-wide settings are altered to advise listeners
371+
* that they may need to update their state.
372+
* @see settingsChanged()
373+
* @note added in QGIS 3.0
374+
*/
375+
void emitSettingsChanged();
376+
367377
signals:
368378
//! @note not available in python bindings
369379
void preNotify( QObject * receiver, QEvent * event, bool * done );
370380

381+
/** Emitted whenever any global, application-wide settings are changed.
382+
* @note added in QGIS 3.0
383+
* @see emitSettingsChanged()
384+
*/
385+
void settingsChanged();
386+
371387
private:
372388
static void copyPath( const QString& src, const QString& dst );
373389
static QObject* ABISYM( mFileOpenEventReceiver );

‎src/core/qgsproject.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,11 @@ void QgsProject::setDirty( bool b )
412412
imp_->dirty = b;
413413
}
414414

415+
void QgsProject::emitVariablesChanged()
416+
{
417+
emit variablesChanged();
418+
}
419+
415420
void QgsProject::setFileName( const QString& name )
416421
{
417422
imp_->file.setFileName( name );

‎src/core/qgsproject.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,11 @@ class CORE_EXPORT QgsProject : public QObject
455455
//! Emitted when the list of layer which are excluded from map identification changes
456456
void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers );
457457

458+
/** Emitted whenever the expression variables stored in the project have been changed.
459+
* @note added in QGIS 3.0
460+
*/
461+
void variablesChanged();
462+
458463
public slots:
459464

460465
/**
@@ -466,6 +471,13 @@ class CORE_EXPORT QgsProject : public QObject
466471
*/
467472
void setDirty( bool b = true );
468473

474+
/** Causes the project to emit the variablesChanged() signal. This should
475+
* be called whenever expression variables related to the project are changed.
476+
* @see variablesChanged()
477+
* @note added in QGIS 3.0
478+
*/
479+
void emitVariablesChanged();
480+
469481
private slots:
470482
void onMapLayersAdded( const QList<QgsMapLayer*>& layers );
471483
void cleanTransactionGroups( bool force = false );

‎src/gui/qgsvariableeditorwidget.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,6 @@ class GUI_EXPORT QgsVariableEditorWidget : public QWidget
6565
*/
6666
QgsExpressionContext* context() const { return mContext.data(); }
6767

68-
/** Reloads all scopes from the editor's current context. This method should be called
69-
* after adding or removing scopes from the attached context.
70-
* @see context()
71-
*/
72-
void reloadContext();
73-
7468
/** Sets the editable scope for the widget. Only variables from the editable scope can
7569
* be modified by users.
7670
* @param scopeIndex index of current editable scope. Set to -1 to disable
@@ -107,6 +101,14 @@ class GUI_EXPORT QgsVariableEditorWidget : public QWidget
107101
*/
108102
QgsStringMap variablesInActiveScope() const;
109103

104+
public slots:
105+
106+
/** Reloads all scopes from the editor's current context. This method should be called
107+
* after adding or removing scopes from the attached context.
108+
* @see context()
109+
*/
110+
void reloadContext();
111+
110112
signals:
111113

112114
/** Emitted when the user has modified a scope using the widget.

‎tests/src/core/testqgsapplication.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void TestQgsApplication::platformName()
8383
QCOMPARE( QgsApplication::platform(), QString( "desktop" ) );
8484
}
8585

86+
8687
void TestQgsApplication::checkPaths()
8788
{
8889
QString myPath = QgsApplication::authorsFilePath();

‎tests/src/core/testqgscomposition.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class TestQgsComposition : public QObject
5353
void resizeToContentsMargin();
5454
void resizeToContentsMultiPage();
5555
void georeference();
56+
void variablesEdited();
5657

5758
private:
5859
QgsComposition *mComposition;
@@ -583,5 +584,19 @@ void TestQgsComposition::georeference()
583584
delete composition;
584585
}
585586

587+
void TestQgsComposition::variablesEdited()
588+
{
589+
QgsMapSettings ms;
590+
QgsComposition c( ms );
591+
QSignalSpy spyVariablesChanged( &c, SIGNAL( variablesChanged() ) );
592+
593+
c.setCustomProperty( "not a variable", "1" );
594+
QVERIFY( spyVariablesChanged.count() == 0 );
595+
c.setCustomProperty( "variableNames", "1" );
596+
QVERIFY( spyVariablesChanged.count() == 1 );
597+
c.setCustomProperty( "variableValues", "1" );
598+
QVERIFY( spyVariablesChanged.count() == 2 );
599+
}
600+
586601
QTEST_MAIN( TestQgsComposition )
587602
#include "testqgscomposition.moc"

‎tests/src/core/testqgsproject.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class TestQgsProject : public QObject
3131

3232
void testReadPath();
3333
void testProjectUnits();
34+
void variablesChanged();
3435
};
3536

3637
void TestQgsProject::init()
@@ -124,6 +125,13 @@ void TestQgsProject::testProjectUnits()
124125
QCOMPARE( prj->areaUnits(), QgsUnitTypes::Acres );
125126
}
126127

128+
void TestQgsProject::variablesChanged()
129+
{
130+
QSignalSpy spyVariablesChanged( QgsProject::instance(), SIGNAL( variablesChanged() ) );
131+
QgsProject::instance()->emitVariablesChanged();
132+
QVERIFY( spyVariablesChanged.count() == 1 );
133+
}
134+
127135

128136
QTEST_MAIN( TestQgsProject )
129137
#include "testqgsproject.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.