QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
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 "qgis_core.h"
21#include "qgis_sip.h"
22#include "qgslogger.h"
23#include "qgssettingstreenode.h"
24
25#include <QMetaEnum>
26#include <QSettings>
27#include <QString>
28
29using namespace Qt::StringLiterals;
30
32
67class CORE_EXPORT QgsSettings : public QObject
68{
69 Q_OBJECT
70 public:
86
91 explicit QgsSettings( const QString &organization, const QString &application = QString(), QObject *parent = nullptr );
92
107 QgsSettings( QSettings::Scope scope, const QString &organization, const QString &application = QString(), QObject *parent = nullptr );
108
123 QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization, 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(), Section section = NoSection ) const;
228#else
229 // clang-format off
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// clang-format on
248#endif
249
250
251#ifndef SIP_RUN
252
263 template<class T> T enumValue( const QString &key, const T &defaultValue, const Section section = NoSection )
264 {
265 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
266 Q_ASSERT( metaEnum.isValid() );
267 if ( !metaEnum.isValid() )
268 {
269 QgsDebugError( u"Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration."_s );
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> void setEnumValue( const QString &key, const T &value, const Section section = NoSection )
314 {
315 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
316 Q_ASSERT( metaEnum.isValid() );
317 if ( metaEnum.isValid() )
318 {
319 setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
320 }
321 else
322 {
323 QgsDebugError( u"Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration."_s );
324 }
325 }
326
337 template<class T> T flagValue( const QString &key, const T &defaultValue, const Section section = NoSection )
338 {
339 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
340 Q_ASSERT( metaEnum.isValid() );
341 if ( !metaEnum.isValid() )
342 {
343 QgsDebugError( u"Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration."_s );
344 }
345
346 T v = defaultValue;
347 bool ok = false;
348
349 if ( metaEnum.isValid() )
350 {
351 // read as string
352 QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
353 const char *vs = ba.data();
354 v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
355 }
356 if ( !ok )
357 {
358 // if failed, try to read as int
359 const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
360 if ( metaEnum.isValid() )
361 {
362 if ( ok )
363 {
364 // check that the int value does correspond to a flag
365 // see https://stackoverflow.com/a/68495949/1548052
366 const QByteArray keys = metaEnum.valueToKeys( intValue );
367 const int intValueCheck = metaEnum.keysToValue( keys );
368 if ( intValue != intValueCheck )
369 {
370 v = defaultValue;
371 }
372 else
373 {
374 // found property as an integer
375 v = T( intValue );
376 // convert the property to the new form (string)
377 // this code could be removed
378 // then the method could be marked as const
379 setFlagValue( key, v );
380 }
381 }
382 else
383 {
384 v = defaultValue;
385 }
386 }
387 }
388
389 return v;
390 }
391
399 template<class T> void setFlagValue( const QString &key, const T &value, const Section section = NoSection )
400 {
401 const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
402 Q_ASSERT( metaEnum.isValid() );
403 if ( metaEnum.isValid() )
404 {
405 setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
406 }
407 else
408 {
409 QgsDebugError( u"Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration."_s );
410 }
411 }
412#endif
413
418 bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
420 QString fileName() const;
421
428 void sync();
430 void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
432 QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
434 void clear();
435
454 static void holdFlush() SIP_SKIP;
455
470 static void releaseFlush() SIP_SKIP;
471
485 static QgsSettingsProxy get() SIP_SKIP;
486
487 private:
488 void init();
489 QString sanitizeKey( const QString &key ) const;
490 std::unique_ptr<QSettings> mUserSettings;
491 std::unique_ptr<QSettings> mGlobalSettings;
492 bool mUsingGlobalArray = false;
493 Q_DISABLE_COPY( QgsSettings )
494};
495
496// as static members cannot be CORE_EXPORTed
498
499#endif // QGSSETTINGS_H
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4609
@ Any
From any origin.
Definition qgis.h:4610
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:68
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
QgsSettings(const QString &organization, const QString &application=QString(), QObject *parent=nullptr)
Constructs a QgsSettings object for accessing settings of the application called application from the...
Section
Sections for namespaced settings.
Definition qgssettings.h:73
@ Gps
GPS section, since QGIS 3.22.
Definition qgssettings.h:84
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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:133
#define QgsDebugError(str)
Definition qgslogger.h:59
QgsSettings * sQgsSettingsThreadSettings