QGIS API Documentation 3.43.0-Master (c67cf405802)
qgssettings.h
Go to the documentation of this file.
1/***************************************************************************
2 qgssettings.h
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#ifndef QGSSETTINGS_H
18#define QGSSETTINGS_H
19
20#include <QSettings>
21#include <QMetaEnum>
22
23#include "qgis_core.h"
24#include "qgis_sip.h"
25#include "qgslogger.h"
26#include "qgssettingstreenode.h"
27
29
65class CORE_EXPORT QgsSettings : public QObject
66{
67 Q_OBJECT
68 public:
69
85
90 explicit QgsSettings( const QString &organization,
91 const QString &application = QString(), QObject *parent = nullptr );
92
107 QgsSettings( QSettings::Scope scope, const QString &organization,
108 const QString &application = QString(), QObject *parent = nullptr );
109
124 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
125 const QString &application = QString(), QObject *parent = nullptr );
126
147 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
148
158 explicit QgsSettings( QObject *parent = nullptr );
159 ~QgsSettings() override;
160
167 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
169 void endGroup();
170
177 QString group() const;
178
180 QStringList allKeys() const;
182 QStringList childKeys() const;
184 QStringList childGroups( Qgis::SettingsOrigin origin = Qgis::SettingsOrigin::Any ) const;
186 QStringList globalChildGroups() const;
188 static QString globalSettingsPath();
190 static bool setGlobalSettingsPath( const QString &path );
192 int beginReadArray( const QString &prefix );
193
199 void beginWriteArray( const QString &prefix, int size = -1 );
201 void endArray();
202
207 void setArrayIndex( int i );
208
214 Qgis::SettingsOrigin origin( const QString &key ) const;
215
220 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
221
228#ifndef SIP_RUN
229 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
230 Section section = NoSection ) const;
231#else
232 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
233 SIP_PYOBJECT type = 0,
234 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
235 % MethodCode
236 typedef PyObject *( *pyqt_from_qvariant_by_type )( QVariant &value, PyObject *type );
237 QVariant value;
238
239 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
240 Py_BEGIN_ALLOW_THREADS
241 value = sipCpp->value( *a0, *a1, a3 );
242 Py_END_ALLOW_THREADS
243
244 pyqt_from_qvariant_by_type f = ( pyqt_from_qvariant_by_type ) sipImportSymbol( SIP_PYQT_FROM_QVARIANT_BY_TYPE );
245 sipRes = f( value, a2 );
246
247 sipIsErr = !sipRes;
248 % End
249#endif
250
251
252#ifndef SIP_RUN
253
264 template <class T>
265 T enumValue( const QString &key, const T &defaultValue,
266 const Section section = NoSection )
267 {
268 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
269 Q_ASSERT( metaEnum.isValid() );
270 if ( !metaEnum.isValid() )
271 {
272 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
273 }
274
275 T v;
276 bool ok = false;
277
278 if ( metaEnum.isValid() )
279 {
280 // read as string
281 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
282 const char *vs = ba.data();
283 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
284 if ( ok )
285 return v;
286 }
287
288 // if failed, try to read as int (old behavior)
289 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
290 // then the method could be marked as const
291 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
292 if ( metaEnum.isValid() )
293 {
294 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
295 {
296 v = defaultValue;
297 }
298 else
299 {
300 // found setting as an integer
301 // convert the setting to the new form (string)
302 setEnumValue( key, v, section );
303 }
304 }
305
306 return v;
307 }
308
316 template <class T>
317 void setEnumValue( const QString &key, const T &value,
318 const Section section = NoSection )
319 {
320 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
321 Q_ASSERT( metaEnum.isValid() );
322 if ( metaEnum.isValid() )
323 {
324 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
325 }
326 else
327 {
328 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
329 }
330 }
331
342 template <class T>
343 T flagValue( const QString &key, const T &defaultValue,
344 const Section section = NoSection )
345 {
346 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
347 Q_ASSERT( metaEnum.isValid() );
348 if ( !metaEnum.isValid() )
349 {
350 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
351 }
352
353 T v = defaultValue;
354 bool ok = false;
355
356 if ( metaEnum.isValid() )
357 {
358 // read as string
359 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
360 const char *vs = ba.data();
361 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
362 }
363 if ( !ok )
364 {
365 // if failed, try to read as int
366 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
367 if ( metaEnum.isValid() )
368 {
369 if ( ok )
370 {
371 // check that the int value does correspond to a flag
372 // see https://stackoverflow.com/a/68495949/1548052
373 const QByteArray keys = metaEnum.valueToKeys( intValue );
374 const int intValueCheck = metaEnum.keysToValue( keys );
375 if ( intValue != intValueCheck )
376 {
377 v = defaultValue;
378 }
379 else
380 {
381 // found property as an integer
382 v = T( intValue );
383 // convert the property to the new form (string)
384 // this code could be removed
385 // then the method could be marked as const
386 setFlagValue( key, v );
387 }
388 }
389 else
390 {
391 v = defaultValue;
392 }
393 }
394 }
395
396 return v;
397 }
398
406 template <class T>
407 void setFlagValue( const QString &key, const T &value,
408 const Section section = NoSection )
409 {
410 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
411 Q_ASSERT( metaEnum.isValid() );
412 if ( metaEnum.isValid() )
413 {
414 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
415 }
416 else
417 {
418 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
419 }
420 }
421#endif
422
427 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
429 QString fileName() const;
430
437 void sync();
439 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
441 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
443 void clear();
444
463 static void holdFlush() SIP_SKIP;
464
479 static void releaseFlush() SIP_SKIP;
480
494 static QgsSettingsProxy get() SIP_SKIP;
495
496 private:
497 void init();
498 QString sanitizeKey( const QString &key ) const;
499 QSettings *mUserSettings = nullptr;
500 QSettings *mGlobalSettings = nullptr;
501 bool mUsingGlobalArray = false;
502 Q_DISABLE_COPY( QgsSettings )
503
504};
505
506// as static members cannot be CORE_EXPORTed
508
509#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4315
@ Any
From any origin.
A helper class for access to either a temporary QgsSettings object or the thread local object.
Stores settings for use within QGIS.
Definition qgssettings.h:66
T flagValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on a flag.
void setFlagValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on a flag.
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
Section
Sections for namespaced settings.
Definition qgssettings.h:72
@ Gps
GPS section, since QGIS 3.22.
Definition qgssettings.h:83
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
#define SIP_SKIP
Definition qgis_sip.h:126
#define QgsDebugError(str)
Definition qgslogger.h:40
thread_local QgsSettings * sQgsSettingsThreadSettings