Skip to content

Commit

Permalink
add QgsSettingsEntryBase and implementation to support tree elements
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Jan 16, 2023
1 parent 7bb250e commit 82d4e0e
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 42 deletions.
54 changes: 43 additions & 11 deletions src/core/settings/qgssettingsentry.cpp
Expand Up @@ -17,11 +17,11 @@
#include "qgslogger.h"

#include <QRegularExpression>
#include <QDir>




QgsSettingsEntryGroup::QgsSettingsEntryGroup( const QList<const QgsSettingsEntryBase *> settings, bool fatalErrorIfInvalid )
QgsSettingsEntryGroup::QgsSettingsEntryGroup( QList<const QgsSettingsEntryBase *> settings, bool fatalErrorIfInvalid )
: mSettings( settings )
{
for ( const auto *setting : std::as_const( mSettings ) )
Expand Down Expand Up @@ -106,6 +106,29 @@ bool QgsSettingsEntryGroup::hasDynamicKey() const
}


QgsSettingsEntryBase::QgsSettingsEntryBase( const QString &key, QgsSettingsTreeElement *parentTreeElement, const QVariant &defaultValue, const QString &description, Qgis::SettingsOptions options )
: mParentTreeElement( parentTreeElement )
, mDefaultValue( defaultValue )
, mDescription( description )
, mPluginName()
, mOptions( options )
{
QgsDebugMsg( QString( "constructor with parent for %1" ).arg( key ) );
mKey = QDir::cleanPath( QStringLiteral( "%1/%2" ).arg( parentTreeElement ? parentTreeElement->completeKey() : QString(), key ) );

if ( parentTreeElement )
{
parentTreeElement->registerChildSetting( this, key );
}
}

QgsSettingsEntryBase::~QgsSettingsEntryBase()
{
if ( mParentTreeElement )
mParentTreeElement->unregisterChildSetting( this );
}


QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const
{
return key( dynamicKeyPartToList( dynamicKeyPart ) );
Expand Down Expand Up @@ -288,31 +311,40 @@ QVariant QgsSettingsEntryBase::formerValueAsVariant( const QStringList &dynamicK
return QgsSettings().value( formerValuekey( dynamicKeyPartList ), defaultValueOverride );
}

bool QgsSettingsEntryBase::migrateFromKey( const QString &oldKey, const QString &oldSection, const QString &dynamicKeyPart ) const
{
return migrateFromKey( oldKey, oldSection, dynamicKeyPartToList( dynamicKeyPart ) );
}

bool QgsSettingsEntryBase::migrateFromKey( const QString &oldKey, const QString &oldSection, const QStringList &dynamicKeyPartList ) const
bool QgsSettingsEntryBase::copyValueFromKey( const QString &key, const QStringList &dynamicKeyPartList, bool deleteOldKey ) const
{
if ( exists( dynamicKeyPartList ) )
return false;

const QString oldCompleteKey = completeKeyPrivate( QStringLiteral( "%1/%2" ).arg( oldSection, oldKey ), dynamicKeyPartList );
QgsSettings settings;

if ( QgsSettings().contains( oldCompleteKey ) )
const QString oldCompleteKey = completeKeyPrivate( key, dynamicKeyPartList );

if ( settings.contains( oldCompleteKey ) )
{
QVariant oldValue = QgsSettings().value( oldCompleteKey, mDefaultValue );
setVariantValuePrivate( oldValue );
QVariant oldValue = settings.value( oldCompleteKey, mDefaultValue );
setVariantValuePrivate( oldValue, dynamicKeyPartList );
if ( deleteOldKey )
settings.remove( oldCompleteKey );
return true;
}
return false;
}

void QgsSettingsEntryBase::copyValueToKey( const QString &key, const QStringList &dynamicKeyPartList ) const
{
QgsSettings settings;
const QString completeKey = completeKeyPrivate( key, dynamicKeyPartList );
QgsSettings().setValue( completeKey, valueAsVariant( dynamicKeyPartList ) );
}

QString QgsSettingsEntryBase::formerValuekey( const QStringList &dynamicKeyPartList ) const
{
return key( dynamicKeyPartList ) + QStringLiteral( "_formervalue" );
}





79 changes: 69 additions & 10 deletions src/core/settings/qgssettingsentry.h
Expand Up @@ -26,6 +26,7 @@
#include "qgssettings.h"

class QgsSettingsEntryBase;
class QgsSettingsTreeElement;


/**
Expand All @@ -39,7 +40,7 @@ class CORE_EXPORT QgsSettingsEntryGroup
{
public:
//! Constructor
QgsSettingsEntryGroup( const QList<const QgsSettingsEntryBase *> settings )
QgsSettingsEntryGroup( QList<const QgsSettingsEntryBase *> settings )
: QgsSettingsEntryGroup( settings, true )
{}
#ifdef SIP_RUN
Expand All @@ -52,7 +53,7 @@ class CORE_EXPORT QgsSettingsEntryGroup
#endif

//! Constructor
QgsSettingsEntryGroup( const QList<const QgsSettingsEntryBase *> settings, bool fatalErrorIfInvalid ) SIP_SKIP;
QgsSettingsEntryGroup( QList<const QgsSettingsEntryBase *> settings, bool fatalErrorIfInvalid ) SIP_SKIP;

//! Returns if the group is valid (if settings share the same base key)
bool isValid() const {return mIsValid;}
Expand Down Expand Up @@ -120,6 +121,8 @@ class CORE_EXPORT QgsSettingsEntryBase
sipType = sipType_QgsSettingsEntryDouble;
else if ( dynamic_cast< QgsSettingsEntryColor * >( sipCpp ) )
sipType = sipType_QgsSettingsEntryColor;
else if ( dynamic_cast< QgsSettingsEntryBase * >( sipCpp ) )
sipType = sipType_QgsSettingsEntryBase;
else
sipType = NULL;
SIP_END
Expand All @@ -133,7 +136,6 @@ class CORE_EXPORT QgsSettingsEntryBase
*/
static QStringList dynamicKeyPartToList( const QString &dynamicKeyPart );


/**
* Constructor for QgsSettingsEntryBase.
*
Expand All @@ -155,10 +157,25 @@ class CORE_EXPORT QgsSettingsEntryBase
, mOptions( options )
{}

/**
* Constructor for QgsSettingsEntryBase.
*
* The \a key argument specifies the key of the settings.
* The \a parent argument specifies the parent in the tree of settings.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
* The \a options argument specifies the options for the settings entry.
*/
QgsSettingsEntryBase( const QString &key,
QgsSettingsTreeElement *parentTreeElement,
const QVariant &defaultValue = QVariant(),
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() );

/**
* Destructor for QgsSettingsEntryBase.
*/
virtual ~QgsSettingsEntryBase() {}
virtual ~QgsSettingsEntryBase();

/**
* Returns settings entry key.
Expand Down Expand Up @@ -297,7 +314,8 @@ class CORE_EXPORT QgsSettingsEntryBase
/**
* Returns the settings entry type.
*/
virtual Qgis::SettingsType settingsType() const = 0;
virtual Qgis::SettingsType settingsType() const {return Qgis::SettingsType::Custom;}
// This cannot be pure virtual otherwise SIP is failing

/**
* Returns the settings entry description.
Expand All @@ -319,17 +337,26 @@ class CORE_EXPORT QgsSettingsEntryBase
QVariant formerValueAsVariant( const QStringList &dynamicKeyPartList ) const;

/**
* Check if the settings does not exist and try to set it from a given \a oldKey and \a oldSection
* Checks if the settings does not exist and try to set it from a given \a oldKey.
* \arg dynamicKeyPartList is the optional dynamic key part to determine the key. It must be the same for origin and destination keys.
* If \a deleteOldKey, the setting with the old key will be removed
* \returns TRUE if the key exists and the setting value could be copied
* \since QGIS 3.30
*/
bool migrateFromKey( const QString &oldKey, const QString &oldSection = QString(), const QString &dynamicKeyPart = QString() ) const;
bool copyValueFromKey( const QString &key, const QStringList &dynamicKeyPartList = QStringList(), bool deleteOldKey = false ) const;

/**
* Check if the settings does not exist and try to set it from a given \a oldKey
* \note The old key must contain its section (the section from the current setting will not be prepended)
* Copies the settings to the given \a key
* \arg dynamicKeyPartList is the optional dynamic key part to determine the key. It must be the same for origin and destination keys.
* \since QGIS 3.30
*/
bool migrateFromKey( const QString &oldKey, const QString &oldSection, const QStringList &dynamicKeyPartList ) const;
void copyValueToKey( const QString &key, const QStringList &dynamicKeyPartList = QStringList() ) const;

/**
* Returns the parent tree element
* \since QGIS 3.30
*/
QgsSettingsTreeElement *parent() const {return mParentTreeElement;}

protected:

Expand All @@ -345,6 +372,7 @@ class CORE_EXPORT QgsSettingsEntryBase

QString completeKeyPrivate( const QString &key, const QStringList &dynamicKeyPartList ) const;

QgsSettingsTreeElement *mParentTreeElement = nullptr;
QString mKey;
QVariant mDefaultValue;
QString mDescription;
Expand Down Expand Up @@ -372,6 +400,24 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase
* Constructor for QgsSettingsEntryByReference.
*
* The \a key argument specifies the key of the settings.
* The \a parent argument specifies the parent in the tree of settings.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
* The \a options arguments specifies the options for the settings entry.
*/
QgsSettingsEntryByReference( const QString &key,
QgsSettingsTreeElement *parent,
const T &defaultValue,
const QString &description = QString(),
Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( key, parent, defaultValue, description, options )
{}

/**
* Constructor for QgsSettingsEntryByReference.
*
* The \a key argument specifies the key of the settings.
* The \a section argument specifies the section.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
* The \a options arguments specifies the options for the settings entry.
Expand Down Expand Up @@ -513,6 +559,19 @@ class QgsSettingsEntryByValue : public QgsSettingsEntryBase
{
public:

/**
* Constructor for QgsSettingsEntryByValue.
*
* The \a key argument specifies the key of the settings.
* The \a parent argument specifies the parent in the tree of settings.
* The \a section argument specifies the section.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
* The \a options arguments specifies the options for the settings entry.
*/
QgsSettingsEntryByValue( const QString &key, QgsSettingsTreeElement *parent, QVariant defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryBase( key, parent, defaultValue, description, options )
{}

/**
* Constructor for QgsSettingsEntryByValue.
Expand Down
25 changes: 25 additions & 0 deletions src/core/settings/qgssettingsentryenumflag.h
Expand Up @@ -39,6 +39,31 @@ class QgsSettingsEntryEnumFlag : public QgsSettingsEntryByValue<T>
* Constructor for QgsSettingsEntryEnumFlagBase.
*
* The \a key argument specifies the final part of the settings key.
* The \a parent argument specifies the parent in the tree of settings.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
*
* \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS).
* \note for Python bindings, a custom implementation is achieved in Python directly
*/
QgsSettingsEntryEnumFlag( const QString &key, QgsSettingsTreeElement *parent, T defaultValue, const QString &description = QString(), Qgis::SettingsOptions options = Qgis::SettingsOptions() )
: QgsSettingsEntryByValue<T>( key,
parent,
QMetaEnum::fromType<T>().isFlag() ? qgsFlagValueToKeys( defaultValue ) : qgsEnumValueToKey( defaultValue ),
description,
options )
{
mMetaEnum = QMetaEnum::fromType<T>();
Q_ASSERT( mMetaEnum.isValid() );
if ( !mMetaEnum.isValid() )
QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum/Flag probably misses Q_ENUM/Q_FLAG declaration. Settings key: '%1'" ).arg( this->key() ) );
}

/**
* Constructor for QgsSettingsEntryEnumFlagBase.
*
* The \a parent argument specifies the parent in the tree of settings.
* The \a key argument specifies the final part of the settings key.
* The \a section argument specifies the section.
* The \a defaultValue argument specifies the default value for the settings entry.
* The \a description argument specifies a description for the settings entry.
Expand Down

0 comments on commit 82d4e0e

Please sign in to comment.