QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
Loading...
Searching...
No Matches
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#include "qgssettingsproxy.h"
26
27Q_GLOBAL_STATIC( QString, sGlobalSettingsPath )
28
30
31bool QgsSettings::setGlobalSettingsPath( const QString &path )
32{
33 if ( QFileInfo::exists( path ) )
34 {
35 *sGlobalSettingsPath() = path;
36 return true;
37 }
38 return false;
39}
40
41void QgsSettings::init()
42{
43 if ( ! sGlobalSettingsPath()->isEmpty() )
44 {
45 mGlobalSettings = new QSettings( *sGlobalSettingsPath(), QSettings::IniFormat );
46#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
47 mGlobalSettings->setIniCodec( "UTF-8" );
48#endif
49 }
50}
51
52
53QgsSettings::QgsSettings( const QString &organization, const QString &application, QObject *parent )
54{
55 mUserSettings = new QSettings( organization, application, parent );
56 init();
57}
58
59QgsSettings::QgsSettings( QSettings::Scope scope, const QString &organization,
60 const QString &application, QObject *parent )
61{
62 mUserSettings = new QSettings( scope, organization, application, parent );
63 init();
64}
65
66QgsSettings::QgsSettings( QSettings::Format format, QSettings::Scope scope,
67 const QString &organization, const QString &application, QObject *parent )
68{
69 mUserSettings = new QSettings( format, scope, organization, application, parent );
70 init();
71}
72
73QgsSettings::QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent )
74{
75 mUserSettings = new QSettings( fileName, format, parent );
76 init();
77}
78
79QgsSettings::QgsSettings( QObject *parent )
80{
81 mUserSettings = new QSettings( parent );
82 init();
83}
84
86{
87 delete mUserSettings;
88 delete mGlobalSettings;
89}
90
91
92void QgsSettings::beginGroup( const QString &prefix, const QgsSettings::Section section )
93{
94 const QString pKey = prefixedKey( prefix, section );
95 mUserSettings->beginGroup( pKey );
96 if ( mGlobalSettings )
97 {
98 mGlobalSettings->beginGroup( pKey );
99 }
100}
101
103{
104 mUserSettings->endGroup();
105 if ( mGlobalSettings )
106 {
107 mGlobalSettings->endGroup();
108 }
109}
110
111QString QgsSettings::group() const
112{
113 return mUserSettings->group();
114}
115
116QStringList QgsSettings::allKeys() const
117{
118 QStringList keys = mUserSettings->allKeys();
119 if ( mGlobalSettings )
120 {
121 const QStringList constAllKeys = mGlobalSettings->allKeys();
122 std::copy_if( constAllKeys.constBegin(), constAllKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
123 }
124 return keys;
125}
126
127
128QStringList QgsSettings::childKeys() const
129{
130 QStringList keys = mUserSettings->childKeys();
131 if ( mGlobalSettings )
132 {
133 const QStringList constChildKeys = mGlobalSettings->childKeys();
134 std::copy_if( constChildKeys.constBegin(), constChildKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
135 }
136 return keys;
137}
138
140{
141 switch ( origin )
142 {
144 {
145 QStringList keys = mUserSettings->childGroups();
146 if ( mGlobalSettings )
147 {
148 const QStringList constChildGroups = mGlobalSettings->childGroups();
149 std::copy_if( constChildGroups.constBegin(), constChildGroups.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
150 }
151 return keys;
152 }
153
155 return mUserSettings->childGroups();
156
158 return mGlobalSettings ? mGlobalSettings->childGroups() : QStringList();
159 }
160
162}
163
168
170{
171 return *sGlobalSettingsPath();
172}
173
174QVariant QgsSettings::value( const QString &key, const QVariant &defaultValue, const QgsSettings::Section section ) const
175{
176 const QString pKey = prefixedKey( key, section );
177 if ( !QgsVariantUtils::isNull( mUserSettings->value( pKey ) ) )
178 {
179 return mUserSettings->value( pKey );
180 }
181 if ( mGlobalSettings )
182 {
183 return mGlobalSettings->value( pKey, defaultValue );
184 }
185 return defaultValue;
186}
187
188bool QgsSettings::contains( const QString &key, const QgsSettings::Section section ) const
189{
190 const QString pKey = prefixedKey( key, section );
191 return mUserSettings->contains( pKey ) ||
192 ( mGlobalSettings && mGlobalSettings->contains( pKey ) );
193}
194
196{
197 return mUserSettings->fileName();
198}
199
201{
202 mUserSettings->sync();
203}
204
205void QgsSettings::remove( const QString &key, const QgsSettings::Section section )
206{
207 const QString pKey = prefixedKey( key, section );
208 mUserSettings->remove( pKey );
209}
210
211QString QgsSettings::prefixedKey( const QString &key, const Section section ) const
212{
213 QString prefix;
214 switch ( section )
215 {
216 case Section::Core:
217 prefix = QStringLiteral( "core" );
218 break;
219 case Section::Server:
220 prefix = QStringLiteral( "server" );
221 break;
222 case Section::Gui:
223 prefix = QStringLiteral( "gui" );
224 break;
225 case Section::Plugins:
226 prefix = QStringLiteral( "plugins" );
227 break;
228 case Section::Misc:
229 prefix = QStringLiteral( "misc" );
230 break;
231 case Section::Auth:
232 prefix = QStringLiteral( "auth" );
233 break;
234 case Section::App:
235 prefix = QStringLiteral( "app" );
236 break;
238 prefix = QStringLiteral( "providers" );
239 break;
241 prefix = QStringLiteral( "expressions" );
242 break;
243 case Section::Gps:
244 prefix = QStringLiteral( "gps" );
245 break;
247 return sanitizeKey( key );
248 }
249 return prefix + "/" + sanitizeKey( key );
250}
251
252
253int QgsSettings::beginReadArray( const QString &prefix )
254{
255 int size = mUserSettings->beginReadArray( sanitizeKey( prefix ) );
256 if ( 0 == size && mGlobalSettings )
257 {
258 size = mGlobalSettings->beginReadArray( sanitizeKey( prefix ) );
259 mUsingGlobalArray = ( size > 0 );
260 }
261 return size;
262}
263
264void QgsSettings::beginWriteArray( const QString &prefix, int size )
265{
266 mUsingGlobalArray = false;
267 mUserSettings->beginWriteArray( prefix, size );
268}
269
271{
272 mUserSettings->endArray();
273 if ( mGlobalSettings )
274 {
275 mGlobalSettings->endArray();
276 }
277 mUsingGlobalArray = false;
278}
279
281{
282 if ( mGlobalSettings && mUsingGlobalArray )
283 {
284 mGlobalSettings->setArrayIndex( i );
285 }
286 else
287 {
288 mUserSettings->setArrayIndex( i );
289 }
290}
291
292Qgis::SettingsOrigin QgsSettings::origin( const QString &key ) const
293{
294 if ( mGlobalSettings && mGlobalSettings->contains( key ) )
296
297 if ( mUserSettings->contains( key ) )
299
301}
302
303void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
304{
305 // TODO: add valueChanged signal
306 // Do not store if it hasn't changed from default value
307 // First check if the values are different and if at least one of them is valid.
308 // The valid check is required because different invalid QVariant types
309 // like QVariant(QVariant::String) and QVariant(QVariant::Int))
310 // may be considered different and we don't want to store the value in that case.
311 const QVariant currentValue = QgsSettings::value( prefixedKey( key, section ) );
312 if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
313 {
314 mUserSettings->setValue( prefixedKey( key, section ), value );
315 }
316 // Deliberately an "else if" because we want to remove a value from the user settings
317 // only if the value is different than the one stored in the global settings (because
318 // it would be the default anyway). The first check is necessary because the global settings
319 // might be a nullptr (for example in case of standalone scripts or apps).
320 else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
321 {
322 mUserSettings->remove( prefixedKey( key, section ) );
323 }
324}
325
326// To lower case and clean the path
327QString QgsSettings::sanitizeKey( const QString &key ) const
328{
329 return QDir::cleanPath( key );
330}
331
333{
334 mUserSettings->clear();
335}
336
337
339{
341 return;
342
344}
345
351
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:3643
@ Global
Global settings are stored in qgis_global_settings.ini
@ Local
Local settings are stored in the user profile.
@ Any
From any origin.
A helper class for access to either a temporary QgsSettings object or the thread local object.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
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.
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...
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...
static void releaseFlush()
Releases a previously made hold on flushing QgsSettings objects and writing new values to the underly...
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:70
@ Gps
GPS section, since QGIS 3.22.
Definition qgssettings.h:81
static void holdFlush()
Temporarily places a hold on flushing QgsSettings objects and writing new values to the underlying in...
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.
static QgsSettingsProxy get()
Returns a proxy for a QgsSettings object.
void setArrayIndex(int i)
Sets the current array index to i.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define BUILTIN_UNREACHABLE
Definition qgis.h:5790
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
thread_local QgsSettings * sQgsSettingsThreadSettings
thread_local QgsSettings * sQgsSettingsThreadSettings