diff --git a/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in b/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in index 5362b6b191d7..5a3c41787aac 100644 --- a/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in +++ b/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in @@ -10,6 +10,7 @@ + class QgsSettingsEditorWidgetWrapper : QObject { %Docstring(signature="appended") @@ -82,6 +83,21 @@ Sets the ``value`` of the widget The wrapper must be configured before calling this medthod %End + void configureAutomaticUpdate( QDialog *dialog = 0 ); +%Docstring +Enables automatic update, which causes the setting to be updated immediately when the widget +value is changed. + +If a ``dialog`` is provided, the setting will be updated when the dialog is accepted. +If not, the setting will be updated directly at each widget value change. + +.. note:: + + This must called after :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor` or :py:func:`~QgsSettingsEditorWidgetWrapper.configureEditor`. + +.. versionadded:: 3.40 +%End + protected: virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0; @@ -92,6 +108,14 @@ Creates the widgets virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; %Docstring Configures an existing ``editor`` widget +%End + + virtual void enableAutomaticUpdatePrivate() = 0; +%Docstring +Enables automatic update, which causes the setting to be updated immediately when the widget +value is changed. + +.. versionadded:: 3.40 %End }; diff --git a/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in b/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in index 270ddc86aa76..08bf87e9b923 100644 --- a/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in +++ b/python/PyQt6/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in @@ -109,6 +109,9 @@ Constructor virtual bool setWidgetValue( const QString &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -145,6 +148,9 @@ Constructor virtual bool setWidgetValue( const bool &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -181,6 +187,9 @@ Constructor virtual bool setWidgetValue( const int &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -218,6 +227,9 @@ Constructor virtual bool setWidgetValue( const double &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -258,6 +270,9 @@ Constructor virtual void configureEditorPrivateImplementation(); + + virtual void enableAutomaticUpdatePrivate(); + }; diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in index 5362b6b191d7..5a3c41787aac 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in @@ -10,6 +10,7 @@ + class QgsSettingsEditorWidgetWrapper : QObject { %Docstring(signature="appended") @@ -82,6 +83,21 @@ Sets the ``value`` of the widget The wrapper must be configured before calling this medthod %End + void configureAutomaticUpdate( QDialog *dialog = 0 ); +%Docstring +Enables automatic update, which causes the setting to be updated immediately when the widget +value is changed. + +If a ``dialog`` is provided, the setting will be updated when the dialog is accepted. +If not, the setting will be updated directly at each widget value change. + +.. note:: + + This must called after :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor` or :py:func:`~QgsSettingsEditorWidgetWrapper.configureEditor`. + +.. versionadded:: 3.40 +%End + protected: virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0; @@ -92,6 +108,14 @@ Creates the widgets virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; %Docstring Configures an existing ``editor`` widget +%End + + virtual void enableAutomaticUpdatePrivate() = 0; +%Docstring +Enables automatic update, which causes the setting to be updated immediately when the widget +value is changed. + +.. versionadded:: 3.40 %End }; diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in index 270ddc86aa76..08bf87e9b923 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in @@ -109,6 +109,9 @@ Constructor virtual bool setWidgetValue( const QString &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -145,6 +148,9 @@ Constructor virtual bool setWidgetValue( const bool &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -181,6 +187,9 @@ Constructor virtual bool setWidgetValue( const int &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -218,6 +227,9 @@ Constructor virtual bool setWidgetValue( const double &value ) const; + + virtual void enableAutomaticUpdatePrivate(); + }; @@ -258,6 +270,9 @@ Constructor virtual void configureEditorPrivateImplementation(); + + virtual void enableAutomaticUpdatePrivate(); + }; diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h index d45056f4736f..c7ec0c0543f8 100644 --- a/src/gui/qgsgui.h +++ b/src/gui/qgsgui.h @@ -19,6 +19,7 @@ #define QGSGUI_H #include "qgis_gui.h" +#include "qgssettingstree.h" #include "qgis_sip.h" #include #include @@ -64,6 +65,8 @@ class GUI_EXPORT QgsGui : public QObject public: + static inline QgsSettingsTreeNode *sTtreeWidgetLastUsedValues = QgsSettingsTree::sTreeApp->createChildNode( QStringLiteral( "widget-last-used-values" ) ) SIP_SKIP; + /** * Defines the behavior to use when setting the CRS for a newly created project. */ diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.cpp b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp index ace0c73f5f2f..039c1a7ba9bd 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapper.cpp +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp @@ -19,6 +19,7 @@ #include "qgslogger.h" #include "qgssettingsentry.h" +#include #include @@ -59,3 +60,19 @@ bool QgsSettingsEditorWidgetWrapper::configureEditor( QWidget *editor, const Qgs return ok; } + +void QgsSettingsEditorWidgetWrapper::configureAutomaticUpdate( QDialog *dialog ) +{ + setWidgetFromSetting(); + if ( dialog ) + { + QObject::connect( dialog, &QDialog::accepted, this, [ = ]() + { + setSettingFromWidget(); + } ); + } + else + { + enableAutomaticUpdatePrivate(); + } +} diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.h b/src/gui/settings/qgssettingseditorwidgetwrapper.h index db6b85d49cf2..df52643c321d 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapper.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.h @@ -23,6 +23,8 @@ class QgsSettingsEntryBase; +class QDialog; + /** * \ingroup gui * \brief Base class for settings editor wrappers @@ -80,6 +82,18 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject */ virtual void setWidgetFromVariant( const QVariant &value ) const = 0; + /** + * Configure the settings update behavior when a widget value is changed. + * + * If a \a dialog is provided, the setting will be updated when the dialog is accepted. + * If not, the setting will be updated directly at each widget value change. + * + * \note This must called after createEditor() or configureEditor(). + * + * \since QGIS 3.40 + */ + void configureAutomaticUpdate( QDialog *dialog = nullptr ); + protected: //! Creates the widgets @@ -88,6 +102,13 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject //! Configures an existing \a editor widget virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; + /** + * Enables automatic update, which causes the setting to be updated immediately when the widget + * value is changed. + * \since QGIS 3.40 + */ + virtual void enableAutomaticUpdatePrivate() = 0; + QStringList mDynamicKeyPartList; }; diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp index ab1b0b23ae33..ebe5706da57a 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp @@ -46,6 +46,14 @@ bool QgsSettingsStringEditorWidgetWrapper::setWidgetValue( const QString &value return false; } +void QgsSettingsStringEditorWidgetWrapper::enableAutomaticUpdatePrivate() +{ + QObject::connect( this->mEditor, &QLineEdit::textChanged, this, [ = ]( const QString & text ) + { + this->mSetting->setValue( text, this->mDynamicKeyPartList ); + } ); +} + bool QgsSettingsStringEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) @@ -96,6 +104,14 @@ bool QgsSettingsBoolEditorWidgetWrapper::setWidgetValue( const bool &value ) con return false; } +void QgsSettingsBoolEditorWidgetWrapper::enableAutomaticUpdatePrivate() +{ + QObject::connect( this->mEditor, &QCheckBox::clicked, this, [ = ]( bool checked ) + { + this->mSetting->setValue( checked, this->mDynamicKeyPartList ); + } ); +} + bool QgsSettingsBoolEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) @@ -148,6 +164,14 @@ bool QgsSettingsIntegerEditorWidgetWrapper::setWidgetValue( const int &value ) c return false; } +void QgsSettingsIntegerEditorWidgetWrapper::enableAutomaticUpdatePrivate() +{ + QObject::connect( this->mEditor, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) + { + this->mSetting->setValue( value, this->mDynamicKeyPartList ); + } ); +} + bool QgsSettingsIntegerEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) @@ -200,6 +224,14 @@ bool QgsSettingsDoubleEditorWidgetWrapper::setWidgetValue( const double &value ) return false; } +void QgsSettingsDoubleEditorWidgetWrapper::enableAutomaticUpdatePrivate() +{ + QObject::connect( this->mEditor, qOverload( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + this->mSetting->setValue( value, this->mDynamicKeyPartList ); + } ); +} + bool QgsSettingsDoubleEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) @@ -262,6 +294,14 @@ void QgsSettingsColorEditorWidgetWrapper::configureEditorPrivateImplementation() } } +void QgsSettingsColorEditorWidgetWrapper::enableAutomaticUpdatePrivate() +{ + QObject::connect( this->mEditor, &QgsColorButton::colorChanged, this, [ = ]( const QColor & color ) + { + this->mSetting->setValue( color, this->mDynamicKeyPartList ); + } ); +} + bool QgsSettingsColorEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h index b9e3b134b688..d71e10cbfdb3 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h @@ -139,6 +139,8 @@ class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditor QString valueFromWidget() const override; bool setWidgetValue( const QString &value ) const override; + + void enableAutomaticUpdatePrivate() override; }; /** @@ -164,6 +166,8 @@ class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWi bool valueFromWidget() const override; bool setWidgetValue( const bool &value ) const override; + + void enableAutomaticUpdatePrivate() override; }; /** @@ -189,6 +193,8 @@ class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEdito int valueFromWidget() const override; bool setWidgetValue( const int &value ) const override; + + void enableAutomaticUpdatePrivate() override; }; @@ -215,6 +221,8 @@ class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditor double valueFromWidget() const override; bool setWidgetValue( const double &value ) const override; + + void enableAutomaticUpdatePrivate() override; }; @@ -243,6 +251,8 @@ class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorW bool setWidgetValue( const QColor &value ) const override; void configureEditorPrivateImplementation() override; + + void enableAutomaticUpdatePrivate() override; }; diff --git a/src/gui/settings/qgssettingsenumflageditorwidgetwrapper.h b/src/gui/settings/qgssettingsenumflageditorwidgetwrapper.h index 86beaa9e7c60..e307ed24d545 100644 --- a/src/gui/settings/qgssettingsenumflageditorwidgetwrapper.h +++ b/src/gui/settings/qgssettingsenumflageditorwidgetwrapper.h @@ -43,6 +43,15 @@ class GUI_EXPORT QgsSettingsFlagsEditorWidgetWrapper : public QgsSettingsEditorW : QgsSettingsEditorWidgetWrapperTemplate, QComboBox, FLAGS>( parent ) {} + void enableAutomaticUpdatePrivate() override + { + QObject::connect( &mModel, &QStandardItemModel::itemChanged, this, [ = ]( const QStandardItem * item ) + { + Q_UNUSED( item ) + setSettingFromWidget(); + } ); + } + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsFlagsEditorWidgetWrapper( parent );} virtual QString id() const override @@ -144,11 +153,28 @@ class QgsSettingsEnumEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplate, QComboBox, ENUM>( parent ) {} + void enableAutomaticUpdatePrivate() override + { + QObject::connect( this->mEditor, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) + { + Q_UNUSED( index ); + ENUM value = this->mEditor->currentData().template value(); + this->mSetting->setValue( value, this->mDynamicKeyPartList ); + } ); + } + virtual QString id() const override { return QStringLiteral( "%1-%2" ).arg( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::EnumFlag ) ), QMetaEnum::fromType().name() ); } + /** + * This will set the display strings so they can be readable and translatable. + * This must be called before calling createEditor or configureEditor. + * \since QGIS 3.40 + */ + void setDisplayStrings( const QMap &displayStrings ) { mDisplayStrings = displayStrings; } + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsEnumEditorWidgetWrapper( parent );} QVariant variantValueFromWidget() const override @@ -206,10 +232,14 @@ class QgsSettingsEnumEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapper const QMap enumMap = qgsEnumMap(); for ( auto it = enumMap.constBegin(); it != enumMap.constEnd(); ++it ) { - this->mEditor->addItem( it.value(), QVariant::fromValue( it.key() ) ); + const QString displayString = mDisplayStrings.value( it.key(), it.value() ); + this->mEditor->addItem( displayString, QVariant::fromValue( it.key() ) ); } } + private: + QMap mDisplayStrings; + }; #endif // QGSSETTINGSENUMFLAGEDITORWIDGETWRAPPER_H