1 | // SPDX-FileCopyrightText: 2016 Kitsune Ral <kitsune-ral@users.sf.net> |
2 | // SPDX-License-Identifier: LGPL-2.1-or-later |
3 | |
4 | #include "settings.h" |
5 | |
6 | #include "logging_categories_p.h" |
7 | #include "util.h" |
8 | |
9 | #include <QtCore/QUrl> |
10 | |
11 | using namespace Quotient; |
12 | |
13 | QString Settings::legacyOrganizationName {}; |
14 | QString Settings::legacyApplicationName {}; |
15 | |
16 | void Settings::setLegacyNames(const QString& organizationName, |
17 | const QString& applicationName) |
18 | { |
19 | legacyOrganizationName = organizationName; |
20 | legacyApplicationName = applicationName; |
21 | } |
22 | |
23 | Settings::Settings(QObject* parent) : QSettings(parent) |
24 | { |
25 | #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) |
26 | setIniCodec("UTF-8" ); |
27 | #endif |
28 | } |
29 | |
30 | void Settings::setValue(const QString& key, const QVariant& value) |
31 | { |
32 | QSettings::setValue(key, value); |
33 | if (legacySettings.contains(key)) |
34 | legacySettings.remove(key); |
35 | } |
36 | |
37 | void Settings::remove(const QString& key) |
38 | { |
39 | QSettings::remove(key); |
40 | if (legacySettings.contains(key)) |
41 | legacySettings.remove(key); |
42 | } |
43 | |
44 | QVariant Settings::value(const QString& key, const QVariant& defaultValue) const |
45 | { |
46 | auto value = QSettings::value(key, defaultValue: legacySettings.value(key, defaultValue)); |
47 | // QML's Qt.labs.Settings stores boolean values as strings, which, if loaded |
48 | // through the usual QSettings interface, confuses QML |
49 | // (QVariant("false") == true in JavaScript). Since we have a mixed |
50 | // environment where both QSettings and Qt.labs.Settings may potentially |
51 | // work with same settings, better ensure compatibility. |
52 | return value.toString() == QStringLiteral("false" ) ? QVariant(false) : value; |
53 | } |
54 | |
55 | bool Settings::contains(const QString& key) const |
56 | { |
57 | return QSettings::contains(key) || legacySettings.contains(key); |
58 | } |
59 | |
60 | QStringList Settings::childGroups() const |
61 | { |
62 | auto groups = QSettings::childGroups(); |
63 | const auto& legacyGroups = legacySettings.childGroups(); |
64 | for (const auto& g: legacyGroups) |
65 | if (!groups.contains(str: g)) |
66 | groups.push_back(t: g); |
67 | return groups; |
68 | } |
69 | |
70 | void SettingsGroup::setValue(const QString& key, const QVariant& value) |
71 | { |
72 | Settings::setValue(key: groupPath + u'/' + key, value); |
73 | } |
74 | |
75 | bool SettingsGroup::contains(const QString& key) const |
76 | { |
77 | return Settings::contains(key: groupPath + u'/' + key); |
78 | } |
79 | |
80 | QVariant SettingsGroup::value(const QString& key, |
81 | const QVariant& defaultValue) const |
82 | { |
83 | return Settings::value(key: groupPath + u'/' + key, defaultValue); |
84 | } |
85 | |
86 | QString SettingsGroup::group() const { return groupPath; } |
87 | |
88 | QStringList SettingsGroup::childGroups() const |
89 | { |
90 | const_cast<SettingsGroup*>(this)->beginGroup(prefix: groupPath); |
91 | const_cast<QSettings&>(legacySettings).beginGroup(prefix: groupPath); |
92 | QStringList l = Settings::childGroups(); |
93 | const_cast<SettingsGroup*>(this)->endGroup(); |
94 | const_cast<QSettings&>(legacySettings).endGroup(); |
95 | return l; |
96 | } |
97 | |
98 | void SettingsGroup::remove(const QString& key) |
99 | { |
100 | QString fullKey { groupPath }; |
101 | if (!key.isEmpty()) |
102 | fullKey += u'/' + key; |
103 | Settings::remove(key: fullKey); |
104 | } |
105 | |
106 | QUO_DEFINE_SETTING(AccountSettings, QString, deviceId, "device_id" , {}, |
107 | setDeviceId) |
108 | QUO_DEFINE_SETTING(AccountSettings, QString, deviceName, "device_name" , {}, |
109 | setDeviceName) |
110 | QUO_DEFINE_SETTING(AccountSettings, bool, keepLoggedIn, "keep_logged_in" , false, |
111 | setKeepLoggedIn) |
112 | |
113 | namespace { |
114 | constexpr auto HomeserverKey = "homeserver"_ls ; |
115 | constexpr auto AccessTokenKey = "access_token"_ls ; |
116 | constexpr auto EncryptionAccountPickleKey = "encryption_account_pickle"_ls ; |
117 | } |
118 | |
119 | QUrl AccountSettings::homeserver() const |
120 | { |
121 | return QUrl::fromUserInput(userInput: value(key: HomeserverKey).toString()); |
122 | } |
123 | |
124 | void AccountSettings::setHomeserver(const QUrl& url) |
125 | { |
126 | setValue(key: HomeserverKey, value: url.toString()); |
127 | } |
128 | |
129 | QString AccountSettings::userId() const { return group().section(asep: u'/', astart: -1); } |
130 | |
131 | void AccountSettings::clearAccessToken() |
132 | { |
133 | legacySettings.remove(key: AccessTokenKey); |
134 | legacySettings.remove(QStringLiteral("device_id" )); // Force the server to |
135 | // re-issue it |
136 | remove(key: AccessTokenKey); |
137 | } |
138 | |
139 | QByteArray AccountSettings::encryptionAccountPickle() |
140 | { |
141 | return value(key: "encryption_account_pickle"_ls , defaultValue: QString()).toByteArray(); |
142 | } |
143 | |
144 | void AccountSettings::setEncryptionAccountPickle( |
145 | const QByteArray& encryptionAccountPickle) |
146 | { |
147 | setValue(key: "encryption_account_pickle"_ls , value: encryptionAccountPickle); |
148 | } |
149 | |
150 | void AccountSettings::clearEncryptionAccountPickle() |
151 | { |
152 | remove(key: EncryptionAccountPickleKey); // TODO: Force to re-issue it? |
153 | } |
154 | |