Skip to content

Commit

Permalink
allow to set specific settings editors + add test
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Oct 14, 2024
1 parent 40246d3 commit 71469b5
Show file tree
Hide file tree
Showing 14 changed files with 158 additions and 44 deletions.
18 changes: 11 additions & 7 deletions python/PyQt6/gui/additions/qgssettingsenumflageditorwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
***************************************************************************
"""

from qgis.PyQt.QtWidgets import QWidget, QComboBox
from qgis.PyQt.QtWidgets import QComboBox

from qgis.core import QgsSettingsEntryBase
from qgis.gui import QgsSettingsEditorWidgetWrapper
Expand Down Expand Up @@ -62,19 +62,23 @@ def variantValueFromWidget(self):
return None

def setWidgetFromVariant(self, value):
if self.editor:
idx = self.editor.findData(value)
self.editor.setCurrentIndex(idx)
if self.editor and value is not None:
ok = True
if isinstance(value, str):
value, ok = self.setting.metaEnum().keyToValue(value)
if ok:
idx = self.editor.findData(int(value))
self.editor.setCurrentIndex(idx)
return idx >= 0
return False

def createEditorPrivate(self, parent=None):
return QComboBox(parent)

def configureEditorPrivate(self, editor: QWidget, setting: QgsSettingsEntryBase):
def configureEditorPrivate(self, editor: QComboBox, setting: QgsSettingsEntryBase):
self.setting = setting
if isinstance(editor, QComboBox):
self.editor = editor
self.editor = editor
if editor is not None:
for i in range(self.setting.metaEnum().keyCount()):
value = self.setting.metaEnum().value(i)
key = self.setting.metaEnum().key(i)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@ Constructor
%End
~QgsSettingsEditorWidgetRegistry();

bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/ );
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper );
%Docstring
Adds an editor widget ``wrapper`` to the registry
If an editor widget with same id already exists, the wrapper is deleted and ``False`` is returned.
%End

QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const;
void addWrapperForSetting( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/, const QgsSettingsEntryBase *setting /KeepReference/ );
%Docstring
Adds an editor widget ``wrapper`` for a specific setting to the registry

.. versionadded:: 3.40
%End

QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const /Factory/;
%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/;
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = 0 ) const /KeepReference/;
%Docstring
Creates an editor widget for the given ``setting`` using the corresponding registered wrapper
%End
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Base class for settings editor wrappers
#include "qgssettingseditorwidgetwrapper.h"
%End
public:
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) /Factory/;
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget );
%Docstring
Creates a wrapper from the definition stored in a ``widget`` created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor`
%End
Expand All @@ -44,12 +44,12 @@ This id of the type of settings it handles
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;
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0 /Factory/;
%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 );
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = 0 ) /KeepReference/;
%Docstring
Creates the editor widget for the given ``setting``
%End
Expand Down Expand Up @@ -77,7 +77,7 @@ 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;
virtual bool setWidgetFromVariant( const QVariant &value ) const = 0;
%Docstring
Sets the ``value`` of the widget
The wrapper must be configured before calling this medthod
Expand Down Expand Up @@ -106,12 +106,12 @@ Returns the dynamic key parts


protected:
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0;
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0 /KeepReference,Factory/;
%Docstring
Creates the widgets
%End

virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0;
virtual bool configureEditorPrivate( QWidget *editor /TransferBack/, const QgsSettingsEntryBase *setting /KeepReference/ ) = 0;
%Docstring
Configures an existing ``editor`` widget
%End
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Constructor

virtual bool setSettingFromWidget() const = 0;

virtual void setWidgetFromVariant( const QVariant &value ) const;
virtual bool setWidgetFromVariant( const QVariant &value ) const;

virtual bool setWidgetValue( const U &value ) const = 0;
%Docstring
Expand Down
14 changes: 9 additions & 5 deletions python/gui/additions/qgssettingsenumflageditorwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
***************************************************************************
"""

from qgis.PyQt.QtWidgets import QWidget, QComboBox
from qgis.PyQt.QtWidgets import QComboBox

from qgis.core import QgsSettingsEntryBase
from qgis.gui import QgsSettingsEditorWidgetWrapper
Expand Down Expand Up @@ -62,16 +62,20 @@ def variantValueFromWidget(self):
return None

def setWidgetFromVariant(self, value):
if self.editor:
idx = self.editor.findData(value)
self.editor.setCurrentIndex(idx)
if self.editor and value is not None:
ok = True
if isinstance(value, str):
value, ok = self.setting.metaEnum().keyToValue(value)
if ok:
idx = self.editor.findData(int(value))
self.editor.setCurrentIndex(idx)
return idx >= 0
return False

def createEditorPrivate(self, parent=None):
return QComboBox(parent)

def configureEditorPrivate(self, editor: QWidget, setting: QgsSettingsEntryBase):
def configureEditorPrivate(self, editor: QComboBox, setting: QgsSettingsEntryBase):
self.setting = setting
if isinstance(editor, QComboBox):
self.editor = editor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@ Constructor
%End
~QgsSettingsEditorWidgetRegistry();

bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/ );
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper );
%Docstring
Adds an editor widget ``wrapper`` to the registry
If an editor widget with same id already exists, the wrapper is deleted and ``False`` is returned.
%End

QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const;
void addWrapperForSetting( QgsSettingsEditorWidgetWrapper *wrapper /Transfer/, const QgsSettingsEntryBase *setting /KeepReference/ );
%Docstring
Adds an editor widget ``wrapper`` for a specific setting to the registry

.. versionadded:: 3.40
%End

QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const /Factory/;
%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/;
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = 0 ) const /KeepReference/;
%Docstring
Creates an editor widget for the given ``setting`` using the corresponding registered wrapper
%End
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Base class for settings editor wrappers
#include "qgssettingseditorwidgetwrapper.h"
%End
public:
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget ) /Factory/;
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget );
%Docstring
Creates a wrapper from the definition stored in a ``widget`` created by :py:func:`~QgsSettingsEditorWidgetWrapper.createEditor`
%End
Expand All @@ -44,12 +44,12 @@ This id of the type of settings it handles
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;
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = 0 ) const = 0 /Factory/;
%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 );
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = 0 ) /KeepReference/;
%Docstring
Creates the editor widget for the given ``setting``
%End
Expand Down Expand Up @@ -77,7 +77,7 @@ 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;
virtual bool setWidgetFromVariant( const QVariant &value ) const = 0;
%Docstring
Sets the ``value`` of the widget
The wrapper must be configured before calling this medthod
Expand Down Expand Up @@ -106,12 +106,12 @@ Returns the dynamic key parts


protected:
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0;
virtual QWidget *createEditorPrivate( QWidget *parent = 0 ) const = 0 /KeepReference,Factory/;
%Docstring
Creates the widgets
%End

virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0;
virtual bool configureEditorPrivate( QWidget *editor /TransferBack/, const QgsSettingsEntryBase *setting /KeepReference/ ) = 0;
%Docstring
Configures an existing ``editor`` widget
%End
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Constructor

virtual bool setSettingFromWidget() const = 0;

virtual void setWidgetFromVariant( const QVariant &value ) const;
virtual bool setWidgetFromVariant( const QVariant &value ) const;

virtual bool setWidgetValue( const U &value ) const = 0;
%Docstring
Expand Down
9 changes: 9 additions & 0 deletions src/gui/settings/qgssettingseditorwidgetregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ bool QgsSettingsEditorWidgetRegistry::addWrapper( QgsSettingsEditorWidgetWrapper
return true;
}

void QgsSettingsEditorWidgetRegistry::addWrapperForSetting( QgsSettingsEditorWidgetWrapper *wrapper, const QgsSettingsEntryBase *setting )
{
mSpecificWrappers.insert( setting, wrapper );
}

QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetRegistry::createWrapper( const QString &id, QObject *parent ) const
{
QgsSettingsEditorWidgetWrapper *wrapper = mWrappers.value( id );
Expand All @@ -97,6 +102,10 @@ QgsSettingsEditorWidgetWrapper *QgsSettingsEditorWidgetRegistry::createWrapper(

QWidget *QgsSettingsEditorWidgetRegistry::createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent ) const
{
if ( mSpecificWrappers.contains( setting ) )
{
return mSpecificWrappers.value( setting )->createEditor( setting, dynamicKeyPartList, parent );
}
QgsSettingsEditorWidgetWrapper *eww = createWrapper( setting->typeId(), parent );
if ( eww )
return eww->createEditor( setting, dynamicKeyPartList, parent );
Expand Down
13 changes: 10 additions & 3 deletions src/gui/settings/qgssettingseditorwidgetregistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,23 @@ class GUI_EXPORT QgsSettingsEditorWidgetRegistry
* Adds an editor widget \a wrapper to the registry
* If an editor widget with same id already exists, the wrapper is deleted and FALSE is returned.
*/
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper SIP_TRANSFER );
bool addWrapper( QgsSettingsEditorWidgetWrapper *wrapper );

/**
* Adds an editor widget \a wrapper for a specific setting to the registry
* \since QGIS 3.40
*/
void addWrapperForSetting( QgsSettingsEditorWidgetWrapper *wrapper SIP_TRANSFER, const QgsSettingsEntryBase *setting SIP_KEEPREFERENCE );

//! Returns a new instance of the editor widget for the given \a id
QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const;
QgsSettingsEditorWidgetWrapper *createWrapper( const QString &id, QObject *parent ) const SIP_FACTORY;

//! 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;
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList, QWidget *parent = nullptr ) const SIP_KEEPREFERENCE;

private:
QMap<QString, QgsSettingsEditorWidgetWrapper *> mWrappers;
QMap<const QgsSettingsEntryBase *, QgsSettingsEditorWidgetWrapper *> mSpecificWrappers;
};

#endif // QGSSETTINGSEDITORREGISTRY_H
12 changes: 6 additions & 6 deletions src/gui/settings/qgssettingseditorwidgetwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ 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;
static QgsSettingsEditorWidgetWrapper *fromWidget( const QWidget *widget );

//! Constructor
QgsSettingsEditorWidgetWrapper( QObject *parent = nullptr );
Expand All @@ -50,10 +50,10 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject
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;
virtual QgsSettingsEditorWidgetWrapper *createWrapper( QObject *parent = nullptr ) const = 0 SIP_FACTORY;

//! Creates the editor widget for the given \a setting
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = nullptr );
QWidget *createEditor( const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList(), QWidget *parent = nullptr ) SIP_KEEPREFERENCE;

//! Configures the \a editor according the setting
bool configureEditor( QWidget *editor, const QgsSettingsEntryBase *setting, const QStringList &dynamicKeyPartList = QStringList() );
Expand All @@ -80,7 +80,7 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject
* Sets the \a value of the widget
* The wrapper must be configured before calling this medthod
*/
virtual void setWidgetFromVariant( const QVariant &value ) const = 0;
virtual bool setWidgetFromVariant( const QVariant &value ) const = 0;

/**
* Configure the settings update behavior when a widget value is changed.
Expand All @@ -103,10 +103,10 @@ class GUI_EXPORT QgsSettingsEditorWidgetWrapper : public QObject

protected:
//! Creates the widgets
virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const = 0;
virtual QWidget *createEditorPrivate( QWidget *parent = nullptr ) const = 0 SIP_KEEPREFERENCE SIP_FACTORY;

//! Configures an existing \a editor widget
virtual bool configureEditorPrivate( QWidget *editor, const QgsSettingsEntryBase *setting ) = 0;
virtual bool configureEditorPrivate( QWidget *editor SIP_TRANSFERBACK, const QgsSettingsEntryBase *setting SIP_KEEPREFERENCE ) = 0;

/**
* Enables automatic update, which causes the setting to be updated immediately when the widget
Expand Down
4 changes: 2 additions & 2 deletions src/gui/settings/qgssettingseditorwidgetwrapperimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ class QgsSettingsEditorWidgetWrapperTemplate : public QgsSettingsEditorWidgetWra

virtual bool setSettingFromWidget() const override = 0;

void setWidgetFromVariant( const QVariant &value ) const override
bool setWidgetFromVariant( const QVariant &value ) const override
{
setWidgetValue( mSetting->convertFromVariant( value ) );
return setWidgetValue( mSetting->convertFromVariant( value ) );
}

//! Sets the widget value
Expand Down
5 changes: 4 additions & 1 deletion src/gui/settings/qgssettingstreemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,10 @@ void QgsSettingsTreeItemDelegate::setEditorData( QWidget *editor, const QModelIn
{
QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor );
if ( eww )
eww->setWidgetFromVariant( index.model()->data( index, Qt::DisplayRole ) );
{
QVariant value = index.model()->data( index, Qt::DisplayRole );
eww->setWidgetFromVariant( value );
}
}

void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
Expand Down
Loading

0 comments on commit 71469b5

Please sign in to comment.