QGIS API Documentation 3.29.0-Master (19d7edcfed)
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
51{
52 // this must be defined in cpp code so we are sure only one instance is around
54 return sTreeRoot;
55}
56
58{
60 if ( te )
61 return te;
62 else
63 return sTreePlugins->createChildElement( pluginName );
64}
65
66void QgsSettings::unregisterPluginTreeElement( const QString &pluginName )
67{
68 //QgsDebugMsg( "unregister plugin tree element" );
69 QgsSettingsTreeNode *pluginTreeElement = sTreePlugins->childElement( pluginName );
70 delete pluginTreeElement;
71}
72
73QgsSettings::QgsSettings( const QString &organization, const QString &application, QObject *parent )
74{
75 mUserSettings = new QSettings( organization, application, parent );
76 init();
77}
78
79QgsSettings::QgsSettings( QSettings::Scope scope, const QString &organization,
80 const QString &application, QObject *parent )
81{
82 mUserSettings = new QSettings( scope, organization, application, parent );
83 init();
84}
85
86QgsSettings::QgsSettings( QSettings::Format format, QSettings::Scope scope,
87 const QString &organization, const QString &application, QObject *parent )
88{
89 mUserSettings = new QSettings( format, scope, organization, application, parent );
90 init();
91}
92
93QgsSettings::QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent )
94{
95 mUserSettings = new QSettings( fileName, format, parent );
96 init();
97}
98
99QgsSettings::QgsSettings( QObject *parent )
100{
101 mUserSettings = new QSettings( parent );
102 init();
103}
104
106{
107 delete mUserSettings;
108 delete mGlobalSettings;
109}
110
111
112void QgsSettings::beginGroup( const QString &prefix, const QgsSettings::Section section )
113{
114 const QString pKey = prefixedKey( prefix, section );
115 mUserSettings->beginGroup( pKey );
116 if ( mGlobalSettings )
117 {
118 mGlobalSettings->beginGroup( pKey );
119 }
120}
121
123{
124 mUserSettings->endGroup();
125 if ( mGlobalSettings )
126 {
127 mGlobalSettings->endGroup();
128 }
129}
130
131QString QgsSettings::group() const
132{
133 return mUserSettings->group();
134}
135
136QStringList QgsSettings::allKeys() const
137{
138 QStringList keys = mUserSettings->allKeys();
139 if ( mGlobalSettings )
140 {
141 const QStringList constAllKeys = mGlobalSettings->allKeys();
142 std::copy_if( constAllKeys.constBegin(), constAllKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
143 }
144 return keys;
145}
146
147
148QStringList QgsSettings::childKeys() const
149{
150 QStringList keys = mUserSettings->childKeys();
151 if ( mGlobalSettings )
152 {
153 const QStringList constChildKeys = mGlobalSettings->childKeys();
154 std::copy_if( constChildKeys.constBegin(), constChildKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
155 }
156 return keys;
157}
158
160{
161 switch ( origin )
162 {
164 {
165 QStringList keys = mUserSettings->childGroups();
166 if ( mGlobalSettings )
167 {
168 const QStringList constChildGroups = mGlobalSettings->childGroups();
169 std::copy_if( constChildGroups.constBegin(), constChildGroups.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
170 }
171 return keys;
172 }
173
175 return mUserSettings->childGroups();
176
178 return mGlobalSettings ? mGlobalSettings->childGroups() : QStringList();
179 }
180
182}
183
185{
187}
188
190{
191 return *sGlobalSettingsPath();
192}
193
194QVariant QgsSettings::value( const QString &key, const QVariant &defaultValue, const QgsSettings::Section section ) const
195{
196 const QString pKey = prefixedKey( key, section );
197 if ( !QgsVariantUtils::isNull( mUserSettings->value( pKey ) ) )
198 {
199 return mUserSettings->value( pKey );
200 }
201 if ( mGlobalSettings )
202 {
203 return mGlobalSettings->value( pKey, defaultValue );
204 }
205 return defaultValue;
206}
207
208bool QgsSettings::contains( const QString &key, const QgsSettings::Section section ) const
209{
210 const QString pKey = prefixedKey( key, section );
211 return mUserSettings->contains( pKey ) ||
212 ( mGlobalSettings && mGlobalSettings->contains( pKey ) );
213}
214
216{
217 return mUserSettings->fileName();
218}
219
221{
222 mUserSettings->sync();
223}
224
225void QgsSettings::remove( const QString &key, const QgsSettings::Section section )
226{
227 const QString pKey = prefixedKey( key, section );
228 mUserSettings->remove( pKey );
229}
230
231QString QgsSettings::prefixedKey( const QString &key, const Section section ) const
232{
233 QString prefix;
234 switch ( section )
235 {
236 case Section::Core:
237 prefix = QStringLiteral( "core" );
238 break;
239 case Section::Server:
240 prefix = QStringLiteral( "server" );
241 break;
242 case Section::Gui:
243 prefix = QStringLiteral( "gui" );
244 break;
245 case Section::Plugins:
246 prefix = QStringLiteral( "plugins" );
247 break;
248 case Section::Misc:
249 prefix = QStringLiteral( "misc" );
250 break;
251 case Section::Auth:
252 prefix = QStringLiteral( "auth" );
253 break;
254 case Section::App:
255 prefix = QStringLiteral( "app" );
256 break;
257 case Section::Providers:
258 prefix = QStringLiteral( "providers" );
259 break;
260 case Section::Expressions:
261 prefix = QStringLiteral( "expressions" );
262 break;
263 case Section::Gps:
264 prefix = QStringLiteral( "gps" );
265 break;
266 case Section::NoSection:
267 return sanitizeKey( key );
268 }
269 return prefix + "/" + sanitizeKey( key );
270}
271
272
273int QgsSettings::beginReadArray( const QString &prefix )
274{
275 int size = mUserSettings->beginReadArray( sanitizeKey( prefix ) );
276 if ( 0 == size && mGlobalSettings )
277 {
278 size = mGlobalSettings->beginReadArray( sanitizeKey( prefix ) );
279 mUsingGlobalArray = ( size > 0 );
280 }
281 return size;
282}
283
284void QgsSettings::beginWriteArray( const QString &prefix, int size )
285{
286 mUsingGlobalArray = false;
287 mUserSettings->beginWriteArray( prefix, size );
288}
289
291{
292 mUserSettings->endArray();
293 if ( mGlobalSettings )
294 {
295 mGlobalSettings->endArray();
296 }
297 mUsingGlobalArray = false;
298}
299
301{
302 if ( mGlobalSettings && mUsingGlobalArray )
303 {
304 mGlobalSettings->setArrayIndex( i );
305 }
306 else
307 {
308 mUserSettings->setArrayIndex( i );
309 }
310}
311
312Qgis::SettingsOrigin QgsSettings::origin( const QString &key ) const
313{
314 if ( mGlobalSettings && mGlobalSettings->contains( key ) )
316
317 if ( mUserSettings->contains( key ) )
319
321}
322
323void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
324{
325 // TODO: add valueChanged signal
326 // Do not store if it hasn't changed from default value
327 // First check if the values are different and if at least one of them is valid.
328 // The valid check is required because different invalid QVariant types
329 // like QVariant(QVariant::String) and QVariant(QVariant::Int))
330 // may be considered different and we don't want to store the value in that case.
331 const QVariant currentValue = QgsSettings::value( prefixedKey( key, section ) );
332 if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
333 {
334 mUserSettings->setValue( prefixedKey( key, section ), value );
335 }
336 // Deliberately an "else if" because we want to remove a value from the user settings
337 // only if the value is different than the one stored in the global settings (because
338 // it would be the default anyway). The first check is necessary because the global settings
339 // might be a nullptr (for example in case of standalone scripts or apps).
340 else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
341 {
342 mUserSettings->remove( prefixedKey( key, section ) );
343 }
344}
345
346// To lower case and clean the path
347QString QgsSettings::sanitizeKey( const QString &key ) const
348{
349 return QDir::cleanPath( key );
350}
351
353{
354 mUserSettings->clear();
355}
SettingsOrigin
The setting origin describes where a setting is stored.
Definition: qgis.h:2537
@ Global
Global settings are stored in global_settings.ini
@ Local
Local settings are stored in the user profile.
@ Any
From any origin.
QgsSettingsTreeNode is a tree element for the settings registry to help organizing and introspecting ...
QgsSettingsTreeNode * createChildElement(const QString &key) SIP_THROW(QgsSettingsException)
Creates a normal tree element It will return the existing child element if it exists at the given key...
static QgsSettingsTreeNode * createRootElement()
Creates a tree root element.
QgsSettingsTreeNode * childElement(const QString &key)
Returns the existing child element if it exists at the given key.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
static QgsSettingsTreeNode * treeRoot()
Returns the tree root element for the settings.
Definition: qgssettings.cpp:50
static QgsSettingsTreeNode * createPluginTreeElement(const QString &pluginName)
Creates a settings tree element for the given pluginName.
Definition: qgssettings.cpp:57
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.
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.
static QgsSettingsTreeNode * sTreePlugins
Definition: qgssettings.h:106
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.
~QgsSettings() override
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:73
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.
static void unregisterPluginTreeElement(const QString &pluginName)
Unregisters the tree element for the given plugin.
Definition: qgssettings.cpp:66
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:3748
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)