QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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 "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 = new 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 = new 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 = new 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 = new QSettings( format, scope, organization, application, parent );
71 init();
72}
73
74QgsSettings::QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent )
75{
76 mUserSettings = new QSettings( fileName, format, parent );
77 init();
78}
79
80QgsSettings::QgsSettings( QObject *parent )
81{
82 mUserSettings = new QSettings( parent );
83 init();
84}
85
87{
88 delete mUserSettings;
89 delete mGlobalSettings;
90}
91
92
93void QgsSettings::beginGroup( const QString &prefix, const QgsSettings::Section section )
94{
95 const QString pKey = prefixedKey( prefix, section );
96 mUserSettings->beginGroup( pKey );
97 if ( mGlobalSettings )
98 {
99 mGlobalSettings->beginGroup( pKey );
100 }
101}
102
104{
105 mUserSettings->endGroup();
106 if ( mGlobalSettings )
107 {
108 mGlobalSettings->endGroup();
109 }
110}
111
112QString QgsSettings::group() const
113{
114 return mUserSettings->group();
115}
116
117QStringList QgsSettings::allKeys() const
118{
119 QStringList keys = mUserSettings->allKeys();
120 if ( mGlobalSettings )
121 {
122 const QStringList constAllKeys = mGlobalSettings->allKeys();
123 std::copy_if( constAllKeys.constBegin(), constAllKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
124 }
125 return keys;
126}
127
128
129QStringList QgsSettings::childKeys() const
130{
131 QStringList keys = mUserSettings->childKeys();
132 if ( mGlobalSettings )
133 {
134 const QStringList constChildKeys = mGlobalSettings->childKeys();
135 std::copy_if( constChildKeys.constBegin(), constChildKeys.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
136 }
137 return keys;
138}
139
141{
142 switch ( origin )
143 {
145 {
146 QStringList keys = mUserSettings->childGroups();
147 if ( mGlobalSettings )
148 {
149 const QStringList constChildGroups = mGlobalSettings->childGroups();
150 std::copy_if( constChildGroups.constBegin(), constChildGroups.constEnd(), std::back_inserter( keys ), [&keys]( const QString & key ) {return !keys.contains( key );} );
151 }
152 return keys;
153 }
154
156 return mUserSettings->childGroups();
157
159 return mGlobalSettings ? mGlobalSettings->childGroups() : QStringList();
160 }
161
163}
164
169
171{
172 return *sGlobalSettingsPath();
173}
174
175QVariant QgsSettings::value( const QString &key, const QVariant &defaultValue, const QgsSettings::Section section ) const
176{
177 const QString pKey = prefixedKey( key, section );
178 if ( !QgsVariantUtils::isNull( mUserSettings->value( pKey ) ) )
179 {
180 return mUserSettings->value( pKey );
181 }
182 if ( mGlobalSettings )
183 {
184 return mGlobalSettings->value( pKey, defaultValue );
185 }
186 return defaultValue;
187}
188
189bool QgsSettings::contains( const QString &key, const QgsSettings::Section section ) const
190{
191 const QString pKey = prefixedKey( key, section );
192 return mUserSettings->contains( pKey ) ||
193 ( mGlobalSettings && mGlobalSettings->contains( pKey ) );
194}
195
197{
198 return mUserSettings->fileName();
199}
200
202{
203 mUserSettings->sync();
204}
205
206void QgsSettings::remove( const QString &key, const QgsSettings::Section section )
207{
208 const QString pKey = prefixedKey( key, section );
209 mUserSettings->remove( pKey );
210}
211
212QString QgsSettings::prefixedKey( const QString &key, const Section section ) const
213{
214 QString prefix;
215 switch ( section )
216 {
217 case Section::Core:
218 prefix = QStringLiteral( "core" );
219 break;
220 case Section::Server:
221 prefix = QStringLiteral( "server" );
222 break;
223 case Section::Gui:
224 prefix = QStringLiteral( "gui" );
225 break;
226 case Section::Plugins:
227 prefix = QStringLiteral( "plugins" );
228 break;
229 case Section::Misc:
230 prefix = QStringLiteral( "misc" );
231 break;
232 case Section::Auth:
233 prefix = QStringLiteral( "auth" );
234 break;
235 case Section::App:
236 prefix = QStringLiteral( "app" );
237 break;
239 prefix = QStringLiteral( "providers" );
240 break;
242 prefix = QStringLiteral( "expressions" );
243 break;
244 case Section::Gps:
245 prefix = QStringLiteral( "gps" );
246 break;
248 return sanitizeKey( key );
249 }
250 return prefix + "/" + sanitizeKey( key );
251}
252
253
254int QgsSettings::beginReadArray( const QString &prefix )
255{
256 int size = mUserSettings->beginReadArray( sanitizeKey( prefix ) );
257 if ( 0 == size && mGlobalSettings )
258 {
259 size = mGlobalSettings->beginReadArray( sanitizeKey( prefix ) );
260 mUsingGlobalArray = ( size > 0 );
261 }
262 return size;
263}
264
265void QgsSettings::beginWriteArray( const QString &prefix, int size )
266{
267 mUsingGlobalArray = false;
268 mUserSettings->beginWriteArray( prefix, size );
269}
270
272{
273 mUserSettings->endArray();
274 if ( mGlobalSettings )
275 {
276 mGlobalSettings->endArray();
277 }
278 mUsingGlobalArray = false;
279}
280
282{
283 if ( mGlobalSettings && mUsingGlobalArray )
284 {
285 mGlobalSettings->setArrayIndex( i );
286 }
287 else
288 {
289 mUserSettings->setArrayIndex( i );
290 }
291}
292
293Qgis::SettingsOrigin QgsSettings::origin( const QString &key ) const
294{
295 if ( mGlobalSettings && mGlobalSettings->contains( key ) )
297
298 if ( mUserSettings->contains( key ) )
300
302}
303
304void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
305{
306 // TODO: add valueChanged signal
307 // Do not store if it hasn't changed from default value
308 // First check if the values are different and if at least one of them is valid.
309 // The valid check is required because different invalid QVariant types
310 // like QVariant(QVariant::String) and QVariant(QVariant::Int))
311 // may be considered different and we don't want to store the value in that case.
312 const QVariant currentValue = QgsSettings::value( prefixedKey( key, section ) );
313 if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
314 {
315 mUserSettings->setValue( prefixedKey( key, section ), value );
316 }
317 // Deliberately an "else if" because we want to remove a value from the user settings
318 // only if the value is different than the one stored in the global settings (because
319 // it would be the default anyway). The first check is necessary because the global settings
320 // might be a nullptr (for example in case of standalone scripts or apps).
321 else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
322 {
323 mUserSettings->remove( prefixedKey( key, section ) );
324 }
325}
326
327// To lower case and clean the path
328QString QgsSettings::sanitizeKey( const QString &key ) const
329{
330 return QDir::cleanPath( key );
331}
332
334{
335 mUserSettings->clear();
336}
337
338
340{
342 return;
343
345}
346
352
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4168
@ 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:6612
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
thread_local QgsSettings * sQgsSettingsThreadSettings
thread_local QgsSettings * sQgsSettingsThreadSettings