QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
63class CORE_EXPORT QgsSettings : public QObject
64{
65 Q_OBJECT
66 public:
67
70 {
82 };
83
88 explicit QgsSettings( const QString &organization,
89 const QString &application = QString(), QObject *parent = nullptr );
90
105 QgsSettings( QSettings::Scope scope, const QString &organization,
106 const QString &application = QString(), QObject *parent = nullptr );
107
122 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
123 const QString &application = QString(), QObject *parent = nullptr );
124
145 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
146
156 explicit QgsSettings( QObject *parent = nullptr );
157 ~QgsSettings() override;
158
165 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
167 void endGroup();
168
175 QString group() const;
176
178 QStringList allKeys() const;
180 QStringList childKeys() const;
182 QStringList childGroups( Qgis::SettingsOrigin origin = Qgis::SettingsOrigin::Any ) const;
184 QStringList globalChildGroups() const;
186 static QString globalSettingsPath();
188 static bool setGlobalSettingsPath( const QString &path );
190 int beginReadArray( const QString &prefix );
191
197 void beginWriteArray( const QString &prefix, int size = -1 );
199 void endArray();
200
205 void setArrayIndex( int i );
206
212 Qgis::SettingsOrigin origin( const QString &key ) const;
213
218 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
219
226#ifndef SIP_RUN
227 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
228 Section section = NoSection ) const;
229#else
230 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
231 SIP_PYOBJECT type = 0,
232 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
233 % MethodCode
234 typedef PyObject *( *pyqt_from_qvariant_by_type )( QVariant &value, PyObject *type );
235 QVariant value;
236
237 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
238 Py_BEGIN_ALLOW_THREADS
239 value = sipCpp->value( *a0, *a1, a3 );
240 Py_END_ALLOW_THREADS
241
242 pyqt_from_qvariant_by_type f = ( pyqt_from_qvariant_by_type ) sipImportSymbol( SIP_PYQT_FROM_QVARIANT_BY_TYPE );
243 sipRes = f( value, a2 );
244
245 sipIsErr = !sipRes;
246 % End
247#endif
248
249
250#ifndef SIP_RUN
251
262 template <class T>
263 T enumValue( const QString &key, const T &defaultValue,
264 const Section section = NoSection )
265 {
266 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
267 Q_ASSERT( metaEnum.isValid() );
268 if ( !metaEnum.isValid() )
269 {
270 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
271 }
272
273 T v;
274 bool ok = false;
275
276 if ( metaEnum.isValid() )
277 {
278 // read as string
279 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
280 const char *vs = ba.data();
281 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
282 if ( ok )
283 return v;
284 }
285
286 // if failed, try to read as int (old behavior)
287 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
288 // then the method could be marked as const
289 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
290 if ( metaEnum.isValid() )
291 {
292 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
293 {
294 v = defaultValue;
295 }
296 else
297 {
298 // found setting as an integer
299 // convert the setting to the new form (string)
300 setEnumValue( key, v, section );
301 }
302 }
303
304 return v;
305 }
306
314 template <class T>
315 void setEnumValue( const QString &key, const T &value,
316 const Section section = NoSection )
317 {
318 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
319 Q_ASSERT( metaEnum.isValid() );
320 if ( metaEnum.isValid() )
321 {
322 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
323 }
324 else
325 {
326 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
327 }
328 }
329
340 template <class T>
341 T flagValue( const QString &key, const T &defaultValue,
342 const Section section = NoSection )
343 {
344 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
345 Q_ASSERT( metaEnum.isValid() );
346 if ( !metaEnum.isValid() )
347 {
348 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
349 }
350
351 T v = defaultValue;
352 bool ok = false;
353
354 if ( metaEnum.isValid() )
355 {
356 // read as string
357 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
358 const char *vs = ba.data();
359 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
360 }
361 if ( !ok )
362 {
363 // if failed, try to read as int
364 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
365 if ( metaEnum.isValid() )
366 {
367 if ( ok )
368 {
369 // check that the int value does correspond to a flag
370 // see https://stackoverflow.com/a/68495949/1548052
371 const QByteArray keys = metaEnum.valueToKeys( intValue );
372 const int intValueCheck = metaEnum.keysToValue( keys );
373 if ( intValue != intValueCheck )
374 {
375 v = defaultValue;
376 }
377 else
378 {
379 // found property as an integer
380 v = T( intValue );
381 // convert the property to the new form (string)
382 // this code could be removed
383 // then the method could be marked as const
384 setFlagValue( key, v );
385 }
386 }
387 else
388 {
389 v = defaultValue;
390 }
391 }
392 }
393
394 return v;
395 }
396
404 template <class T>
405 void setFlagValue( const QString &key, const T &value,
406 const Section section = NoSection )
407 {
408 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
409 Q_ASSERT( metaEnum.isValid() );
410 if ( metaEnum.isValid() )
411 {
412 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
413 }
414 else
415 {
416 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
417 }
418 }
419#endif
420
425 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
427 QString fileName() const;
428
435 void sync();
437 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
439 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
441 void clear();
442
461 static void holdFlush() SIP_SKIP;
462
477 static void releaseFlush() SIP_SKIP;
478
492 static QgsSettingsProxy get() SIP_SKIP;
493
494 private:
495 void init();
496 QString sanitizeKey( const QString &key ) const;
497 QSettings *mUserSettings = nullptr;
498 QSettings *mGlobalSettings = nullptr;
499 bool mUsingGlobalArray = false;
500 Q_DISABLE_COPY( QgsSettings )
501
502};
503
504// as static members cannot be CORE_EXPORTed
506
507#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition: qgis.h:3705
@ Any
From any origin.
A helper class for access to either a temporary QgsSettings object or the thread local object.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
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:341
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:405
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:315
Section
Sections for namespaced settings.
Definition: qgssettings.h:70
@ Gps
GPS section, since QGIS 3.22.
Definition: qgssettings.h:81
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:263
#define SIP_SKIP
Definition: qgis_sip.h:126
#define QgsDebugError(str)
Definition: qgslogger.h:38
thread_local QgsSettings * sQgsSettingsThreadSettings
Definition: qgssettings.cpp:29