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