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