QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgssettingsentry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssettingsentry.cpp
3 --------------------------------------
4 Date : February 2021
5 Copyright : (C) 2021 by Damiano Lombardi
6 Email : damiano at opengis dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgssettingsentry.h"
17#include "qgslogger.h"
18
19#include <QRegularExpression>
20
21
22
23
24QgsSettingsEntryGroup::QgsSettingsEntryGroup( const QList<const QgsSettingsEntryBase *> settings, bool fatalErrorIfInvalid )
25 : mSettings( settings )
26{
27 for ( const auto *setting : std::as_const( mSettings ) )
28 {
29 QString otherBaseKey = setting->definitionKey();
30 otherBaseKey = otherBaseKey.left( otherBaseKey.lastIndexOf( QLatin1Char( '/' ) ) );
31 if ( mDefinitionBaseKey.isEmpty() )
32 {
33 mDefinitionBaseKey = otherBaseKey;
34 }
35 else
36 {
37 if ( mDefinitionBaseKey != otherBaseKey )
38 {
39 QgsDebugMsg( "Settings do not share the same base definition key for this group. This will lead to unpredictable results." );
40 if ( fatalErrorIfInvalid )
41 Q_ASSERT( false );
42 mIsValid = false;
43 }
44 }
45 }
46}
47
48QString QgsSettingsEntryGroup::baseKey( const QStringList &dynamicKeyPartList ) const
49{
50 QString key = mDefinitionBaseKey;
51
52 if ( dynamicKeyPartList.isEmpty() )
53 {
54 if ( hasDynamicKey() )
55 QgsDebugMsg( QStringLiteral( "Settings group '%1' have a dynamic key but the dynamic key part was not provided" ).arg( key ) );
56
57 return key;
58 }
59 else
60 {
61 if ( !hasDynamicKey() )
62 {
63 QgsDebugMsg( QStringLiteral( "Settings group '%1' don't have a dynamic key, the provided dynamic key part will be ignored" ).arg( key ) );
64 return key;
65 }
66
67 for ( int i = 0; i < dynamicKeyPartList.size(); i++ )
68 {
69 key.replace( QStringLiteral( "%" ).append( QString::number( i + 1 ) ), dynamicKeyPartList.at( i ) );
70 }
71 }
72
73 return key;
74}
75
76void QgsSettingsEntryGroup::removeAllSettingsAtBaseKey( const QStringList &dynamicKeyPartList ) const
77{
78 QString key = baseKey( dynamicKeyPartList );
79 // https://regex101.com/r/kICr42/1
80 const thread_local QRegularExpression regularExpression( QStringLiteral( "^(\\/?(qgis\\/?)?)?$" ) );
81 if ( key.contains( regularExpression ) )
82 {
83 QgsDebugMsg( QStringLiteral( "Preventing mass removal of settings at key %1" ).arg( key ) );
84 return;
85 }
86
88 settings.remove( key );
89}
90
91void QgsSettingsEntryGroup::removeAllChildrenSettings( const QString &dynamicKeyPart ) const
92{
94}
95
96void QgsSettingsEntryGroup::removeAllChildrenSettings( const QStringList &dynamicKeyPartList ) const
97{
98 for ( const auto *setting : mSettings )
99 setting->remove( dynamicKeyPartList );
100}
101
102bool QgsSettingsEntryGroup::hasDynamicKey() const
103{
104 const thread_local QRegularExpression regularExpression( QStringLiteral( "%\\d+" ) );
105 return mDefinitionBaseKey.contains( regularExpression );
106}
107
108
109QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const
110{
111 return key( dynamicKeyPartToList( dynamicKeyPart ) );
112}
113
114QString QgsSettingsEntryBase::key( const QStringList &dynamicKeyPartList ) const
115{
116 QString completeKey = mKey;
117 if ( !mPluginName.isEmpty() )
118 {
119 if ( !completeKey.startsWith( '/' ) )
120 completeKey.prepend( '/' );
121 completeKey.prepend( mPluginName );
122 }
123
124 if ( dynamicKeyPartList.isEmpty() )
125 {
126 if ( hasDynamicKey() )
127 QgsDebugMsg( QStringLiteral( "Settings '%1' have a dynamic key but the dynamic key part was not provided" ).arg( completeKey ) );
128
129 return completeKey;
130 }
131 else
132 {
133 if ( !hasDynamicKey() )
134 {
135 QgsDebugMsg( QStringLiteral( "Settings '%1' don't have a dynamic key, the provided dynamic key part will be ignored" ).arg( completeKey ) );
136 return completeKey;
137 }
138
139 for ( int i = 0; i < dynamicKeyPartList.size(); i++ )
140 {
141 completeKey.replace( QStringLiteral( "%" ).append( QString::number( i + 1 ) ), dynamicKeyPartList.at( i ) );
142 }
143 }
144 return completeKey;
145}
146
147bool QgsSettingsEntryBase::keyIsValid( const QString &key ) const
148{
149 if ( !hasDynamicKey() )
150 {
151 if ( !key.contains( definitionKey() ) )
152 return false;
153 else
154 return key == definitionKey();
155 }
156
157 const QRegularExpression regularExpression( definitionKey().replace( QRegularExpression( QStringLiteral( "%\\d+" ) ), QStringLiteral( ".*" ) ) );
158 const QRegularExpressionMatch regularExpressionMatch = regularExpression.match( key );
159 return regularExpressionMatch.hasMatch();
160}
161
163{
164 return mKey;
165}
166
168{
169 const thread_local QRegularExpression regularExpression( QStringLiteral( "%\\d+" ) );
170 return mKey.contains( regularExpression );
171}
172
173bool QgsSettingsEntryBase::exists( const QString &dynamicKeyPart ) const
174{
175 return QgsSettings().contains( key( dynamicKeyPart ) );
176}
177
178bool QgsSettingsEntryBase::exists( const QStringList &dynamicKeyPartList ) const
179{
180 return QgsSettings().contains( key( dynamicKeyPartList ) );
181}
182
183void QgsSettingsEntryBase::remove( const QString &dynamicKeyPart ) const
184{
185 QgsSettings().remove( key( dynamicKeyPart ) );
186}
187
188void QgsSettingsEntryBase::remove( const QStringList &dynamicKeyPartList ) const
189{
190 QgsSettings().remove( key( dynamicKeyPartList ) );
191}
192
193bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QString &dynamicKeyPart ) const
194{
195 return setVariantValuePrivate( value, dynamicKeyPartToList( dynamicKeyPart ) );
196}
197
198bool QgsSettingsEntryBase::setVariantValue( const QVariant &value, const QStringList &dynamicKeyPartList ) const
199{
200 return setVariantValuePrivate( value, dynamicKeyPartList );
201}
202
203bool QgsSettingsEntryBase::setVariantValuePrivate( const QVariant &value, const QStringList &dynamicKeyPartList ) const
204{
205 if ( mOptions.testFlag( Qgis::SettingsOption::SaveFormerValue ) )
206 {
207 if ( exists( dynamicKeyPartList ) )
208 {
209 QVariant currentValue = valueAsVariant( key( dynamicKeyPartList ) );
210 if ( value != currentValue )
211 {
212 QgsSettings().setValue( formerValuekey( dynamicKeyPartList ), currentValue );
213 }
214 }
215 }
216 QgsSettings().setValue( key( dynamicKeyPartList ), value );
217 return true;
218}
219
220QStringList QgsSettingsEntryBase::dynamicKeyPartToList( const QString &dynamicKeyPart )
221{
222 QStringList dynamicKeyPartList;
223 if ( !dynamicKeyPart.isNull() )
224 dynamicKeyPartList.append( dynamicKeyPart );
225 return dynamicKeyPartList;
226}
227
228QVariant QgsSettingsEntryBase::valueAsVariant( const QString &dynamicKeyPart ) const
229{
230 return valueAsVariant( dynamicKeyPartToList( dynamicKeyPart ) );
231}
232
233QVariant QgsSettingsEntryBase::valueAsVariant( const QStringList &dynamicKeyPartList ) const
234{
235 return QgsSettings().value( key( dynamicKeyPartList ), mDefaultValue );
236}
237
238QVariant QgsSettingsEntryBase::valueAsVariant( const QString &dynamicKeyPart, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const
239{
241 return valueAsVariant( dynamicKeyPartToList( dynamicKeyPart ), useDefaultValueOverride, defaultValueOverride );
243}
244
245QVariant QgsSettingsEntryBase::valueAsVariant( const QStringList &dynamicKeyPartList, bool useDefaultValueOverride, const QVariant &defaultValueOverride ) const
246{
247 if ( useDefaultValueOverride )
248 return QgsSettings().value( key( dynamicKeyPartList ), defaultValueOverride );
249 else
250 return QgsSettings().value( key( dynamicKeyPartList ), mDefaultValue );
251}
252
253QVariant QgsSettingsEntryBase::valueAsVariantWithDefaultOverride( const QVariant &defaultValueOverride, const QString &dynamicKeyPart ) const
254{
255 return QgsSettings().value( key( dynamicKeyPart ), defaultValueOverride );
256}
257
258QVariant QgsSettingsEntryBase::valueAsVariantWithDefaultOverride( const QVariant &defaultValueOverride, const QStringList &dynamicKeyPartList ) const
259{
260 return QgsSettings().value( key( dynamicKeyPartList ), defaultValueOverride );
261}
262
263
265{
266 return mDefaultValue;
267}
268
270{
271 return mDescription;
272}
273
274QVariant QgsSettingsEntryBase::formerValueAsVariant( const QString &dynamicKeyPart ) const
275{
276 return formerValueAsVariant( dynamicKeyPartToList( dynamicKeyPart ) );
277}
278
279QVariant QgsSettingsEntryBase::formerValueAsVariant( const QStringList &dynamicKeyPartList ) const
280{
281 Q_ASSERT( mOptions.testFlag( Qgis::SettingsOption::SaveFormerValue ) );
282 QVariant defaultValueOverride = valueAsVariant( key( dynamicKeyPartList ) );
283 return QgsSettings().value( formerValuekey( dynamicKeyPartList ), defaultValueOverride );
284}
285
286QString QgsSettingsEntryBase::formerValuekey( const QStringList &dynamicKeyPartList ) const
287{
288 return key( dynamicKeyPartList ) + QStringLiteral( "_formervalue" );
289}
290
bool exists(const QString &dynamicKeyPart=QString()) const
Returns true if the settings is contained in the underlying QSettings.
QVariant defaultValueAsVariant() const
Returns settings default value.
bool keyIsValid(const QString &key) const
Returns true if the provided key match the settings entry.
QString description() const
Returns the settings entry description.
bool hasDynamicKey() const
Returns true if a part of the settings key is built dynamically.
void remove(const QString &dynamicKeyPart=QString()) const
Removes the settings from the underlying QSettings.
virtual Q_DECL_DEPRECATED bool setVariantValue(const QVariant &value, const QString &dynamicKeyPart=QString()) const
Set settings value.
QString definitionKey() const
Returns settings entry defining key.
QVariant formerValueAsVariant(const QString &dynamicKeyPart) const
Returns the former value of the settings if it has been enabled in the options.
QVariant valueAsVariant(const QString &dynamicKeyPart=QString()) const
Returns settings value with the dynamicKeyPart argument specifying the dynamic part of the settings k...
bool setVariantValuePrivate(const QVariant &value, const QStringList &dynamicKeyPartList=QStringList()) const
Sets the settings value with a variant value.
QString key(const QString &dynamicKeyPart=QString()) const
Returns settings entry key.
static QStringList dynamicKeyPartToList(const QString &dynamicKeyPart)
Transforms a dynamic key part string to list.
QVariant valueAsVariantWithDefaultOverride(const QVariant &defaultValueOverride, const QString &dynamicKeyPart=QString()) const
Returns settings value with a defaultValueOverride.
void removeAllChildrenSettings(const QString &dynamicKeyPart=QString()) const
Removes all the settings from this group The dynamicKeyPart argument specifies the dynamic part of th...
const QList< const QgsSettingsEntryBase * > settings() const
Returns all the settings.
void removeAllSettingsAtBaseKey(const QStringList &dynamicKeyPartList=QStringList()) const
Removes all the settings at the base key for the given dynamicKeyPartList This means it might remove ...
QgsSettingsEntryGroup(const QList< const QgsSettingsEntryBase * > settings)
Constructor.
QString baseKey(const QStringList &dynamicKeyPartList=QStringList()) const
Returns the base key for the given dynamicKeyPartList.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:3061
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:3060
#define QgsDebugMsg(str)
Definition: qgslogger.h:38