mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Make sure variable editor widgets always show current variables
On behalf of Faunalia, sponsored by ENEL
This commit is contained in:
		
							parent
							
								
									9e5357c0fc
								
							
						
					
					
						commit
						c7ffdfa5e9
					
				@ -900,4 +900,9 @@ class QgsComposition : QGraphicsScene
 | 
			
		||||
 | 
			
		||||
    /** Is emitted when the composition has an updated status bar message for the composer window*/
 | 
			
		||||
    void statusMsgChanged( QString message );
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever the expression variables stored in the composition have been changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -379,7 +379,23 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv)
 | 
			
		||||
    bool x11EventFilter ( XEvent * event );
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
 | 
			
		||||
    /** Causes the application instance to emit the settingsChanged() signal. This should
 | 
			
		||||
     * be called whenever global, application-wide settings are altered to advise listeners
 | 
			
		||||
     * that they may need to update their state.
 | 
			
		||||
     * @see settingsChanged()
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void emitSettingsChanged();
 | 
			
		||||
 | 
			
		||||
  signals:
 | 
			
		||||
    //! @note not available in python bindings
 | 
			
		||||
    // void preNotify( QObject * receiver, QEvent * event, bool * done );
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever any global, application-wide settings are changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     * @see emitSettingsChanged()
 | 
			
		||||
     */
 | 
			
		||||
    void settingsChanged();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -397,6 +397,11 @@ class QgsProject : QObject
 | 
			
		||||
    //! Emitted when the home path of the project changes
 | 
			
		||||
    void homePathChanged();
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever the expression variables stored in the project have been changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -408,6 +413,13 @@ class QgsProject : QObject
 | 
			
		||||
     */
 | 
			
		||||
    void setDirty( bool b = true );
 | 
			
		||||
 | 
			
		||||
    /** Causes the project to emit the variablesChanged() signal. This should
 | 
			
		||||
     * be called whenever expression variables related to the project are changed.
 | 
			
		||||
     * @see variablesChanged()
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void emitVariablesChanged();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    QgsProject(); // private 'cause it's a singleton
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include "qgspoint.h"
 | 
			
		||||
#include "qgsdatadefinedbutton.h"
 | 
			
		||||
#include "qgsexpressioncontext.h"
 | 
			
		||||
#include "qgsproject.h"
 | 
			
		||||
#include <QColorDialog>
 | 
			
		||||
#include <QPen>
 | 
			
		||||
 | 
			
		||||
@ -109,6 +110,14 @@ QgsVectorLayer* QgsComposerItemBaseWidget::atlasCoverageLayer() const
 | 
			
		||||
 | 
			
		||||
//QgsComposerItemWidget
 | 
			
		||||
 | 
			
		||||
void QgsComposerItemWidget::updateVariables()
 | 
			
		||||
{
 | 
			
		||||
  QgsExpressionContext* context = mItem->createExpressionContext();
 | 
			
		||||
  mVariableEditor->setContext( context );
 | 
			
		||||
  mVariableEditor->setEditableScopeIndex( context->scopeCount() - 1 );
 | 
			
		||||
  delete context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem* item )
 | 
			
		||||
    : QgsComposerItemBaseWidget( parent, item )
 | 
			
		||||
    , mItem( item )
 | 
			
		||||
@ -141,12 +150,17 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*
 | 
			
		||||
 | 
			
		||||
  connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpnBx, SLOT( setValue( int ) ) );
 | 
			
		||||
 | 
			
		||||
  QgsExpressionContext* context = mItem->createExpressionContext();
 | 
			
		||||
  mVariableEditor->setContext( context );
 | 
			
		||||
  mVariableEditor->setEditableScopeIndex( context->scopeCount() - 1 );
 | 
			
		||||
  delete context;
 | 
			
		||||
 | 
			
		||||
  updateVariables();
 | 
			
		||||
  connect( mVariableEditor, SIGNAL( scopeChanged() ), this, SLOT( variablesChanged() ) );
 | 
			
		||||
  // listen out for variable edits
 | 
			
		||||
  QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
 | 
			
		||||
  if ( app )
 | 
			
		||||
  {
 | 
			
		||||
    connect( app, SIGNAL( settingsChanged() ), this, SLOT( updateVariables() ) );
 | 
			
		||||
  }
 | 
			
		||||
  connect( QgsProject::instance(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
 | 
			
		||||
  if ( mItem->composition() )
 | 
			
		||||
    connect( mItem->composition(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
 | 
			
		||||
 | 
			
		||||
  //connect atlas signals to data defined buttons
 | 
			
		||||
  QgsAtlasComposition* atlas = atlasComposition();
 | 
			
		||||
 | 
			
		||||
@ -142,8 +142,7 @@ class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsCo
 | 
			
		||||
  private slots:
 | 
			
		||||
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void updateVariables();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //QGSCOMPOSERITEMWIDGET_H
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include "qgssymbolv2selectordialog.h"
 | 
			
		||||
#include "qgssymbollayerv2utils.h"
 | 
			
		||||
#include "qgsexpressioncontext.h"
 | 
			
		||||
#include "qgsproject.h"
 | 
			
		||||
#include <QColorDialog>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <QPrinter> //for screen resolution
 | 
			
		||||
@ -45,13 +46,15 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
 | 
			
		||||
  //read with/height from composition and find suitable entries to display
 | 
			
		||||
  displayCompositionWidthHeight();
 | 
			
		||||
 | 
			
		||||
  mVariableEditor->context()->appendScope( QgsExpressionContextUtils::globalScope() );
 | 
			
		||||
  mVariableEditor->context()->appendScope( QgsExpressionContextUtils::projectScope() );
 | 
			
		||||
  mVariableEditor->context()->appendScope( QgsExpressionContextUtils::compositionScope( mComposition ) );
 | 
			
		||||
  mVariableEditor->reloadContext();
 | 
			
		||||
  mVariableEditor->setEditableScopeIndex( 2 );
 | 
			
		||||
 | 
			
		||||
  updateVariables();
 | 
			
		||||
  connect( mVariableEditor, SIGNAL( scopeChanged() ), this, SLOT( variablesChanged() ) );
 | 
			
		||||
  // listen out for variable edits
 | 
			
		||||
  QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
 | 
			
		||||
  if ( app )
 | 
			
		||||
  {
 | 
			
		||||
    connect( app, SIGNAL( settingsChanged() ), this, SLOT( updateVariables() ) );
 | 
			
		||||
  }
 | 
			
		||||
  connect( QgsProject::instance(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
 | 
			
		||||
 | 
			
		||||
  if ( mComposition )
 | 
			
		||||
  {
 | 
			
		||||
@ -209,6 +212,16 @@ void QgsCompositionWidget::resizeMarginsChanged()
 | 
			
		||||
      mLeftMarginSpinBox->value() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsCompositionWidget::updateVariables()
 | 
			
		||||
{
 | 
			
		||||
  QgsExpressionContext context;
 | 
			
		||||
  context << QgsExpressionContextUtils::globalScope()
 | 
			
		||||
  << QgsExpressionContextUtils::projectScope()
 | 
			
		||||
  << QgsExpressionContextUtils::compositionScope( mComposition );
 | 
			
		||||
  mVariableEditor->setContext( &context );
 | 
			
		||||
  mVariableEditor->setEditableScopeIndex( 2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsCompositionWidget::setDataDefinedProperty( const QgsDataDefinedButton* ddBtn, QgsComposerObject::DataDefinedProperty property )
 | 
			
		||||
{
 | 
			
		||||
  if ( !mComposition )
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,8 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
 | 
			
		||||
 | 
			
		||||
    void resizeMarginsChanged();
 | 
			
		||||
 | 
			
		||||
    void updateVariables();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    QgsComposition* mComposition;
 | 
			
		||||
    QMap<QString, QgsCompositionPaper> mPaperMap;
 | 
			
		||||
 | 
			
		||||
@ -1481,6 +1481,12 @@ void QgsOptions::saveOptions()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  saveDefaultDatumTransformations();
 | 
			
		||||
 | 
			
		||||
  QgsApplication* app = qobject_cast<QgsApplication*>( QgsApplication::instance() );
 | 
			
		||||
  if ( app )
 | 
			
		||||
  {
 | 
			
		||||
    app->emitSettingsChanged();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsOptions::rejectOptions()
 | 
			
		||||
 | 
			
		||||
@ -1187,6 +1187,7 @@ void QgsProjectProperties::apply()
 | 
			
		||||
 | 
			
		||||
  //save variables
 | 
			
		||||
  QgsExpressionContextUtils::setProjectVariables( mVariableEditor->variablesInActiveScope() );
 | 
			
		||||
  QgsProject::instance()->emitVariablesChanged();
 | 
			
		||||
 | 
			
		||||
  emit refresh();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1069,6 +1069,8 @@ bool QgsComposition::readXML( const QDomElement& compositionElem, const QDomDocu
 | 
			
		||||
 | 
			
		||||
  updateBounds();
 | 
			
		||||
 | 
			
		||||
  emit variablesChanged();
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3506,6 +3508,9 @@ void QgsComposition::setDataDefinedProperty( const QgsComposerObject::DataDefine
 | 
			
		||||
void QgsComposition::setCustomProperty( const QString& key, const QVariant& value )
 | 
			
		||||
{
 | 
			
		||||
  mCustomProperties.setValue( key, value );
 | 
			
		||||
 | 
			
		||||
  if ( key.startsWith( "variable" ) )
 | 
			
		||||
    emit variablesChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant QgsComposition::customProperty( const QString& key, const QVariant& defaultValue ) const
 | 
			
		||||
 | 
			
		||||
@ -1146,6 +1146,11 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
 | 
			
		||||
    /** Is emitted when the composition has an updated status bar message for the composer window*/
 | 
			
		||||
    void statusMsgChanged( const QString& message );
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever the expression variables stored in the composition have been changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
 | 
			
		||||
    friend class QgsComposerObject; //for accessing dataDefinedEvaluate, readDataDefinedPropertyMap and writeDataDefinedPropertyMap
 | 
			
		||||
    friend class QgsComposerModel; //for accessing updateZValues (should not be public)
 | 
			
		||||
    friend class TestQgsComposition;
 | 
			
		||||
 | 
			
		||||
@ -1371,3 +1371,8 @@ void QgsApplication::setMaxThreads( int maxThreads )
 | 
			
		||||
  QgsDebugMsg( QString( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsApplication::emitSettingsChanged()
 | 
			
		||||
{
 | 
			
		||||
  emit settingsChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -364,10 +364,26 @@ class CORE_EXPORT QgsApplication : public QApplication
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
 | 
			
		||||
    /** Causes the application instance to emit the settingsChanged() signal. This should
 | 
			
		||||
     * be called whenever global, application-wide settings are altered to advise listeners
 | 
			
		||||
     * that they may need to update their state.
 | 
			
		||||
     * @see settingsChanged()
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void emitSettingsChanged();
 | 
			
		||||
 | 
			
		||||
  signals:
 | 
			
		||||
    //! @note not available in python bindings
 | 
			
		||||
    void preNotify( QObject * receiver, QEvent * event, bool * done );
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever any global, application-wide settings are changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     * @see emitSettingsChanged()
 | 
			
		||||
     */
 | 
			
		||||
    void settingsChanged();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    static void copyPath( const QString& src, const QString& dst );
 | 
			
		||||
    static QObject* ABISYM( mFileOpenEventReceiver );
 | 
			
		||||
 | 
			
		||||
@ -412,6 +412,11 @@ void QgsProject::setDirty( bool b )
 | 
			
		||||
  imp_->dirty = b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsProject::emitVariablesChanged()
 | 
			
		||||
{
 | 
			
		||||
  emit variablesChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsProject::setFileName( const QString& name )
 | 
			
		||||
{
 | 
			
		||||
  if ( name == imp_->file.fileName() )
 | 
			
		||||
 | 
			
		||||
@ -462,6 +462,11 @@ class CORE_EXPORT QgsProject : public QObject
 | 
			
		||||
    //! Emitted when the home path of the project changes
 | 
			
		||||
    void homePathChanged();
 | 
			
		||||
 | 
			
		||||
    /** Emitted whenever the expression variables stored in the project have been changed.
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -473,6 +478,13 @@ class CORE_EXPORT QgsProject : public QObject
 | 
			
		||||
     */
 | 
			
		||||
    void setDirty( bool b = true );
 | 
			
		||||
 | 
			
		||||
    /** Causes the project to emit the variablesChanged() signal. This should
 | 
			
		||||
     * be called whenever expression variables related to the project are changed.
 | 
			
		||||
     * @see variablesChanged()
 | 
			
		||||
     * @note added in QGIS 3.0
 | 
			
		||||
     */
 | 
			
		||||
    void emitVariablesChanged();
 | 
			
		||||
 | 
			
		||||
  private slots:
 | 
			
		||||
    void onMapLayersAdded( const QList<QgsMapLayer*>& layers );
 | 
			
		||||
    void cleanTransactionGroups( bool force = false );
 | 
			
		||||
 | 
			
		||||
@ -65,12 +65,6 @@ class GUI_EXPORT QgsVariableEditorWidget : public QWidget
 | 
			
		||||
     */
 | 
			
		||||
    QgsExpressionContext* context() const { return mContext.data(); }
 | 
			
		||||
 | 
			
		||||
    /** Reloads all scopes from the editor's current context. This method should be called
 | 
			
		||||
     * after adding or removing scopes from the attached context.
 | 
			
		||||
     * @see context()
 | 
			
		||||
     */
 | 
			
		||||
    void reloadContext();
 | 
			
		||||
 | 
			
		||||
    /** Sets the editable scope for the widget. Only variables from the editable scope can
 | 
			
		||||
     * be modified by users.
 | 
			
		||||
     * @param scopeIndex index of current editable scope. Set to -1 to disable
 | 
			
		||||
@ -107,6 +101,14 @@ class GUI_EXPORT QgsVariableEditorWidget : public QWidget
 | 
			
		||||
     */
 | 
			
		||||
    QgsStringMap variablesInActiveScope() const;
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
 | 
			
		||||
    /** Reloads all scopes from the editor's current context. This method should be called
 | 
			
		||||
     * after adding or removing scopes from the attached context.
 | 
			
		||||
     * @see context()
 | 
			
		||||
     */
 | 
			
		||||
    void reloadContext();
 | 
			
		||||
 | 
			
		||||
  signals:
 | 
			
		||||
 | 
			
		||||
    /** Emitted when the user has modified a scope using the widget.
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,7 @@ void TestQgsApplication::platformName()
 | 
			
		||||
  QCOMPARE( QgsApplication::platform(), QString( "desktop" ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void TestQgsApplication::checkPaths()
 | 
			
		||||
{
 | 
			
		||||
  QString myPath = QgsApplication::authorsFilePath();
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ class TestQgsComposition : public QObject
 | 
			
		||||
    void resizeToContentsMargin();
 | 
			
		||||
    void resizeToContentsMultiPage();
 | 
			
		||||
    void georeference();
 | 
			
		||||
    void variablesEdited();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    QgsComposition *mComposition;
 | 
			
		||||
@ -583,5 +584,19 @@ void TestQgsComposition::georeference()
 | 
			
		||||
  delete composition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TestQgsComposition::variablesEdited()
 | 
			
		||||
{
 | 
			
		||||
  QgsMapSettings ms;
 | 
			
		||||
  QgsComposition c( ms );
 | 
			
		||||
  QSignalSpy spyVariablesChanged( &c, SIGNAL( variablesChanged() ) );
 | 
			
		||||
 | 
			
		||||
  c.setCustomProperty( "not a variable", "1" );
 | 
			
		||||
  QVERIFY( spyVariablesChanged.count() == 0 );
 | 
			
		||||
  c.setCustomProperty( "variableNames", "1" );
 | 
			
		||||
  QVERIFY( spyVariablesChanged.count() == 1 );
 | 
			
		||||
  c.setCustomProperty( "variableValues", "1" );
 | 
			
		||||
  QVERIFY( spyVariablesChanged.count() == 2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QTEST_MAIN( TestQgsComposition )
 | 
			
		||||
#include "testqgscomposition.moc"
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@ class TestQgsProject : public QObject
 | 
			
		||||
 | 
			
		||||
    void testReadPath();
 | 
			
		||||
    void testProjectUnits();
 | 
			
		||||
    void variablesChanged();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void TestQgsProject::init()
 | 
			
		||||
@ -124,6 +125,13 @@ void TestQgsProject::testProjectUnits()
 | 
			
		||||
  QCOMPARE( prj->areaUnits(), QgsUnitTypes::Acres );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TestQgsProject::variablesChanged()
 | 
			
		||||
{
 | 
			
		||||
  QSignalSpy spyVariablesChanged( QgsProject::instance(), SIGNAL( variablesChanged() ) );
 | 
			
		||||
  QgsProject::instance()->emitVariablesChanged();
 | 
			
		||||
  QVERIFY( spyVariablesChanged.count() == 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
QTEST_MAIN( TestQgsProject )
 | 
			
		||||
#include "testqgsproject.moc"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user