From 3534cd8763947e99549b94699f87c834bb9808a3 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:10:03 +0200 Subject: [PATCH 01/20] simplification of settings API always pass value by reference (drop of QgsSettingsEntryByValue) undeprecate setVariantValue --- python/sipify.yaml | 3 +- src/core/settings/qgssettingsentry.cpp | 14 +- src/core/settings/qgssettingsentry.h | 259 ++++--------------- src/core/settings/qgssettingsentryenumflag.h | 28 +- src/core/settings/qgssettingsentryimpl.cpp | 12 +- src/core/settings/qgssettingsentryimpl.h | 85 +++--- 6 files changed, 114 insertions(+), 287 deletions(-) diff --git a/python/sipify.yaml b/python/sipify.yaml index 3f3f683c5b7..608a7e54336 100644 --- a/python/sipify.yaml +++ b/python/sipify.yaml @@ -2,8 +2,7 @@ class_headerfile: QgsAbstractFeatureIteratorFromSource: qgsfeatureiterator.h - QgsSettingsEntryByReference: qgssettingsentry.h - QgsSettingsEntryByValue: qgssettingsentry.h + QgsSettingsEntryBaseTemplate: qgssettingsentry.h no_export_macro: diff --git a/src/core/settings/qgssettingsentry.cpp b/src/core/settings/qgssettingsentry.cpp index 1b286c117f9..2fd83610740 100644 --- a/src/core/settings/qgssettingsentry.cpp +++ b/src/core/settings/qgssettingsentry.cpp @@ -43,6 +43,11 @@ QgsSettingsEntryBase::~QgsSettingsEntryBase() mParentTreeElement->unregisterChildSetting( this ); } +QString QgsSettingsEntryBase::typeId() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( settingsType() ) ) ); +} + QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const { @@ -139,15 +144,10 @@ int QgsSettingsEntryBase::section() const bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QString &dynamicKeyPart ) const { - return setVariantValuePrivate( value, dynamicKeyPartToList( dynamicKeyPart ) ); + return setVariantValue( value, dynamicKeyPartToList( dynamicKeyPart ) ); } bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const -{ - return setVariantValuePrivate( value, dynamicKeyPartList ); -} - -bool QgsSettingsEntryBase::setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList ) const { if ( mOptions.testFlag( Qgis::SettingsOption::SaveFormerValue ) ) { @@ -243,7 +243,7 @@ bool QgsSettingsEntryBase::copyValueFromKey( const QString &key, const QStringLi if ( settings.contains( oldCompleteKey ) ) { QVariant oldValue = settings.value( oldCompleteKey, mDefaultValue ); - setVariantValuePrivate( oldValue, dynamicKeyPartList ); + setVariantValue( oldValue, dynamicKeyPartList ); if ( removeSettingAtKey ) settings.remove( oldCompleteKey ); return true; diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index cb02fb189f9..8faca8034d4 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -28,6 +28,9 @@ class QgsSettingsTreeNode; +static const inline QMetaEnum sSettingsTypeMetaEnum = QMetaEnum::fromType() SIP_SKIP; + + /** * \ingroup core * \class QgsSettingsEntryBase @@ -118,6 +121,13 @@ class CORE_EXPORT QgsSettingsEntryBase */ virtual ~QgsSettingsEntryBase(); + /** + * Returns the id of the type of settings + * This can be re-implemented in a custom implementation of a setting + * \since QGIS 3.32 + */ + virtual QString typeId() const; + /** * Returns the name of the settings * \since QGIS 3.30 @@ -213,18 +223,16 @@ class CORE_EXPORT QgsSettingsEntryBase * * \param value specifies the value to set. * \param dynamicKeyPart specifies the dynamic part of the settings key. - * \deprecated since QGIS 3.26 use setVariantValuePrivate or an implementation setValue instead */ - Q_DECL_DEPRECATED virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const SIP_DEPRECATED; + bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; /** * Set settings value. - * - * \param value specifies the value to set. + * This should be called from any implementation as it takes care of actually calling QSettings + * \param value specifies the value to set. * \param dynamicKeyPartList specifies the list of dynamic parts of the settings key. - * \deprecated since QGIS 3.26 use setVariantValuePrivate or an implementation setValue instead */ - Q_DECL_DEPRECATED virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const SIP_DEPRECATED; + bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; //! Returns settings value with \param dynamicKeyPart specifying the dynamic part of the settings key. QVariant valueAsVariant( const QString &dynamicKeyPart = QString() ) const; @@ -323,14 +331,12 @@ class CORE_EXPORT QgsSettingsEntryBase */ QgsSettingsTreeNode *parent() const {return mParentTreeElement;} - protected: - - /** - * Sets the settings value with a variant value. - * This should be called from any implementation as it takes care of actually calling QSettings - * \since QGIS 3.26 - */ - bool setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList = QStringList() ) const; + //! Returns TRUE if the given \a value is valid towards the setting definition + virtual bool checkValueVariant( const QVariant &value ) const + { + Q_UNUSED( value ) + return true; + } private: QString formerValuekey( const QStringList &dynamicKeyPartList ) const; @@ -345,7 +351,6 @@ class CORE_EXPORT QgsSettingsEntryBase Qgis::SettingsOptions mOptions; }; - /** * \ingroup core * \class QgsSettingsEntryByReference @@ -357,7 +362,7 @@ class CORE_EXPORT QgsSettingsEntryBase * \since QGIS 3.26 */ template -class QgsSettingsEntryByReference : public QgsSettingsEntryBase +class QgsSettingsEntryBaseTemplate : public QgsSettingsEntryBase { public: @@ -373,11 +378,11 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase * * \since QGIS 3.30 */ - QgsSettingsEntryByReference( const QString &name, - QgsSettingsTreeNode *parent, - const T &defaultValue, - const QString &description = QString(), - Qgis::SettingsOptions options = Qgis::SettingsOptions() ) + QgsSettingsEntryBaseTemplate( const QString &name, + QgsSettingsTreeNode *parent, + const QVariant &defaultValue, + const QString &description = QString(), + Qgis::SettingsOptions options = Qgis::SettingsOptions() ) : QgsSettingsEntryBase( name, parent, defaultValue, description, options ) {} @@ -390,11 +395,11 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase * \param description specifies a description for the settings entry. * \param options specifies the options for the settings entry. */ - QgsSettingsEntryByReference( const QString &key, - const QString §ion, - const T &defaultValue, - const QString &description = QString(), - Qgis::SettingsOptions options = Qgis::SettingsOptions() ) + QgsSettingsEntryBaseTemplate( const QString &key, + const QString §ion, + const QVariant &defaultValue, + const QString &description = QString(), + Qgis::SettingsOptions options = Qgis::SettingsOptions() ) : QgsSettingsEntryBase( key, section, defaultValue, description, options ) {} @@ -428,30 +433,6 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPartList ) ); } - /** - * Returns the settings value for the \a dynamicKeyPart and with a \a defaultValueOverride - * \deprecated since QGIS 3.26 use valueAsVariantWithDefaultOverride instead - */ - Q_DECL_DEPRECATED T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const T &defaultValueOverride ) const SIP_DEPRECATED - { - if ( useDefaultValueOverride ) - return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) ); - else - return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) ); - } - - /** - * Returns the settings value for the \a dynamicKeyPartList and with a \a defaultValueOverride - * \deprecated since QGIS 3.26 use valueAsVariantWithDefaultOverride instead - */ - Q_DECL_DEPRECATED T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const T &defaultValueOverride ) const SIP_DEPRECATED - { - if ( useDefaultValueOverride ) - return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) ); - else - return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) ); - } - /** * Set settings value. * @@ -489,19 +470,24 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase */ T formerValue( const QStringList &dynamicKeyPartList ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPartList ) );} - protected: - //! Sets the settings value with an optional list of dynamic parts - bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const + bool checkValueVariant( const QVariant &value ) const override { - if ( checkValue( value ) ) - return QgsSettingsEntryBase::setVariantValuePrivate( convertToVariant( value ), dynamicKeyPartList ); - else - return false; + return checkValuePrivate( convertFromVariant( value ) ); } //! Converts the variant value to the value type of the setting virtual T convertFromVariant( const QVariant &value ) const = 0; + protected: + //! Sets the settings value with an optional list of dynamic parts + virtual bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const + { + if ( checkValuePrivate( value ) ) + return QgsSettingsEntryBase::setVariantValue( convertToVariant( value ), dynamicKeyPartList ); + else + return false; + } + //! Converts the value to a variant virtual QVariant convertToVariant( const T &value ) const { @@ -509,7 +495,7 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase } //! Check if the value is valid - virtual bool checkValue( const T &value ) const + virtual bool checkValuePrivate( const T &value ) const { Q_UNUSED( value ) return true; @@ -517,163 +503,6 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase }; -/** - * \ingroup core - * \class QgsSettingsEntryByValue - * - * \brief Base abstract class for settings entry which are passed by value - * \see QgsSettingsEntryBase - * \see QgsSettingsEntryByReference - * - * \since QGIS 3.26 - */ -template -class QgsSettingsEntryByValue : public QgsSettingsEntryBase -{ - public: - - /** - * Constructor for QgsSettingsEntryByValue. - * - * \param key specifies the key of the settings. - * \param parent specifies the parent in the tree of settings. - * \param defaultValue specifies the default value for the settings entry. - * \param description specifies a description for the settings entry. - * \param options specifies the options for the settings entry. - * \throws QgsSettingsException if the number of given parent named items doesn't match the complete key definition - */ - QgsSettingsEntryByValue( const QString &key, QgsSettingsTreeNode *parent, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) - : QgsSettingsEntryBase( key, parent, defaultValue, description, options ) - {} - - /** - * Constructor for QgsSettingsEntryByValue. - * - * \param key specifies the key of the settings. - * \param section specifies the section. - * \param defaultValue specifies the default value for the settings entry. - * \param description specifies a description for the settings entry. - * \param options specifies the options for the settings entry. - */ - QgsSettingsEntryByValue( const QString &key, const QString §ion, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) - : QgsSettingsEntryBase( key, section, defaultValue, description, options ) - {} - - virtual Qgis::SettingsType settingsType() const override = 0; - - /** - * Returns settings value. - * - * \param dynamicKeyPart specifies the dynamic part of the settings key. - */ - T value( const QString &dynamicKeyPart = QString() ) const { return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) );} - - /** - * Returns settings value. - * - * \param dynamicKeyPartList specifies the list of dynamic parts of the settings key. - */ - T value( const QStringList &dynamicKeyPartList ) const { return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) );} - - //! Returns the settings value with a \a defaultValueOverride and with an optional \a dynamicKeyPart - inline T valueWithDefaultOverride( T defaultValueOverride, const QString &dynamicKeyPart = QString() ) const - { - return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPart ) ); - } - - //! Returns the settings value with a \a defaultValueOverride for the \a dynamicKeyPartList - inline T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const - { - return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPartList ) ); - } - - /** - * Returns the settings value for the \a dynamicKeyPart and with a \a defaultValueOverride - * \deprecated since QGIS 3.26 use valueWithDefaultOverride instead - */ - Q_DECL_DEPRECATED T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, T defaultValueOverride ) const SIP_DEPRECATED - { - if ( useDefaultValueOverride ) - return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) ); - else - return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) ); - } - - /** - * Returns the settings value for the \a dynamicKeyPartList and with a \a defaultValueOverride - * \deprecated since QGIS 3.26 use valueWithDefaultOverride instead - */ - Q_DECL_DEPRECATED T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, T defaultValueOverride ) const SIP_DEPRECATED - { - if ( useDefaultValueOverride ) - return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) ); - else - return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) ); - } - - /** - * Set settings value. - * - * \param value specifies the value to set. - * \param dynamicKeyPart specifies the dynamic part of the settings key. - */ - bool setValue( T value, const QString &dynamicKeyPart = QString() ) const - { - return setValuePrivate( value, dynamicKeyPartToList( dynamicKeyPart ) ); - } - - /** - * Set settings value. - * - * \param value specifies the value to set. - * \param dynamicKeyPartList specifies the list of dynamic parts of the settings key. - */ - bool setValue( T value, const QStringList &dynamicKeyPartList ) const - { - return setValuePrivate( value, dynamicKeyPartList ); - } - - //! Returns settings default value. - T defaultValue() const {return convertFromVariant( defaultValueAsVariant() );} - - /** - * Returns the former value - * Returns the current value (or default) if there is no former value. - */ - T formerValue( const QString &dynamicKeyPart = QString() ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPart ) );} - - /** - * Returns the former value - * Returns the current value (or default) if there is no former value. - */ - T formerValue( const QStringList &dynamicKeyPartList ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPartList ) );} - - protected: - //! Sets the settings value with an optional list of dynamic parts - virtual bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const - { - if ( checkValue( value ) ) - return QgsSettingsEntryBase::setVariantValuePrivate( convertToVariant( value ), dynamicKeyPartList ); - else - return false; - } - - //! Converts the variant value to the value type of the setting - virtual T convertFromVariant( const QVariant &value ) const = 0; - - //! Converts the value to a variant - virtual QVariant convertToVariant( T value ) const - { - return QVariant::fromValue( value ); - } - - //! Check if the value is valid - virtual bool checkValue( T value ) const - { - Q_UNUSED( value ) - return true; - } -}; #endif // QGSSETTINGSENTRY_H diff --git a/src/core/settings/qgssettingsentryenumflag.h b/src/core/settings/qgssettingsentryenumflag.h index 1ba281cb664..ca3401bb074 100644 --- a/src/core/settings/qgssettingsentryenumflag.h +++ b/src/core/settings/qgssettingsentryenumflag.h @@ -32,7 +32,7 @@ * \since QGIS 3.20 */ template -class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue +class QgsSettingsEntryEnumFlag : public QgsSettingsEntryBaseTemplate { public: @@ -50,11 +50,11 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue * \since QGIS 3.30 */ QgsSettingsEntryEnumFlag( const QString &name, QgsSettingsTreeNode *parent, T defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) - : QgsSettingsEntryByValue( name, - parent, - QMetaEnum::fromType().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ), - description, - options ) + : QgsSettingsEntryBaseTemplate( name, + parent, + QMetaEnum::fromType().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ), + description, + options ) { mMetaEnum = QMetaEnum::fromType(); Q_ASSERT( mMetaEnum.isValid() ); @@ -75,11 +75,11 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue * \note for Python bindings, a custom implementation is achieved in Python directly */ QgsSettingsEntryEnumFlag( const QString &key, const QString §ion, T defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) - : QgsSettingsEntryByValue( key, - section, - QVariant::fromValue( defaultValue ), - description, - options ) + : QgsSettingsEntryBaseTemplate( key, + section, + QMetaEnum::fromType().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ), + description, + options ) { mMetaEnum = QMetaEnum::fromType(); Q_ASSERT( mMetaEnum.isValid() ); @@ -87,7 +87,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( this->key() ) ); } - QVariant convertToVariant( T value ) const override + QVariant convertToVariant( const T &value ) const override { if ( mMetaEnum.isFlag() ) return qgsFlagValueToKeys( value ); @@ -129,7 +129,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue * The \a value to set. * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. */ - bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const override + bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const override { if ( !mMetaEnum.isValid() ) { @@ -153,7 +153,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue } if ( ok ) - return this->setVariantValuePrivate( variantValue, dynamicKeyPartList ); + return this->setVariantValue( variantValue, dynamicKeyPartList ); else return false; } diff --git a/src/core/settings/qgssettingsentryimpl.cpp b/src/core/settings/qgssettingsentryimpl.cpp index d9d5403378f..3fa8cf92f1a 100644 --- a/src/core/settings/qgssettingsentryimpl.cpp +++ b/src/core/settings/qgssettingsentryimpl.cpp @@ -24,7 +24,7 @@ Qgis::SettingsType QgsSettingsEntryVariant::settingsType() const } -bool QgsSettingsEntryString::checkValue( const QString &value ) const +bool QgsSettingsEntryString::checkValuePrivate( const QString &value ) const { if ( value.length() < mMinLength ) { @@ -89,7 +89,7 @@ Qgis::SettingsType QgsSettingsEntryBool::settingsType() const } -bool QgsSettingsEntryInteger::checkValue( int value ) const +bool QgsSettingsEntryInteger::checkValuePrivate( const int &value ) const { if ( value < mMinValue ) { @@ -130,7 +130,7 @@ int QgsSettingsEntryInteger::minValue() const return mMaxValue; } -bool QgsSettingsEntryInteger64::checkValue( qlonglong value ) const +bool QgsSettingsEntryInteger64::checkValuePrivate( const qlonglong &value ) const { if ( value < mMinValue ) { @@ -173,7 +173,7 @@ qlonglong QgsSettingsEntryInteger64::minValue() const -bool QgsSettingsEntryDouble::checkValue( double value ) const +bool QgsSettingsEntryDouble::checkValuePrivate( const double &value ) const { if ( value < mMinValue ) { @@ -233,7 +233,7 @@ Qgis::SettingsType QgsSettingsEntryColor::settingsType() const return Qgis::SettingsType::Color; } -bool QgsSettingsEntryColor::checkValue( const QColor &value ) const +bool QgsSettingsEntryColor::checkValuePrivate( const QColor &value ) const { if ( !mAllowAlpha && value.alpha() != 255 ) { @@ -263,7 +263,7 @@ bool QgsSettingsEntryColor::copyValueFromKeys( const QString &redKey, const QStr settings.remove( alphaKey ); } - setVariantValuePrivate( oldValue ); + setVariantValue( oldValue ); return true; } return false; diff --git a/src/core/settings/qgssettingsentryimpl.h b/src/core/settings/qgssettingsentryimpl.h index 0bdeb43789c..be7a51fc917 100644 --- a/src/core/settings/qgssettingsentryimpl.h +++ b/src/core/settings/qgssettingsentryimpl.h @@ -26,7 +26,7 @@ * \brief A variant settings entry. * \since QGIS 3.20 */ -class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference +class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryBaseTemplate { public: @@ -46,7 +46,7 @@ class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference +class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryBaseTemplate { public: @@ -147,7 +146,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) , mMinLength( minLength ) , mMaxLength( maxLength ) {} @@ -170,7 +169,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) , mMinLength( minLength ) , mMaxLength( maxLength ) {} @@ -211,10 +210,11 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference +class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryBaseTemplate { public: @@ -246,7 +246,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc const QStringList &defaultValue = QStringList(), const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER - : QgsSettingsEntryByReference( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) {} /** @@ -263,7 +263,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc const QStringList &defaultValue = QStringList(), const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE - : QgsSettingsEntryByReference( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) {} @@ -291,9 +291,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc virtual Qgis::SettingsType settingsType() const override; - private: QStringList convertFromVariant( const QVariant &value ) const override SIP_FORCE; - }; @@ -304,7 +302,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc * \brief A boolean settings entry. * \since QGIS 3.20 */ -class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue +class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryBaseTemplate { public: @@ -322,7 +320,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue bool defaultValue = false, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER - : QgsSettingsEntryByValue( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) {} /** @@ -339,7 +337,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue bool defaultValue = false, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE - : QgsSettingsEntryByValue( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) {} #ifdef SIP_RUN @@ -367,7 +365,6 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue virtual Qgis::SettingsType settingsType() const override; - private: bool convertFromVariant( const QVariant &value ) const override SIP_FORCE; }; @@ -379,7 +376,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue * \brief An integer settings entry. * \since QGIS 3.20 */ -class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue +class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryBaseTemplate { public: @@ -401,7 +398,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue Qgis::SettingsOptions options = Qgis::SettingsOptions(), int minValue = std::numeric_limits::min(), int maxValue = std::numeric_limits::max() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER - : QgsSettingsEntryByValue( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) { } @@ -424,7 +421,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue Qgis::SettingsOptions options = Qgis::SettingsOptions(), int minValue = std::numeric_limits::min(), int maxValue = std::numeric_limits::max() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE - : QgsSettingsEntryByValue( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) { } @@ -467,9 +464,10 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue */ int maxValue() const; - private: - bool checkValue( int value ) const override SIP_FORCE; int convertFromVariant( const QVariant &value ) const override SIP_FORCE; + + private: + bool checkValuePrivate( const int &value ) const override SIP_FORCE; int mMinValue; int mMaxValue; }; @@ -484,7 +482,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue * \brief A 64 bits integer (long long) settings entry. * \since QGIS 3.30 */ -class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue +class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryBaseTemplate { public: @@ -506,7 +504,7 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue::min(), qlonglong maxValue = std::numeric_limits::max() ) SIP_THROW( QgsSettingsException ) - : QgsSettingsEntryByValue( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) { } @@ -529,7 +527,7 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue::min(), qlonglong maxValue = std::numeric_limits::max() ) - : QgsSettingsEntryByValue( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) { } @@ -546,9 +544,10 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue +class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryBaseTemplate { public: @@ -586,7 +585,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue::lowest(), double maxValue = std::numeric_limits::max(), int displayDecimals = 1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER - : QgsSettingsEntryByValue( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) , mDisplayHintDecimals( displayDecimals ) @@ -613,7 +612,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue::lowest(), double maxValue = std::numeric_limits::max(), int displayDecimals = 1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE - : QgsSettingsEntryByValue( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) , mMinValue( minValue ) , mMaxValue( maxValue ) , mDisplayHintDecimals( displayDecimals ) @@ -672,9 +671,10 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue +class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryBaseTemplate { public: @@ -711,7 +711,7 @@ class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference +class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryBaseTemplate { public: @@ -812,7 +812,7 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc const QVariantMap &defaultValue = QVariantMap(), const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER - : QgsSettingsEntryByReference( name, parent, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options ) { } @@ -830,7 +830,7 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc const QVariantMap &defaultValue = QVariantMap(), const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE - : QgsSettingsEntryByReference( key, section, defaultValue, description, options ) + : QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options ) { } @@ -858,9 +858,8 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc virtual Qgis::SettingsType settingsType() const override; - private: QVariantMap convertFromVariant( const QVariant &value ) const override SIP_FORCE; - }; + #endif // QGSSETTINGSENTRYIMPL_H From 7872ddbf71fc84377c2dd06a94eded1f55ee99eb Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:12:16 +0200 Subject: [PATCH 02/20] rename QgsSettingsTreeWidget to QgsSettingsTreeWidget (app) --- src/app/CMakeLists.txt | 3 +- ...idget.cpp => qgssettingstreewidgetold.cpp} | 93 +++++++------------ ...reewidget.h => qgssettingstreewidgetold.h} | 13 ++- 3 files changed, 43 insertions(+), 66 deletions(-) rename src/app/{qgssettingstreewidget.cpp => qgssettingstreewidgetold.cpp} (80%) rename src/app/{qgssettingstreewidget.h => qgssettingstreewidgetold.h} (92%) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index dad5a5ffa47..355d8a019f2 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -282,7 +282,7 @@ set(QGIS_APP_SRCS pluginmanager/qgspluginsortfilterproxymodel.cpp pluginmanager/qgspluginitemdelegate.cpp - qgssettingstreewidget.cpp + qgssettingstreewidgetold.cpp qgssettingsregistryapp.cpp qgsvariantdelegate.cpp qgscrashhandler.cpp @@ -534,6 +534,7 @@ target_include_directories(qgis_app PUBLIC ${CMAKE_SOURCE_DIR}/src/app/locator ${CMAKE_SOURCE_DIR}/src/app/options ${CMAKE_SOURCE_DIR}/src/app/pointcloud + ${CMAKE_SOURCE_DIR}/src/app/settings ${CMAKE_SOURCE_DIR}/src/app/vectortile ${CMAKE_SOURCE_DIR}/src/plugins ${CMAKE_SOURCE_DIR}/src/python diff --git a/src/app/qgssettingstreewidget.cpp b/src/app/qgssettingstreewidgetold.cpp similarity index 80% rename from src/app/qgssettingstreewidget.cpp rename to src/app/qgssettingstreewidgetold.cpp index 891deef5abd..f9359e6613e 100644 --- a/src/app/qgssettingstreewidget.cpp +++ b/src/app/qgssettingstreewidgetold.cpp @@ -41,7 +41,7 @@ #include #include -#include "qgssettingstreewidget.h" +#include "qgssettingstreewidgetold.h" #include "qgsvariantdelegate.h" #include "qgslogger.h" #include "qgssettings.h" @@ -51,7 +51,7 @@ #include #include -QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent ) +QgsSettingsTreeWidgetOld::QgsSettingsTreeWidgetOld( QWidget *parent ) : QTreeWidget( parent ) { setItemDelegate( new QgsVariantDelegate( this ) ); @@ -72,45 +72,25 @@ QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent ) setEditTriggers( QAbstractItemView::AllEditTriggers ); - connect( &mRefreshTimer, &QTimer::timeout, this, &QgsSettingsTreeWidget::maybeRefresh ); + connect( &mRefreshTimer, &QTimer::timeout, this, &QgsSettingsTreeWidgetOld::maybeRefresh ); setContextMenuPolicy( Qt::CustomContextMenu ); - connect( this, &QTreeWidget::customContextMenuRequested, this, &QgsSettingsTreeWidget::showContextMenu ); + connect( this, &QTreeWidget::customContextMenuRequested, this, &QgsSettingsTreeWidgetOld::showContextMenu ); mContextMenu = new QMenu( this ); } -void QgsSettingsTreeWidget::setSettingsObject( QgsSettings *settings ) -{ - mSettings = settings; - clear(); - - if ( mSettings ) - { - mSettings->setParent( this ); - if ( isVisible() ) - refresh(); - if ( mAutoRefresh ) - mRefreshTimer.start(); - } - else - { - mRefreshTimer.stop(); - } -} - -QSize QgsSettingsTreeWidget::sizeHint() const +QSize QgsSettingsTreeWidgetOld::sizeHint() const { return QSize( 800, 600 ); } -void QgsSettingsTreeWidget::setAutoRefresh( bool autoRefresh ) +void QgsSettingsTreeWidgetOld::setAutoRefresh( bool autoRefresh ) { mAutoRefresh = autoRefresh; if ( mAutoRefresh ) { maybeRefresh(); - if ( mSettings ) - mRefreshTimer.start(); + mRefreshTimer.start(); } else { @@ -118,29 +98,26 @@ void QgsSettingsTreeWidget::setAutoRefresh( bool autoRefresh ) } } -void QgsSettingsTreeWidget::maybeRefresh() +void QgsSettingsTreeWidgetOld::maybeRefresh() { if ( state() != EditingState ) refresh(); } -void QgsSettingsTreeWidget::refresh() +void QgsSettingsTreeWidgetOld::refresh() { - if ( !mSettings ) - return; - disconnect( this, &QTreeWidget::itemChanged, - this, &QgsSettingsTreeWidget::updateSetting ); + this, &QgsSettingsTreeWidgetOld::updateSetting ); - mSettings->sync(); + mSettings.sync(); // add any settings not in QgsSettings object, so it will show up in the tree view QMap::const_iterator it = mSettingsMap.constBegin(); while ( it != mSettingsMap.constEnd() ) { - if ( ! mSettings->contains( it.key() ) ) + if ( ! mSettings.contains( it.key() ) ) { - mSettings->setValue( it.key(), it.value().at( 3 ) ); + mSettings.setValue( it.key(), it.value().at( 3 ) ); } ++it; } @@ -148,10 +125,10 @@ void QgsSettingsTreeWidget::refresh() updateChildItems( nullptr ); connect( this, &QTreeWidget::itemChanged, - this, &QgsSettingsTreeWidget::updateSetting ); + this, &QgsSettingsTreeWidgetOld::updateSetting ); } -bool QgsSettingsTreeWidget::event( QEvent *event ) +bool QgsSettingsTreeWidgetOld::event( QEvent *event ) { if ( event->type() == QEvent::WindowActivate ) { @@ -161,24 +138,24 @@ bool QgsSettingsTreeWidget::event( QEvent *event ) return QTreeWidget::event( event ); } -void QgsSettingsTreeWidget::showEvent( QShowEvent * ) +void QgsSettingsTreeWidgetOld::showEvent( QShowEvent * ) { const QgsTemporaryCursorOverride waitCursor( Qt::BusyCursor ); refresh(); } -void QgsSettingsTreeWidget::updateSetting( QTreeWidgetItem *item ) +void QgsSettingsTreeWidgetOld::updateSetting( QTreeWidgetItem *item ) { const QString key = itemKey( item ); if ( key.isNull() ) return; - mSettings->setValue( key, item->data( ColumnValue, Qt::UserRole ) ); + mSettings.setValue( key, item->data( ColumnValue, Qt::UserRole ) ); if ( mAutoRefresh ) refresh(); } -void QgsSettingsTreeWidget::showContextMenu( QPoint pos ) +void QgsSettingsTreeWidgetOld::showContextMenu( QPoint pos ) { QTreeWidgetItem *item = itemAt( pos ); if ( !item ) @@ -202,7 +179,7 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos ) return; - mSettings->remove( itemPath ); + mSettings.remove( itemPath ); refresh(); } ); @@ -220,7 +197,7 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos ) QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes ) return; - mSettings->remove( itemPath ); + mSettings.remove( itemPath ); refresh(); } ); @@ -233,11 +210,11 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos ) mContextMenu->exec( mapToGlobal( pos ) ); } -void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent ) +void QgsSettingsTreeWidgetOld::updateChildItems( QTreeWidgetItem *parent ) { int dividerIndex = 0; - const auto constChildGroups = mSettings->childGroups(); + const auto constChildGroups = mSettings.childGroups(); for ( const QString &group : constChildGroups ) { QTreeWidgetItem *child = nullptr; @@ -257,12 +234,12 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent ) child->setIcon( ColumnSettings, mGroupIcon ); ++dividerIndex; - mSettings->beginGroup( group ); + mSettings.beginGroup( group ); updateChildItems( child ); - mSettings->endGroup(); + mSettings.endGroup(); } - const auto constChildKeys = mSettings->childKeys(); + const auto constChildKeys = mSettings.childKeys(); for ( const QString &key : constChildKeys ) { QTreeWidgetItem *child = nullptr; @@ -289,7 +266,7 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent ) child = childAt( parent, childIndex ); } - const QVariant value = mSettings->value( key ); + const QVariant value = mSettings.value( key ); if ( value.type() == QVariant::Invalid ) { child->setText( ColumnType, QStringLiteral( "Invalid" ) ); @@ -306,7 +283,7 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent ) delete childAt( parent, dividerIndex ); } -QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text, +QTreeWidgetItem *QgsSettingsTreeWidgetOld::createItem( const QString &text, QTreeWidgetItem *parent, int index, const bool isGroup ) { QTreeWidgetItem *after = nullptr; @@ -325,7 +302,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text, item->setData( ColumnSettings, TypeRole, isGroup ? Group : Setting ); - const QString completeSettingsPath = mSettings->group().isEmpty() ? text : mSettings->group() + '/' + text; + const QString completeSettingsPath = mSettings.group().isEmpty() ? text : mSettings.group() + '/' + text; item->setData( ColumnSettings, PathRole, completeSettingsPath ); const QString key = itemKey( item ); @@ -343,7 +320,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text, return item; } -QString QgsSettingsTreeWidget::itemKey( QTreeWidgetItem *item ) +QString QgsSettingsTreeWidgetOld::itemKey( QTreeWidgetItem *item ) { if ( ! item ) return QString(); @@ -359,7 +336,7 @@ QString QgsSettingsTreeWidget::itemKey( QTreeWidgetItem *item ) return key; } -QTreeWidgetItem *QgsSettingsTreeWidget::childAt( QTreeWidgetItem *parent, int index ) +QTreeWidgetItem *QgsSettingsTreeWidgetOld::childAt( QTreeWidgetItem *parent, int index ) { if ( parent ) return parent->child( index ); @@ -367,7 +344,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::childAt( QTreeWidgetItem *parent, int in return topLevelItem( index ); } -int QgsSettingsTreeWidget::childCount( QTreeWidgetItem *parent ) +int QgsSettingsTreeWidgetOld::childCount( QTreeWidgetItem *parent ) { if ( parent ) return parent->childCount(); @@ -375,8 +352,8 @@ int QgsSettingsTreeWidget::childCount( QTreeWidgetItem *parent ) return topLevelItemCount(); } -int QgsSettingsTreeWidget::findChild( QTreeWidgetItem *parent, const QString &text, - int startIndex ) +int QgsSettingsTreeWidgetOld::findChild( QTreeWidgetItem *parent, const QString &text, + int startIndex ) { for ( int i = startIndex; i < childCount( parent ); ++i ) { @@ -386,7 +363,7 @@ int QgsSettingsTreeWidget::findChild( QTreeWidgetItem *parent, const QString &te return -1; } -void QgsSettingsTreeWidget::moveItemForward( QTreeWidgetItem *parent, int oldIndex, +void QgsSettingsTreeWidgetOld::moveItemForward( QTreeWidgetItem *parent, int oldIndex, int newIndex ) { for ( int i = 0; i < oldIndex - newIndex; ++i ) diff --git a/src/app/qgssettingstreewidget.h b/src/app/qgssettingstreewidgetold.h similarity index 92% rename from src/app/qgssettingstreewidget.h rename to src/app/qgssettingstreewidgetold.h index b89d0c6a04d..1dff30e8af4 100644 --- a/src/app/qgssettingstreewidget.h +++ b/src/app/qgssettingstreewidgetold.h @@ -38,16 +38,16 @@ ** ****************************************************************************/ -#ifndef QGSSETTINGSTREEWIDGET_H -#define QGSSETTINGSTREEWIDGET_H +#ifndef QGSSETTINGSTREEWIDGETOLD_H +#define QGSSETTINGSTREEWIDGETOLD_H +#include "qgssettings.h" #include #include #include -class QgsSettings; -class QgsSettingsTreeWidget : public QTreeWidget +class QgsSettingsTreeWidgetOld : public QTreeWidget { Q_OBJECT @@ -68,9 +68,8 @@ class QgsSettingsTreeWidget : public QTreeWidget }; Q_ENUM( Type ) - explicit QgsSettingsTreeWidget( QWidget *parent = nullptr ); + explicit QgsSettingsTreeWidgetOld( QWidget *parent = nullptr ); - void setSettingsObject( QgsSettings *mSettings ); QSize sizeHint() const override; void setSettingsMap( QMap< QString, QStringList > &map ) { mSettingsMap = map; } @@ -107,7 +106,7 @@ class QgsSettingsTreeWidget : public QTreeWidget int findChild( QTreeWidgetItem *parent, const QString &text, int startIndex ); void moveItemForward( QTreeWidgetItem *parent, int oldIndex, int newIndex ); - QgsSettings *mSettings = nullptr; + QgsSettings mSettings; QTimer mRefreshTimer; bool mAutoRefresh = false; QIcon mGroupIcon; From effbfc220677e3693b49ba915e7267b08e1cbe7f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:14:06 +0200 Subject: [PATCH 03/20] add base class and implementation of wrappers for settings editor widgets --- .../qgssettingseditorwidgetwrapper.cpp | 61 ++++ .../settings/qgssettingseditorwidgetwrapper.h | 94 +++++ .../qgssettingseditorwidgetwrapperimpl.cpp | 328 ++++++++++++++++++ .../qgssettingseditorwidgetwrapperimpl.h | 252 ++++++++++++++ 4 files changed, 735 insertions(+) create mode 100644 src/gui/settings/qgssettingseditorwidgetwrapper.cpp create mode 100644 src/gui/settings/qgssettingseditorwidgetwrapper.h create mode 100644 src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp create mode 100644 src/gui/settings/qgssettingseditorwidgetwrapperimpl.h diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.cpp b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp new file mode 100644 index 00000000000..a15a90807b9 --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + qgssettingseditorwidgetwrapper.cpp + -------------------------------------- + Date : February 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "qgssettingseditorwidgetwrapper.h" + +#include "qgslogger.h" +#include "qgssettingsentry.h" + +#include + + +QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetWrapper::fromWidget( const QWidget *widget ) +{ + QVariant editorDataVariant = widget->property( "SETTING-EDITOR-WIDGET-WRAPPER" ); + if ( editorDataVariant.isValid() ) + { + return editorDataVariant.value(); + } + + return nullptr; +} + +QgsSettingsEditorWidgetWrapper::QgsSettingsEditorWidgetWrapper( QObject *parent ) + : QObject( parent ) +{ +} + +QWidget *QgsSettingsEditorWidgetWrapper::createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent ) +{ + QWidget *editor = createEditorPrivate( parent ); + if ( configureEditor( editor, setting, dynamicKeyPartList ) ) + return editor; + else + QgsDebugMsg( QStringLiteral( "editor could not be confiugured" ) ); + return nullptr; +} + +bool QgsSettingsEditorWidgetWrapper::configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList ) +{ + mDynamicKeyPartList = dynamicKeyPartList; + + bool ok = configureEditorPrivate( editor, setting ); + + if ( ok ) + editor->setProperty( "SETTING-EDITOR-WIDGET-WRAPPER", QVariant::fromValue( this ) ); + + return ok; +} diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.h b/src/gui/settings/qgssettingseditorwidgetwrapper.h new file mode 100644 index 00000000000..5ecf842d188 --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.h @@ -0,0 +1,94 @@ +/*************************************************************************** + qgssettingseditorwidgetwrapper.h + -------------------------------------- + Date : February 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSEDITORWIDGETWRAPPER_H +#define QGSSETTINGSEDITORWIDGETWRAPPER_H + +#include + +#include "qgis_sip.h" +#include "qgis_gui.h" + +class QgsSettingsEntryBase; + +/** + * \ingroup gui + * \brief Base class for settings editor wrappers + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject +{ + Q_OBJECT + public: + //! Creates a wrapper from the definition stored in a widget created by createEditor() + static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) SIP_FACTORY; + + //! Constructor + QgsSettingsEditorWidgetWrapper( QObject *parent = nullptr ); + + virtual ~QgsSettingsEditorWidgetWrapper() = default; + + /** + * This id of the type of settings it handles + * \note This mostly correspond to the content of Qgis::SettingsType but it's a string since custom Python implementation are possible. + */ + virtual QString id() const = 0; + + //! Creates a new instance of the editor wrapper so it can be configured for a widget and a setting + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const = 0; + +//! Creates the editor for the given widget + QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = nullptr ); + + //! Configures the \a editor according the setting + bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() ); + + /** + * Sets the widget value from the setting value + * The wrapper must be configured before calling this medthod + */ + virtual bool setWidgetFromSetting() const = 0; + + /** + * SDets the setting value from the widget value + * The wrapper must be configured before calling this medthod + */ + virtual bool setSettingFromWidget() const = 0; + + /** + * Returns the value from the widget as a variant + * The wrapper must be configured before calling this medthod + */ + virtual QVariant variantValueFromWidget() const = 0; + + /** + * Sets the value of the widget + * The wrapper must be configured before calling this medthod + */ + virtual void setWidgetFromVariant( const QVariant &value ) const = 0; + + + protected: + virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const = 0; + + virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; + + QStringList mDynamicKeyPartList; +}; + + + +#endif // QGSSETTINGSEDITORWIDGETWRAPPER_H diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp new file mode 100644 index 00000000000..81a69658009 --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.cpp @@ -0,0 +1,328 @@ +/*************************************************************************** + qgssettingseditorwidgetwrapperimpl.cpp + -------------------------------------- + Date : February 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "qgssettingseditorwidgetwrapperimpl.h" +#include "qgslogger.h" +#include "qgssettingsentryimpl.h" +#include "qgscolorbutton.h" + +#include +#include + + +// ******* +// String +// ******* + +QString QgsSettingsStringEditorWidgetWrapper::id() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::String ) ) ); +} + +bool QgsSettingsStringEditorWidgetWrapper::setWidgetValue( const QString &value ) const +{ + if ( mEditor ) + { + mEditor->setText( value ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsStringEditorWidgetWrapper::setSettingFromWidget() const +{ + if ( mEditor ) + { + mSetting->setValue( mEditor->text(), mDynamicKeyPartList ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +QString QgsSettingsStringEditorWidgetWrapper::valueFromWidget() const +{ + if ( mEditor ) + { + return mEditor->text(); + } + else + { + QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) ); + } + return QString(); +} + +// ******* +// Boolean +// ******* + +QString QgsSettingsBoolEditorWidgetWrapper::id() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::Bool ) ) ); +} + +bool QgsSettingsBoolEditorWidgetWrapper::setWidgetValue( const bool &value ) const +{ + if ( mEditor ) + { + mEditor->setChecked( value ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsBoolEditorWidgetWrapper::setSettingFromWidget() const +{ + if ( mEditor ) + { + mSetting->setValue( mEditor->isChecked(), mDynamicKeyPartList ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsBoolEditorWidgetWrapper::valueFromWidget() const +{ + + if ( mEditor ) + { + return mEditor->isChecked(); + } + else + { + QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) ); + } + return false; +} + + +// ******* +// Integer +// ******* + +QString QgsSettingsIntegerEditorWidgetWrapper::id() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::Integer ) ) ); +} + +bool QgsSettingsIntegerEditorWidgetWrapper::setWidgetValue( const int &value ) const +{ + if ( mEditor ) + { + mEditor->setValue( value ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsIntegerEditorWidgetWrapper::setSettingFromWidget() const +{ + if ( mEditor ) + { + mSetting->setValue( mEditor->value(), mDynamicKeyPartList ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +int QgsSettingsIntegerEditorWidgetWrapper::valueFromWidget() const +{ + if ( mEditor ) + { + return mEditor->value(); + } + else + { + QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) ); + } + return std::numeric_limits::quiet_NaN(); +} + + + +// ******* +// Double +// ******* + +QString QgsSettingsDoubleEditorWidgetWrapper::id() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::Double ) ) ); +} + +bool QgsSettingsDoubleEditorWidgetWrapper::setWidgetValue( const double &value ) const +{ + if ( mEditor ) + { + mEditor->setValue( value ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsDoubleEditorWidgetWrapper::setSettingFromWidget() const +{ + if ( mEditor ) + { + mSetting->setValue( mEditor->value(), mDynamicKeyPartList ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +double QgsSettingsDoubleEditorWidgetWrapper::valueFromWidget() const +{ + if ( mEditor ) + { + return mEditor->value(); + } + else + { + QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) ); + } + return std::numeric_limits::quiet_NaN(); +} + +// ******* +// Color +// ******* + +QString QgsSettingsColorEditorWidgetWrapper::id() const +{ + return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::Color ) ) ); +} + +bool QgsSettingsColorEditorWidgetWrapper::setWidgetValue( const QColor &value ) const +{ + if ( mEditor ) + { + mEditor->setColor( value ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +bool QgsSettingsColorEditorWidgetWrapper::setSettingFromWidget() const +{ + if ( mEditor ) + { + mSetting->setValue( mEditor->color(), mDynamicKeyPartList ); + return true; + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } + return false; +} + +QColor QgsSettingsColorEditorWidgetWrapper::valueFromWidget() const +{ + if ( mEditor ) + { + return mEditor->color(); + } + else + { + QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) ); + } + return QColor(); +} + +// ******* +// StringList +// ******* + +//QString QgsSettingsStringListEditorWidgetWrapper::id() const +//{ +// return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast( Qgis::SettingsType::StringList ) ) ); +//} + +//bool QgsSettingsStringListEditorWidgetWrapper::setWidgetFromSetting() const +//{ +// if ( mEditor ) +// { +// mEditor->setValue( mSetting->value( mDynamicKeyPartList ) ); +// return true; +// } +// else +// { +// QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); +// } +// return false; +//} + +//bool QgsSettingsStringListEditorWidgetWrapper::setSettingFromWidget() const +//{ +// if ( mEditor ) +// { +// mSetting->setValue( mEditor->value(), mDynamicKeyPartList ); +// return true; +// } +// else +// { +// QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); +// } +// return false; +//} + +//QVariant QgsSettingsStringListEditorWidgetWrapper::valueFromWidget() const +//{ +// if ( mEditor ) +// { +// return mEditor->value(); +// } +// else +// { +// QgsDebugMsg(QString("editor is not set, returning a non-existing value")); +// } +// return QStringList(); +//} diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h new file mode 100644 index 00000000000..63afb7f06ea --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h @@ -0,0 +1,252 @@ +/*************************************************************************** + qgssettingseditorwidgetwrapperimpl.h + -------------------------------------- + Date : February 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H +#define QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H + +#include + +#include "qgis_gui.h" +#include "qgssettingseditorwidgetwrapper.h" +#include "qgslogger.h" + +#include "qgssettingsentryimpl.h" +#include "qgscolorbutton.h" +#include +#include +#include +#include +#include + + +//TODO variant map, enum + +class QgsColorButton; + +/** + * \ingroup gui + * \brief This class is a base factory of editor for settings + * + * \since QGIS 3.32 + */ +template +class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEditorWidgetWrapper +{ + public: + QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapper( parent ) {} + + virtual QString id() const override = 0; + + virtual bool setWidgetFromSetting() const override + { + if ( mSetting ) + return setWidgetValue( mSetting->value( mDynamicKeyPartList ) ); + + QgsDebugMsg( "editor is not configured" ); + return false; + } + + virtual bool setSettingFromWidget() const override = 0; + + void setWidgetFromVariant( const QVariant &value ) const override + { + setWidgetValue( mSetting->convertFromVariant( value ) ); + } + + virtual bool setWidgetValue( const U &value ) const = 0; + + QVariant variantValueFromWidget() const override + { + return valueFromWidget(); + }; + + virtual U valueFromWidget() const = 0; + + //! Returns the editor + V *editor() const {return mEditor;} + + //! Returns the setting + const T *setting() const {return mSetting;} + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override = 0; + + protected: + virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const override + { + V *editor = new V( parent ); + editor->setAutoFillBackground( true ); + return editor; + } + + bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) override + { + mSetting = dynamic_cast( setting ); + mEditor = qobject_cast( editor ); + if ( mEditor ) + { + configureEditorPrivateImplementation(); + return true; + } + return false; + } + + virtual void configureEditorPrivateImplementation() {} + + const T *mSetting = nullptr; + V *mEditor = nullptr; +}; + + +/** + * \ingroup gui + * \brief This class is a factory of editor for string settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +{ + public: + QgsSettingsStringEditorWidgetWrapper( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} + + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsStringEditorWidgetWrapper( parent );} + + QString id() const override; + + bool setSettingFromWidget() const override; + + QString valueFromWidget() const override; + + bool setWidgetValue( const QString &value ) const override; +}; + +/** + * \ingroup gui + * \brief This class is a factory of editor for boolean settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +{ + public: + QgsSettingsBoolEditorWidgetWrapper( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} + + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsBoolEditorWidgetWrapper( parent );} + + QString id() const override; + + bool setSettingFromWidget() const override; + + bool valueFromWidget() const override; + + bool setWidgetValue( const bool &value ) const override; +}; + +/** + * \ingroup gui + * \brief This class is a factory of editor for integer settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +{ + public: + QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} + + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsIntegerEditorWidgetWrapper( parent );} + + QString id() const override; + + bool setSettingFromWidget() const override; + + int valueFromWidget() const override; + + bool setWidgetValue( const int &value ) const override; +}; + + +/** + * \ingroup gui + * \brief This class is a factory of editor for double settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +{ + public: + QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} + + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsDoubleEditorWidgetWrapper( parent );} + + QString id() const override; + + bool setSettingFromWidget() const override; + + double valueFromWidget() const override; + + bool setWidgetValue( const double &value ) const override; +}; + + +/** + * \ingroup gui + * \brief This class is a factory of editor for color settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +{ + public: + QgsSettingsColorEditorWidgetWrapper( QObject *parent = nullptr ) + : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} + + QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsColorEditorWidgetWrapper( parent );} + + QString id() const override; + + bool setSettingFromWidget() const override; + + QColor valueFromWidget() const override; + + bool setWidgetValue( const QColor &value ) const override; +}; + +///** +// * \ingroup gui +// * \brief This class is a factory of editor for boolean settings +// * +// * \since QGIS 3.32 +// */ +//class GUI_EXPORT QgsSettingsStringListEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate +//{ +// public: +// QgsSettingsStringListEditorWidgetWrapper() +// : QgsSettingsEditorWidgetWrapperTemplate() {} + +// QString id() const override; + +// bool setWidgetFromSetting() const override; + +// bool setSettingFromWidget() const override; + +// QStringList valueFromWidget() const override; +//}; + + +#endif // QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H From 77cc02f27eceb8cdd8792a1597deaff046201599 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:15:07 +0200 Subject: [PATCH 04/20] add registry of settings editors wrappers --- src/gui/qgsgui.cpp | 11 +++ src/gui/qgsgui.h | 9 ++- .../qgssettingseditorwidgetregistry.cpp | 72 +++++++++++++++++++ .../qgssettingseditorwidgetregistry.h | 62 ++++++++++++++++ 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/gui/settings/qgssettingseditorwidgetregistry.cpp create mode 100644 src/gui/settings/qgssettingseditorwidgetregistry.h diff --git a/src/gui/qgsgui.cpp b/src/gui/qgsgui.cpp index a0c9574e89f..73cfd784d80 100644 --- a/src/gui/qgsgui.cpp +++ b/src/gui/qgsgui.cpp @@ -63,6 +63,9 @@ #include "qgssensorguiregistry.h" #include "qgshistoryentry.h" +#include "qgssettingseditorwidgetregistry.h" + + #include #include @@ -182,6 +185,11 @@ QgsHistoryProviderRegistry *QgsGui::historyProviderRegistry() return instance()->mHistoryProviderRegistry; } +QgsSettingsEditorWidgetRegistry *QgsGui::settingsEditorWidgetRegistry() +{ + return instance()->mSettingsEditorRegistry; +} + void QgsGui::enableAutoGeometryRestore( QWidget *widget, const QString &key ) { if ( widget->objectName().isEmpty() ) @@ -238,6 +246,7 @@ QgsGui::~QgsGui() delete mRelationEditorRegistry; delete mSettingsRegistryGui; delete mSensorGuiRegistry; + delete mSettingsEditorRegistry; } QColor QgsGui::sampleColor( QPoint point ) @@ -288,6 +297,8 @@ QgsGui::QgsGui() mSettingsRegistryGui = new QgsSettingsRegistryGui(); + mSettingsEditorRegistry = new QgsSettingsEditorWidgetRegistry(); + mCodeEditorColorSchemeRegistry = new QgsCodeEditorColorSchemeRegistry(); // provider gui registry initialize QgsProviderRegistry too diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h index 4329b1eeb9b..0c5850bc80e 100644 --- a/src/gui/qgsgui.h +++ b/src/gui/qgsgui.h @@ -48,7 +48,7 @@ class QgsRelationWidgetRegistry; class QgsMapToolShapeRegistry; class QgsHistoryProviderRegistry; class QgsSensorGuiRegistry; - +class QgsSettingsEditorWidgetRegistry; /** * \ingroup gui @@ -213,6 +213,12 @@ class GUI_EXPORT QgsGui : public QObject */ static QgsHistoryProviderRegistry *historyProviderRegistry() SIP_KEEPREFERENCE; + /** + * Returns the registry of settings editors. + * \since QGIS 3.32 + */ + static QgsSettingsEditorWidgetRegistry *settingsEditorWidgetRegistry() SIP_KEEPREFERENCE; + /** * Register the widget to allow its position to be automatically saved and restored when open and closed. * Use this to avoid needing to call saveGeometry() and restoreGeometry() on your widget. @@ -322,6 +328,7 @@ class GUI_EXPORT QgsGui : public QObject QgsMapToolShapeRegistry *mShapeMapToolRegistry = nullptr; QgsHistoryProviderRegistry *mHistoryProviderRegistry = nullptr; QgsSensorGuiRegistry *mSensorGuiRegistry = nullptr; + QgsSettingsEditorWidgetRegistry *mSettingsEditorRegistry = nullptr; std::unique_ptr< QgsWindowManagerInterface > mWindowManager; #ifdef SIP_RUN diff --git a/src/gui/settings/qgssettingseditorwidgetregistry.cpp b/src/gui/settings/qgssettingseditorwidgetregistry.cpp new file mode 100644 index 00000000000..345173b3271 --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetregistry.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + qgssettingsfactoryfactoryregistry.cpp + --------------------- + begin : April 2023 + copyright : (C) 2023 by Denis Rouzaud + email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgssettingseditorwidgetregistry.h" + +#include "qgslogger.h" +#include "qgssettingseditorwidgetwrapper.h" +#include "qgssettingseditorwidgetwrapperimpl.h" +#include "qgssettingsentry.h" + +QgsSettingsEditorWidgetRegistry::QgsSettingsEditorWidgetRegistry() +{ + addWrapper( new QgsSettingsStringEditorWidgetWrapper() ); + addWrapper( new QgsSettingsBoolEditorWidgetWrapper() ); + addWrapper( new QgsSettingsIntegerEditorWidgetWrapper() ); + addWrapper( new QgsSettingsDoubleEditorWidgetWrapper() ); + addWrapper( new QgsSettingsColorEditorWidgetWrapper() ); + +} + +QgsSettingsEditorWidgetRegistry::~QgsSettingsEditorWidgetRegistry() +{ + qDeleteAll( mWrappers ); +} + +bool QgsSettingsEditorWidgetRegistry::addWrapper( QgsSettingsEditorWidgetWrapper *wrapper ) +{ + if ( mWrappers.contains( wrapper->id() ) ) + return false; + + mWrappers.insert( wrapper->id(), wrapper ); + return true; +} + +QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetRegistry::createWrapper( const QString &id, QObject *parent ) const +{ + QgsSettingsEditorWidgetWrapper *wrapper = mWrappers.value( id ); + if ( wrapper ) + { + return wrapper->createWrapper( parent ); + } + else + { + QgsDebugMsg( QStringLiteral( "Setting factory was not found for '%1', returning the default string factory" ).arg( id ) ); + return nullptr; + } +} + +QWidget *QgsSettingsEditorWidgetRegistry::createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent ) const +{ + QgsSettingsEditorWidgetWrapper *eww = createWrapper( setting->typeId(), parent ); + if ( eww ) + return eww->createEditor( setting, dynamicKeyPartList, parent ); + else + return nullptr; +} + + + + diff --git a/src/gui/settings/qgssettingseditorwidgetregistry.h b/src/gui/settings/qgssettingseditorwidgetregistry.h new file mode 100644 index 00000000000..4461c7e3a2a --- /dev/null +++ b/src/gui/settings/qgssettingseditorwidgetregistry.h @@ -0,0 +1,62 @@ +/*************************************************************************** + qgssettingseditorwidgetregistry.h + --------------------- + begin : April 2023 + copyright : (C) 2023 by Denis Rouzaud + email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSEDITORREGISTRY_H +#define QGSSETTINGSEDITORREGISTRY_H + +#include +#include + +#include "qgis_gui.h" +#include "qgis_sip.h" + +class QWidget; +class QgsSettingsEntryBase; +class QgsSettingsEditorWidgetWrapper; + +/** + * \ingroup gui + * \brief This class manages editors for settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsEditorWidgetRegistry +{ + public: + //! Constructor + QgsSettingsEditorWidgetRegistry(); + ~QgsSettingsEditorWidgetRegistry(); + + /** + * Adds a editor to the registry + * Returns FALSE if a editor with same id already exists. + */ + bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper SIP_TRANSFER ); + + //! Returns a new instance of the editor for the given id + QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const; + + //! Creates the editor for the given settings using the corresponding registered wrapper + QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = nullptr ) const SIP_FACTORY; + + //! Returns a map of all registered editors. + QMap editorNames() const; + + + private: + QMap mWrappers; +}; + +#endif // QGSSETTINGSEDITORREGISTRY_H From 07762f5a33d386dff01f94e65e7e049988cefdc4 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:15:57 +0200 Subject: [PATCH 05/20] add tree view + model to show/edit settings values --- src/gui/settings/qgssettingstreemodel.cpp | 426 +++++++++++++++++++++ src/gui/settings/qgssettingstreemodel.h | 206 ++++++++++ src/gui/settings/qgssettingstreewidget.cpp | 48 +++ src/gui/settings/qgssettingstreewidget.h | 51 +++ 4 files changed, 731 insertions(+) create mode 100644 src/gui/settings/qgssettingstreemodel.cpp create mode 100644 src/gui/settings/qgssettingstreemodel.h create mode 100644 src/gui/settings/qgssettingstreewidget.cpp create mode 100644 src/gui/settings/qgssettingstreewidget.h diff --git a/src/gui/settings/qgssettingstreemodel.cpp b/src/gui/settings/qgssettingstreemodel.cpp new file mode 100644 index 00000000000..2bada3c4168 --- /dev/null +++ b/src/gui/settings/qgssettingstreemodel.cpp @@ -0,0 +1,426 @@ +/*************************************************************************** + qgssettingstreemodel.cpp + -------------------------------------- + Date : January 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include "qgssettingstreemodel.h" +#include "qgssettingsentry.h" +#include "qgssettingstreenode.h" +#include "qgssettingseditorwidgetwrapper.h" +#include "qgssettingseditorwidgetregistry.h" +#include "qgsgui.h" +#include "qgslogger.h" + + +QgsSettingsTreeModelNodeData *QgsSettingsTreeModelNodeData::createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent = nullptr ) +{ + QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( parent ); + nodeData->mType = Type::RootNode; + nodeData->mName = rootNode->key(); + nodeData->mTreeNode = rootNode; + nodeData->fillChildren(); + return nodeData; +} + +void QgsSettingsTreeModelNodeData::applyChanges() +{ + switch ( type() ) + { + case Type::NamedListTreeNode: + case Type::RootNode: + case Type::TreeNode: + case Type::NamedListItem: + { + QList::iterator it = mChildren.begin(); + for ( ; it != mChildren.end(); ++it ) + ( *it )->applyChanges(); + break; + } + case Type::Setting: + { + if ( isEdited() ) + { + setting()->setVariantValue( mValue, mNamedParentNodes ); + } + break; + } + } +} + +bool QgsSettingsTreeModelNodeData::setValue( const QVariant &value ) +{ + Q_ASSERT( mType == Type::Setting ); + if ( !value.isValid() && mValue.isValid() ) + { + mExists = false; + mIsEdited = true; + mValue = QVariant(); + } + else if ( !mValue.isValid() || mValue != value ) + { + mValue = value; + mIsEdited = ( value != mOriginalValue ); + } + // TODO: check the value of setting is fullfilling the settings' contraints + return true; +} + + +void QgsSettingsTreeModelNodeData::addChildForTreeNode( const QgsSettingsTreeNode *node ) +{ + QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this ); + nodeData->mParent = this; + nodeData->mNamedParentNodes = mNamedParentNodes; + nodeData->mName = node->key(); + nodeData->mTreeNode = node; + if ( node->type() == Qgis::SettingsTreeNodeType::NamedList ) + { + nodeData->mType = Type::NamedListTreeNode; + const QgsSettingsTreeNamedListNode *nln = dynamic_cast( node ); + const QStringList items = nln->items( mNamedParentNodes ); + for ( const QString &item : items ) + { + nodeData->addChildForNamedListItemNode( item, nln ); + } + } + else + { + nodeData->mType = Type::TreeNode; + nodeData->fillChildren(); + } + mChildren.append( nodeData ); +} + +void QgsSettingsTreeModelNodeData::addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode ) +{ + QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this ); + nodeData->mType = Type::NamedListItem; + nodeData->mParent = this; + nodeData->mNamedParentNodes = mNamedParentNodes; + nodeData->mNamedParentNodes.append( item ); + nodeData->mName = item; + nodeData->mTreeNode = namedListNode; + nodeData->fillChildren(); + mChildren.append( nodeData ); +} + +void QgsSettingsTreeModelNodeData::addChildForSetting( const QgsSettingsEntryBase *setting ) +{ + QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this ); + nodeData->mType = Type::Setting; + nodeData->mParent = this; + nodeData->mNamedParentNodes = mNamedParentNodes; + nodeData->mSetting = setting; + nodeData->mName = setting->name(); + nodeData->mValue = setting->valueAsVariant( mNamedParentNodes ); + nodeData->mOriginalValue = nodeData->mValue; + nodeData->mExists = setting->exists( mNamedParentNodes ); + + switch ( mNamedParentNodes.count() ) + { + case 1: + QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ) ) ); + break; + case 2: + QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ), mNamedParentNodes.at( 1 ) ) ); + break; + case 0: + QgsDebugMsg( QString( "getting %1" ).arg( setting->definitionKey() ) ); + break; + default: + Q_ASSERT( false ); + QgsDebugMsg( QString( "Not handling that many named parent nodes for %1" ).arg( setting->definitionKey() ) ); + break; + } + + mChildren.append( nodeData ); +} + +void QgsSettingsTreeModelNodeData::fillChildren() +{ + const QList childrenNodes = mTreeNode->childrenNodes(); + for ( const QgsSettingsTreeNode *childNode : childrenNodes ) + { + addChildForTreeNode( childNode ); + } + const QList childrenSettings = mTreeNode->childrenSettings(); + for ( const QgsSettingsEntryBase *setting : childrenSettings ) + { + addChildForSetting( setting ); + } +} + + + +QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObject *parent ) + : QAbstractItemModel( parent ) +{ + mRootNode = QgsSettingsTreeModelNodeData::createRootNodeData( rootNode, this ); +} + +QgsSettingsTreeModel::~QgsSettingsTreeModel() +{ + //delete mRootNode; +} + +void QgsSettingsTreeModel::applyChanges() +{ + beginResetModel(); + mRootNode->applyChanges(); + endResetModel(); +} + +QgsSettingsTreeModelNodeData *QgsSettingsTreeModel::index2node( const QModelIndex &index ) const +{ + if ( !index.isValid() ) + return mRootNode; + + QObject *obj = reinterpret_cast( index.internalPointer() ); + return qobject_cast( obj ); +} + + +QModelIndex QgsSettingsTreeModel::index( int row, int column, const QModelIndex &parent ) const +{ + if ( column < 0 || column >= columnCount( parent ) || + row < 0 || row >= rowCount( parent ) ) + return QModelIndex(); + + QgsSettingsTreeModelNodeData *n = index2node( parent ); + if ( !n ) + return QModelIndex(); // have no children + + + return createIndex( row, column, static_cast( n->children().at( row ) ) ); +} + +QModelIndex QgsSettingsTreeModel::parent( const QModelIndex &child ) const +{ + if ( !child.isValid() ) + return QModelIndex(); + + if ( QgsSettingsTreeModelNodeData *n = index2node( child ) ) + { + return indexOfParentSettingsTreeNode( n->parent() ); // must not be null + } + else + { + Q_ASSERT( false ); // no other node types! + return QModelIndex(); + } +} + +QModelIndex QgsSettingsTreeModel::indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const +{ + Q_ASSERT( parentNode ); + + const QgsSettingsTreeModelNodeData *grandParentNode = parentNode->parent(); + if ( !grandParentNode ) + return QModelIndex(); // root node -> invalid index + + int row = grandParentNode->children().indexOf( parentNode ); + Q_ASSERT( row >= 0 ); + + return createIndex( row, 0, static_cast( parentNode ) ); +} + +int QgsSettingsTreeModel::rowCount( const QModelIndex &parent ) const +{ + QgsSettingsTreeModelNodeData *n = index2node( parent ); + if ( !n ) + return 0; + + return n->children().count(); +} + +int QgsSettingsTreeModel::columnCount( const QModelIndex &parent ) const +{ + Q_UNUSED( parent ) + return 3; +} + +QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const +{ + if ( !index.isValid() || index.column() > columnCount( index ) ) + return QVariant(); + + QgsSettingsTreeModelNodeData *node = index2node( index ); + + switch ( static_cast( index.column() ) ) + { + case Column::Name: + { + if ( role == Qt::DisplayRole || role == Qt::EditRole ) + { + return node->name(); + } + break; + } + + case Column::Value: + { + if ( role == Qt::DisplayRole || role == Qt::EditRole ) + { + return node->value(); + } + else if ( role == Qt::FontRole ) + { + if ( !node->exists() ) + { + QFont font; + font.setItalic( true ); + return font; + } + } + else if ( role == Qt::ForegroundRole ) + { + if ( node->isEdited() ) + return QColorConstants::Red; + } + else if ( role == Qt::BackgroundRole ) + { + if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + switch ( node->setting()->settingsType() ) + { + case Qgis::SettingsType::Custom: + case Qgis::SettingsType::Variant: + case Qgis::SettingsType::String: + case Qgis::SettingsType::StringList: + case Qgis::SettingsType::VariantMap: + case Qgis::SettingsType::Bool: + case Qgis::SettingsType::Integer: + case Qgis::SettingsType::Double: + case Qgis::SettingsType::EnumFlag: + break; + + case Qgis::SettingsType::Color: + return node->value(); + } + } + } + break; + } + + case Column::Description: + { + if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + if ( role == Qt::DisplayRole || role == Qt::EditRole ) + { + return node->setting()->description(); + } + } + break; + } + + default: + break; + } + + return QVariant(); +} + + +QVariant QgsSettingsTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const +{ + if ( orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole ) + { + switch ( static_cast( section ) ) + { + case Column::Name: + return tr( "Name" ); + case Column::Value: + return tr( "Value" ); + case Column::Description: + return tr( "Description" ); + }; + } + + return QVariant(); +} + +Qt::ItemFlags QgsSettingsTreeModel::flags( const QModelIndex &index ) const +{ + if ( index.column() == static_cast( Column::Value ) ) + { + QgsSettingsTreeModelNodeData *nodeData = index2node( index ); + if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + return Qt::ItemIsEnabled | Qt::ItemIsEditable; + } + } + else + { + return Qt::ItemIsEnabled; + } + return Qt::NoItemFlags; +} + +bool QgsSettingsTreeModel::setData( const QModelIndex &index, const QVariant &value, int role ) +{ + if ( role == Qt::EditRole && index.column() == static_cast( Column::Value ) ) + { + QgsSettingsTreeModelNodeData *nodeData = index2node( index ); + if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + nodeData->setValue( value ); + emit dataChanged( index, index ); + return true; + } + } + return false; +} + + +QgsSettingsTreeItemDelegate::QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent ) + : QItemDelegate( parent ) + , mModel( model ) +{ +} + +QWidget *QgsSettingsTreeItemDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const +{ + Q_UNUSED( option ) + if ( static_cast( index.column() ) == QgsSettingsTreeModel::Column::Value ) + { + QgsSettingsTreeModelNodeData *nodeData = mModel->index2node( index ); + if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + return QgsGui::settingsEditorWidgetRegistry()->createEditor( nodeData->setting(), nodeData->namedParentNodes(), parent ); + } + } + return nullptr; +} + +void QgsSettingsTreeItemDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const +{ + Q_UNUSED( index ) + QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor ); + if ( eww ) + eww->setWidgetFromVariant( mModel->data( index, Qt::DisplayRole ) ); +} + +void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const +{ + Q_UNUSED( index ) + QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor ); + if ( eww ) + model->setData( index, eww->variantValueFromWidget(), Qt::EditRole ); +} + + + + diff --git a/src/gui/settings/qgssettingstreemodel.h b/src/gui/settings/qgssettingstreemodel.h new file mode 100644 index 00000000000..345ae907625 --- /dev/null +++ b/src/gui/settings/qgssettingstreemodel.h @@ -0,0 +1,206 @@ +/*************************************************************************** + qgssettingstreemodel.h + -------------------------------------- + Date : January 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSTREEMODEL_H +#define QGSSETTINGSTREEMODEL_H + + +#include "qgis_sip.h" +#include "qgis_gui.h" + +#include +#include + +class QgsSettingsEntryBase; +class QgsSettingsTreeNode; +class QgsSettingsTreeModel; +class QgsSettingsTreeNamedListNode; + +#ifndef SIP_RUN + +///@cond PRIVATE + +/** + * \ingroup gui + * \class QgsSettingsTreeNodeData + * \brief QgsSettingsTree holds data of the tree model for the settings tree. + * + * \note Not available in Python bindings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject +{ + Q_OBJECT + public: + + //! Type of tree element + enum class Type + { + RootNode, + TreeNode, + NamedListTreeNode, + NamedListItem, + Setting + }; + + //! Constructor for the tree node data + static QgsSettingsTreeModelNodeData *createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent ); + + //! Apply changes to the settings + void applyChanges(); + + //! Returns if the node is the root node + bool isRoot() const {return mParent == nullptr;} + + //! Returns the dynamic key parts of the named list parent tree nodes + QStringList namedParentNodes() const {return mNamedParentNodes;} + + //! Returns the children nodes of the node (setting or tree node) + QList children() const {return mChildren;} + + //! Returns the parent of the node + QgsSettingsTreeModelNodeData *parent() const {return mParent;} + + //! Returns the type of the node (setting or tree node) + Type type() const {return mType;} + + //! Returns the name of the node (setting or tree node) + QString name() const {return mName;} + + //! Returns the value of the node (setting or tree node) + QVariant value() const {return mValue;} + + //! Returns the value of the node (setting or tree node) + QVariant originalValue() const {return mOriginalValue;} + + //! Sets the value of the setting node + bool setValue( const QVariant &value ); + + //! Returns if the setting exists (value is set) + bool exists() const {return mExists;} + + //! Returns if the setting is edited + bool isEdited() const {return mIsEdited;} + + /** + * Returns the setting of the node + * It returns a nullptr if the setting does not exist + */ + const QgsSettingsEntryBase *setting() const {return mSetting;} + + private: + //! Private constructor, use createRootNodeData instead + QgsSettingsTreeModelNodeData( QObject *parent ) : QObject( parent ) {} + void addChildForTreeNode( const QgsSettingsTreeNode *node ); + void addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode ); + void addChildForSetting( const QgsSettingsEntryBase *setting ); + void fillChildren(); + + Type mType = Type::TreeNode; + QString mName; + QVariant mValue; + QVariant mOriginalValue; + QStringList mNamedParentNodes; + bool mExists = false; + bool mIsEdited = false; + + QList mChildren; + QgsSettingsTreeModelNodeData *mParent = nullptr; + + const QgsSettingsTreeNode *mTreeNode = nullptr; + const QgsSettingsEntryBase *mSetting = nullptr; +}; + + +/** + * \ingroup gui + * \class QgsSettingsTreeItemDelegate + * \brief QgsSettingsTreeItemDelegate allows editing the settings in the settings tree + * + * \note Not available in Python bindings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsTreeItemDelegate : public QItemDelegate +{ + Q_OBJECT + + public: + //! Constructor + explicit QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent = nullptr ); + + 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; + + private: + QgsSettingsTreeModel *mModel = nullptr; +}; + +///@endcond + +#endif + + +/** + * \ingroup gui + * \class QgsSettingsTreeModel + * \brief QgsSettingsTreeModel is a tree model for the settings tree. + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel +{ + public: + + //! Columns + enum class Column + { + Name, //!< Name + Value, //!< Value + Description, //!< Description + }; + + //! Constructor + QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode = nullptr, QObject *parent = nullptr ); + + ~QgsSettingsTreeModel(); + + void applyChanges(); + + /** + * Returns settings tree node for given index. Returns root node for invalid index. + */ + QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP; + + + QModelIndex index( int row, int column, const QModelIndex &parent ) const override; + QModelIndex parent( const QModelIndex &child ) const override; + int rowCount( const QModelIndex &parent ) const override; + int columnCount( const QModelIndex &parent ) const override; + QVariant data( const QModelIndex &index, int role ) const override; + QVariant headerData( int section, Qt::Orientation orientation, int role ) const override; + Qt::ItemFlags flags( const QModelIndex &index ) const override; + bool setData( const QModelIndex &index, const QVariant &value, int role ) override; + + private: + QModelIndex indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const; + + QgsSettingsTreeModelNodeData *mRootNode = nullptr; + +}; + +#endif // QGSSETTINGSTREEMODEL_H diff --git a/src/gui/settings/qgssettingstreewidget.cpp b/src/gui/settings/qgssettingstreewidget.cpp new file mode 100644 index 00000000000..624296c427f --- /dev/null +++ b/src/gui/settings/qgssettingstreewidget.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + qgssettingstreewidget.h + -------------------------------------- + Date : April 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgssettingstreewidget.h" +#include "qgssettingstreemodel.h" +#include "qgssettingstree.h" + +#include +#include +#include +#include + + +QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent ) + : QWidget( parent ) +{ + QVBoxLayout *mainLayout = new QVBoxLayout( this ); + mainLayout->setContentsMargins( 0, 0, 0, 0 ); + + mTreeModel = new QgsSettingsTreeModel( QgsSettingsTree::treeRoot() ); + + mTreeView = new QTreeView( this ); + mTreeView->setModel( mTreeModel ); + mTreeView->setItemDelegate( new QgsSettingsTreeItemDelegate( mTreeModel, this ) ); + mTreeView->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + mTreeView->setMinimumWidth( 400 ); + mTreeView->resizeColumnToContents( 0 ); + + mainLayout->addWidget( mTreeView ); +} + +void QgsSettingsTreeWidget::applyChanges() const +{ + mTreeModel->applyChanges(); +} + diff --git a/src/gui/settings/qgssettingstreewidget.h b/src/gui/settings/qgssettingstreewidget.h new file mode 100644 index 00000000000..d92276c9e1b --- /dev/null +++ b/src/gui/settings/qgssettingstreewidget.h @@ -0,0 +1,51 @@ +/*************************************************************************** + qgssettingstreewidget.h + -------------------------------------- + Date : April 2023 + Copyright : (C) 2023 by Denis Rouzaud + Email : denis@opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSTREEWIDGET_H +#define QGSSETTINGSTREEWIDGET_H + +#include "qgis_gui.h" + +#include "qwidget.h" + +class QTreeView; + +class QgsSettingsTreeModel; + +/** + * \ingroup gui + * \class QgsSettingsTreeWidget + * \brief QgsSettingsTreeWidget is a widget with the settings tree to visualize, search and edit settings + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsTreeWidget : public QWidget +{ + + public: + //! Constructor + explicit QgsSettingsTreeWidget( QWidget *parent = nullptr ); + + + // Apply changes to settings value + void applyChanges() const; + + private: + QgsSettingsTreeModel *mTreeModel = nullptr; + QTreeView *mTreeView = nullptr; + +}; + +#endif // QGSSETTINGSTREEWIDGET_H From 0255230f485bb809dbeac0788729111a89fcbae0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:17:07 +0200 Subject: [PATCH 06/20] use new settings tree in advanced options choice can be made to use the old or new tree also add a hidden setting to bypass warning --- src/app/options/qgsadvancedoptions.cpp | 42 +++++++++++++++++++++----- src/app/options/qgsadvancedoptions.h | 17 ++++++++--- src/app/options/qgsoptions.cpp | 5 --- src/ui/qgsadvancedsettingswidget.ui | 40 +++++++++++++----------- 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/app/options/qgsadvancedoptions.cpp b/src/app/options/qgsadvancedoptions.cpp index 0b248e5bea8..015310fe1dc 100644 --- a/src/app/options/qgsadvancedoptions.cpp +++ b/src/app/options/qgsadvancedoptions.cpp @@ -14,26 +14,41 @@ ***************************************************************************/ #include "qgsadvancedoptions.h" +#include "qgssettingstreewidget.h" +#include "qgssettingstreewidgetold.h" #include "qgsapplication.h" -#include "qgssettings.h" #include "qgis.h" // // QgsAdvancedSettingsWidget // +const QgsSettingsEntryBool *QgsAdvancedSettingsWidget::settingsUseNewTreeWidget = new QgsSettingsEntryBool( QStringLiteral( "use-new-widget" ), sTreeSettings, true, QStringLiteral( "Use new settings widget" ) ); +const QgsSettingsEntryBool *QgsAdvancedSettingsWidget::settingsShowWarning = new QgsSettingsEntryBool( QStringLiteral( "show-warning" ), sTreeSettings, true, QStringLiteral( "Show warning before opening the settings tree" ) ); + QgsAdvancedSettingsWidget::QgsAdvancedSettingsWidget( QWidget *parent ) : QgsOptionsPageWidget( parent ) { setupUi( this ); + mUseNewSettingsTree->setChecked( settingsUseNewTreeWidget->value() ); + layout()->setContentsMargins( 0, 0, 0, 0 ); - connect( mAdvancedSettingsEnableButton, &QPushButton::clicked, this, [ = ] + if ( !settingsShowWarning->value() ) { - mAdvancedSettingsEditor->show(); mAdvancedSettingsWarning->hide(); - } ); + mGroupBox->layout()->addWidget( createSettingsTreeWidget() ); + } + else + { + connect( mAdvancedSettingsEnableButton, &QPushButton::clicked, this, [ = ] + { + settingsUseNewTreeWidget->setValue( mUseNewSettingsTree->isChecked() ); + mAdvancedSettingsWarning->hide(); + mGroupBox->layout()->addWidget( createSettingsTreeWidget() ); + } ); + } } QgsAdvancedSettingsWidget::~QgsAdvancedSettingsWidget() @@ -42,12 +57,25 @@ QgsAdvancedSettingsWidget::~QgsAdvancedSettingsWidget() void QgsAdvancedSettingsWidget::apply() { -// nothing to do -- mAdvancedSettingsEditor applies changes immediately + // mAdvancedSettingsEditor applies changes immediately + // new settings tree is performing changes on appy + if ( mTreeWidget ) + mTreeWidget->applyChanges(); + } -QgsSettingsTreeWidget *QgsAdvancedSettingsWidget::settingsTree() +QWidget *QgsAdvancedSettingsWidget::createSettingsTreeWidget() { - return mAdvancedSettingsEditor; + if ( settingsUseNewTreeWidget->value() ) + { + mTreeWidget = new QgsSettingsTreeWidget( this ); + return mTreeWidget; + } + else + { + return new QgsSettingsTreeWidgetOld( this ); + } + } // diff --git a/src/app/options/qgsadvancedoptions.h b/src/app/options/qgsadvancedoptions.h index 239d9925031..36a922e8f7b 100644 --- a/src/app/options/qgsadvancedoptions.h +++ b/src/app/options/qgsadvancedoptions.h @@ -17,8 +17,10 @@ #include "ui_qgsadvancedsettingswidget.h" #include "qgsoptionswidgetfactory.h" -#include "qgssettings.h" -#include "qgssettingstreewidget.h" +#include "qgssettingstree.h" +#include "qgssettingsentryimpl.h" + +class QgsSettingsTreeWidget; /** * \ingroup app @@ -33,6 +35,11 @@ class QgsAdvancedSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsAd public: + static inline QgsSettingsTreeNode *sTreeSettings = QgsSettingsTree::sTreeApp->createChildNode( QStringLiteral( "settings" ) ); + static const QgsSettingsEntryBool *settingsUseNewTreeWidget; + static const QgsSettingsEntryBool *settingsShowWarning; + + /** * Constructor for QgsAdvancedSettingsWidget with the specified \a parent widget. */ @@ -40,11 +47,11 @@ class QgsAdvancedSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsAd ~QgsAdvancedSettingsWidget() override; void apply() override; - QgsSettingsTreeWidget *settingsTree(); - private: - QgsSettings mSettings; + QWidget *createSettingsTreeWidget(); + + QgsSettingsTreeWidget *mTreeWidget = nullptr; }; diff --git a/src/app/options/qgsoptions.cpp b/src/app/options/qgsoptions.cpp index 56563a254f6..7c675d6e502 100644 --- a/src/app/options/qgsoptions.cpp +++ b/src/app/options/qgsoptions.cpp @@ -1164,11 +1164,6 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListtitle(), factory->title(), factory->icon(), page, factory->path(), factory->key() ); else insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage, factory->path(), factory->key() ); - - if ( QgsAdvancedSettingsWidget *advancedPage = qobject_cast< QgsAdvancedSettingsWidget * >( page ) ) - { - advancedPage->settingsTree()->setSettingsObject( mSettings ); - } } if ( mOptTreeView ) diff --git a/src/ui/qgsadvancedsettingswidget.ui b/src/ui/qgsadvancedsettingswidget.ui index 12c5463c422..42de80b6370 100644 --- a/src/ui/qgsadvancedsettingswidget.ui +++ b/src/ui/qgsadvancedsettingswidget.ui @@ -10,7 +10,13 @@ 610 - + + + 0 + 0 + + + 0 @@ -24,11 +30,17 @@ 0 - + + + + 0 + 0 + + Advanced Settings Editor - + @@ -42,6 +54,13 @@ + + + + Use new settings tree widget (some settings will be missing) + + + @@ -52,26 +71,11 @@ - - - - false - - - - - - QgsSettingsTreeWidget - QWidget -
qgssettingstreewidget.h
- 1 -
-
From 9f3ac79b8ba165fc462497f8b792fe8c9e8a3989 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:19:47 +0200 Subject: [PATCH 07/20] sipify + CMakeLists --- .../settings/qgssettingsentry.sip.in | 226 +++------------- .../settings/qgssettingsentryimpl.sip.in | 80 +++--- .../auto_additions/qgssettingstreemodel.py | 7 + python/gui/auto_generated/qgsgui.sip.in | 8 +- .../qgssettingseditorwidgetregistry.sip.in | 61 +++++ .../qgssettingseditorwidgetwrapper.sip.in | 101 ++++++++ .../qgssettingseditorwidgetwrapperimpl.sip.in | 245 ++++++++++++++++++ .../settings/qgssettingstreemodel.sip.in | 72 +++++ .../settings/qgssettingstreewidget.sip.in | 42 +++ python/gui/gui_auto.sip | 5 + src/gui/CMakeLists.txt | 10 + 11 files changed, 626 insertions(+), 231 deletions(-) create mode 100644 python/gui/auto_additions/qgssettingstreemodel.py create mode 100644 python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in create mode 100644 python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in create mode 100644 python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in create mode 100644 python/gui/auto_generated/settings/qgssettingstreemodel.sip.in create mode 100644 python/gui/auto_generated/settings/qgssettingstreewidget.sip.in diff --git a/python/core/auto_generated/settings/qgssettingsentry.sip.in b/python/core/auto_generated/settings/qgssettingsentry.sip.in index 22e600491d0..30a76693312 100644 --- a/python/core/auto_generated/settings/qgssettingsentry.sip.in +++ b/python/core/auto_generated/settings/qgssettingsentry.sip.in @@ -12,6 +12,8 @@ + + class QgsSettingsEntryBase { %Docstring(signature="appended") @@ -93,6 +95,14 @@ Constructor for QgsSettingsEntryBase. virtual ~QgsSettingsEntryBase(); + virtual QString typeId() const; +%Docstring +Returns the id of the type of settings +This can be re-implemented in a custom implementation of a setting + +.. versionadded:: 3.32 +%End + QString name() const; %Docstring Returns the name of the settings @@ -191,26 +201,21 @@ Returns settings section. The settings section of the parent group is returned i the key is entirely self-defined %End - virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const /Deprecated/; + bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; %Docstring Set settings value. :param value: specifies the value to set. :param dynamicKeyPart: specifies the dynamic part of the settings key. - -.. deprecated:: QGIS 3.26 - use setVariantValuePrivate or an implementation setValue instead %End - virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const /Deprecated/; + bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; %Docstring Set settings value. +This should be called from any implementation as it takes care of actually calling QSettings :param value: specifies the value to set. :param dynamicKeyPartList: specifies the list of dynamic parts of the settings key. - -.. deprecated:: QGIS 3.26 - use setVariantValuePrivate or an implementation setValue instead %End QVariant valueAsVariant( const QString &dynamicKeyPart = QString() ) const; @@ -330,21 +335,15 @@ Returns the parent tree element .. versionadded:: 3.30 %End - protected: - - bool setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList = QStringList() ) const; + virtual bool checkValueVariant( const QVariant &value ) const; %Docstring -Sets the settings value with a variant value. -This should be called from any implementation as it takes care of actually calling QSettings - -.. versionadded:: 3.26 +Returns ``True`` if the given ``value`` is valid towards the setting definition %End }; - template -class QgsSettingsEntryByReference : QgsSettingsEntryBase +class QgsSettingsEntryBaseTemplate : QgsSettingsEntryBase { %Docstring(signature="appended") @@ -362,13 +361,13 @@ Base abstract class for settings entry which are passed by reference %End public: - QgsSettingsEntryByReference( const QString &name, - QgsSettingsTreeNode *parent, - const T &defaultValue, - const QString &description = QString(), - Qgis::SettingsOptions options = Qgis::SettingsOptions() ); + QgsSettingsEntryBaseTemplate( const QString &name, + QgsSettingsTreeNode *parent, + const QVariant &defaultValue, + const QString &description = QString(), + Qgis::SettingsOptions options = Qgis::SettingsOptions() ); %Docstring -Constructor for QgsSettingsEntryByReference. +Constructor for :py:class:`QgsSettingsEntryByReference`. :param name: specifies the key of the settings. :param parent: specifies the parent in the tree of settings. @@ -381,13 +380,13 @@ Constructor for QgsSettingsEntryByReference. .. versionadded:: 3.30 %End - QgsSettingsEntryByReference( const QString &key, - const QString §ion, - const T &defaultValue, - const QString &description = QString(), - Qgis::SettingsOptions options = Qgis::SettingsOptions() ); + QgsSettingsEntryBaseTemplate( const QString &key, + const QString §ion, + const QVariant &defaultValue, + const QString &description = QString(), + Qgis::SettingsOptions options = Qgis::SettingsOptions() ); %Docstring -Constructor for QgsSettingsEntryByReference. +Constructor for :py:class:`QgsSettingsEntryByReference`. :param key: specifies the key of the settings. :param section: specifies the section. @@ -424,22 +423,6 @@ Returns the settings value with a ``defaultValueOverride`` and with an optional Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList`` %End - T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const T &defaultValueOverride ) const /Deprecated/; -%Docstring -Returns the settings value for the ``dynamicKeyPart`` and with a ``defaultValueOverride`` - -.. deprecated:: QGIS 3.26 - use valueAsVariantWithDefaultOverride instead -%End - - T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const T &defaultValueOverride ) const /Deprecated/; -%Docstring -Returns the settings value for the ``dynamicKeyPartList`` and with a ``defaultValueOverride`` - -.. deprecated:: QGIS 3.26 - use valueAsVariantWithDefaultOverride instead -%End - bool setValue( const T &value, const QString &dynamicKeyPart = QString() ) const; %Docstring Set settings value. @@ -473,15 +456,17 @@ Returns the former value Returns the current value (or default) if there is no former value. %End - protected: - bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const; -%Docstring -Sets the settings value with an optional list of dynamic parts -%End + virtual bool checkValueVariant( const QVariant &value ) const; virtual T convertFromVariant( const QVariant &value ) const = 0; %Docstring Converts the variant value to the value type of the setting +%End + + protected: + virtual bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Sets the settings value with an optional list of dynamic parts %End virtual QVariant convertToVariant( const T &value ) const; @@ -489,152 +474,13 @@ Converts the variant value to the value type of the setting Converts the value to a variant %End - virtual bool checkValue( const T &value ) const; + virtual bool checkValuePrivate( const T &value ) const; %Docstring Check if the value is valid %End }; -template -class QgsSettingsEntryByValue : QgsSettingsEntryBase -{ -%Docstring(signature="appended") - -Base abstract class for settings entry which are passed by value - -.. seealso:: :py:class:`QgsSettingsEntryBase` - -.. seealso:: :py:class:`QgsSettingsEntryByReference` - -.. versionadded:: 3.26 -%End - -%TypeHeaderCode -#include "qgssettingsentry.h" -%End - public: - - QgsSettingsEntryByValue( const QString &key, QgsSettingsTreeNode *parent, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ); -%Docstring -Constructor for QgsSettingsEntryByValue. - -:param key: specifies the key of the settings. -:param parent: specifies the parent in the tree of settings. -:param defaultValue: specifies the default value for the settings entry. -:param description: specifies a description for the settings entry. -:param options: specifies the options for the settings entry. - -:raises QgsSettingsException: if the number of given parent named items doesn't match the complete key definition -%End - - QgsSettingsEntryByValue( const QString &key, const QString §ion, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() ); -%Docstring -Constructor for QgsSettingsEntryByValue. - -:param key: specifies the key of the settings. -:param section: specifies the section. -:param defaultValue: specifies the default value for the settings entry. -:param description: specifies a description for the settings entry. -:param options: specifies the options for the settings entry. -%End - - virtual Qgis::SettingsType settingsType() const = 0; - - T value( const QString &dynamicKeyPart = QString() ) const; -%Docstring -Returns settings value. - -:param dynamicKeyPart: specifies the dynamic part of the settings key. -%End - - T value( const QStringList &dynamicKeyPartList ) const; -%Docstring -Returns settings value. - -:param dynamicKeyPartList: specifies the list of dynamic parts of the settings key. -%End - - T valueWithDefaultOverride( T defaultValueOverride, const QString &dynamicKeyPart = QString() ) const; -%Docstring -Returns the settings value with a ``defaultValueOverride`` and with an optional ``dynamicKeyPart`` -%End - - T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const; -%Docstring -Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList`` -%End - - T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, T defaultValueOverride ) const /Deprecated/; -%Docstring -Returns the settings value for the ``dynamicKeyPart`` and with a ``defaultValueOverride`` - -.. deprecated:: QGIS 3.26 - use valueWithDefaultOverride instead -%End - - T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, T defaultValueOverride ) const /Deprecated/; -%Docstring -Returns the settings value for the ``dynamicKeyPartList`` and with a ``defaultValueOverride`` - -.. deprecated:: QGIS 3.26 - use valueWithDefaultOverride instead -%End - - bool setValue( T value, const QString &dynamicKeyPart = QString() ) const; -%Docstring -Set settings value. - -:param value: specifies the value to set. -:param dynamicKeyPart: specifies the dynamic part of the settings key. -%End - - bool setValue( T value, const QStringList &dynamicKeyPartList ) const; -%Docstring -Set settings value. - -:param value: specifies the value to set. -:param dynamicKeyPartList: specifies the list of dynamic parts of the settings key. -%End - - T defaultValue() const; -%Docstring -Returns settings default value. -%End - - T formerValue( const QString &dynamicKeyPart = QString() ) const; -%Docstring -Returns the former value -Returns the current value (or default) if there is no former value. -%End - - T formerValue( const QStringList &dynamicKeyPartList ) const; -%Docstring -Returns the former value -Returns the current value (or default) if there is no former value. -%End - - protected: - virtual bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const; -%Docstring -Sets the settings value with an optional list of dynamic parts -%End - - virtual T convertFromVariant( const QVariant &value ) const = 0; -%Docstring -Converts the variant value to the value type of the setting -%End - - virtual QVariant convertToVariant( T value ) const; -%Docstring -Converts the value to a variant -%End - - virtual bool checkValue( T value ) const; -%Docstring -Check if the value is valid -%End -}; /************************************************************************ diff --git a/python/core/auto_generated/settings/qgssettingsentryimpl.sip.in b/python/core/auto_generated/settings/qgssettingsentryimpl.sip.in index d0e0480be7a..0b465263daf 100644 --- a/python/core/auto_generated/settings/qgssettingsentryimpl.sip.in +++ b/python/core/auto_generated/settings/qgssettingsentryimpl.sip.in @@ -10,9 +10,9 @@ -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQVariantBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQVariantBase; -class QgsSettingsEntryVariant : QgsSettingsEntryByReferenceQVariantBase +class QgsSettingsEntryVariant : QgsSettingsEntryBaseTemplateQVariantBase { %Docstring(signature="appended") @@ -24,7 +24,7 @@ A variant settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQVariantBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQVariantBase; %End public: @@ -107,14 +107,13 @@ Returns settings value. virtual Qgis::SettingsType settingsType() const; - private: virtual QVariant convertFromVariant( const QVariant &value ) const; }; -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQStringBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQStringBase; -class QgsSettingsEntryString : QgsSettingsEntryByReferenceQStringBase +class QgsSettingsEntryString : QgsSettingsEntryBaseTemplateQStringBase { %Docstring(signature="appended") @@ -126,7 +125,7 @@ A string settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQStringBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQStringBase; %End public: @@ -203,18 +202,19 @@ Returns the string minimum length. Returns the string maximum length. By -1 there is no limitation. %End - private: - virtual bool checkValue( const QString &value ) const; - virtual QString convertFromVariant( const QVariant &value ) const; + + private: + virtual bool checkValuePrivate( const QString &value ) const; + }; -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQStringListBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQStringListBase; -class QgsSettingsEntryStringList : QgsSettingsEntryByReferenceQStringListBase +class QgsSettingsEntryStringList : QgsSettingsEntryBaseTemplateQStringListBase { %Docstring(signature="appended") @@ -226,7 +226,7 @@ A string list settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQStringListBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQStringListBase; %End public: @@ -284,16 +284,15 @@ This constructor is intended to be used from plugins. virtual Qgis::SettingsType settingsType() const; - private: virtual QStringList convertFromVariant( const QVariant &value ) const; }; -typedef QgsSettingsEntryByValue QgsSettingsEntryByValueboolBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateboolBase; -class QgsSettingsEntryBool : QgsSettingsEntryByValueboolBase +class QgsSettingsEntryBool : QgsSettingsEntryBaseTemplateboolBase { %Docstring(signature="appended") @@ -305,7 +304,7 @@ A boolean settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByValue QgsSettingsEntryByValueboolBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateboolBase; %End public: @@ -363,16 +362,15 @@ This constructor is intended to be used from plugins. virtual Qgis::SettingsType settingsType() const; - private: virtual bool convertFromVariant( const QVariant &value ) const; }; -typedef QgsSettingsEntryByValue QgsSettingsEntryByValueintBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateintBase; -class QgsSettingsEntryInteger : QgsSettingsEntryByValueintBase +class QgsSettingsEntryInteger : QgsSettingsEntryBaseTemplateintBase { %Docstring(signature="appended") @@ -384,7 +382,7 @@ An integer settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByValue QgsSettingsEntryByValueintBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateintBase; %End public: @@ -463,18 +461,19 @@ Returns the minimum value. Returns the maximum value. %End - private: - virtual bool checkValue( int value ) const; - virtual int convertFromVariant( const QVariant &value ) const; + + private: + virtual bool checkValuePrivate( const int &value ) const; + }; -typedef QgsSettingsEntryByValue QgsSettingsEntryByValuedoubleBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplatedoubleBase; -class QgsSettingsEntryDouble : QgsSettingsEntryByValuedoubleBase +class QgsSettingsEntryDouble : QgsSettingsEntryBaseTemplatedoubleBase { %Docstring(signature="appended") @@ -486,7 +485,7 @@ A double settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByValue QgsSettingsEntryByValuedoubleBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplatedoubleBase; %End public: @@ -586,19 +585,20 @@ displayHintDecimals The number of decimals that should be shown in the Gui. Returns how much decimals should be shown in the Gui. %End - private: - virtual bool checkValue( double value ) const; - virtual double convertFromVariant( const QVariant &value ) const; + + private: + virtual bool checkValuePrivate( const double &value ) const; + }; -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQColorBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQColorBase; -class QgsSettingsEntryColor : QgsSettingsEntryByReferenceQColorBase +class QgsSettingsEntryColor : QgsSettingsEntryBaseTemplateQColorBase { %Docstring(signature="appended") @@ -610,7 +610,7 @@ A color settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQColorBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQColorBase; %End public: @@ -681,18 +681,18 @@ Returns ``True`` if transparency is allowed for the color - - private: virtual QColor convertFromVariant( const QVariant &value ) const; - virtual bool checkValue( const QColor &value ) const; + + private: + virtual bool checkValuePrivate( const QColor &value ) const; }; -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQVariantMapBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQVariantMapBase; -class QgsSettingsEntryVariantMap : QgsSettingsEntryByReferenceQVariantMapBase +class QgsSettingsEntryVariantMap : QgsSettingsEntryBaseTemplateQVariantMapBase { %Docstring(signature="appended") @@ -704,7 +704,7 @@ A string list settings entry. %TypeHeaderCode #include "qgssettingsentryimpl.h" #include "qgssettingsentry.h" -typedef QgsSettingsEntryByReference QgsSettingsEntryByReferenceQVariantMapBase; +typedef QgsSettingsEntryBaseTemplate QgsSettingsEntryBaseTemplateQVariantMapBase; %End public: @@ -762,11 +762,11 @@ This constructor is intended to be used from plugins. virtual Qgis::SettingsType settingsType() const; - private: virtual QVariantMap convertFromVariant( const QVariant &value ) const; }; + /************************************************************************ * This file has been generated automatically from * * * diff --git a/python/gui/auto_additions/qgssettingstreemodel.py b/python/gui/auto_additions/qgssettingstreemodel.py new file mode 100644 index 00000000000..c0416ba40a5 --- /dev/null +++ b/python/gui/auto_additions/qgssettingstreemodel.py @@ -0,0 +1,7 @@ +# The following has been generated automatically from src/gui/settings/qgssettingstreemodel.h +# monkey patching scoped based enum +QgsSettingsTreeModel.Column.Name.__doc__ = "Name" +QgsSettingsTreeModel.Column.Value.__doc__ = "Value" +QgsSettingsTreeModel.Column.Description.__doc__ = "Description" +QgsSettingsTreeModel.Column.__doc__ = 'Columns\n\n' + '* ``Name``: ' + QgsSettingsTreeModel.Column.Name.__doc__ + '\n' + '* ``Value``: ' + QgsSettingsTreeModel.Column.Value.__doc__ + '\n' + '* ``Description``: ' + QgsSettingsTreeModel.Column.Description.__doc__ +# -- diff --git a/python/gui/auto_generated/qgsgui.sip.in b/python/gui/auto_generated/qgsgui.sip.in index 6907c2f9a46..dc59e717514 100644 --- a/python/gui/auto_generated/qgsgui.sip.in +++ b/python/gui/auto_generated/qgsgui.sip.in @@ -10,7 +10,6 @@ - class QgsGui : QObject { %Docstring(signature="appended") @@ -167,6 +166,13 @@ Returns the global relation widget registry, used for managing all known relatio Returns the global history provider registry, used for tracking history providers. .. versionadded:: 3.24 +%End + + static QgsSettingsEditorWidgetRegistry *settingsEditorWidgetRegistry() /KeepReference/; +%Docstring +Returns the registry of settings editors. + +.. versionadded:: 3.32 %End static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() ); diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in new file mode 100644 index 00000000000..50cec15b4ee --- /dev/null +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in @@ -0,0 +1,61 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + +class QgsSettingsEditorWidgetRegistry +{ +%Docstring(signature="appended") +This class manages editors for settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetregistry.h" +%End + public: + QgsSettingsEditorWidgetRegistry(); +%Docstring +Constructor +%End + ~QgsSettingsEditorWidgetRegistry(); + + bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/ ); +%Docstring +Adds a editor to the registry +Returns ``False`` if a editor with same id already exists. +%End + + QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const; +%Docstring +Returns a new instance of the editor for the given id +%End + + QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = 0 ) const /Factory/; +%Docstring +Creates the editor for the given settings using the corresponding registered wrapper +%End + + QMap editorNames() const; +%Docstring +Returns a map of all registered editors. +%End + + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in new file mode 100644 index 00000000000..be8d13ee48a --- /dev/null +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in @@ -0,0 +1,101 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetwrapper.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + +class QgsSettingsEditorWidgetWrapper : QObject +{ +%Docstring(signature="appended") +Base class for settings editor wrappers + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapper.h" +%End + public: + static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) /Factory/; +%Docstring +Creates a wrapper from the definition stored in a widget created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor` +%End + + QgsSettingsEditorWidgetWrapper( QObject *parent = 0 ); +%Docstring +Constructor +%End + + virtual ~QgsSettingsEditorWidgetWrapper(); + + virtual QString id() const = 0; +%Docstring +This id of the type of settings it handles + +.. note:: + + This mostly correspond to the content of :py:class:`Qgis`.SettingsType but it's a string since custom Python implementation are possible. +%End + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0; +%Docstring +Creates a new instance of the editor wrapper so it can be configured for a widget and a setting +%End + + QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = 0 ); +%Docstring +Creates the editor for the given widget +%End + + bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() ); +%Docstring +Configures the ``editor`` according the setting +%End + + virtual bool setWidgetFromSetting() const = 0; +%Docstring +Sets the widget value from the setting value +The wrapper must be configured before calling this medthod +%End + + virtual bool setSettingFromWidget() const = 0; +%Docstring +SDets the setting value from the widget value +The wrapper must be configured before calling this medthod +%End + + virtual QVariant variantValueFromWidget() const = 0; +%Docstring +Returns the value from the widget as a variant +The wrapper must be configured before calling this medthod +%End + + virtual void setWidgetFromVariant( const QVariant &value ) const = 0; +%Docstring +Sets the value of the widget +The wrapper must be configured before calling this medthod +%End + + + protected: + virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0; + + virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; + +}; + + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetwrapper.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in new file mode 100644 index 00000000000..43bea0c56e0 --- /dev/null +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in @@ -0,0 +1,245 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetwrapperimpl.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + + +template +class QgsSettingsEditorWidgetWrapperTemplate : QgsSettingsEditorWidgetWrapper +{ +%Docstring(signature="appended") +This class is a base factory of editor for settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +%End + public: + QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = 0 ); + virtual QString id() const = 0; + + virtual bool setWidgetFromSetting() const; + + virtual bool setSettingFromWidget() const = 0; + + virtual void setWidgetFromVariant( const QVariant &value ) const; + + virtual bool setWidgetValue( const U &value ) const = 0; + + virtual QVariant variantValueFromWidget() const; + + virtual U valueFromWidget() const = 0; + + V *editor() const; +%Docstring +Returns the editor +%End + + const T *setting() const; +%Docstring +Returns the setting +%End + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0; + + protected: + virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const; + + virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ); + + virtual void configureEditorPrivateImplementation(); + +}; + + + +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase; + +class QgsSettingsStringEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase +{ +%Docstring(signature="appended") +This class is a factory of editor for string settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase; +%End + public: + QgsSettingsStringEditorWidgetWrapper( QObject *parent = 0 ); + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const; + + virtual QString id() const; + + + virtual bool setSettingFromWidget() const; + + + virtual QString valueFromWidget() const; + + + virtual bool setWidgetValue( const QString &value ) const; + +}; + + +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase; + +class QgsSettingsBoolEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase +{ +%Docstring(signature="appended") +This class is a factory of editor for boolean settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase; +%End + public: + QgsSettingsBoolEditorWidgetWrapper( QObject *parent = 0 ); + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const; + + virtual QString id() const; + + + virtual bool setSettingFromWidget() const; + + + virtual bool valueFromWidget() const; + + + virtual bool setWidgetValue( const bool &value ) const; + +}; + + +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase; + +class QgsSettingsIntegerEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase +{ +%Docstring(signature="appended") +This class is a factory of editor for integer settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase; +%End + public: + QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = 0 ); + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const; + + virtual QString id() const; + + + virtual bool setSettingFromWidget() const; + + + virtual int valueFromWidget() const; + + + virtual bool setWidgetValue( const int &value ) const; + +}; + + + +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase; + +class QgsSettingsDoubleEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase +{ +%Docstring(signature="appended") +This class is a factory of editor for double settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase; +%End + public: + QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = 0 ); + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const; + + virtual QString id() const; + + + virtual bool setSettingFromWidget() const; + + + virtual double valueFromWidget() const; + + + virtual bool setWidgetValue( const double &value ) const; + +}; + + + +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase; + +class QgsSettingsColorEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase +{ +%Docstring(signature="appended") +This class is a factory of editor for color settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingseditorwidgetwrapperimpl.h" +typedef QgsSettingsEditorWidgetWrapperTemplate QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase; +%End + public: + QgsSettingsColorEditorWidgetWrapper( QObject *parent = 0 ); + + virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const; + + virtual QString id() const; + + + virtual bool setSettingFromWidget() const; + + + virtual QColor valueFromWidget() const; + + + virtual bool setWidgetValue( const QColor &value ) const; + +}; + + + + + + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingseditorwidgetwrapperimpl.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in b/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in new file mode 100644 index 00000000000..11cf47c0297 --- /dev/null +++ b/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in @@ -0,0 +1,72 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingstreemodel.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + + +class QgsSettingsTreeModel : QAbstractItemModel +{ +%Docstring(signature="appended") +:py:class:`QgsSettingsTreeModel` is a tree model for the settings tree. + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingstreemodel.h" +%End + public: + + enum class Column + { + Name, + Value, + Description, + }; + + QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode = 0, QObject *parent = 0 ); +%Docstring +Constructor +%End + + ~QgsSettingsTreeModel(); + + void applyChanges(); + + + + virtual QModelIndex index( int row, int column, const QModelIndex &parent ) const; + + virtual QModelIndex parent( const QModelIndex &child ) const; + + virtual int rowCount( const QModelIndex &parent ) const; + + virtual int columnCount( const QModelIndex &parent ) const; + + virtual QVariant data( const QModelIndex &index, int role ) const; + + virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const; + + virtual Qt::ItemFlags flags( const QModelIndex &index ) const; + + virtual bool setData( const QModelIndex &index, const QVariant &value, int role ); + + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingstreemodel.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in b/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in new file mode 100644 index 00000000000..8bcd7cf3bfe --- /dev/null +++ b/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in @@ -0,0 +1,42 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingstreewidget.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + +class QgsSettingsTreeWidget : QWidget +{ +%Docstring(signature="appended") +:py:class:`QgsSettingsTreeWidget` is a widget with the settings tree to visualize, search and edit settings + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingstreewidget.h" +%End + public: + explicit QgsSettingsTreeWidget( QWidget *parent = 0 ); +%Docstring +Constructor +%End + + + void applyChanges() const; + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/settings/qgssettingstreewidget.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip index 742163c3be3..28156bdfcad 100644 --- a/python/gui/gui_auto.sip +++ b/python/gui/gui_auto.sip @@ -483,7 +483,12 @@ %Include auto_generated/symbology/qgsvectorfieldsymbollayerwidget.sip %Include auto_generated/sensor/qgssensorguiregistry.sip %Include auto_generated/sensor/qgssensorwidget.sip +%Include auto_generated/settings/qgssettingseditorwidgetwrapper.sip +%Include auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip +%Include auto_generated/settings/qgssettingseditorwidgetregistry.sip %Include auto_generated/settings/qgssettingsregistrygui.sip +%Include auto_generated/settings/qgssettingstreemodel.sip +%Include auto_generated/settings/qgssettingstreewidget.sip %Include auto_generated/tableeditor/qgstableeditordialog.sip %Include auto_generated/tableeditor/qgstableeditorwidget.sip %Include auto_generated/vectortile/qgsvectortilelayerproperties.sip diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 38e2af3d6b3..2f328d62cf8 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -438,7 +438,12 @@ set(QGIS_GUI_SRCS sensor/qgssensorguiregistry.cpp sensor/qgssensorwidget.cpp + settings/qgssettingseditorwidgetwrapper.cpp + settings/qgssettingseditorwidgetwrapperimpl.cpp + settings/qgssettingseditorwidgetregistry.cpp settings/qgssettingsregistrygui.cpp + settings/qgssettingstreemodel.cpp + settings/qgssettingstreewidget.cpp tableeditor/qgstableeditordialog.cpp tableeditor/qgstableeditorformattingwidget.cpp @@ -1428,7 +1433,12 @@ set(QGIS_GUI_HDRS sensor/qgssensorguiregistry.h sensor/qgssensorwidget.h + settings/qgssettingseditorwidgetwrapper.h + settings/qgssettingseditorwidgetwrapperimpl.h + settings/qgssettingseditorwidgetregistry.h settings/qgssettingsregistrygui.h + settings/qgssettingstreemodel.h + settings/qgssettingstreewidget.h tableeditor/qgstableeditordialog.h tableeditor/qgstableeditorformattingwidget.h From 92a00151ccd6e0773c9e30918c89e27597f62735 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 07:47:08 +0200 Subject: [PATCH 08/20] fix dox --- src/gui/settings/qgssettingstreemodel.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/settings/qgssettingstreemodel.cpp b/src/gui/settings/qgssettingstreemodel.cpp index 2bada3c4168..abc941eddd3 100644 --- a/src/gui/settings/qgssettingstreemodel.cpp +++ b/src/gui/settings/qgssettingstreemodel.cpp @@ -23,6 +23,8 @@ #include "qgsgui.h" #include "qgslogger.h" +///@cond PRIVATE + QgsSettingsTreeModelNodeData *QgsSettingsTreeModelNodeData::createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent = nullptr ) { @@ -162,6 +164,8 @@ void QgsSettingsTreeModelNodeData::fillChildren() } } +///@endcond + QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObject *parent ) @@ -385,6 +389,9 @@ bool QgsSettingsTreeModel::setData( const QModelIndex &index, const QVariant &va } +///@cond PRIVATE + + QgsSettingsTreeItemDelegate::QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent ) : QItemDelegate( parent ) , mModel( model ) @@ -421,6 +428,7 @@ void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemMo model->setData( index, eww->variantValueFromWidget(), Qt::EditRole ); } +///@endcond From de1363df05a232bfba9609d90983114badb2745e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 08:04:21 +0200 Subject: [PATCH 09/20] use opactify in colorbutton when possible --- .../qgssettingseditorwidgetwrapperimpl.sip.in | 6 ++++++ .../settings/qgssettingseditorwidgetwrapperimpl.cpp | 12 ++++++++++++ .../settings/qgssettingseditorwidgetwrapperimpl.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in index 43bea0c56e0..0c573b3288e 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in @@ -59,6 +59,9 @@ Returns the setting virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ); virtual void configureEditorPrivateImplementation(); +%Docstring +To be re-implemented to implemeent type specific configuration (e.g. opacity for colors) +%End }; @@ -228,6 +231,9 @@ typedef QgsSettingsEditorWidgetWrapperTemplatesetAllowOpacity( mSetting->allowAlpha() ); + } + else + { + QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) ); + } +} + bool QgsSettingsColorEditorWidgetWrapper::setSettingFromWidget() const { if ( mEditor ) diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h index 63afb7f06ea..cda7b8dcad2 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h @@ -103,6 +103,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEdit return false; } + //! To be re-implemented to implemeent type specific configuration (e.g. opacity for colors) virtual void configureEditorPrivateImplementation() {} const T *mSetting = nullptr; @@ -225,6 +226,8 @@ class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorW QColor valueFromWidget() const override; bool setWidgetValue( const QColor &value ) const override; + + void configureEditorPrivateImplementation() override; }; ///** From 7498d0994cdd82e66232e753df788a8ff484f43e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 23 Apr 2023 08:10:37 +0200 Subject: [PATCH 10/20] fix dox --- .../settings/qgssettingsentry.sip.in | 6 ++--- .../qgssettingseditorwidgetwrapper.sip.in | 6 +++++ .../qgssettingseditorwidgetwrapperimpl.sip.in | 24 +++++++++++++++++++ .../settings/qgssettingstreemodel.sip.in | 3 +++ .../settings/qgssettingstreewidget.sip.in | 3 +++ src/app/options/qgsadvancedoptions.cpp | 4 ++-- src/core/settings/qgssettingsentry.h | 7 +++--- .../qgssettingseditorwidgetregistry.cpp | 6 +---- .../qgssettingseditorwidgetregistry.h | 10 ++++---- .../qgssettingseditorwidgetwrapper.cpp | 2 +- .../settings/qgssettingseditorwidgetwrapper.h | 10 ++++---- .../qgssettingseditorwidgetwrapperimpl.h | 8 +++++++ src/gui/settings/qgssettingstreemodel.h | 13 +++++----- src/gui/settings/qgssettingstreewidget.h | 2 +- 14 files changed, 72 insertions(+), 32 deletions(-) diff --git a/python/core/auto_generated/settings/qgssettingsentry.sip.in b/python/core/auto_generated/settings/qgssettingsentry.sip.in index 30a76693312..407a9f3a302 100644 --- a/python/core/auto_generated/settings/qgssettingsentry.sip.in +++ b/python/core/auto_generated/settings/qgssettingsentry.sip.in @@ -347,13 +347,11 @@ class QgsSettingsEntryBaseTemplate : QgsSettingsEntryBase { %Docstring(signature="appended") -Base abstract class for settings entry which are passed by reference +Base abstract class for settings entries with typed get and set methods .. seealso:: :py:class:`QgsSettingsEntryBase` -.. seealso:: :py:class:`QgsSettingsEntryByValue` - -.. versionadded:: 3.26 +.. versionadded:: 3.32 %End %TypeHeaderCode diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in index be8d13ee48a..994d78ca4ac 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in @@ -85,8 +85,14 @@ The wrapper must be configured before calling this medthod protected: virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0; +%Docstring +Creates the widgets +%End virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; +%Docstring +Configures an existing widget +%End }; diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in index 0c573b3288e..0fdf25d3540 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip.in @@ -27,6 +27,9 @@ This class is a base factory of editor for settings %End public: QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = 0 ); +%Docstring +Constructor +%End virtual QString id() const = 0; virtual bool setWidgetFromSetting() const; @@ -36,10 +39,16 @@ This class is a base factory of editor for settings virtual void setWidgetFromVariant( const QVariant &value ) const; virtual bool setWidgetValue( const U &value ) const = 0; +%Docstring +Sets the widget value +%End virtual QVariant variantValueFromWidget() const; virtual U valueFromWidget() const = 0; +%Docstring +Returns the widget value +%End V *editor() const; %Docstring @@ -83,6 +92,9 @@ typedef QgsSettingsEditorWidgetWrapperTemplateapplyChanges(); diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index 8faca8034d4..3c04924a106 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -353,13 +353,12 @@ class CORE_EXPORT QgsSettingsEntryBase /** * \ingroup core - * \class QgsSettingsEntryByReference + * \class QgsSettingsEntryBaseTemplate * - * \brief Base abstract class for settings entry which are passed by reference + * \brief Base abstract class for settings entries with typed get and set methods * \see QgsSettingsEntryBase - * \see QgsSettingsEntryByValue * - * \since QGIS 3.26 + * \since QGIS 3.32 */ template class QgsSettingsEntryBaseTemplate : public QgsSettingsEntryBase diff --git a/src/gui/settings/qgssettingseditorwidgetregistry.cpp b/src/gui/settings/qgssettingseditorwidgetregistry.cpp index 345173b3271..a5d11debbe2 100644 --- a/src/gui/settings/qgssettingseditorwidgetregistry.cpp +++ b/src/gui/settings/qgssettingseditorwidgetregistry.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgssettingsfactoryfactoryregistry.cpp + qgssettingseditorwidgetregistry.cpp --------------------- begin : April 2023 copyright : (C) 2023 by Denis Rouzaud @@ -66,7 +66,3 @@ QWidget *QgsSettingsEditorWidgetRegistry::createEditor( const QgsSettingsEntryBa else return nullptr; } - - - - diff --git a/src/gui/settings/qgssettingseditorwidgetregistry.h b/src/gui/settings/qgssettingseditorwidgetregistry.h index 4461c7e3a2a..03935c925c0 100644 --- a/src/gui/settings/qgssettingseditorwidgetregistry.h +++ b/src/gui/settings/qgssettingseditorwidgetregistry.h @@ -28,7 +28,7 @@ class QgsSettingsEditorWidgetWrapper; /** * \ingroup gui - * \brief This class manages editors for settings + * \brief This class manages editor widgets for settings * * \since QGIS 3.32 */ @@ -40,15 +40,15 @@ class GUI_EXPORT QgsSettingsEditorWidgetRegistry ~QgsSettingsEditorWidgetRegistry(); /** - * Adds a editor to the registry - * Returns FALSE if a editor with same id already exists. + * Adds an editor widget \a wrapper to the registry + * Returns FALSE if an editor widget with same id already exists. */ bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper SIP_TRANSFER ); - //! Returns a new instance of the editor for the given id + //! Returns a new instance of the editor widget for the given \a id QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const; - //! Creates the editor for the given settings using the corresponding registered wrapper + //! Creates an editor widget for the given \a setting using the corresponding registered wrapper QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = nullptr ) const SIP_FACTORY; //! Returns a map of all registered editors. diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.cpp b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp index a15a90807b9..144ce2f7734 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapper.cpp +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.cpp @@ -44,7 +44,7 @@ QWidget *QgsSettingsEditorWidgetWrapper::createEditor( const QgsSettingsEntryBas if ( configureEditor( editor, setting, dynamicKeyPartList ) ) return editor; else - QgsDebugMsg( QStringLiteral( "editor could not be confiugured" ) ); + QgsDebugMsg( QStringLiteral( "editor could not be configured" ) ); return nullptr; } diff --git a/src/gui/settings/qgssettingseditorwidgetwrapper.h b/src/gui/settings/qgssettingseditorwidgetwrapper.h index 5ecf842d188..db6b85d49cf 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapper.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapper.h @@ -33,7 +33,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject { Q_OBJECT public: - //! Creates a wrapper from the definition stored in a widget created by createEditor() + //! Creates a wrapper from the definition stored in a \a widget created by createEditor() static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) SIP_FACTORY; //! Constructor @@ -50,7 +50,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject //! Creates a new instance of the editor wrapper so it can be configured for a widget and a setting virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const = 0; -//! Creates the editor for the given widget + //! Creates the editor widget for the given \a setting QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = nullptr ); //! Configures the \a editor according the setting @@ -63,7 +63,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject virtual bool setWidgetFromSetting() const = 0; /** - * SDets the setting value from the widget value + * Sets the setting value from the widget value * The wrapper must be configured before calling this medthod */ virtual bool setSettingFromWidget() const = 0; @@ -75,15 +75,17 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject virtual QVariant variantValueFromWidget() const = 0; /** - * Sets the value of the widget + * Sets the \a value of the widget * The wrapper must be configured before calling this medthod */ virtual void setWidgetFromVariant( const QVariant &value ) const = 0; protected: + //! Creates the widgets virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const = 0; + //! Configures an existing \a editor widget virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; QStringList mDynamicKeyPartList; diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h index cda7b8dcad2..056225c6407 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h @@ -45,6 +45,7 @@ template class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEditorWidgetWrapper { public: + //! Constructor QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapper( parent ) {} @@ -66,6 +67,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEdit setWidgetValue( mSetting->convertFromVariant( value ) ); } + //! Sets the widget value virtual bool setWidgetValue( const U &value ) const = 0; QVariant variantValueFromWidget() const override @@ -73,6 +75,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEdit return valueFromWidget(); }; + //! Returns the widget value virtual U valueFromWidget() const = 0; //! Returns the editor @@ -120,6 +123,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEdit class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { public: + //! Constructor QgsSettingsStringEditorWidgetWrapper( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} @@ -143,6 +147,7 @@ class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditor class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { public: + //! Constructor QgsSettingsBoolEditorWidgetWrapper( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} @@ -166,6 +171,7 @@ class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWi class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { public: + //! Constructor QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} @@ -190,6 +196,7 @@ class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEdito class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { public: + //! Constructor QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} @@ -214,6 +221,7 @@ class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditor class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { public: + //! Constructor QgsSettingsColorEditorWidgetWrapper( QObject *parent = nullptr ) : QgsSettingsEditorWidgetWrapperTemplate( parent ) {} diff --git a/src/gui/settings/qgssettingstreemodel.h b/src/gui/settings/qgssettingstreemodel.h index 345ae907625..f645bb241d6 100644 --- a/src/gui/settings/qgssettingstreemodel.h +++ b/src/gui/settings/qgssettingstreemodel.h @@ -63,10 +63,10 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject void applyChanges(); //! Returns if the node is the root node - bool isRoot() const {return mParent == nullptr;} + bool isRoot() const { return mParent == nullptr; } //! Returns the dynamic key parts of the named list parent tree nodes - QStringList namedParentNodes() const {return mNamedParentNodes;} + QStringList namedParentNodes() const { return mNamedParentNodes; } //! Returns the children nodes of the node (setting or tree node) QList children() const {return mChildren;} @@ -86,7 +86,7 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject //! Returns the value of the node (setting or tree node) QVariant originalValue() const {return mOriginalValue;} - //! Sets the value of the setting node + //! Sets the \a value of the setting node bool setValue( const QVariant &value ); //! Returns if the setting exists (value is set) @@ -96,8 +96,8 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject bool isEdited() const {return mIsEdited;} /** - * Returns the setting of the node - * It returns a nullptr if the setting does not exist + * Returns a pointer to the setting of the node or NULLPTR if the + * setting does not exist. */ const QgsSettingsEntryBase *setting() const {return mSetting;} @@ -179,10 +179,11 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel ~QgsSettingsTreeModel(); + //! Apply pending changes in the model to the corresponding settings void applyChanges(); /** - * Returns settings tree node for given index. Returns root node for invalid index. + * Returns settings tree node for given \a index or the root node if the index is invalid. */ QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP; diff --git a/src/gui/settings/qgssettingstreewidget.h b/src/gui/settings/qgssettingstreewidget.h index d92276c9e1b..fde47cb5de2 100644 --- a/src/gui/settings/qgssettingstreewidget.h +++ b/src/gui/settings/qgssettingstreewidget.h @@ -39,7 +39,7 @@ class GUI_EXPORT QgsSettingsTreeWidget : public QWidget explicit QgsSettingsTreeWidget( QWidget *parent = nullptr ); - // Apply changes to settings value + //! Apply changes to settings value void applyChanges() const; private: From 83d735fbcf466febcfbf63758273b45efa2eb054 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 10:34:02 +0200 Subject: [PATCH 11/20] refactor QgsOptionsDialogHighlighWidget to use it as an interface by removing the inheritance of QObject, an implementation of QWidget can now also inherit from QgsOptionsDialogHighlighWidget and provide the interface to search/highlight texts --- .../qgsoptionsdialoghighlightwidget.sip.in | 11 +++-- src/gui/qgsoptionsdialogbase.cpp | 34 +++++++------- src/gui/qgsoptionsdialoghighlightwidget.cpp | 44 ++++++++++++------- src/gui/qgsoptionsdialoghighlightwidget.h | 42 ++++++++++++++---- .../qgsoptionsdialoghighlightwidgetsimpl.cpp | 2 - .../qgsoptionsdialoghighlightwidgetsimpl.h | 6 --- 6 files changed, 86 insertions(+), 53 deletions(-) diff --git a/python/gui/auto_generated/qgsoptionsdialoghighlightwidget.sip.in b/python/gui/auto_generated/qgsoptionsdialoghighlightwidget.sip.in index 36bbfca9ad9..b2d3895f8ab 100644 --- a/python/gui/auto_generated/qgsoptionsdialoghighlightwidget.sip.in +++ b/python/gui/auto_generated/qgsoptionsdialoghighlightwidget.sip.in @@ -9,7 +9,9 @@ -class QgsOptionsDialogHighlightWidget : QObject + + +class QgsOptionsDialogHighlightWidget { %Docstring(signature="appended") Container for a widget to be used to search text in the option dialog @@ -34,6 +36,8 @@ For instance a :py:class:`QgsOptionsDialogHighlightButton` for button. for the given widget. %End + virtual ~QgsOptionsDialogHighlightWidget(); + bool isValid(); %Docstring Returns if it valid: if the widget type is handled and if the widget is not still available @@ -51,11 +55,6 @@ search for a text pattern and highlight the widget if the text is found Returns the widget %End - - virtual bool eventFilter( QObject *obj, QEvent *event ); - - - protected: virtual bool searchText( const QString &text ) = 0; diff --git a/src/gui/qgsoptionsdialogbase.cpp b/src/gui/qgsoptionsdialogbase.cpp index 49c2c9bf867..576d80a434e 100644 --- a/src/gui/qgsoptionsdialogbase.cpp +++ b/src/gui/qgsoptionsdialogbase.cpp @@ -33,7 +33,6 @@ #include #include "qgsfilterlineedit.h" -#include "qgsmessagebaritem.h" #include "qgslogger.h" #include "qgsoptionsdialoghighlightwidget.h" #include "qgsoptionswidgetfactory.h" @@ -652,31 +651,34 @@ void QgsOptionsDialogBase::registerTextSearchWidgets() for ( int i = 0; i < mOptStackedWidget->count(); i++ ) { - const QList< QWidget * > widgets = mOptStackedWidget->widget( i )->findChildren(); - for ( QWidget *w : widgets ) + for ( QWidget *widget : widgets ) { - // get custom highlight widget in user added pages - QHash customHighlightWidgets; - QgsOptionsPageWidget *opw = qobject_cast( mOptStackedWidget->widget( i ) ); - if ( opw ) + // see if the widget also inherits QgsOptionsDialogHighlightWidget + QgsOptionsDialogHighlightWidget *shw = dynamic_cast( widget ); + if ( !shw ) { - customHighlightWidgets = opw->registeredHighlightWidgets(); - } - QgsOptionsDialogHighlightWidget *shw = nullptr; - // take custom if exists - if ( customHighlightWidgets.contains( w ) ) - { - shw = customHighlightWidgets.value( w ); + // get custom highlight widget in user added pages + QHash customHighlightWidgets; + QgsOptionsPageWidget *opw = qobject_cast( mOptStackedWidget->widget( i ) ); + if ( opw ) + { + customHighlightWidgets = opw->registeredHighlightWidgets(); + } + // take custom if exists + if ( customHighlightWidgets.contains( widget ) ) + { + shw = customHighlightWidgets.value( widget ); + } } // try to construct one otherwise if ( !shw || !shw->isValid() ) { - shw = QgsOptionsDialogHighlightWidget::createWidget( w ); + shw = QgsOptionsDialogHighlightWidget::createWidget( widget ); } if ( shw && shw->isValid() ) { - QgsDebugMsgLevel( QStringLiteral( "Registering: %1" ).arg( w->objectName() ), 4 ); + QgsDebugMsgLevel( QStringLiteral( "Registering: %1" ).arg( widget->objectName() ), 4 ); mRegisteredSearchWidgets.append( qMakePair( shw, i ) ); } else diff --git a/src/gui/qgsoptionsdialoghighlightwidget.cpp b/src/gui/qgsoptionsdialoghighlightwidget.cpp index 8727d2bcf0f..3a3bab10286 100644 --- a/src/gui/qgsoptionsdialoghighlightwidget.cpp +++ b/src/gui/qgsoptionsdialoghighlightwidget.cpp @@ -33,8 +33,7 @@ QgsOptionsDialogHighlightWidget::QgsOptionsDialogHighlightWidget( QWidget *widget ) - : QObject( widget ) - , mWidget( widget ) + : mWidget( widget ) {} QgsOptionsDialogHighlightWidget *QgsOptionsDialogHighlightWidget::createWidget( QWidget *widget ) @@ -52,6 +51,11 @@ QgsOptionsDialogHighlightWidget *QgsOptionsDialogHighlightWidget::createWidget( } } + if ( dynamic_cast( widget ) ) + { + return dynamic_cast( widget ); + } + if ( qobject_cast( widget ) ) { return new QgsOptionsDialogHighlightLabel( qobject_cast( widget ) ); @@ -97,15 +101,16 @@ bool QgsOptionsDialogHighlightWidget::searchHighlight( const QString &text ) mChangedStyle = false; } - if ( mInstalledFilter ) + if ( mEventFilter ) { - mWidget->removeEventFilter( this ); - mInstalledFilter = false; + mWidget->removeEventFilter( mEventFilter ); + delete mEventFilter; + mEventFilter = nullptr; } if ( !text.isEmpty() ) { - found = searchText( text ); + found = searchText( mSearchText ); } if ( found ) @@ -113,30 +118,38 @@ bool QgsOptionsDialogHighlightWidget::searchHighlight( const QString &text ) if ( !mWidget->isVisible() ) { - mWidget->installEventFilter( this ); - mInstalledFilter = true; + mEventFilter = new QgsOptionsDialogHighlightWidgetEventFilter( this ); + mWidget->installEventFilter( mEventFilter ); } else { - mChangedStyle = highlightText( text ); + mChangedStyle = highlightText( mSearchText ); } } return found; } -bool QgsOptionsDialogHighlightWidget::eventFilter( QObject *obj, QEvent *event ) + + +///@cond PRIVATE + +QgsOptionsDialogHighlightWidgetEventFilter::QgsOptionsDialogHighlightWidgetEventFilter( QgsOptionsDialogHighlightWidget *highlightWidget ) + : QObject( highlightWidget->widget() ) + , mHighlightWidget( highlightWidget ) +{} + +bool QgsOptionsDialogHighlightWidgetEventFilter::eventFilter( QObject *obj, QEvent *event ) { - if ( mInstalledFilter && event->type() == QEvent::Show && obj == mWidget ) + if ( event->type() == QEvent::Show && obj == mHighlightWidget->widget() ) { - mWidget->removeEventFilter( this ); - mInstalledFilter = false; + mHighlightWidget->widget()->removeEventFilter( this ); // instead of catching the event and calling show again // it might be better to use a timer to change the style // after the widget is shown #if 1 - mWidget->show(); - mChangedStyle = highlightText( mSearchText ); + mHighlightWidget->widget()->show(); + mHighlightWidget->mChangedStyle = mHighlightWidget->highlightText( mHighlightWidget->mSearchText ); return true; #else QTimer::singleShot( 500, this, [ = ] @@ -148,5 +161,6 @@ bool QgsOptionsDialogHighlightWidget::eventFilter( QObject *obj, QEvent *event ) return QObject::eventFilter( obj, event ); } +///@endcond diff --git a/src/gui/qgsoptionsdialoghighlightwidget.h b/src/gui/qgsoptionsdialoghighlightwidget.h index 7576b203374..36435fbf7e7 100644 --- a/src/gui/qgsoptionsdialoghighlightwidget.h +++ b/src/gui/qgsoptionsdialoghighlightwidget.h @@ -23,6 +23,34 @@ #include "qgis_gui.h" #include "qgis_sip.h" +class QgsOptionsDialogHighlightWidget; + +#ifndef SIP_RUN + +///@cond PRIVATE + +/** + * \ingroup gui + * \class QgsOptionsDialogHighlightWidgetEventFilter + * \brief QgsOptionsDialogHighlightWidgetEventFilter is an event filter implementation for QgsOptionsDialogHighlightWidget + * \since QGIS 3.32 + */ +class QgsOptionsDialogHighlightWidgetEventFilter : public QObject +{ + Q_OBJECT + public: + //! Constructor + QgsOptionsDialogHighlightWidgetEventFilter( QgsOptionsDialogHighlightWidget *highlightWidget ); + bool eventFilter( QObject *obj, QEvent *event ) override; + private: + QgsOptionsDialogHighlightWidget *mHighlightWidget; + +}; + +///@endcond + +#endif + /** * \ingroup gui * \class QgsOptionsDialogHighlightWidget @@ -32,10 +60,8 @@ * This uses stylesheets. * \since QGIS 3.0 */ -class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject +class GUI_EXPORT QgsOptionsDialogHighlightWidget { - - Q_OBJECT public: /** @@ -46,6 +72,8 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject */ static QgsOptionsDialogHighlightWidget *createWidget( QWidget *widget ) SIP_FACTORY; + virtual ~QgsOptionsDialogHighlightWidget() = default; + /** * Returns if it valid: if the widget type is handled and if the widget is not still available */ @@ -62,10 +90,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject */ QWidget *widget() {return mWidget;} - - bool eventFilter( QObject *obj, QEvent *event ) override; - - protected: /** @@ -94,9 +118,11 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject QPointer< QWidget > mWidget; private: + friend class QgsOptionsDialogHighlightWidgetEventFilter; + QString mSearchText = QString(); bool mChangedStyle = false; - bool mInstalledFilter = false; + QgsOptionsDialogHighlightWidgetEventFilter *mEventFilter = nullptr; }; #endif // QGSOPTIONSDIALOGHIGHLIGHTWIDGET_H diff --git a/src/gui/qgsoptionsdialoghighlightwidgetsimpl.cpp b/src/gui/qgsoptionsdialoghighlightwidgetsimpl.cpp index 5af4f561fd0..c0d4e456ba6 100644 --- a/src/gui/qgsoptionsdialoghighlightwidgetsimpl.cpp +++ b/src/gui/qgsoptionsdialoghighlightwidgetsimpl.cpp @@ -26,8 +26,6 @@ #include #include "qgsoptionsdialoghighlightwidget.h" -#include "qgsmessagebaritem.h" -#include "qgslogger.h" #include "qgsoptionsdialoghighlightwidgetsimpl.h" diff --git a/src/gui/qgsoptionsdialoghighlightwidgetsimpl.h b/src/gui/qgsoptionsdialoghighlightwidgetsimpl.h index d274accd52c..e7944e66b83 100644 --- a/src/gui/qgsoptionsdialoghighlightwidgetsimpl.h +++ b/src/gui/qgsoptionsdialoghighlightwidgetsimpl.h @@ -43,7 +43,6 @@ class QTableView; */ class GUI_EXPORT QgsOptionsDialogHighlightLabel : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a label QgsOptionsDialogHighlightLabel( QLabel *label ); @@ -64,7 +63,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightLabel : public QgsOptionsDialogHighlig */ class GUI_EXPORT QgsOptionsDialogHighlightCheckBox : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a checkbox QgsOptionsDialogHighlightCheckBox( QCheckBox *checkBox ); @@ -85,7 +83,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightCheckBox : public QgsOptionsDialogHigh */ class GUI_EXPORT QgsOptionsDialogHighlightButton : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a button. QgsOptionsDialogHighlightButton( QAbstractButton *button ); @@ -106,7 +103,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightButton : public QgsOptionsDialogHighli */ class GUI_EXPORT QgsOptionsDialogHighlightGroupBox : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a group box. QgsOptionsDialogHighlightGroupBox( QGroupBox *groupBox ); @@ -129,7 +125,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightGroupBox : public QgsOptionsDialogHigh */ class GUI_EXPORT QgsOptionsDialogHighlightTree : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a tree view or widget. QgsOptionsDialogHighlightTree( QTreeView *treeView ); @@ -152,7 +147,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightTree : public QgsOptionsDialogHighligh */ class GUI_EXPORT QgsOptionsDialogHighlightTable : public QgsOptionsDialogHighlightWidget { - Q_OBJECT public: //! constructs a highlight widget for a table view or widget. QgsOptionsDialogHighlightTable( QTableView *tableView ); From 2d28f1ec941b2dc3ab9316d7dacb07d4681e70eb Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 10:34:50 +0200 Subject: [PATCH 12/20] create settings trees on start so texts can be searched --- src/app/options/qgsadvancedoptions.cpp | 29 ++++++++++++++++++-------- src/app/options/qgsadvancedoptions.h | 5 +++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/app/options/qgsadvancedoptions.cpp b/src/app/options/qgsadvancedoptions.cpp index 0bd29f919bd..1e4b650e3b1 100644 --- a/src/app/options/qgsadvancedoptions.cpp +++ b/src/app/options/qgsadvancedoptions.cpp @@ -38,15 +38,21 @@ QgsAdvancedSettingsWidget::QgsAdvancedSettingsWidget( QWidget *parent ) if ( !settingsShowWarning->value() ) { mAdvancedSettingsWarning->hide(); - mGroupBox->layout()->addWidget( createSettingsTreeWidget() ); + bool newTree = settingsUseNewTreeWidget->value(); + createSettingsTreeWidget( newTree, !newTree, false ); } else { + createSettingsTreeWidget( true, true, true ); + connect( mAdvancedSettingsEnableButton, &QPushButton::clicked, this, [ = ] { settingsUseNewTreeWidget->setValue( mUseNewSettingsTree->isChecked() ); mAdvancedSettingsWarning->hide(); - mGroupBox->layout()->addWidget( createSettingsTreeWidget() ); + if ( settingsUseNewTreeWidget->value() ) + mTreeWidget->show(); + else + mTreeWidgetOld->show(); } ); } } @@ -64,18 +70,23 @@ void QgsAdvancedSettingsWidget::apply() } -QWidget *QgsAdvancedSettingsWidget::createSettingsTreeWidget() +void QgsAdvancedSettingsWidget::createSettingsTreeWidget( bool newWidget, bool oldWidget, bool hide ) { - if ( settingsUseNewTreeWidget->value() ) + if ( newWidget ) { mTreeWidget = new QgsSettingsTreeWidget( this ); - return mTreeWidget; - } - else - { - return new QgsSettingsTreeWidgetOld( this ); + mGroupBox->layout()->addWidget( mTreeWidget ); + if ( hide ) + mTreeWidget->hide(); } + if ( oldWidget ) + { + mTreeWidgetOld = new QgsSettingsTreeWidgetOld( this ); + mGroupBox->layout()->addWidget( mTreeWidgetOld ); + if ( hide ) + mTreeWidgetOld->hide(); + } } // diff --git a/src/app/options/qgsadvancedoptions.h b/src/app/options/qgsadvancedoptions.h index 36a922e8f7b..856c7b43cb4 100644 --- a/src/app/options/qgsadvancedoptions.h +++ b/src/app/options/qgsadvancedoptions.h @@ -21,6 +21,7 @@ #include "qgssettingsentryimpl.h" class QgsSettingsTreeWidget; +class QgsSettingsTreeWidgetOld; /** * \ingroup app @@ -48,10 +49,10 @@ class QgsAdvancedSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsAd void apply() override; private: - - QWidget *createSettingsTreeWidget(); + void createSettingsTreeWidget( bool newWidget, bool oldWidget, bool hide ); QgsSettingsTreeWidget *mTreeWidget = nullptr; + QgsSettingsTreeWidgetOld *mTreeWidgetOld = nullptr; }; From 0b8ef936753cbe376d1195d47c00c8386e021e08 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 10:35:11 +0200 Subject: [PATCH 13/20] add proxy model to filter the settings tree --- .../settings/qgssettingstreemodel.sip.in | 36 +++++++++ .../settings/qgssettingstreewidget.sip.in | 10 ++- src/gui/settings/qgssettingstreemodel.cpp | 75 +++++++++++++++++++ src/gui/settings/qgssettingstreemodel.h | 37 +++++++++ src/gui/settings/qgssettingstreewidget.cpp | 24 +++++- src/gui/settings/qgssettingstreewidget.h | 15 +++- 6 files changed, 190 insertions(+), 7 deletions(-) diff --git a/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in b/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in index ae0d278ccd9..f16d6bf0250 100644 --- a/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in +++ b/python/gui/auto_generated/settings/qgssettingstreemodel.sip.in @@ -47,6 +47,7 @@ Apply pending changes in the model to the corresponding settings + virtual QModelIndex index( int row, int column, const QModelIndex &parent ) const; virtual QModelIndex parent( const QModelIndex &child ) const; @@ -64,6 +65,41 @@ Apply pending changes in the model to the corresponding settings virtual bool setData( const QModelIndex &index, const QVariant &value, int role ); +}; + +class QgsSettingsTreeProxyModel : QSortFilterProxyModel +{ +%Docstring(signature="appended") +:py:class:`QgsSettingsTreeProxyModel` allows filtering the settings tree + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgssettingstreemodel.h" +%End + public: + QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode = 0, QObject *parent = 0 ); +%Docstring +Constructor +%End + + void applyChanges(); +%Docstring +Apply pending changes in the model to the corresponding settings +%End + + public slots: + void setFilterText( const QString &filterText = QString() ); +%Docstring +Sets the filter text +%End + + + protected: + virtual bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const; + + }; /************************************************************************ diff --git a/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in b/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in index b939b4db0c1..2027bf167cb 100644 --- a/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in +++ b/python/gui/auto_generated/settings/qgssettingstreewidget.sip.in @@ -11,7 +11,8 @@ -class QgsSettingsTreeWidget : QWidget + +class QgsSettingsTreeWidget : QWidget, QgsOptionsDialogHighlightWidget { %Docstring(signature="appended") :py:class:`QgsSettingsTreeWidget` is a widget with the settings tree to visualize, search and edit settings @@ -34,6 +35,13 @@ Constructor Apply changes to settings value %End + protected: + virtual bool searchText( const QString &text ); + + virtual bool highlightText( const QString &text ); + + virtual void reset(); + }; /************************************************************************ diff --git a/src/gui/settings/qgssettingstreemodel.cpp b/src/gui/settings/qgssettingstreemodel.cpp index abc941eddd3..90ce98b93c8 100644 --- a/src/gui/settings/qgssettingstreemodel.cpp +++ b/src/gui/settings/qgssettingstreemodel.cpp @@ -195,6 +195,18 @@ QgsSettingsTreeModelNodeData *QgsSettingsTreeModel::index2node( const QModelInde return qobject_cast( obj ); } +QModelIndex QgsSettingsTreeModel::node2index( QgsSettingsTreeModelNodeData *node ) const +{ + if ( !node || !node->parent() ) + return QModelIndex(); // this is the only root item -> invalid index + + QModelIndex parentIndex = node2index( node->parent() ); + + int row = node->parent()->children().indexOf( node ); + Q_ASSERT( row >= 0 ); + return index( row, static_cast( Column::Name ), parentIndex ); +} + QModelIndex QgsSettingsTreeModel::index( int row, int column, const QModelIndex &parent ) const { @@ -432,3 +444,66 @@ void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemMo + + +QgsSettingsTreeProxyModel::QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode, QObject *parent ) + : QSortFilterProxyModel( parent ) +{ + mSourceModel = new QgsSettingsTreeModel( rootNode, parent ); + QSortFilterProxyModel::setSourceModel( mSourceModel ); +} + +void QgsSettingsTreeProxyModel::setFilterText( const QString &filterText ) +{ + if ( filterText == mFilterText ) + return; + + mFilterText = filterText; + invalidateFilter(); +} + +bool QgsSettingsTreeProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const +{ + QgsSettingsTreeModelNodeData *node = mSourceModel->index2node( mSourceModel->index( source_row, static_cast( QgsSettingsTreeModel::Column::Name ), source_parent ) ); + return nodeShown( node ); +} + +bool QgsSettingsTreeProxyModel::nodeShown( QgsSettingsTreeModelNodeData *node ) const +{ + if ( !node ) + return false; + if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + if ( node->name().contains( mFilterText, Qt::CaseInsensitive ) ) + return true; + + // also returns settings for which the parent nodes have a match + QModelIndex index = mSourceModel->node2index( node ).parent(); + while ( ( index.isValid() ) ) + { + QgsSettingsTreeModelNodeData *parentNode = mSourceModel->index2node( mSourceModel->index( index.row(), static_cast( QgsSettingsTreeModel::Column::Name ), index.parent() ) ); + if ( parentNode->name().contains( mFilterText, Qt::CaseInsensitive ) ) + return true; + + index = index.parent(); + } + return false; + } + else + { + // show all children if name of node matches + if ( node->name().contains( mFilterText, Qt::CaseInsensitive ) ) + return true; + + const auto constChildren = node->children(); + for ( QgsSettingsTreeModelNodeData *child : constChildren ) + { + if ( nodeShown( child ) ) + { + return true; + } + } + return false; + } +} + diff --git a/src/gui/settings/qgssettingstreemodel.h b/src/gui/settings/qgssettingstreemodel.h index f645bb241d6..aeb690c9bdf 100644 --- a/src/gui/settings/qgssettingstreemodel.h +++ b/src/gui/settings/qgssettingstreemodel.h @@ -21,6 +21,7 @@ #include "qgis_gui.h" #include +#include #include class QgsSettingsEntryBase; @@ -164,6 +165,7 @@ class GUI_EXPORT QgsSettingsTreeItemDelegate : public QItemDelegate */ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel { + Q_OBJECT public: //! Columns @@ -187,6 +189,9 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel */ QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP; + //! Returns the index from the settings tree node + QModelIndex node2index( QgsSettingsTreeModelNodeData *node ) const SIP_SKIP; + QModelIndex index( int row, int column, const QModelIndex &parent ) const override; QModelIndex parent( const QModelIndex &child ) const override; @@ -204,4 +209,36 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel }; +/** + * \ingroup gui + * \class QgsSettingsTreeProxyModel + * \brief QgsSettingsTreeProxyModel allows filtering the settings tree + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsSettingsTreeProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + public: + //! Constructor + QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode = nullptr, QObject *parent = nullptr ); + + //! Apply pending changes in the model to the corresponding settings + void applyChanges() {mSourceModel->applyChanges();} + + public slots: + //! Sets the filter text + void setFilterText( const QString &filterText = QString() ); + + + protected: + bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const override; + + private: + QgsSettingsTreeModel *mSourceModel = nullptr; + + bool nodeShown( QgsSettingsTreeModelNodeData *node ) const; + QString mFilterText; +}; + #endif // QGSSETTINGSTREEMODEL_H diff --git a/src/gui/settings/qgssettingstreewidget.cpp b/src/gui/settings/qgssettingstreewidget.cpp index 624296c427f..8f7c25cff84 100644 --- a/src/gui/settings/qgssettingstreewidget.cpp +++ b/src/gui/settings/qgssettingstreewidget.cpp @@ -25,15 +25,18 @@ QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent ) : QWidget( parent ) + , QgsOptionsDialogHighlightWidget( this ) { + setObjectName( QStringLiteral( "mSettingsTreeWidget" ) ); + QVBoxLayout *mainLayout = new QVBoxLayout( this ); mainLayout->setContentsMargins( 0, 0, 0, 0 ); - mTreeModel = new QgsSettingsTreeModel( QgsSettingsTree::treeRoot() ); + mTreeModel = new QgsSettingsTreeProxyModel( QgsSettingsTree::treeRoot() ); mTreeView = new QTreeView( this ); mTreeView->setModel( mTreeModel ); - mTreeView->setItemDelegate( new QgsSettingsTreeItemDelegate( mTreeModel, this ) ); + mTreeView->setItemDelegate( new QgsSettingsTreeItemDelegate( qobject_cast( mTreeModel->sourceModel() ), parent ) ); mTreeView->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); mTreeView->setMinimumWidth( 400 ); mTreeView->resizeColumnToContents( 0 ); @@ -46,3 +49,20 @@ void QgsSettingsTreeWidget::applyChanges() const mTreeModel->applyChanges(); } + +bool QgsSettingsTreeWidget::searchText( const QString &text ) +{ + mTreeModel->setFilterText( text ); + return mTreeModel->rowCount() > 0; +} + +bool QgsSettingsTreeWidget::highlightText( const QString &text ) +{ + Q_UNUSED( text ); + return true; +} + +void QgsSettingsTreeWidget::reset() +{ + mTreeModel->setFilterText( QString() ); +} diff --git a/src/gui/settings/qgssettingstreewidget.h b/src/gui/settings/qgssettingstreewidget.h index fde47cb5de2..738c6e021d0 100644 --- a/src/gui/settings/qgssettingstreewidget.h +++ b/src/gui/settings/qgssettingstreewidget.h @@ -18,11 +18,12 @@ #include "qgis_gui.h" -#include "qwidget.h" +#include "qgsoptionsdialoghighlightwidget.h" + class QTreeView; -class QgsSettingsTreeModel; +class QgsSettingsTreeProxyModel; /** * \ingroup gui @@ -31,7 +32,7 @@ class QgsSettingsTreeModel; * * \since QGIS 3.32 */ -class GUI_EXPORT QgsSettingsTreeWidget : public QWidget +class GUI_EXPORT QgsSettingsTreeWidget : public QWidget, public QgsOptionsDialogHighlightWidget { public: @@ -43,9 +44,15 @@ class GUI_EXPORT QgsSettingsTreeWidget : public QWidget void applyChanges() const; private: - QgsSettingsTreeModel *mTreeModel = nullptr; + QgsSettingsTreeProxyModel *mTreeModel = nullptr; QTreeView *mTreeView = nullptr; + + // QgsOptionsDialogHighlightWidget interface + protected: + bool searchText( const QString &text ) override; + bool highlightText( const QString &text ) override; + void reset() override; }; #endif // QGSSETTINGSTREEWIDGET_H From feb9b44cc0b20bd433b981fa9430378a57783092 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 10:38:48 +0200 Subject: [PATCH 14/20] sipify --- .../settings/qgssettingseditorwidgetregistry.sip.in | 10 +++++----- .../settings/qgssettingseditorwidgetwrapper.sip.in | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in index 50cec15b4ee..e1822db024a 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in @@ -13,7 +13,7 @@ class QgsSettingsEditorWidgetRegistry { %Docstring(signature="appended") -This class manages editors for settings +This class manages editor widgets for settings .. versionadded:: 3.32 %End @@ -30,18 +30,18 @@ Constructor bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/ ); %Docstring -Adds a editor to the registry -Returns ``False`` if a editor with same id already exists. +Adds an editor widget ``wrapper`` to the registry +Returns ``False`` if an editor widget with same id already exists. %End QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const; %Docstring -Returns a new instance of the editor for the given id +Returns a new instance of the editor widget for the given ``id`` %End QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = 0 ) const /Factory/; %Docstring -Creates the editor for the given settings using the corresponding registered wrapper +Creates an editor widget for the given ``setting`` using the corresponding registered wrapper %End QMap editorNames() const; diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in index 994d78ca4ac..6d55ca21645 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetwrapper.sip.in @@ -24,7 +24,7 @@ Base class for settings editor wrappers public: static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) /Factory/; %Docstring -Creates a wrapper from the definition stored in a widget created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor` +Creates a wrapper from the definition stored in a ``widget`` created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor` %End QgsSettingsEditorWidgetWrapper( QObject *parent = 0 ); @@ -50,7 +50,7 @@ Creates a new instance of the editor wrapper so it can be configured for a widge QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = 0 ); %Docstring -Creates the editor for the given widget +Creates the editor widget for the given ``setting`` %End bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() ); @@ -66,7 +66,7 @@ The wrapper must be configured before calling this medthod virtual bool setSettingFromWidget() const = 0; %Docstring -SDets the setting value from the widget value +Sets the setting value from the widget value The wrapper must be configured before calling this medthod %End @@ -78,7 +78,7 @@ The wrapper must be configured before calling this medthod virtual void setWidgetFromVariant( const QVariant &value ) const = 0; %Docstring -Sets the value of the widget +Sets the ``value`` of the widget The wrapper must be configured before calling this medthod %End @@ -91,7 +91,7 @@ Creates the widgets virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0; %Docstring -Configures an existing widget +Configures an existing ``editor`` widget %End }; From cb42a20a38f1b3f1eaeb82769be37610224d5aae Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 21:00:18 +0200 Subject: [PATCH 15/20] use checkbox for booleans + palette for colors --- src/gui/settings/qgssettingstreemodel.cpp | 106 +++++++++++++++++----- src/gui/settings/qgssettingstreemodel.h | 16 ++-- 2 files changed, 91 insertions(+), 31 deletions(-) diff --git a/src/gui/settings/qgssettingstreemodel.cpp b/src/gui/settings/qgssettingstreemodel.cpp index 90ce98b93c8..ab7091bd2cd 100644 --- a/src/gui/settings/qgssettingstreemodel.cpp +++ b/src/gui/settings/qgssettingstreemodel.cpp @@ -13,6 +13,7 @@ * * ***************************************************************************/ +#include #include #include "qgssettingstreemodel.h" @@ -75,7 +76,7 @@ bool QgsSettingsTreeModelNodeData::setValue( const QVariant &value ) mValue = value; mIsEdited = ( value != mOriginalValue ); } - // TODO: check the value of setting is fullfilling the settings' contraints + // TODO: check the value of setting is fullfilling the settings' contraints ? return true; } @@ -172,6 +173,11 @@ QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObje : QAbstractItemModel( parent ) { mRootNode = QgsSettingsTreeModelNodeData::createRootNodeData( rootNode, this ); + + QPalette pal = qApp->palette(); + mEditedColorBack = pal.color( QPalette::Active, QPalette::Mid ); + mEditedColorFore = pal.color( QPalette::Active, QPalette::BrightText ); + mNotSetColor = pal.color( QPalette::Disabled, QPalette::WindowText ); } QgsSettingsTreeModel::~QgsSettingsTreeModel() @@ -274,6 +280,31 @@ QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const QgsSettingsTreeModelNodeData *node = index2node( index ); + if ( role == Qt::ForegroundRole && node->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + if ( !node->exists() ) + { + // settings not yet set + return mNotSetColor; + } + + if ( node->isEdited() && + ( node->setting()->settingsType() != Qgis::SettingsType::Color || index.column() != static_cast( Column::Value ) ) ) + { + return mEditedColorFore; + } + } + + if ( role == Qt::BackgroundRole && node->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + // background for edited settings (except colors) + if ( node->isEdited() && + ( node->setting()->settingsType() != Qgis::SettingsType::Color || index.column() != static_cast( Column::Value ) ) ) + { + return mEditedColorBack; + } + } + switch ( static_cast( index.column() ) ) { case Column::Name: @@ -287,23 +318,27 @@ QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const case Column::Value: { - if ( role == Qt::DisplayRole || role == Qt::EditRole ) + if ( role == Qt::CheckStateRole ) { - return node->value(); - } - else if ( role == Qt::FontRole ) - { - if ( !node->exists() ) + if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting && + node->setting()->settingsType() == Qgis::SettingsType::Bool ) { - QFont font; - font.setItalic( true ); - return font; + // special handling of bool setting to show combobox + return node->value().toBool() ? Qt::Checked : Qt::Unchecked; } } - else if ( role == Qt::ForegroundRole ) + if ( role == Qt::DisplayRole || role == Qt::EditRole ) { - if ( node->isEdited() ) - return QColorConstants::Red; + if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting && + node->setting()->settingsType() == Qgis::SettingsType::Bool ) + { + // special handling of bool setting to show combobox + return QString(); + } + else + { + return node->value(); + } } else if ( role == Qt::BackgroundRole ) { @@ -345,7 +380,6 @@ QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const default: break; } - return QVariant(); } @@ -375,7 +409,14 @@ Qt::ItemFlags QgsSettingsTreeModel::flags( const QModelIndex &index ) const QgsSettingsTreeModelNodeData *nodeData = index2node( index ); if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) { - return Qt::ItemIsEnabled | Qt::ItemIsEditable; + if ( nodeData->setting()->settingsType() == Qgis::SettingsType::Bool ) + { + return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled; + } + else + { + return Qt::ItemIsEnabled | Qt::ItemIsEditable; + } } } else @@ -387,14 +428,25 @@ Qt::ItemFlags QgsSettingsTreeModel::flags( const QModelIndex &index ) const bool QgsSettingsTreeModel::setData( const QModelIndex &index, const QVariant &value, int role ) { - if ( role == Qt::EditRole && index.column() == static_cast( Column::Value ) ) + if ( index.column() == static_cast( Column::Value ) ) { - QgsSettingsTreeModelNodeData *nodeData = index2node( index ); - if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + if ( role == Qt::EditRole || role == Qt::CheckStateRole ) { - nodeData->setValue( value ); - emit dataChanged( index, index ); - return true; + QgsSettingsTreeModelNodeData *nodeData = index2node( index ); + if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) + { + if ( role == Qt::CheckStateRole ) + { + Q_ASSERT( nodeData->setting()->settingsType() == Qgis::SettingsType::Bool ); + nodeData->setValue( value == Qt::Checked ? true : false ); + } + else + { + nodeData->setValue( value ); + } + emit dataChanged( index.siblingAtColumn( 0 ), index.siblingAtColumn( columnCount( index.parent() ) - 1 ) ); + return true; + } } } return false; @@ -415,7 +467,13 @@ QWidget *QgsSettingsTreeItemDelegate::createEditor( QWidget *parent, const QStyl Q_UNUSED( option ) if ( static_cast( index.column() ) == QgsSettingsTreeModel::Column::Value ) { - QgsSettingsTreeModelNodeData *nodeData = mModel->index2node( index ); + QModelIndex sourceIndex = index; + const QgsSettingsTreeProxyModel *proxyModel = qobject_cast( index.model() ); + if ( proxyModel ) + { + sourceIndex = proxyModel->mapToSource( index ); + } + QgsSettingsTreeModelNodeData *nodeData = mModel->index2node( sourceIndex ); if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting ) { return QgsGui::settingsEditorWidgetRegistry()->createEditor( nodeData->setting(), nodeData->namedParentNodes(), parent ); @@ -426,15 +484,13 @@ QWidget *QgsSettingsTreeItemDelegate::createEditor( QWidget *parent, const QStyl void QgsSettingsTreeItemDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const { - Q_UNUSED( index ) QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor ); if ( eww ) - eww->setWidgetFromVariant( mModel->data( index, Qt::DisplayRole ) ); + eww->setWidgetFromVariant( index.model()->data( index, Qt::DisplayRole ) ); } void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const { - Q_UNUSED( index ) QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor ); if ( eww ) model->setData( index, eww->variantValueFromWidget(), Qt::EditRole ); diff --git a/src/gui/settings/qgssettingstreemodel.h b/src/gui/settings/qgssettingstreemodel.h index aeb690c9bdf..1a89a03dbbb 100644 --- a/src/gui/settings/qgssettingstreemodel.h +++ b/src/gui/settings/qgssettingstreemodel.h @@ -64,10 +64,10 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject void applyChanges(); //! Returns if the node is the root node - bool isRoot() const { return mParent == nullptr; } + bool isRoot() const {return mParent == nullptr;} //! Returns the dynamic key parts of the named list parent tree nodes - QStringList namedParentNodes() const { return mNamedParentNodes; } + QStringList namedParentNodes() const {return mNamedParentNodes;} //! Returns the children nodes of the node (setting or tree node) QList children() const {return mChildren;} @@ -87,7 +87,7 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject //! Returns the value of the node (setting or tree node) QVariant originalValue() const {return mOriginalValue;} - //! Sets the \a value of the setting node + //! Sets the value of the setting node bool setValue( const QVariant &value ); //! Returns if the setting exists (value is set) @@ -97,8 +97,8 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject bool isEdited() const {return mIsEdited;} /** - * Returns a pointer to the setting of the node or NULLPTR if the - * setting does not exist. + * Returns the setting of the node + * It returns a nullptr if the setting does not exist */ const QgsSettingsEntryBase *setting() const {return mSetting;} @@ -185,7 +185,7 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel void applyChanges(); /** - * Returns settings tree node for given \a index or the root node if the index is invalid. + * Returns settings tree node for given index. Returns root node for invalid index. */ QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP; @@ -207,6 +207,10 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel QgsSettingsTreeModelNodeData *mRootNode = nullptr; + QColor mEditedColorBack; + QColor mEditedColorFore; + QColor mNotSetColor; + }; /** From 429c740b5bcdc3c7853c9be0925decca61943841 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 10:27:01 +0200 Subject: [PATCH 16/20] Apply suggestions from code review Co-authored-by: Mathieu Pellerin --- src/gui/settings/qgssettingstreemodel.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/settings/qgssettingstreemodel.h b/src/gui/settings/qgssettingstreemodel.h index 1a89a03dbbb..073c25aba26 100644 --- a/src/gui/settings/qgssettingstreemodel.h +++ b/src/gui/settings/qgssettingstreemodel.h @@ -64,10 +64,10 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject void applyChanges(); //! Returns if the node is the root node - bool isRoot() const {return mParent == nullptr;} + bool isRoot() const { return mParent == nullptr; } //! Returns the dynamic key parts of the named list parent tree nodes - QStringList namedParentNodes() const {return mNamedParentNodes;} + QStringList namedParentNodes() const { return mNamedParentNodes; } //! Returns the children nodes of the node (setting or tree node) QList children() const {return mChildren;} @@ -87,7 +87,7 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject //! Returns the value of the node (setting or tree node) QVariant originalValue() const {return mOriginalValue;} - //! Sets the value of the setting node + //! Sets the \a value of the setting node bool setValue( const QVariant &value ); //! Returns if the setting exists (value is set) @@ -97,8 +97,8 @@ class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject bool isEdited() const {return mIsEdited;} /** - * Returns the setting of the node - * It returns a nullptr if the setting does not exist + * Returns a pointer to the setting of the node or NULLPTR if the + * setting does not exist. */ const QgsSettingsEntryBase *setting() const {return mSetting;} @@ -185,7 +185,7 @@ class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel void applyChanges(); /** - * Returns settings tree node for given index. Returns root node for invalid index. + * Returns settings tree node for given \a index or the root node if the index is invalid. */ QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP; From 2033624f622ee726dc8a1cf338001903748868d4 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Apr 2023 21:35:06 +0200 Subject: [PATCH 17/20] better dark theme + fix typo --- src/gui/settings/qgssettingstreemodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/settings/qgssettingstreemodel.cpp b/src/gui/settings/qgssettingstreemodel.cpp index ab7091bd2cd..1592daadd57 100644 --- a/src/gui/settings/qgssettingstreemodel.cpp +++ b/src/gui/settings/qgssettingstreemodel.cpp @@ -76,7 +76,7 @@ bool QgsSettingsTreeModelNodeData::setValue( const QVariant &value ) mValue = value; mIsEdited = ( value != mOriginalValue ); } - // TODO: check the value of setting is fullfilling the settings' contraints ? + // TODO: check the value of setting is fulfilling the settings' contsraints ? return true; } @@ -175,7 +175,7 @@ QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObje mRootNode = QgsSettingsTreeModelNodeData::createRootNodeData( rootNode, this ); QPalette pal = qApp->palette(); - mEditedColorBack = pal.color( QPalette::Active, QPalette::Mid ); + mEditedColorBack = pal.color( QPalette::Active, QPalette::Dark ); mEditedColorFore = pal.color( QPalette::Active, QPalette::BrightText ); mNotSetColor = pal.color( QPalette::Disabled, QPalette::WindowText ); } From a97b33d1aeae520a0ac35d010aef624302bc62ad Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 28 Apr 2023 08:08:34 +0200 Subject: [PATCH 18/20] add missing Q_OBJECT macro --- src/gui/settings/qgssettingseditorwidgetwrapperimpl.h | 5 +++++ src/gui/settings/qgssettingstreewidget.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h index 056225c6407..00664471fb8 100644 --- a/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h +++ b/src/gui/settings/qgssettingseditorwidgetwrapperimpl.h @@ -122,6 +122,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEdit */ class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { + Q_OBJECT public: //! Constructor QgsSettingsStringEditorWidgetWrapper( QObject *parent = nullptr ) @@ -146,6 +147,7 @@ class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditor */ class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { + Q_OBJECT public: //! Constructor QgsSettingsBoolEditorWidgetWrapper( QObject *parent = nullptr ) @@ -170,6 +172,7 @@ class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWi */ class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { + Q_OBJECT public: //! Constructor QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = nullptr ) @@ -195,6 +198,7 @@ class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEdito */ class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { + Q_OBJECT public: //! Constructor QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = nullptr ) @@ -220,6 +224,7 @@ class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditor */ class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate { + Q_OBJECT public: //! Constructor QgsSettingsColorEditorWidgetWrapper( QObject *parent = nullptr ) diff --git a/src/gui/settings/qgssettingstreewidget.h b/src/gui/settings/qgssettingstreewidget.h index 738c6e021d0..13086fc3484 100644 --- a/src/gui/settings/qgssettingstreewidget.h +++ b/src/gui/settings/qgssettingstreewidget.h @@ -34,7 +34,7 @@ class QgsSettingsTreeProxyModel; */ class GUI_EXPORT QgsSettingsTreeWidget : public QWidget, public QgsOptionsDialogHighlightWidget { - + Q_OBJECT public: //! Constructor explicit QgsSettingsTreeWidget( QWidget *parent = nullptr ); From de02e8899c864be9d427af1dc6eb60c982d176ee Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Sun, 30 Apr 2023 15:34:32 +0200 Subject: [PATCH 19/20] remove useless method --- .../settings/qgssettingseditorwidgetregistry.sip.in | 6 ------ src/gui/settings/qgssettingseditorwidgetregistry.h | 4 ---- 2 files changed, 10 deletions(-) diff --git a/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in index e1822db024a..ac0c8882e21 100644 --- a/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in +++ b/python/gui/auto_generated/settings/qgssettingseditorwidgetregistry.sip.in @@ -44,12 +44,6 @@ Returns a new instance of the editor widget for the given ``id`` Creates an editor widget for the given ``setting`` using the corresponding registered wrapper %End - QMap editorNames() const; -%Docstring -Returns a map of all registered editors. -%End - - }; /************************************************************************ diff --git a/src/gui/settings/qgssettingseditorwidgetregistry.h b/src/gui/settings/qgssettingseditorwidgetregistry.h index 03935c925c0..e3223f79f9c 100644 --- a/src/gui/settings/qgssettingseditorwidgetregistry.h +++ b/src/gui/settings/qgssettingseditorwidgetregistry.h @@ -51,10 +51,6 @@ class GUI_EXPORT QgsSettingsEditorWidgetRegistry //! Creates an editor widget for the given \a setting using the corresponding registered wrapper QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = nullptr ) const SIP_FACTORY; - //! Returns a map of all registered editors. - QMap editorNames() const; - - private: QMap mWrappers; }; From d888ee2a702da257d8d67e7dfae4ec1f2c67980e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 1 May 2023 09:57:09 +0200 Subject: [PATCH 20/20] use public method --- python/core/additions/qgssettingsentry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/core/additions/qgssettingsentry.py b/python/core/additions/qgssettingsentry.py index 1a74f56dbd5..4b119a69d18 100644 --- a/python/core/additions/qgssettingsentry.py +++ b/python/core/additions/qgssettingsentry.py @@ -132,7 +132,7 @@ class PyQgsSettingsEntryEnumFlag(QgsSettingsEntryBase): elif dynamicKeyPart is None: dynamicKeyPart = [] - return super().setVariantValuePrivate(enum_flag_key, dynamicKeyPart) + return super().setVariantValue(enum_flag_key, dynamicKeyPart) def settingsType(self): """