QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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
87 explicit QgsSettings( const QString &organization,
88 const QString &application = QString(), QObject *parent = nullptr );
89
104 QgsSettings( QSettings::Scope scope, const QString &organization,
105 const QString &application = QString(), QObject *parent = nullptr );
106
121 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
122 const QString &application = QString(), QObject *parent = nullptr );
123
144 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
145
155 explicit QgsSettings( QObject *parent = nullptr );
156 ~QgsSettings() override;
157
164 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
166 void endGroup();
167
174 QString group() const;
175
177 QStringList allKeys() const;
179 QStringList childKeys() const;
181 QStringList childGroups( Qgis::SettingsOrigin origin = Qgis::SettingsOrigin::Any ) const;
183 QStringList globalChildGroups() const;
185 static QString globalSettingsPath();
187 static bool setGlobalSettingsPath( const QString &path );
189 int beginReadArray( const QString &prefix );
190
196 void beginWriteArray( const QString &prefix, int size = -1 );
198 void endArray();
199
204 void setArrayIndex( int i );
205
211 Qgis::SettingsOrigin origin( const QString &key ) const;
212
217 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
218
225#ifndef SIP_RUN
226 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
227 Section section = NoSection ) const;
228#else
229 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
230 SIP_PYOBJECT type = 0,
231 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
232 % MethodCode
233 typedef PyObject *( *pyqt5_from_qvariant_by_type )( QVariant &value, PyObject *type );
234 QVariant value;
235
236 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
237 Py_BEGIN_ALLOW_THREADS
238 value = sipCpp->value( *a0, *a1, a3 );
239 Py_END_ALLOW_THREADS
240
241 pyqt5_from_qvariant_by_type f = ( pyqt5_from_qvariant_by_type ) sipImportSymbol( "pyqt5_from_qvariant_by_type" );
242 sipRes = f( value, a2 );
243
244 sipIsErr = !sipRes;
245 % End
246#endif
247
248
249#ifndef SIP_RUN
250
261 template <class T>
262 T enumValue( const QString &key, const T &defaultValue,
263 const Section section = NoSection )
264 {
265 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
266 Q_ASSERT( metaEnum.isValid() );
267 if ( !metaEnum.isValid() )
268 {
269 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
270 }
271
272 T v;
273 bool ok = false;
274
275 if ( metaEnum.isValid() )
276 {
277 // read as string
278 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
279 const char *vs = ba.data();
280 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
281 if ( ok )
282 return v;
283 }
284
285 // if failed, try to read as int (old behavior)
286 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
287 // then the method could be marked as const
288 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
289 if ( metaEnum.isValid() )
290 {
291 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
292 {
293 v = defaultValue;
294 }
295 else
296 {
297 // found setting as an integer
298 // convert the setting to the new form (string)
299 setEnumValue( key, v, section );
300 }
301 }
302
303 return v;
304 }
305
313 template <class T>
314 void setEnumValue( const QString &key, const T &value,
315 const Section section = NoSection )
316 {
317 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
318 Q_ASSERT( metaEnum.isValid() );
319 if ( metaEnum.isValid() )
320 {
321 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
322 }
323 else
324 {
325 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
326 }
327 }
328
339 template <class T>
340 T flagValue( const QString &key, const T &defaultValue,
341 const Section section = NoSection )
342 {
343 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
344 Q_ASSERT( metaEnum.isValid() );
345 if ( !metaEnum.isValid() )
346 {
347 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
348 }
349
350 T v = defaultValue;
351 bool ok = false;
352
353 if ( metaEnum.isValid() )
354 {
355 // read as string
356 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
357 const char *vs = ba.data();
358 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
359 }
360 if ( !ok )
361 {
362 // if failed, try to read as int
363 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
364 if ( metaEnum.isValid() )
365 {
366 if ( ok )
367 {
368 // check that the int value does correspond to a flag
369 // see https://stackoverflow.com/a/68495949/1548052
370 const QByteArray keys = metaEnum.valueToKeys( intValue );
371 const int intValueCheck = metaEnum.keysToValue( keys );
372 if ( intValue != intValueCheck )
373 {
374 v = defaultValue;
375 }
376 else
377 {
378 // found property as an integer
379 v = T( intValue );
380 // convert the property to the new form (string)
381 // this code could be removed
382 // then the method could be marked as const
383 setFlagValue( key, v );
384 }
385 }
386 else
387 {
388 v = defaultValue;
389 }
390 }
391 }
392
393 return v;
394 }
395
403 template <class T>
404 void setFlagValue( const QString &key, const T &value,
405 const Section section = NoSection )
406 {
407 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
408 Q_ASSERT( metaEnum.isValid() );
409 if ( metaEnum.isValid() )
410 {
411 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
412 }
413 else
414 {
415 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
416 }
417 }
418#endif
419
424 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
426 QString fileName() const;
427
434 void sync();
436 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
438 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
440 void clear();
441
442 private:
443 void init();
444 QString sanitizeKey( const QString &key ) const;
445 QSettings *mUserSettings = nullptr;
446 QSettings *mGlobalSettings = nullptr;
447 bool mUsingGlobalArray = false;
448 Q_DISABLE_COPY( QgsSettings )
449
450};
451
452#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition: qgis.h:2907
@ Any
From any origin.
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:340
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:404
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:314
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:262
#define QgsDebugError(str)
Definition: qgslogger.h:38