diff --git a/python/core/__init__.py.in b/python/core/__init__.py.in index 77e240a55595..76eb01d58c74 100644 --- a/python/core/__init__.py.in +++ b/python/core/__init__.py.in @@ -34,6 +34,7 @@ from .additions.qgsfeature import mapping_feature from .additions.qgsfunction import register_function, qgsfunction from .additions.qgsgeometry import _geometryNonZero, mapping_geometry from .additions.qgssettings import _qgssettings_enum_value, _qgssettings_set_enum_value, _qgssettings_flag_value +from .additions.qgssettingsentry import PyQgsSettingsEntryEnum, PyQgsSettingsEntryFlag from .additions.qgstaskwrapper import QgsTaskWrapper from .additions.readwritecontextentercategory import ReadWriteContextEnterCategory from .additions.runtimeprofiler import ScopedRuntimeProfileContextManager @@ -57,6 +58,10 @@ QgsTask.fromFunction = fromFunction QgsDateTimeRange.__repr__ = datetime_range_repr QgsDateRange.__repr__ = date_range_repr +# Classes patched +QgsSettingsEntryEnum = PyQgsSettingsEntryEnum +QgsSettingsEntryFlag = PyQgsSettingsEntryFlag + # Classes patched using a derived class QgsProviderMetadata = PyProviderMetadata diff --git a/python/core/additions/qgssettings.py b/python/core/additions/qgssettings.py index 655cddffa04d..570e92febdc2 100644 --- a/python/core/additions/qgssettings.py +++ b/python/core/additions/qgssettings.py @@ -110,7 +110,7 @@ def _qgssettings_flag_value(self, key, flagDefaultValue, section=QgsSettings.NoS # this should not happen raise ValueError("could not get the meta enum for given enum default value (type: {})".format(type(flagDefaultValue))) - str_val = self.value(key, meta_enum.valueToKey(flagDefaultValue), str, section) + str_val = self.value(key, meta_enum.valueToKeys(flagDefaultValue), str, section) # need a new meta enum as QgsSettings.value is making a copy and leads to seg fault (probably a PyQt issue) meta_enum_2 = metaEnumFromValue(flagDefaultValue) (flag_val, ok) = meta_enum_2.keysToValue(str_val) diff --git a/python/core/additions/qgssettingsentry.py b/python/core/additions/qgssettingsentry.py new file mode 100644 index 000000000000..447a8228b3ab --- /dev/null +++ b/python/core/additions/qgssettingsentry.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + qgssettingsentry.py + --------------------- + Date : April 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano@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. * +* * +*************************************************************************** +""" + +from .metaenum import metaEnumFromValue +from qgis.core import QgsSettings, QgsSettingsEntryBase, QgsLogger +import qgis # required to get base class of enums + + +class _PyQgsSettingsEntryEnumFlag(QgsSettingsEntryBase): + """ class QgsSettingsEntryEnum + ingroup core + An enum settings entry. + since QGIS 3.20 + """ + + def __init__(self, key, pluginName, defaultValue, description=str()): + """ Constructor for _PyQgsSettingsEntryEnumFlag. + + :param self: the QgsSettingsEntryEnum object + :param key: argument specifies the final part of the settings key. + :param pluginName: argument is inserted in the key after the section. + :param defaultValue: argument specifies the default value for the settings entry. + :param description: argument specifies a description for the settings entry. + + .. note:: This constructor should not be used. Use PyQgsSettingsEntryEnum + or PyQgsSettingsEntryFlag instead. + """ + + defaultValueStr = str() + self.__metaEnum = metaEnumFromValue(defaultValue) + if self.__metaEnum is None or not self.__metaEnum.isValid(): + QgsLogger.debug("Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '{0}'".format(self.key())) + else: + if self.settingsType() is self.SettingsType.Enum: + defaultValueStr = self.__metaEnum.valueToKey(defaultValue) + else: + defaultValueStr = self.__metaEnum.valueToKeys(defaultValue) + self.__enumFlagClass = defaultValue.__class__ + + super().__init__(key, pluginName, defaultValueStr, description) + + def value(self, dynamicKeyPart=None, useDefaultValueOverride=False, defaultValueOverride=None): + """ Get settings value. + + :param self: the _PyQgsSettingsEntryEnumFlag object + :param dynamicKeyPart: argument specifies the dynamic part of the settings key. + :param useDefaultValueOverride: argument specifies if defaultValueOverride should be used. + :param defaultValueOverride: argument if valid is used instead of the normal default value. + """ + + defaultValue = self.defaultValue() + if useDefaultValueOverride: + defaultValue = defaultValueOverride + + if self.settingsType() is self.SettingsType.Enum: + return QgsSettings().enumValue(self.key(dynamicKeyPart), + defaultValue, + self.section()) + else: + return QgsSettings().flagValue(self.key(dynamicKeyPart), + defaultValue, + self.section()) + + def defaultValue(self): + """ Get settings default value. + + :param self: the _PyQgsSettingsEntryEnumFlag object + """ + + if self.__metaEnum is None or not self.__metaEnum.isValid(): + QgsLogger.debug("Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '{0}'".format(self.key())) + return -1 + + defaultValueString = self.defaultValueAsVariant() + if self.settingsType() is self.SettingsType.Enum: + (defaultValue, ok) = self.__metaEnum.keyToValue(defaultValueString) + else: + (defaultValue, ok) = self.__metaEnum.keysToValue(defaultValueString) + if not ok: + QgsLogger.debug("Invalid enum/flag key/s '{0}'.".format(self.defaultValueAsVariant())) + return -1 + + # cast to the enum class + defaultValue = self.__enumFlagClass(defaultValue) + return defaultValue + + def setValue(self, value, dynamicKeyPart=None): + """ Set settings value. + + :param self: the _PyQgsSettingsEntryEnumFlag object + :param dynamicKeyPart: argument specifies the dynamic part of the settings key. + """ + + if self.__metaEnum is None or not self.__metaEnum.isValid(): + QgsLogger.debug("Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '{0}'".format(self.key())) + return False + + enumFlagKey = str() + if self.settingsType() is self.SettingsType.Enum: + enumFlagKey = self.__metaEnum.valueToKey(value) + else: + enumFlagKey = self.__metaEnum.valueToKeys(value) + if not enumFlagKey: + QgsLogger.debug("Invalid enum/flag value '{0}'.".format(value)) + return False + + return super().setVariantValue(enumFlagKey, dynamicKeyPart) + + +class PyQgsSettingsEntryEnum(_PyQgsSettingsEntryEnumFlag): + """ class QgsSettingsEntryEnum + ingroup core + An enum settings entry. + since QGIS 3.20 + """ + + def __init__(self, key, pluginName, defaultValue, description=str()): + """ Constructor for QgsSettingsEntryEnum. + + :param self: the QgsSettingsEntryEnum object + :param key: argument specifies the final part of the settings key. + :param pluginName: argument is inserted in the key after the section. + :param defaultValue: argument specifies the default value for the settings entry. + :param description: argument specifies a description for the settings entry. + + .. note:: The enum needs to be declared with Q_ENUM. + """ + + super().__init__(key, pluginName, defaultValue, description) + + def settingsType(self): + """ Get the settings entry type. + + :param self: the QgsSettingsEntryEnum object + """ + + return self.SettingsType.Enum + + +class PyQgsSettingsEntryFlag(_PyQgsSettingsEntryEnumFlag): + """ class QgsSettingsEntryFlag + ingroup core + A flag settings entry. + since QGIS 3.20 + """ + + def __init__(self, key, pluginName, defaultValue, description=str()): + """ Constructor for QgsSettingsEntryFlag. + + :param self: the QgsSettingsEntryFlag object + :param key: argument specifies the final part of the settings key. + :param pluginName: argument is inserted in the key after the section. + :param defaultValue: argument specifies the default value for the settings entry. + :param description: argument specifies a description for the settings entry. + + .. note:: The flag needs to be declared with Q_FLAG (not Q_FLAGS). + """ + + super().__init__(key, pluginName, defaultValue, description) + + def settingsType(self): + """ Get the settings entry type. + + :param self: the QgsSettingsEntryFlag object + """ + + return self.SettingsType.Flag diff --git a/python/core/auto_additions/qgssettingsentry.py b/python/core/auto_additions/qgssettingsentry.py new file mode 100644 index 000000000000..246bc2767354 --- /dev/null +++ b/python/core/auto_additions/qgssettingsentry.py @@ -0,0 +1,12 @@ +# The following has been generated automatically from src/core/settings/qgssettingsentry.h +# monkey patching scoped based enum +QgsSettingsEntryBase.SettingsType.Variant.__doc__ = "" +QgsSettingsEntryBase.SettingsType.String.__doc__ = "" +QgsSettingsEntryBase.SettingsType.StringList.__doc__ = "" +QgsSettingsEntryBase.SettingsType.Bool.__doc__ = "" +QgsSettingsEntryBase.SettingsType.Integer.__doc__ = "" +QgsSettingsEntryBase.SettingsType.Double.__doc__ = "" +QgsSettingsEntryBase.SettingsType.Enum.__doc__ = "" +QgsSettingsEntryBase.SettingsType.Flag.__doc__ = "" +QgsSettingsEntryBase.SettingsType.__doc__ = '\n\n' + '* ``Variant``: ' + QgsSettingsEntryBase.SettingsType.Variant.__doc__ + '\n' + '* ``String``: ' + QgsSettingsEntryBase.SettingsType.String.__doc__ + '\n' + '* ``StringList``: ' + QgsSettingsEntryBase.SettingsType.StringList.__doc__ + '\n' + '* ``Bool``: ' + QgsSettingsEntryBase.SettingsType.Bool.__doc__ + '\n' + '* ``Integer``: ' + QgsSettingsEntryBase.SettingsType.Integer.__doc__ + '\n' + '* ``Double``: ' + QgsSettingsEntryBase.SettingsType.Double.__doc__ + '\n' + '* ``Enum``: ' + QgsSettingsEntryBase.SettingsType.Enum.__doc__ + '\n' + '* ``Flag``: ' + QgsSettingsEntryBase.SettingsType.Flag.__doc__ +# -- diff --git a/python/core/auto_generated/layout/qgslayout.sip.in b/python/core/auto_generated/layout/qgslayout.sip.in index cd416a440139..7918a46f736f 100644 --- a/python/core/auto_generated/layout/qgslayout.sip.in +++ b/python/core/auto_generated/layout/qgslayout.sip.in @@ -614,6 +614,8 @@ should be canceled. .. versionadded:: 3.10 %End + const QgsSettingsEntryStringList settingsSearchPathForTemplates; + public slots: void refresh(); diff --git a/python/core/auto_generated/locator/qgslocator.sip.in b/python/core/auto_generated/locator/qgslocator.sip.in index 65b99f05b808..2c6dfcace923 100644 --- a/python/core/auto_generated/locator/qgslocator.sip.in +++ b/python/core/auto_generated/locator/qgslocator.sip.in @@ -141,6 +141,10 @@ This list is updated when preparing the search .. versionadded:: 3.16 %End + const QgsSettingsEntryBool settingsLocatorFilterEnabled; + const QgsSettingsEntryBool settingsLocatorFilterDefault; + const QgsSettingsEntryString settingsLocatorFilterPrefix; + signals: void foundResult( const QgsLocatorResult &result ); diff --git a/python/core/auto_generated/qgsapplication.sip.in b/python/core/auto_generated/qgsapplication.sip.in index 7f595dd2b2f7..830ac64ea32b 100644 --- a/python/core/auto_generated/qgsapplication.sip.in +++ b/python/core/auto_generated/qgsapplication.sip.in @@ -657,6 +657,13 @@ Returns the application's task manager, used for managing application wide background task handling. .. versionadded:: 3.0 +%End + + static QgsSettingsRegistryCore *settingsRegistryCore() /KeepReference/; +%Docstring +Returns the application's settings registry, used for managing application settings. + +.. versionadded:: 3.20 %End static QgsColorSchemeRegistry *colorSchemeRegistry() /KeepReference/; diff --git a/python/core/auto_generated/settings/qgssettingsentry.sip.in b/python/core/auto_generated/settings/qgssettingsentry.sip.in new file mode 100644 index 000000000000..617bcd4cf5a5 --- /dev/null +++ b/python/core/auto_generated/settings/qgssettingsentry.sip.in @@ -0,0 +1,721 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/settings/qgssettingsentry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsSettingsEntryBase +{ +%Docstring(signature="appended") + +Represent settings entry and provides methods for reading and writing settings values. +Different subclasses are provided for different settings types with metainformations +to validate set values and provide more accurate settings description for the gui. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End +%ConvertToSubClassCode + if ( dynamic_cast< QgsSettingsEntryVariant * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryVariant; + else if ( dynamic_cast< QgsSettingsEntryString * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryString; + else if ( dynamic_cast< QgsSettingsEntryStringList * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryStringList; + else if ( dynamic_cast< QgsSettingsEntryBool * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryBool; + else if ( dynamic_cast< QgsSettingsEntryInteger * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryInteger; + else if ( dynamic_cast< QgsSettingsEntryDouble * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryDouble; + else + sipType = NULL; +%End + public: + + enum class SettingsType + { + Variant, + String, + StringList, + Bool, + Integer, + Double, + Enum, + Flag + }; + + + QgsSettingsEntryBase( const QString &key, + const QString &pluginName, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); +%Docstring +Constructor for :py:class:`QgsSettingsEntry`. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + virtual ~QgsSettingsEntryBase(); + + QString key( const QString &dynamicKeyPart = QString() ) const; +%Docstring +Get settings entry key. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + QString key( const QStringList &dynamicKeyPartList ) const; +%Docstring +Get settings entry key. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + bool hasDynamicKey() const; +%Docstring +Returns true if a part of the settings key is built dynamically. +%End + + bool exists( const QString &dynamicKeyPart = QString() ) const; +%Docstring +Returns true if the settings is contained in the underlying QSettings. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool exists( const QStringList &dynamicKeyPartList ) const; +%Docstring +Returns true if the settings is contained in the underlying QSettings. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + void remove( const QString &dynamicKeyPart = QString() ) const; +%Docstring +Removes the settings from the underlying QSettings. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + void remove( const QStringList &dynamicKeyPartList ) const; +%Docstring +Removes the settings from the underlying QSettings. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + QgsSettings::Section section() const; +%Docstring +Get settings section. The settings section of the parent group is returned if available. +%End + + virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + QVariant valueAsVariant( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QVariant valueAsVariant( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QVariant defaultValueAsVariant() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const = 0; +%Docstring +Get the settings entry type. +%End + + QString description() const; +%Docstring +Get the settings entry description. +%End + +}; + + +class QgsSettingsEntryVariant : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +A variant settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + QgsSettingsEntryVariant( const QString &key, + const QString &pluginName, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryVariant. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + QVariant value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QVariant value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QVariant defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End +}; + + +class QgsSettingsEntryString : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +A string settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + QgsSettingsEntryString( const QString &key, + const QString &pluginName, + const QString &defaultValue = QString(), + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryString. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( const QString &value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( const QString &value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + QString value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QString &defaultValueOverride = QString() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QString value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QString &defaultValueOverride = QString() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QString defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End + + void setMinLength( int minLength ); +%Docstring +Set the string minimum length. + +minLength The string minimum length. +%End + + int minLength(); +%Docstring +Returns the string minimum length. +%End + + void setMaxLength( int maxLength ); +%Docstring +Set the string maximum length. + +maxLength The string maximum length. +%End + + int maxLength(); +%Docstring +Returns the string maximum length. By -1 there is no limitation. +%End + +}; + + +class QgsSettingsEntryStringList : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +A string list settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + QgsSettingsEntryStringList( const QString &key, + const QString &pluginName, + const QStringList &defaultValue = QStringList(), + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryStringList. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( const QStringList &value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( const QStringList &value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + QStringList value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QStringList &defaultValueOverride = QStringList() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QStringList value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QStringList &defaultValueOverride = QStringList() ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + QStringList defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End + +}; + + +class QgsSettingsEntryBool : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +A boolean settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + QgsSettingsEntryBool( const QString &key, + const QString &pluginName, + bool defaultValue = false, + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryBool. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( bool value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( bool value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + bool value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, bool defaultValueOverride = false ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + bool value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, bool defaultValueOverride = false ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + bool defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End +}; + + +class QgsSettingsEntryInteger : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +An integer settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + + QgsSettingsEntryInteger( const QString &key, + const QString &pluginName, + qlonglong defaultValue = 0, + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryInteger. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( qlonglong value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( qlonglong value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + qlonglong value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, qlonglong defaultValueOverride = 0 ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + qlonglong value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, qlonglong defaultValueOverride = 0 ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + qlonglong defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End + + void setMinValue( qlonglong minValue ); +%Docstring +Set the minimum value. + +minValue The minimum value. +%End + + qlonglong minValue(); +%Docstring +Returns the minimum value. +%End + + void setMaxValue( qlonglong maxValue ); +%Docstring +Set the maximum value. + +maxValue The maximum value. +%End + + qlonglong maxValue(); +%Docstring +Returns the maximum value. +%End + +}; + + +class QgsSettingsEntryDouble : QgsSettingsEntryBase +{ +%Docstring(signature="appended") +A double settings entry. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsentry.h" +%End + public: + + + QgsSettingsEntryDouble( const QString &key, + const QString &pluginName, + double defaultValue, + const QString &description = QString() ); +%Docstring +Constructor for QgsSettingsEntryDouble. +This constructor is intended to be used from plugins. + +The ``key`` argument specifies the key of the settings. +The ``pluginName`` argument is inserted in the key after the section. +The ``default`` value argument specifies the default value for the settings entry. +The ``description`` argument specifies a description for the settings entry. +%End + + bool setValue( double value, const QString &dynamicKeyPart = QString() ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +%End + + bool setValue( double value, const QStringList &dynamicKeyPartList ) const; +%Docstring +Set settings value. + +The ``value`` to set. +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +%End + + double value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, double defaultValueOverride = 0.0 ) const; +%Docstring +Get settings value. + +The ``dynamicKeyPart`` argument specifies the dynamic part of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + double value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, double defaultValueOverride = 0.0 ) const; +%Docstring +Get settings value. + +The ``dynamicKeyParts`` argument specifies the list of dynamic parts of the settings key. +The ``useDefaultValueOverride`` argument specifies if defaultValueOverride should be used. +The ``defaultValueOverride`` argument if valid is used instead of the normal default value. +%End + + double defaultValue() const; +%Docstring +Get settings default value. +%End + + virtual SettingsType settingsType() const; +%Docstring +\copydoc :py:class:`QgsSettingsEntryBase`.settingsType +%End + + void setMinValue( double minValue ); +%Docstring +Set the minimum value. + +minValue The minimum value. +%End + + double minValue() const; +%Docstring +Returns the minimum value. +%End + + void setMaxValue( double maxValue ); +%Docstring +Set the maximum value. + +maxValue The maximum value. +%End + + double maxValue() const; +%Docstring +Returns the maximum value. +%End + + void setDisplayHintDecimals( int displayHintDecimals ); +%Docstring +Set the display hint decimals. + +displayHintDecimals The number of decimals that should be shown in the Gui. +%End + + int displayHintDecimals() const; +%Docstring +Returns how much decimals should be shown in the Gui. +%End + +}; + + + + + + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/settings/qgssettingsentry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/settings/qgssettingsregistrycore.sip.in b/python/core/auto_generated/settings/qgssettingsregistrycore.sip.in new file mode 100644 index 000000000000..5f77a9252559 --- /dev/null +++ b/python/core/auto_generated/settings/qgssettingsregistrycore.sip.in @@ -0,0 +1,44 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/settings/qgssettingsregistrycore.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + +class QgsSettingsRegistryCore +{ +%Docstring(signature="appended") +:py:class:`QgsSettingsRegistryCore` is used for settings introspection and collects all +:py:class:`QgsSettingsEntry` instances of core. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssettingsregistrycore.h" +%End + public: + + QgsSettingsRegistryCore(); +%Docstring +Constructor for QgsSettingsRegistryCore. +%End + + virtual ~QgsSettingsRegistryCore(); + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/settings/qgssettingsregistrycore.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index caed1f41264f..f318b2fbe541 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -602,6 +602,8 @@ %Include auto_generated/textrenderer/qgstextrenderer.sip %Include auto_generated/textrenderer/qgstextrendererutils.sip %Include auto_generated/textrenderer/qgstextshadowsettings.sip +%Include auto_generated/settings/qgssettingsentry.sip +%Include auto_generated/settings/qgssettingsregistrycore.sip %Include auto_generated/validity/qgsabstractvaliditycheck.sip %Include auto_generated/validity/qgsvaliditycheckcontext.sip %Include auto_generated/validity/qgsvaliditycheckregistry.sip diff --git a/src/app/locator/qgslocatoroptionswidget.cpp b/src/app/locator/qgslocatoroptionswidget.cpp index 35c1bb73e6b8..bd6ba70140c9 100644 --- a/src/app/locator/qgslocatoroptionswidget.cpp +++ b/src/app/locator/qgslocatoroptionswidget.cpp @@ -322,8 +322,6 @@ QVariant QgsLocatorFiltersModel::headerData( int section, Qt::Orientation orient void QgsLocatorFiltersModel::commitChanges() { - QgsSettings settings; - QHash< QgsLocatorFilter *, QString >::const_iterator itp = mPrefixes.constBegin(); for ( ; itp != mPrefixes.constEnd(); ++itp ) { @@ -332,26 +330,26 @@ void QgsLocatorFiltersModel::commitChanges() if ( !activePrefix.isEmpty() && activePrefix != filter->prefix() ) { filter->setActivePrefix( activePrefix ); - settings.setValue( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), activePrefix, QgsSettings::Section::Gui ); + QgsLocator::settingsLocatorFilterPrefix.setValue( activePrefix, filter->name() ); } else { filter->setActivePrefix( QString() ); - settings.remove( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), QgsSettings::Section::Gui ); + QgsLocator::settingsLocatorFilterPrefix.remove( filter->name() ); } } QHash< QgsLocatorFilter *, bool >::const_iterator it = mEnabledChanges.constBegin(); for ( ; it != mEnabledChanges.constEnd(); ++it ) { QgsLocatorFilter *filter = it.key(); - settings.setValue( QStringLiteral( "locator_filters/enabled_%1" ).arg( filter->name() ), it.value(), QgsSettings::Section::Gui ); + QgsLocator::settingsLocatorFilterEnabled.setValue( it.value(), filter->name() ); filter->setEnabled( it.value() ); } it = mDefaultChanges.constBegin(); for ( ; it != mDefaultChanges.constEnd(); ++it ) { QgsLocatorFilter *filter = it.key(); - settings.setValue( QStringLiteral( "locator_filters/default_%1" ).arg( filter->name() ), it.value(), QgsSettings::Section::Gui ); + QgsLocator::settingsLocatorFilterDefault.setValue( it.value(), filter->name() ); filter->setUseWithoutPrefix( it.value() ); } } diff --git a/src/app/options/qgsoptions.cpp b/src/app/options/qgsoptions.cpp index c3d9956c32d3..7c5894328731 100644 --- a/src/app/options/qgsoptions.cpp +++ b/src/app/options/qgsoptions.cpp @@ -62,6 +62,7 @@ #include "qgsbearingnumericformat.h" #include "qgssublayersdialog.h" #include "options/qgsadvancedoptions.h" +#include "qgslayout.h" #ifdef HAVE_OPENCL #include "qgsopenclutils.h" @@ -1480,7 +1481,7 @@ void QgsOptions::saveOptions() { pathsList << mListComposerTemplatePaths->item( i )->text(); } - mSettings->setValue( QStringLiteral( "Layout/searchPathsForTemplates" ), pathsList, QgsSettings::Core ); + QgsLayout::settingsSearchPathForTemplates.setValue( pathsList ); pathsList.clear(); for ( int r = 0; r < mLocalizedDataPathListWidget->count(); r++ ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8b3c33cc91d6..2f08298a669b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -716,6 +716,9 @@ set(QGIS_CORE_SRCS geocms/geonode/qgsgeonodeconnection.cpp geocms/geonode/qgsgeonoderequest.cpp + settings/qgssettingsentry.cpp + settings/qgssettingsregistrycore.cpp + validity/qgsabstractvaliditycheck.cpp validity/qgsvaliditycheckcontext.cpp validity/qgsvaliditycheckregistry.cpp @@ -1555,6 +1558,9 @@ set(QGIS_CORE_HDRS textrenderer/qgstextrendererutils.h textrenderer/qgstextshadowsettings.h + settings/qgssettingsentry.h + settings/qgssettingsregistrycore.h + validity/qgsabstractvaliditycheck.h validity/qgsvaliditycheckcontext.h validity/qgsvaliditycheckregistry.h @@ -1803,6 +1809,7 @@ target_include_directories(qgis_core PUBLIC raster renderer scalebar + settings symbology textrenderer validity diff --git a/src/core/layout/qgslayout.h b/src/core/layout/qgslayout.h index 12c2da188578..d045d0a34887 100644 --- a/src/core/layout/qgslayout.h +++ b/src/core/layout/qgslayout.h @@ -24,6 +24,7 @@ #include "qgslayoutguidecollection.h" #include "qgslayoutexporter.h" #include "qgsmasterlayoutinterface.h" +#include "qgssettingsentry.h" class QgsLayoutItemMap; class QgsLayoutModel; @@ -657,6 +658,9 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext */ bool accept( QgsStyleEntityVisitorInterface *visitor ) const; + //! Settings entry search path for templates + static const inline QgsSettingsEntryStringList settingsSearchPathForTemplates = QgsSettingsEntryStringList( QStringLiteral( "Layout/searchPathsForTemplates" ), QgsSettings::Core, QStringList(), QObject::tr( "Search path for templates" ) ); + public slots: /** diff --git a/src/core/locator/qgslocator.cpp b/src/core/locator/qgslocator.cpp index f55b0f00ec71..761ea2724225 100644 --- a/src/core/locator/qgslocator.cpp +++ b/src/core/locator/qgslocator.cpp @@ -94,10 +94,9 @@ void QgsLocator::registerFilter( QgsLocatorFilter *filter ) filter->setParent( this ); // restore settings - QgsSettings settings; - bool enabled = settings.value( QStringLiteral( "locator_filters/enabled_%1" ).arg( filter->name() ), true, QgsSettings::Section::Gui ).toBool(); - bool byDefault = settings.value( QStringLiteral( "locator_filters/default_%1" ).arg( filter->name() ), filter->useWithoutPrefix(), QgsSettings::Section::Gui ).toBool(); - QString prefix = settings.value( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), filter->prefix(), QgsSettings::Section::Gui ).toString(); + bool enabled = QgsLocator::settingsLocatorFilterEnabled.value( filter->name() ); + bool byDefault = QgsLocator::settingsLocatorFilterDefault.value( filter->name(), true, filter->useWithoutPrefix() ); + QString prefix = QgsLocator::settingsLocatorFilterPrefix.value( filter->name(), true, filter->prefix() ); if ( prefix.isEmpty() ) { prefix = filter->prefix(); diff --git a/src/core/locator/qgslocator.h b/src/core/locator/qgslocator.h index e554436f9dfa..b5eb3629bfcd 100644 --- a/src/core/locator/qgslocator.h +++ b/src/core/locator/qgslocator.h @@ -29,6 +29,7 @@ #include "qgslocatorfilter.h" #include "qgsfeedback.h" #include "qgslocatorcontext.h" +#include "qgssettingsentry.h" /** @@ -152,6 +153,13 @@ class CORE_EXPORT QgsLocator : public QObject */ QStringList completionList() const {return mAutocompletionList;} + //! Settings entry locator filter enabled + static const inline QgsSettingsEntryBool settingsLocatorFilterEnabled = QgsSettingsEntryBool( QStringLiteral( "locator_filters/enabled_%1" ), QgsSettings::Gui, true, "Locator filter enabled" ); + //! Settings entry locator filter default value + static const inline QgsSettingsEntryBool settingsLocatorFilterDefault = QgsSettingsEntryBool( QStringLiteral( "locator_filters/default_%1" ), QgsSettings::Gui, false, "Locator filter default value" ); + //! Settings entry locator filter prefix + static const inline QgsSettingsEntryString settingsLocatorFilterPrefix = QgsSettingsEntryString( QStringLiteral( "locator_filters/prefix_%1" ), QgsSettings::Gui, QString(), "Locator filter prefix" ); + signals: /** diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index 16d316026023..33ca1e027fed 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -20,6 +20,7 @@ #include "qgsexception.h" #include "qgsgeometry.h" #include "qgsannotationitemregistry.h" +#include "qgslayout.h" #include "qgslayoutitemregistry.h" #include "qgslogger.h" #include "qgsproject.h" @@ -52,6 +53,7 @@ #include "qgsmessagelog.h" #include "qgsannotationregistry.h" #include "qgssettings.h" +#include "qgssettingsregistrycore.h" #include "qgstiledownloadmanager.h" #include "qgsunittypes.h" #include "qgsuserprofile.h" @@ -1105,10 +1107,7 @@ QStringList QgsApplication::layoutTemplatePaths() { //local directories to search when looking for an template with a given basename //defined by user in options dialog - QgsSettings settings; - QStringList pathList = settings.value( QStringLiteral( "Layout/searchPathsForTemplates" ), QVariant(), QgsSettings::Core ).toStringList(); - - return pathList; + return QgsLayout::settingsSearchPathForTemplates.value(); } QMap QgsApplication::systemEnvVars() @@ -2173,6 +2172,11 @@ QgsTaskManager *QgsApplication::taskManager() return members()->mTaskManager; } +QgsSettingsRegistryCore *QgsApplication::settingsRegistryCore() +{ + return members()->mSettingsRegistryCore; +} + QgsColorSchemeRegistry *QgsApplication::colorSchemeRegistry() { return members()->mColorSchemeRegistry; @@ -2362,6 +2366,7 @@ QgsApplication::ApplicationMembers::ApplicationMembers() { // don't use initializer lists or scoped pointers - as more objects are added here we // will need to be careful with the order of creation/destruction + mSettingsRegistryCore = new QgsSettingsRegistryCore(); mLocalizedDataPathRegistry = new QgsLocalizedDataPathRegistry(); mMessageLog = new QgsMessageLog(); QgsRuntimeProfiler *profiler = QgsRuntimeProfiler::threadLocalInstance(); @@ -2563,6 +2568,7 @@ QgsApplication::ApplicationMembers::~ApplicationMembers() delete mConnectionRegistry; delete mLocalizedDataPathRegistry; delete mCrsRegistry; + delete mSettingsRegistryCore; } QgsApplication::ApplicationMembers *QgsApplication::members() diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index fee2c3eb1199..2ea07b19e720 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -25,6 +25,7 @@ #include "qgsconfig.h" #include "qgstranslationcontext.h" +class QgsSettingsRegistryCore; class Qgs3DRendererRegistry; class QgsActionScopeRegistry; class QgsAnnotationItemRegistry; @@ -617,6 +618,12 @@ class CORE_EXPORT QgsApplication : public QApplication */ static QgsTaskManager *taskManager(); + /** + * Returns the application's settings registry, used for managing application settings. + * \since QGIS 3.20 + */ + static QgsSettingsRegistryCore *settingsRegistryCore() SIP_KEEPREFERENCE; + /** * Returns the application's color scheme registry, used for managing color schemes. * \since QGIS 3.0 @@ -994,6 +1001,7 @@ class CORE_EXPORT QgsApplication : public QApplication struct ApplicationMembers { + QgsSettingsRegistryCore *mSettingsRegistryCore = nullptr; QgsCoordinateReferenceSystemRegistry *mCrsRegistry = nullptr; Qgs3DRendererRegistry *m3DRendererRegistry = nullptr; Qgs3DSymbolRegistry *m3DSymbolRegistry = nullptr; diff --git a/src/core/settings/qgssettingsentry.cpp b/src/core/settings/qgssettingsentry.cpp new file mode 100644 index 000000000000..0f6510d33631 --- /dev/null +++ b/src/core/settings/qgssettingsentry.cpp @@ -0,0 +1,594 @@ +/*************************************************************************** + qgssettingsentry.cpp + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot 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 "qgssettingsentry.h" + +#include "qgslogger.h" + +#include + +QgsSettingsEntryBase::QgsSettingsEntryBase( const QString &key, QgsSettings::Section section, const QVariant &defaultValue, const QString &description ) + : mKey( key ) + , mDefaultValue( defaultValue ) + , mSection( section ) + , mDescription( description ) + , mPluginName() +{ +} + +QgsSettingsEntryBase::QgsSettingsEntryBase( const QString &key, const QString &pluginName, const QVariant &defaultValue, const QString &description ) + : mKey( key ) + , mDefaultValue( defaultValue ) + , mSection( QgsSettings::Plugins ) + , mDescription( description ) + , mPluginName( pluginName ) +{ +} + +QgsSettingsEntryBase::~QgsSettingsEntryBase() +{ +} + +QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return key( dynamicKeyPartList ); +} + +QString QgsSettingsEntryBase::key( const QStringList &dynamicKeyPartList ) const +{ + QString completeKey = mKey; + if ( !mPluginName.isEmpty() ) + { + if ( !completeKey.startsWith( "/" ) ) + completeKey.prepend( "/" ); + completeKey.prepend( mPluginName ); + } + + if ( dynamicKeyPartList.isEmpty() ) + { + if ( hasDynamicKey() ) + QgsLogger::warning( QStringLiteral( "Settings '%1' have a dynamic key but the dynamic key part was not provided" ).arg( completeKey ) ); + + return completeKey; + } + else + { + if ( !hasDynamicKey() ) + { + QgsLogger::warning( QStringLiteral( "Settings '%1' don't have a dynamic key, the provided dynamic key part will be ignored" ).arg( completeKey ) ); + return completeKey; + } + + for ( int i = 0; i < dynamicKeyPartList.size(); i++ ) + { + completeKey.replace( QString( "%%1" ).arg( QString::number( i + 1 ) ), dynamicKeyPartList.at( i ) ); + } + } + return completeKey; +} + +bool QgsSettingsEntryBase::hasDynamicKey() const +{ + static const QRegularExpression regularExpression( "%\\d+" ); + return mKey.contains( regularExpression ); +} + +bool QgsSettingsEntryBase::exists( const QString &dynamicKeyPart ) const +{ + return QgsSettings().contains( key( dynamicKeyPart ), section() ); +} + +bool QgsSettingsEntryBase::exists( const QStringList &dynamicKeyPartList ) const +{ + return QgsSettings().contains( key( dynamicKeyPartList ), section() ); +} + +void QgsSettingsEntryBase::remove( const QString &dynamicKeyPart ) const +{ + QgsSettings().remove( key( dynamicKeyPart ), section() ); +} + +void QgsSettingsEntryBase::remove( const QStringList &dynamicKeyPartList ) const +{ + QgsSettings().remove( key( dynamicKeyPartList ), section() ); +} + +QgsSettings::Section QgsSettingsEntryBase::section() const +{ + return mSection; +} + +bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QString &dynamicKeyPart ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return setVariantValue( value, dynamicKeyPartList ); +} + +bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const +{ + QgsSettings().setValue( key( dynamicKeyPartList ), + value, + section() ); + return true; +} + +QVariant QgsSettingsEntryBase::valueAsVariant( const QString &dynamicKeyPart, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ); +} + +QVariant QgsSettingsEntryBase::valueAsVariant( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const +{ + if ( useDefaultValueOverride ) + return QgsSettings().value( key( dynamicKeyPartList ), + defaultValueOverride, + mSection ); + else + return QgsSettings().value( key( dynamicKeyPartList ), + mDefaultValue, + mSection ); +} + +QVariant QgsSettingsEntryBase::defaultValueAsVariant() const +{ + return mDefaultValue; +} + +QString QgsSettingsEntryBase::description() const +{ + return mDescription; +} + + +QgsSettingsEntryVariant::QgsSettingsEntryVariant( const QString &key, QgsSettings::Section section, const QVariant &defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) +{ +} + +QgsSettingsEntryVariant::QgsSettingsEntryVariant( const QString &key, const QString &pluginName, const QVariant &defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) +{ +} + +bool QgsSettingsEntryVariant::setValue( const QVariant &value, const QString &dynamicKeyPart ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPart ); +} + +bool QgsSettingsEntryVariant::setValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +QVariant QgsSettingsEntryVariant::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ); +} + +QVariant QgsSettingsEntryVariant::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ); +} + +QVariant QgsSettingsEntryVariant::defaultValue() const +{ + return defaultValueAsVariant(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryVariant::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::Variant; +} + +QgsSettingsEntryString::QgsSettingsEntryString( const QString &key, QgsSettings::Section section, const QString &defaultValue, const QString &description, int minLength, int maxLength ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) + , mMinLength( minLength ) + , mMaxLength( maxLength ) +{ +} + +QgsSettingsEntryString::QgsSettingsEntryString( const QString &key, const QString &pluginName, const QString &defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) + , mMinLength( 0 ) + , mMaxLength( -1 ) +{ +} + +bool QgsSettingsEntryString::setValue( const QString &value, const QString &dynamicKeyPart ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return setValue( value, dynamicKeyPartList ); +} + +bool QgsSettingsEntryString::setValue( const QString &value, const QStringList &dynamicKeyPartList ) const +{ + if ( value.length() < mMinLength ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. String length '%2' is shorter than minimum length '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + value.length(), + mMinLength ) ); + return false; + } + + if ( mMaxLength >= 0 + && value.length() > mMaxLength ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. String length '%2' is longer than maximum length '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + value.length(), + mMinLength ) ); + return false; + } + + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +QString QgsSettingsEntryString::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const QString &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ).toString(); +} + +QString QgsSettingsEntryString::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const QString &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ).toString(); +} + +QString QgsSettingsEntryString::defaultValue() const +{ + return defaultValueAsVariant().toString(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryString::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::String; +} + +void QgsSettingsEntryString::setMinLength( int minLength ) +{ + mMinLength = minLength; +} + +int QgsSettingsEntryString::minLength() +{ + return mMinLength; +} + +void QgsSettingsEntryString::setMaxLength( int maxLength ) +{ + mMaxLength = maxLength; +} + +int QgsSettingsEntryString::maxLength() +{ + return mMaxLength; +} + +QgsSettingsEntryStringList::QgsSettingsEntryStringList( const QString &key, QgsSettings::Section section, const QStringList &defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) +{ +} + +QgsSettingsEntryStringList::QgsSettingsEntryStringList( const QString &key, const QString &pluginName, const QStringList &defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) +{ +} + +bool QgsSettingsEntryStringList::setValue( const QStringList &value, const QString &dynamicKeyPart ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPart ); +} + +bool QgsSettingsEntryStringList::setValue( const QStringList &value, const QStringList &dynamicKeyPartList ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +QStringList QgsSettingsEntryStringList::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const QStringList &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ).toStringList(); +} + +QStringList QgsSettingsEntryStringList::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const QStringList &defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ).toStringList(); +} + +QStringList QgsSettingsEntryStringList::defaultValue() const +{ + return defaultValueAsVariant().toStringList(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryStringList::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::StringList; +} + +QgsSettingsEntryBool::QgsSettingsEntryBool( const QString &key, QgsSettings::Section section, bool defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) +{ +} + +QgsSettingsEntryBool::QgsSettingsEntryBool( const QString &key, const QString &pluginName, bool defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) +{ +} + +bool QgsSettingsEntryBool::setValue( bool value, const QString &dynamicKeyPart ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPart ); +} + +bool QgsSettingsEntryBool::setValue( bool value, const QStringList &dynamicKeyPartList ) const +{ + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +bool QgsSettingsEntryBool::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, bool defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ).toBool(); +} + +bool QgsSettingsEntryBool::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, bool defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ).toBool(); +} + +bool QgsSettingsEntryBool::defaultValue() const +{ + return defaultValueAsVariant().toBool(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryBool::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::Bool; +} + +QgsSettingsEntryInteger::QgsSettingsEntryInteger( const QString &key, QgsSettings::Section section, qlonglong defaultValue, const QString &description, qlonglong minValue, qlonglong maxValue ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) + , mMinValue( minValue ) + , mMaxValue( maxValue ) +{ +} + +QgsSettingsEntryInteger::QgsSettingsEntryInteger( const QString &key, const QString &pluginName, qlonglong defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) + , mMinValue( std::numeric_limits::min() ) + , mMaxValue( std::numeric_limits::max() ) +{ +} + +bool QgsSettingsEntryInteger::setValue( qlonglong value, const QString &dynamicKeyPart ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return setValue( value, dynamicKeyPartList ); +} + +bool QgsSettingsEntryInteger::setValue( qlonglong value, const QStringList &dynamicKeyPartList ) const +{ + if ( value < mMinValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is less than minimum value '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + QString::number( value ), + QString::number( mMinValue ) ) ); + return false; + } + + if ( value > mMaxValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is greather than maximum value '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + QString::number( value ), + QString::number( mMinValue ) ) ); + return false; + } + + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +qlonglong QgsSettingsEntryInteger::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, qlonglong defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ).toLongLong(); +} + +qlonglong QgsSettingsEntryInteger::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, qlonglong defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ).toLongLong(); +} + +qlonglong QgsSettingsEntryInteger::defaultValue() const +{ + return defaultValueAsVariant().toLongLong(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryInteger::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::Integer; +} + +void QgsSettingsEntryInteger::setMinValue( qlonglong minValue ) +{ + mMinValue = minValue; +} + +qlonglong QgsSettingsEntryInteger::minValue() +{ + return mMinValue; +} + +void QgsSettingsEntryInteger::setMaxValue( qlonglong maxValue ) +{ + mMaxValue = maxValue; +} + +qlonglong QgsSettingsEntryInteger::maxValue() +{ + return mMaxValue; +} + +QgsSettingsEntryDouble::QgsSettingsEntryDouble( const QString &key, QgsSettings::Section section, double defaultValue, const QString &description, double minValue, double maxValue, int displayDecimals ) + : QgsSettingsEntryBase( key, + section, + defaultValue, + description ) + , mMinValue( minValue ) + , mMaxValue( maxValue ) + , mDisplayHintDecimals( displayDecimals ) +{ +} + +QgsSettingsEntryDouble::QgsSettingsEntryDouble( const QString &key, const QString &pluginName, double defaultValue, const QString &description ) + : QgsSettingsEntryBase( key, + pluginName, + defaultValue, + description ) + , mMinValue( std::numeric_limits::lowest() ) + , mMaxValue( std::numeric_limits::max() ) + , mDisplayHintDecimals( 1 ) +{ +} + +bool QgsSettingsEntryDouble::setValue( double value, const QString &dynamicKeyPart ) const +{ + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isNull() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return setValue( value, dynamicKeyPartList ); +} + +bool QgsSettingsEntryDouble::setValue( double value, const QStringList &dynamicKeyPartList ) const +{ + if ( value < mMinValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is less than minimum value '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + QString::number( value ), + QString::number( mMinValue ) ) ); + return false; + } + + if ( value > mMaxValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is greather than maximum value '%3'." ) + .arg( QgsSettingsEntryBase::key( dynamicKeyPartList ), + QString::number( value ), + QString::number( mMinValue ) ) ); + return false; + } + + return QgsSettingsEntryBase::setVariantValue( value, dynamicKeyPartList ); +} + +double QgsSettingsEntryDouble::value( const QString &dynamicKeyPart, bool useDefaultValueOverride, double defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPart, useDefaultValueOverride, defaultValueOverride ).toDouble(); +} + +double QgsSettingsEntryDouble::value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, double defaultValueOverride ) const +{ + return valueAsVariant( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ).toDouble(); +} + +double QgsSettingsEntryDouble::defaultValue() const +{ + return defaultValueAsVariant().toDouble(); +} + +QgsSettingsEntryBase::SettingsType QgsSettingsEntryDouble::settingsType() const +{ + return QgsSettingsEntryBase::SettingsType::Double; +} + +void QgsSettingsEntryDouble::setMinValue( double minValue ) +{ + mMinValue = minValue; +} + +double QgsSettingsEntryDouble::minValue() const +{ + return mMinValue; +} + +void QgsSettingsEntryDouble::setMaxValue( double maxValue ) +{ + mMaxValue = maxValue; +} + +double QgsSettingsEntryDouble::maxValue() const +{ + return mMaxValue; +} + +void QgsSettingsEntryDouble::setDisplayHintDecimals( int displayHintDecimals ) +{ + mDisplayHintDecimals = displayHintDecimals; +} + +int QgsSettingsEntryDouble::displayHintDecimals() const +{ + return mDisplayHintDecimals; +} + + + diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h new file mode 100644 index 000000000000..2b11e0d712c6 --- /dev/null +++ b/src/core/settings/qgssettingsentry.h @@ -0,0 +1,1095 @@ +/*************************************************************************** + qgssettingsentry.h + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot 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 QGSSETTINGSENTRY_H +#define QGSSETTINGSENTRY_H + +#include +#include + +#include "qgis_core.h" +#include "qgis_sip.h" +#include "qgssettings.h" + +/** + * \ingroup core + * \class QgsSettingsEntry + * + * Represent settings entry and provides methods for reading and writing settings values. + * Different subclasses are provided for different settings types with metainformations + * to validate set values and provide more accurate settings description for the gui. + * + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryBase +{ + +#ifdef SIP_RUN + SIP_CONVERT_TO_SUBCLASS_CODE + if ( dynamic_cast< QgsSettingsEntryVariant * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryVariant; + else if ( dynamic_cast< QgsSettingsEntryString * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryString; + else if ( dynamic_cast< QgsSettingsEntryStringList * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryStringList; + else if ( dynamic_cast< QgsSettingsEntryBool * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryBool; + else if ( dynamic_cast< QgsSettingsEntryInteger * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryInteger; + else if ( dynamic_cast< QgsSettingsEntryDouble * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryDouble; + else + sipType = NULL; + SIP_END +#endif + + public: + + enum class SettingsType : int + { + Variant, + String, + StringList, + Bool, + Integer, + Double, + Enum, + Flag + }; + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntry. + * + * The \a key argument specifies the key of the settings. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryBase( const QString &key, + QgsSettings::Section section, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); + +#endif + + /** + * Constructor for QgsSettingsEntry. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryBase( const QString &key, + const QString &pluginName, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); + + /** + * Destructor for QgsSettingsEntry. + */ + virtual ~QgsSettingsEntryBase(); + + /** + * Get settings entry key. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + QString key( const QString &dynamicKeyPart = QString() ) const; + + /** + * Get settings entry key. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + QString key( const QStringList &dynamicKeyPartList ) const; + + /** + * Returns true if a part of the settings key is built dynamically. + */ + bool hasDynamicKey() const; + + /** + * Returns true if the settings is contained in the underlying QSettings. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool exists( const QString &dynamicKeyPart = QString() ) const; + + /** + * Returns true if the settings is contained in the underlying QSettings. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool exists( const QStringList &dynamicKeyPartList ) const; + + /** + * Removes the settings from the underlying QSettings. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + void remove( const QString &dynamicKeyPart = QString() ) const; + + /** + * Removes the settings from the underlying QSettings. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + void remove( const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings section. The settings section of the parent group is returned if available. + */ + QgsSettings::Section section() const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QVariant valueAsVariant( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QVariant valueAsVariant( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; + + /** + * Get settings default value. + */ + QVariant defaultValueAsVariant() const; + + /** + * Get the settings entry type. + */ + virtual SettingsType settingsType() const = 0; + + /** + * Get the settings entry description. + */ + QString description() const; + + private: + + QString mKey; + QVariant mDefaultValue; + QgsSettings::Section mSection; + QString mDescription; + QString mPluginName; +}; + + +/** + * \class QgsSettingsEntryVariant + * \ingroup core + * A variant settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryBase +{ + public: + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryVariant. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryVariant( const QString &key, + QgsSettings::Section section, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); + +#endif + + /** + * Constructor for QgsSettingsEntryVariant. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryVariant( const QString &key, + const QString &pluginName, + const QVariant &defaultValue = QVariant(), + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QVariant value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QVariant value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QVariant &defaultValueOverride = QVariant() ) const; + + /** + * Get settings default value. + */ + QVariant defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; +}; + + +/** + * \class QgsSettingsEntryString + * \ingroup core + * A string settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryBase +{ + public: + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryString. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minLength argument specifies the minimal length of the string value. + * The \a maxLength argument specifies the maximal length of the string value. + * By -1 the there is no limit + */ + QgsSettingsEntryString( const QString &key, + QgsSettings::Section section, + const QString &defaultValue = QString(), + const QString &description = QString(), + int minLength = 0, + int maxLength = -1 ); + +#endif + + /** + * Constructor for QgsSettingsEntryString. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryString( const QString &key, + const QString &pluginName, + const QString &defaultValue = QString(), + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( const QString &value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( const QString &value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QString value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QString &defaultValueOverride = QString() ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QString value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QString &defaultValueOverride = QString() ) const; + + /** + * Get settings default value. + */ + QString defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; + + /** + * Set the string minimum length. + * + * minLength The string minimum length. + */ + void setMinLength( int minLength ); + + /** + * Returns the string minimum length. + */ + int minLength(); + + /** + * Set the string maximum length. + * + * maxLength The string maximum length. + */ + void setMaxLength( int maxLength ); + + /** + * Returns the string maximum length. By -1 there is no limitation. + */ + int maxLength(); + + private: + + int mMinLength; + int mMaxLength; + +}; + + +/** + * \class QgsSettingsEntryStringList + * \ingroup core + * A string list settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryBase +{ + public: + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryStringList. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryStringList( const QString &key, + QgsSettings::Section section, + const QStringList &defaultValue = QStringList(), + const QString &description = QString() ); + +#endif + + /** + * Constructor for QgsSettingsEntryStringList. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryStringList( const QString &key, + const QString &pluginName, + const QStringList &defaultValue = QStringList(), + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( const QStringList &value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( const QStringList &value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QStringList value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const QStringList &defaultValueOverride = QStringList() ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + QStringList value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const QStringList &defaultValueOverride = QStringList() ) const; + + /** + * Get settings default value. + */ + QStringList defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; + +}; + + +/** + * \class QgsSettingsEntryBool + * \ingroup core + * A boolean settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryBase +{ + public: + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryBool. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryBool( const QString &key, + QgsSettings::Section section, + bool defaultValue = false, + const QString &description = QString() ); + +#endif + + /** + * Constructor for QgsSettingsEntryBool. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryBool( const QString &key, + const QString &pluginName, + bool defaultValue = false, + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( bool value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( bool value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + bool value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, bool defaultValueOverride = false ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + bool value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, bool defaultValueOverride = false ) const; + + /** + * Get settings default value. + */ + bool defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; +}; + + +/** + * \class QgsSettingsEntryInteger + * \ingroup core + * An integer settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryBase +{ + public: + + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryInteger. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minValue argument specifies the minimal value. + * The \a maxValue argument specifies the maximal value. + */ + QgsSettingsEntryInteger( const QString &key, + QgsSettings::Section section, + qlonglong defaultValue = 0, + const QString &description = QString(), + qlonglong minValue = std::numeric_limits::min(), + qlonglong maxValue = std::numeric_limits::max() ); + +#endif + + /** + * Constructor for QgsSettingsEntryInteger. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryInteger( const QString &key, + const QString &pluginName, + qlonglong defaultValue = 0, + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( qlonglong value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( qlonglong value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + qlonglong value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, qlonglong defaultValueOverride = 0 ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + qlonglong value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, qlonglong defaultValueOverride = 0 ) const; + + /** + * Get settings default value. + */ + qlonglong defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; + + /** + * Set the minimum value. + * + * minValue The minimum value. + */ + void setMinValue( qlonglong minValue ); + + /** + * Returns the minimum value. + */ + qlonglong minValue(); + + /** + * Set the maximum value. + * + * maxValue The maximum value. + */ + void setMaxValue( qlonglong maxValue ); + + /** + * Returns the maximum value. + */ + qlonglong maxValue(); + + private: + + qlonglong mMinValue; + qlonglong mMaxValue; + +}; + + +/** + * \class QgsSettingsEntryDouble + * \ingroup core + * A double settings entry. + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryBase +{ + public: + +#ifndef SIP_RUN + + /** + * Constructor for QgsSettingsEntryDouble. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minValue argument specifies the minimal value. + * The \a maxValue argument specifies the maximal value. + * The \a displayDecimals specifies an hint for the gui about how much decimals to show + * for example for a QDoubleSpinBox. + */ + QgsSettingsEntryDouble( const QString &key, + QgsSettings::Section section, + double defaultValue = 0.0, + const QString &description = QString(), + double minValue = std::numeric_limits::lowest(), + double maxValue = std::numeric_limits::max(), + int displayDecimals = 1 ); + +#endif + + /** + * Constructor for QgsSettingsEntryDouble. + * This constructor is intended to be used from plugins. + * + * The \a key argument specifies the key of the settings. + * The \a pluginName argument is inserted in the key after the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryDouble( const QString &key, + const QString &pluginName, + double defaultValue, + const QString &description = QString() ); + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool setValue( double value, const QString &dynamicKeyPart = QString() ) const; + + /** + * Set settings value. + * + * The \a value to set. + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + */ + bool setValue( double value, const QStringList &dynamicKeyPartList ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + double value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, double defaultValueOverride = 0.0 ) const; + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + double value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, double defaultValueOverride = 0.0 ) const; + + /** + * Get settings default value. + */ + double defaultValue() const; + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual SettingsType settingsType() const override; + + /** + * Set the minimum value. + * + * minValue The minimum value. + */ + void setMinValue( double minValue ); + + /** + * Returns the minimum value. + */ + double minValue() const; + + /** + * Set the maximum value. + * + * maxValue The maximum value. + */ + void setMaxValue( double maxValue ); + + /** + * Returns the maximum value. + */ + double maxValue() const; + + /** + * Set the display hint decimals. + * + * displayHintDecimals The number of decimals that should be shown in the Gui. + */ + void setDisplayHintDecimals( int displayHintDecimals ); + + /** + * Returns how much decimals should be shown in the Gui. + */ + int displayHintDecimals() const; + + private: + + double mMinValue; + double mMaxValue; + + int mDisplayHintDecimals; + +}; + + +#ifndef SIP_RUN + +/** + * \class QgsSettingsEntryEnum + * \ingroup core + * A base class for enum and flag settings entry. + * \since QGIS 3.20 + */ +template +class CORE_EXPORT QgsSettingsEntryEnumFlagBase : public QgsSettingsEntryBase +{ + public: + + /** + * Constructor for QgsSettingsEntryEnumFlagBase. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * + * \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS). + * \note for Python bindings, a custom implementation is achieved in Python directly + */ + QgsSettingsEntryEnumFlagBase( const QString &key, + QgsSettings::Section section, + const T &defaultValue, + const QString &description = QString() ) + : QgsSettingsEntryBase( key, + section, + QMetaEnum::fromType().isFlag() ? + QVariant( QMetaEnum::fromType().valueToKeys( defaultValue ) ) : + QVariant( QMetaEnum::fromType().valueToKey( defaultValue ) ), + description ) + { + mMetaEnum = QMetaEnum::fromType(); + Q_ASSERT( mMetaEnum.isValid() ); + if ( !mMetaEnum.isValid() ) + QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( QgsSettingsEntryBase::key() ) ); + } + + /** + * Get settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + T value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const T &defaultValueOverride = T() ) const + { + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isEmpty() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return value( dynamicKeyPartList, useDefaultValueOverride, defaultValueOverride ); + } + + /** + * Get settings value. + * + * The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key. + * The \a useDefaultValueOverride argument specifies if defaultValueOverride should be used. + * The \a defaultValueOverride argument if valid is used instead of the normal default value. + */ + T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride = false, const T &defaultValueOverride = T() ) const + { + T defaultVal = defaultValue(); + if ( useDefaultValueOverride ) + defaultVal = defaultValueOverride; + + if ( settingsType() == QgsSettingsEntryBase::SettingsType::Enum ) + return QgsSettings().enumValue( key( dynamicKeyPartList ), + defaultVal, + section() ); + else + return QgsSettings().flagValue( key( dynamicKeyPartList ), + defaultVal, + section() ); + } + + /** + * Get settings default value. + */ + T defaultValue() const + { + if ( !mMetaEnum.isValid() ) + { + QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( key() ) ); + return T(); + } + + bool ok = false; + T defaultValue; + if ( settingsType() == QgsSettingsEntryBase::SettingsType::Enum ) + defaultValue = static_cast( mMetaEnum.keyToValue( defaultValueAsVariant().toByteArray(), &ok ) ); + else + defaultValue = static_cast( mMetaEnum.keysToValue( defaultValueAsVariant().toByteArray(), &ok ) ); + + if ( !ok ) + { + QgsDebugMsg( QStringLiteral( "Invalid enum/flag key/s '%1' for settings key '%2'" ).arg( defaultValueAsVariant().toString(), key() ) ); + return T(); + } + + return defaultValue; + } + + //! \copydoc QgsSettingsEntryBase::setValue + bool setValue( const T &value, const QString &dynamicKeyPart = QString() ) const + { + QStringList dynamicKeyPartList; + if ( !dynamicKeyPart.isEmpty() ) + dynamicKeyPartList.append( dynamicKeyPart ); + + return setValue( value, dynamicKeyPartList ); + } + + //! \copydoc QgsSettingsEntryBase::setValue + bool setValue( const T &value, const QStringList &dynamicKeyPartList ) const + { + if ( !mMetaEnum.isValid() ) + { + QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( key( dynamicKeyPartList ) ) ); + return false; + } + + if ( settingsType() == QgsSettingsEntryBase::SettingsType::Enum ) + { + const char *enumKey = mMetaEnum.valueToKey( value ); + if ( enumKey == nullptr ) + { + QgsDebugMsg( QStringLiteral( "Invalid enum value '%1'." ).arg( value ) ); + return false; + } + + return QgsSettingsEntryBase::setVariantValue( enumKey, dynamicKeyPartList ); + } + else + { + QByteArray flagKeys = mMetaEnum.valueToKeys( value ); + if ( flagKeys.isEmpty() ) + { + QgsDebugMsg( QStringLiteral( "Invalid flag value '%1'." ).arg( value ) ); + return false; + } + return QgsSettingsEntryBase::setVariantValue( flagKeys, dynamicKeyPartList ); + } + } + + private: + + QMetaEnum mMetaEnum; + +}; +#endif + + +#ifndef SIP_RUN + +/** + * \class QgsSettingsEntryEnum + * \ingroup core + * An enum settings entry. + * \since QGIS 3.20 + */ +template +class CORE_EXPORT QgsSettingsEntryEnum : public QgsSettingsEntryEnumFlagBase +{ + public: + + /** + * Constructor for QgsSettingsEntryEnum. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * + * \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS). + * \note for Python bindings, a custom implementation is achieved in Python directly + */ + QgsSettingsEntryEnum( const QString &key, + QgsSettings::Section section, + const T &defaultValue, + const QString &description = QString() ) + : QgsSettingsEntryEnumFlagBase( key, + section, + defaultValue, + description ) + { + } + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual QgsSettingsEntryBase::SettingsType settingsType() const override + { + return QgsSettingsEntryBase::SettingsType::Enum; + } +}; +#endif + + +#ifndef SIP_RUN + +/** + * \class QgsSettingsEntryFlag + * \ingroup core + * An flag settings entry. + * \since QGIS 3.20 + */ +template +class CORE_EXPORT QgsSettingsEntryFlag : public QgsSettingsEntryEnumFlagBase +{ + public: + + /** + * Constructor for QgsSettingsEntryFlag. + * + * The \a key argument specifies the final part of the settings key. + * The \a section argument specifies the section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * + * \note The flag needs to be declared with Q_FLAG (not Q_FLAGS). + * \note for Python bindings, a custom implementation is achieved in Python directly. + */ + QgsSettingsEntryFlag( const QString &key, + QgsSettings::Section section, + const T &defaultValue, + const QString &description = QString() ) + : QgsSettingsEntryEnumFlagBase( key, + section, + defaultValue, + description ) + { + } + + //! \copydoc QgsSettingsEntryBase::settingsType + virtual QgsSettingsEntryBase::SettingsType settingsType() const override + { + return QgsSettingsEntryBase::SettingsType::Flag; + } +}; +#endif + +#endif // QGSSETTINGSENTRY_H diff --git a/src/core/settings/qgssettingsregistrycore.cpp b/src/core/settings/qgssettingsregistrycore.cpp new file mode 100644 index 000000000000..188028a23f8d --- /dev/null +++ b/src/core/settings/qgssettingsregistrycore.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + qgssettingsregistrycore.cpp + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot 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 "qgssettingsregistrycore.h" + +#include "qgslayout.h" +#include "qgslocator.h" + +QgsSettingsRegistryCore::QgsSettingsRegistryCore() + : mSettingsEntries() +{ + mSettingsEntries.append( &QgsLayout::settingsSearchPathForTemplates ); + + mSettingsEntries.append( &QgsLocator::settingsLocatorFilterEnabled ); + mSettingsEntries.append( &QgsLocator::settingsLocatorFilterDefault ); + mSettingsEntries.append( &QgsLocator::settingsLocatorFilterPrefix ); +} + +QgsSettingsRegistryCore::~QgsSettingsRegistryCore() +{ +} + + diff --git a/src/core/settings/qgssettingsregistrycore.h b/src/core/settings/qgssettingsregistrycore.h new file mode 100644 index 000000000000..933b5d4bfc8c --- /dev/null +++ b/src/core/settings/qgssettingsregistrycore.h @@ -0,0 +1,59 @@ +/*************************************************************************** + qgssettingsregistrycore.h + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot 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 QGSSETTINGSREGISTRYCORE_H +#define QGSSETTINGSREGISTRYCORE_H + +#include "qgis_core.h" +#include "qgis_sip.h" +#include "qgssettingsentry.h" + +#include "qgslayout.h" +#include "qgslocator.h" + +#include + +class QgsSettingsEntryStringList; + +/** + * \ingroup core + * \class QgsSettingsRegistryCore + * QgsSettingsRegistryCore is used for settings introspection and collects all + * QgsSettingsEntry instances of core. + * + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsSettingsRegistryCore +{ + public: + + /** + * Constructor for QgsSettingsRegistryCore. + */ + QgsSettingsRegistryCore(); + + /** + * Destructor for QgsSettingsRegistryCore. + */ + virtual ~QgsSettingsRegistryCore(); + + private: + + QList mSettingsEntries; + +}; + +#endif // QGSSETTINGSREGISTRYCORE_H diff --git a/tests/src/core/CMakeLists.txt b/tests/src/core/CMakeLists.txt index 2804be878141..61acef4e54f0 100644 --- a/tests/src/core/CMakeLists.txt +++ b/tests/src/core/CMakeLists.txt @@ -188,6 +188,7 @@ set(TESTS testqgsrulebasedrenderer.cpp testqgsruntimeprofiler.cpp testqgssettings.cpp + testqgssettingsentry.cpp testqgsshapeburst.cpp testqgssimplemarker.cpp testqgssnappingutils.cpp diff --git a/tests/src/core/testqgssettingsentry.cpp b/tests/src/core/testqgssettingsentry.cpp new file mode 100644 index 000000000000..f060258a02c0 --- /dev/null +++ b/tests/src/core/testqgssettingsentry.cpp @@ -0,0 +1,183 @@ +/*************************************************************************** + testqgssettingsentry.cpp + -------------------------------------- + Date : 01.04.2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano@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 "qgssettings.h" +#include "qgssettingsentry.h" +#include "qgsunittypes.h" +#include "qgsmaplayerproxymodel.h" +#include "qgstest.h" + + +/** + * \ingroup UnitTests + * This is a unit test for the operations on curve geometries + */ +class TestQgsSettingsEntry : public QObject +{ + Q_OBJECT + + private slots: + void settingsKey(); + void enumValue(); + void flagValue(); +}; + +void TestQgsSettingsEntry::settingsKey() +{ + QgsSettings settings; + + { + QString key( QStringLiteral( "/qgis/testing/settingsKey" ) ); + + // Be sure that settings does not exist already + settings.remove( key ); + + // Check that keys are handled same way for QgsSettings and QgsSettingsEntry + settings.setValue( key, 42 ); + + QgsSettingsEntryInteger settingsEntryInteger( key, QgsSettings::NoSection, 0 ); + QCOMPARE( settingsEntryInteger.value(), 42 ); + } + + { + QString key( QStringLiteral( "qgis/testing/settingsKey" ) ); + + // Be sure that settings does not exist already + settings.remove( key ); + + // Check that keys are handled same way for QgsSettings and QgsSettingsEntry + settings.setValue( key, 43 ); + + QgsSettingsEntryInteger settingsEntryInteger( key, QgsSettings::NoSection, 0 ); + QCOMPARE( settingsEntryInteger.value(), 43 ); + } + + { + QString key( QStringLiteral( "/qgis/testing/settingsKey" ) ); + + // Be sure that settings does not exist already + settings.remove( key, QgsSettings::Core ); + + // Check that keys are handled same way for QgsSettings and QgsSettingsEntry + settings.setValue( key, 44, QgsSettings::Core ); + + QgsSettingsEntryInteger settingsEntryInteger( key, QgsSettings::Core, 0 ); + QCOMPARE( settingsEntryInteger.value(), 44 ); + } + + { + QString key( QStringLiteral( "qgis/testing/settingsKey" ) ); + + // Be sure that settings does not exist already + settings.remove( key, QgsSettings::Core ); + + // Check that keys are handled same way for QgsSettings and QgsSettingsEntry + settings.setValue( key, 45, QgsSettings::Core ); + + QgsSettingsEntryInteger settingsEntryInteger( key, QgsSettings::Core, 0 ); + QCOMPARE( settingsEntryInteger.value(), 45 ); + } +} + +void TestQgsSettingsEntry::enumValue() +{ + QString settingsKey( "qgis/testing/my_enum_value_for_units" ); + + // Make sure the setting is not existing + QgsSettings().remove( settingsKey, QgsSettings::NoSection ); + + QgsSettingsEntryEnum settingsEntryEnum( settingsKey, QgsSettings::NoSection, QgsUnitTypes::LayoutMeters, "Layout unit" ); + + // Check default value + QCOMPARE( settingsEntryEnum.defaultValue(), QgsUnitTypes::LayoutMeters ); + + // Check set value + { + bool success = settingsEntryEnum.setValue( QgsUnitTypes::LayoutFeet ); + QCOMPARE( success, true ); + QgsUnitTypes::LayoutUnit qgsSettingsValue = QgsSettings().enumValue( settingsKey, QgsUnitTypes::LayoutMeters, QgsSettings::NoSection ); + QCOMPARE( qgsSettingsValue, QgsUnitTypes::LayoutFeet ); + } + + // Check get value + QgsSettings().setEnumValue( settingsKey, QgsUnitTypes::LayoutPicas, QgsSettings::NoSection ); + QCOMPARE( settingsEntryEnum.value(), QgsUnitTypes::LayoutPicas ); + + // Check settings type + QCOMPARE( settingsEntryEnum.settingsType(), QgsSettingsEntryBase::SettingsType::Enum ); + + // assign to inexisting value + { + bool success = settingsEntryEnum.setValue( static_cast( -1 ) ); + QCOMPARE( success, false ); + + // Current value should not have changed + QgsUnitTypes::LayoutUnit qgsSettingsValue = QgsSettings().enumValue( settingsKey, QgsUnitTypes::LayoutMeters, QgsSettings::NoSection ); + QCOMPARE( qgsSettingsValue, QgsUnitTypes::LayoutPicas ); + } + + // check that value is stored as string + QCOMPARE( settingsEntryEnum.valueAsVariant().toString(), QMetaEnum::fromType().key( QgsUnitTypes::LayoutPicas ) ); + + // auto conversion of old settings (int to str) + QSettings().setValue( settingsKey, static_cast( QgsUnitTypes::LayoutCentimeters ) ); + QCOMPARE( settingsEntryEnum.valueAsVariant().toInt(), QgsUnitTypes::LayoutCentimeters ); + QCOMPARE( settingsEntryEnum.value(), QgsUnitTypes::LayoutCentimeters ); +} + +void TestQgsSettingsEntry::flagValue() +{ + QString settingsKey( "qgis/testing/my_flag_value_for_units" ); + QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer ); + QgsMapLayerProxyModel::Filters pointAndPolygon = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::PolygonLayer ); + QgsMapLayerProxyModel::Filters hasGeometry = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::HasGeometry ); + + // Make sure the setting is not existing + QgsSettings().remove( settingsKey, QgsSettings::NoSection ); + + QgsSettingsEntryFlag settingsEntryFlag( settingsKey, QgsSettings::NoSection, pointAndLine, "Filters" ); + + // Check default value + QCOMPARE( settingsEntryFlag.defaultValue(), pointAndLine ); + + // Check set value + { + bool success = settingsEntryFlag.setValue( hasGeometry ); + QCOMPARE( success, true ); + QgsMapLayerProxyModel::Filters qgsSettingsValue = QgsSettings().flagValue( settingsKey, pointAndLine, QgsSettings::NoSection ); + QCOMPARE( qgsSettingsValue, hasGeometry ); + } + + // Check get value + QgsSettings().setFlagValue( settingsKey, pointAndLine, QgsSettings::NoSection ); + QCOMPARE( settingsEntryFlag.value(), pointAndLine ); + + // Check settings type + QCOMPARE( settingsEntryFlag.settingsType(), QgsSettingsEntryBase::SettingsType::Flag ); + + // check that value is stored as string + QCOMPARE( settingsEntryFlag.valueAsVariant().toByteArray(), QMetaEnum::fromType().valueToKeys( pointAndLine ) ); + + // auto conversion of old settings (int to str) + QSettings().setValue( settingsKey, static_cast( pointAndPolygon ) ); + QCOMPARE( settingsEntryFlag.valueAsVariant().toInt(), pointAndPolygon ); + QCOMPARE( settingsEntryFlag.value(), pointAndPolygon ); +} + + +QGSTEST_MAIN( TestQgsSettingsEntry ) +#include "testqgssettingsentry.moc" diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index b4110721387a..4ef757ed589e 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -340,6 +340,7 @@ ADD_PYTHON_TEST(PyQgsDBManagerGpkg test_db_manager_gpkg.py) ADD_PYTHON_TEST(PyQgsDBManagerSpatialite test_db_manager_spatialite.py) ADD_PYTHON_TEST(PyQgsFileDownloader test_qgsfiledownloader.py) ADD_PYTHON_TEST(PyQgsSettings test_qgssettings.py) +ADD_PYTHON_TEST(PyQgsSettingsEntry test_qgssettingsentry.py) ADD_PYTHON_TEST(PyQgsZipUtils test_qgsziputils.py) ADD_PYTHON_TEST(PyQgsSourceSelectProvider test_qgssourceselectprovider.py) ADD_PYTHON_TEST(PyQgsAuthManagerProxy test_authmanager_proxy.py) diff --git a/tests/src/python/test_qgssettingsentry.py b/tests/src/python/test_qgssettingsentry.py new file mode 100644 index 000000000000..547002e02508 --- /dev/null +++ b/tests/src/python/test_qgssettingsentry.py @@ -0,0 +1,363 @@ +# -*- coding: utf-8 -*- +""" +Test the QgsSettingsEntry classes + +Run with: ctest -V -R PyQgsSettingsEntry + +.. note:: 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. +""" + +import os +import tempfile +from qgis.core import QgsSettings, QgsSettingsEntryBase, QgsSettingsEntryVariant, QgsSettingsEntryString, QgsSettingsEntryStringList, QgsSettingsEntryBool, QgsSettingsEntryInteger, QgsSettingsEntryDouble, QgsSettingsEntryEnum, QgsSettingsEntryFlag, QgsUnitTypes, QgsMapLayerProxyModel +from qgis.testing import start_app, unittest +from qgis.PyQt.QtCore import QSettings, QVariant, QMetaEnum +from pathlib import Path + +__author__ = 'Damiano Lombardi' +__date__ = '02/04/2021' +__copyright__ = 'Copyright 2021, The QGIS Project' + + +start_app() + + +class TestQgsSettingsEntry(unittest.TestCase): + + cnt = 0 + + def setUp(self): + self.pluginName = "UnitTest" + + def tearDown(self): + pass + + def test_settings_entry_base(self): + settingsKey = "settingsEntryBase/variantValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 42 + description = "Variant value for basic functionality test" + settingsEntryVariant = QgsSettingsEntryVariant(settingsKey, self.pluginName, defaultValue, description) + + # Check key + self.assertEqual(settingsEntryVariant.key(), settingsKeyComplete) + + # Passing dynamicKeyPart to a non dynamic settings has no effect + self.assertEqual(settingsEntryVariant.key("gugus"), settingsKeyComplete) + + self.assertEqual(settingsEntryVariant.hasDynamicKey(), False) + + # At this point settings should still not exists in underlyng QSettings as it was still not written (setValue) + self.assertEqual(settingsEntryVariant.exists(), False) + settingsEntryVariant.setValue(43) + self.assertEqual(settingsEntryVariant.exists(), True) + settingsEntryVariant.remove() + self.assertEqual(settingsEntryVariant.exists(), False) + + # Section + self.assertEqual(settingsEntryVariant.section(), QgsSettings.Plugins) + + # DefaultValue + self.assertEqual(settingsEntryVariant.defaultValueAsVariant(), defaultValue) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryVariant.valueAsVariant(), defaultValue) + settingsEntryVariant.setValue(43) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), 43) + self.assertEqual(settingsEntryVariant.valueAsVariant(), 43) + + # Settings type + self.assertEqual(settingsEntryVariant.settingsType(), QgsSettingsEntryBase.SettingsType.Variant) + + # Description + self.assertEqual(settingsEntryVariant.description(), description) + + def test_settings_entry_base_default_value_override(self): + settingsKey = "settingsEntryBase/defaultValueOverride/variantValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 42 + defaultValueOverride = 123 + description = "Variant value for default override functionality test" + settingsEntryVariant = QgsSettingsEntryVariant(settingsKey, self.pluginName, defaultValue, description) + + # Normal default value + self.assertEqual(settingsEntryVariant.value(), defaultValue) + + # Normal default value + self.assertEqual(settingsEntryVariant.value(None, False, defaultValueOverride), defaultValue) + + # Overridden default value + self.assertEqual(settingsEntryVariant.value(None, True, defaultValueOverride), defaultValueOverride) + + def test_settings_entry_base_dynamic_key(self): + settingsKeyDynamic = "settingsEntryBase/%1/variantValue" + dynamicKeyPart1 = "first" + dynamicKeyPart2 = "second" + settingsKeyComplete1 = self.pluginName + "/" + settingsKeyDynamic.replace("%1", dynamicKeyPart1) + settingsKeyComplete2 = self.pluginName + "/" + settingsKeyDynamic.replace("%1", dynamicKeyPart2) + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete1, QgsSettings.Plugins) + QgsSettings().remove(settingsKeyComplete2, QgsSettings.Plugins) + + defaultValue = 42 + settingsEntryVariantDynamic = QgsSettingsEntryVariant(settingsKeyDynamic, self.pluginName, defaultValue, "Variant value for dynamic key functionality test") + + # Check key + self.assertEqual(settingsEntryVariantDynamic.key(dynamicKeyPart1), settingsKeyComplete1) + self.assertEqual(settingsEntryVariantDynamic.key(dynamicKeyPart2), settingsKeyComplete2) + + # Get set values + settingsEntryVariantDynamic.setValue(43, dynamicKeyPart1) + settingsEntryVariantDynamic.setValue(44, dynamicKeyPart2) + self.assertEqual(QgsSettings().value(settingsKeyComplete1, defaultValue, section=QgsSettings.Plugins), 43) + self.assertEqual(QgsSettings().value(settingsKeyComplete2, defaultValue, section=QgsSettings.Plugins), 44) + self.assertEqual(settingsEntryVariantDynamic.value(dynamicKeyPart1), 43) + self.assertEqual(settingsEntryVariantDynamic.value(dynamicKeyPart2), 44) + + def test_settings_entry_base_dynamic_multiple_keys(self): + settingsKeyDynamic = "settingsEntryBase/%1/anotherPart_%2/variantValue" + dynamicKeyPart1 = "first" + dynamicKeyPart2 = "second" + settingsKeyComplete = self.pluginName + "/" + settingsKeyDynamic.replace("%1", dynamicKeyPart1) + settingsKeyComplete = settingsKeyComplete.replace("%2", dynamicKeyPart2) + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 42 + settingsEntryVariantDynamic = QgsSettingsEntryVariant(settingsKeyDynamic, self.pluginName, defaultValue, "Variant value for dynamic multiple keys functionality test") + + # Check key + self.assertEqual(settingsEntryVariantDynamic.key([dynamicKeyPart1, dynamicKeyPart2]), settingsKeyComplete) + + # Get set values + settingsEntryVariantDynamic.setValue(43, [dynamicKeyPart1, dynamicKeyPart2]) + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), 43) + self.assertEqual(settingsEntryVariantDynamic.value([dynamicKeyPart1, dynamicKeyPart2]), 43) + + def test_settings_entry_variant(self): + settingsKey = "settingsEntryVariant/variantValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 42 + description = "Variant value functionality test" + settingsEntryVariant = QgsSettingsEntryVariant(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryVariant.valueAsVariant(), defaultValue) + settingsEntryVariant.setValue("abc") + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), "abc") + self.assertEqual(settingsEntryVariant.valueAsVariant(), "abc") + + # Settings type + self.assertEqual(settingsEntryVariant.settingsType(), QgsSettingsEntryBase.SettingsType.Variant) + + def test_settings_entry_string(self): + settingsKey = "settingsEntryString/stringValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = "abc" + description = "String value functionality test" + settingsEntryString = QgsSettingsEntryString(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryString.valueAsVariant(), defaultValue) + settingsEntryString.setValue("xyz") + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), "xyz") + self.assertEqual(settingsEntryString.valueAsVariant(), "xyz") + + # Settings type + self.assertEqual(settingsEntryString.settingsType(), QgsSettingsEntryBase.SettingsType.String) + + def test_settings_entry_stringlist(self): + settingsKey = "settingsEntryStringList/stringListValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = ["abc", "def"] + description = "String list value functionality test" + settingsEntryStringList = QgsSettingsEntryStringList(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryStringList.valueAsVariant(), defaultValue) + settingsEntryStringList.setValue(["uvw", "xyz"]) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), ["uvw", "xyz"]) + self.assertEqual(settingsEntryStringList.valueAsVariant(), ["uvw", "xyz"]) + + # Settings type + self.assertEqual(settingsEntryStringList.settingsType(), QgsSettingsEntryBase.SettingsType.StringList) + + def test_settings_entry_bool(self): + settingsKey = "settingsEntryBool/boolValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = False + description = "Bool value functionality test" + settingsEntryBool = QgsSettingsEntryBool(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryBool.valueAsVariant(), defaultValue) + settingsEntryBool.setValue(True) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), True) + self.assertEqual(settingsEntryBool.valueAsVariant(), True) + + # Settings type + self.assertEqual(settingsEntryBool.settingsType(), QgsSettingsEntryBase.SettingsType.Bool) + + def test_settings_entry_integer(self): + settingsKey = "settingsEntryInteger/integerValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 42 + description = "Integer value functionality test" + settingsEntryInteger = QgsSettingsEntryInteger(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryInteger.valueAsVariant(), defaultValue) + settingsEntryInteger.setValue(43) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), 43) + self.assertEqual(settingsEntryInteger.valueAsVariant(), 43) + + # Set/Get negative value + settingsEntryInteger.setValue(-42) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), -42) + self.assertEqual(settingsEntryInteger.valueAsVariant(), -42) + + # Settings type + self.assertEqual(settingsEntryInteger.settingsType(), QgsSettingsEntryBase.SettingsType.Integer) + + def test_settings_entry_double(self): + settingsKey = "settingsEntryDouble/doubleValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = 3.14 + description = "Double value functionality test" + settingsEntryDouble = QgsSettingsEntryDouble(settingsKey, self.pluginName, defaultValue, description) + + # Set/Get value + # as settings still does not exists return default value + self.assertEqual(settingsEntryDouble.valueAsVariant(), defaultValue) + settingsEntryDouble.setValue(1.618) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), 1.618) + self.assertEqual(settingsEntryDouble.valueAsVariant(), 1.618) + + # Set/Get negative value + settingsEntryDouble.setValue(-273.15) + # Verify setValue using QgsSettings + self.assertEqual(QgsSettings().value(settingsKeyComplete, defaultValue, section=QgsSettings.Plugins), -273.15) + self.assertEqual(settingsEntryDouble.valueAsVariant(), -273.15) + + # Settings type + self.assertEqual(settingsEntryDouble.settingsType(), QgsSettingsEntryBase.SettingsType.Double) + + def test_settings_entry_enum(self): + settingsKey = "settingsEntryEnum/enumValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + defaultValue = QgsUnitTypes.LayoutMeters + description = "Enum value functionality test" + settingsEntryEnum = QgsSettingsEntryEnum(settingsKey, self.pluginName, defaultValue, description) + + # Check default value + self.assertEqual(settingsEntryEnum.defaultValue(), QgsUnitTypes.LayoutMeters) + + # Check set value + success = settingsEntryEnum.setValue(QgsUnitTypes.LayoutFeet) + self.assertEqual(success, True) + qgsSettingsValue = QgsSettings().enumValue(settingsKeyComplete, QgsUnitTypes.LayoutMeters, QgsSettings.Plugins) + self.assertEqual(qgsSettingsValue, QgsUnitTypes.LayoutFeet) + + # Check get value + QgsSettings().setEnumValue(settingsKeyComplete, QgsUnitTypes.LayoutPicas, QgsSettings.Plugins) + self.assertEqual(settingsEntryEnum.value(), QgsUnitTypes.LayoutPicas) + + # Check settings type + self.assertEqual(settingsEntryEnum.settingsType(), QgsSettingsEntryBase.SettingsType.Enum) + + # assign to inexisting value + success = settingsEntryEnum.setValue(-1) + self.assertEqual(success, False) + + # Current value should not have changed + qgsSettingsValue = QgsSettings().enumValue(settingsKeyComplete, QgsUnitTypes.LayoutMeters, QgsSettings.Plugins) + self.assertEqual(qgsSettingsValue, QgsUnitTypes.LayoutPicas) + + def test_settings_entry_flag(self): + settingsKey = "settingsEntryFlag/flagValue" + settingsKeyComplete = self.pluginName + "/" + settingsKey + + pointAndLine = QgsMapLayerProxyModel.Filters(QgsMapLayerProxyModel.PointLayer | QgsMapLayerProxyModel.LineLayer) + pointAndPolygon = QgsMapLayerProxyModel.Filters(QgsMapLayerProxyModel.PointLayer | QgsMapLayerProxyModel.PolygonLayer) + hasGeometry = QgsMapLayerProxyModel.Filters(QgsMapLayerProxyModel.HasGeometry) + + # Make sure settings does not exists + QgsSettings().remove(settingsKeyComplete, QgsSettings.Plugins) + + description = "Flag value functionality test" + settingsEntryFlag = QgsSettingsEntryFlag(settingsKey, self.pluginName, pointAndLine, description) + + # Check default value + self.assertEqual(settingsEntryFlag.defaultValue(), pointAndLine) + + # Check set value + success = settingsEntryFlag.setValue(hasGeometry) + self.assertEqual(success, True) + qgsSettingsValue = QgsSettings().flagValue(settingsKeyComplete, pointAndLine, QgsSettings.Plugins) + self.assertEqual(qgsSettingsValue, hasGeometry) + + # Check get value + QgsSettings().setValue(settingsKeyComplete, 'PointLayer|PolygonLayer', QgsSettings.Plugins) + self.assertEqual(settingsEntryFlag.value(), pointAndPolygon) + + # Check settings type + self.assertEqual(settingsEntryFlag.settingsType(), QgsSettingsEntryBase.SettingsType.Flag) + + +if __name__ == '__main__': + unittest.main()