keepassxc

Форк
0
/
ApplicationSettingsWidget.cpp 
563 строки · 28.5 Кб
1
/*
2
 *  Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
3
 *  Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 2 or (at your option)
8
 *  version 3 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
#include "ApplicationSettingsWidget.h"
20
#include "ui_ApplicationSettingsWidgetGeneral.h"
21
#include "ui_ApplicationSettingsWidgetSecurity.h"
22
#include <QDesktopServices>
23
#include <QDir>
24
#include <QToolTip>
25

26
#include "config-keepassx.h"
27

28
#include "autotype/AutoType.h"
29
#include "core/Translator.h"
30
#include "gui/Icons.h"
31
#include "gui/MainWindow.h"
32
#include "gui/osutils/OSUtils.h"
33
#include "quickunlock/QuickUnlockInterface.h"
34

35
#include "FileDialog.h"
36
#include "MessageBox.h"
37

38
class ApplicationSettingsWidget::ExtraPage
39
{
40
public:
41
    ExtraPage(ISettingsPage* page, QWidget* widget)
42
        : settingsPage(page)
43
        , widget(widget)
44
    {
45
    }
46

47
    void loadSettings() const
48
    {
49
        settingsPage->loadSettings(widget);
50
    }
51

52
    void saveSettings() const
53
    {
54
        settingsPage->saveSettings(widget);
55
    }
56

57
private:
58
    QSharedPointer<ISettingsPage> settingsPage;
59
    QWidget* widget;
60
};
61

62
/**
63
 * Helper class to ignore mouse wheel events on non-focused widgets
64
 * NOTE: The widget must NOT have a focus policy of "WHEEL"
65
 */
66
class MouseWheelEventFilter : public QObject
67
{
68
public:
69
    explicit MouseWheelEventFilter(QObject* parent)
70
        : QObject(parent){};
71

72
protected:
73
    bool eventFilter(QObject* obj, QEvent* event) override
74
    {
75
        const auto* widget = qobject_cast<QWidget*>(obj);
76
        if (event->type() == QEvent::Wheel && widget && !widget->hasFocus()) {
77
            event->ignore();
78
            return true;
79
        }
80
        return QObject::eventFilter(obj, event);
81
    }
82
};
83

84
ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
85
    : EditWidget(parent)
86
    , m_secWidget(new QWidget())
87
    , m_generalWidget(new QWidget())
88
    , m_secUi(new Ui::ApplicationSettingsWidgetSecurity())
89
    , m_generalUi(new Ui::ApplicationSettingsWidgetGeneral())
90
    , m_globalAutoTypeKey(static_cast<Qt::Key>(0))
91
    , m_globalAutoTypeModifiers(Qt::NoModifier)
92
{
93
    setHeadline(tr("Application Settings"));
94
    showApplyButton(false);
95

96
    m_secUi->setupUi(m_secWidget);
97
    m_generalUi->setupUi(m_generalWidget);
98
    addPage(tr("General"), icons()->icon("preferences-other"), m_generalWidget);
99
    addPage(tr("Security"), icons()->icon("security-high"), m_secWidget);
100

101
    if (!autoType()->isAvailable()) {
102
        m_generalUi->generalSettingsTabWidget->removeTab(1);
103
    }
104

105
    connect(this, SIGNAL(accepted()), SLOT(saveSettings()));
106
    connect(this, SIGNAL(rejected()), SLOT(reject()));
107

108
    // clang-format off
109
    connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)), SLOT(autoSaveToggled(bool)));
110
    connect(m_generalUi->hideWindowOnCopyCheckBox, SIGNAL(toggled(bool)), SLOT(hideWindowOnCopyCheckBoxToggled(bool)));
111
    connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), SLOT(systrayToggled(bool)));
112
    connect(m_generalUi->rememberLastDatabasesCheckBox, SIGNAL(toggled(bool)), SLOT(rememberDatabasesToggled(bool)));
113
    connect(m_generalUi->resetSettingsButton, SIGNAL(clicked()), SLOT(resetSettings()));
114
    connect(m_generalUi->useAlternativeSaveCheckBox, SIGNAL(toggled(bool)),
115
            m_generalUi->alternativeSaveComboBox, SLOT(setEnabled(bool)));
116

117
    connect(m_generalUi->backupBeforeSaveCheckBox, SIGNAL(toggled(bool)),
118
            m_generalUi->backupFilePath, SLOT(setEnabled(bool)));
119
    connect(m_generalUi->backupBeforeSaveCheckBox, SIGNAL(toggled(bool)),
120
            m_generalUi->backupFilePathPicker, SLOT(setEnabled(bool)));
121
    connect(m_generalUi->backupFilePathPicker, SIGNAL(pressed()), SLOT(selectBackupDirectory()));
122
    connect(m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox, SIGNAL(toggled(bool)),
123
            SLOT(showExpiredEntriesOnDatabaseUnlockToggled(bool)));
124

125
    connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
126
            m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
127
    connect(m_secUi->clearSearchCheckBox, SIGNAL(toggled(bool)),
128
            m_secUi->clearSearchSpinBox, SLOT(setEnabled(bool)));
129
    connect(m_secUi->lockDatabaseIdleCheckBox, SIGNAL(toggled(bool)),
130
            m_secUi->lockDatabaseIdleSpinBox, SLOT(setEnabled(bool)));
131
    // clang-format on
132

133
    connect(m_generalUi->minimizeAfterUnlockCheckBox, &QCheckBox::toggled, this, [this](bool state) {
134
        if (state) {
135
            m_secUi->lockDatabaseMinimizeCheckBox->setChecked(false);
136
        }
137
        m_secUi->lockDatabaseMinimizeCheckBox->setToolTip(
138
            state ? tr("This setting cannot be enabled when minimize on unlock is enabled.") : "");
139
        m_secUi->lockDatabaseMinimizeCheckBox->setEnabled(!state);
140
    });
141

142
    // Set Auto-Type shortcut when changed
143
    connect(
144
        m_generalUi->autoTypeShortcutWidget, &ShortcutWidget::shortcutChanged, this, [this](auto key, auto modifiers) {
145
            QString error;
146
            if (autoType()->registerGlobalShortcut(key, modifiers, &error)) {
147
                m_generalUi->autoTypeShortcutWidget->setStyleSheet("");
148
            } else {
149
                QToolTip::showText(mapToGlobal(rect().bottomLeft()), error);
150
                m_generalUi->autoTypeShortcutWidget->setStyleSheet("background-color: #FF9696;");
151
            }
152
        });
153
    connect(m_generalUi->autoTypeShortcutWidget, &ShortcutWidget::shortcutReset, this, [this] {
154
        autoType()->unregisterGlobalShortcut();
155
        m_generalUi->autoTypeShortcutWidget->setStyleSheet("");
156
    });
157

158
    // Disable mouse wheel grab when scrolling
159
    // This prevents combo box and spinner values from changing without explicit focus
160
    auto mouseWheelFilter = new MouseWheelEventFilter(this);
161
    m_generalUi->faviconTimeoutSpinBox->installEventFilter(mouseWheelFilter);
162
    m_generalUi->toolButtonStyleComboBox->installEventFilter(mouseWheelFilter);
163
    m_generalUi->languageComboBox->installEventFilter(mouseWheelFilter);
164
    m_generalUi->trayIconAppearance->installEventFilter(mouseWheelFilter);
165

166
#ifdef WITH_XC_UPDATECHECK
167
    connect(m_generalUi->checkForUpdatesOnStartupCheckBox, SIGNAL(toggled(bool)), SLOT(checkUpdatesToggled(bool)));
168
#else
169
    m_generalUi->checkForUpdatesOnStartupCheckBox->setVisible(false);
170
    m_generalUi->checkForUpdatesIncludeBetasCheckBox->setVisible(false);
171
    m_generalUi->checkUpdatesSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
172
#endif
173

174
#ifndef WITH_XC_NETWORKING
175
    m_secUi->privacy->setVisible(false);
176
    m_generalUi->faviconTimeoutLabel->setVisible(false);
177
    m_generalUi->faviconTimeoutSpinBox->setVisible(false);
178
#endif
179
}
180

181
ApplicationSettingsWidget::~ApplicationSettingsWidget() = default;
182

183
void ApplicationSettingsWidget::addSettingsPage(ISettingsPage* page)
184
{
185
    QWidget* widget = page->createWidget();
186
    widget->setParent(this);
187
    m_extraPages.append(ExtraPage(page, widget));
188
    addPage(page->name(), page->icon(), widget);
189
}
190

191
void ApplicationSettingsWidget::loadSettings()
192
{
193
    if (config()->hasAccessError()) {
194
        showMessage(tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
195
    }
196

197
#ifdef QT_DEBUG
198
    m_generalUi->singleInstanceCheckBox->setEnabled(false);
199
    m_generalUi->launchAtStartup->setEnabled(false);
200
#endif
201
    m_generalUi->singleInstanceCheckBox->setChecked(config()->get(Config::SingleInstance).toBool());
202
    m_generalUi->launchAtStartup->setChecked(osUtils->isLaunchAtStartupEnabled());
203
    m_generalUi->rememberLastDatabasesCheckBox->setChecked(config()->get(Config::RememberLastDatabases).toBool());
204
    m_generalUi->rememberLastDatabasesSpinbox->setValue(config()->get(Config::NumberOfRememberedLastDatabases).toInt());
205
    m_generalUi->rememberLastKeyFilesCheckBox->setChecked(config()->get(Config::RememberLastKeyFiles).toBool());
206
    m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked(
207
        config()->get(Config::OpenPreviousDatabasesOnStartup).toBool());
208
    m_generalUi->autoSaveAfterEveryChangeCheckBox->setChecked(config()->get(Config::AutoSaveAfterEveryChange).toBool());
209
    m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get(Config::AutoSaveOnExit).toBool());
210
    m_generalUi->autoSaveNonDataChangesCheckBox->setChecked(config()->get(Config::AutoSaveNonDataChanges).toBool());
211
    m_generalUi->backupBeforeSaveCheckBox->setChecked(config()->get(Config::BackupBeforeSave).toBool());
212

213
    m_generalUi->backupFilePath->setText(config()->get(Config::BackupFilePathPattern).toString());
214

215
    m_generalUi->useAlternativeSaveCheckBox->setChecked(!config()->get(Config::UseAtomicSaves).toBool());
216
    m_generalUi->alternativeSaveComboBox->setCurrentIndex(config()->get(Config::UseDirectWriteSaves).toBool() ? 1 : 0);
217
    m_generalUi->autoReloadOnChangeCheckBox->setChecked(config()->get(Config::AutoReloadOnChange).toBool());
218
    m_generalUi->minimizeAfterUnlockCheckBox->setChecked(config()->get(Config::MinimizeAfterUnlock).toBool());
219
    m_generalUi->minimizeOnOpenUrlCheckBox->setChecked(config()->get(Config::MinimizeOnOpenUrl).toBool());
220
    m_generalUi->hideWindowOnCopyCheckBox->setChecked(config()->get(Config::HideWindowOnCopy).toBool());
221
    hideWindowOnCopyCheckBoxToggled(m_generalUi->hideWindowOnCopyCheckBox->isChecked());
222
    m_generalUi->minimizeOnCopyRadioButton->setChecked(config()->get(Config::MinimizeOnCopy).toBool());
223
    m_generalUi->dropToBackgroundOnCopyRadioButton->setChecked(config()->get(Config::DropToBackgroundOnCopy).toBool());
224
    m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(
225
        config()->get(Config::UseGroupIconOnEntryCreation).toBool());
226
    m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryTitleMatch).toBool());
227
    m_generalUi->autoTypeEntryURLMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryURLMatch).toBool());
228
    m_generalUi->autoTypeHideExpiredEntryCheckBox->setChecked(config()->get(Config::AutoTypeHideExpiredEntry).toBool());
229
    m_generalUi->faviconTimeoutSpinBox->setValue(config()->get(Config::FaviconDownloadTimeout).toInt());
230

231
    m_generalUi->languageComboBox->clear();
232
    QList<QPair<QString, QString>> languages = Translator::availableLanguages();
233
    for (const auto& language : languages) {
234
        m_generalUi->languageComboBox->addItem(language.second, language.first);
235
    }
236
    int defaultIndex = m_generalUi->languageComboBox->findData(config()->get(Config::GUI_Language));
237
    if (defaultIndex > 0) {
238
        m_generalUi->languageComboBox->setCurrentIndex(defaultIndex);
239
    }
240

241
    m_generalUi->toolbarMovableCheckBox->setChecked(config()->get(Config::GUI_MovableToolbar).toBool());
242
    m_generalUi->monospaceNotesCheckBox->setChecked(config()->get(Config::GUI_MonospaceNotes).toBool());
243
    m_generalUi->colorPasswordsCheckBox->setChecked(config()->get(Config::GUI_ColorPasswords).toBool());
244

245
    m_generalUi->toolButtonStyleComboBox->clear();
246
    m_generalUi->toolButtonStyleComboBox->addItem(tr("Icon only"), Qt::ToolButtonIconOnly);
247
    m_generalUi->toolButtonStyleComboBox->addItem(tr("Text only"), Qt::ToolButtonTextOnly);
248
    m_generalUi->toolButtonStyleComboBox->addItem(tr("Text beside icon"), Qt::ToolButtonTextBesideIcon);
249
    m_generalUi->toolButtonStyleComboBox->addItem(tr("Text under icon"), Qt::ToolButtonTextUnderIcon);
250
    m_generalUi->toolButtonStyleComboBox->addItem(tr("Follow style"), Qt::ToolButtonFollowStyle);
251
    int toolButtonStyleIndex =
252
        m_generalUi->toolButtonStyleComboBox->findData(config()->get(Config::GUI_ToolButtonStyle));
253
    if (toolButtonStyleIndex > 0) {
254
        m_generalUi->toolButtonStyleComboBox->setCurrentIndex(toolButtonStyleIndex);
255
    }
256

257
    m_generalUi->systrayShowCheckBox->setChecked(config()->get(Config::GUI_ShowTrayIcon).toBool());
258
    systrayToggled(m_generalUi->systrayShowCheckBox->isChecked());
259
    m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get(Config::GUI_MinimizeToTray).toBool());
260
    m_generalUi->minimizeOnCloseCheckBox->setChecked(config()->get(Config::GUI_MinimizeOnClose).toBool());
261
    m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get(Config::GUI_MinimizeOnStartup).toBool());
262
    m_generalUi->checkForUpdatesOnStartupCheckBox->setChecked(config()->get(Config::GUI_CheckForUpdates).toBool());
263
    checkUpdatesToggled(m_generalUi->checkForUpdatesOnStartupCheckBox->isChecked());
264
    m_generalUi->checkForUpdatesIncludeBetasCheckBox->setChecked(
265
        config()->get(Config::GUI_CheckForUpdatesIncludeBetas).toBool());
266

267
    m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox->setChecked(
268
        config()->get(Config::GUI_ShowExpiredEntriesOnDatabaseUnlock).toBool());
269
    m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->setValue(
270
        config()->get(Config::GUI_ShowExpiredEntriesOnDatabaseUnlockOffsetDays).toInt());
271
    showExpiredEntriesOnDatabaseUnlockToggled(m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox->isChecked());
272

273
    m_generalUi->autoTypeAskCheckBox->setChecked(config()->get(Config::Security_AutoTypeAsk).toBool());
274
    m_generalUi->autoTypeRelockDatabaseCheckBox->setChecked(config()->get(Config::Security_RelockAutoType).toBool());
275

276
    if (autoType()->isAvailable()) {
277
        m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get(Config::GlobalAutoTypeKey).toInt());
278
        m_globalAutoTypeModifiers =
279
            static_cast<Qt::KeyboardModifiers>(config()->get(Config::GlobalAutoTypeModifiers).toInt());
280
        if (m_globalAutoTypeKey > 0 && m_globalAutoTypeModifiers > 0) {
281
            m_generalUi->autoTypeShortcutWidget->setShortcut(m_globalAutoTypeKey, m_globalAutoTypeModifiers);
282
        }
283
        m_generalUi->autoTypeRetypeTimeSpinBox->setValue(config()->get(Config::GlobalAutoTypeRetypeTime).toInt());
284
        m_generalUi->autoTypeShortcutWidget->setAttribute(Qt::WA_MacShowFocusRect, true);
285
        m_generalUi->autoTypeDelaySpinBox->setValue(config()->get(Config::AutoTypeDelay).toInt());
286
        m_generalUi->autoTypeStartDelaySpinBox->setValue(config()->get(Config::AutoTypeStartDelay).toInt());
287
    }
288

289
    m_generalUi->trayIconAppearance->clear();
290
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
291
    m_generalUi->trayIconAppearance->addItem(tr("Monochrome"), "monochrome");
292
#else
293
    m_generalUi->trayIconAppearance->addItem(tr("Monochrome (light)"), "monochrome-light");
294
    m_generalUi->trayIconAppearance->addItem(tr("Monochrome (dark)"), "monochrome-dark");
295
#endif
296
    m_generalUi->trayIconAppearance->addItem(tr("Colorful"), "colorful");
297
    int trayIconIndex = m_generalUi->trayIconAppearance->findData(icons()->trayIconAppearance());
298
    if (trayIconIndex > 0) {
299
        m_generalUi->trayIconAppearance->setCurrentIndex(trayIconIndex);
300
    }
301

302
    m_secUi->clearClipboardCheckBox->setChecked(config()->get(Config::Security_ClearClipboard).toBool());
303
    m_secUi->clearClipboardSpinBox->setValue(config()->get(Config::Security_ClearClipboardTimeout).toInt());
304

305
    m_secUi->clearSearchCheckBox->setChecked(config()->get(Config::Security_ClearSearch).toBool());
306
    m_secUi->clearSearchSpinBox->setValue(config()->get(Config::Security_ClearSearchTimeout).toInt());
307

308
    m_secUi->lockDatabaseIdleCheckBox->setChecked(config()->get(Config::Security_LockDatabaseIdle).toBool());
309
    m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get(Config::Security_LockDatabaseIdleSeconds).toInt());
310
    m_secUi->lockDatabaseMinimizeCheckBox->setChecked(m_secUi->lockDatabaseMinimizeCheckBox->isEnabled()
311
                                                      && config()->get(Config::Security_LockDatabaseMinimize).toBool());
312
    m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked(
313
        config()->get(Config::Security_LockDatabaseScreenLock).toBool());
314
    m_secUi->fallbackToSearch->setChecked(config()->get(Config::Security_IconDownloadFallback).toBool());
315

316
    m_secUi->passwordsHiddenCheckBox->setChecked(config()->get(Config::Security_PasswordsHidden).toBool());
317
    m_secUi->passwordShowDotsCheckBox->setChecked(config()->get(Config::Security_PasswordEmptyPlaceholder).toBool());
318
    m_secUi->passwordPreviewCleartextCheckBox->setChecked(
319
        config()->get(Config::Security_HidePasswordPreviewPanel).toBool());
320
    m_secUi->hideTotpCheckBox->setChecked(config()->get(Config::Security_HideTotpPreviewPanel).toBool());
321
    m_secUi->hideNotesCheckBox->setChecked(config()->get(Config::Security_HideNotes).toBool());
322
    m_secUi->NoConfirmMoveEntryToRecycleBinCheckBox->setChecked(
323
        config()->get(Config::Security_NoConfirmMoveEntryToRecycleBin).toBool());
324
    m_secUi->EnableCopyOnDoubleClickCheckBox->setChecked(
325
        config()->get(Config::Security_EnableCopyOnDoubleClick).toBool());
326

327
    m_secUi->quickUnlockCheckBox->setEnabled(getQuickUnlock()->isAvailable());
328
    m_secUi->quickUnlockCheckBox->setChecked(config()->get(Config::Security_QuickUnlock).toBool());
329

330
    for (const ExtraPage& page : asConst(m_extraPages)) {
331
        page.loadSettings();
332
    }
333

334
    setCurrentPage(0);
335
}
336

337
void ApplicationSettingsWidget::saveSettings()
338
{
339
    if (config()->hasAccessError()) {
340
        showMessage(tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
341
        // We prevent closing the settings page if we could not write to
342
        // the config file.
343
        return;
344
    }
345

346
#ifndef QT_DEBUG
347
    osUtils->setLaunchAtStartup(m_generalUi->launchAtStartup->isChecked());
348
#endif
349

350
    config()->set(Config::SingleInstance, m_generalUi->singleInstanceCheckBox->isChecked());
351
    config()->set(Config::RememberLastDatabases, m_generalUi->rememberLastDatabasesCheckBox->isChecked());
352
    config()->set(Config::NumberOfRememberedLastDatabases, m_generalUi->rememberLastDatabasesSpinbox->value());
353
    config()->set(Config::RememberLastKeyFiles, m_generalUi->rememberLastKeyFilesCheckBox->isChecked());
354
    config()->set(Config::OpenPreviousDatabasesOnStartup,
355
                  m_generalUi->openPreviousDatabasesOnStartupCheckBox->isChecked());
356
    config()->set(Config::AutoSaveAfterEveryChange, m_generalUi->autoSaveAfterEveryChangeCheckBox->isChecked());
357
    config()->set(Config::AutoSaveOnExit, m_generalUi->autoSaveOnExitCheckBox->isChecked());
358
    config()->set(Config::AutoSaveNonDataChanges, m_generalUi->autoSaveNonDataChangesCheckBox->isChecked());
359
    config()->set(Config::BackupBeforeSave, m_generalUi->backupBeforeSaveCheckBox->isChecked());
360

361
    config()->set(Config::BackupFilePathPattern, m_generalUi->backupFilePath->text());
362

363
    config()->set(Config::UseAtomicSaves, !m_generalUi->useAlternativeSaveCheckBox->isChecked());
364
    config()->set(Config::UseDirectWriteSaves, m_generalUi->alternativeSaveComboBox->currentIndex() == 1);
365
    config()->set(Config::AutoReloadOnChange, m_generalUi->autoReloadOnChangeCheckBox->isChecked());
366
    config()->set(Config::MinimizeAfterUnlock, m_generalUi->minimizeAfterUnlockCheckBox->isChecked());
367
    config()->set(Config::MinimizeOnOpenUrl, m_generalUi->minimizeOnOpenUrlCheckBox->isChecked());
368
    config()->set(Config::HideWindowOnCopy, m_generalUi->hideWindowOnCopyCheckBox->isChecked());
369
    config()->set(Config::MinimizeOnCopy, m_generalUi->minimizeOnCopyRadioButton->isChecked());
370
    config()->set(Config::DropToBackgroundOnCopy, m_generalUi->dropToBackgroundOnCopyRadioButton->isChecked());
371
    config()->set(Config::UseGroupIconOnEntryCreation, m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
372
    config()->set(Config::AutoTypeEntryTitleMatch, m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
373
    config()->set(Config::AutoTypeEntryURLMatch, m_generalUi->autoTypeEntryURLMatchCheckBox->isChecked());
374
    config()->set(Config::AutoTypeHideExpiredEntry, m_generalUi->autoTypeHideExpiredEntryCheckBox->isChecked());
375
    config()->set(Config::FaviconDownloadTimeout, m_generalUi->faviconTimeoutSpinBox->value());
376

377
    auto language = m_generalUi->languageComboBox->currentData().toString();
378
    if (config()->get(Config::GUI_Language) != language) {
379
        QTimer::singleShot(200, [] {
380
            getMainWindow()->restartApp(
381
                tr("You must restart the application to set the new language. Would you like to restart now?"));
382
        });
383
    }
384
    config()->set(Config::GUI_Language, language);
385

386
    config()->set(Config::GUI_MovableToolbar, m_generalUi->toolbarMovableCheckBox->isChecked());
387
    config()->set(Config::GUI_MonospaceNotes, m_generalUi->monospaceNotesCheckBox->isChecked());
388
    config()->set(Config::GUI_ColorPasswords, m_generalUi->colorPasswordsCheckBox->isChecked());
389

390
    config()->set(Config::GUI_ToolButtonStyle, m_generalUi->toolButtonStyleComboBox->currentData().toString());
391

392
    config()->set(Config::GUI_ShowTrayIcon, m_generalUi->systrayShowCheckBox->isChecked());
393
    config()->set(Config::GUI_TrayIconAppearance, m_generalUi->trayIconAppearance->currentData().toString());
394
    config()->set(Config::GUI_MinimizeToTray, m_generalUi->systrayMinimizeToTrayCheckBox->isChecked());
395
    config()->set(Config::GUI_MinimizeOnClose, m_generalUi->minimizeOnCloseCheckBox->isChecked());
396
    config()->set(Config::GUI_MinimizeOnStartup, m_generalUi->systrayMinimizeOnStartup->isChecked());
397
    config()->set(Config::GUI_CheckForUpdates, m_generalUi->checkForUpdatesOnStartupCheckBox->isChecked());
398
    config()->set(Config::GUI_CheckForUpdatesIncludeBetas,
399
                  m_generalUi->checkForUpdatesIncludeBetasCheckBox->isChecked());
400

401
    config()->set(Config::GUI_ShowExpiredEntriesOnDatabaseUnlock,
402
                  m_generalUi->showExpiredEntriesOnDatabaseUnlockCheckBox->isChecked());
403
    config()->set(Config::GUI_ShowExpiredEntriesOnDatabaseUnlockOffsetDays,
404
                  m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->value());
405

406
    config()->set(Config::Security_AutoTypeAsk, m_generalUi->autoTypeAskCheckBox->isChecked());
407
    config()->set(Config::Security_RelockAutoType, m_generalUi->autoTypeRelockDatabaseCheckBox->isChecked());
408

409
    if (autoType()->isAvailable()) {
410
        config()->set(Config::GlobalAutoTypeKey, m_generalUi->autoTypeShortcutWidget->key());
411
        config()->set(Config::GlobalAutoTypeModifiers,
412
                      static_cast<int>(m_generalUi->autoTypeShortcutWidget->modifiers()));
413
        config()->set(Config::GlobalAutoTypeRetypeTime, m_generalUi->autoTypeRetypeTimeSpinBox->value());
414
        config()->set(Config::AutoTypeDelay, m_generalUi->autoTypeDelaySpinBox->value());
415
        config()->set(Config::AutoTypeStartDelay, m_generalUi->autoTypeStartDelaySpinBox->value());
416
    }
417
    config()->set(Config::Security_ClearClipboard, m_secUi->clearClipboardCheckBox->isChecked());
418
    config()->set(Config::Security_ClearClipboardTimeout, m_secUi->clearClipboardSpinBox->value());
419

420
    config()->set(Config::Security_ClearSearch, m_secUi->clearSearchCheckBox->isChecked());
421
    config()->set(Config::Security_ClearSearchTimeout, m_secUi->clearSearchSpinBox->value());
422

423
    config()->set(Config::Security_LockDatabaseIdle, m_secUi->lockDatabaseIdleCheckBox->isChecked());
424
    config()->set(Config::Security_LockDatabaseIdleSeconds, m_secUi->lockDatabaseIdleSpinBox->value());
425
    config()->set(Config::Security_LockDatabaseMinimize, m_secUi->lockDatabaseMinimizeCheckBox->isChecked());
426
    config()->set(Config::Security_LockDatabaseScreenLock, m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked());
427
    config()->set(Config::Security_IconDownloadFallback, m_secUi->fallbackToSearch->isChecked());
428

429
    config()->set(Config::Security_PasswordsHidden, m_secUi->passwordsHiddenCheckBox->isChecked());
430
    config()->set(Config::Security_PasswordEmptyPlaceholder, m_secUi->passwordShowDotsCheckBox->isChecked());
431

432
    config()->set(Config::Security_HidePasswordPreviewPanel, m_secUi->passwordPreviewCleartextCheckBox->isChecked());
433
    config()->set(Config::Security_HideTotpPreviewPanel, m_secUi->hideTotpCheckBox->isChecked());
434
    config()->set(Config::Security_HideNotes, m_secUi->hideNotesCheckBox->isChecked());
435
    config()->set(Config::Security_NoConfirmMoveEntryToRecycleBin,
436
                  m_secUi->NoConfirmMoveEntryToRecycleBinCheckBox->isChecked());
437
    config()->set(Config::Security_EnableCopyOnDoubleClick, m_secUi->EnableCopyOnDoubleClickCheckBox->isChecked());
438

439
    if (m_secUi->quickUnlockCheckBox->isEnabled()) {
440
        config()->set(Config::Security_QuickUnlock, m_secUi->quickUnlockCheckBox->isChecked());
441
    }
442

443
    // Security: clear storage if related settings are disabled
444
    if (!config()->get(Config::RememberLastDatabases).toBool()) {
445
        config()->remove(Config::LastDir);
446
        config()->remove(Config::LastDatabases);
447
        config()->remove(Config::LastActiveDatabase);
448
    }
449

450
    if (!config()->get(Config::RememberLastKeyFiles).toBool()) {
451
        config()->remove(Config::LastDir);
452
        config()->remove(Config::LastKeyFiles);
453
        config()->remove(Config::LastChallengeResponse);
454
    }
455

456
    for (const ExtraPage& page : asConst(m_extraPages)) {
457
        page.saveSettings();
458
    }
459
}
460

461
void ApplicationSettingsWidget::resetSettings()
462
{
463
    // Confirm reset
464
    auto ans = MessageBox::question(this,
465
                                    tr("Reset Settings?"),
466
                                    tr("Are you sure you want to reset all general and security settings to default?"),
467
                                    MessageBox::Reset | MessageBox::Cancel,
468
                                    MessageBox::Cancel);
469
    if (ans == MessageBox::Cancel) {
470
        return;
471
    }
472

473
    if (config()->hasAccessError()) {
474
        showMessage(tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
475
        // We prevent closing the settings page if we could not write to
476
        // the config file.
477
        return;
478
    }
479

480
    // Reset general and security settings to default
481
    config()->resetToDefaults();
482

483
    // Clear recently used data
484
    config()->remove(Config::LastDatabases);
485
    config()->remove(Config::LastActiveDatabase);
486
    config()->remove(Config::LastKeyFiles);
487
    config()->remove(Config::LastDir);
488

489
    // Save the Extra Pages (these are NOT reset)
490
    for (const ExtraPage& page : asConst(m_extraPages)) {
491
        page.saveSettings();
492
    }
493

494
    config()->sync();
495

496
    // Refresh the settings widget and notify listeners
497
    loadSettings();
498
    emit settingsReset();
499
}
500

501
void ApplicationSettingsWidget::reject()
502
{
503
    // register the old key again as it might have changed
504
    if (m_globalAutoTypeKey > 0 && m_globalAutoTypeModifiers > 0) {
505
        autoType()->registerGlobalShortcut(m_globalAutoTypeKey, m_globalAutoTypeModifiers);
506
    }
507
}
508

509
void ApplicationSettingsWidget::autoSaveToggled(bool checked)
510
{
511
    // Explicitly enable other auto-save options
512
    if (checked) {
513
        m_generalUi->autoSaveOnExitCheckBox->setChecked(true);
514
        m_generalUi->autoSaveNonDataChangesCheckBox->setChecked(true);
515
    }
516
    m_generalUi->autoSaveOnExitCheckBox->setEnabled(!checked);
517
    m_generalUi->autoSaveNonDataChangesCheckBox->setEnabled(!checked);
518
}
519

520
void ApplicationSettingsWidget::hideWindowOnCopyCheckBoxToggled(bool checked)
521
{
522
    m_generalUi->minimizeOnCopyRadioButton->setEnabled(checked);
523
    m_generalUi->dropToBackgroundOnCopyRadioButton->setEnabled(checked);
524
}
525

526
void ApplicationSettingsWidget::systrayToggled(bool checked)
527
{
528
    m_generalUi->trayIconAppearance->setEnabled(checked);
529
    m_generalUi->trayIconAppearanceLabel->setEnabled(checked);
530
    m_generalUi->systrayMinimizeToTrayCheckBox->setEnabled(checked);
531
}
532

533
void ApplicationSettingsWidget::rememberDatabasesToggled(bool checked)
534
{
535
    if (!checked) {
536
        m_generalUi->rememberLastKeyFilesCheckBox->setChecked(false);
537
        m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked(false);
538
    }
539

540
    m_generalUi->rememberLastDatabasesSpinbox->setEnabled(checked);
541
    m_generalUi->rememberLastKeyFilesCheckBox->setEnabled(checked);
542
    m_generalUi->openPreviousDatabasesOnStartupCheckBox->setEnabled(checked);
543
}
544

545
void ApplicationSettingsWidget::checkUpdatesToggled(bool checked)
546
{
547
    m_generalUi->checkForUpdatesIncludeBetasCheckBox->setEnabled(checked);
548
}
549

550
void ApplicationSettingsWidget::showExpiredEntriesOnDatabaseUnlockToggled(bool checked)
551
{
552
    m_generalUi->showExpiredEntriesOnDatabaseUnlockOffsetSpinBox->setEnabled(checked);
553
}
554

555
void ApplicationSettingsWidget::selectBackupDirectory()
556
{
557
    auto backupDirectory =
558
        FileDialog::instance()->getExistingDirectory(this, tr("Select backup storage directory"), QDir::homePath());
559
    if (!backupDirectory.isEmpty()) {
560
        m_generalUi->backupFilePath->setText(
561
            QDir(backupDirectory).filePath(config()->getDefault(Config::BackupFilePathPattern).toString()));
562
    }
563
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.