QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
86  explicit QgsSettings( const QString &organization,
87  const QString &application = QString(), QObject *parent = nullptr );
88 
103  QgsSettings( QSettings::Scope scope, const QString &organization,
104  const QString &application = QString(), QObject *parent = nullptr );
105 
120  QgsSettings( QSettings::Format format, QSettings::Scope scope, const QString &organization,
121  const QString &application = QString(), QObject *parent = nullptr );
122 
143  QgsSettings( const QString &fileName, QSettings::Format format, QObject *parent = nullptr );
144 
154  explicit QgsSettings( QObject *parent = nullptr );
155  ~QgsSettings() override;
156 
163  void beginGroup( const QString &prefix, QgsSettings::Section section = QgsSettings::NoSection );
165  void endGroup();
166 
173  QString group() const;
174 
176  QStringList allKeys() const;
178  QStringList childKeys() const;
180  QStringList childGroups() const;
182  QStringList globalChildGroups() const;
184  static QString globalSettingsPath();
186  static bool setGlobalSettingsPath( const QString &path );
188  int beginReadArray( const QString &prefix );
189 
195  void beginWriteArray( const QString &prefix, int size = -1 );
197  void endArray();
198 
203  void setArrayIndex( int i );
204 
209  void setValue( const QString &key, const QVariant &value, QgsSettings::Section section = QgsSettings::NoSection );
210 
217 #ifndef SIP_RUN
218  QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
219  Section section = NoSection ) const;
220 #else
221  SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
222  SIP_PYOBJECT type = 0,
223  QgsSettings::Section section = QgsSettings::NoSection ) const / ReleaseGIL /;
224  % MethodCode
225  typedef PyObject *( *pyqt5_from_qvariant_by_type )( QVariant &value, PyObject *type );
226  QVariant value;
227 
228  // QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
229  Py_BEGIN_ALLOW_THREADS
230  value = sipCpp->value( *a0, *a1, a3 );
231  Py_END_ALLOW_THREADS
232 
233  pyqt5_from_qvariant_by_type f = ( pyqt5_from_qvariant_by_type ) sipImportSymbol( "pyqt5_from_qvariant_by_type" );
234  sipRes = f( value, a2 );
235 
236  sipIsErr = !sipRes;
237  % End
238 #endif
239 
240 #ifndef SIP_RUN
241 
252  template <class T>
253  T enumValue( const QString &key, const T &defaultValue,
254  const Section section = NoSection )
255  {
256  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
257  Q_ASSERT( metaEnum.isValid() );
258  if ( !metaEnum.isValid() )
259  {
260  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
261  }
262 
263  T v;
264  bool ok = false;
265 
266  if ( metaEnum.isValid() )
267  {
268  // read as string
269  QByteArray ba = value( key, metaEnum.valueToKey( static_cast<const int>( defaultValue ) ), section ).toString().toUtf8();
270  const char *vs = ba.data();
271  v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
272  if ( ok )
273  return v;
274  }
275 
276  // if failed, try to read as int (old behavior)
277  // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
278  // then the method could be marked as const
279  v = static_cast<T>( value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok ) );
280  if ( metaEnum.isValid() )
281  {
282  if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
283  {
284  v = defaultValue;
285  }
286  else
287  {
288  // found setting as an integer
289  // convert the setting to the new form (string)
290  setEnumValue( key, v, section );
291  }
292  }
293 
294  return v;
295  }
296 
304  template <class T>
305  void setEnumValue( const QString &key, const T &value,
306  const Section section = NoSection )
307  {
308  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
309  Q_ASSERT( metaEnum.isValid() );
310  if ( metaEnum.isValid() )
311  {
312  setValue( key, metaEnum.valueToKey( static_cast<const int>( value ) ), section );
313  }
314  else
315  {
316  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
317  }
318  }
319 
330  template <class T>
331  T flagValue( const QString &key, const T &defaultValue,
332  const Section section = NoSection )
333  {
334  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
335  Q_ASSERT( metaEnum.isValid() );
336  if ( !metaEnum.isValid() )
337  {
338  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
339  }
340 
341  T v = defaultValue;
342  bool ok = false;
343 
344  if ( metaEnum.isValid() )
345  {
346  // read as string
347  QByteArray ba = value( key, metaEnum.valueToKeys( static_cast< const int >( defaultValue ) ) ).toString().toUtf8();
348  const char *vs = ba.data();
349  v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
350  }
351  if ( !ok )
352  {
353  // if failed, try to read as int
354  const int intValue = value( key, static_cast<const int>( defaultValue ), section ).toInt( &ok );
355  if ( metaEnum.isValid() )
356  {
357  if ( ok )
358  {
359  // check that the int value does correspond to a flag
360  // see https://stackoverflow.com/a/68495949/1548052
361  const QByteArray keys = metaEnum.valueToKeys( intValue );
362  const int intValueCheck = metaEnum.keysToValue( keys );
363  if ( intValue != intValueCheck )
364  {
365  v = defaultValue;
366  }
367  else
368  {
369  // found property as an integer
370  v = T( intValue );
371  // convert the property to the new form (string)
372  // this code could be removed
373  // then the method could be marked as const
374  setFlagValue( key, v );
375  }
376  }
377  else
378  {
379  v = defaultValue;
380  }
381  }
382  }
383 
384  return v;
385  }
386 
394  template <class T>
395  void setFlagValue( const QString &key, const T &value,
396  const Section section = NoSection )
397  {
398  const QMetaEnum metaEnum = QMetaEnum::fromType<T>();
399  Q_ASSERT( metaEnum.isValid() );
400  if ( metaEnum.isValid() )
401  {
402  setValue( key, metaEnum.valueToKeys( static_cast< const int >( value ) ), section );
403  }
404  else
405  {
406  QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) );
407  }
408  }
409 #endif
410 
415  bool contains( const QString &key, QgsSettings::Section section = QgsSettings::NoSection ) const;
417  QString fileName() const;
418 
425  void sync();
427  void remove( const QString &key, QgsSettings::Section section = QgsSettings::NoSection );
429  QString prefixedKey( const QString &key, QgsSettings::Section section ) const;
431  void clear();
432 
433  private:
434  void init();
435  QString sanitizeKey( const QString &key ) const;
436  QSettings *mUserSettings = nullptr;
437  QSettings *mGlobalSettings = nullptr;
438  bool mUsingGlobalArray = false;
439  Q_DISABLE_COPY( QgsSettings )
440 
441 };
442 
443 #endif // QGSSETTINGS_H
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:331
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:395
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:305
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:253
#define QgsDebugMsg(str)
Definition: qgslogger.h:38