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