libQuotient
A Qt library for building matrix clients
settings.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016 Kitsune Ral <kitsune-ral@users.sf.net>
2 // SPDX-License-Identifier: LGPL-2.1-or-later
3 
4 #pragma once
5 
6 #include "util.h"
7 
8 #include <QtCore/QSettings>
9 #include <QtCore/QUrl>
10 #include <QtCore/QStringBuilder>
11 
12 class QVariant;
13 
14 namespace Quotient {
15 
16 class QUOTIENT_API Settings : public QSettings {
17  Q_OBJECT
18 public:
19  /// Add a legacy organisation/application name to migrate settings from
20  /*!
21  * Use this function before creating any Settings objects in order
22  * to set a legacy location where configuration has previously been stored.
23  * This will provide an additional fallback in case of renaming
24  * the organisation/application. Values in legacy locations are _removed_
25  * when setValue() or remove() is called.
26  */
27  static void setLegacyNames(const QString& organizationName,
28  const QString& applicationName = {});
29 
30  explicit Settings(QObject* parent = nullptr);
31 
32  /// Set the value for a given key
33  /*! If the key exists in the legacy location, it is removed. */
34  Q_INVOKABLE void setValue(const QString& key, const QVariant& value);
35 
36  /// Remove the value from both the primary and legacy locations
37  Q_INVOKABLE void remove(const QString& key);
38 
39  /// Obtain a value for a given key
40  /*!
41  * If the key doesn't exist in the primary settings location, the legacy
42  * location is checked. If neither location has the key,
43  * \p defaultValue is returned.
44  *
45  * This function returns a QVariant; use get<>() to get the unwrapped
46  * value if you know the type upfront.
47  *
48  * \sa setLegacyNames, get
49  */
50  Q_INVOKABLE QVariant value(const QString& key, const QVariant& defaultValue = {}) const;
51 
52  /// Obtain a value for a given key, coerced to the given type
53  /*!
54  * On top of value(), this function unwraps the QVariant and returns
55  * its contents assuming the type passed as the template parameter.
56  * If the type is different from the one stored inside the QVariant,
57  * \p defaultValue is returned. In presence of legacy settings,
58  * only the first found value is checked; if its type does not match,
59  * further checks through legacy settings are not performed and
60  * \p defaultValue is returned.
61  */
62  template <typename T>
63  T get(const QString& key, const T& defaultValue = {}) const
64  {
65  const auto qv = value(key);
66  return qv.isValid() && qv.canConvert<T>() ? qv.value<T>() : defaultValue;
67  }
68 
69  Q_INVOKABLE bool contains(const QString& key) const;
70  Q_INVOKABLE QStringList childGroups() const;
71 
72 private:
73  static QString legacyOrganizationName;
74  static QString legacyApplicationName;
75 
76 protected:
77  QSettings legacySettings { legacyOrganizationName, legacyApplicationName };
78 };
79 
80 class QUOTIENT_API SettingsGroup : public Settings {
81 public:
82  explicit SettingsGroup(QString path, QObject* parent = nullptr)
83  : Settings(parent)
84  , groupPath(std::move(path))
85  {}
86 
87  Q_INVOKABLE bool contains(const QString& key) const;
88  Q_INVOKABLE QVariant value(const QString& key, const QVariant& defaultValue = {}) const;
89 
90  template <typename T>
91  T get(const QString& key, const T& defaultValue = {}) const
92  {
93  const auto qv = value(key);
94  return qv.isValid() && qv.canConvert<T>() ? qv.value<T>() : defaultValue;
95  }
96 
97  Q_INVOKABLE QString group() const;
98  Q_INVOKABLE QStringList childGroups() const;
99  Q_INVOKABLE void setValue(const QString& key, const QVariant& value);
100 
101  Q_INVOKABLE void remove(const QString& key);
102 
103 private:
104  QString fullPath(QAnyStringView key) const { return groupPath % u'/' % key.toString(); }
105 
106  QString groupPath;
107 };
108 
109 #define QUO_DECLARE_SETTING(type, propname, setter)
110  Q_PROPERTY(type propname READ propname WRITE setter) public
111  :
112  type propname() const;
113  void setter(type newValue);
114  private
115  :
116 
117 #define QUO_DEFINE_SETTING(classname, type, propname, qsettingname, defaultValue, setter)
118  type classname::propname() const { return get<type>(qsettingname##_L1, defaultValue); }
119  void classname::setter(type newValue) { setValue(qsettingname##_L1, std::move(newValue)); }
120 
121 class QUOTIENT_API AccountSettings : public SettingsGroup {
122  Q_OBJECT
123  Q_PROPERTY(QString userId READ userId CONSTANT)
124  QUO_DECLARE_SETTING(QString, deviceId, setDeviceId)
125  QUO_DECLARE_SETTING(QString, deviceName, setDeviceName)
126  QUO_DECLARE_SETTING(bool, keepLoggedIn, setKeepLoggedIn)
127  Q_PROPERTY(QByteArray encryptionAccountPickle READ encryptionAccountPickle
128  WRITE setEncryptionAccountPickle)
129 public:
130  explicit AccountSettings(const QString& accountId, QObject* parent = nullptr)
131  : SettingsGroup("Accounts/"_L1 + accountId, parent)
132  {}
133 
134  QString userId() const;
135 
136  QUrl homeserver() const;
137  void setHomeserver(const QUrl& url);
138 
139  QByteArray encryptionAccountPickle();
140  void setEncryptionAccountPickle(const QByteArray& encryptionAccountPickle);
141  Q_INVOKABLE void clearEncryptionAccountPickle();
142 };
143 } // namespace Quotient