QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
61class CORE_EXPORT QgsSettings : public QObject
62{
63 Q_OBJECT
64 public:
65
68 {
80 };
81
88 {
89 public:
90 static const inline char *APP_GEOREFERENCER = "app/georeferencer";
91 static const inline char *CORE = "core";
92 static const inline char *CORE_LAYOUT = "core/Layout";
93 static const inline char *GEOMETRYVALIDATION = "geometry_validation";
94 static const inline char *GPS = "gps";
95 static const inline char *GUI_LOCATORFILTERS = "gui/locator_filters";
96 static const inline char *GUI_QGIS = "gui/qgis";
97 static const inline char *LOCALE = "locale";
98 static const inline char *MAP = "Map";
99 static const inline char *PLUGINS = "plugins";
100 static const inline char *PROCESSING_CONFIGURATION = "Processing/Configuration";
101 static const inline char *QGIS = "qgis";
102 static const inline char *QGIS_DIGITIZING = "qgis/digitizing";
103 static const inline char *QGIS_DIGITIZING_SHAPEMAPTOOLS = "qgis/digitizing/shape-map-tools";
104 static const inline char *QGIS_NETWORKANDPROXY = "qgis/networkAndProxy";
105 static const inline char *SVG = "svg";
106 static const inline char *ELEVATION_PROFILE = "elevation-profile";
107 static const inline char *CORE_LAYERTREE = "core/layer-tree";
108 static const inline char *STYLE_MANAGER = "app/style-manager";
109 static const inline char *FONTS = "fonts";
110 static const inline char *WMS = "wms";
111 };
112
117 explicit QgsSettings( const QString &organization,
118 const QString &application = QString(), QObject *parent = nullptr );
119
134 QgsSettings( QSettings::Scope scope, const QString &organization,
135 const QString &application = QString(), QObject *parent = nullptr );
136
151 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
152 const QString &application = QString(), QObject *parent = nullptr );
153
174 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
175
185 explicit QgsSettings( QObject *parent = nullptr );
186 ~QgsSettings() override;
187
194 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
196 void endGroup();
197
204 QString group() const;
205
207 QStringList allKeys() const;
209 QStringList childKeys() const;
211 QStringList childGroups() const;
213 QStringList globalChildGroups() const;
215 static QString globalSettingsPath();
217 static bool setGlobalSettingsPath( const QString &path );
219 int beginReadArray( const QString &prefix );
220
226 void beginWriteArray( const QString &prefix, int size = -1 );
228 void endArray();
229
234 void setArrayIndex( int i );
235
240 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
241
248#ifndef SIP_RUN
249 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
250 Section section = NoSection ) const;
251#else
252 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
253 SIP_PYOBJECT type = 0,
254 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
255 % MethodCode
256 typedef PyObject *( *pyqt5_from_qvariant_by_type )( QVariant &value, PyObject *type );
257 QVariant value;
258
259 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
260 Py_BEGIN_ALLOW_THREADS
261 value = sipCpp->value( *a0, *a1, a3 );
262 Py_END_ALLOW_THREADS
263
264 pyqt5_from_qvariant_by_type f = ( pyqt5_from_qvariant_by_type ) sipImportSymbol( "pyqt5_from_qvariant_by_type" );
265 sipRes = f( value, a2 );
266
267 sipIsErr = !sipRes;
268 % End
269#endif
270
271#ifndef SIP_RUN
272
283 template <class T>
284 T enumValue( const QString &key, const T &defaultValue,
285 const Section section = NoSection )
286 {
287 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
288 Q_ASSERT( metaEnum.isValid() );
289 if ( !metaEnum.isValid() )
290 {
291 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
292 }
293
294 T v;
295 bool ok = false;
296
297 if ( metaEnum.isValid() )
298 {
299 // read as string
300 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
301 const char *vs = ba.data();
302 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
303 if ( ok )
304 return v;
305 }
306
307 // if failed, try to read as int (old behavior)
308 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
309 // then the method could be marked as const
310 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
311 if ( metaEnum.isValid() )
312 {
313 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
314 {
315 v = defaultValue;
316 }
317 else
318 {
319 // found setting as an integer
320 // convert the setting to the new form (string)
321 setEnumValue( key, v, section );
322 }
323 }
324
325 return v;
326 }
327
335 template <class T>
336 void setEnumValue( const QString &key, const T &value,
337 const Section section = NoSection )
338 {
339 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
340 Q_ASSERT( metaEnum.isValid() );
341 if ( metaEnum.isValid() )
342 {
343 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
344 }
345 else
346 {
347 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
348 }
349 }
350
361 template <class T>
362 T flagValue( const QString &key, const T &defaultValue,
363 const Section section = NoSection )
364 {
365 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
366 Q_ASSERT( metaEnum.isValid() );
367 if ( !metaEnum.isValid() )
368 {
369 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
370 }
371
372 T v = defaultValue;
373 bool ok = false;
374
375 if ( metaEnum.isValid() )
376 {
377 // read as string
378 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
379 const char *vs = ba.data();
380 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
381 }
382 if ( !ok )
383 {
384 // if failed, try to read as int
385 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
386 if ( metaEnum.isValid() )
387 {
388 if ( ok )
389 {
390 // check that the int value does correspond to a flag
391 // see https://stackoverflow.com/a/68495949/1548052
392 const QByteArray keys = metaEnum.valueToKeys( intValue );
393 const int intValueCheck = metaEnum.keysToValue( keys );
394 if ( intValue != intValueCheck )
395 {
396 v = defaultValue;
397 }
398 else
399 {
400 // found property as an integer
401 v = T( intValue );
402 // convert the property to the new form (string)
403 // this code could be removed
404 // then the method could be marked as const
405 setFlagValue( key, v );
406 }
407 }
408 else
409 {
410 v = defaultValue;
411 }
412 }
413 }
414
415 return v;
416 }
417
425 template <class T>
426 void setFlagValue( const QString &key, const T &value,
427 const Section section = NoSection )
428 {
429 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
430 Q_ASSERT( metaEnum.isValid() );
431 if ( metaEnum.isValid() )
432 {
433 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
434 }
435 else
436 {
437 QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
438 }
439 }
440#endif
441
446 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
448 QString fileName() const;
449
456 void sync();
458 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
460 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
462 void clear();
463
464 private:
465 void init();
466 QString sanitizeKey( const QString &key ) const;
467 QSettings *mUserSettings = nullptr;
468 QSettings *mGlobalSettings = nullptr;
469 bool mUsingGlobalArray = false;
470 Q_DISABLE_COPY( QgsSettings )
471
472};
473
474#endif // QGSSETTINGS_H
Prefixes for the settings keys.
Definition: qgssettings.h:88
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
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:362
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:426
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:336
Section
Sections for namespaced settings.
Definition: qgssettings.h:68
@ Gps
GPS section, since QGIS 3.22.
Definition: qgssettings.h:79
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:284
As part of the API refactoring and improvements which landed in QGIS
#define SIP_SKIP
Definition: qgis_sip.h:126
#define QgsDebugMsg(str)
Definition: qgslogger.h:38