Line data Source code
1 : // SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2 : // SPDX-License-Identifier: GPL-3.0-or-later
3 : /**
4 : * @file
5 : * @brief QtPassSettings, the QSettings singleton behind every saved setting,
6 : * the profiles and the Pass backend accessors.
7 : */
8 : #ifndef SRC_QTPASSSETTINGS_H_
9 : #define SRC_QTPASSSETTINGS_H_
10 :
11 : #include "appsettings.h"
12 : #include "enums.h"
13 : #include "imitatepass.h"
14 : #include "passwordconfiguration.h"
15 : #include "profile.h"
16 : #include "realpass.h"
17 : #include "settingsconstants.h"
18 :
19 : #include <QByteArray>
20 : #include <QHash>
21 : #include <QPoint>
22 : #include <QSettings>
23 : #include <QSize>
24 : #include <QVariant>
25 :
26 : /**
27 : * @class QtPassSettings
28 : * @ingroup settings
29 : * @brief Singleton that stores QtPass settings, handles persistence and
30 : * defaults.
31 : *
32 : * QtPassSettings manages all application configuration including:
33 : * - Window geometry (QWidget::saveGeometry blobs, main window and dialogs)
34 : * - Password store configuration (path, GPG settings)
35 : * - Executable paths (pass, git, gpg, pwgen)
36 : * - UI preferences (clipboard, autoclear, display options)
37 : * - gopass configuration
38 : *
39 : * Uses QSettings for persistence with a singleton pattern.
40 : * All getters accept a default value returned when setting is not yet saved.
41 : */
42 : class QtPassSettings : public QSettings {
43 : private:
44 : /**
45 : * @brief Private default constructor to enforce singleton usage and prevent
46 : * direct instantiation.
47 : */
48 : explicit QtPassSettings() = delete;
49 :
50 : /**
51 : * @brief Settings in an explicit file: the portable `qtpass.ini` next to
52 : * the executable, which getInstance() prefers when it exists.
53 : * @param organization The file's path (QSettings' file-name constructor).
54 : * @param format The file's format; IniFormat for the portable file.
55 : */
56 : QtPassSettings(const QString &organization, const QSettings::Format format)
57 0 : : QSettings(organization, format) {}
58 : /**
59 : * @brief Per-user settings in QSettings::defaultFormat().
60 : *
61 : * QSettings(organization, application) ignores setDefaultFormat() and
62 : * always uses NativeFormat; going through the explicit-format constructor
63 : * keeps the production default (NativeFormat) while letting the test
64 : * suites redirect settings to an ini file in a temporary directory.
65 : * @param organization The organisation the settings are filed under
66 : * ("IJHack").
67 : * @param application The application name ("QtPass").
68 : */
69 15 : QtPassSettings(const QString &organization, const QString &application)
70 15 : : QSettings(QSettings::defaultFormat(), QSettings::UserScope,
71 15 : organization, application) {}
72 :
73 0 : ~QtPassSettings() override = default;
74 :
75 : /// Whether getInstance() has chosen the store and built m_instance.
76 : static bool initialized;
77 : /// The one instance, built on the first getInstance() and kept for the
78 : /// life of the process.
79 : static QtPassSettings *m_instance;
80 :
81 : public:
82 : /**
83 : * @brief Get the singleton instance.
84 : * @return Pointer to the QtPassSettings instance.
85 : */
86 : static auto getInstance() -> QtPassSettings *;
87 :
88 : /**
89 : * @brief Load all flat settings into an AppSettings value object.
90 : *
91 : * Convenience facade over SettingsSerializer using the singleton store.
92 : * Note: nested/keyed settings (profiles, per-dialog geometry) are not part
93 : * of AppSettings and still use their dedicated accessors.
94 : * @return Current settings.
95 : */
96 : static auto load() -> AppSettings;
97 : /**
98 : * @brief Persist an AppSettings value object to the singleton store.
99 : *
100 : * Writes via SettingsSerializer and invalidates the cached Pass backend so a
101 : * changed "use pass" mode takes effect on the next getPass().
102 : * @param settings Values to save.
103 : */
104 : static void save(const AppSettings &settings);
105 :
106 : // Window settings
107 : /**
108 : * @brief Get saved application version.
109 : * @param defaultValue String returned if no version saved.
110 : * @return Application version string.
111 : */
112 : static auto getVersion(const QString &defaultValue = QVariant().toString())
113 : -> QString;
114 : /**
115 : * @brief Save application version.
116 : * @param version Version string to save.
117 : */
118 : static void setVersion(const QString &version);
119 :
120 : /**
121 : * @brief Get saved window geometry.
122 : * @param defaultValue Byte array returned if no geometry saved.
123 : * @return Window geometry as QByteArray.
124 : */
125 : static auto
126 : getGeometry(const QByteArray &defaultValue = QVariant().toByteArray())
127 : -> QByteArray;
128 : /**
129 : * @brief Save window geometry.
130 : * @param geometry Window geometry to save.
131 : */
132 : static void setGeometry(const QByteArray &geometry);
133 :
134 : /**
135 : * @brief Get saved window state.
136 : * @param defaultValue Byte array returned if no state saved.
137 : * @return Window state as QByteArray.
138 : */
139 : static auto
140 : getSavestate(const QByteArray &defaultValue = QVariant().toByteArray())
141 : -> QByteArray;
142 : /**
143 : * @brief Save window state.
144 : * @param saveState Window state to save.
145 : */
146 : static void setSavestate(const QByteArray &saveState);
147 :
148 : // Dialog-specific settings
149 : /**
150 : * @brief Get saved dialog geometry.
151 : * @param key Dialog identifier (e.g., "usersDialog").
152 : * @param defaultValue Byte array returned if not saved.
153 : * @return Dialog geometry as QByteArray.
154 : */
155 : static auto
156 : getDialogGeometry(const QString &key,
157 : const QByteArray &defaultValue = QVariant().toByteArray())
158 : -> QByteArray;
159 : /**
160 : * @brief Save dialog geometry.
161 : * @param key Dialog identifier.
162 : * @param geometry Dialog geometry to save.
163 : */
164 : static void setDialogGeometry(const QString &key, const QByteArray &geometry);
165 :
166 : // Password store settings
167 : /**
168 : * @brief Save use pass setting.
169 : * @param usePass true to use pass, false for GPG.
170 : */
171 : static void setUsePass(const bool &usePass);
172 :
173 : // UI settings
174 :
175 : /**
176 : * @brief Get autoclear delay in seconds.
177 : * @param defaultValue Integer returned if not saved.
178 : * @return Seconds before clipboard is cleared.
179 : */
180 : static auto getAutoclearSeconds(const int &defaultValue = QVariant().toInt())
181 : -> int;
182 : // Pass store path
183 : /**
184 : * @brief Get password store directory path.
185 : * @param defaultValue String returned if not saved.
186 : * @return Path to password store.
187 : */
188 : static auto getPassStore(const QString &defaultValue = QVariant().toString())
189 : -> QString;
190 : /**
191 : * @brief Save password store path.
192 : * @param passStore Path to password store.
193 : */
194 : static void setPassStore(const QString &passStore);
195 :
196 : // Executable paths
197 : /**
198 : * @brief Initialize executable paths by auto-detecting them.
199 : */
200 : static void initExecutables();
201 : /**
202 : * @brief Get pass executable path.
203 : * @param defaultValue String returned if not saved.
204 : * @return Path to pass executable.
205 : */
206 : static auto
207 : getPassExecutable(const QString &defaultValue = QVariant().toString())
208 : -> QString;
209 : /**
210 : * @brief Get active profile name.
211 : * @param defaultValue String returned if not saved.
212 : * @return Active profile name.
213 : */
214 : static auto getProfile(const QString &defaultValue = QVariant().toString())
215 : -> QString;
216 :
217 : /**
218 : * @brief Check whether Git integration is enabled.
219 : * @param defaultValue Value returned if not saved.
220 : * @return True if Git integration is enabled.
221 : */
222 : static auto isUseGit(const bool &defaultValue = QVariant().toBool()) -> bool;
223 : /**
224 : * @brief Check whether content search is enabled.
225 : * @param defaultValue Value returned if not saved (defaults to false).
226 : * @return True if grep search is enabled.
227 : */
228 : static auto isUseGrepSearch(const bool &defaultValue = false) -> bool;
229 : /**
230 : * @brief Check whether OTP support is enabled.
231 : * @param defaultValue Value returned if not saved (defaults to true).
232 : * @return True if OTP support is enabled.
233 : */
234 : static auto isUseOtp(const bool &defaultValue = true) -> bool;
235 : /**
236 : * @brief Save qrencode executable path.
237 : * @param qrencodeExecutable Path to qrencode executable.
238 : */
239 : static void setQrencodeExecutable(const QString &qrencodeExecutable);
240 :
241 : /**
242 : * @brief Get complete password generation configuration.
243 : * @return Password generation configuration.
244 : */
245 : static auto getPasswordConfiguration() -> PasswordConfiguration;
246 : /**
247 : * @brief Check whether closing the window hides the application.
248 : * @param defaultValue Value returned if not saved.
249 : * @return True if close action hides the application.
250 : */
251 : static auto isHideOnClose(const bool &defaultValue = QVariant().toBool())
252 : -> bool;
253 : /**
254 : * @brief Check whether main window should stay always on top.
255 : * @param defaultValue Value returned if not saved.
256 : * @return True if always-on-top is enabled.
257 : */
258 : static auto isAlwaysOnTop(const bool &defaultValue = QVariant().toBool())
259 : -> bool;
260 : /**
261 : * @brief Check whether automatic push is enabled.
262 : * @param defaultValue Value returned if not saved.
263 : * @return True if automatic push is enabled.
264 : */
265 : static auto isAutoPush(const bool &defaultValue = QVariant().toBool())
266 : -> bool;
267 : /**
268 : * @brief Get showProcessOutput setting.
269 : * @param defaultValue Default value if not set.
270 : * @return Whether process output should be displayed.
271 : */
272 : static auto isShowProcessOutput(const bool &defaultValue = false) -> bool;
273 : /**
274 : * @brief Get all configured profiles.
275 : * @return Profile map keyed by profile name.
276 : */
277 : static auto getProfiles() -> Profiles;
278 : /**
279 : * @brief Save all configured profiles.
280 : * @param profiles Profile map keyed by profile name.
281 : */
282 : static void setProfiles(const Profiles &profiles);
283 :
284 : /**
285 : * @brief Get currently active pass backend instance.
286 : * @return Pointer to pass backend.
287 : */
288 : static auto getPass() -> Pass *;
289 : /**
290 : * @brief Get real pass backend instance.
291 : * @return Pointer to real pass backend.
292 : */
293 : static auto getRealPass() -> RealPass *;
294 : /**
295 : * @brief Get imitate pass backend instance.
296 : * @return Pointer to imitate pass backend.
297 : */
298 : static auto getImitatePass() -> ImitatePass *;
299 : /**
300 : * @brief Whether no backend, the active one or one kept from before a
301 : * switch, runs or waits for anything (PassBackendFactory::isIdle()).
302 : * @return true when all are idle.
303 : */
304 : static auto backendsIdle() -> bool;
305 : };
306 :
307 : #endif // SRC_QTPASSSETTINGS_H_
|