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