QGIS API Documentation 3.29.0-Master (19d7edcfed)
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
62class CORE_EXPORT QgsSettings : public QObject
63{
64 Q_OBJECT
65 public:
66
69 {
81 };
82
83#ifndef SIP_RUN
84
89 static QgsSettingsTreeNode *treeRoot();
90
91 // only create first level here
92 static inline QgsSettingsTreeNode *sTreeApp = treeRoot()->createChildElement( QStringLiteral( "app" ) );
93 static inline QgsSettingsTreeNode *sTreeConnections = treeRoot()->createChildElement( QStringLiteral( "connections" ) );
94 static inline QgsSettingsTreeNode *sTreeCore = treeRoot()->createChildElement( QStringLiteral( "core" ) );
95 static inline QgsSettingsTreeNode *sTreeElevationProfile = treeRoot()->createChildElement( QStringLiteral( "elevation-profile" ) );
96 static inline QgsSettingsTreeNode *sTreeFonts = treeRoot()->createChildElement( QStringLiteral( "fonts" ) );
97 static inline QgsSettingsTreeNode *sTreeGeometryValidation = treeRoot()->createChildElement( QStringLiteral( "geometry_validation" ) );
98 static inline QgsSettingsTreeNode *sTreeGps = treeRoot()->createChildElement( QStringLiteral( "gps" ) );
99 static inline QgsSettingsTreeNode *sTreeGui = treeRoot()->createChildElement( QStringLiteral( "gui" ) );
100 static inline QgsSettingsTreeNode *sTreeLayerTree = treeRoot()->createChildElement( QStringLiteral( "layer-tree" ) );
101 static inline QgsSettingsTreeNode *sTreeLayout = treeRoot()->createChildElement( QStringLiteral( "layout" ) );
102 static inline QgsSettingsTreeNode *sTreeLocale = treeRoot()->createChildElement( QStringLiteral( "locale" ) );
103 static inline QgsSettingsTreeNode *sTreeMap = treeRoot()->createChildElement( QStringLiteral( "map" ) );
104 static inline QgsSettingsTreeNode *sTreeNetwork = treeRoot()->createChildElement( QStringLiteral( "network" ) );
105 static inline QgsSettingsTreeNode *sTreeQgis = treeRoot()->createChildElement( QStringLiteral( "qgis" ) );
106 static inline QgsSettingsTreeNode *sTreePlugins = treeRoot()->createChildElement( QStringLiteral( "plugins" ) );
107 static inline QgsSettingsTreeNode *sTreeProcessing = treeRoot()->createChildElement( QStringLiteral( "processing" ) );
108 static inline QgsSettingsTreeNode *sTreeSvg = treeRoot()->createChildElement( QStringLiteral( "svg" ) );
109 static inline QgsSettingsTreeNode *sTreeWms = treeRoot()->createChildElement( QStringLiteral( "wms" ) );
110
111 // sub levels
112 static inline QgsSettingsTreeNode *sTreeDigitizing = sTreeQgis->createChildElement( QStringLiteral( "digitizing" ) );
113
114#endif
115
120 static QgsSettingsTreeNode *createPluginTreeElement( const QString &pluginName );
121
122
127 static void unregisterPluginTreeElement( const QString &pluginName );
128
133 explicit QgsSettings( const QString &organization,
134 const QString &application = QString(), QObject *parent = nullptr );
135
150 QgsSettings( QSettings::Scope scope, const QString &organization,
151 const QString &application = QString(), QObject *parent = nullptr );
152
167 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
168 const QString &application = QString(), QObject *parent = nullptr );
169
190 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
191
201 explicit QgsSettings( QObject *parent = nullptr );
202 ~QgsSettings() override;
203
210 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
212 void endGroup();
213
220 QString group() const;
221
223 QStringList allKeys() const;
225 QStringList childKeys() const;
227 QStringList childGroups( Qgis::SettingsOrigin origin = Qgis::SettingsOrigin::Any ) const;
229 QStringList globalChildGroups() const;
231 static QString globalSettingsPath();
233 static bool setGlobalSettingsPath( const QString &path );
235 int beginReadArray( const QString &prefix );
236
242 void beginWriteArray( const QString &prefix, int size = -1 );
244 void endArray();
245
250 void setArrayIndex( int i );
251
257 Qgis::SettingsOrigin origin( const QString &key ) const;
258
263 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
264
271#ifndef SIP_RUN
272 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
273 Section section = NoSection ) const;
274#else
275 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
276 SIP_PYOBJECT type = 0,
277 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
278 % MethodCode
279 typedef PyObject *( *pyqt5_from_qvariant_by_type )( QVariant &value, PyObject *type );
280 QVariant value;
281
282 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
283 Py_BEGIN_ALLOW_THREADS
284 value = sipCpp->value( *a0, *a1, a3 );
285 Py_END_ALLOW_THREADS
286
287 pyqt5_from_qvariant_by_type f = ( pyqt5_from_qvariant_by_type ) sipImportSymbol( "pyqt5_from_qvariant_by_type" );
288 sipRes = f( value, a2 );
289
290 sipIsErr = !sipRes;
291 % End
292#endif
293
294
295#ifndef SIP_RUN
296
307 template <class T>
308 T enumValue( const QString &key, const T &defaultValue,
309 const Section section = NoSection )
310 {
311 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
312 Q_ASSERT( metaEnum.isValid() );
313 if ( !metaEnum.isValid() )
314 {
315 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
316 }
317
318 T v;
319 bool ok = false;
320
321 if ( metaEnum.isValid() )
322 {
323 // read as string
324 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
325 const char *vs = ba.data();
326 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
327 if ( ok )
328 return v;
329 }
330
331 // if failed, try to read as int (old behavior)
332 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
333 // then the method could be marked as const
334 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
335 if ( metaEnum.isValid() )
336 {
337 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
338 {
339 v = defaultValue;
340 }
341 else
342 {
343 // found setting as an integer
344 // convert the setting to the new form (string)
345 setEnumValue( key, v, section );
346 }
347 }
348
349 return v;
350 }
351
359 template <class T>
360 void setEnumValue( const QString &key, const T &value,
361 const Section section = NoSection )
362 {
363 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
364 Q_ASSERT( metaEnum.isValid() );
365 if ( metaEnum.isValid() )
366 {
367 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
368 }
369 else
370 {
371 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
372 }
373 }
374
385 template <class T>
386 T flagValue( const QString &key, const T &defaultValue,
387 const Section section = NoSection )
388 {
389 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
390 Q_ASSERT( metaEnum.isValid() );
391 if ( !metaEnum.isValid() )
392 {
393 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
394 }
395
396 T v = defaultValue;
397 bool ok = false;
398
399 if ( metaEnum.isValid() )
400 {
401 // read as string
402 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
403 const char *vs = ba.data();
404 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
405 }
406 if ( !ok )
407 {
408 // if failed, try to read as int
409 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
410 if ( metaEnum.isValid() )
411 {
412 if ( ok )
413 {
414 // check that the int value does correspond to a flag
415 // see https://stackoverflow.com/a/68495949/1548052
416 const QByteArray keys = metaEnum.valueToKeys( intValue );
417 const int intValueCheck = metaEnum.keysToValue( keys );
418 if ( intValue != intValueCheck )
419 {
420 v = defaultValue;
421 }
422 else
423 {
424 // found property as an integer
425 v = T( intValue );
426 // convert the property to the new form (string)
427 // this code could be removed
428 // then the method could be marked as const
429 setFlagValue( key, v );
430 }
431 }
432 else
433 {
434 v = defaultValue;
435 }
436 }
437 }
438
439 return v;
440 }
441
449 template <class T>
450 void setFlagValue( const QString &key, const T &value,
451 const Section section = NoSection )
452 {
453 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
454 Q_ASSERT( metaEnum.isValid() );
455 if ( metaEnum.isValid() )
456 {
457 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
458 }
459 else
460 {
461 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
462 }
463 }
464#endif
465
470 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
472 QString fileName() const;
473
480 void sync();
482 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
484 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
486 void clear();
487
488 private:
489 void init();
490 QString sanitizeKey( const QString &key ) const;
491 QSettings *mUserSettings = nullptr;
492 QSettings *mGlobalSettings = nullptr;
493 bool mUsingGlobalArray = false;
494 Q_DISABLE_COPY( QgsSettings )
495
496};
497
498#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition: qgis.h:2537
@ Any
From any origin.
QgsSettingsTreeNode is a tree element for the settings registry to help organizing and introspecting ...
QgsSettingsTreeNode * createChildElement(const QString &key) SIP_THROW(QgsSettingsException)
Creates a normal tree element It will return the existing child element if it exists at the given key...
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
T flagValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on a flag.
Definition: qgssettings.h:386
void setFlagValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on a flag.
Definition: qgssettings.h:450
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
Definition: qgssettings.h:360
Section
Sections for namespaced settings.
Definition: qgssettings.h:69
@ Gps
GPS section, since QGIS 3.22.
Definition: qgssettings.h:80
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
Definition: qgssettings.h:308
#define QgsDebugMsg(str)
Definition: qgslogger.h:38