Merge pull request #52847 from 3nids/settings-treewidget

Settings editors
This commit is contained in:
Denis Rouzaud 2023-05-02 21:31:35 +02:00 committed by GitHub
commit 30a641111d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 2885 additions and 682 deletions

View File

@ -132,7 +132,7 @@ class PyQgsSettingsEntryEnumFlag(QgsSettingsEntryBase):
elif dynamicKeyPart is None:
dynamicKeyPart = []
return super().setVariantValuePrivate(enum_flag_key, dynamicKeyPart)
return super().setVariantValue(enum_flag_key, dynamicKeyPart)
def settingsType(self):
"""

View File

@ -12,6 +12,8 @@
class QgsSettingsEntryBase
{
%Docstring(signature="appended")
@ -93,6 +95,14 @@ Constructor for QgsSettingsEntryBase.
virtual ~QgsSettingsEntryBase();
virtual QString typeId() const;
%Docstring
Returns the id of the type of settings
This can be re-implemented in a custom implementation of a setting
.. versionadded:: 3.32
%End
QString name() const;
%Docstring
Returns the name of the settings
@ -191,26 +201,21 @@ Returns settings section. The settings section of the parent group is returned i
the key is entirely self-defined
%End
virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const /Deprecated/;
bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const;
%Docstring
Set settings value.
:param value: specifies the value to set.
:param dynamicKeyPart: specifies the dynamic part of the settings key.
.. deprecated:: QGIS 3.26
use setVariantValuePrivate or an implementation setValue instead
%End
virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const /Deprecated/;
bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const;
%Docstring
Set settings value.
This should be called from any implementation as it takes care of actually calling QSettings
:param value: specifies the value to set.
:param dynamicKeyPartList: specifies the list of dynamic parts of the settings key.
.. deprecated:: QGIS 3.26
use setVariantValuePrivate or an implementation setValue instead
%End
QVariant valueAsVariant( const QString &dynamicKeyPart = QString() ) const;
@ -330,31 +335,23 @@ Returns the parent tree element
.. versionadded:: 3.30
%End
protected:
bool setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList = QStringList() ) const;
virtual bool checkValueVariant( const QVariant &value ) const;
%Docstring
Sets the settings value with a variant value.
This should be called from any implementation as it takes care of actually calling QSettings
.. versionadded:: 3.26
Returns ``True`` if the given ``value`` is valid towards the setting definition
%End
};
template<T>
class QgsSettingsEntryByReference : QgsSettingsEntryBase
class QgsSettingsEntryBaseTemplate : QgsSettingsEntryBase
{
%Docstring(signature="appended")
Base abstract class for settings entry which are passed by reference
Base abstract class for settings entries with typed get and set methods
.. seealso:: :py:class:`QgsSettingsEntryBase`
.. seealso:: :py:class:`QgsSettingsEntryByValue`
.. versionadded:: 3.26
.. versionadded:: 3.32
%End
%TypeHeaderCode
@ -362,13 +359,13 @@ Base abstract class for settings entry which are passed by reference
%End
public:
QgsSettingsEntryByReference( const QString &name,
QgsSettingsTreeNode *parent,
const T &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() );
QgsSettingsEntryBaseTemplate( const QString &name,
QgsSettingsTreeNode *parent,
const QVariant &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() );
%Docstring
Constructor for QgsSettingsEntryByReference.
Constructor for :py:class:`QgsSettingsEntryByReference`.
:param name: specifies the key of the settings.
:param parent: specifies the parent in the tree of settings.
@ -381,13 +378,13 @@ Constructor for QgsSettingsEntryByReference.
.. versionadded:: 3.30
%End
QgsSettingsEntryByReference( const QString &key,
const QString &section,
const T &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() );
QgsSettingsEntryBaseTemplate( const QString &key,
const QString &section,
const QVariant &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() );
%Docstring
Constructor for QgsSettingsEntryByReference.
Constructor for :py:class:`QgsSettingsEntryByReference`.
:param key: specifies the key of the settings.
:param section: specifies the section.
@ -424,22 +421,6 @@ Returns the settings value with a ``defaultValueOverride`` and with an optional
Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList``
%End
T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const T &defaultValueOverride ) const /Deprecated/;
%Docstring
Returns the settings value for the ``dynamicKeyPart`` and with a ``defaultValueOverride``
.. deprecated:: QGIS 3.26
use valueAsVariantWithDefaultOverride instead
%End
T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const T &defaultValueOverride ) const /Deprecated/;
%Docstring
Returns the settings value for the ``dynamicKeyPartList`` and with a ``defaultValueOverride``
.. deprecated:: QGIS 3.26
use valueAsVariantWithDefaultOverride instead
%End
bool setValue( const T &value, const QString &dynamicKeyPart = QString() ) const;
%Docstring
Set settings value.
@ -473,15 +454,17 @@ Returns the former value
Returns the current value (or default) if there is no former value.
%End
protected:
bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const;
%Docstring
Sets the settings value with an optional list of dynamic parts
%End
virtual bool checkValueVariant( const QVariant &value ) const;
virtual T convertFromVariant( const QVariant &value ) const = 0;
%Docstring
Converts the variant value to the value type of the setting
%End
protected:
virtual bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const;
%Docstring
Sets the settings value with an optional list of dynamic parts
%End
virtual QVariant convertToVariant( const T &value ) const;
@ -489,152 +472,13 @@ Converts the variant value to the value type of the setting
Converts the value to a variant
%End
virtual bool checkValue( const T &value ) const;
virtual bool checkValuePrivate( const T &value ) const;
%Docstring
Check if the value is valid
%End
};
template<T>
class QgsSettingsEntryByValue : QgsSettingsEntryBase
{
%Docstring(signature="appended")
Base abstract class for settings entry which are passed by value
.. seealso:: :py:class:`QgsSettingsEntryBase`
.. seealso:: :py:class:`QgsSettingsEntryByReference`
.. versionadded:: 3.26
%End
%TypeHeaderCode
#include "qgssettingsentry.h"
%End
public:
QgsSettingsEntryByValue( const QString &key, QgsSettingsTreeNode *parent, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() );
%Docstring
Constructor for QgsSettingsEntryByValue.
:param key: specifies the key of the settings.
:param parent: specifies the parent in the tree of settings.
:param defaultValue: specifies the default value for the settings entry.
:param description: specifies a description for the settings entry.
:param options: specifies the options for the settings entry.
:raises QgsSettingsException: if the number of given parent named items doesn't match the complete key definition
%End
QgsSettingsEntryByValue( const QString &key, const QString &section, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() );
%Docstring
Constructor for QgsSettingsEntryByValue.
:param key: specifies the key of the settings.
:param section: specifies the section.
:param defaultValue: specifies the default value for the settings entry.
:param description: specifies a description for the settings entry.
:param options: specifies the options for the settings entry.
%End
virtual Qgis::SettingsType settingsType() const = 0;
T value( const QString &dynamicKeyPart = QString() ) const;
%Docstring
Returns settings value.
:param dynamicKeyPart: specifies the dynamic part of the settings key.
%End
T value( const QStringList &dynamicKeyPartList ) const;
%Docstring
Returns settings value.
:param dynamicKeyPartList: specifies the list of dynamic parts of the settings key.
%End
T valueWithDefaultOverride( T defaultValueOverride, const QString &dynamicKeyPart = QString() ) const;
%Docstring
Returns the settings value with a ``defaultValueOverride`` and with an optional ``dynamicKeyPart``
%End
T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const;
%Docstring
Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList``
%End
T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, T defaultValueOverride ) const /Deprecated/;
%Docstring
Returns the settings value for the ``dynamicKeyPart`` and with a ``defaultValueOverride``
.. deprecated:: QGIS 3.26
use valueWithDefaultOverride instead
%End
T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, T defaultValueOverride ) const /Deprecated/;
%Docstring
Returns the settings value for the ``dynamicKeyPartList`` and with a ``defaultValueOverride``
.. deprecated:: QGIS 3.26
use valueWithDefaultOverride instead
%End
bool setValue( T value, const QString &dynamicKeyPart = QString() ) const;
%Docstring
Set settings value.
:param value: specifies the value to set.
:param dynamicKeyPart: specifies the dynamic part of the settings key.
%End
bool setValue( T value, const QStringList &dynamicKeyPartList ) const;
%Docstring
Set settings value.
:param value: specifies the value to set.
:param dynamicKeyPartList: specifies the list of dynamic parts of the settings key.
%End
T defaultValue() const;
%Docstring
Returns settings default value.
%End
T formerValue( const QString &dynamicKeyPart = QString() ) const;
%Docstring
Returns the former value
Returns the current value (or default) if there is no former value.
%End
T formerValue( const QStringList &dynamicKeyPartList ) const;
%Docstring
Returns the former value
Returns the current value (or default) if there is no former value.
%End
protected:
virtual bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const;
%Docstring
Sets the settings value with an optional list of dynamic parts
%End
virtual T convertFromVariant( const QVariant &value ) const = 0;
%Docstring
Converts the variant value to the value type of the setting
%End
virtual QVariant convertToVariant( T value ) const;
%Docstring
Converts the value to a variant
%End
virtual bool checkValue( T value ) const;
%Docstring
Check if the value is valid
%End
};
/************************************************************************

View File

@ -10,9 +10,9 @@
typedef QgsSettingsEntryByReference<QVariant> QgsSettingsEntryByReferenceQVariantBase;
typedef QgsSettingsEntryBaseTemplate<QVariant> QgsSettingsEntryBaseTemplateQVariantBase;
class QgsSettingsEntryVariant : QgsSettingsEntryByReferenceQVariantBase
class QgsSettingsEntryVariant : QgsSettingsEntryBaseTemplateQVariantBase
{
%Docstring(signature="appended")
@ -24,7 +24,7 @@ A variant settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByReference<QVariant> QgsSettingsEntryByReferenceQVariantBase;
typedef QgsSettingsEntryBaseTemplate<QVariant> QgsSettingsEntryBaseTemplateQVariantBase;
%End
public:
@ -107,14 +107,13 @@ Returns settings value.
virtual Qgis::SettingsType settingsType() const;
private:
virtual QVariant convertFromVariant( const QVariant &value ) const;
};
typedef QgsSettingsEntryByReference<QString> QgsSettingsEntryByReferenceQStringBase;
typedef QgsSettingsEntryBaseTemplate<QString> QgsSettingsEntryBaseTemplateQStringBase;
class QgsSettingsEntryString : QgsSettingsEntryByReferenceQStringBase
class QgsSettingsEntryString : QgsSettingsEntryBaseTemplateQStringBase
{
%Docstring(signature="appended")
@ -126,7 +125,7 @@ A string settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByReference<QString> QgsSettingsEntryByReferenceQStringBase;
typedef QgsSettingsEntryBaseTemplate<QString> QgsSettingsEntryBaseTemplateQStringBase;
%End
public:
@ -203,18 +202,19 @@ Returns the string minimum length.
Returns the string maximum length. By -1 there is no limitation.
%End
private:
virtual bool checkValue( const QString &value ) const;
virtual QString convertFromVariant( const QVariant &value ) const;
private:
virtual bool checkValuePrivate( const QString &value ) const;
};
typedef QgsSettingsEntryByReference<QStringList> QgsSettingsEntryByReferenceQStringListBase;
typedef QgsSettingsEntryBaseTemplate<QStringList> QgsSettingsEntryBaseTemplateQStringListBase;
class QgsSettingsEntryStringList : QgsSettingsEntryByReferenceQStringListBase
class QgsSettingsEntryStringList : QgsSettingsEntryBaseTemplateQStringListBase
{
%Docstring(signature="appended")
@ -226,7 +226,7 @@ A string list settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByReference<QStringList> QgsSettingsEntryByReferenceQStringListBase;
typedef QgsSettingsEntryBaseTemplate<QStringList> QgsSettingsEntryBaseTemplateQStringListBase;
%End
public:
@ -284,16 +284,15 @@ This constructor is intended to be used from plugins.
virtual Qgis::SettingsType settingsType() const;
private:
virtual QStringList convertFromVariant( const QVariant &value ) const;
};
typedef QgsSettingsEntryByValue<bool> QgsSettingsEntryByValueboolBase;
typedef QgsSettingsEntryBaseTemplate<bool> QgsSettingsEntryBaseTemplateboolBase;
class QgsSettingsEntryBool : QgsSettingsEntryByValueboolBase
class QgsSettingsEntryBool : QgsSettingsEntryBaseTemplateboolBase
{
%Docstring(signature="appended")
@ -305,7 +304,7 @@ A boolean settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByValue<bool> QgsSettingsEntryByValueboolBase;
typedef QgsSettingsEntryBaseTemplate<bool> QgsSettingsEntryBaseTemplateboolBase;
%End
public:
@ -363,16 +362,15 @@ This constructor is intended to be used from plugins.
virtual Qgis::SettingsType settingsType() const;
private:
virtual bool convertFromVariant( const QVariant &value ) const;
};
typedef QgsSettingsEntryByValue<int> QgsSettingsEntryByValueintBase;
typedef QgsSettingsEntryBaseTemplate<int> QgsSettingsEntryBaseTemplateintBase;
class QgsSettingsEntryInteger : QgsSettingsEntryByValueintBase
class QgsSettingsEntryInteger : QgsSettingsEntryBaseTemplateintBase
{
%Docstring(signature="appended")
@ -384,7 +382,7 @@ An integer settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByValue<int> QgsSettingsEntryByValueintBase;
typedef QgsSettingsEntryBaseTemplate<int> QgsSettingsEntryBaseTemplateintBase;
%End
public:
@ -463,18 +461,19 @@ Returns the minimum value.
Returns the maximum value.
%End
private:
virtual bool checkValue( int value ) const;
virtual int convertFromVariant( const QVariant &value ) const;
private:
virtual bool checkValuePrivate( const int &value ) const;
};
typedef QgsSettingsEntryByValue<double> QgsSettingsEntryByValuedoubleBase;
typedef QgsSettingsEntryBaseTemplate<double> QgsSettingsEntryBaseTemplatedoubleBase;
class QgsSettingsEntryDouble : QgsSettingsEntryByValuedoubleBase
class QgsSettingsEntryDouble : QgsSettingsEntryBaseTemplatedoubleBase
{
%Docstring(signature="appended")
@ -486,7 +485,7 @@ A double settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByValue<double> QgsSettingsEntryByValuedoubleBase;
typedef QgsSettingsEntryBaseTemplate<double> QgsSettingsEntryBaseTemplatedoubleBase;
%End
public:
@ -586,19 +585,20 @@ displayHintDecimals The number of decimals that should be shown in the Gui.
Returns how much decimals should be shown in the Gui.
%End
private:
virtual bool checkValue( double value ) const;
virtual double convertFromVariant( const QVariant &value ) const;
private:
virtual bool checkValuePrivate( const double &value ) const;
};
typedef QgsSettingsEntryByReference<QColor> QgsSettingsEntryByReferenceQColorBase;
typedef QgsSettingsEntryBaseTemplate<QColor> QgsSettingsEntryBaseTemplateQColorBase;
class QgsSettingsEntryColor : QgsSettingsEntryByReferenceQColorBase
class QgsSettingsEntryColor : QgsSettingsEntryBaseTemplateQColorBase
{
%Docstring(signature="appended")
@ -610,7 +610,7 @@ A color settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByReference<QColor> QgsSettingsEntryByReferenceQColorBase;
typedef QgsSettingsEntryBaseTemplate<QColor> QgsSettingsEntryBaseTemplateQColorBase;
%End
public:
@ -681,18 +681,18 @@ Returns ``True`` if transparency is allowed for the color
private:
virtual QColor convertFromVariant( const QVariant &value ) const;
virtual bool checkValue( const QColor &value ) const;
private:
virtual bool checkValuePrivate( const QColor &value ) const;
};
typedef QgsSettingsEntryByReference<QVariantMap> QgsSettingsEntryByReferenceQVariantMapBase;
typedef QgsSettingsEntryBaseTemplate<QVariantMap> QgsSettingsEntryBaseTemplateQVariantMapBase;
class QgsSettingsEntryVariantMap : QgsSettingsEntryByReferenceQVariantMapBase
class QgsSettingsEntryVariantMap : QgsSettingsEntryBaseTemplateQVariantMapBase
{
%Docstring(signature="appended")
@ -704,7 +704,7 @@ A string list settings entry.
%TypeHeaderCode
#include "qgssettingsentryimpl.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryByReference<QVariantMap> QgsSettingsEntryByReferenceQVariantMapBase;
typedef QgsSettingsEntryBaseTemplate<QVariantMap> QgsSettingsEntryBaseTemplateQVariantMapBase;
%End
public:
@ -762,11 +762,11 @@ This constructor is intended to be used from plugins.
virtual Qgis::SettingsType settingsType() const;
private:
virtual QVariantMap convertFromVariant( const QVariant &value ) const;
};
/************************************************************************
* This file has been generated automatically from *
* *

View File

@ -0,0 +1,7 @@
# The following has been generated automatically from src/gui/settings/qgssettingstreemodel.h
# monkey patching scoped based enum
QgsSettingsTreeModel.Column.Name.__doc__ = "Name"
QgsSettingsTreeModel.Column.Value.__doc__ = "Value"
QgsSettingsTreeModel.Column.Description.__doc__ = "Description"
QgsSettingsTreeModel.Column.__doc__ = 'Columns\n\n' + '* ``Name``: ' + QgsSettingsTreeModel.Column.Name.__doc__ + '\n' + '* ``Value``: ' + QgsSettingsTreeModel.Column.Value.__doc__ + '\n' + '* ``Description``: ' + QgsSettingsTreeModel.Column.Description.__doc__
# --

View File

@ -10,7 +10,6 @@
class QgsGui : QObject
{
%Docstring(signature="appended")
@ -167,6 +166,13 @@ Returns the global relation widget registry, used for managing all known relatio
Returns the global history provider registry, used for tracking history providers.
.. versionadded:: 3.24
%End
static QgsSettingsEditorWidgetRegistry *settingsEditorWidgetRegistry() /KeepReference/;
%Docstring
Returns the registry of settings editors.
.. versionadded:: 3.32
%End
static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );

View File

@ -9,7 +9,9 @@
class QgsOptionsDialogHighlightWidget : QObject
class QgsOptionsDialogHighlightWidget
{
%Docstring(signature="appended")
Container for a widget to be used to search text in the option dialog
@ -34,6 +36,8 @@ For instance a :py:class:`QgsOptionsDialogHighlightButton` for button.
for the given widget.
%End
virtual ~QgsOptionsDialogHighlightWidget();
bool isValid();
%Docstring
Returns if it valid: if the widget type is handled and if the widget is not still available
@ -51,11 +55,6 @@ search for a text pattern and highlight the widget if the text is found
Returns the widget
%End
virtual bool eventFilter( QObject *obj, QEvent *event );
protected:
virtual bool searchText( const QString &text ) = 0;

View File

@ -0,0 +1,55 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsSettingsEditorWidgetRegistry
{
%Docstring(signature="appended")
This class manages editor widgets for settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetregistry.h"
%End
public:
QgsSettingsEditorWidgetRegistry();
%Docstring
Constructor
%End
~QgsSettingsEditorWidgetRegistry();
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/ );
%Docstring
Adds an editor widget ``wrapper`` to the registry
Returns ``False`` if an editor widget with same id already exists.
%End
QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const;
%Docstring
Returns a new instance of the editor widget for the given ``id``
%End
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = 0 ) const /Factory/;
%Docstring
Creates an editor widget for the given ``setting`` using the corresponding registered wrapper
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,107 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetwrapper.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsSettingsEditorWidgetWrapper : QObject
{
%Docstring(signature="appended")
Base class for settings editor wrappers
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapper.h"
%End
public:
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) /Factory/;
%Docstring
Creates a wrapper from the definition stored in a ``widget`` created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor`
%End
QgsSettingsEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual ~QgsSettingsEditorWidgetWrapper();
virtual QString id() const = 0;
%Docstring
This id of the type of settings it handles
.. note::
This mostly correspond to the content of :py:class:`Qgis`.SettingsType but it's a string since custom Python implementation are possible.
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0;
%Docstring
Creates a new instance of the editor wrapper so it can be configured for a widget and a setting
%End
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = 0 );
%Docstring
Creates the editor widget for the given ``setting``
%End
bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() );
%Docstring
Configures the ``editor`` according the setting
%End
virtual bool setWidgetFromSetting() const = 0;
%Docstring
Sets the widget value from the setting value
The wrapper must be configured before calling this medthod
%End
virtual bool setSettingFromWidget() const = 0;
%Docstring
Sets the setting value from the widget value
The wrapper must be configured before calling this medthod
%End
virtual QVariant variantValueFromWidget() const = 0;
%Docstring
Returns the value from the widget as a variant
The wrapper must be configured before calling this medthod
%End
virtual void setWidgetFromVariant( const QVariant &value ) const = 0;
%Docstring
Sets the ``value`` of the widget
The wrapper must be configured before calling this medthod
%End
protected:
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0;
%Docstring
Creates the widgets
%End
virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0;
%Docstring
Configures an existing ``editor`` widget
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetwrapper.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,275 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetwrapperimpl.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
template<T,V,U>
class QgsSettingsEditorWidgetWrapperTemplate : QgsSettingsEditorWidgetWrapper
{
%Docstring(signature="appended")
This class is a base factory of editor for settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
%End
public:
QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QString id() const = 0;
virtual bool setWidgetFromSetting() const;
virtual bool setSettingFromWidget() const = 0;
virtual void setWidgetFromVariant( const QVariant &value ) const;
virtual bool setWidgetValue( const U &value ) const = 0;
%Docstring
Sets the widget value
%End
virtual QVariant variantValueFromWidget() const;
virtual U valueFromWidget() const = 0;
%Docstring
Returns the widget value
%End
V *editor() const;
%Docstring
Returns the editor
%End
const T *setting() const;
%Docstring
Returns the setting
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0;
protected:
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const;
virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting );
virtual void configureEditorPrivateImplementation();
%Docstring
To be re-implemented to implemeent type specific configuration (e.g. opacity for colors)
%End
};
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryString,QLineEdit,QString> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase;
class QgsSettingsStringEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase
{
%Docstring(signature="appended")
This class is a factory of editor for string settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryString,QLineEdit,QString> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryStringQLineEditQStringBase;
%End
public:
QgsSettingsStringEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const;
virtual QString id() const;
virtual bool setSettingFromWidget() const;
virtual QString valueFromWidget() const;
virtual bool setWidgetValue( const QString &value ) const;
};
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryBool,QCheckBox,bool> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase;
class QgsSettingsBoolEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase
{
%Docstring(signature="appended")
This class is a factory of editor for boolean settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryBool,QCheckBox,bool> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryBoolQCheckBoxboolBase;
%End
public:
QgsSettingsBoolEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const;
virtual QString id() const;
virtual bool setSettingFromWidget() const;
virtual bool valueFromWidget() const;
virtual bool setWidgetValue( const bool &value ) const;
};
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryInteger,QSpinBox,int> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase;
class QgsSettingsIntegerEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase
{
%Docstring(signature="appended")
This class is a factory of editor for integer settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryInteger,QSpinBox,int> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryIntegerQSpinBoxintBase;
%End
public:
QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const;
virtual QString id() const;
virtual bool setSettingFromWidget() const;
virtual int valueFromWidget() const;
virtual bool setWidgetValue( const int &value ) const;
};
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryDouble,QDoubleSpinBox,double> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase;
class QgsSettingsDoubleEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase
{
%Docstring(signature="appended")
This class is a factory of editor for double settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryDouble,QDoubleSpinBox,double> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryDoubleQDoubleSpinBoxdoubleBase;
%End
public:
QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const;
virtual QString id() const;
virtual bool setSettingFromWidget() const;
virtual double valueFromWidget() const;
virtual bool setWidgetValue( const double &value ) const;
};
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryColor,QgsColorButton,QColor> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase;
class QgsSettingsColorEditorWidgetWrapper : QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase
{
%Docstring(signature="appended")
This class is a factory of editor for color settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingseditorwidgetwrapperimpl.h"
typedef QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryColor,QgsColorButton,QColor> QgsSettingsEditorWidgetWrapperTemplateQgsSettingsEntryColorQgsColorButtonQColorBase;
%End
public:
QgsSettingsColorEditorWidgetWrapper( QObject *parent = 0 );
%Docstring
Constructor
%End
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const;
virtual QString id() const;
virtual bool setSettingFromWidget() const;
virtual QColor valueFromWidget() const;
virtual bool setWidgetValue( const QColor &value ) const;
virtual void configureEditorPrivateImplementation();
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingseditorwidgetwrapperimpl.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,111 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingstreemodel.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsSettingsTreeModel : QAbstractItemModel
{
%Docstring(signature="appended")
:py:class:`QgsSettingsTreeModel` is a tree model for the settings tree.
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingstreemodel.h"
%End
public:
enum class Column
{
Name,
Value,
Description,
};
QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode = 0, QObject *parent = 0 );
%Docstring
Constructor
%End
~QgsSettingsTreeModel();
void applyChanges();
%Docstring
Apply pending changes in the model to the corresponding settings
%End
virtual QModelIndex index( int row, int column, const QModelIndex &parent ) const;
virtual QModelIndex parent( const QModelIndex &child ) const;
virtual int rowCount( const QModelIndex &parent ) const;
virtual int columnCount( const QModelIndex &parent ) const;
virtual QVariant data( const QModelIndex &index, int role ) const;
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
virtual bool setData( const QModelIndex &index, const QVariant &value, int role );
};
class QgsSettingsTreeProxyModel : QSortFilterProxyModel
{
%Docstring(signature="appended")
:py:class:`QgsSettingsTreeProxyModel` allows filtering the settings tree
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingstreemodel.h"
%End
public:
QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode = 0, QObject *parent = 0 );
%Docstring
Constructor
%End
void applyChanges();
%Docstring
Apply pending changes in the model to the corresponding settings
%End
public slots:
void setFilterText( const QString &filterText = QString() );
%Docstring
Sets the filter text
%End
protected:
virtual bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const;
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingstreemodel.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,53 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingstreewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsSettingsTreeWidget : QWidget, QgsOptionsDialogHighlightWidget
{
%Docstring(signature="appended")
:py:class:`QgsSettingsTreeWidget` is a widget with the settings tree to visualize, search and edit settings
.. versionadded:: 3.32
%End
%TypeHeaderCode
#include "qgssettingstreewidget.h"
%End
public:
explicit QgsSettingsTreeWidget( QWidget *parent = 0 );
%Docstring
Constructor
%End
void applyChanges() const;
%Docstring
Apply changes to settings value
%End
protected:
virtual bool searchText( const QString &text );
virtual bool highlightText( const QString &text );
virtual void reset();
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/settings/qgssettingstreewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -487,7 +487,12 @@
%Include auto_generated/symbology/qgsvectorfieldsymbollayerwidget.sip
%Include auto_generated/sensor/qgssensorguiregistry.sip
%Include auto_generated/sensor/qgssensorwidget.sip
%Include auto_generated/settings/qgssettingseditorwidgetwrapper.sip
%Include auto_generated/settings/qgssettingseditorwidgetwrapperimpl.sip
%Include auto_generated/settings/qgssettingseditorwidgetregistry.sip
%Include auto_generated/settings/qgssettingsregistrygui.sip
%Include auto_generated/settings/qgssettingstreemodel.sip
%Include auto_generated/settings/qgssettingstreewidget.sip
%Include auto_generated/tableeditor/qgstableeditordialog.sip
%Include auto_generated/tableeditor/qgstableeditorwidget.sip
%Include auto_generated/vectortile/qgsvectortilelayerproperties.sip

View File

@ -2,8 +2,7 @@
class_headerfile:
QgsAbstractFeatureIteratorFromSource: qgsfeatureiterator.h
QgsSettingsEntryByReference: qgssettingsentry.h
QgsSettingsEntryByValue: qgssettingsentry.h
QgsSettingsEntryBaseTemplate: qgssettingsentry.h
no_export_macro:

View File

@ -284,7 +284,7 @@ set(QGIS_APP_SRCS
pluginmanager/qgspluginsortfilterproxymodel.cpp
pluginmanager/qgspluginitemdelegate.cpp
qgssettingstreewidget.cpp
qgssettingstreewidgetold.cpp
qgssettingsregistryapp.cpp
qgsvariantdelegate.cpp
qgscrashhandler.cpp
@ -536,6 +536,7 @@ target_include_directories(qgis_app PUBLIC
${CMAKE_SOURCE_DIR}/src/app/locator
${CMAKE_SOURCE_DIR}/src/app/options
${CMAKE_SOURCE_DIR}/src/app/pointcloud
${CMAKE_SOURCE_DIR}/src/app/settings
${CMAKE_SOURCE_DIR}/src/app/vectortile
${CMAKE_SOURCE_DIR}/src/plugins
${CMAKE_SOURCE_DIR}/src/python

View File

@ -14,26 +14,47 @@
***************************************************************************/
#include "qgsadvancedoptions.h"
#include "qgssettingstreewidget.h"
#include "qgssettingstreewidgetold.h"
#include "qgsapplication.h"
#include "qgssettings.h"
#include "qgis.h"
//
// QgsAdvancedSettingsWidget
//
const QgsSettingsEntryBool *QgsAdvancedSettingsWidget::settingsUseNewTreeWidget = new QgsSettingsEntryBool( QStringLiteral( "use-new-widget" ), sTreeSettings, true, QStringLiteral( "Use new settings widget" ) );
const QgsSettingsEntryBool *QgsAdvancedSettingsWidget::settingsShowWarning = new QgsSettingsEntryBool( QStringLiteral( "show-warning" ), sTreeSettings, true, QStringLiteral( "Show warning before opening the settings tree" ) );
QgsAdvancedSettingsWidget::QgsAdvancedSettingsWidget( QWidget *parent )
: QgsOptionsPageWidget( parent )
{
setupUi( this );
mUseNewSettingsTree->setChecked( settingsUseNewTreeWidget->value() );
layout()->setContentsMargins( 0, 0, 0, 0 );
connect( mAdvancedSettingsEnableButton, &QPushButton::clicked, this, [ = ]
if ( !settingsShowWarning->value() )
{
mAdvancedSettingsEditor->show();
mAdvancedSettingsWarning->hide();
} );
bool newTree = settingsUseNewTreeWidget->value();
createSettingsTreeWidget( newTree, !newTree, false );
}
else
{
createSettingsTreeWidget( true, true, true );
connect( mAdvancedSettingsEnableButton, &QPushButton::clicked, this, [ = ]
{
settingsUseNewTreeWidget->setValue( mUseNewSettingsTree->isChecked() );
mAdvancedSettingsWarning->hide();
if ( settingsUseNewTreeWidget->value() )
mTreeWidget->show();
else
mTreeWidgetOld->show();
} );
}
}
QgsAdvancedSettingsWidget::~QgsAdvancedSettingsWidget()
@ -42,12 +63,30 @@ QgsAdvancedSettingsWidget::~QgsAdvancedSettingsWidget()
void QgsAdvancedSettingsWidget::apply()
{
// nothing to do -- mAdvancedSettingsEditor applies changes immediately
// the old settings editor applies changes immediately
// new settings tree is performing changes on apply
if ( mTreeWidget )
mTreeWidget->applyChanges();
}
QgsSettingsTreeWidget *QgsAdvancedSettingsWidget::settingsTree()
void QgsAdvancedSettingsWidget::createSettingsTreeWidget( bool newWidget, bool oldWidget, bool hide )
{
return mAdvancedSettingsEditor;
if ( newWidget )
{
mTreeWidget = new QgsSettingsTreeWidget( this );
mGroupBox->layout()->addWidget( mTreeWidget );
if ( hide )
mTreeWidget->hide();
}
if ( oldWidget )
{
mTreeWidgetOld = new QgsSettingsTreeWidgetOld( this );
mGroupBox->layout()->addWidget( mTreeWidgetOld );
if ( hide )
mTreeWidgetOld->hide();
}
}
//

View File

@ -17,8 +17,11 @@
#include "ui_qgsadvancedsettingswidget.h"
#include "qgsoptionswidgetfactory.h"
#include "qgssettings.h"
#include "qgssettingstreewidget.h"
#include "qgssettingstree.h"
#include "qgssettingsentryimpl.h"
class QgsSettingsTreeWidget;
class QgsSettingsTreeWidgetOld;
/**
* \ingroup app
@ -33,6 +36,11 @@ class QgsAdvancedSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsAd
public:
static inline QgsSettingsTreeNode *sTreeSettings = QgsSettingsTree::sTreeApp->createChildNode( QStringLiteral( "settings" ) );
static const QgsSettingsEntryBool *settingsUseNewTreeWidget;
static const QgsSettingsEntryBool *settingsShowWarning;
/**
* Constructor for QgsAdvancedSettingsWidget with the specified \a parent widget.
*/
@ -40,11 +48,11 @@ class QgsAdvancedSettingsWidget : public QgsOptionsPageWidget, private Ui::QgsAd
~QgsAdvancedSettingsWidget() override;
void apply() override;
QgsSettingsTreeWidget *settingsTree();
private:
void createSettingsTreeWidget( bool newWidget, bool oldWidget, bool hide );
QgsSettings mSettings;
QgsSettingsTreeWidget *mTreeWidget = nullptr;
QgsSettingsTreeWidgetOld *mTreeWidgetOld = nullptr;
};

View File

@ -1182,11 +1182,6 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
addPage( factory->title(), factory->title(), factory->icon(), page, factory->path(), factory->key() );
else
insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage, factory->path(), factory->key() );
if ( QgsAdvancedSettingsWidget *advancedPage = qobject_cast< QgsAdvancedSettingsWidget * >( page ) )
{
advancedPage->settingsTree()->setSettingsObject( mSettings );
}
}
if ( mOptTreeView )

View File

@ -41,7 +41,7 @@
#include <QHeaderView>
#include <QEvent>
#include "qgssettingstreewidget.h"
#include "qgssettingstreewidgetold.h"
#include "qgsvariantdelegate.h"
#include "qgslogger.h"
#include "qgssettings.h"
@ -51,7 +51,7 @@
#include <QMenu>
#include <QMessageBox>
QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent )
QgsSettingsTreeWidgetOld::QgsSettingsTreeWidgetOld( QWidget *parent )
: QTreeWidget( parent )
{
setItemDelegate( new QgsVariantDelegate( this ) );
@ -72,45 +72,25 @@ QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent )
setEditTriggers( QAbstractItemView::AllEditTriggers );
connect( &mRefreshTimer, &QTimer::timeout, this, &QgsSettingsTreeWidget::maybeRefresh );
connect( &mRefreshTimer, &QTimer::timeout, this, &QgsSettingsTreeWidgetOld::maybeRefresh );
setContextMenuPolicy( Qt::CustomContextMenu );
connect( this, &QTreeWidget::customContextMenuRequested, this, &QgsSettingsTreeWidget::showContextMenu );
connect( this, &QTreeWidget::customContextMenuRequested, this, &QgsSettingsTreeWidgetOld::showContextMenu );
mContextMenu = new QMenu( this );
}
void QgsSettingsTreeWidget::setSettingsObject( QgsSettings *settings )
{
mSettings = settings;
clear();
if ( mSettings )
{
mSettings->setParent( this );
if ( isVisible() )
refresh();
if ( mAutoRefresh )
mRefreshTimer.start();
}
else
{
mRefreshTimer.stop();
}
}
QSize QgsSettingsTreeWidget::sizeHint() const
QSize QgsSettingsTreeWidgetOld::sizeHint() const
{
return QSize( 800, 600 );
}
void QgsSettingsTreeWidget::setAutoRefresh( bool autoRefresh )
void QgsSettingsTreeWidgetOld::setAutoRefresh( bool autoRefresh )
{
mAutoRefresh = autoRefresh;
if ( mAutoRefresh )
{
maybeRefresh();
if ( mSettings )
mRefreshTimer.start();
mRefreshTimer.start();
}
else
{
@ -118,29 +98,26 @@ void QgsSettingsTreeWidget::setAutoRefresh( bool autoRefresh )
}
}
void QgsSettingsTreeWidget::maybeRefresh()
void QgsSettingsTreeWidgetOld::maybeRefresh()
{
if ( state() != EditingState )
refresh();
}
void QgsSettingsTreeWidget::refresh()
void QgsSettingsTreeWidgetOld::refresh()
{
if ( !mSettings )
return;
disconnect( this, &QTreeWidget::itemChanged,
this, &QgsSettingsTreeWidget::updateSetting );
this, &QgsSettingsTreeWidgetOld::updateSetting );
mSettings->sync();
mSettings.sync();
// add any settings not in QgsSettings object, so it will show up in the tree view
QMap<QString, QStringList>::const_iterator it = mSettingsMap.constBegin();
while ( it != mSettingsMap.constEnd() )
{
if ( ! mSettings->contains( it.key() ) )
if ( ! mSettings.contains( it.key() ) )
{
mSettings->setValue( it.key(), it.value().at( 3 ) );
mSettings.setValue( it.key(), it.value().at( 3 ) );
}
++it;
}
@ -148,10 +125,10 @@ void QgsSettingsTreeWidget::refresh()
updateChildItems( nullptr );
connect( this, &QTreeWidget::itemChanged,
this, &QgsSettingsTreeWidget::updateSetting );
this, &QgsSettingsTreeWidgetOld::updateSetting );
}
bool QgsSettingsTreeWidget::event( QEvent *event )
bool QgsSettingsTreeWidgetOld::event( QEvent *event )
{
if ( event->type() == QEvent::WindowActivate )
{
@ -161,24 +138,24 @@ bool QgsSettingsTreeWidget::event( QEvent *event )
return QTreeWidget::event( event );
}
void QgsSettingsTreeWidget::showEvent( QShowEvent * )
void QgsSettingsTreeWidgetOld::showEvent( QShowEvent * )
{
const QgsTemporaryCursorOverride waitCursor( Qt::BusyCursor );
refresh();
}
void QgsSettingsTreeWidget::updateSetting( QTreeWidgetItem *item )
void QgsSettingsTreeWidgetOld::updateSetting( QTreeWidgetItem *item )
{
const QString key = itemKey( item );
if ( key.isNull() )
return;
mSettings->setValue( key, item->data( ColumnValue, Qt::UserRole ) );
mSettings.setValue( key, item->data( ColumnValue, Qt::UserRole ) );
if ( mAutoRefresh )
refresh();
}
void QgsSettingsTreeWidget::showContextMenu( QPoint pos )
void QgsSettingsTreeWidgetOld::showContextMenu( QPoint pos )
{
QTreeWidgetItem *item = itemAt( pos );
if ( !item )
@ -202,7 +179,7 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos )
return;
mSettings->remove( itemPath );
mSettings.remove( itemPath );
refresh();
} );
@ -220,7 +197,7 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos )
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;
mSettings->remove( itemPath );
mSettings.remove( itemPath );
refresh();
} );
@ -233,11 +210,11 @@ void QgsSettingsTreeWidget::showContextMenu( QPoint pos )
mContextMenu->exec( mapToGlobal( pos ) );
}
void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent )
void QgsSettingsTreeWidgetOld::updateChildItems( QTreeWidgetItem *parent )
{
int dividerIndex = 0;
const auto constChildGroups = mSettings->childGroups();
const auto constChildGroups = mSettings.childGroups();
for ( const QString &group : constChildGroups )
{
QTreeWidgetItem *child = nullptr;
@ -257,12 +234,12 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent )
child->setIcon( ColumnSettings, mGroupIcon );
++dividerIndex;
mSettings->beginGroup( group );
mSettings.beginGroup( group );
updateChildItems( child );
mSettings->endGroup();
mSettings.endGroup();
}
const auto constChildKeys = mSettings->childKeys();
const auto constChildKeys = mSettings.childKeys();
for ( const QString &key : constChildKeys )
{
QTreeWidgetItem *child = nullptr;
@ -289,7 +266,7 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent )
child = childAt( parent, childIndex );
}
const QVariant value = mSettings->value( key );
const QVariant value = mSettings.value( key );
if ( value.type() == QVariant::Invalid )
{
child->setText( ColumnType, QStringLiteral( "Invalid" ) );
@ -306,7 +283,7 @@ void QgsSettingsTreeWidget::updateChildItems( QTreeWidgetItem *parent )
delete childAt( parent, dividerIndex );
}
QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text,
QTreeWidgetItem *QgsSettingsTreeWidgetOld::createItem( const QString &text,
QTreeWidgetItem *parent, int index, const bool isGroup )
{
QTreeWidgetItem *after = nullptr;
@ -325,7 +302,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text,
item->setData( ColumnSettings, TypeRole, isGroup ? Group : Setting );
const QString completeSettingsPath = mSettings->group().isEmpty() ? text : mSettings->group() + '/' + text;
const QString completeSettingsPath = mSettings.group().isEmpty() ? text : mSettings.group() + '/' + text;
item->setData( ColumnSettings, PathRole, completeSettingsPath );
const QString key = itemKey( item );
@ -343,7 +320,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::createItem( const QString &text,
return item;
}
QString QgsSettingsTreeWidget::itemKey( QTreeWidgetItem *item )
QString QgsSettingsTreeWidgetOld::itemKey( QTreeWidgetItem *item )
{
if ( ! item )
return QString();
@ -359,7 +336,7 @@ QString QgsSettingsTreeWidget::itemKey( QTreeWidgetItem *item )
return key;
}
QTreeWidgetItem *QgsSettingsTreeWidget::childAt( QTreeWidgetItem *parent, int index )
QTreeWidgetItem *QgsSettingsTreeWidgetOld::childAt( QTreeWidgetItem *parent, int index )
{
if ( parent )
return parent->child( index );
@ -367,7 +344,7 @@ QTreeWidgetItem *QgsSettingsTreeWidget::childAt( QTreeWidgetItem *parent, int in
return topLevelItem( index );
}
int QgsSettingsTreeWidget::childCount( QTreeWidgetItem *parent )
int QgsSettingsTreeWidgetOld::childCount( QTreeWidgetItem *parent )
{
if ( parent )
return parent->childCount();
@ -375,8 +352,8 @@ int QgsSettingsTreeWidget::childCount( QTreeWidgetItem *parent )
return topLevelItemCount();
}
int QgsSettingsTreeWidget::findChild( QTreeWidgetItem *parent, const QString &text,
int startIndex )
int QgsSettingsTreeWidgetOld::findChild( QTreeWidgetItem *parent, const QString &text,
int startIndex )
{
for ( int i = startIndex; i < childCount( parent ); ++i )
{
@ -386,7 +363,7 @@ int QgsSettingsTreeWidget::findChild( QTreeWidgetItem *parent, const QString &te
return -1;
}
void QgsSettingsTreeWidget::moveItemForward( QTreeWidgetItem *parent, int oldIndex,
void QgsSettingsTreeWidgetOld::moveItemForward( QTreeWidgetItem *parent, int oldIndex,
int newIndex )
{
for ( int i = 0; i < oldIndex - newIndex; ++i )

View File

@ -38,16 +38,16 @@
**
****************************************************************************/
#ifndef QGSSETTINGSTREEWIDGET_H
#define QGSSETTINGSTREEWIDGET_H
#ifndef QGSSETTINGSTREEWIDGETOLD_H
#define QGSSETTINGSTREEWIDGETOLD_H
#include "qgssettings.h"
#include <QIcon>
#include <QTimer>
#include <QTreeWidget>
class QgsSettings;
class QgsSettingsTreeWidget : public QTreeWidget
class QgsSettingsTreeWidgetOld : public QTreeWidget
{
Q_OBJECT
@ -68,9 +68,8 @@ class QgsSettingsTreeWidget : public QTreeWidget
};
Q_ENUM( Type )
explicit QgsSettingsTreeWidget( QWidget *parent = nullptr );
explicit QgsSettingsTreeWidgetOld( QWidget *parent = nullptr );
void setSettingsObject( QgsSettings *mSettings );
QSize sizeHint() const override;
void setSettingsMap( QMap< QString, QStringList > &map ) { mSettingsMap = map; }
@ -107,7 +106,7 @@ class QgsSettingsTreeWidget : public QTreeWidget
int findChild( QTreeWidgetItem *parent, const QString &text, int startIndex );
void moveItemForward( QTreeWidgetItem *parent, int oldIndex, int newIndex );
QgsSettings *mSettings = nullptr;
QgsSettings mSettings;
QTimer mRefreshTimer;
bool mAutoRefresh = false;
QIcon mGroupIcon;

View File

@ -43,6 +43,11 @@ QgsSettingsEntryBase::~QgsSettingsEntryBase()
mParentTreeElement->unregisterChildSetting( this );
}
QString QgsSettingsEntryBase::typeId() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( settingsType() ) ) );
}
QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const
{
@ -139,15 +144,10 @@ int QgsSettingsEntryBase::section() const
bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QString &dynamicKeyPart ) const
{
return setVariantValuePrivate( value, dynamicKeyPartToList( dynamicKeyPart ) );
return setVariantValue( value, dynamicKeyPartToList( dynamicKeyPart ) );
}
bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const
{
return setVariantValuePrivate( value, dynamicKeyPartList );
}
bool QgsSettingsEntryBase::setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList ) const
{
if ( mOptions.testFlag( Qgis::SettingsOption::SaveFormerValue ) )
{
@ -243,7 +243,7 @@ bool QgsSettingsEntryBase::copyValueFromKey( const QString &key, const QStringLi
if ( settings.contains( oldCompleteKey ) )
{
QVariant oldValue = settings.value( oldCompleteKey, mDefaultValue );
setVariantValuePrivate( oldValue, dynamicKeyPartList );
setVariantValue( oldValue, dynamicKeyPartList );
if ( removeSettingAtKey )
settings.remove( oldCompleteKey );
return true;

View File

@ -28,6 +28,9 @@
class QgsSettingsTreeNode;
static const inline QMetaEnum sSettingsTypeMetaEnum = QMetaEnum::fromType<Qgis::SettingsType>() SIP_SKIP;
/**
* \ingroup core
* \class QgsSettingsEntryBase
@ -118,6 +121,13 @@ class CORE_EXPORT QgsSettingsEntryBase
*/
virtual ~QgsSettingsEntryBase();
/**
* Returns the id of the type of settings
* This can be re-implemented in a custom implementation of a setting
* \since QGIS 3.32
*/
virtual QString typeId() const;
/**
* Returns the name of the settings
* \since QGIS 3.30
@ -213,18 +223,16 @@ class CORE_EXPORT QgsSettingsEntryBase
*
* \param value specifies the value to set.
* \param dynamicKeyPart specifies the dynamic part of the settings key.
* \deprecated since QGIS 3.26 use setVariantValuePrivate or an implementation setValue instead
*/
Q_DECL_DEPRECATED virtual bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const SIP_DEPRECATED;
bool setVariantValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) const;
/**
* Set settings value.
*
* \param value specifies the value to set.
* This should be called from any implementation as it takes care of actually calling QSettings
* \param value specifies the value to set.
* \param dynamicKeyPartList specifies the list of dynamic parts of the settings key.
* \deprecated since QGIS 3.26 use setVariantValuePrivate or an implementation setValue instead
*/
Q_DECL_DEPRECATED virtual bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const SIP_DEPRECATED;
bool setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const;
//! Returns settings value with \param dynamicKeyPart specifying the dynamic part of the settings key.
QVariant valueAsVariant( const QString &dynamicKeyPart = QString() ) const;
@ -323,14 +331,12 @@ class CORE_EXPORT QgsSettingsEntryBase
*/
QgsSettingsTreeNode *parent() const {return mParentTreeElement;}
protected:
/**
* Sets the settings value with a variant value.
* This should be called from any implementation as it takes care of actually calling QSettings
* \since QGIS 3.26
*/
bool setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList = QStringList() ) const;
//! Returns TRUE if the given \a value is valid towards the setting definition
virtual bool checkValueVariant( const QVariant &value ) const
{
Q_UNUSED( value )
return true;
}
private:
QString formerValuekey( const QStringList &dynamicKeyPartList ) const;
@ -345,19 +351,17 @@ class CORE_EXPORT QgsSettingsEntryBase
Qgis::SettingsOptions mOptions;
};
/**
* \ingroup core
* \class QgsSettingsEntryByReference
* \class QgsSettingsEntryBaseTemplate
*
* \brief Base abstract class for settings entry which are passed by reference
* \brief Base abstract class for settings entries with typed get and set methods
* \see QgsSettingsEntryBase
* \see QgsSettingsEntryByValue
*
* \since QGIS 3.26
* \since QGIS 3.32
*/
template<class T>
class QgsSettingsEntryByReference : public QgsSettingsEntryBase
class QgsSettingsEntryBaseTemplate : public QgsSettingsEntryBase
{
public:
@ -373,11 +377,11 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
*
* \since QGIS 3.30
*/
QgsSettingsEntryByReference( const QString &name,
QgsSettingsTreeNode *parent,
const T &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() )
QgsSettingsEntryBaseTemplate( const QString &name,
QgsSettingsTreeNode *parent,
const QVariant &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( name, parent, defaultValue, description, options )
{}
@ -390,11 +394,11 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
* \param description specifies a description for the settings entry.
* \param options specifies the options for the settings entry.
*/
QgsSettingsEntryByReference( const QString &key,
const QString &section,
const T &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() )
QgsSettingsEntryBaseTemplate( const QString &key,
const QString &section,
const QVariant &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( key, section, defaultValue, description, options )
{}
@ -428,30 +432,6 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPartList ) );
}
/**
* Returns the settings value for the \a dynamicKeyPart and with a \a defaultValueOverride
* \deprecated since QGIS 3.26 use valueAsVariantWithDefaultOverride instead
*/
Q_DECL_DEPRECATED T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, const T &defaultValueOverride ) const SIP_DEPRECATED
{
if ( useDefaultValueOverride )
return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) );
else
return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) );
}
/**
* Returns the settings value for the \a dynamicKeyPartList and with a \a defaultValueOverride
* \deprecated since QGIS 3.26 use valueAsVariantWithDefaultOverride instead
*/
Q_DECL_DEPRECATED T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const T &defaultValueOverride ) const SIP_DEPRECATED
{
if ( useDefaultValueOverride )
return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) );
else
return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) );
}
/**
* Set settings value.
*
@ -489,19 +469,24 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
*/
T formerValue( const QStringList &dynamicKeyPartList ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPartList ) );}
protected:
//! Sets the settings value with an optional list of dynamic parts
bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const
bool checkValueVariant( const QVariant &value ) const override
{
if ( checkValue( value ) )
return QgsSettingsEntryBase::setVariantValuePrivate( convertToVariant( value ), dynamicKeyPartList );
else
return false;
return checkValuePrivate( convertFromVariant( value ) );
}
//! Converts the variant value to the value type of the setting
virtual T convertFromVariant( const QVariant &value ) const = 0;
protected:
//! Sets the settings value with an optional list of dynamic parts
virtual bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const
{
if ( checkValuePrivate( value ) )
return QgsSettingsEntryBase::setVariantValue( convertToVariant( value ), dynamicKeyPartList );
else
return false;
}
//! Converts the value to a variant
virtual QVariant convertToVariant( const T &value ) const
{
@ -509,7 +494,7 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
}
//! Check if the value is valid
virtual bool checkValue( const T &value ) const
virtual bool checkValuePrivate( const T &value ) const
{
Q_UNUSED( value )
return true;
@ -517,163 +502,6 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
};
/**
* \ingroup core
* \class QgsSettingsEntryByValue
*
* \brief Base abstract class for settings entry which are passed by value
* \see QgsSettingsEntryBase
* \see QgsSettingsEntryByReference
*
* \since QGIS 3.26
*/
template<class T>
class QgsSettingsEntryByValue : public QgsSettingsEntryBase
{
public:
/**
* Constructor for QgsSettingsEntryByValue.
*
* \param key specifies the key of the settings.
* \param parent specifies the parent in the tree of settings.
* \param defaultValue specifies the default value for the settings entry.
* \param description specifies a description for the settings entry.
* \param options specifies the options for the settings entry.
* \throws QgsSettingsException if the number of given parent named items doesn't match the complete key definition
*/
QgsSettingsEntryByValue( const QString &key, QgsSettingsTreeNode *parent, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( key, parent, defaultValue, description, options )
{}
/**
* Constructor for QgsSettingsEntryByValue.
*
* \param key specifies the key of the settings.
* \param section specifies the section.
* \param defaultValue specifies the default value for the settings entry.
* \param description specifies a description for the settings entry.
* \param options specifies the options for the settings entry.
*/
QgsSettingsEntryByValue( const QString &key, const QString &section, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( key, section, defaultValue, description, options )
{}
virtual Qgis::SettingsType settingsType() const override = 0;
/**
* Returns settings value.
*
* \param dynamicKeyPart specifies the dynamic part of the settings key.
*/
T value( const QString &dynamicKeyPart = QString() ) const { return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) );}
/**
* Returns settings value.
*
* \param dynamicKeyPartList specifies the list of dynamic parts of the settings key.
*/
T value( const QStringList &dynamicKeyPartList ) const { return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) );}
//! Returns the settings value with a \a defaultValueOverride and with an optional \a dynamicKeyPart
inline T valueWithDefaultOverride( T defaultValueOverride, const QString &dynamicKeyPart = QString() ) const
{
return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPart ) );
}
//! Returns the settings value with a \a defaultValueOverride for the \a dynamicKeyPartList
inline T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const
{
return this->convertFromVariant( valueAsVariantWithDefaultOverride( convertToVariant( defaultValueOverride ), dynamicKeyPartList ) );
}
/**
* Returns the settings value for the \a dynamicKeyPart and with a \a defaultValueOverride
* \deprecated since QGIS 3.26 use valueWithDefaultOverride instead
*/
Q_DECL_DEPRECATED T value( const QString &dynamicKeyPart, bool useDefaultValueOverride, T defaultValueOverride ) const SIP_DEPRECATED
{
if ( useDefaultValueOverride )
return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) );
else
return this->convertFromVariant( valueAsVariant( dynamicKeyPart ) );
}
/**
* Returns the settings value for the \a dynamicKeyPartList and with a \a defaultValueOverride
* \deprecated since QGIS 3.26 use valueWithDefaultOverride instead
*/
Q_DECL_DEPRECATED T value( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, T defaultValueOverride ) const SIP_DEPRECATED
{
if ( useDefaultValueOverride )
return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) );
else
return this->convertFromVariant( valueAsVariant( dynamicKeyPartList ) );
}
/**
* Set settings value.
*
* \param value specifies the value to set.
* \param dynamicKeyPart specifies the dynamic part of the settings key.
*/
bool setValue( T value, const QString &dynamicKeyPart = QString() ) const
{
return setValuePrivate( value, dynamicKeyPartToList( dynamicKeyPart ) );
}
/**
* Set settings value.
*
* \param value specifies the value to set.
* \param dynamicKeyPartList specifies the list of dynamic parts of the settings key.
*/
bool setValue( T value, const QStringList &dynamicKeyPartList ) const
{
return setValuePrivate( value, dynamicKeyPartList );
}
//! Returns settings default value.
T defaultValue() const {return convertFromVariant( defaultValueAsVariant() );}
/**
* Returns the former value
* Returns the current value (or default) if there is no former value.
*/
T formerValue( const QString &dynamicKeyPart = QString() ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPart ) );}
/**
* Returns the former value
* Returns the current value (or default) if there is no former value.
*/
T formerValue( const QStringList &dynamicKeyPartList ) const {return convertFromVariant( formerValueAsVariant( dynamicKeyPartList ) );}
protected:
//! Sets the settings value with an optional list of dynamic parts
virtual bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const
{
if ( checkValue( value ) )
return QgsSettingsEntryBase::setVariantValuePrivate( convertToVariant( value ), dynamicKeyPartList );
else
return false;
}
//! Converts the variant value to the value type of the setting
virtual T convertFromVariant( const QVariant &value ) const = 0;
//! Converts the value to a variant
virtual QVariant convertToVariant( T value ) const
{
return QVariant::fromValue( value );
}
//! Check if the value is valid
virtual bool checkValue( T value ) const
{
Q_UNUSED( value )
return true;
}
};
#endif // QGSSETTINGSENTRY_H

View File

@ -32,7 +32,7 @@
* \since QGIS 3.20
*/
template <typename T>
class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
class QgsSettingsEntryEnumFlag : public QgsSettingsEntryBaseTemplate<T>
{
public:
@ -50,11 +50,11 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
* \since QGIS 3.30
*/
QgsSettingsEntryEnumFlag( const QString &name, QgsSettingsTreeNode *parent, T defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryByValue<T>( name,
parent,
QMetaEnum::fromType<T>().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ),
description,
options )
: QgsSettingsEntryBaseTemplate<T>( name,
parent,
QMetaEnum::fromType<T>().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ),
description,
options )
{
mMetaEnum = QMetaEnum::fromType<T>();
Q_ASSERT( mMetaEnum.isValid() );
@ -75,11 +75,11 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
* \note for Python bindings, a custom implementation is achieved in Python directly
*/
QgsSettingsEntryEnumFlag( const QString &key, const QString &section, T defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryByValue<T>( key,
section,
QVariant::fromValue( defaultValue ),
description,
options )
: QgsSettingsEntryBaseTemplate<T>( key,
section,
QMetaEnum::fromType<T>().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ),
description,
options )
{
mMetaEnum = QMetaEnum::fromType<T>();
Q_ASSERT( mMetaEnum.isValid() );
@ -87,7 +87,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( this->key() ) );
}
QVariant convertToVariant( T value ) const override
QVariant convertToVariant( const T &value ) const override
{
if ( mMetaEnum.isFlag() )
return qgsFlagValueToKeys( value );
@ -129,7 +129,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
* The \a value to set.
* The \a dynamicKeyParts argument specifies the list of dynamic parts of the settings key.
*/
bool setValuePrivate( T value, const QStringList &dynamicKeyPartList ) const override
bool setValuePrivate( const T &value, const QStringList &dynamicKeyPartList ) const override
{
if ( !mMetaEnum.isValid() )
{
@ -153,7 +153,7 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
}
if ( ok )
return this->setVariantValuePrivate( variantValue, dynamicKeyPartList );
return this->setVariantValue( variantValue, dynamicKeyPartList );
else
return false;
}

View File

@ -24,7 +24,7 @@ Qgis::SettingsType QgsSettingsEntryVariant::settingsType() const
}
bool QgsSettingsEntryString::checkValue( const QString &value ) const
bool QgsSettingsEntryString::checkValuePrivate( const QString &value ) const
{
if ( value.length() < mMinLength )
{
@ -89,7 +89,7 @@ Qgis::SettingsType QgsSettingsEntryBool::settingsType() const
}
bool QgsSettingsEntryInteger::checkValue( int value ) const
bool QgsSettingsEntryInteger::checkValuePrivate( const int &value ) const
{
if ( value < mMinValue )
{
@ -130,7 +130,7 @@ int QgsSettingsEntryInteger::minValue() const
return mMaxValue;
}
bool QgsSettingsEntryInteger64::checkValue( qlonglong value ) const
bool QgsSettingsEntryInteger64::checkValuePrivate( const qlonglong &value ) const
{
if ( value < mMinValue )
{
@ -173,7 +173,7 @@ qlonglong QgsSettingsEntryInteger64::minValue() const
bool QgsSettingsEntryDouble::checkValue( double value ) const
bool QgsSettingsEntryDouble::checkValuePrivate( const double &value ) const
{
if ( value < mMinValue )
{
@ -233,7 +233,7 @@ Qgis::SettingsType QgsSettingsEntryColor::settingsType() const
return Qgis::SettingsType::Color;
}
bool QgsSettingsEntryColor::checkValue( const QColor &value ) const
bool QgsSettingsEntryColor::checkValuePrivate( const QColor &value ) const
{
if ( !mAllowAlpha && value.alpha() != 255 )
{
@ -263,7 +263,7 @@ bool QgsSettingsEntryColor::copyValueFromKeys( const QString &redKey, const QStr
settings.remove( alphaKey );
}
setVariantValuePrivate( oldValue );
setVariantValue( oldValue );
return true;
}
return false;

View File

@ -26,7 +26,7 @@
* \brief A variant settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference<QVariant>
class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryBaseTemplate<QVariant>
{
public:
@ -46,7 +46,7 @@ class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference<Q
const QVariant &defaultValue = QVariant(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByReference( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
{}
/**
@ -64,7 +64,7 @@ class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference<Q
const QVariant &defaultValue = QVariant(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByReference( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
{}
#ifdef SIP_RUN
@ -114,7 +114,6 @@ class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference<Q
virtual Qgis::SettingsType settingsType() const override;
private:
QVariant convertFromVariant( const QVariant &value ) const override SIP_FORCE {return value;}
};
@ -125,7 +124,7 @@ class CORE_EXPORT QgsSettingsEntryVariant : public QgsSettingsEntryByReference<Q
* \brief A string settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference<QString>
class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryBaseTemplate<QString>
{
public:
@ -147,7 +146,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference<QS
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
int minLength = 0,
int maxLength = -1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByReference<QString>( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate<QString>( name, parent, defaultValue, description, options )
, mMinLength( minLength )
, mMaxLength( maxLength )
{}
@ -170,7 +169,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference<QS
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
int minLength = 0,
int maxLength = -1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByReference<QString>( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate<QString>( key, section, defaultValue, description, options )
, mMinLength( minLength )
, mMaxLength( maxLength )
{}
@ -211,10 +210,11 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference<QS
*/
int maxLength() const;
private:
bool checkValue( const QString &value ) const override SIP_FORCE;
QString convertFromVariant( const QVariant &value ) const override SIP_FORCE;
private:
bool checkValuePrivate( const QString &value ) const override SIP_FORCE;
int mMinLength;
int mMaxLength;
@ -228,7 +228,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntryByReference<QS
* \brief A string list settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReference<QStringList>
class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryBaseTemplate<QStringList>
{
public:
@ -246,7 +246,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc
const QStringList &defaultValue = QStringList(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByReference( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
{}
/**
@ -263,7 +263,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc
const QStringList &defaultValue = QStringList(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByReference( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
{}
@ -291,9 +291,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc
virtual Qgis::SettingsType settingsType() const override;
private:
QStringList convertFromVariant( const QVariant &value ) const override SIP_FORCE;
};
@ -304,7 +302,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntryByReferenc
* \brief A boolean settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue<bool>
class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryBaseTemplate<bool>
{
public:
@ -322,7 +320,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue<bool>
bool defaultValue = false,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByValue( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
{}
/**
@ -339,7 +337,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue<bool>
bool defaultValue = false,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByValue( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
{}
#ifdef SIP_RUN
@ -367,7 +365,6 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue<bool>
virtual Qgis::SettingsType settingsType() const override;
private:
bool convertFromVariant( const QVariant &value ) const override SIP_FORCE;
};
@ -379,7 +376,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntryByValue<bool>
* \brief An integer settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue<int>
class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryBaseTemplate<int>
{
public:
@ -401,7 +398,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue<int>
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
int minValue = std::numeric_limits<int>::min(),
int maxValue = std::numeric_limits<int>::max() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByValue( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
{ }
@ -424,7 +421,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue<int>
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
int minValue = std::numeric_limits<int>::min(),
int maxValue = std::numeric_limits<int>::max() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByValue( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
{ }
@ -467,9 +464,10 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue<int>
*/
int maxValue() const;
private:
bool checkValue( int value ) const override SIP_FORCE;
int convertFromVariant( const QVariant &value ) const override SIP_FORCE;
private:
bool checkValuePrivate( const int &value ) const override SIP_FORCE;
int mMinValue;
int mMaxValue;
};
@ -484,7 +482,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntryByValue<int>
* \brief A 64 bits integer (long long) settings entry.
* \since QGIS 3.30
*/
class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue<qlonglong>
class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryBaseTemplate<qlonglong>
{
public:
@ -506,7 +504,7 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue<qlo
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
qlonglong minValue = std::numeric_limits<qlonglong>::min(),
qlonglong maxValue = std::numeric_limits<qlonglong>::max() ) SIP_THROW( QgsSettingsException )
: QgsSettingsEntryByValue( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
{ }
@ -529,7 +527,7 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue<qlo
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
qlonglong minValue = std::numeric_limits<qlonglong>::min(),
qlonglong maxValue = std::numeric_limits<qlonglong>::max() )
: QgsSettingsEntryByValue( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
{ }
@ -546,9 +544,10 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue<qlo
*/
qlonglong maxValue() const;
private:
bool checkValue( qlonglong value ) const override;
qlonglong convertFromVariant( const QVariant &value ) const override;
private:
bool checkValuePrivate( const qlonglong &value ) const override;
qlonglong mMinValue;
qlonglong mMaxValue;
};
@ -561,7 +560,7 @@ class CORE_EXPORT QgsSettingsEntryInteger64 : public QgsSettingsEntryByValue<qlo
* \brief A double settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue<double>
class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryBaseTemplate<double>
{
public:
@ -586,7 +585,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue<double
double minValue = std::numeric_limits<double>::lowest(),
double maxValue = std::numeric_limits<double>::max(),
int displayDecimals = 1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByValue( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
, mDisplayHintDecimals( displayDecimals )
@ -613,7 +612,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue<double
double minValue = std::numeric_limits<double>::lowest(),
double maxValue = std::numeric_limits<double>::max(),
int displayDecimals = 1 ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByValue( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
, mMinValue( minValue )
, mMaxValue( maxValue )
, mDisplayHintDecimals( displayDecimals )
@ -672,9 +671,10 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue<double
*/
int displayHintDecimals() const;
private:
bool checkValue( double value ) const override SIP_FORCE;
double convertFromVariant( const QVariant &value ) const override SIP_FORCE;
private:
bool checkValuePrivate( const double &value ) const override SIP_FORCE;
double mMinValue;
double mMaxValue;
@ -691,7 +691,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntryByValue<double
* \brief A color settings entry.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference<QColor>
class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryBaseTemplate<QColor>
{
public:
@ -711,7 +711,7 @@ class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference<QCo
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
bool allowAlpha = true ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByReference( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
, mAllowAlpha( allowAlpha )
{}
@ -731,7 +731,7 @@ class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference<QCo
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions(),
bool allowAlpha = true ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByReference( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
, mAllowAlpha( allowAlpha )
{}
@ -779,10 +779,10 @@ class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference<QCo
*/
void copyValueToKeys( const QString &redKey, const QString &greenKey, const QString &blueKey, const QString &alphaKey = QString() ) const SIP_SKIP;
QColor convertFromVariant( const QVariant &value ) const override SIP_FORCE;
private:
QColor convertFromVariant( const QVariant &value ) const override SIP_FORCE;
bool checkValue( const QColor &value ) const override SIP_FORCE;
bool checkValuePrivate( const QColor &value ) const override SIP_FORCE;
bool mAllowAlpha = true;
};
@ -793,7 +793,7 @@ class CORE_EXPORT QgsSettingsEntryColor : public QgsSettingsEntryByReference<QCo
* \brief A string list settings entry.
* \since QGIS 3.30
*/
class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReference<QVariantMap>
class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryBaseTemplate<QVariantMap>
{
public:
@ -812,7 +812,7 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc
const QVariantMap &defaultValue = QVariantMap(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER
: QgsSettingsEntryByReference( name, parent, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( name, parent, defaultValue, description, options )
{
}
@ -830,7 +830,7 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc
const QVariantMap &defaultValue = QVariantMap(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() ) SIP_THROW( QgsSettingsException ) SIP_TRANSFER SIP_MAKE_PRIVATE
: QgsSettingsEntryByReference( key, section, defaultValue, description, options )
: QgsSettingsEntryBaseTemplate( key, section, defaultValue, description, options )
{
}
@ -858,9 +858,8 @@ class CORE_EXPORT QgsSettingsEntryVariantMap : public QgsSettingsEntryByReferenc
virtual Qgis::SettingsType settingsType() const override;
private:
QVariantMap convertFromVariant( const QVariant &value ) const override SIP_FORCE;
};
#endif // QGSSETTINGSENTRYIMPL_H

View File

@ -441,7 +441,12 @@ set(QGIS_GUI_SRCS
sensor/qgssensorguiregistry.cpp
sensor/qgssensorwidget.cpp
settings/qgssettingseditorwidgetwrapper.cpp
settings/qgssettingseditorwidgetwrapperimpl.cpp
settings/qgssettingseditorwidgetregistry.cpp
settings/qgssettingsregistrygui.cpp
settings/qgssettingstreemodel.cpp
settings/qgssettingstreewidget.cpp
tableeditor/qgstableeditordialog.cpp
tableeditor/qgstableeditorformattingwidget.cpp
@ -1436,7 +1441,12 @@ set(QGIS_GUI_HDRS
sensor/qgssensorguiregistry.h
sensor/qgssensorwidget.h
settings/qgssettingseditorwidgetwrapper.h
settings/qgssettingseditorwidgetwrapperimpl.h
settings/qgssettingseditorwidgetregistry.h
settings/qgssettingsregistrygui.h
settings/qgssettingstreemodel.h
settings/qgssettingstreewidget.h
tableeditor/qgstableeditordialog.h
tableeditor/qgstableeditorformattingwidget.h

View File

@ -63,6 +63,9 @@
#include "qgssensorguiregistry.h"
#include "qgshistoryentry.h"
#include "qgssettingseditorwidgetregistry.h"
#include <QPushButton>
#include <QToolButton>
@ -182,6 +185,11 @@ QgsHistoryProviderRegistry *QgsGui::historyProviderRegistry()
return instance()->mHistoryProviderRegistry;
}
QgsSettingsEditorWidgetRegistry *QgsGui::settingsEditorWidgetRegistry()
{
return instance()->mSettingsEditorRegistry;
}
void QgsGui::enableAutoGeometryRestore( QWidget *widget, const QString &key )
{
if ( widget->objectName().isEmpty() )
@ -238,6 +246,7 @@ QgsGui::~QgsGui()
delete mRelationEditorRegistry;
delete mSettingsRegistryGui;
delete mSensorGuiRegistry;
delete mSettingsEditorRegistry;
}
QColor QgsGui::sampleColor( QPoint point )
@ -288,6 +297,8 @@ QgsGui::QgsGui()
mSettingsRegistryGui = new QgsSettingsRegistryGui();
mSettingsEditorRegistry = new QgsSettingsEditorWidgetRegistry();
mCodeEditorColorSchemeRegistry = new QgsCodeEditorColorSchemeRegistry();
// provider gui registry initialize QgsProviderRegistry too

View File

@ -48,7 +48,7 @@ class QgsRelationWidgetRegistry;
class QgsMapToolShapeRegistry;
class QgsHistoryProviderRegistry;
class QgsSensorGuiRegistry;
class QgsSettingsEditorWidgetRegistry;
/**
* \ingroup gui
@ -213,6 +213,12 @@ class GUI_EXPORT QgsGui : public QObject
*/
static QgsHistoryProviderRegistry *historyProviderRegistry() SIP_KEEPREFERENCE;
/**
* Returns the registry of settings editors.
* \since QGIS 3.32
*/
static QgsSettingsEditorWidgetRegistry *settingsEditorWidgetRegistry() SIP_KEEPREFERENCE;
/**
* Register the widget to allow its position to be automatically saved and restored when open and closed.
* Use this to avoid needing to call saveGeometry() and restoreGeometry() on your widget.
@ -322,6 +328,7 @@ class GUI_EXPORT QgsGui : public QObject
QgsMapToolShapeRegistry *mShapeMapToolRegistry = nullptr;
QgsHistoryProviderRegistry *mHistoryProviderRegistry = nullptr;
QgsSensorGuiRegistry *mSensorGuiRegistry = nullptr;
QgsSettingsEditorWidgetRegistry *mSettingsEditorRegistry = nullptr;
std::unique_ptr< QgsWindowManagerInterface > mWindowManager;
#ifdef SIP_RUN

View File

@ -33,7 +33,6 @@
#include <functional>
#include "qgsfilterlineedit.h"
#include "qgsmessagebaritem.h"
#include "qgslogger.h"
#include "qgsoptionsdialoghighlightwidget.h"
#include "qgsoptionswidgetfactory.h"
@ -652,31 +651,34 @@ void QgsOptionsDialogBase::registerTextSearchWidgets()
for ( int i = 0; i < mOptStackedWidget->count(); i++ )
{
const QList< QWidget * > widgets = mOptStackedWidget->widget( i )->findChildren<QWidget *>();
for ( QWidget *w : widgets )
for ( QWidget *widget : widgets )
{
// get custom highlight widget in user added pages
QHash<QWidget *, QgsOptionsDialogHighlightWidget *> customHighlightWidgets;
QgsOptionsPageWidget *opw = qobject_cast<QgsOptionsPageWidget *>( mOptStackedWidget->widget( i ) );
if ( opw )
// see if the widget also inherits QgsOptionsDialogHighlightWidget
QgsOptionsDialogHighlightWidget *shw = dynamic_cast<QgsOptionsDialogHighlightWidget *>( widget );
if ( !shw )
{
customHighlightWidgets = opw->registeredHighlightWidgets();
}
QgsOptionsDialogHighlightWidget *shw = nullptr;
// take custom if exists
if ( customHighlightWidgets.contains( w ) )
{
shw = customHighlightWidgets.value( w );
// get custom highlight widget in user added pages
QHash<QWidget *, QgsOptionsDialogHighlightWidget *> customHighlightWidgets;
QgsOptionsPageWidget *opw = qobject_cast<QgsOptionsPageWidget *>( mOptStackedWidget->widget( i ) );
if ( opw )
{
customHighlightWidgets = opw->registeredHighlightWidgets();
}
// take custom if exists
if ( customHighlightWidgets.contains( widget ) )
{
shw = customHighlightWidgets.value( widget );
}
}
// try to construct one otherwise
if ( !shw || !shw->isValid() )
{
shw = QgsOptionsDialogHighlightWidget::createWidget( w );
shw = QgsOptionsDialogHighlightWidget::createWidget( widget );
}
if ( shw && shw->isValid() )
{
QgsDebugMsgLevel( QStringLiteral( "Registering: %1" ).arg( w->objectName() ), 4 );
QgsDebugMsgLevel( QStringLiteral( "Registering: %1" ).arg( widget->objectName() ), 4 );
mRegisteredSearchWidgets.append( qMakePair( shw, i ) );
}
else

View File

@ -33,8 +33,7 @@
QgsOptionsDialogHighlightWidget::QgsOptionsDialogHighlightWidget( QWidget *widget )
: QObject( widget )
, mWidget( widget )
: mWidget( widget )
{}
QgsOptionsDialogHighlightWidget *QgsOptionsDialogHighlightWidget::createWidget( QWidget *widget )
@ -52,6 +51,11 @@ QgsOptionsDialogHighlightWidget *QgsOptionsDialogHighlightWidget::createWidget(
}
}
if ( dynamic_cast<QgsOptionsDialogHighlightWidget *>( widget ) )
{
return dynamic_cast<QgsOptionsDialogHighlightWidget *>( widget );
}
if ( qobject_cast<QLabel *>( widget ) )
{
return new QgsOptionsDialogHighlightLabel( qobject_cast<QLabel *>( widget ) );
@ -97,15 +101,16 @@ bool QgsOptionsDialogHighlightWidget::searchHighlight( const QString &text )
mChangedStyle = false;
}
if ( mInstalledFilter )
if ( mEventFilter )
{
mWidget->removeEventFilter( this );
mInstalledFilter = false;
mWidget->removeEventFilter( mEventFilter );
delete mEventFilter;
mEventFilter = nullptr;
}
if ( !text.isEmpty() )
{
found = searchText( text );
found = searchText( mSearchText );
}
if ( found )
@ -113,30 +118,38 @@ bool QgsOptionsDialogHighlightWidget::searchHighlight( const QString &text )
if ( !mWidget->isVisible() )
{
mWidget->installEventFilter( this );
mInstalledFilter = true;
mEventFilter = new QgsOptionsDialogHighlightWidgetEventFilter( this );
mWidget->installEventFilter( mEventFilter );
}
else
{
mChangedStyle = highlightText( text );
mChangedStyle = highlightText( mSearchText );
}
}
return found;
}
bool QgsOptionsDialogHighlightWidget::eventFilter( QObject *obj, QEvent *event )
///@cond PRIVATE
QgsOptionsDialogHighlightWidgetEventFilter::QgsOptionsDialogHighlightWidgetEventFilter( QgsOptionsDialogHighlightWidget *highlightWidget )
: QObject( highlightWidget->widget() )
, mHighlightWidget( highlightWidget )
{}
bool QgsOptionsDialogHighlightWidgetEventFilter::eventFilter( QObject *obj, QEvent *event )
{
if ( mInstalledFilter && event->type() == QEvent::Show && obj == mWidget )
if ( event->type() == QEvent::Show && obj == mHighlightWidget->widget() )
{
mWidget->removeEventFilter( this );
mInstalledFilter = false;
mHighlightWidget->widget()->removeEventFilter( this );
// instead of catching the event and calling show again
// it might be better to use a timer to change the style
// after the widget is shown
#if 1
mWidget->show();
mChangedStyle = highlightText( mSearchText );
mHighlightWidget->widget()->show();
mHighlightWidget->mChangedStyle = mHighlightWidget->highlightText( mHighlightWidget->mSearchText );
return true;
#else
QTimer::singleShot( 500, this, [ = ]
@ -148,5 +161,6 @@ bool QgsOptionsDialogHighlightWidget::eventFilter( QObject *obj, QEvent *event )
return QObject::eventFilter( obj, event );
}
///@endcond

View File

@ -23,6 +23,34 @@
#include "qgis_gui.h"
#include "qgis_sip.h"
class QgsOptionsDialogHighlightWidget;
#ifndef SIP_RUN
///@cond PRIVATE
/**
* \ingroup gui
* \class QgsOptionsDialogHighlightWidgetEventFilter
* \brief QgsOptionsDialogHighlightWidgetEventFilter is an event filter implementation for QgsOptionsDialogHighlightWidget
* \since QGIS 3.32
*/
class QgsOptionsDialogHighlightWidgetEventFilter : public QObject
{
Q_OBJECT
public:
//! Constructor
QgsOptionsDialogHighlightWidgetEventFilter( QgsOptionsDialogHighlightWidget *highlightWidget );
bool eventFilter( QObject *obj, QEvent *event ) override;
private:
QgsOptionsDialogHighlightWidget *mHighlightWidget;
};
///@endcond
#endif
/**
* \ingroup gui
* \class QgsOptionsDialogHighlightWidget
@ -32,10 +60,8 @@
* This uses stylesheets.
* \since QGIS 3.0
*/
class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject
class GUI_EXPORT QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
/**
@ -46,6 +72,8 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject
*/
static QgsOptionsDialogHighlightWidget *createWidget( QWidget *widget ) SIP_FACTORY;
virtual ~QgsOptionsDialogHighlightWidget() = default;
/**
* Returns if it valid: if the widget type is handled and if the widget is not still available
*/
@ -62,10 +90,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject
*/
QWidget *widget() {return mWidget;}
bool eventFilter( QObject *obj, QEvent *event ) override;
protected:
/**
@ -94,9 +118,11 @@ class GUI_EXPORT QgsOptionsDialogHighlightWidget : public QObject
QPointer< QWidget > mWidget;
private:
friend class QgsOptionsDialogHighlightWidgetEventFilter;
QString mSearchText = QString();
bool mChangedStyle = false;
bool mInstalledFilter = false;
QgsOptionsDialogHighlightWidgetEventFilter *mEventFilter = nullptr;
};
#endif // QGSOPTIONSDIALOGHIGHLIGHTWIDGET_H

View File

@ -26,8 +26,6 @@
#include <QTextDocumentFragment>
#include "qgsoptionsdialoghighlightwidget.h"
#include "qgsmessagebaritem.h"
#include "qgslogger.h"
#include "qgsoptionsdialoghighlightwidgetsimpl.h"

View File

@ -43,7 +43,6 @@ class QTableView;
*/
class GUI_EXPORT QgsOptionsDialogHighlightLabel : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a label
QgsOptionsDialogHighlightLabel( QLabel *label );
@ -64,7 +63,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightLabel : public QgsOptionsDialogHighlig
*/
class GUI_EXPORT QgsOptionsDialogHighlightCheckBox : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a checkbox
QgsOptionsDialogHighlightCheckBox( QCheckBox *checkBox );
@ -85,7 +83,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightCheckBox : public QgsOptionsDialogHigh
*/
class GUI_EXPORT QgsOptionsDialogHighlightButton : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a button.
QgsOptionsDialogHighlightButton( QAbstractButton *button );
@ -106,7 +103,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightButton : public QgsOptionsDialogHighli
*/
class GUI_EXPORT QgsOptionsDialogHighlightGroupBox : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a group box.
QgsOptionsDialogHighlightGroupBox( QGroupBox *groupBox );
@ -129,7 +125,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightGroupBox : public QgsOptionsDialogHigh
*/
class GUI_EXPORT QgsOptionsDialogHighlightTree : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a tree view or widget.
QgsOptionsDialogHighlightTree( QTreeView *treeView );
@ -152,7 +147,6 @@ class GUI_EXPORT QgsOptionsDialogHighlightTree : public QgsOptionsDialogHighligh
*/
class GUI_EXPORT QgsOptionsDialogHighlightTable : public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! constructs a highlight widget for a table view or widget.
QgsOptionsDialogHighlightTable( QTableView *tableView );

View File

@ -0,0 +1,68 @@
/***************************************************************************
qgssettingseditorwidgetregistry.cpp
---------------------
begin : April 2023
copyright : (C) 2023 by Denis Rouzaud
email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssettingseditorwidgetregistry.h"
#include "qgslogger.h"
#include "qgssettingseditorwidgetwrapper.h"
#include "qgssettingseditorwidgetwrapperimpl.h"
#include "qgssettingsentry.h"
QgsSettingsEditorWidgetRegistry::QgsSettingsEditorWidgetRegistry()
{
addWrapper( new QgsSettingsStringEditorWidgetWrapper() );
addWrapper( new QgsSettingsBoolEditorWidgetWrapper() );
addWrapper( new QgsSettingsIntegerEditorWidgetWrapper() );
addWrapper( new QgsSettingsDoubleEditorWidgetWrapper() );
addWrapper( new QgsSettingsColorEditorWidgetWrapper() );
}
QgsSettingsEditorWidgetRegistry::~QgsSettingsEditorWidgetRegistry()
{
qDeleteAll( mWrappers );
}
bool QgsSettingsEditorWidgetRegistry::addWrapper( QgsSettingsEditorWidgetWrapper *wrapper )
{
if ( mWrappers.contains( wrapper->id() ) )
return false;
mWrappers.insert( wrapper->id(), wrapper );
return true;
}
QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetRegistry::createWrapper( const QString &id, QObject *parent ) const
{
QgsSettingsEditorWidgetWrapper *wrapper = mWrappers.value( id );
if ( wrapper )
{
return wrapper->createWrapper( parent );
}
else
{
QgsDebugMsg( QStringLiteral( "Setting factory was not found for '%1', returning the default string factory" ).arg( id ) );
return nullptr;
}
}
QWidget *QgsSettingsEditorWidgetRegistry::createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent ) const
{
QgsSettingsEditorWidgetWrapper *eww = createWrapper( setting->typeId(), parent );
if ( eww )
return eww->createEditor( setting, dynamicKeyPartList, parent );
else
return nullptr;
}

View File

@ -0,0 +1,58 @@
/***************************************************************************
qgssettingseditorwidgetregistry.h
---------------------
begin : April 2023
copyright : (C) 2023 by Denis Rouzaud
email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSETTINGSEDITORREGISTRY_H
#define QGSSETTINGSEDITORREGISTRY_H
#include <QObject>
#include <QMap>
#include "qgis_gui.h"
#include "qgis_sip.h"
class QWidget;
class QgsSettingsEntryBase;
class QgsSettingsEditorWidgetWrapper;
/**
* \ingroup gui
* \brief This class manages editor widgets for settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsEditorWidgetRegistry
{
public:
//! Constructor
QgsSettingsEditorWidgetRegistry();
~QgsSettingsEditorWidgetRegistry();
/**
* Adds an editor widget \a wrapper to the registry
* Returns FALSE if an editor widget with same id already exists.
*/
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper SIP_TRANSFER );
//! Returns a new instance of the editor widget for the given \a id
QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const;
//! Creates an editor widget for the given \a setting using the corresponding registered wrapper
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = nullptr ) const SIP_FACTORY;
private:
QMap<QString, QgsSettingsEditorWidgetWrapper *> mWrappers;
};
#endif // QGSSETTINGSEDITORREGISTRY_H

View File

@ -0,0 +1,61 @@
/***************************************************************************
qgssettingseditorwidgetwrapper.cpp
--------------------------------------
Date : February 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssettingseditorwidgetwrapper.h"
#include "qgslogger.h"
#include "qgssettingsentry.h"
#include <QWidget>
QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetWrapper::fromWidget( const QWidget *widget )
{
QVariant editorDataVariant = widget->property( "SETTING-EDITOR-WIDGET-WRAPPER" );
if ( editorDataVariant.isValid() )
{
return editorDataVariant.value<QgsSettingsEditorWidgetWrapper *>();
}
return nullptr;
}
QgsSettingsEditorWidgetWrapper::QgsSettingsEditorWidgetWrapper( QObject *parent )
: QObject( parent )
{
}
QWidget *QgsSettingsEditorWidgetWrapper::createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent )
{
QWidget *editor = createEditorPrivate( parent );
if ( configureEditor( editor, setting, dynamicKeyPartList ) )
return editor;
else
QgsDebugMsg( QStringLiteral( "editor could not be configured" ) );
return nullptr;
}
bool QgsSettingsEditorWidgetWrapper::configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList )
{
mDynamicKeyPartList = dynamicKeyPartList;
bool ok = configureEditorPrivate( editor, setting );
if ( ok )
editor->setProperty( "SETTING-EDITOR-WIDGET-WRAPPER", QVariant::fromValue( this ) );
return ok;
}

View File

@ -0,0 +1,96 @@
/***************************************************************************
qgssettingseditorwidgetwrapper.h
--------------------------------------
Date : February 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSETTINGSEDITORWIDGETWRAPPER_H
#define QGSSETTINGSEDITORWIDGETWRAPPER_H
#include <QVariant>
#include "qgis_sip.h"
#include "qgis_gui.h"
class QgsSettingsEntryBase;
/**
* \ingroup gui
* \brief Base class for settings editor wrappers
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject
{
Q_OBJECT
public:
//! Creates a wrapper from the definition stored in a \a widget created by createEditor()
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) SIP_FACTORY;
//! Constructor
QgsSettingsEditorWidgetWrapper( QObject *parent = nullptr );
virtual ~QgsSettingsEditorWidgetWrapper() = default;
/**
* This id of the type of settings it handles
* \note This mostly correspond to the content of Qgis::SettingsType but it's a string since custom Python implementation are possible.
*/
virtual QString id() const = 0;
//! Creates a new instance of the editor wrapper so it can be configured for a widget and a setting
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const = 0;
//! Creates the editor widget for the given \a setting
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = nullptr );
//! Configures the \a editor according the setting
bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() );
/**
* Sets the widget value from the setting value
* The wrapper must be configured before calling this medthod
*/
virtual bool setWidgetFromSetting() const = 0;
/**
* Sets the setting value from the widget value
* The wrapper must be configured before calling this medthod
*/
virtual bool setSettingFromWidget() const = 0;
/**
* Returns the value from the widget as a variant
* The wrapper must be configured before calling this medthod
*/
virtual QVariant variantValueFromWidget() const = 0;
/**
* Sets the \a value of the widget
* The wrapper must be configured before calling this medthod
*/
virtual void setWidgetFromVariant( const QVariant &value ) const = 0;
protected:
//! Creates the widgets
virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const = 0;
//! Configures an existing \a editor widget
virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0;
QStringList mDynamicKeyPartList;
};
#endif // QGSSETTINGSEDITORWIDGETWRAPPER_H

View File

@ -0,0 +1,340 @@
/***************************************************************************
qgssettingseditorwidgetwrapperimpl.cpp
--------------------------------------
Date : February 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssettingseditorwidgetwrapperimpl.h"
#include "qgslogger.h"
#include "qgssettingsentryimpl.h"
#include "qgscolorbutton.h"
#include <QLineEdit>
#include <QCheckBox>
// *******
// String
// *******
QString QgsSettingsStringEditorWidgetWrapper::id() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::String ) ) );
}
bool QgsSettingsStringEditorWidgetWrapper::setWidgetValue( const QString &value ) const
{
if ( mEditor )
{
mEditor->setText( value );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
bool QgsSettingsStringEditorWidgetWrapper::setSettingFromWidget() const
{
if ( mEditor )
{
mSetting->setValue( mEditor->text(), mDynamicKeyPartList );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
QString QgsSettingsStringEditorWidgetWrapper::valueFromWidget() const
{
if ( mEditor )
{
return mEditor->text();
}
else
{
QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) );
}
return QString();
}
// *******
// Boolean
// *******
QString QgsSettingsBoolEditorWidgetWrapper::id() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::Bool ) ) );
}
bool QgsSettingsBoolEditorWidgetWrapper::setWidgetValue( const bool &value ) const
{
if ( mEditor )
{
mEditor->setChecked( value );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
bool QgsSettingsBoolEditorWidgetWrapper::setSettingFromWidget() const
{
if ( mEditor )
{
mSetting->setValue( mEditor->isChecked(), mDynamicKeyPartList );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
bool QgsSettingsBoolEditorWidgetWrapper::valueFromWidget() const
{
if ( mEditor )
{
return mEditor->isChecked();
}
else
{
QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) );
}
return false;
}
// *******
// Integer
// *******
QString QgsSettingsIntegerEditorWidgetWrapper::id() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::Integer ) ) );
}
bool QgsSettingsIntegerEditorWidgetWrapper::setWidgetValue( const int &value ) const
{
if ( mEditor )
{
mEditor->setValue( value );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
bool QgsSettingsIntegerEditorWidgetWrapper::setSettingFromWidget() const
{
if ( mEditor )
{
mSetting->setValue( mEditor->value(), mDynamicKeyPartList );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
int QgsSettingsIntegerEditorWidgetWrapper::valueFromWidget() const
{
if ( mEditor )
{
return mEditor->value();
}
else
{
QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) );
}
return std::numeric_limits<int>::quiet_NaN();
}
// *******
// Double
// *******
QString QgsSettingsDoubleEditorWidgetWrapper::id() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::Double ) ) );
}
bool QgsSettingsDoubleEditorWidgetWrapper::setWidgetValue( const double &value ) const
{
if ( mEditor )
{
mEditor->setValue( value );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
bool QgsSettingsDoubleEditorWidgetWrapper::setSettingFromWidget() const
{
if ( mEditor )
{
mSetting->setValue( mEditor->value(), mDynamicKeyPartList );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
double QgsSettingsDoubleEditorWidgetWrapper::valueFromWidget() const
{
if ( mEditor )
{
return mEditor->value();
}
else
{
QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) );
}
return std::numeric_limits<double>::quiet_NaN();
}
// *******
// Color
// *******
QString QgsSettingsColorEditorWidgetWrapper::id() const
{
return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::Color ) ) );
}
bool QgsSettingsColorEditorWidgetWrapper::setWidgetValue( const QColor &value ) const
{
if ( mEditor )
{
mEditor->setColor( value );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
void QgsSettingsColorEditorWidgetWrapper::configureEditorPrivateImplementation()
{
if ( mEditor )
{
mEditor->setAllowOpacity( mSetting->allowAlpha() );
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
}
bool QgsSettingsColorEditorWidgetWrapper::setSettingFromWidget() const
{
if ( mEditor )
{
mSetting->setValue( mEditor->color(), mDynamicKeyPartList );
return true;
}
else
{
QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
}
return false;
}
QColor QgsSettingsColorEditorWidgetWrapper::valueFromWidget() const
{
if ( mEditor )
{
return mEditor->color();
}
else
{
QgsDebugMsg( QString( "editor is not set, returning a non-existing value" ) );
}
return QColor();
}
// *******
// StringList
// *******
//QString QgsSettingsStringListEditorWidgetWrapper::id() const
//{
// return QString::fromUtf8( sSettingsTypeMetaEnum.valueToKey( static_cast<int>( Qgis::SettingsType::StringList ) ) );
//}
//bool QgsSettingsStringListEditorWidgetWrapper::setWidgetFromSetting() const
//{
// if ( mEditor )
// {
// mEditor->setValue( mSetting->value( mDynamicKeyPartList ) );
// return true;
// }
// else
// {
// QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
// }
// return false;
//}
//bool QgsSettingsStringListEditorWidgetWrapper::setSettingFromWidget() const
//{
// if ( mEditor )
// {
// mSetting->setValue( mEditor->value(), mDynamicKeyPartList );
// return true;
// }
// else
// {
// QgsDebugMsg( QStringLiteral( "Settings editor not set for %1" ).arg( mSetting->definitionKey() ) );
// }
// return false;
//}
//QVariant QgsSettingsStringListEditorWidgetWrapper::valueFromWidget() const
//{
// if ( mEditor )
// {
// return mEditor->value();
// }
// else
// {
// QgsDebugMsg(QString("editor is not set, returning a non-existing value"));
// }
// return QStringList();
//}

View File

@ -0,0 +1,268 @@
/***************************************************************************
qgssettingseditorwidgetwrapperimpl.h
--------------------------------------
Date : February 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H
#define QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H
#include <QColor>
#include "qgis_gui.h"
#include "qgssettingseditorwidgetwrapper.h"
#include "qgslogger.h"
#include "qgssettingsentryimpl.h"
#include "qgscolorbutton.h"
#include <QLineEdit>
#include <QCheckBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QTableWidget>
//TODO variant map, enum
class QgsColorButton;
/**
* \ingroup gui
* \brief This class is a base factory of editor for settings
*
* \since QGIS 3.32
*/
template<class T, class V, class U>
class GUI_EXPORT QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEditorWidgetWrapper
{
public:
//! Constructor
QgsSettingsEditorWidgetWrapperTemplate( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapper( parent ) {}
virtual QString id() const override = 0;
virtual bool setWidgetFromSetting() const override
{
if ( mSetting )
return setWidgetValue( mSetting->value( mDynamicKeyPartList ) );
QgsDebugMsg( "editor is not configured" );
return false;
}
virtual bool setSettingFromWidget() const override = 0;
void setWidgetFromVariant( const QVariant &value ) const override
{
setWidgetValue( mSetting->convertFromVariant( value ) );
}
//! Sets the widget value
virtual bool setWidgetValue( const U &value ) const = 0;
QVariant variantValueFromWidget() const override
{
return valueFromWidget();
};
//! Returns the widget value
virtual U valueFromWidget() const = 0;
//! Returns the editor
V *editor() const {return mEditor;}
//! Returns the setting
const T *setting() const {return mSetting;}
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override = 0;
protected:
virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const override
{
V *editor = new V( parent );
editor->setAutoFillBackground( true );
return editor;
}
bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) override
{
mSetting = dynamic_cast<const T *>( setting );
mEditor = qobject_cast<V *>( editor );
if ( mEditor )
{
configureEditorPrivateImplementation();
return true;
}
return false;
}
//! To be re-implemented to implemeent type specific configuration (e.g. opacity for colors)
virtual void configureEditorPrivateImplementation() {}
const T *mSetting = nullptr;
V *mEditor = nullptr;
};
/**
* \ingroup gui
* \brief This class is a factory of editor for string settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsStringEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryString, QLineEdit, QString>
{
Q_OBJECT
public:
//! Constructor
QgsSettingsStringEditorWidgetWrapper( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryString, QLineEdit, QString>( parent ) {}
QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsStringEditorWidgetWrapper( parent );}
QString id() const override;
bool setSettingFromWidget() const override;
QString valueFromWidget() const override;
bool setWidgetValue( const QString &value ) const override;
};
/**
* \ingroup gui
* \brief This class is a factory of editor for boolean settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsBoolEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryBool, QCheckBox, bool>
{
Q_OBJECT
public:
//! Constructor
QgsSettingsBoolEditorWidgetWrapper( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryBool, QCheckBox, bool>( parent ) {}
QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsBoolEditorWidgetWrapper( parent );}
QString id() const override;
bool setSettingFromWidget() const override;
bool valueFromWidget() const override;
bool setWidgetValue( const bool &value ) const override;
};
/**
* \ingroup gui
* \brief This class is a factory of editor for integer settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsIntegerEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryInteger, QSpinBox, int>
{
Q_OBJECT
public:
//! Constructor
QgsSettingsIntegerEditorWidgetWrapper( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryInteger, QSpinBox, int>( parent ) {}
QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsIntegerEditorWidgetWrapper( parent );}
QString id() const override;
bool setSettingFromWidget() const override;
int valueFromWidget() const override;
bool setWidgetValue( const int &value ) const override;
};
/**
* \ingroup gui
* \brief This class is a factory of editor for double settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsDoubleEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryDouble, QDoubleSpinBox, double>
{
Q_OBJECT
public:
//! Constructor
QgsSettingsDoubleEditorWidgetWrapper( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryDouble, QDoubleSpinBox, double>( parent ) {}
QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsDoubleEditorWidgetWrapper( parent );}
QString id() const override;
bool setSettingFromWidget() const override;
double valueFromWidget() const override;
bool setWidgetValue( const double &value ) const override;
};
/**
* \ingroup gui
* \brief This class is a factory of editor for color settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsColorEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryColor, QgsColorButton, QColor>
{
Q_OBJECT
public:
//! Constructor
QgsSettingsColorEditorWidgetWrapper( QObject *parent = nullptr )
: QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryColor, QgsColorButton, QColor>( parent ) {}
QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const override {return new QgsSettingsColorEditorWidgetWrapper( parent );}
QString id() const override;
bool setSettingFromWidget() const override;
QColor valueFromWidget() const override;
bool setWidgetValue( const QColor &value ) const override;
void configureEditorPrivateImplementation() override;
};
///**
// * \ingroup gui
// * \brief This class is a factory of editor for boolean settings
// *
// * \since QGIS 3.32
// */
//class GUI_EXPORT QgsSettingsStringListEditorWidgetWrapper : public QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryStringList, QTableWidget, QStringList>
//{
// public:
// QgsSettingsStringListEditorWidgetWrapper()
// : QgsSettingsEditorWidgetWrapperTemplate<QgsSettingsEntryStringList, QTableWidget, QStringList>() {}
// QString id() const override;
// bool setWidgetFromSetting() const override;
// bool setSettingFromWidget() const override;
// QStringList valueFromWidget() const override;
//};
#endif // QGSSETTINGSEDITORWIDGETWRAPPERIMPL_H

View File

@ -0,0 +1,565 @@
/***************************************************************************
qgssettingstreemodel.cpp
--------------------------------------
Date : January 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QGuiApplication>
#include <QFont>
#include "qgssettingstreemodel.h"
#include "qgssettingsentry.h"
#include "qgssettingstreenode.h"
#include "qgssettingseditorwidgetwrapper.h"
#include "qgssettingseditorwidgetregistry.h"
#include "qgsgui.h"
#include "qgslogger.h"
///@cond PRIVATE
QgsSettingsTreeModelNodeData *QgsSettingsTreeModelNodeData::createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent = nullptr )
{
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( parent );
nodeData->mType = Type::RootNode;
nodeData->mName = rootNode->key();
nodeData->mTreeNode = rootNode;
nodeData->fillChildren();
return nodeData;
}
void QgsSettingsTreeModelNodeData::applyChanges()
{
switch ( type() )
{
case Type::NamedListTreeNode:
case Type::RootNode:
case Type::TreeNode:
case Type::NamedListItem:
{
QList<QgsSettingsTreeModelNodeData *>::iterator it = mChildren.begin();
for ( ; it != mChildren.end(); ++it )
( *it )->applyChanges();
break;
}
case Type::Setting:
{
if ( isEdited() )
{
setting()->setVariantValue( mValue, mNamedParentNodes );
}
break;
}
}
}
bool QgsSettingsTreeModelNodeData::setValue( const QVariant &value )
{
Q_ASSERT( mType == Type::Setting );
if ( !value.isValid() && mValue.isValid() )
{
mExists = false;
mIsEdited = true;
mValue = QVariant();
}
else if ( !mValue.isValid() || mValue != value )
{
mValue = value;
mIsEdited = ( value != mOriginalValue );
}
// TODO: check the value of setting is fulfilling the settings' contsraints ?
return true;
}
void QgsSettingsTreeModelNodeData::addChildForTreeNode( const QgsSettingsTreeNode *node )
{
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
nodeData->mParent = this;
nodeData->mNamedParentNodes = mNamedParentNodes;
nodeData->mName = node->key();
nodeData->mTreeNode = node;
if ( node->type() == Qgis::SettingsTreeNodeType::NamedList )
{
nodeData->mType = Type::NamedListTreeNode;
const QgsSettingsTreeNamedListNode *nln = dynamic_cast<const QgsSettingsTreeNamedListNode *>( node );
const QStringList items = nln->items( mNamedParentNodes );
for ( const QString &item : items )
{
nodeData->addChildForNamedListItemNode( item, nln );
}
}
else
{
nodeData->mType = Type::TreeNode;
nodeData->fillChildren();
}
mChildren.append( nodeData );
}
void QgsSettingsTreeModelNodeData::addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode )
{
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
nodeData->mType = Type::NamedListItem;
nodeData->mParent = this;
nodeData->mNamedParentNodes = mNamedParentNodes;
nodeData->mNamedParentNodes.append( item );
nodeData->mName = item;
nodeData->mTreeNode = namedListNode;
nodeData->fillChildren();
mChildren.append( nodeData );
}
void QgsSettingsTreeModelNodeData::addChildForSetting( const QgsSettingsEntryBase *setting )
{
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
nodeData->mType = Type::Setting;
nodeData->mParent = this;
nodeData->mNamedParentNodes = mNamedParentNodes;
nodeData->mSetting = setting;
nodeData->mName = setting->name();
nodeData->mValue = setting->valueAsVariant( mNamedParentNodes );
nodeData->mOriginalValue = nodeData->mValue;
nodeData->mExists = setting->exists( mNamedParentNodes );
switch ( mNamedParentNodes.count() )
{
case 1:
QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ) ) );
break;
case 2:
QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ), mNamedParentNodes.at( 1 ) ) );
break;
case 0:
QgsDebugMsg( QString( "getting %1" ).arg( setting->definitionKey() ) );
break;
default:
Q_ASSERT( false );
QgsDebugMsg( QString( "Not handling that many named parent nodes for %1" ).arg( setting->definitionKey() ) );
break;
}
mChildren.append( nodeData );
}
void QgsSettingsTreeModelNodeData::fillChildren()
{
const QList<QgsSettingsTreeNode *> childrenNodes = mTreeNode->childrenNodes();
for ( const QgsSettingsTreeNode *childNode : childrenNodes )
{
addChildForTreeNode( childNode );
}
const QList<const QgsSettingsEntryBase *> childrenSettings = mTreeNode->childrenSettings();
for ( const QgsSettingsEntryBase *setting : childrenSettings )
{
addChildForSetting( setting );
}
}
///@endcond
QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObject *parent )
: QAbstractItemModel( parent )
{
mRootNode = QgsSettingsTreeModelNodeData::createRootNodeData( rootNode, this );
QPalette pal = qApp->palette();
mEditedColorBack = pal.color( QPalette::Active, QPalette::Dark );
mEditedColorFore = pal.color( QPalette::Active, QPalette::BrightText );
mNotSetColor = pal.color( QPalette::Disabled, QPalette::WindowText );
}
QgsSettingsTreeModel::~QgsSettingsTreeModel()
{
//delete mRootNode;
}
void QgsSettingsTreeModel::applyChanges()
{
beginResetModel();
mRootNode->applyChanges();
endResetModel();
}
QgsSettingsTreeModelNodeData *QgsSettingsTreeModel::index2node( const QModelIndex &index ) const
{
if ( !index.isValid() )
return mRootNode;
QObject *obj = reinterpret_cast<QObject *>( index.internalPointer() );
return qobject_cast<QgsSettingsTreeModelNodeData *>( obj );
}
QModelIndex QgsSettingsTreeModel::node2index( QgsSettingsTreeModelNodeData *node ) const
{
if ( !node || !node->parent() )
return QModelIndex(); // this is the only root item -> invalid index
QModelIndex parentIndex = node2index( node->parent() );
int row = node->parent()->children().indexOf( node );
Q_ASSERT( row >= 0 );
return index( row, static_cast<int>( Column::Name ), parentIndex );
}
QModelIndex QgsSettingsTreeModel::index( int row, int column, const QModelIndex &parent ) const
{
if ( column < 0 || column >= columnCount( parent ) ||
row < 0 || row >= rowCount( parent ) )
return QModelIndex();
QgsSettingsTreeModelNodeData *n = index2node( parent );
if ( !n )
return QModelIndex(); // have no children
return createIndex( row, column, static_cast<QObject *>( n->children().at( row ) ) );
}
QModelIndex QgsSettingsTreeModel::parent( const QModelIndex &child ) const
{
if ( !child.isValid() )
return QModelIndex();
if ( QgsSettingsTreeModelNodeData *n = index2node( child ) )
{
return indexOfParentSettingsTreeNode( n->parent() ); // must not be null
}
else
{
Q_ASSERT( false ); // no other node types!
return QModelIndex();
}
}
QModelIndex QgsSettingsTreeModel::indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const
{
Q_ASSERT( parentNode );
const QgsSettingsTreeModelNodeData *grandParentNode = parentNode->parent();
if ( !grandParentNode )
return QModelIndex(); // root node -> invalid index
int row = grandParentNode->children().indexOf( parentNode );
Q_ASSERT( row >= 0 );
return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
}
int QgsSettingsTreeModel::rowCount( const QModelIndex &parent ) const
{
QgsSettingsTreeModelNodeData *n = index2node( parent );
if ( !n )
return 0;
return n->children().count();
}
int QgsSettingsTreeModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent )
return 3;
}
QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() || index.column() > columnCount( index ) )
return QVariant();
QgsSettingsTreeModelNodeData *node = index2node( index );
if ( role == Qt::ForegroundRole && node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
if ( !node->exists() )
{
// settings not yet set
return mNotSetColor;
}
if ( node->isEdited() &&
( node->setting()->settingsType() != Qgis::SettingsType::Color || index.column() != static_cast<int>( Column::Value ) ) )
{
return mEditedColorFore;
}
}
if ( role == Qt::BackgroundRole && node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
// background for edited settings (except colors)
if ( node->isEdited() &&
( node->setting()->settingsType() != Qgis::SettingsType::Color || index.column() != static_cast<int>( Column::Value ) ) )
{
return mEditedColorBack;
}
}
switch ( static_cast<Column>( index.column() ) )
{
case Column::Name:
{
if ( role == Qt::DisplayRole || role == Qt::EditRole )
{
return node->name();
}
break;
}
case Column::Value:
{
if ( role == Qt::CheckStateRole )
{
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting &&
node->setting()->settingsType() == Qgis::SettingsType::Bool )
{
// special handling of bool setting to show combobox
return node->value().toBool() ? Qt::Checked : Qt::Unchecked;
}
}
if ( role == Qt::DisplayRole || role == Qt::EditRole )
{
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting &&
node->setting()->settingsType() == Qgis::SettingsType::Bool )
{
// special handling of bool setting to show combobox
return QString();
}
else
{
return node->value();
}
}
else if ( role == Qt::BackgroundRole )
{
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
switch ( node->setting()->settingsType() )
{
case Qgis::SettingsType::Custom:
case Qgis::SettingsType::Variant:
case Qgis::SettingsType::String:
case Qgis::SettingsType::StringList:
case Qgis::SettingsType::VariantMap:
case Qgis::SettingsType::Bool:
case Qgis::SettingsType::Integer:
case Qgis::SettingsType::Double:
case Qgis::SettingsType::EnumFlag:
break;
case Qgis::SettingsType::Color:
return node->value();
}
}
}
break;
}
case Column::Description:
{
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
if ( role == Qt::DisplayRole || role == Qt::EditRole )
{
return node->setting()->description();
}
}
break;
}
default:
break;
}
return QVariant();
}
QVariant QgsSettingsTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
if ( orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole )
{
switch ( static_cast<Column>( section ) )
{
case Column::Name:
return tr( "Name" );
case Column::Value:
return tr( "Value" );
case Column::Description:
return tr( "Description" );
};
}
return QVariant();
}
Qt::ItemFlags QgsSettingsTreeModel::flags( const QModelIndex &index ) const
{
if ( index.column() == static_cast<int>( Column::Value ) )
{
QgsSettingsTreeModelNodeData *nodeData = index2node( index );
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
if ( nodeData->setting()->settingsType() == Qgis::SettingsType::Bool )
{
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
}
else
{
return Qt::ItemIsEnabled | Qt::ItemIsEditable;
}
}
}
else
{
return Qt::ItemIsEnabled;
}
return Qt::NoItemFlags;
}
bool QgsSettingsTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
if ( index.column() == static_cast<int>( Column::Value ) )
{
if ( role == Qt::EditRole || role == Qt::CheckStateRole )
{
QgsSettingsTreeModelNodeData *nodeData = index2node( index );
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
if ( role == Qt::CheckStateRole )
{
Q_ASSERT( nodeData->setting()->settingsType() == Qgis::SettingsType::Bool );
nodeData->setValue( value == Qt::Checked ? true : false );
}
else
{
nodeData->setValue( value );
}
emit dataChanged( index.siblingAtColumn( 0 ), index.siblingAtColumn( columnCount( index.parent() ) - 1 ) );
return true;
}
}
}
return false;
}
///@cond PRIVATE
QgsSettingsTreeItemDelegate::QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent )
: QItemDelegate( parent )
, mModel( model )
{
}
QWidget *QgsSettingsTreeItemDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
Q_UNUSED( option )
if ( static_cast<QgsSettingsTreeModel::Column>( index.column() ) == QgsSettingsTreeModel::Column::Value )
{
QModelIndex sourceIndex = index;
const QgsSettingsTreeProxyModel *proxyModel = qobject_cast<const QgsSettingsTreeProxyModel *>( index.model() );
if ( proxyModel )
{
sourceIndex = proxyModel->mapToSource( index );
}
QgsSettingsTreeModelNodeData *nodeData = mModel->index2node( sourceIndex );
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
return QgsGui::settingsEditorWidgetRegistry()->createEditor( nodeData->setting(), nodeData->namedParentNodes(), parent );
}
}
return nullptr;
}
void QgsSettingsTreeItemDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
{
QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor );
if ( eww )
eww->setWidgetFromVariant( index.model()->data( index, Qt::DisplayRole ) );
}
void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
{
QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor );
if ( eww )
model->setData( index, eww->variantValueFromWidget(), Qt::EditRole );
}
///@endcond
QgsSettingsTreeProxyModel::QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode, QObject *parent )
: QSortFilterProxyModel( parent )
{
mSourceModel = new QgsSettingsTreeModel( rootNode, parent );
QSortFilterProxyModel::setSourceModel( mSourceModel );
}
void QgsSettingsTreeProxyModel::setFilterText( const QString &filterText )
{
if ( filterText == mFilterText )
return;
mFilterText = filterText;
invalidateFilter();
}
bool QgsSettingsTreeProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
{
QgsSettingsTreeModelNodeData *node = mSourceModel->index2node( mSourceModel->index( source_row, static_cast<int>( QgsSettingsTreeModel::Column::Name ), source_parent ) );
return nodeShown( node );
}
bool QgsSettingsTreeProxyModel::nodeShown( QgsSettingsTreeModelNodeData *node ) const
{
if ( !node )
return false;
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
{
if ( node->name().contains( mFilterText, Qt::CaseInsensitive ) )
return true;
// also returns settings for which the parent nodes have a match
QModelIndex index = mSourceModel->node2index( node ).parent();
while ( ( index.isValid() ) )
{
QgsSettingsTreeModelNodeData *parentNode = mSourceModel->index2node( mSourceModel->index( index.row(), static_cast<int>( QgsSettingsTreeModel::Column::Name ), index.parent() ) );
if ( parentNode->name().contains( mFilterText, Qt::CaseInsensitive ) )
return true;
index = index.parent();
}
return false;
}
else
{
// show all children if name of node matches
if ( node->name().contains( mFilterText, Qt::CaseInsensitive ) )
return true;
const auto constChildren = node->children();
for ( QgsSettingsTreeModelNodeData *child : constChildren )
{
if ( nodeShown( child ) )
{
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,248 @@
/***************************************************************************
qgssettingstreemodel.h
--------------------------------------
Date : January 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSETTINGSTREEMODEL_H
#define QGSSETTINGSTREEMODEL_H
#include "qgis_sip.h"
#include "qgis_gui.h"
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QItemDelegate>
class QgsSettingsEntryBase;
class QgsSettingsTreeNode;
class QgsSettingsTreeModel;
class QgsSettingsTreeNamedListNode;
#ifndef SIP_RUN
///@cond PRIVATE
/**
* \ingroup gui
* \class QgsSettingsTreeNodeData
* \brief QgsSettingsTree holds data of the tree model for the settings tree.
*
* \note Not available in Python bindings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject
{
Q_OBJECT
public:
//! Type of tree element
enum class Type
{
RootNode,
TreeNode,
NamedListTreeNode,
NamedListItem,
Setting
};
//! Constructor for the tree node data
static QgsSettingsTreeModelNodeData *createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent );
//! Apply changes to the settings
void applyChanges();
//! Returns if the node is the root node
bool isRoot() const { return mParent == nullptr; }
//! Returns the dynamic key parts of the named list parent tree nodes
QStringList namedParentNodes() const { return mNamedParentNodes; }
//! Returns the children nodes of the node (setting or tree node)
QList<QgsSettingsTreeModelNodeData *> children() const {return mChildren;}
//! Returns the parent of the node
QgsSettingsTreeModelNodeData *parent() const {return mParent;}
//! Returns the type of the node (setting or tree node)
Type type() const {return mType;}
//! Returns the name of the node (setting or tree node)
QString name() const {return mName;}
//! Returns the value of the node (setting or tree node)
QVariant value() const {return mValue;}
//! Returns the value of the node (setting or tree node)
QVariant originalValue() const {return mOriginalValue;}
//! Sets the \a value of the setting node
bool setValue( const QVariant &value );
//! Returns if the setting exists (value is set)
bool exists() const {return mExists;}
//! Returns if the setting is edited
bool isEdited() const {return mIsEdited;}
/**
* Returns a pointer to the setting of the node or NULLPTR if the
* setting does not exist.
*/
const QgsSettingsEntryBase *setting() const {return mSetting;}
private:
//! Private constructor, use createRootNodeData instead
QgsSettingsTreeModelNodeData( QObject *parent ) : QObject( parent ) {}
void addChildForTreeNode( const QgsSettingsTreeNode *node );
void addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode );
void addChildForSetting( const QgsSettingsEntryBase *setting );
void fillChildren();
Type mType = Type::TreeNode;
QString mName;
QVariant mValue;
QVariant mOriginalValue;
QStringList mNamedParentNodes;
bool mExists = false;
bool mIsEdited = false;
QList<QgsSettingsTreeModelNodeData *> mChildren;
QgsSettingsTreeModelNodeData *mParent = nullptr;
const QgsSettingsTreeNode *mTreeNode = nullptr;
const QgsSettingsEntryBase *mSetting = nullptr;
};
/**
* \ingroup gui
* \class QgsSettingsTreeItemDelegate
* \brief QgsSettingsTreeItemDelegate allows editing the settings in the settings tree
*
* \note Not available in Python bindings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsTreeItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
//! Constructor
explicit QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent = nullptr );
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
void setEditorData( QWidget *editor, const QModelIndex &index ) const override;
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override;
private:
QgsSettingsTreeModel *mModel = nullptr;
};
///@endcond
#endif
/**
* \ingroup gui
* \class QgsSettingsTreeModel
* \brief QgsSettingsTreeModel is a tree model for the settings tree.
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
//! Columns
enum class Column
{
Name, //!< Name
Value, //!< Value
Description, //!< Description
};
//! Constructor
QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode = nullptr, QObject *parent = nullptr );
~QgsSettingsTreeModel();
//! Apply pending changes in the model to the corresponding settings
void applyChanges();
/**
* Returns settings tree node for given \a index or the root node if the index is invalid.
*/
QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP;
//! Returns the index from the settings tree node
QModelIndex node2index( QgsSettingsTreeModelNodeData *node ) const SIP_SKIP;
QModelIndex index( int row, int column, const QModelIndex &parent ) const override;
QModelIndex parent( const QModelIndex &child ) const override;
int rowCount( const QModelIndex &parent ) const override;
int columnCount( const QModelIndex &parent ) const override;
QVariant data( const QModelIndex &index, int role ) const override;
QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
Qt::ItemFlags flags( const QModelIndex &index ) const override;
bool setData( const QModelIndex &index, const QVariant &value, int role ) override;
private:
QModelIndex indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const;
QgsSettingsTreeModelNodeData *mRootNode = nullptr;
QColor mEditedColorBack;
QColor mEditedColorFore;
QColor mNotSetColor;
};
/**
* \ingroup gui
* \class QgsSettingsTreeProxyModel
* \brief QgsSettingsTreeProxyModel allows filtering the settings tree
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsTreeProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
//! Constructor
QgsSettingsTreeProxyModel( QgsSettingsTreeNode *rootNode = nullptr, QObject *parent = nullptr );
//! Apply pending changes in the model to the corresponding settings
void applyChanges() {mSourceModel->applyChanges();}
public slots:
//! Sets the filter text
void setFilterText( const QString &filterText = QString() );
protected:
bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const override;
private:
QgsSettingsTreeModel *mSourceModel = nullptr;
bool nodeShown( QgsSettingsTreeModelNodeData *node ) const;
QString mFilterText;
};
#endif // QGSSETTINGSTREEMODEL_H

View File

@ -0,0 +1,68 @@
/***************************************************************************
qgssettingstreewidget.h
--------------------------------------
Date : April 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssettingstreewidget.h"
#include "qgssettingstreemodel.h"
#include "qgssettingstree.h"
#include <QAction>
#include <QTreeView>
#include <QHBoxLayout>
#include <QVBoxLayout>
QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent )
: QWidget( parent )
, QgsOptionsDialogHighlightWidget( this )
{
setObjectName( QStringLiteral( "mSettingsTreeWidget" ) );
QVBoxLayout *mainLayout = new QVBoxLayout( this );
mainLayout->setContentsMargins( 0, 0, 0, 0 );
mTreeModel = new QgsSettingsTreeProxyModel( QgsSettingsTree::treeRoot() );
mTreeView = new QTreeView( this );
mTreeView->setModel( mTreeModel );
mTreeView->setItemDelegate( new QgsSettingsTreeItemDelegate( qobject_cast<QgsSettingsTreeModel *>( mTreeModel->sourceModel() ), parent ) );
mTreeView->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
mTreeView->setMinimumWidth( 400 );
mTreeView->resizeColumnToContents( 0 );
mainLayout->addWidget( mTreeView );
}
void QgsSettingsTreeWidget::applyChanges() const
{
mTreeModel->applyChanges();
}
bool QgsSettingsTreeWidget::searchText( const QString &text )
{
mTreeModel->setFilterText( text );
return mTreeModel->rowCount() > 0;
}
bool QgsSettingsTreeWidget::highlightText( const QString &text )
{
Q_UNUSED( text );
return true;
}
void QgsSettingsTreeWidget::reset()
{
mTreeModel->setFilterText( QString() );
}

View File

@ -0,0 +1,58 @@
/***************************************************************************
qgssettingstreewidget.h
--------------------------------------
Date : April 2023
Copyright : (C) 2023 by Denis Rouzaud
Email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSETTINGSTREEWIDGET_H
#define QGSSETTINGSTREEWIDGET_H
#include "qgis_gui.h"
#include "qgsoptionsdialoghighlightwidget.h"
class QTreeView;
class QgsSettingsTreeProxyModel;
/**
* \ingroup gui
* \class QgsSettingsTreeWidget
* \brief QgsSettingsTreeWidget is a widget with the settings tree to visualize, search and edit settings
*
* \since QGIS 3.32
*/
class GUI_EXPORT QgsSettingsTreeWidget : public QWidget, public QgsOptionsDialogHighlightWidget
{
Q_OBJECT
public:
//! Constructor
explicit QgsSettingsTreeWidget( QWidget *parent = nullptr );
//! Apply changes to settings value
void applyChanges() const;
private:
QgsSettingsTreeProxyModel *mTreeModel = nullptr;
QTreeView *mTreeView = nullptr;
// QgsOptionsDialogHighlightWidget interface
protected:
bool searchText( const QString &text ) override;
bool highlightText( const QString &text ) override;
void reset() override;
};
#endif // QGSSETTINGSTREEWIDGET_H

View File

@ -10,7 +10,13 @@
<height>610</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
@ -24,11 +30,17 @@
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_26">
<widget class="QGroupBox" name="mGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Advanced Settings Editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_42">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="mAdvancedSettingsWarning" native="true">
<layout class="QVBoxLayout" name="verticalLayout_44">
@ -42,6 +54,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mUseNewSettingsTree">
<property name="text">
<string>Use new settings tree widget (some settings will be missing)</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mAdvancedSettingsEnableButton">
<property name="text">
@ -52,26 +71,11 @@
</layout>
</widget>
</item>
<item>
<widget class="QgsSettingsTreeWidget" name="mAdvancedSettingsEditor" native="true">
<property name="visible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsSettingsTreeWidget</class>
<extends>QWidget</extends>
<header>qgssettingstreewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>