QGIS API Documentation 3.43.0-Master (ac9f54ad1f7)
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 "moc_qgssettings.cpp"
25#include "qgsvariantutils.h"
26#include "qgssettingsproxy.h"
27
28Q_GLOBAL_STATIC( QString, sGlobalSettingsPath )
29
31
32bool QgsSettings::setGlobalSettingsPath( const QString &path )
33{
34 if ( QFileInfo::exists( path ) )
35 {
36 *sGlobalSettingsPath() = path;
37 return true;
38 }
39 return false;
40}
41
42void QgsSettings::init()
43{
44 if ( ! sGlobalSettingsPath()->isEmpty() )
45 {
46 mGlobalSettings = std::make_unique<QSettings>( *sGlobalSettingsPath(), QSettings::IniFormat );
47#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
48 mGlobalSettings->setIniCodec( "UTF-8" );
49#endif
50 }
51}
52
53
54QgsSettings::QgsSettings( const QString &organization, const QString &application, QObject *parent )
55{
56 mUserSettings = std::make_unique<QSettings>( organization, application, parent );
57 init();
58}
59
60QgsSettings::QgsSettings( QSettings::Scope scope, const QString &organization,
61 const QString &application, QObject *parent )
62{
63 mUserSettings = std::make_unique<QSettings>( scope, organization, application, parent );
64 init();
65}
66
67QgsSettings::QgsSettings( QSettings::Format format, QSettings::Scope scope,
68 const QString &organization, const QString &application, QObject *parent )
69{
70 mUserSettings = std::make_unique<QSettings>( format, scope, organization, application, parent );
71 init();
72}
73
74QgsSettings::QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent )
75{
76 mUserSettings = std::make_unique<QSettings>( fileName, format, parent );
77 init();
78}
79
80QgsSettings::QgsSettings( QObject *parent )
81{
82 mUserSettings = std::make_unique<QSettings>( parent );
83 init();
84}
85
89
90
91void QgsSettings::beginGroup( const QString &prefix, const QgsSettings::Section section )
92{
93 const QString pKey = prefixedKey( prefix, section );
94 mUserSettings->beginGroup( pKey );
95 if ( mGlobalSettings )
96 {
97 mGlobalSettings->beginGroup( pKey );
98 }
99}
100
102{
103 mUserSettings->endGroup();
104 if ( mGlobalSettings )
105 {
106 mGlobalSettings->endGroup();
107 }
108}
109
110QString QgsSettings::group() const
111{
112 return mUserSettings->group();
113}
114
115QStringList QgsSettings::allKeys() const
116{
117 QStringList keys = mUserSettings->allKeys();
118 if ( mGlobalSettings )
119 {
120 const QStringList constAllKeys = mGlobalSettings->allKeys();
121 std::copy_if( constAllKeys.constBegin(), constAllKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
122 }
123 return keys;
124}
125
126
127QStringList QgsSettings::childKeys() const
128{
129 QStringList keys = mUserSettings->childKeys();
130 if ( mGlobalSettings )
131 {
132 const QStringList constChildKeys = mGlobalSettings->childKeys();
133 std::copy_if( constChildKeys.constBegin(), constChildKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
134 }
135 return keys;
136}
137
139{
140 switch ( origin )
141 {
143 {
144 QStringList keys = mUserSettings->childGroups();
145 if ( mGlobalSettings )
146 {
147 const QStringList constChildGroups = mGlobalSettings->childGroups();
148 std::copy_if( constChildGroups.constBegin(), constChildGroups.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
149 }
150 return keys;
151 }
152
154 return mUserSettings->childGroups();
155
157 return mGlobalSettings ? mGlobalSettings->childGroups() : QStringList();
158 }
159
161}
162
167
169{
170 return *sGlobalSettingsPath();
171}
172
173QVariant QgsSettings::value( const QString &key, const QVariant &defaultValue, const QgsSettings::Section section ) const
174{
175 const QString pKey = prefixedKey( key, section );
176 if ( !QgsVariantUtils::isNull( mUserSettings->value( pKey ) ) )
177 {
178 return mUserSettings->value( pKey );
179 }
180 if ( mGlobalSettings )
181 {
182 return mGlobalSettings->value( pKey, defaultValue );
183 }
184 return defaultValue;
185}
186
187bool QgsSettings::contains( const QString &key, const QgsSettings::Section section ) const
188{
189 const QString pKey = prefixedKey( key, section );
190 return mUserSettings->contains( pKey ) ||
191 ( mGlobalSettings && mGlobalSettings->contains( pKey ) );
192}
193
195{
196 return mUserSettings->fileName();
197}
198
200{
201 mUserSettings->sync();
202}
203
204void QgsSettings::remove( const QString &key, const QgsSettings::Section section )
205{
206 const QString pKey = prefixedKey( key, section );
207 mUserSettings->remove( pKey );
208}
209
210QString QgsSettings::prefixedKey( const QString &key, const Section section ) const
211{
212 QString prefix;
213 switch ( section )
214 {
215 case Section::Core:
216 prefix = QStringLiteral( "core" );
217 break;
218 case Section::Server:
219 prefix = QStringLiteral( "server" );
220 break;
221 case Section::Gui:
222 prefix = QStringLiteral( "gui" );
223 break;
224 case Section::Plugins:
225 prefix = QStringLiteral( "plugins" );
226 break;
227 case Section::Misc:
228 prefix = QStringLiteral( "misc" );
229 break;
230 case Section::Auth:
231 prefix = QStringLiteral( "auth" );
232 break;
233 case Section::App:
234 prefix = QStringLiteral( "app" );
235 break;
237 prefix = QStringLiteral( "providers" );
238 break;
240 prefix = QStringLiteral( "expressions" );
241 break;
242 case Section::Gps:
243 prefix = QStringLiteral( "gps" );
244 break;
246 return sanitizeKey( key );
247 }
248 return prefix + "/" + sanitizeKey( key );
249}
250
251
252int QgsSettings::beginReadArray( const QString &prefix )
253{
254 int size = mUserSettings->beginReadArray( sanitizeKey( prefix ) );
255 if ( 0 == size && mGlobalSettings )
256 {
257 size = mGlobalSettings->beginReadArray( sanitizeKey( prefix ) );
258 mUsingGlobalArray = ( size > 0 );
259 }
260 return size;
261}
262
263void QgsSettings::beginWriteArray( const QString &prefix, int size )
264{
265 mUsingGlobalArray = false;
266 mUserSettings->beginWriteArray( prefix, size );
267}
268
270{
271 mUserSettings->endArray();
272 if ( mGlobalSettings )
273 {
274 mGlobalSettings->endArray();
275 }
276 mUsingGlobalArray = false;
277}
278
280{
281 if ( mGlobalSettings && mUsingGlobalArray )
282 {
283 mGlobalSettings->setArrayIndex( i );
284 }
285 else
286 {
287 mUserSettings->setArrayIndex( i );
288 }
289}
290
291Qgis::SettingsOrigin QgsSettings::origin( const QString &key ) const
292{
293 if ( mGlobalSettings && mGlobalSettings->contains( key ) )
295
296 if ( mUserSettings->contains( key ) )
298
300}
301
302void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
303{
304 // TODO: add valueChanged signal
305 // Do not store if it hasn't changed from default value
306 // First check if the values are different and if at least one of them is valid.
307 // The valid check is required because different invalid QVariant types
308 // like QVariant(QVariant::String) and QVariant(QVariant::Int))
309 // may be considered different and we don't want to store the value in that case.
310 const QVariant currentValue = QgsSettings::value( prefixedKey( key, section ) );
311 if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
312 {
313 mUserSettings->setValue( prefixedKey( key, section ), value );
314 }
315 // Deliberately an "else if" because we want to remove a value from the user settings
316 // only if the value is different than the one stored in the global settings (because
317 // it would be the default anyway). The first check is necessary because the global settings
318 // might be a nullptr (for example in case of standalone scripts or apps).
319 else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
320 {
321 mUserSettings->remove( prefixedKey( key, section ) );
322 }
323}
324
325// To lower case and clean the path
326QString QgsSettings::sanitizeKey( const QString &key ) const
327{
328 return QDir::cleanPath( key );
329}
330
332{
333 mUserSettings->clear();
334}
335
336
338{
340 return;
341
343}
344
350
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4330
@ 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.
Stores settings for use within QGIS.
Definition qgssettings.h:65
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:71
@ Gps
GPS section, since QGIS 3.22.
Definition qgssettings.h:82
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:6932
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
thread_local QgsSettings * sQgsSettingsThreadSettings
thread_local QgsSettings * sQgsSettingsThreadSettings