QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgssettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssettings.cpp
3 --------------------------------------
4 Date : January 2017
5 Copyright : (C) 2017 by Alessandro Pasotti
6 Email : apasotti at boundlessgeo dot com
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
17#include <cstdlib>
18
19#include <QFileInfo>
20#include <QSettings>
21#include <QDir>
22
23#include "qgssettings.h"
24#include "qgsvariantutils.h"
25
26Q_GLOBAL_STATIC( QString, sGlobalSettingsPath )
27
28bool QgsSettings::setGlobalSettingsPath( const QString &path )
29{
30 if ( QFileInfo::exists( path ) )
31 {
32 *sGlobalSettingsPath() = path;
33 return true;
34 }
35 return false;
36}
37
38void QgsSettings::init()
39{
40 if ( ! sGlobalSettingsPath()->isEmpty() )
41 {
42 mGlobalSettings = new QSettings( *sGlobalSettingsPath(), QSettings::IniFormat );
43#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
44 mGlobalSettings->setIniCodec( "UTF-8" );
45#endif
46 }
47}
48
49
50QgsSettings::QgsSettings( const QString &organization, const QString &application, QObject *parent )
51{
52 mUserSettings = new QSettings( organization, application, parent );
53 init();
54}
55
56QgsSettings::QgsSettings( QSettings::Scope scope, const QString &organization,
57 const QString &application, QObject *parent )
58{
59 mUserSettings = new QSettings( scope, organization, application, parent );
60 init();
61}
62
63QgsSettings::QgsSettings( QSettings::Format format, QSettings::Scope scope,
64 const QString &organization, const QString &application, QObject *parent )
65{
66 mUserSettings = new QSettings( format, scope, organization, application, parent );
67 init();
68}
69
70QgsSettings::QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent )
71{
72 mUserSettings = new QSettings( fileName, format, parent );
73 init();
74}
75
76QgsSettings::QgsSettings( QObject *parent )
77{
78 mUserSettings = new QSettings( parent );
79 init();
80}
81
83{
84 delete mUserSettings;
85 delete mGlobalSettings;
86}
87
88
89void QgsSettings::beginGroup( const QString &prefix, const QgsSettings::Section section )
90{
91 const QString pKey = prefixedKey( prefix, section );
92 mUserSettings->beginGroup( pKey );
93 if ( mGlobalSettings )
94 {
95 mGlobalSettings->beginGroup( pKey );
96 }
97}
98
100{
101 mUserSettings->endGroup();
102 if ( mGlobalSettings )
103 {
104 mGlobalSettings->endGroup();
105 }
106}
107
108QString QgsSettings::group() const
109{
110 return mUserSettings->group();
111}
112
113QStringList QgsSettings::allKeys() const
114{
115 QStringList keys = mUserSettings->allKeys();
116 if ( mGlobalSettings )
117 {
118 const QStringList constAllKeys = mGlobalSettings->allKeys();
119 std::copy_if( constAllKeys.constBegin(), constAllKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
120 }
121 return keys;
122}
123
124
125QStringList QgsSettings::childKeys() const
126{
127 QStringList keys = mUserSettings->childKeys();
128 if ( mGlobalSettings )
129 {
130 const QStringList constChildKeys = mGlobalSettings->childKeys();
131 std::copy_if( constChildKeys.constBegin(), constChildKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
132 }
133 return keys;
134}
135
137{
138 switch ( origin )
139 {
141 {
142 QStringList keys = mUserSettings->childGroups();
143 if ( mGlobalSettings )
144 {
145 const QStringList constChildGroups = mGlobalSettings->childGroups();
146 std::copy_if( constChildGroups.constBegin(), constChildGroups.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
147 }
148 return keys;
149 }
150
152 return mUserSettings->childGroups();
153
155 return mGlobalSettings ? mGlobalSettings->childGroups() : QStringList();
156 }
157
159}
160
162{
164}
165
167{
168 return *sGlobalSettingsPath();
169}
170
171QVariant QgsSettings::value( const QString &key, const QVariant &defaultValue, const QgsSettings::Section section ) const
172{
173 const QString pKey = prefixedKey( key, section );
174 if ( !QgsVariantUtils::isNull( mUserSettings->value( pKey ) ) )
175 {
176 return mUserSettings->value( pKey );
177 }
178 if ( mGlobalSettings )
179 {
180 return mGlobalSettings->value( pKey, defaultValue );
181 }
182 return defaultValue;
183}
184
185bool QgsSettings::contains( const QString &key, const QgsSettings::Section section ) const
186{
187 const QString pKey = prefixedKey( key, section );
188 return mUserSettings->contains( pKey ) ||
189 ( mGlobalSettings && mGlobalSettings->contains( pKey ) );
190}
191
193{
194 return mUserSettings->fileName();
195}
196
198{
199 mUserSettings->sync();
200}
201
202void QgsSettings::remove( const QString &key, const QgsSettings::Section section )
203{
204 const QString pKey = prefixedKey( key, section );
205 mUserSettings->remove( pKey );
206}
207
208QString QgsSettings::prefixedKey( const QString &key, const Section section ) const
209{
210 QString prefix;
211 switch ( section )
212 {
213 case Section::Core:
214 prefix = QStringLiteral( "core" );
215 break;
216 case Section::Server:
217 prefix = QStringLiteral( "server" );
218 break;
219 case Section::Gui:
220 prefix = QStringLiteral( "gui" );
221 break;
222 case Section::Plugins:
223 prefix = QStringLiteral( "plugins" );
224 break;
225 case Section::Misc:
226 prefix = QStringLiteral( "misc" );
227 break;
228 case Section::Auth:
229 prefix = QStringLiteral( "auth" );
230 break;
231 case Section::App:
232 prefix = QStringLiteral( "app" );
233 break;
234 case Section::Providers:
235 prefix = QStringLiteral( "providers" );
236 break;
237 case Section::Expressions:
238 prefix = QStringLiteral( "expressions" );
239 break;
240 case Section::Gps:
241 prefix = QStringLiteral( "gps" );
242 break;
243 case Section::NoSection:
244 return sanitizeKey( key );
245 }
246 return prefix + "/" + sanitizeKey( key );
247}
248
249
250int QgsSettings::beginReadArray( const QString &prefix )
251{
252 int size = mUserSettings->beginReadArray( sanitizeKey( prefix ) );
253 if ( 0 == size && mGlobalSettings )
254 {
255 size = mGlobalSettings->beginReadArray( sanitizeKey( prefix ) );
256 mUsingGlobalArray = ( size > 0 );
257 }
258 return size;
259}
260
261void QgsSettings::beginWriteArray( const QString &prefix, int size )
262{
263 mUsingGlobalArray = false;
264 mUserSettings->beginWriteArray( prefix, size );
265}
266
268{
269 mUserSettings->endArray();
270 if ( mGlobalSettings )
271 {
272 mGlobalSettings->endArray();
273 }
274 mUsingGlobalArray = false;
275}
276
278{
279 if ( mGlobalSettings && mUsingGlobalArray )
280 {
281 mGlobalSettings->setArrayIndex( i );
282 }
283 else
284 {
285 mUserSettings->setArrayIndex( i );
286 }
287}
288
289Qgis::SettingsOrigin QgsSettings::origin( const QString &key ) const
290{
291 if ( mGlobalSettings && mGlobalSettings->contains( key ) )
293
294 if ( mUserSettings->contains( key ) )
296
298}
299
300void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
301{
302 // TODO: add valueChanged signal
303 // Do not store if it hasn't changed from default value
304 // First check if the values are different and if at least one of them is valid.
305 // The valid check is required because different invalid QVariant types
306 // like QVariant(QVariant::String) and QVariant(QVariant::Int))
307 // may be considered different and we don't want to store the value in that case.
308 const QVariant currentValue = QgsSettings::value( prefixedKey( key, section ) );
309 if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
310 {
311 mUserSettings->setValue( prefixedKey( key, section ), value );
312 }
313 // Deliberately an "else if" because we want to remove a value from the user settings
314 // only if the value is different than the one stored in the global settings (because
315 // it would be the default anyway). The first check is necessary because the global settings
316 // might be a nullptr (for example in case of standalone scripts or apps).
317 else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
318 {
319 mUserSettings->remove( prefixedKey( key, section ) );
320 }
321}
322
323// To lower case and clean the path
324QString QgsSettings::sanitizeKey( const QString &key ) const
325{
326 return QDir::cleanPath( key );
327}
328
330{
331 mUserSettings->clear();
332}
SettingsOrigin
The setting origin describes where a setting is stored.
Definition: qgis.h:2702
@ Global
Global settings are stored in global_settings.ini
@ Local
Local settings are stored in the user profile.
@ Any
From any origin.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
QStringList childGroups(Qgis::SettingsOrigin origin=Qgis::SettingsOrigin::Any) const
Returns a list of all key top-level groups that contain keys that can be read using the QSettings obj...
Qgis::SettingsOrigin origin(const QString &key) const
Returns the origin of the setting if it exists at the given key.
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
Definition: qgssettings.cpp:99
void clear()
Removes all entries in the user settings.
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.
QString prefixedKey(const QString &key, QgsSettings::Section section) const
Returns the sanitized and prefixed key.
void endArray()
Closes the array that was started using beginReadArray() or beginWriteArray().
QString group() const
Returns the current group.
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
Definition: qgssettings.cpp:89
~QgsSettings() override
Definition: qgssettings.cpp:82
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object.
static QString globalSettingsPath()
Returns the path to the Global Settings QSettings storage file.
QgsSettings(const QString &organization, const QString &application=QString(), QObject *parent=nullptr)
Constructs a QgsSettings object for accessing settings of the application called application from the...
Definition: qgssettings.cpp:50
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
QStringList globalChildGroups() const
Returns a list of all key top-level groups (same as childGroups) but only for groups defined in globa...
void beginWriteArray(const QString &prefix, int size=-1)
Adds prefix to the current group and starts writing an array of size size.
Section
Sections for namespaced settings.
Definition: qgssettings.h:69
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.
QString fileName() const
Returns the path where settings written using this QSettings object are stored.
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object.
int beginReadArray(const QString &prefix)
Adds prefix to the current group and starts reading from an array. Returns the size of the array.
void setArrayIndex(int i)
Sets the current array index to i.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
#define BUILTIN_UNREACHABLE
Definition: qgis.h:4180
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)