QGIS API Documentation  3.27.0-Master (597e8eebd4)
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 
61 class CORE_EXPORT QgsSettings : public QObject
62 {
63  Q_OBJECT
64  public:
65 
67  enum Section
68  {
71  Gui,
75  App,
79  Gps,
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  };
111 
116  explicit QgsSettings( const QString &organization,
117  const QString &application = QString(), QObject *parent = nullptr );
118 
133  QgsSettings( QSettings::Scope scope, const QString &organization,
134  const QString &application = QString(), QObject *parent = nullptr );
135 
150  QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
151  const QString &application = QString(), QObject *parent = nullptr );
152 
173  QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
174 
184  explicit QgsSettings( QObject *parent = nullptr );
185  ~QgsSettings() override;
186 
193  void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
195  void endGroup();
196 
203  QString group() const;
204 
206  QStringList allKeys() const;
208  QStringList childKeys() const;
210  QStringList childGroups() const;
212  QStringList globalChildGroups() const;
214  static QString globalSettingsPath();
216  static bool setGlobalSettingsPath( const QString &path );
218  int beginReadArray( const QString &prefix );
219 
225  void beginWriteArray( const QString &prefix, int size = -1 );
227  void endArray();
228 
233  void setArrayIndex( int i );
234 
239  void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
240 
247 #ifndef SIP_RUN
248  QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
249  Section section = NoSection ) const;
250 #else
251  SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
252  SIP_PYOBJECT type = 0,
253  QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
254  % MethodCode
255  typedef PyObject *( *pyqt5_from_qvariant_by_type )( QVariant &value, PyObject *type );
256  QVariant value;
257 
258  // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
259  Py_BEGIN_ALLOW_THREADS
260  value = sipCpp->value( *a0, *a1, a3 );
261  Py_END_ALLOW_THREADS
262 
263  pyqt5_from_qvariant_by_type f = ( pyqt5_from_qvariant_by_type ) sipImportSymbol( "pyqt5_from_qvariant_by_type" );
264  sipRes = f( value, a2 );
265 
266  sipIsErr = !sipRes;
267  % End
268 #endif
269 
270 #ifndef SIP_RUN
271 
282  template <class T>
283  T enumValue( const QString &key, const T &defaultValue,
284  const Section section = NoSection )
285  {
286  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
287  Q_ASSERT( metaEnum.isValid() );
288  if ( !metaEnum.isValid() )
289  {
290  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
291  }
292 
293  T v;
294  bool ok = false;
295 
296  if ( metaEnum.isValid() )
297  {
298  // read as string
299  QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
300  const char *vs = ba.data();
301  v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
302  if ( ok )
303  return v;
304  }
305 
306  // if failed, try to read as int (old behavior)
307  // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
308  // then the method could be marked as const
309  v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
310  if ( metaEnum.isValid() )
311  {
312  if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
313  {
314  v = defaultValue;
315  }
316  else
317  {
318  // found setting as an integer
319  // convert the setting to the new form (string)
320  setEnumValue( key, v, section );
321  }
322  }
323 
324  return v;
325  }
326 
334  template <class T>
335  void setEnumValue( const QString &key, const T &value,
336  const Section section = NoSection )
337  {
338  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
339  Q_ASSERT( metaEnum.isValid() );
340  if ( metaEnum.isValid() )
341  {
342  setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
343  }
344  else
345  {
346  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
347  }
348  }
349 
360  template <class T>
361  T flagValue( const QString &key, const T &defaultValue,
362  const Section section = NoSection )
363  {
364  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
365  Q_ASSERT( metaEnum.isValid() );
366  if ( !metaEnum.isValid() )
367  {
368  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
369  }
370 
371  T v = defaultValue;
372  bool ok = false;
373 
374  if ( metaEnum.isValid() )
375  {
376  // read as string
377  QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
378  const char *vs = ba.data();
379  v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
380  }
381  if ( !ok )
382  {
383  // if failed, try to read as int
384  const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
385  if ( metaEnum.isValid() )
386  {
387  if ( ok )
388  {
389  // check that the int value does correspond to a flag
390  // see https://stackoverflow.com/a/68495949/1548052
391  const QByteArray keys = metaEnum.valueToKeys( intValue );
392  const int intValueCheck = metaEnum.keysToValue( keys );
393  if ( intValue != intValueCheck )
394  {
395  v = defaultValue;
396  }
397  else
398  {
399  // found property as an integer
400  v = T( intValue );
401  // convert the property to the new form (string)
402  // this code could be removed
403  // then the method could be marked as const
404  setFlagValue( key, v );
405  }
406  }
407  else
408  {
409  v = defaultValue;
410  }
411  }
412  }
413 
414  return v;
415  }
416 
424  template <class T>
425  void setFlagValue( const QString &key, const T &value,
426  const Section section = NoSection )
427  {
428  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
429  Q_ASSERT( metaEnum.isValid() );
430  if ( metaEnum.isValid() )
431  {
432  setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
433  }
434  else
435  {
436  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
437  }
438  }
439 #endif
440 
445  bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
447  QString fileName() const;
448 
455  void sync();
457  void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
459  QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
461  void clear();
462 
463  private:
464  void init();
465  QString sanitizeKey( const QString &key ) const;
466  QSettings *mUserSettings = nullptr;
467  QSettings *mGlobalSettings = nullptr;
468  bool mUsingGlobalArray = false;
469  Q_DISABLE_COPY( QgsSettings )
470 
471 };
472 
473 #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:361
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:425
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:335
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:283
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