QGIS API Documentation 3.43.0-Master (1896cf2247d)
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
64class CORE_EXPORT QgsSettings : public QObject
65{
66 Q_OBJECT
67 public:
68
84
89 explicit QgsSettings( const QString &organization,
90 const QString &application = QString(), QObject *parent = nullptr );
91
106 QgsSettings( QSettings::Scope scope, const QString &organization,
107 const QString &application = QString(), QObject *parent = nullptr );
108
123 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
124 const QString &application = QString(), QObject *parent = nullptr );
125
146 QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
147
157 explicit QgsSettings( QObject *parent = nullptr );
158 ~QgsSettings() override;
159
166 void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
168 void endGroup();
169
176 QString group() const;
177
179 QStringList allKeys() const;
181 QStringList childKeys() const;
183 QStringList childGroups( Qgis::SettingsOrigin origin = Qgis::SettingsOrigin::Any ) const;
185 QStringList globalChildGroups() const;
187 static QString globalSettingsPath();
189 static bool setGlobalSettingsPath( const QString &path );
191 int beginReadArray( const QString &prefix );
192
198 void beginWriteArray( const QString &prefix, int size = -1 );
200 void endArray();
201
206 void setArrayIndex( int i );
207
213 Qgis::SettingsOrigin origin( const QString &key ) const;
214
219 void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
220
227#ifndef SIP_RUN
228 QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
229 Section section = NoSection ) const;
230#else
231 SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
232 SIP_PYOBJECT type = 0,
233 QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
234 % MethodCode
235 typedef PyObject *( *pyqt_from_qvariant_by_type )( QVariant &value, PyObject *type );
236 QVariant value;
237
238 // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
239 Py_BEGIN_ALLOW_THREADS
240 value = sipCpp->value( *a0, *a1, a3 );
241 Py_END_ALLOW_THREADS
242
243 pyqt_from_qvariant_by_type f = ( pyqt_from_qvariant_by_type ) sipImportSymbol( SIP_PYQT_FROM_QVARIANT_BY_TYPE );
244 sipRes = f( value, a2 );
245
246 sipIsErr = !sipRes;
247 % End
248#endif
249
250
251#ifndef SIP_RUN
252
263 template <class T>
264 T enumValue( const QString &key, const T &defaultValue,
265 const Section section = NoSection )
266 {
267 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
268 Q_ASSERT( metaEnum.isValid() );
269 if ( !metaEnum.isValid() )
270 {
271 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
272 }
273
274 T v;
275 bool ok = false;
276
277 if ( metaEnum.isValid() )
278 {
279 // read as string
280 QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
281 const char *vs = ba.data();
282 v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
283 if ( ok )
284 return v;
285 }
286
287 // if failed, try to read as int (old behavior)
288 // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
289 // then the method could be marked as const
290 v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
291 if ( metaEnum.isValid() )
292 {
293 if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
294 {
295 v = defaultValue;
296 }
297 else
298 {
299 // found setting as an integer
300 // convert the setting to the new form (string)
301 setEnumValue( key, v, section );
302 }
303 }
304
305 return v;
306 }
307
315 template <class T>
316 void setEnumValue( const QString &key, const T &value,
317 const Section section = NoSection )
318 {
319 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
320 Q_ASSERT( metaEnum.isValid() );
321 if ( metaEnum.isValid() )
322 {
323 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
324 }
325 else
326 {
327 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
328 }
329 }
330
341 template <class T>
342 T flagValue( const QString &key, const T &defaultValue,
343 const Section section = NoSection )
344 {
345 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
346 Q_ASSERT( metaEnum.isValid() );
347 if ( !metaEnum.isValid() )
348 {
349 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
350 }
351
352 T v = defaultValue;
353 bool ok = false;
354
355 if ( metaEnum.isValid() )
356 {
357 // read as string
358 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
359 const char *vs = ba.data();
360 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
361 }
362 if ( !ok )
363 {
364 // if failed, try to read as int
365 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
366 if ( metaEnum.isValid() )
367 {
368 if ( ok )
369 {
370 // check that the int value does correspond to a flag
371 // see https://stackoverflow.com/a/68495949/1548052
372 const QByteArray keys = metaEnum.valueToKeys( intValue );
373 const int intValueCheck = metaEnum.keysToValue( keys );
374 if ( intValue != intValueCheck )
375 {
376 v = defaultValue;
377 }
378 else
379 {
380 // found property as an integer
381 v = T( intValue );
382 // convert the property to the new form (string)
383 // this code could be removed
384 // then the method could be marked as const
385 setFlagValue( key, v );
386 }
387 }
388 else
389 {
390 v = defaultValue;
391 }
392 }
393 }
394
395 return v;
396 }
397
405 template <class T>
406 void setFlagValue( const QString &key, const T &value,
407 const Section section = NoSection )
408 {
409 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
410 Q_ASSERT( metaEnum.isValid() );
411 if ( metaEnum.isValid() )
412 {
413 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
414 }
415 else
416 {
417 QgsDebugError( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
418 }
419 }
420#endif
421
426 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
428 QString fileName() const;
429
436 void sync();
438 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
440 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
442 void clear();
443
462 static void holdFlush() SIP_SKIP;
463
478 static void releaseFlush() SIP_SKIP;
479
493 static QgsSettingsProxy get() SIP_SKIP;
494
495 private:
496 void init();
497 QString sanitizeKey( const QString &key ) const;
498 std::unique_ptr<QSettings> mUserSettings;
499 std::unique_ptr<QSettings> mGlobalSettings;
500 bool mUsingGlobalArray = false;
501 Q_DISABLE_COPY( QgsSettings )
502
503};
504
505// as static members cannot be CORE_EXPORTed
507
508#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4330
@ 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:65
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:71
@ Gps
GPS section, since QGIS 3.22.
Definition qgssettings.h:82
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