From 596d2cf425c3c8495b4c4a58c61798afe9fdd536 Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Sun, 26 Apr 2020 01:31:38 +0200 Subject: [PATCH] Refactor Config. Replaces all string configuration options with enum types that can be checked by the compiler. This prevents spelling errors, in-place configuration definitions, and inconsistent default values. The default value config getter signature was removed in favour of consistently and centrally default-initialised configuration values. Individual default values were adjusted for better security, such as the default password length, which was increased from 16 characters to 32. The already existing config option deprecation map was extended by a general migration procedure using configuration versioning. Settings were split into Roaming and Local settings, which go to their respective AppData locations on Windows. Fixes #2574 Fixes #2193 --- src/autotype/AutoType.cpp | 10 +- src/autotype/AutoTypeSelectDialog.cpp | 4 +- src/browser/BrowserSettings.cpp | 148 +++--- src/core/Bootstrap.cpp | 8 +- src/core/Config.cpp | 502 +++++++++++++----- src/core/Config.h | 166 +++++- src/core/Group.cpp | 4 +- src/core/IconDownloader.cpp | 4 +- src/core/PasswordGenerator.h | 16 +- src/core/Resources.cpp | 2 +- src/core/Translator.cpp | 2 +- src/fdosecrets/FdoSecretsSettings.cpp | 17 +- src/gui/Application.cpp | 6 +- src/gui/ApplicationSettingsWidget.cpp | 260 ++++----- src/gui/Clipboard.cpp | 4 +- src/gui/DatabaseOpenWidget.cpp | 32 +- src/gui/DatabaseTabWidget.cpp | 14 +- src/gui/DatabaseWidget.cpp | 29 +- src/gui/DatabaseWidgetStateSync.cpp | 24 +- src/gui/EditWidgetIcons.cpp | 2 +- src/gui/EntryPreviewWidget.cpp | 16 +- src/gui/FileDialog.cpp | 12 +- src/gui/IconDownloaderDialog.cpp | 2 +- src/gui/MainWindow.cpp | 78 +-- src/gui/PasswordEdit.cpp | 4 +- src/gui/PasswordGeneratorWidget.cpp | 116 ++-- src/gui/SearchWidget.cpp | 8 +- src/gui/TotpDialog.cpp | 6 +- src/gui/TotpExportSettingsDialog.cpp | 6 +- src/gui/WelcomeWidget.cpp | 2 +- src/gui/dbsettings/DatabaseSettingsDialog.cpp | 4 +- src/gui/entry/EditEntryWidget.cpp | 16 +- src/gui/entry/EntryAttachmentsWidget.cpp | 8 +- src/gui/entry/EntryModel.cpp | 4 +- src/gui/group/EditGroupWidget.cpp | 2 +- src/keeshare/KeeShare.cpp | 25 +- src/keeshare/KeeShare.h | 3 +- src/keeshare/SettingsWidgetKeeShare.cpp | 10 +- src/keeshare/ShareObserver.cpp | 2 +- .../group/EditGroupWidgetKeeShare.cpp | 4 +- src/sshagent/SSHAgent.cpp | 12 +- src/updatecheck/UpdateChecker.cpp | 8 +- tests/TestAutoType.cpp | 12 +- tests/gui/TestGui.cpp | 14 +- tests/gui/TestGuiBrowser.cpp | 12 +- 45 files changed, 1002 insertions(+), 638 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 2a937363b..117df903b 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -234,7 +234,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c #endif } - Tools::wait(qMax(100, config()->get("AutoTypeStartDelay", 500).toInt())); + Tools::wait(qMax(100, config()->get(Config::AutoTypeStartDelay).toInt())); // Used only for selected entry auto-type if (!window) { @@ -339,7 +339,7 @@ void AutoType::performGlobalAutoType(const QList>& dbLi m_inGlobalAutoTypeDialog.unlock(); emit autotypeRejected(); - } else if ((matchList.size() == 1) && !config()->get("security/autotypeask").toBool()) { + } else if ((matchList.size() == 1) && !config()->get(Config::Security_AutoTypeAsk).toBool()) { executeAutoTypeActions(matchList.first().entry, nullptr, matchList.first().sequence, m_windowForGlobal); m_inGlobalAutoTypeDialog.unlock(); } else { @@ -390,7 +390,7 @@ bool AutoType::parseActions(const QString& actionSequence, const Entry* entry, Q { QString tmpl; bool inTmpl = false; - m_autoTypeDelay = qMax(config()->get("AutoTypeDelay").toInt(), 0); + m_autoTypeDelay = qMax(config()->get(Config::AutoTypeDelay).toInt(), 0); QString sequence = actionSequence; sequence.replace("{{}", "{LEFTBRACE}"); @@ -617,12 +617,12 @@ QList AutoType::autoTypeSequences(const Entry* entry, const QString& wi } } - if (config()->get("AutoTypeEntryTitleMatch").toBool() + if (config()->get(Config::AutoTypeEntryTitleMatch).toBool() && windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))) { sequenceList.append(entry->effectiveAutoTypeSequence()); } - if (config()->get("AutoTypeEntryURLMatch").toBool() + if (config()->get(Config::AutoTypeEntryURLMatch).toBool() && windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url()))) { sequenceList.append(entry->effectiveAutoTypeSequence()); } diff --git a/src/autotype/AutoTypeSelectDialog.cpp b/src/autotype/AutoTypeSelectDialog.cpp index 717b1eb5f..3b264b7bc 100644 --- a/src/autotype/AutoTypeSelectDialog.cpp +++ b/src/autotype/AutoTypeSelectDialog.cpp @@ -56,7 +56,7 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent) #else QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos()); #endif - QSize size = config()->get("GUI/AutoTypeSelectDialogSize", QSize(600, 250)).toSize(); + QSize size = config()->get(Config::GUI_AutoTypeSelectDialogSize).toSize(); size.setWidth(qMin(size.width(), screenGeometry.width())); size.setHeight(qMin(size.height(), screenGeometry.height())); resize(size); @@ -111,7 +111,7 @@ void AutoTypeSelectDialog::setMatchList(const QList& matchList) void AutoTypeSelectDialog::done(int r) { - config()->set("GUI/AutoTypeSelectDialogSize", size()); + config()->set(Config::GUI_AutoTypeSelectDialogSize, size()); QDialog::done(r); } diff --git a/src/browser/BrowserSettings.cpp b/src/browser/BrowserSettings.cpp index eb5d81d29..7fa80ea3b 100644 --- a/src/browser/BrowserSettings.cpp +++ b/src/browser/BrowserSettings.cpp @@ -34,62 +34,62 @@ BrowserSettings* BrowserSettings::instance() bool BrowserSettings::isEnabled() { - return config()->get("Browser/Enabled", false).toBool(); + return config()->get(Config::Browser_Enabled).toBool(); } void BrowserSettings::setEnabled(bool enabled) { - config()->set("Browser/Enabled", enabled); + config()->set(Config::Browser_Enabled, enabled); } bool BrowserSettings::showNotification() { - return config()->get("Browser/ShowNotification", true).toBool(); + return config()->get(Config::Browser_ShowNotification).toBool(); } void BrowserSettings::setShowNotification(bool showNotification) { - config()->set("Browser/ShowNotification", showNotification); + config()->set(Config::Browser_ShowNotification, showNotification); } bool BrowserSettings::bestMatchOnly() { - return config()->get("Browser/BestMatchOnly", false).toBool(); + return config()->get(Config::Browser_BestMatchOnly).toBool(); } void BrowserSettings::setBestMatchOnly(bool bestMatchOnly) { - config()->set("Browser/BestMatchOnly", bestMatchOnly); + config()->set(Config::Browser_BestMatchOnly, bestMatchOnly); } bool BrowserSettings::unlockDatabase() { - return config()->get("Browser/UnlockDatabase", true).toBool(); + return config()->get(Config::Browser_UnlockDatabase).toBool(); } void BrowserSettings::setUnlockDatabase(bool unlockDatabase) { - config()->set("Browser/UnlockDatabase", unlockDatabase); + config()->set(Config::Browser_UnlockDatabase, unlockDatabase); } bool BrowserSettings::matchUrlScheme() { - return config()->get("Browser/MatchUrlScheme", true).toBool(); + return config()->get(Config::Browser_MatchUrlScheme).toBool(); } void BrowserSettings::setMatchUrlScheme(bool matchUrlScheme) { - config()->set("Browser/MatchUrlScheme", matchUrlScheme); + config()->set(Config::Browser_MatchUrlScheme, matchUrlScheme); } bool BrowserSettings::sortByUsername() { - return config()->get("Browser/SortByUsername", false).toBool(); + return config()->get(Config::Browser_SortByUsername).toBool(); } void BrowserSettings::setSortByUsername(bool sortByUsername) { - config()->set("Browser/SortByUsername", sortByUsername); + config()->set(Config::Browser_SortByUsername, sortByUsername); } bool BrowserSettings::sortByTitle() @@ -104,82 +104,82 @@ void BrowserSettings::setSortByTitle(bool sortByUsertitle) bool BrowserSettings::alwaysAllowAccess() { - return config()->get("Browser/AlwaysAllowAccess", false).toBool(); + return config()->get(Config::Browser_AlwaysAllowAccess).toBool(); } void BrowserSettings::setAlwaysAllowAccess(bool alwaysAllowAccess) { - config()->set("Browser/AlwaysAllowAccess", alwaysAllowAccess); + config()->set(Config::Browser_AlwaysAllowAccess, alwaysAllowAccess); } bool BrowserSettings::alwaysAllowUpdate() { - return config()->get("Browser/AlwaysAllowUpdate", false).toBool(); + return config()->get(Config::Browser_AlwaysAllowUpdate).toBool(); } void BrowserSettings::setAlwaysAllowUpdate(bool alwaysAllowUpdate) { - config()->set("Browser/AlwaysAllowUpdate", alwaysAllowUpdate); + config()->set(Config::Browser_AlwaysAllowUpdate, alwaysAllowUpdate); } bool BrowserSettings::httpAuthPermission() { - return config()->get("Browser/HttpAuthPermission", false).toBool(); + return config()->get(Config::Browser_HttpAuthPermission).toBool(); } void BrowserSettings::setHttpAuthPermission(bool httpAuthPermission) { - config()->set("Browser/HttpAuthPermission", httpAuthPermission); + config()->set(Config::Browser_HttpAuthPermission, httpAuthPermission); } bool BrowserSettings::searchInAllDatabases() { - return config()->get("Browser/SearchInAllDatabases", false).toBool(); + return config()->get(Config::Browser_SearchInAllDatabases).toBool(); } void BrowserSettings::setSearchInAllDatabases(bool searchInAllDatabases) { - config()->set("Browser/SearchInAllDatabases", searchInAllDatabases); + config()->set(Config::Browser_SearchInAllDatabases, searchInAllDatabases); } bool BrowserSettings::supportKphFields() { - return config()->get("Browser/SupportKphFields", true).toBool(); + return config()->get(Config::Browser_SupportKphFields).toBool(); } void BrowserSettings::setSupportKphFields(bool supportKphFields) { - config()->set("Browser/SupportKphFields", supportKphFields); + config()->set(Config::Browser_SupportKphFields, supportKphFields); } bool BrowserSettings::noMigrationPrompt() { - return config()->get("Browser/NoMigrationPrompt", false).toBool(); + return config()->get(Config::Browser_NoMigrationPrompt).toBool(); } void BrowserSettings::setNoMigrationPrompt(bool prompt) { - config()->set("Browser/NoMigrationPrompt", prompt); + config()->set(Config::Browser_NoMigrationPrompt, prompt); } bool BrowserSettings::supportBrowserProxy() { - return config()->get("Browser/SupportBrowserProxy", true).toBool(); + return config()->get(Config::Browser_SupportBrowserProxy).toBool(); } void BrowserSettings::setSupportBrowserProxy(bool enabled) { - config()->set("Browser/SupportBrowserProxy", enabled); + config()->set(Config::Browser_SupportBrowserProxy, enabled); } bool BrowserSettings::useCustomProxy() { - return config()->get("Browser/UseCustomProxy", false).toBool(); + return config()->get(Config::Browser_UseCustomProxy).toBool(); } void BrowserSettings::setUseCustomProxy(bool enabled) { - config()->set("Browser/UseCustomProxy", enabled); + config()->set(Config::Browser_UseCustomProxy, enabled); } QString BrowserSettings::customProxyLocation() @@ -187,32 +187,32 @@ QString BrowserSettings::customProxyLocation() if (!useCustomProxy()) { return QString(); } - return config()->get("Browser/CustomProxyLocation", "").toString(); + return config()->get(Config::Browser_CustomProxyLocation).toString(); } void BrowserSettings::setCustomProxyLocation(const QString& location) { - config()->set("Browser/CustomProxyLocation", location); + config()->set(Config::Browser_CustomProxyLocation, location); } bool BrowserSettings::updateBinaryPath() { - return config()->get("Browser/UpdateBinaryPath", true).toBool(); + return config()->get(Config::Browser_UpdateBinaryPath).toBool(); } void BrowserSettings::setUpdateBinaryPath(bool enabled) { - config()->set("Browser/UpdateBinaryPath", enabled); + config()->set(Config::Browser_UpdateBinaryPath, enabled); } bool BrowserSettings::allowExpiredCredentials() { - return config()->get("Browser/AllowExpiredCredentials", false).toBool(); + return config()->get(Config::Browser_AllowExpiredCredentials).toBool(); } void BrowserSettings::setAllowExpiredCredentials(bool enabled) { - config()->set("Browser/AllowExpiredCredentials", enabled); + config()->set(Config::Browser_AllowExpiredCredentials, enabled); } bool BrowserSettings::chromeSupport() @@ -294,202 +294,202 @@ void BrowserSettings::setEdgeSupport(bool enabled) bool BrowserSettings::passwordUseNumbers() { - return config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool(); + return config()->get(Config::PasswordGenerator_Numbers).toBool(); } void BrowserSettings::setPasswordUseNumbers(bool useNumbers) { - config()->set("generator/Numbers", useNumbers); + config()->set(Config::PasswordGenerator_Numbers, useNumbers); } bool BrowserSettings::passwordUseLowercase() { - return config()->get("generator/LowerCase", PasswordGenerator::DefaultLower).toBool(); + return config()->get(Config::PasswordGenerator_LowerCase).toBool(); } void BrowserSettings::setPasswordUseLowercase(bool useLowercase) { - config()->set("generator/LowerCase", useLowercase); + config()->set(Config::PasswordGenerator_LowerCase, useLowercase); } bool BrowserSettings::passwordUseUppercase() { - return config()->get("generator/UpperCase", PasswordGenerator::DefaultUpper).toBool(); + return config()->get(Config::PasswordGenerator_UpperCase).toBool(); } void BrowserSettings::setPasswordUseUppercase(bool useUppercase) { - config()->set("generator/UpperCase", useUppercase); + config()->set(Config::PasswordGenerator_UpperCase, useUppercase); } bool BrowserSettings::passwordUseSpecial() { - return config()->get("generator/SpecialChars", PasswordGenerator::DefaultSpecial).toBool(); + return config()->get(Config::PasswordGenerator_SpecialChars).toBool(); } void BrowserSettings::setPasswordUseSpecial(bool useSpecial) { - config()->set("generator/SpecialChars", useSpecial); + config()->set(Config::PasswordGenerator_SpecialChars, useSpecial); } bool BrowserSettings::passwordUseBraces() { - return config()->get("generator/Braces", PasswordGenerator::DefaultBraces).toBool(); + return config()->get(Config::PasswordGenerator_Braces).toBool(); } void BrowserSettings::setPasswordUseBraces(bool useBraces) { - config()->set("generator/Braces", useBraces); + config()->set(Config::PasswordGenerator_Braces, useBraces); } bool BrowserSettings::passwordUsePunctuation() { - return config()->get("generator/Punctuation", PasswordGenerator::DefaultQuotes).toBool(); + return config()->get(Config::PasswordGenerator_Punctuation).toBool(); } void BrowserSettings::setPasswordUsePunctuation(bool usePunctuation) { - config()->set("generator/Punctuation", usePunctuation); + config()->set(Config::PasswordGenerator_Punctuation, usePunctuation); } bool BrowserSettings::passwordUseQuotes() { - return config()->get("generator/Quotes", PasswordGenerator::DefaultQuotes).toBool(); + return config()->get(Config::PasswordGenerator_Quotes).toBool(); } void BrowserSettings::setPasswordUseQuotes(bool useQuotes) { - config()->set("generator/Quotes", useQuotes); + config()->set(Config::PasswordGenerator_Quotes, useQuotes); } bool BrowserSettings::passwordUseDashes() { - return config()->get("generator/Dashes", PasswordGenerator::DefaultDashes).toBool(); + return config()->get(Config::PasswordGenerator_Dashes).toBool(); } void BrowserSettings::setPasswordUseDashes(bool useDashes) { - config()->set("generator/Dashes", useDashes); + config()->set(Config::PasswordGenerator_Dashes, useDashes); } bool BrowserSettings::passwordUseMath() { - return config()->get("generator/Math", PasswordGenerator::DefaultMath).toBool(); + return config()->get(Config::PasswordGenerator_Math).toBool(); } void BrowserSettings::setPasswordUseMath(bool useMath) { - config()->set("generator/Math", useMath); + config()->set(Config::PasswordGenerator_Math, useMath); } bool BrowserSettings::passwordUseLogograms() { - return config()->get("generator/Logograms", PasswordGenerator::DefaultLogograms).toBool(); + return config()->get(Config::PasswordGenerator_Logograms).toBool(); } void BrowserSettings::setPasswordUseLogograms(bool useLogograms) { - config()->set("generator/Logograms", useLogograms); + config()->set(Config::PasswordGenerator_Logograms, useLogograms); } bool BrowserSettings::passwordUseEASCII() { - return config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool(); + return config()->get(Config::PasswordGenerator_EASCII).toBool(); } void BrowserSettings::setPasswordUseEASCII(bool useEASCII) { - config()->set("generator/EASCII", useEASCII); + config()->set(Config::PasswordGenerator_EASCII, useEASCII); } bool BrowserSettings::advancedMode() { - return config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool(); + return config()->get(Config::PasswordGenerator_AdvancedMode).toBool(); } void BrowserSettings::setAdvancedMode(bool advancedMode) { - config()->set("generator/AdvancedMode", advancedMode); + config()->set(Config::PasswordGenerator_AdvancedMode, advancedMode); } QString BrowserSettings::passwordAdditionalChars() { - return config()->get("generator/AdditionalChars", PasswordGenerator::DefaultAdditionalChars).toString(); + return config()->get(Config::PasswordGenerator_AdditionalChars).toString(); } void BrowserSettings::setPasswordAdditionalChars(const QString& chars) { - config()->set("generator/AdditionalChars", chars); + config()->set(Config::PasswordGenerator_AdditionalChars, chars); } QString BrowserSettings::passwordExcludedChars() { - return config()->get("generator/ExcludedChars", PasswordGenerator::DefaultExcludedChars).toString(); + return config()->get(Config::PasswordGenerator_ExcludedChars).toString(); } void BrowserSettings::setPasswordExcludedChars(const QString& chars) { - config()->set("generator/ExcludedChars", chars); + config()->set(Config::PasswordGenerator_ExcludedChars, chars); } int BrowserSettings::passPhraseWordCount() { - return config()->get("generator/WordCount", PassphraseGenerator::DefaultWordCount).toInt(); + return config()->get(Config::PasswordGenerator_WordCount).toInt(); } void BrowserSettings::setPassPhraseWordCount(int wordCount) { - config()->set("generator/WordCount", wordCount); + config()->set(Config::PasswordGenerator_WordCount, wordCount); } QString BrowserSettings::passPhraseWordSeparator() { - return config()->get("generator/WordSeparator", PassphraseGenerator::DefaultSeparator).toString(); + return config()->get(Config::PasswordGenerator_WordSeparator).toString(); } void BrowserSettings::setPassPhraseWordSeparator(const QString& separator) { - config()->set("generator/WordSeparator", separator); + config()->set(Config::PasswordGenerator_WordSeparator, separator); } int BrowserSettings::generatorType() { - return config()->get("generator/Type", 0).toInt(); + return config()->get(Config::PasswordGenerator_Type).toInt(); } void BrowserSettings::setGeneratorType(int type) { - config()->set("generator/Type", type); + config()->set(Config::PasswordGenerator_Type, type); } bool BrowserSettings::passwordEveryGroup() { - return config()->get("generator/EnsureEvery", PasswordGenerator::DefaultFromEveryGroup).toBool(); + return config()->get(Config::PasswordGenerator_EnsureEvery).toBool(); } void BrowserSettings::setPasswordEveryGroup(bool everyGroup) { - config()->get("generator/EnsureEvery", everyGroup); + config()->set(Config::PasswordGenerator_EnsureEvery, everyGroup); } bool BrowserSettings::passwordExcludeAlike() { - return config()->get("generator/ExcludeAlike", PasswordGenerator::DefaultLookAlike).toBool(); + return config()->get(Config::PasswordGenerator_ExcludeAlike).toBool(); } void BrowserSettings::setPasswordExcludeAlike(bool excludeAlike) { - config()->set("generator/ExcludeAlike", excludeAlike); + config()->set(Config::PasswordGenerator_ExcludeAlike, excludeAlike); } int BrowserSettings::passwordLength() { - return config()->get("generator/Length", PasswordGenerator::DefaultLength).toInt(); + return config()->get(Config::PasswordGenerator_Length).toInt(); } void BrowserSettings::setPasswordLength(int length) { - config()->set("generator/Length", length); + config()->set(Config::PasswordGenerator_Length, length); m_passwordGenerator.setLength(length); } diff --git a/src/core/Bootstrap.cpp b/src/core/Bootstrap.cpp index 99b950928..3f5a67a05 100644 --- a/src/core/Bootstrap.cpp +++ b/src/core/Bootstrap.cpp @@ -100,7 +100,7 @@ namespace Bootstrap void restoreMainWindowState(MainWindow& mainWindow) { // start minimized if configured - if (config()->get("GUI/MinimizeOnStartup").toBool()) { + if (config()->get(Config::GUI_MinimizeOnStartup).toBool()) { #ifdef Q_OS_WIN mainWindow.showMinimized(); #else @@ -110,14 +110,14 @@ namespace Bootstrap mainWindow.bringToFront(); } - if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) { - const QStringList fileNames = config()->get("LastOpenedDatabases").toStringList(); + if (config()->get(Config::OpenPreviousDatabasesOnStartup).toBool()) { + const QStringList fileNames = config()->get(Config::LastOpenedDatabases).toStringList(); for (const QString& filename : fileNames) { if (!filename.isEmpty() && QFile::exists(filename)) { mainWindow.openDatabase(filename); } } - auto lastActiveFile = config()->get("LastActiveDatabase").toString(); + auto lastActiveFile = config()->get(Config::LastActiveDatabase).toString(); if (!lastActiveFile.isEmpty()) { mainWindow.openDatabase(lastActiveFile); } diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 5965367b1..f874d8fb2 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -1,6 +1,6 @@ /* + * Copyright (C) 2020 KeePassXC Team * Copyright (C) 2011 Felix Geyer - * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,40 +17,202 @@ */ #include "Config.h" +#include "Global.h" #include #include +#include #include +#include #include #include -/* - * Map of configuration file settings that are either deprecated, or have - * had their name changed. Entries in the map are of the form - * {oldName, newName} - * Set newName to empty string to remove the setting from the file. - */ -static const QMap deprecationMap = { - // >2.3.4 - {QStringLiteral("security/hidepassworddetails"), QStringLiteral("security/HidePasswordPreviewPanel")}, - // >2.3.4 - {QStringLiteral("GUI/HideDetailsView"), QStringLiteral("GUI/HidePreviewPanel")}, - // >2.3.4 - {QStringLiteral("GUI/DetailSplitterState"), QStringLiteral("GUI/PreviewSplitterState")}, - // >2.3.4 - {QStringLiteral("security/IconDownloadFallbackToGoogle"), QStringLiteral("security/IconDownloadFallback")}, +#define CONFIG_VERSION 1 +#define QS QStringLiteral + +enum ConfigType +{ + Local, + Roaming }; +struct ConfigDirective +{ + QString name; + ConfigType type; + QVariant defaultValue; +}; + +// clang-format off + +/** + * Map of legal config values, their type and default value. + */ +static const QHash configStrings = { + // General + {Config::SingleInstance,{QS("SingleInstance"), Roaming, true}}, + {Config::RememberLastDatabases,{QS("RememberLastDatabases"), Roaming, true}}, + {Config::NumberOfRememberedLastDatabases,{QS("NumberOfRememberedLastDatabases"), Roaming, 5}}, + {Config::RememberLastKeyFiles,{QS("RememberLastKeyFiles"), Roaming, true}}, + {Config::OpenPreviousDatabasesOnStartup,{QS("OpenPreviousDatabasesOnStartup"), Roaming, true}}, + {Config::AutoSaveAfterEveryChange,{QS("AutoSaveAfterEveryChange"), Roaming, true}}, + {Config::AutoReloadOnChange,{QS("AutoReloadOnChange"), Roaming, true}}, + {Config::AutoSaveOnExit,{QS("AutoSaveOnExit"), Roaming, true}}, + {Config::BackupBeforeSave,{QS("BackupBeforeSave"), Roaming, false}}, + {Config::UseAtomicSaves,{QS("UseAtomicSaves"), Roaming, true}}, + {Config::SearchLimitGroup,{QS("SearchLimitGroup"), Roaming, false}}, + {Config::MinimizeOnOpenUrl,{QS("MinimizeOnOpenUrl"), Roaming, false}}, + {Config::HideWindowOnCopy,{QS("HideWindowOnCopy"), Roaming, false}}, + {Config::MinimizeOnCopy,{QS("MinimizeOnCopy"), Roaming, true}}, + {Config::MinimizeAfterUnlock,{QS("MinimizeAfterUnlock"), Roaming, false}}, + {Config::DropToBackgroundOnCopy,{QS("DropToBackgroundOnCopy"), Roaming, false}}, + {Config::UseGroupIconOnEntryCreation,{QS("UseGroupIconOnEntryCreation"), Roaming, true}}, + {Config::AutoTypeEntryTitleMatch,{QS("AutoTypeEntryTitleMatch"), Roaming, true}}, + {Config::AutoTypeEntryURLMatch,{QS("AutoTypeEntryURLMatch"), Roaming, true}}, + {Config::AutoTypeDelay,{QS("AutoTypeDelay"), Roaming, 25}}, + {Config::AutoTypeStartDelay,{QS("AutoTypeStartDelay"), Roaming, 500}}, + {Config::GlobalAutoTypeKey,{QS("GlobalAutoTypeKey"), Roaming, 0}}, + {Config::GlobalAutoTypeModifiers,{QS("GlobalAutoTypeModifiers"), Roaming, 0}}, + {Config::IgnoreGroupExpansion,{QS("IgnoreGroupExpansion"), Roaming, true}}, + {Config::FaviconDownloadTimeout,{QS("FaviconDownloadTimeout"), Roaming, 10}}, + {Config::UpdateCheckMessageShown,{QS("UpdateCheckMessageShown"), Roaming, true}}, + {Config::UseTouchID,{QS("UseTouchID"), Roaming, false}}, + + {Config::LastDatabases, {QS("LastDatabases"), Local, {}}}, + {Config::LastKeyFiles, {QS("LastKeyFiles"), Local, {}}}, + {Config::LastChallengeResponse, {QS("LastChallengeResponse"), Local, {}}}, + {Config::LastActiveDatabase, {QS("LastActiveDatabase"), Local, {}}}, + {Config::LastOpenedDatabases, {QS("LastOpenedDatabases"), Local, {}}}, + {Config::LastDir, {QS("LastDir"), Local, QDir::homePath()}}, + {Config::LastAttachmentDir, {QS("LastAttachmentDir"), Local, {}}}, + + // GUI + {Config::GUI_Language, {QS("GUI/Language"), Roaming, QS("system")}}, + {Config::GUI_HideToolbar, {QS("GUI/HideToolbar"), Roaming, false}}, + {Config::GUI_MovableToolbar, {QS("GUI/MovableToolbar"), Roaming, false}}, + {Config::GUI_HidePreviewPanel, {QS("GUI/HidePreviewPanel"), Roaming, false}}, + {Config::GUI_ToolButtonStyle, {QS("GUI/ToolButtonStyle"), Roaming, Qt::ToolButtonIconOnly}}, + {Config::GUI_ShowTrayIcon, {QS("GUI/ShowTrayIcon"), Roaming, false}}, + {Config::GUI_DarkTrayIcon, {QS("GUI/DarkTrayIcon"), Roaming, false}}, + {Config::GUI_MinimizeToTray, {QS("GUI/MinimizeToTray"), Roaming, false}}, + {Config::GUI_MinimizeOnStartup, {QS("GUI/MinimizeOnStartup"), Roaming, false}}, + {Config::GUI_MinimizeOnClose, {QS("GUI/MinimizeOnClose"), Roaming, false}}, + {Config::GUI_HideUsernames, {QS("GUI/HideUsernames"), Roaming, false}}, + {Config::GUI_HidePasswords, {QS("GUI/HidePasswords"), Roaming, true}}, + {Config::GUI_AdvancedSettings, {QS("GUI/AdvancedSettings"), Roaming, false}}, + {Config::GUI_MonospaceNotes, {QS("GUI/MonospaceNotes"), Roaming, false}}, + {Config::GUI_ApplicationTheme, {QS("GUI/ApplicationTheme"), Roaming, QS("auto")}}, + {Config::GUI_CheckForUpdates, {QS("GUI/CheckForUpdates"), Roaming, true}}, + {Config::GUI_CheckForUpdatesIncludeBetas, {QS("GUI/CheckForUpdatesIncludeBetas"), Roaming, false}}, + + {Config::GUI_MainWindowGeometry, {QS("GUI/MainWindowGeometry"), Local, {}}}, + {Config::GUI_MainWindowState, {QS("GUI/MainWindowState"), Local, {}}}, + {Config::GUI_ListViewState, {QS("GUI/ListViewState"), Local, {}}}, + {Config::GUI_SearchViewState, {QS("GUI/SearchViewState"), Local, {}}}, + {Config::GUI_SplitterState, {QS("GUI/SplitterState"), Local, {}}}, + {Config::GUI_PreviewSplitterState, {QS("GUI/PreviewSplitterState"), Local, {}}}, + {Config::GUI_AutoTypeSelectDialogSize, {QS("GUI/AutoTypeSelectDialogSize"), Local, QSize(600, 250)}}, + {Config::GUI_CheckForUpdatesNextCheck, {QS("GUI/AutoTypeSelectDialogSize"), Local, 0}}, + + // Security + {Config::Security_ClearClipboard, {QS("Security/ClearClipboard"), Roaming, true}}, + {Config::Security_ClearClipboardTimeout, {QS("Security/ClearClipboardTimeout"), Roaming, 10}}, + {Config::Security_ClearSearch, {QS("Security/ClearSearch"), Roaming, true}}, + {Config::Security_ClearSearchTimeout, {QS("Security/ClearSearchTimeout"), Roaming, 5}}, + {Config::Security_HideNotes, {QS("Security/Security_HideNotes"), Roaming, false}}, + {Config::Security_LockDatabaseIdle, {QS("Security/LockDatabaseIdle"), Roaming, false}}, + {Config::Security_LockDatabaseIdleSeconds, {QS("Security/LockDatabaseIdleSeconds"), Roaming, 240}}, + {Config::Security_LockDatabaseMinimize, {QS("Security/LockDatabaseMinimize"), Roaming, false}}, + {Config::Security_LockDatabaseScreenLock, {QS("Security/LockDatabaseScreenLock"), Roaming, true}}, + {Config::Security_RelockAutoType, {QS("Security/RelockAutoType"), Roaming, false}}, + {Config::Security_PasswordsRepeat, {QS("Security/PasswordsRepeat"), Roaming, false}}, + {Config::Security_PasswordsCleartext, {QS("Security/PasswordsCleartext"), Roaming, false}}, + {Config::Security_PasswordEmptyNoDots, {QS("Security/PasswordEmptyNoDots"), Roaming, true}}, + {Config::Security_HidePasswordPreviewPanel, {QS("Security/HidePasswordPreviewPanel"), Roaming, true}}, + {Config::Security_AutoTypeAsk, {QS("Security/AutotypeAsk"), Roaming, true}}, + {Config::Security_IconDownloadFallback, {QS("Security/IconDownloadFallback"), Roaming, false}}, + {Config::Security_ResetTouchId, {QS("Security/ResetTouchId"), Roaming, false}}, + {Config::Security_ResetTouchIdTimeout, {QS("Security/ResetTouchIdTimeout"), Roaming, 30}}, + {Config::Security_ResetTouchIdScreenlock,{QS("Security/ResetTouchIdScreenlock"), Roaming, true}}, + + // Browser + {Config::Browser_Enabled, {QS("Browser/Enabled"), Roaming, false}}, + {Config::Browser_ShowNotification, {QS("Browser/ShowNotification"), Roaming, true}}, + {Config::Browser_BestMatchOnly, {QS("Browser/BestMatchOnly"), Roaming, false}}, + {Config::Browser_UnlockDatabase, {QS("Browser/UnlockDatabase"), Roaming, true}}, + {Config::Browser_MatchUrlScheme, {QS("Browser/MatchUrlScheme"), Roaming, true}}, + {Config::Browser_SortByUsername, {QS("Browser/SortByUsername"), Roaming, false}}, + {Config::Browser_SupportBrowserProxy, {QS("Browser/SupportBrowserProxy"), Roaming, true}}, + {Config::Browser_UseCustomProxy, {QS("Browser/UseCustomProxy"), Roaming, false}}, + {Config::Browser_CustomProxyLocation, {QS("Browser/CustomProxyLocation"), Roaming, {}}}, + {Config::Browser_UpdateBinaryPath, {QS("Browser/UpdateBinaryPath"), Roaming, true}}, + {Config::Browser_AllowExpiredCredentials, {QS("Browser/AllowExpiredCredentials"), Roaming, false}}, + {Config::Browser_AlwaysAllowAccess, {QS("Browser/AlwaysAllowAccess"), Roaming, false}}, + {Config::Browser_AlwaysAllowUpdate, {QS("Browser/AlwaysAllowUpdate"), Roaming, false}}, + {Config::Browser_HttpAuthPermission, {QS("Browser/HttpAuthPermission"), Roaming, false}}, + {Config::Browser_SearchInAllDatabases, {QS("Browser/SearchInAllDatabases"), Roaming, false}}, + {Config::Browser_SupportKphFields, {QS("Browser/SupportKphFields"), Roaming, true}}, + {Config::Browser_NoMigrationPrompt, {QS("Browser/NoMigrationPrompt"), Roaming, false}}, + + // SSHAgent + {Config::SSHAgent_Enabled, {QS("SSHAgent/Enabled"), Roaming, false}}, + {Config::SSHAgent_UseOpenSSH, {QS("SSHAgent/UseOpenSSH"), Roaming, false}}, + {Config::SSHAgent_AuthSockOverride, {QS("SSHAgent/AuthSockOverride"), Local, {}}}, + + // FdoSecrets + {Config::FdoSecrets_Enabled, {QS("FdoSecrets/Enabled"), Roaming, false}}, + {Config::FdoSecrets_ShowNotification, {QS("FdoSecrets/ShowNotification"), Roaming, true}}, + {Config::FdoSecrets_NoConfirmDeleteItem, {QS("FdoSecrets/NoConfirmDeleteItem"), Roaming, false}}, + + // KeeShare + {Config::KeeShare_QuietSuccess, {QS("KeeShare/QuietSuccess"), Roaming, false}}, + {Config::KeeShare_Own, {QS("KeeShare/Own"), Roaming, {}}}, + {Config::KeeShare_Foreign, {QS("KeeShare/Foreign"), Roaming, {}}}, + {Config::KeeShare_Active, {QS("KeeShare/Active"), Roaming, {}}}, + {Config::KeeShare_LastDir, {QS("KeeShare/LastDir"), Local, QDir::homePath()}}, + {Config::KeeShare_LastKeyDir, {QS("KeeShare/LastKeyDir"), Local, QDir::homePath()}}, + {Config::KeeShare_LastShareDir, {QS("KeeShare/LastShareDir"), Local, QDir::homePath()}}, + + // PasswordGenerator + {Config::PasswordGenerator_LowerCase, {QS("PasswordGenerator/LowerCase"), Roaming, true}}, + {Config::PasswordGenerator_UpperCase, {QS("PasswordGenerator/UpperCase"), Roaming, true}}, + {Config::PasswordGenerator_Numbers, {QS("PasswordGenerator/Numbers"), Roaming, true}}, + {Config::PasswordGenerator_EASCII, {QS("PasswordGenerator/EASCII"), Roaming, false}}, + {Config::PasswordGenerator_AdvancedMode, {QS("PasswordGenerator/AdvancedMode"), Roaming, false}}, + {Config::PasswordGenerator_SpecialChars, {QS("PasswordGenerator/SpecialChars"), Roaming, true}}, + {Config::PasswordGenerator_AdditionalChars, {QS("PasswordGenerator/AdditionalChars"), Roaming, true}}, + {Config::PasswordGenerator_Braces, {QS("PasswordGenerator/Braces"), Roaming, false}}, + {Config::PasswordGenerator_Punctuation, {QS("PasswordGenerator/Punctuation"), Roaming, false}}, + {Config::PasswordGenerator_Quotes, {QS("PasswordGenerator/Quotes"), Roaming, false}}, + {Config::PasswordGenerator_Dashes, {QS("PasswordGenerator/Dashes"), Roaming, false}}, + {Config::PasswordGenerator_Math, {QS("PasswordGenerator/Math"), Roaming, false}}, + {Config::PasswordGenerator_Logograms, {QS("PasswordGenerator/Logograms"), Roaming, false}}, + {Config::PasswordGenerator_ExcludedChars, {QS("PasswordGenerator/ExcludedChars"), Roaming, {}}}, + {Config::PasswordGenerator_ExcludeAlike, {QS("PasswordGenerator/ExcludeAlike"), Roaming, true}}, + {Config::PasswordGenerator_EnsureEvery, {QS("PasswordGenerator/EnsureEvery"), Roaming, true}}, + {Config::PasswordGenerator_Length, {QS("PasswordGenerator/Length"), Roaming, 20}}, + {Config::PasswordGenerator_WordCount, {QS("PasswordGenerator/WordCount"), Roaming, 7}}, + {Config::PasswordGenerator_WordSeparator, {QS("PasswordGenerator/WordSeparator"), Roaming, QS(" ")}}, + {Config::PasswordGenerator_WordList, {QS("PasswordGenerator/WordList"), Roaming, QS("eff_large.wordlist")}}, + {Config::PasswordGenerator_WordCase, {QS("PasswordGenerator/WordCase"), Roaming, 0}}, + {Config::PasswordGenerator_Type, {QS("PasswordGenerator/Type"), Roaming, 0}}, + + // Messages + {Config::Messages_NoLegacyKeyFileWarning, {QS("Messages/NoLegacyKeyFileWarning"), Roaming, false}}, + {Config::Messages_Qt55CompatibilityWarning, {QS("Messages/Messages_Qt55CompatibilityWarning"), Local, false}}}; + +// clang-format on + QPointer Config::m_instance(nullptr); -QVariant Config::get(const QString& key) +QVariant Config::get(ConfigKey key) { - return m_settings->value(key, m_defaults.value(key)); -} - -QVariant Config::get(const QString& key, const QVariant& defaultValue) -{ - return m_settings->value(key, defaultValue); + auto cfg = configStrings[key]; + auto defaultValue = configStrings[key].defaultValue; + if (m_localSettings && cfg.type == Local) { + return m_localSettings->value(cfg.name, defaultValue); + } + return m_settings->value(cfg.name, defaultValue); } bool Config::hasAccessError() @@ -63,18 +225,32 @@ QString Config::getFileName() return m_settings->fileName(); } -void Config::set(const QString& key, const QVariant& value) +void Config::set(ConfigKey key, const QVariant& value) { - if (m_settings->contains(key) && m_settings->value(key) == value) { + if (get(key) == value) { return; } - const bool surpressSignal = !m_settings->contains(key) && m_defaults.value(key) == value; - m_settings->setValue(key, value); - - if (!surpressSignal) { - emit changed(key); + auto cfg = configStrings[key]; + if (cfg.type == Local && m_localSettings) { + m_localSettings->setValue(cfg.name, value); + } else { + m_settings->setValue(cfg.name, value); } + + emit changed(key); +} + +void Config::remove(ConfigKey key) +{ + auto cfg = configStrings[key]; + if (cfg.type == Local && m_localSettings) { + m_localSettings->remove(cfg.name); + } else { + m_settings->remove(cfg.name); + } + + emit changed(key); } /** @@ -87,38 +263,143 @@ void Config::set(const QString& key, const QVariant& value) void Config::sync() { m_settings->sync(); + if (m_localSettings) { + m_localSettings->sync(); + } } void Config::resetToDefaults() { - for (const auto& setting : m_defaults.keys()) { - m_settings->setValue(setting, m_defaults.value(setting)); + m_settings->clear(); + if (m_localSettings) { + m_localSettings->clear(); } } -void Config::upgrade() +/** + * Map of configuration file settings that are either deprecated, or have + * had their name changed to their new config enum values. + * + * Set a value to Deleted to remove the setting. + */ +static const QHash deprecationMap = { + // 2.3.4 + {QS("security/hidepassworddetails"), Config::Security_HidePasswordPreviewPanel}, + {QS("GUI/HideDetailsView"), Config::GUI_HidePreviewPanel}, + {QS("GUI/DetailSplitterState"), Config::GUI_PreviewSplitterState}, + {QS("security/IconDownloadFallbackToGoogle"), Config::Security_IconDownloadFallback}, + + // 2.6.0 + {QS("security/autotypeask"), Config::Security_AutoTypeAsk}, + {QS("security/clearclipboard"), Config::Security_ClearClipboard}, + {QS("security/clearclipboardtimeout"), Config::Security_ClearClipboardTimeout}, + {QS("security/clearsearch"), Config::Security_ClearSearch}, + {QS("security/clearsearchtimeout"), Config::Security_ClearSearchTimeout}, + {QS("security/lockdatabaseidle"), Config::Security_LockDatabaseIdle}, + {QS("security/lockdatabaseidlesec"), Config::Security_LockDatabaseIdleSeconds}, + {QS("security/lockdatabaseminimize"), Config::Security_LockDatabaseMinimize}, + {QS("security/lockdatabasescreenlock"), Config::Security_LockDatabaseScreenLock}, + {QS("security/relockautotype"), Config::Security_RelockAutoType}, + {QS("security/IconDownloadFallback"), Config::Security_IconDownloadFallback}, + {QS("security/passwordscleartext"), Config::Security_PasswordsCleartext}, + {QS("security/passwordemptynodots"), Config::Security_PasswordEmptyNoDots}, + {QS("security/HidePasswordPreviewPanel"), Config::Security_HidePasswordPreviewPanel}, + {QS("security/passwordsrepeat"), Config::Security_PasswordsRepeat}, + {QS("security/hidenotes"), Config::Security_HideNotes}, + {QS("security/resettouchid"), Config::Security_ResetTouchId}, + {QS("security/resettouchidtimeout"), Config::Security_ResetTouchIdTimeout}, + {QS("security/resettouchidscreenlock"), Config::Security_ResetTouchIdScreenlock}, + {QS("KeeShare/Settings.own"), Config::KeeShare_Own}, + {QS("KeeShare/Settings.foreign"), Config::KeeShare_Foreign}, + {QS("KeeShare/Settings.active"), Config::KeeShare_Active}, + {QS("SSHAgent"), Config::SSHAgent_Enabled}, + {QS("SSHAgentOpenSSH"), Config::SSHAgent_UseOpenSSH}, + {QS("SSHAuthSockOverride"), Config::SSHAgent_AuthSockOverride}, + {QS("generator/LowerCase"), Config::PasswordGenerator_LowerCase}, + {QS("generator/UpperCase"), Config::PasswordGenerator_UpperCase}, + {QS("generator/Numbers"), Config::PasswordGenerator_Numbers}, + {QS("generator/EASCII"), Config::PasswordGenerator_EASCII}, + {QS("generator/AdvancedMode"), Config::PasswordGenerator_AdvancedMode}, + {QS("generator/SpecialChars"), Config::PasswordGenerator_SpecialChars}, + {QS("generator/AdditionalChars"), Config::PasswordGenerator_AdditionalChars}, + {QS("generator/Braces"), Config::PasswordGenerator_Braces}, + {QS("generator/Punctuation"), Config::PasswordGenerator_Punctuation}, + {QS("generator/Quotes"), Config::PasswordGenerator_Quotes}, + {QS("generator/Dashes"), Config::PasswordGenerator_Dashes}, + {QS("generator/Math"), Config::PasswordGenerator_Math}, + {QS("generator/Logograms"), Config::PasswordGenerator_Logograms}, + {QS("generator/ExcludedChars"), Config::PasswordGenerator_ExcludedChars}, + {QS("generator/ExcludeAlike"), Config::PasswordGenerator_ExcludeAlike}, + {QS("generator/EnsureEvery"), Config::PasswordGenerator_EnsureEvery}, + {QS("generator/Length"), Config::PasswordGenerator_Length}, + {QS("generator/WordCount"), Config::PasswordGenerator_WordCount}, + {QS("generator/WordSeparator"), Config::PasswordGenerator_WordSeparator}, + {QS("generator/WordList"), Config::PasswordGenerator_WordList}, + {QS("generator/WordCase"), Config::PasswordGenerator_WordCase}, + {QS("generator/Type"), Config::PasswordGenerator_Type}, + {QS("QtErrorMessageShown"), Config::Messages_Qt55CompatibilityWarning}}; + +/** + * Migrate settings from previous versions. + */ +void Config::migrate() { - const auto keys = deprecationMap.keys(); - for (const auto& setting : keys) { + int previousVersion = m_settings->value("ConfigVersion").toInt(); + if (CONFIG_VERSION <= previousVersion) { + return; + } + + // Update renamed keys and drop obsolete keys + for (const auto& setting : deprecationMap.keys()) { + QVariant value; if (m_settings->contains(setting)) { - if (!deprecationMap.value(setting).isEmpty()) { - // Add entry with new name and old entry's value - m_settings->setValue(deprecationMap.value(setting), m_settings->value(setting)); - } + value = m_settings->value(setting); m_settings->remove(setting); + } else if (m_localSettings && m_localSettings->contains(setting)) { + value = m_localSettings->value(setting); + m_localSettings->remove(setting); + } else { + continue; } + + if (deprecationMap[setting] == Config::Deleted) { + continue; + } + + set(deprecationMap[setting], value); } - // > 2.3.4 - if (m_settings->value("AutoSaveAfterEveryChange").toBool()) { - m_settings->setValue("AutoSaveOnExit", true); + // Move local settings to separate file + if (m_localSettings) + for (const auto& setting : asConst(configStrings)) { + if (setting.type == Local && m_settings->contains(setting.name)) { + m_localSettings->setValue(setting.name, m_settings->value(setting.name)); + m_settings->remove(setting.name); + } + } + + // Detailed version migrations + + // pre 2.6.0 (no versioned configs) + if (previousVersion < 1) { + + // 2.3.4 + if (get(AutoSaveAfterEveryChange).toBool()) { + set(AutoSaveOnExit, true); + } + + // Setting defaults for 'hide window on copy' behavior, keeping the user's original setting + if (get(HideWindowOnCopy).isNull()) { + set(HideWindowOnCopy, get(MinimizeOnCopy).toBool()); + set(MinimizeOnCopy, true); + } + + // Reset database columns if upgrading from pre 2.6.0 + remove(GUI_ListViewState); } - // Setting defaults for 'hide window on copy' behavior, keeping the user's original setting - if (m_settings->value("HideWindowOnCopy").isNull()) { - m_settings->setValue("HideWindowOnCopy", m_settings->value("MinimizeOnCopy").toBool()); - m_settings->setValue("MinimizeOnCopy", true); - } + m_settings->setValue("ConfigVersion", CONFIG_VERSION); + sync(); } Config::Config(const QString& fileName, QObject* parent) @@ -130,109 +411,64 @@ Config::Config(const QString& fileName, QObject* parent) Config::Config(QObject* parent) : QObject(parent) { - // Check if portable config is present. If not, find it in user's directory - QString portablePath = QCoreApplication::applicationDirPath() + "/keepassxc.ini"; + // Check if portable config is present (use it also to store local config) + QString portablePath = QDir::fromNativeSeparators(QCoreApplication::applicationDirPath()) + "/keepassxc.ini"; if (QFile::exists(portablePath)) { init(portablePath); - } else { - QString userPath; - QString homePath = QDir::homePath(); + return; + } -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - // we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME - QByteArray env = qgetenv("XDG_CONFIG_HOME"); - if (env.isEmpty()) { - userPath = homePath; - userPath += "/.config"; - } else if (env[0] == '/') { - userPath = QFile::decodeName(env); - } else { - userPath = homePath; - userPath += '/'; - userPath += QFile::decodeName(env); - } + QString configPath; + QString localConfigPath; - userPath += "/keepassxc/"; +#if defined(Q_OS_WIN) + configPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + localConfigPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); +#elif defined(Q_OS_MACOS) + configPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + localConfigPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); #else - userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); - // storageLocation() appends the application name ("/keepassxc") to the end - userPath += "/"; + configPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + localConfigPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); #endif + configPath += "/keepassxc"; + localConfigPath += "/keepassxc"; + #ifdef QT_DEBUG - userPath += "keepassxc_debug.ini"; -#else - userPath += "keepassxc.ini"; + configPath += "_debug"; + localConfigPath += "_debug"; #endif - init(userPath); - } + configPath += ".ini"; + localConfigPath += ".ini"; + + init(QDir::toNativeSeparators(configPath), QDir::toNativeSeparators(localConfigPath)); } Config::~Config() { } -void Config::init(const QString& fileName) +void Config::init(const QString& configFileName, const QString& localConfigFileName) { - m_settings.reset(new QSettings(fileName, QSettings::IniFormat)); - upgrade(); - connect(qApp, &QCoreApplication::aboutToQuit, this, &Config::sync); + // Upgrade from previous KeePassXC version which stores its config + // in AppData/Local on Windows instead of AppData/Roaming. + // Move file to correct location before continuing. + if (!localConfigFileName.isEmpty() && QFile::exists(localConfigFileName) && !QFile::exists(configFileName)) { + QDir().mkpath(QFileInfo(configFileName).absolutePath()); + QFile::copy(localConfigFileName, configFileName); + QFile::remove(localConfigFileName); + QDir().rmdir(QFileInfo(localConfigFileName).absolutePath()); + } - m_defaults.insert("SingleInstance", true); - m_defaults.insert("RememberLastDatabases", true); - m_defaults.insert("NumberOfRememberedLastDatabases", 5); - m_defaults.insert("RememberLastKeyFiles", true); - m_defaults.insert("OpenPreviousDatabasesOnStartup", true); - m_defaults.insert("AutoSaveAfterEveryChange", true); - m_defaults.insert("AutoReloadOnChange", true); - m_defaults.insert("AutoSaveOnExit", true); - m_defaults.insert("BackupBeforeSave", false); - m_defaults.insert("UseAtomicSaves", true); - m_defaults.insert("SearchLimitGroup", false); - m_defaults.insert("MinimizeOnOpenUrl", false); - m_defaults.insert("HideWindowOnCopy", false); - m_defaults.insert("MinimizeOnCopy", true); - m_defaults.insert("MinimizeAfterUnlock", false); - m_defaults.insert("DropToBackgroundOnCopy", false); - m_defaults.insert("UseGroupIconOnEntryCreation", false); - m_defaults.insert("AutoTypeEntryTitleMatch", true); - m_defaults.insert("AutoTypeEntryURLMatch", true); - m_defaults.insert("AutoTypeDelay", 25); - m_defaults.insert("AutoTypeStartDelay", 500); - m_defaults.insert("UseGroupIconOnEntryCreation", true); - m_defaults.insert("IgnoreGroupExpansion", true); - m_defaults.insert("FaviconDownloadTimeout", 10); - m_defaults.insert("security/clearclipboard", true); - m_defaults.insert("security/clearclipboardtimeout", 10); - m_defaults.insert("security/clearsearch", true); - m_defaults.insert("security/clearsearchtimeout", 5); - m_defaults.insert("security/lockdatabaseidle", false); - m_defaults.insert("security/lockdatabaseidlesec", 240); - m_defaults.insert("security/lockdatabaseminimize", false); - m_defaults.insert("security/lockdatabasescreenlock", true); - m_defaults.insert("security/passwordsrepeat", false); - m_defaults.insert("security/passwordscleartext", false); - m_defaults.insert("security/passwordemptynodots", true); - m_defaults.insert("security/HidePasswordPreviewPanel", true); - m_defaults.insert("security/autotypeask", true); - m_defaults.insert("security/IconDownloadFallback", false); - m_defaults.insert("security/resettouchid", false); - m_defaults.insert("security/resettouchidtimeout", 30); - m_defaults.insert("security/resettouchidscreenlock", true); - m_defaults.insert("GUI/Language", "system"); - m_defaults.insert("GUI/HideToolbar", false); - m_defaults.insert("GUI/MovableToolbar", false); - m_defaults.insert("GUI/ToolButtonStyle", Qt::ToolButtonIconOnly); - m_defaults.insert("GUI/ShowTrayIcon", false); - m_defaults.insert("GUI/DarkTrayIcon", false); - m_defaults.insert("GUI/MinimizeToTray", false); - m_defaults.insert("GUI/MinimizeOnClose", false); - m_defaults.insert("GUI/HideUsernames", false); - m_defaults.insert("GUI/HidePasswords", true); - m_defaults.insert("GUI/AdvancedSettings", false); - m_defaults.insert("GUI/MonospaceNotes", false); - m_defaults.insert("GUI/ApplicationTheme", "auto"); + m_settings.reset(new QSettings(configFileName, QSettings::IniFormat)); + if (!localConfigFileName.isEmpty() && configFileName != localConfigFileName) { + m_localSettings.reset(new QSettings(localConfigFileName, QSettings::IniFormat)); + } + + migrate(); + connect(qApp, &QCoreApplication::aboutToQuit, this, &Config::sync); } Config* Config::instance() @@ -264,3 +500,5 @@ void Config::createTempFileInstance() m_instance = new Config(tmpFile->fileName(), qApp); tmpFile->setParent(m_instance); } + +#undef QS diff --git a/src/core/Config.h b/src/core/Config.h index ef6dd6af1..0914f1cbe 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -1,6 +1,6 @@ /* + * Copyright (C) 2020 KeePassXC Team * Copyright (C) 2011 Felix Geyer - * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,11 +32,160 @@ class Config : public QObject public: Q_DISABLE_COPY(Config) + enum ConfigKey + { + SingleInstance, + RememberLastDatabases, + NumberOfRememberedLastDatabases, + RememberLastKeyFiles, + OpenPreviousDatabasesOnStartup, + AutoSaveAfterEveryChange, + AutoReloadOnChange, + AutoSaveOnExit, + BackupBeforeSave, + UseAtomicSaves, + SearchLimitGroup, + MinimizeOnOpenUrl, + HideWindowOnCopy, + MinimizeOnCopy, + MinimizeAfterUnlock, + DropToBackgroundOnCopy, + UseGroupIconOnEntryCreation, + AutoTypeEntryTitleMatch, + AutoTypeEntryURLMatch, + AutoTypeDelay, + AutoTypeStartDelay, + GlobalAutoTypeKey, + GlobalAutoTypeModifiers, + IgnoreGroupExpansion, + FaviconDownloadTimeout, + UpdateCheckMessageShown, + UseTouchID, + + LastDatabases, + LastKeyFiles, + LastChallengeResponse, + LastActiveDatabase, + LastOpenedDatabases, + LastDir, + LastAttachmentDir, + + GUI_Language, + GUI_HideToolbar, + GUI_MovableToolbar, + GUI_HidePreviewPanel, + GUI_ToolButtonStyle, + GUI_ShowTrayIcon, + GUI_DarkTrayIcon, + GUI_MinimizeToTray, + GUI_MinimizeOnStartup, + GUI_MinimizeOnClose, + GUI_HideUsernames, + GUI_HidePasswords, + GUI_AdvancedSettings, + GUI_MonospaceNotes, + GUI_ApplicationTheme, + GUI_CheckForUpdates, + GUI_CheckForUpdatesIncludeBetas, + + GUI_MainWindowGeometry, + GUI_MainWindowState, + GUI_ListViewState, + GUI_SearchViewState, + GUI_PreviewSplitterState, + GUI_SplitterState, + GUI_AutoTypeSelectDialogSize, + GUI_CheckForUpdatesNextCheck, + + Security_ClearClipboard, + Security_ClearClipboardTimeout, + Security_ClearSearch, + Security_ClearSearchTimeout, + Security_HideNotes, + Security_LockDatabaseIdle, + Security_LockDatabaseIdleSeconds, + Security_LockDatabaseMinimize, + Security_LockDatabaseScreenLock, + Security_RelockAutoType, + Security_PasswordsRepeat, + Security_PasswordsCleartext, + Security_PasswordEmptyNoDots, + Security_HidePasswordPreviewPanel, + Security_AutoTypeAsk, + Security_IconDownloadFallback, + Security_ResetTouchId, + Security_ResetTouchIdTimeout, + Security_ResetTouchIdScreenlock, + + Browser_Enabled, + Browser_ShowNotification, + Browser_BestMatchOnly, + Browser_UnlockDatabase, + Browser_MatchUrlScheme, + Browser_SortByUsername, + Browser_SupportBrowserProxy, + Browser_UseCustomProxy, + Browser_CustomProxyLocation, + Browser_UpdateBinaryPath, + Browser_AllowExpiredCredentials, + Browser_AlwaysAllowAccess, + Browser_AlwaysAllowUpdate, + Browser_HttpAuthPermission, + Browser_SearchInAllDatabases, + Browser_SupportKphFields, + Browser_NoMigrationPrompt, + + SSHAgent_Enabled, + SSHAgent_UseOpenSSH, + SSHAgent_AuthSockOverride, + + FdoSecrets_Enabled, + FdoSecrets_ShowNotification, + FdoSecrets_NoConfirmDeleteItem, + + KeeShare_QuietSuccess, + KeeShare_Own, + KeeShare_Foreign, + KeeShare_Active, + KeeShare_LastDir, + KeeShare_LastKeyDir, + KeeShare_LastShareDir, + + PasswordGenerator_LowerCase, + PasswordGenerator_UpperCase, + PasswordGenerator_Numbers, + PasswordGenerator_EASCII, + PasswordGenerator_AdvancedMode, + PasswordGenerator_SpecialChars, + PasswordGenerator_AdditionalChars, + PasswordGenerator_Braces, + PasswordGenerator_Punctuation, + PasswordGenerator_Quotes, + PasswordGenerator_Dashes, + PasswordGenerator_Math, + PasswordGenerator_Logograms, + PasswordGenerator_ExcludedChars, + PasswordGenerator_ExcludeAlike, + PasswordGenerator_EnsureEvery, + PasswordGenerator_Length, + PasswordGenerator_WordCount, + PasswordGenerator_WordSeparator, + PasswordGenerator_WordList, + PasswordGenerator_WordCase, + PasswordGenerator_Type, + + Messages_NoLegacyKeyFileWarning, + Messages_Qt55CompatibilityWarning, + + // Special internal value + Deleted + }; + ~Config() override; - QVariant get(const QString& key); - QVariant get(const QString& key, const QVariant& defaultValue); + QVariant get(ConfigKey key); QString getFileName(); - void set(const QString& key, const QVariant& value); + void set(ConfigKey key, const QVariant& value); + void remove(ConfigKey key); bool hasAccessError(); void sync(); void resetToDefaults(); @@ -46,17 +195,18 @@ public: static void createTempFileInstance(); signals: - void changed(const QString& key); + void changed(ConfigKey key); private: - Config(const QString& fileName, QObject* parent); + Config(const QString& fileName, QObject* parent = nullptr); explicit Config(QObject* parent); - void init(const QString& fileName); - void upgrade(); + void init(const QString& configFileName, const QString& localConfigFileName = ""); + void migrate(); static QPointer m_instance; QScopedPointer m_settings; + QScopedPointer m_localSettings; QHash m_defaults; }; diff --git a/src/core/Group.cpp b/src/core/Group.cpp index eb795f950..acb6d114d 100644 --- a/src/core/Group.cpp +++ b/src/core/Group.cpp @@ -364,7 +364,7 @@ void Group::setExpanded(bool expanded) { if (m_data.isExpanded != expanded) { m_data.isExpanded = expanded; - if (config()->get("IgnoreGroupExpansion").toBool()) { + if (config()->get(Config::IgnoreGroupExpansion).toBool()) { updateTimeinfo(); return; } @@ -1112,7 +1112,7 @@ void Group::applyGroupIconOnCreateTo(Entry* entry) { Q_ASSERT(entry); - if (!config()->get("UseGroupIconOnEntryCreation").toBool()) { + if (!config()->get(Config::UseGroupIconOnEntryCreation).toBool()) { return; } diff --git a/src/core/IconDownloader.cpp b/src/core/IconDownloader.cpp index 1d9bd01ad..1dccc554c 100644 --- a/src/core/IconDownloader.cpp +++ b/src/core/IconDownloader.cpp @@ -103,7 +103,7 @@ void IconDownloader::setUrl(const QString& entryUrl) } // Start with the "fallback" url (if enabled) to try to get the best favicon - if (config()->get("security/IconDownloadFallback", false).toBool()) { + if (config()->get(Config::Security_IconDownloadFallback).toBool()) { QUrl fallbackUrl = QUrl("https://icons.duckduckgo.com"); fallbackUrl.setPath("/ip3/" + QUrl::toPercentEncoding(fullyQualifiedDomain) + ".ico"); m_urlsToTry.append(fallbackUrl); @@ -131,7 +131,7 @@ void IconDownloader::download() } if (!m_timeout.isActive()) { - int timeout = config()->get("FaviconDownloadTimeout", 10).toInt(); + int timeout = config()->get(Config::FaviconDownloadTimeout).toInt(); m_timeout.start(timeout * 1000); // Use the first URL to start the download process diff --git a/src/core/PasswordGenerator.h b/src/core/PasswordGenerator.h index 20681c233..308142563 100644 --- a/src/core/PasswordGenerator.h +++ b/src/core/PasswordGenerator.h @@ -67,23 +67,9 @@ public: QString generatePassword() const; - static const int DefaultLength = 16; + static const int DefaultLength = 32; static const char* DefaultAdditionalChars; static const char* DefaultExcludedChars; - static constexpr bool DefaultLower = (DefaultCharset & LowerLetters) != 0; - static constexpr bool DefaultUpper = (DefaultCharset & UpperLetters) != 0; - static constexpr bool DefaultNumbers = (DefaultCharset & Numbers) != 0; - static constexpr bool DefaultSpecial = (DefaultCharset & SpecialCharacters) != 0; - static constexpr bool DefaultAdvancedMode = (DefaultFlags & AdvancedMode) != 0; - static constexpr bool DefaultBraces = (DefaultCharset & Braces) != 0; - static constexpr bool DefaultPunctuation = (DefaultCharset & Punctuation) != 0; - static constexpr bool DefaultQuotes = (DefaultCharset & Quotes) != 0; - static constexpr bool DefaultDashes = (DefaultCharset & Dashes) != 0; - static constexpr bool DefaultMath = (DefaultCharset & Math) != 0; - static constexpr bool DefaultLogograms = (DefaultCharset & Logograms) != 0; - static constexpr bool DefaultEASCII = (DefaultCharset & EASCII) != 0; - static constexpr bool DefaultLookAlike = (DefaultFlags & ExcludeLookAlike) != 0; - static constexpr bool DefaultFromEveryGroup = (DefaultFlags & CharFromEveryGroup) != 0; private: QVector passwordGroups() const; diff --git a/src/core/Resources.cpp b/src/core/Resources.cpp index 90bc117ae..5f13a7cdf 100644 --- a/src/core/Resources.cpp +++ b/src/core/Resources.cpp @@ -217,7 +217,7 @@ bool Resources::testResourceDir(const QString& dir) bool Resources::useDarkIcon() { - return config()->get("GUI/DarkTrayIcon").toBool(); + return config()->get(Config::GUI_DarkTrayIcon).toBool(); } Resources* Resources::instance() diff --git a/src/core/Translator.cpp b/src/core/Translator.cpp index 28dc6aa68..e90d63837 100644 --- a/src/core/Translator.cpp +++ b/src/core/Translator.cpp @@ -35,7 +35,7 @@ void Translator::installTranslators() { QStringList languages; - QString languageSetting = config()->get("GUI/Language").toString(); + QString languageSetting = config()->get(Config::GUI_Language).toString(); if (languageSetting.isEmpty() || languageSetting == "system") { // NOTE: this is a workaround for the terrible way Qt loads languages // using the QLocale::uiLanguages() approach. Instead, we search each diff --git a/src/fdosecrets/FdoSecretsSettings.cpp b/src/fdosecrets/FdoSecretsSettings.cpp index 36c41705f..20eff4a08 100644 --- a/src/fdosecrets/FdoSecretsSettings.cpp +++ b/src/fdosecrets/FdoSecretsSettings.cpp @@ -24,11 +24,6 @@ namespace Keys { - - constexpr auto FdoSecretsEnabled = "FdoSecrets/Enabled"; - constexpr auto FdoSecretsShowNotification = "FdoSecrets/ShowNotification"; - constexpr auto FdoSecretsNoConfirmDeleteItem = "FdoSecrets/NoConfirmDeleteItem"; - namespace Db { constexpr auto FdoSecretsExposedGroup = "FDO_SECRETS_EXPOSED_GROUP"; @@ -51,32 +46,32 @@ namespace FdoSecrets bool FdoSecretsSettings::isEnabled() const { - return config()->get(Keys::FdoSecretsEnabled, false).toBool(); + return config()->get(Config::FdoSecrets_Enabled).toBool(); } void FdoSecretsSettings::setEnabled(bool enabled) { - config()->set(Keys::FdoSecretsEnabled, enabled); + config()->set(Config::FdoSecrets_Enabled, enabled); } bool FdoSecretsSettings::showNotification() const { - return config()->get(Keys::FdoSecretsShowNotification, true).toBool(); + return config()->get(Config::FdoSecrets_ShowNotification).toBool(); } void FdoSecretsSettings::setShowNotification(bool show) { - config()->set(Keys::FdoSecretsShowNotification, show); + config()->set(Config::FdoSecrets_ShowNotification, show); } bool FdoSecretsSettings::noConfirmDeleteItem() const { - return config()->get(Keys::FdoSecretsNoConfirmDeleteItem, false).toBool(); + return config()->get(Config::FdoSecrets_NoConfirmDeleteItem).toBool(); } void FdoSecretsSettings::setNoConfirmDeleteItem(bool noConfirm) { - config()->set(Keys::FdoSecretsNoConfirmDeleteItem, noConfirm); + config()->set(Config::FdoSecrets_NoConfirmDeleteItem, noConfirm); } QUuid FdoSecretsSettings::exposedGroup(const QSharedPointer& db) const diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp index 7a2e956fc..4a382567e 100644 --- a/src/gui/Application.cpp +++ b/src/gui/Application.cpp @@ -68,7 +68,7 @@ Application::Application(int& argc, char** argv) registerUnixSignals(); #endif - QString appTheme = config()->get("GUI/ApplicationTheme").toString(); + QString appTheme = config()->get(Config::GUI_ApplicationTheme).toString(); if (appTheme == "auto") { if (osUtils->isDarkMode()) { setStyle(new DarkStyle); @@ -119,7 +119,7 @@ Application::Application(int& argc, char** argv) m_lockServer.listen(m_socketName); break; case QLockFile::LockFailedError: { - if (config()->get("SingleInstance").toBool()) { + if (config()->get(Config::SingleInstance).toBool()) { // Attempt to connect to the existing instance QLocalSocket client; for (int i = 0; i < 3; ++i) { @@ -280,7 +280,7 @@ bool Application::isAlreadyRunning() const // In DEBUG mode we can run unlimited instances return false; #endif - return config()->get("SingleInstance").toBool() && m_alreadyRunning; + return config()->get(Config::SingleInstance).toBool() && m_alreadyRunning; } bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames) diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index b9e5638a7..7f4c10ce3 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -174,26 +174,27 @@ void ApplicationSettingsWidget::loadSettings() #ifdef QT_DEBUG m_generalUi->singleInstanceCheckBox->setEnabled(false); #endif - m_generalUi->singleInstanceCheckBox->setChecked(config()->get("SingleInstance").toBool()); - m_generalUi->rememberLastDatabasesCheckBox->setChecked(config()->get("RememberLastDatabases").toBool()); - m_generalUi->rememberLastKeyFilesCheckBox->setChecked(config()->get("RememberLastKeyFiles").toBool()); + m_generalUi->singleInstanceCheckBox->setChecked(config()->get(Config::SingleInstance).toBool()); + m_generalUi->rememberLastDatabasesCheckBox->setChecked(config()->get(Config::RememberLastDatabases).toBool()); + m_generalUi->rememberLastKeyFilesCheckBox->setChecked(config()->get(Config::RememberLastKeyFiles).toBool()); m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked( - config()->get("OpenPreviousDatabasesOnStartup").toBool()); - m_generalUi->autoSaveAfterEveryChangeCheckBox->setChecked(config()->get("AutoSaveAfterEveryChange").toBool()); - m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool()); - m_generalUi->backupBeforeSaveCheckBox->setChecked(config()->get("BackupBeforeSave").toBool()); - m_generalUi->useAtomicSavesCheckBox->setChecked(config()->get("UseAtomicSaves").toBool()); - m_generalUi->autoReloadOnChangeCheckBox->setChecked(config()->get("AutoReloadOnChange").toBool()); - m_generalUi->minimizeAfterUnlockCheckBox->setChecked(config()->get("MinimizeAfterUnlock").toBool()); - m_generalUi->minimizeOnOpenUrlCheckBox->setChecked(config()->get("MinimizeOnOpenUrl").toBool()); - m_generalUi->hideWindowOnCopyCheckBox->setChecked(config()->get("HideWindowOnCopy").toBool()); - m_generalUi->minimizeOnCopyRadioButton->setChecked(config()->get("MinimizeOnCopy").toBool()); - m_generalUi->dropToBackgroundOnCopyRadioButton->setChecked(config()->get("DropToBackgroundOnCopy").toBool()); - m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool()); - m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool()); - m_generalUi->autoTypeEntryURLMatchCheckBox->setChecked(config()->get("AutoTypeEntryURLMatch").toBool()); - m_generalUi->ignoreGroupExpansionCheckBox->setChecked(config()->get("IgnoreGroupExpansion").toBool()); - m_generalUi->faviconTimeoutSpinBox->setValue(config()->get("FaviconDownloadTimeout").toInt()); + config()->get(Config::OpenPreviousDatabasesOnStartup).toBool()); + m_generalUi->autoSaveAfterEveryChangeCheckBox->setChecked(config()->get(Config::AutoSaveAfterEveryChange).toBool()); + m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get(Config::AutoSaveOnExit).toBool()); + m_generalUi->backupBeforeSaveCheckBox->setChecked(config()->get(Config::BackupBeforeSave).toBool()); + m_generalUi->useAtomicSavesCheckBox->setChecked(config()->get(Config::UseAtomicSaves).toBool()); + m_generalUi->autoReloadOnChangeCheckBox->setChecked(config()->get(Config::AutoReloadOnChange).toBool()); + m_generalUi->minimizeAfterUnlockCheckBox->setChecked(config()->get(Config::MinimizeAfterUnlock).toBool()); + m_generalUi->minimizeOnOpenUrlCheckBox->setChecked(config()->get(Config::MinimizeOnOpenUrl).toBool()); + m_generalUi->hideWindowOnCopyCheckBox->setChecked(config()->get(Config::HideWindowOnCopy).toBool()); + m_generalUi->minimizeOnCopyRadioButton->setChecked(config()->get(Config::MinimizeOnCopy).toBool()); + m_generalUi->dropToBackgroundOnCopyRadioButton->setChecked(config()->get(Config::DropToBackgroundOnCopy).toBool()); + m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked( + config()->get(Config::UseGroupIconOnEntryCreation).toBool()); + m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryTitleMatch).toBool()); + m_generalUi->autoTypeEntryURLMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryURLMatch).toBool()); + m_generalUi->ignoreGroupExpansionCheckBox->setChecked(config()->get(Config::IgnoreGroupExpansion).toBool()); + m_generalUi->faviconTimeoutSpinBox->setValue(config()->get(Config::FaviconDownloadTimeout).toInt()); if (!m_generalUi->hideWindowOnCopyCheckBox->isChecked()) { hideWindowOnCopyCheckBoxToggled(false); @@ -204,15 +205,15 @@ void ApplicationSettingsWidget::loadSettings() for (const auto& language : languages) { m_generalUi->languageComboBox->addItem(language.second, language.first); } - int defaultIndex = m_generalUi->languageComboBox->findData(config()->get("GUI/Language")); + int defaultIndex = m_generalUi->languageComboBox->findData(config()->get(Config::GUI_Language)); if (defaultIndex > 0) { m_generalUi->languageComboBox->setCurrentIndex(defaultIndex); } - m_generalUi->previewHideCheckBox->setChecked(config()->get("GUI/HidePreviewPanel").toBool()); - m_generalUi->toolbarHideCheckBox->setChecked(config()->get("GUI/HideToolbar").toBool()); - m_generalUi->toolbarMovableCheckBox->setChecked(config()->get("GUI/MovableToolbar").toBool()); - m_generalUi->monospaceNotesCheckBox->setChecked(config()->get("GUI/MonospaceNotes").toBool()); + m_generalUi->previewHideCheckBox->setChecked(config()->get(Config::GUI_HidePreviewPanel).toBool()); + m_generalUi->toolbarHideCheckBox->setChecked(config()->get(Config::GUI_HideToolbar).toBool()); + m_generalUi->toolbarMovableCheckBox->setChecked(config()->get(Config::GUI_MovableToolbar).toBool()); + m_generalUi->monospaceNotesCheckBox->setChecked(config()->get(Config::GUI_MonospaceNotes).toBool()); m_generalUi->appThemeSelection->clear(); m_generalUi->appThemeSelection->addItem(tr("Automatic"), QStringLiteral("auto")); @@ -220,7 +221,7 @@ void ApplicationSettingsWidget::loadSettings() m_generalUi->appThemeSelection->addItem(tr("Dark"), QStringLiteral("dark")); m_generalUi->appThemeSelection->addItem(tr("Classic (Platform-native)"), QStringLiteral("classic")); m_generalUi->appThemeSelection->setCurrentIndex( - m_generalUi->appThemeSelection->findData(config()->get("GUI/ApplicationTheme").toString())); + m_generalUi->appThemeSelection->findData(config()->get(Config::GUI_ApplicationTheme).toString())); m_generalUi->toolButtonStyleComboBox->clear(); m_generalUi->toolButtonStyleComboBox->addItem(tr("Icon only"), Qt::ToolButtonIconOnly); @@ -228,55 +229,59 @@ void ApplicationSettingsWidget::loadSettings() m_generalUi->toolButtonStyleComboBox->addItem(tr("Text beside icon"), Qt::ToolButtonTextBesideIcon); m_generalUi->toolButtonStyleComboBox->addItem(tr("Text under icon"), Qt::ToolButtonTextUnderIcon); m_generalUi->toolButtonStyleComboBox->addItem(tr("Follow style"), Qt::ToolButtonFollowStyle); - int toolButtonStyleIndex = m_generalUi->toolButtonStyleComboBox->findData(config()->get("GUI/ToolButtonStyle")); + int toolButtonStyleIndex = + m_generalUi->toolButtonStyleComboBox->findData(config()->get(Config::GUI_ToolButtonStyle)); if (toolButtonStyleIndex > 0) { m_generalUi->toolButtonStyleComboBox->setCurrentIndex(toolButtonStyleIndex); } - m_generalUi->systrayShowCheckBox->setChecked(config()->get("GUI/ShowTrayIcon").toBool()); - m_generalUi->systrayDarkIconCheckBox->setChecked(config()->get("GUI/DarkTrayIcon").toBool()); - m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool()); - m_generalUi->minimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool()); - m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get("GUI/MinimizeOnStartup").toBool()); - m_generalUi->checkForUpdatesOnStartupCheckBox->setChecked(config()->get("GUI/CheckForUpdates").toBool()); + m_generalUi->systrayShowCheckBox->setChecked(config()->get(Config::GUI_ShowTrayIcon).toBool()); + m_generalUi->systrayDarkIconCheckBox->setChecked(config()->get(Config::GUI_DarkTrayIcon).toBool()); + m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get(Config::GUI_MinimizeToTray).toBool()); + m_generalUi->minimizeOnCloseCheckBox->setChecked(config()->get(Config::GUI_MinimizeOnClose).toBool()); + m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get(Config::GUI_MinimizeOnStartup).toBool()); + m_generalUi->checkForUpdatesOnStartupCheckBox->setChecked(config()->get(Config::GUI_CheckForUpdates).toBool()); m_generalUi->checkForUpdatesIncludeBetasCheckBox->setChecked( - config()->get("GUI/CheckForUpdatesIncludeBetas").toBool()); - m_generalUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool()); + config()->get(Config::GUI_CheckForUpdatesIncludeBetas).toBool()); + m_generalUi->autoTypeAskCheckBox->setChecked(config()->get(Config::Security_AutoTypeAsk).toBool()); if (autoType()->isAvailable()) { - m_globalAutoTypeKey = static_cast(config()->get("GlobalAutoTypeKey").toInt()); + m_globalAutoTypeKey = static_cast(config()->get(Config::GlobalAutoTypeKey).toInt()); m_globalAutoTypeModifiers = - static_cast(config()->get("GlobalAutoTypeModifiers").toInt()); + static_cast(config()->get(Config::GlobalAutoTypeModifiers).toInt()); if (m_globalAutoTypeKey > 0 && m_globalAutoTypeModifiers > 0) { m_generalUi->autoTypeShortcutWidget->setShortcut(m_globalAutoTypeKey, m_globalAutoTypeModifiers); } m_generalUi->autoTypeShortcutWidget->setAttribute(Qt::WA_MacShowFocusRect, true); - m_generalUi->autoTypeDelaySpinBox->setValue(config()->get("AutoTypeDelay").toInt()); - m_generalUi->autoTypeStartDelaySpinBox->setValue(config()->get("AutoTypeStartDelay").toInt()); + m_generalUi->autoTypeDelaySpinBox->setValue(config()->get(Config::AutoTypeDelay).toInt()); + m_generalUi->autoTypeStartDelaySpinBox->setValue(config()->get(Config::AutoTypeStartDelay).toInt()); } - m_secUi->clearClipboardCheckBox->setChecked(config()->get("security/clearclipboard").toBool()); - m_secUi->clearClipboardSpinBox->setValue(config()->get("security/clearclipboardtimeout").toInt()); + m_secUi->clearClipboardCheckBox->setChecked(config()->get(Config::Security_ClearClipboard).toBool()); + m_secUi->clearClipboardSpinBox->setValue(config()->get(Config::Security_ClearClipboardTimeout).toInt()); - m_secUi->clearSearchCheckBox->setChecked(config()->get("security/clearsearch").toBool()); - m_secUi->clearSearchSpinBox->setValue(config()->get("security/clearsearchtimeout").toInt()); + m_secUi->clearSearchCheckBox->setChecked(config()->get(Config::Security_ClearSearch).toBool()); + m_secUi->clearSearchSpinBox->setValue(config()->get(Config::Security_ClearSearchTimeout).toInt()); - m_secUi->lockDatabaseIdleCheckBox->setChecked(config()->get("security/lockdatabaseidle").toBool()); - m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get("security/lockdatabaseidlesec").toInt()); - m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get("security/lockdatabaseminimize").toBool()); - m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked(config()->get("security/lockdatabasescreenlock").toBool()); - m_secUi->relockDatabaseAutoTypeCheckBox->setChecked(config()->get("security/relockautotype").toBool()); - m_secUi->fallbackToSearch->setChecked(config()->get("security/IconDownloadFallback").toBool()); + m_secUi->lockDatabaseIdleCheckBox->setChecked(config()->get(Config::Security_LockDatabaseIdle).toBool()); + m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get(Config::Security_LockDatabaseIdleSeconds).toInt()); + m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get(Config::Security_LockDatabaseMinimize).toBool()); + m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked( + config()->get(Config::Security_LockDatabaseScreenLock).toBool()); + m_secUi->relockDatabaseAutoTypeCheckBox->setChecked(config()->get(Config::Security_RelockAutoType).toBool()); + m_secUi->fallbackToSearch->setChecked(config()->get(Config::Security_IconDownloadFallback).toBool()); - m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool()); - m_secUi->passwordShowDotsCheckBox->setChecked(config()->get("security/passwordemptynodots").toBool()); - m_secUi->passwordPreviewCleartextCheckBox->setChecked(config()->get("security/HidePasswordPreviewPanel").toBool()); - m_secUi->passwordRepeatCheckBox->setChecked(config()->get("security/passwordsrepeat").toBool()); - m_secUi->hideNotesCheckBox->setChecked(config()->get("security/hidenotes").toBool()); + m_secUi->passwordCleartextCheckBox->setChecked(config()->get(Config::Security_PasswordsCleartext).toBool()); + m_secUi->passwordShowDotsCheckBox->setChecked(config()->get(Config::Security_PasswordEmptyNoDots).toBool()); + m_secUi->passwordPreviewCleartextCheckBox->setChecked( + config()->get(Config::Security_HidePasswordPreviewPanel).toBool()); + m_secUi->passwordRepeatCheckBox->setChecked(config()->get(Config::Security_PasswordsRepeat).toBool()); + m_secUi->hideNotesCheckBox->setChecked(config()->get(Config::Security_HideNotes).toBool()); - m_secUi->touchIDResetCheckBox->setChecked(config()->get("security/resettouchid").toBool()); - m_secUi->touchIDResetSpinBox->setValue(config()->get("security/resettouchidtimeout").toInt()); - m_secUi->touchIDResetOnScreenLockCheckBox->setChecked(config()->get("security/resettouchidscreenlock").toBool()); + m_secUi->touchIDResetCheckBox->setChecked(config()->get(Config::Security_ResetTouchId).toBool()); + m_secUi->touchIDResetSpinBox->setValue(config()->get(Config::Security_ResetTouchIdTimeout).toInt()); + m_secUi->touchIDResetOnScreenLockCheckBox->setChecked( + config()->get(Config::Security_ResetTouchIdScreenlock).toBool()); for (const ExtraPage& page : asConst(m_extraPages)) { page.loadSettings(); @@ -294,88 +299,91 @@ void ApplicationSettingsWidget::saveSettings() return; } - config()->set("SingleInstance", m_generalUi->singleInstanceCheckBox->isChecked()); - config()->set("RememberLastDatabases", m_generalUi->rememberLastDatabasesCheckBox->isChecked()); - config()->set("RememberLastKeyFiles", m_generalUi->rememberLastKeyFilesCheckBox->isChecked()); - config()->set("OpenPreviousDatabasesOnStartup", m_generalUi->openPreviousDatabasesOnStartupCheckBox->isChecked()); - config()->set("AutoSaveAfterEveryChange", m_generalUi->autoSaveAfterEveryChangeCheckBox->isChecked()); - config()->set("AutoSaveOnExit", m_generalUi->autoSaveOnExitCheckBox->isChecked()); - config()->set("BackupBeforeSave", m_generalUi->backupBeforeSaveCheckBox->isChecked()); - config()->set("UseAtomicSaves", m_generalUi->useAtomicSavesCheckBox->isChecked()); - config()->set("AutoReloadOnChange", m_generalUi->autoReloadOnChangeCheckBox->isChecked()); - config()->set("MinimizeAfterUnlock", m_generalUi->minimizeAfterUnlockCheckBox->isChecked()); - config()->set("MinimizeOnOpenUrl", m_generalUi->minimizeOnOpenUrlCheckBox->isChecked()); - config()->set("HideWindowOnCopy", m_generalUi->hideWindowOnCopyCheckBox->isChecked()); - config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyRadioButton->isChecked()); - config()->set("DropToBackgroundOnCopy", m_generalUi->dropToBackgroundOnCopyRadioButton->isChecked()); - config()->set("UseGroupIconOnEntryCreation", m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked()); - config()->set("IgnoreGroupExpansion", m_generalUi->ignoreGroupExpansionCheckBox->isChecked()); - config()->set("AutoTypeEntryTitleMatch", m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked()); - config()->set("AutoTypeEntryURLMatch", m_generalUi->autoTypeEntryURLMatchCheckBox->isChecked()); - config()->set("FaviconDownloadTimeout", m_generalUi->faviconTimeoutSpinBox->value()); + config()->set(Config::SingleInstance, m_generalUi->singleInstanceCheckBox->isChecked()); + config()->set(Config::RememberLastDatabases, m_generalUi->rememberLastDatabasesCheckBox->isChecked()); + config()->set(Config::RememberLastKeyFiles, m_generalUi->rememberLastKeyFilesCheckBox->isChecked()); + config()->set(Config::OpenPreviousDatabasesOnStartup, + m_generalUi->openPreviousDatabasesOnStartupCheckBox->isChecked()); + config()->set(Config::AutoSaveAfterEveryChange, m_generalUi->autoSaveAfterEveryChangeCheckBox->isChecked()); + config()->set(Config::AutoSaveOnExit, m_generalUi->autoSaveOnExitCheckBox->isChecked()); + config()->set(Config::BackupBeforeSave, m_generalUi->backupBeforeSaveCheckBox->isChecked()); + config()->set(Config::UseAtomicSaves, m_generalUi->useAtomicSavesCheckBox->isChecked()); + config()->set(Config::AutoReloadOnChange, m_generalUi->autoReloadOnChangeCheckBox->isChecked()); + config()->set(Config::MinimizeAfterUnlock, m_generalUi->minimizeAfterUnlockCheckBox->isChecked()); + config()->set(Config::MinimizeOnOpenUrl, m_generalUi->minimizeOnOpenUrlCheckBox->isChecked()); + config()->set(Config::HideWindowOnCopy, m_generalUi->hideWindowOnCopyCheckBox->isChecked()); + config()->set(Config::MinimizeOnCopy, m_generalUi->minimizeOnCopyRadioButton->isChecked()); + config()->set(Config::DropToBackgroundOnCopy, m_generalUi->dropToBackgroundOnCopyRadioButton->isChecked()); + config()->set(Config::UseGroupIconOnEntryCreation, m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked()); + config()->set(Config::IgnoreGroupExpansion, m_generalUi->ignoreGroupExpansionCheckBox->isChecked()); + config()->set(Config::AutoTypeEntryTitleMatch, m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked()); + config()->set(Config::AutoTypeEntryURLMatch, m_generalUi->autoTypeEntryURLMatchCheckBox->isChecked()); + config()->set(Config::FaviconDownloadTimeout, m_generalUi->faviconTimeoutSpinBox->value()); - config()->set("GUI/Language", m_generalUi->languageComboBox->currentData().toString()); - config()->set("GUI/HidePreviewPanel", m_generalUi->previewHideCheckBox->isChecked()); - config()->set("GUI/HideToolbar", m_generalUi->toolbarHideCheckBox->isChecked()); - config()->set("GUI/MovableToolbar", m_generalUi->toolbarMovableCheckBox->isChecked()); - config()->set("GUI/MonospaceNotes", m_generalUi->monospaceNotesCheckBox->isChecked()); + config()->set(Config::GUI_Language, m_generalUi->languageComboBox->currentData().toString()); + config()->set(Config::GUI_HidePreviewPanel, m_generalUi->previewHideCheckBox->isChecked()); + config()->set(Config::GUI_HideToolbar, m_generalUi->toolbarHideCheckBox->isChecked()); + config()->set(Config::GUI_MovableToolbar, m_generalUi->toolbarMovableCheckBox->isChecked()); + config()->set(Config::GUI_MonospaceNotes, m_generalUi->monospaceNotesCheckBox->isChecked()); QString theme = m_generalUi->appThemeSelection->currentData().toString(); - config()->set("GUI/ApplicationTheme", theme); + config()->set(Config::GUI_ApplicationTheme, theme); - config()->set("GUI/ToolButtonStyle", m_generalUi->toolButtonStyleComboBox->currentData().toString()); + config()->set(Config::GUI_ToolButtonStyle, m_generalUi->toolButtonStyleComboBox->currentData().toString()); - config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked()); - config()->set("GUI/DarkTrayIcon", m_generalUi->systrayDarkIconCheckBox->isChecked()); - config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked()); - config()->set("GUI/MinimizeOnClose", m_generalUi->minimizeOnCloseCheckBox->isChecked()); - config()->set("GUI/MinimizeOnStartup", m_generalUi->systrayMinimizeOnStartup->isChecked()); - config()->set("GUI/CheckForUpdates", m_generalUi->checkForUpdatesOnStartupCheckBox->isChecked()); - config()->set("GUI/CheckForUpdatesIncludeBetas", m_generalUi->checkForUpdatesIncludeBetasCheckBox->isChecked()); + config()->set(Config::GUI_ShowTrayIcon, m_generalUi->systrayShowCheckBox->isChecked()); + config()->set(Config::GUI_DarkTrayIcon, m_generalUi->systrayDarkIconCheckBox->isChecked()); + config()->set(Config::GUI_MinimizeToTray, m_generalUi->systrayMinimizeToTrayCheckBox->isChecked()); + config()->set(Config::GUI_MinimizeOnClose, m_generalUi->minimizeOnCloseCheckBox->isChecked()); + config()->set(Config::GUI_MinimizeOnStartup, m_generalUi->systrayMinimizeOnStartup->isChecked()); + config()->set(Config::GUI_CheckForUpdates, m_generalUi->checkForUpdatesOnStartupCheckBox->isChecked()); + config()->set(Config::GUI_CheckForUpdatesIncludeBetas, + m_generalUi->checkForUpdatesIncludeBetasCheckBox->isChecked()); - config()->set("security/autotypeask", m_generalUi->autoTypeAskCheckBox->isChecked()); + config()->set(Config::Security_AutoTypeAsk, m_generalUi->autoTypeAskCheckBox->isChecked()); if (autoType()->isAvailable()) { - config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key()); - config()->set("GlobalAutoTypeModifiers", static_cast(m_generalUi->autoTypeShortcutWidget->modifiers())); - config()->set("AutoTypeDelay", m_generalUi->autoTypeDelaySpinBox->value()); - config()->set("AutoTypeStartDelay", m_generalUi->autoTypeStartDelaySpinBox->value()); + config()->set(Config::GlobalAutoTypeKey, m_generalUi->autoTypeShortcutWidget->key()); + config()->set(Config::GlobalAutoTypeModifiers, + static_cast(m_generalUi->autoTypeShortcutWidget->modifiers())); + config()->set(Config::AutoTypeDelay, m_generalUi->autoTypeDelaySpinBox->value()); + config()->set(Config::AutoTypeStartDelay, m_generalUi->autoTypeStartDelaySpinBox->value()); } - config()->set("security/clearclipboard", m_secUi->clearClipboardCheckBox->isChecked()); - config()->set("security/clearclipboardtimeout", m_secUi->clearClipboardSpinBox->value()); + config()->set(Config::Security_ClearClipboard, m_secUi->clearClipboardCheckBox->isChecked()); + config()->set(Config::Security_ClearClipboardTimeout, m_secUi->clearClipboardSpinBox->value()); - config()->set("security/clearsearch", m_secUi->clearSearchCheckBox->isChecked()); - config()->set("security/clearsearchtimeout", m_secUi->clearSearchSpinBox->value()); + config()->set(Config::Security_ClearSearch, m_secUi->clearSearchCheckBox->isChecked()); + config()->set(Config::Security_ClearSearchTimeout, m_secUi->clearSearchSpinBox->value()); - config()->set("security/lockdatabaseidle", m_secUi->lockDatabaseIdleCheckBox->isChecked()); - config()->set("security/lockdatabaseidlesec", m_secUi->lockDatabaseIdleSpinBox->value()); - config()->set("security/lockdatabaseminimize", m_secUi->lockDatabaseMinimizeCheckBox->isChecked()); - config()->set("security/lockdatabasescreenlock", m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked()); - config()->set("security/relockautotype", m_secUi->relockDatabaseAutoTypeCheckBox->isChecked()); - config()->set("security/IconDownloadFallback", m_secUi->fallbackToSearch->isChecked()); + config()->set(Config::Security_LockDatabaseIdle, m_secUi->lockDatabaseIdleCheckBox->isChecked()); + config()->set(Config::Security_LockDatabaseIdleSeconds, m_secUi->lockDatabaseIdleSpinBox->value()); + config()->set(Config::Security_LockDatabaseMinimize, m_secUi->lockDatabaseMinimizeCheckBox->isChecked()); + config()->set(Config::Security_LockDatabaseScreenLock, m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked()); + config()->set(Config::Security_RelockAutoType, m_secUi->relockDatabaseAutoTypeCheckBox->isChecked()); + config()->set(Config::Security_IconDownloadFallback, m_secUi->fallbackToSearch->isChecked()); - config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked()); - config()->set("security/passwordemptynodots", m_secUi->passwordShowDotsCheckBox->isChecked()); + config()->set(Config::Security_PasswordsCleartext, m_secUi->passwordCleartextCheckBox->isChecked()); + config()->set(Config::Security_PasswordEmptyNoDots, m_secUi->passwordShowDotsCheckBox->isChecked()); - config()->set("security/HidePasswordPreviewPanel", m_secUi->passwordPreviewCleartextCheckBox->isChecked()); - config()->set("security/passwordsrepeat", m_secUi->passwordRepeatCheckBox->isChecked()); - config()->set("security/hidenotes", m_secUi->hideNotesCheckBox->isChecked()); + config()->set(Config::Security_HidePasswordPreviewPanel, m_secUi->passwordPreviewCleartextCheckBox->isChecked()); + config()->set(Config::Security_PasswordsRepeat, m_secUi->passwordRepeatCheckBox->isChecked()); + config()->set(Config::Security_HideNotes, m_secUi->hideNotesCheckBox->isChecked()); - config()->set("security/resettouchid", m_secUi->touchIDResetCheckBox->isChecked()); - config()->set("security/resettouchidtimeout", m_secUi->touchIDResetSpinBox->value()); - config()->set("security/resettouchidscreenlock", m_secUi->touchIDResetOnScreenLockCheckBox->isChecked()); + config()->set(Config::Security_ResetTouchId, m_secUi->touchIDResetCheckBox->isChecked()); + config()->set(Config::Security_ResetTouchIdTimeout, m_secUi->touchIDResetSpinBox->value()); + config()->set(Config::Security_ResetTouchIdScreenlock, m_secUi->touchIDResetOnScreenLockCheckBox->isChecked()); // Security: clear storage if related settings are disabled - if (!config()->get("RememberLastDatabases").toBool()) { - config()->set("LastDatabases", {}); - config()->set("OpenPreviousDatabasesOnStartup", {}); - config()->set("LastActiveDatabase", {}); - config()->set("LastAttachmentDir", {}); + if (!config()->get(Config::RememberLastDatabases).toBool()) { + config()->remove(Config::LastDatabases); + config()->remove(Config::OpenPreviousDatabasesOnStartup); + config()->remove(Config::LastActiveDatabase); + config()->remove(Config::LastAttachmentDir); } - if (!config()->get("RememberLastKeyFiles").toBool()) { - config()->set("LastKeyFiles", {}); - config()->set("LastDir", ""); + if (!config()->get(Config::RememberLastKeyFiles).toBool()) { + config()->remove(Config::LastKeyFiles); + config()->remove(Config::LastDir); } for (const ExtraPage& page : asConst(m_extraPages)) { @@ -406,12 +414,12 @@ void ApplicationSettingsWidget::resetSettings() config()->resetToDefaults(); // Clear recently used data - config()->set("LastDatabases", {}); - config()->set("OpenPreviousDatabasesOnStartup", {}); - config()->set("LastActiveDatabase", {}); - config()->set("LastAttachmentDir", {}); - config()->set("LastKeyFiles", {}); - config()->set("LastDir", ""); + config()->remove(Config::LastDatabases); + config()->remove(Config::OpenPreviousDatabasesOnStartup); + config()->remove(Config::LastActiveDatabase); + config()->remove(Config::LastAttachmentDir); + config()->remove(Config::LastKeyFiles); + config()->remove(Config::LastDir); // Save the Extra Pages (these are NOT reset) for (const ExtraPage& page : asConst(m_extraPages)) { diff --git a/src/gui/Clipboard.cpp b/src/gui/Clipboard.cpp index 10f959531..ae5d8290f 100644 --- a/src/gui/Clipboard.cpp +++ b/src/gui/Clipboard.cpp @@ -67,8 +67,8 @@ void Clipboard::setText(const QString& text, bool clear) } #endif - if (clear && config()->get("security/clearclipboard").toBool()) { - int timeout = config()->get("security/clearclipboardtimeout").toInt(); + if (clear && config()->get(Config::Security_ClearClipboard).toBool()) { + int timeout = config()->get(Config::Security_ClearClipboardTimeout).toInt(); if (timeout > 0) { m_lastCopied = text; m_timer->start(timeout * 1000); diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 31391b12b..1b1c74cd5 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -147,15 +147,15 @@ void DatabaseOpenWidget::load(const QString& filename) m_ui->keyFileClearIcon->setVisible(false); m_keyFileComboEdited = false; - if (config()->get("RememberLastKeyFiles").toBool()) { - QHash lastKeyFiles = config()->get("LastKeyFiles").toHash(); + if (config()->get(Config::RememberLastKeyFiles).toBool()) { + QHash lastKeyFiles = config()->get(Config::LastKeyFiles).toHash(); if (lastKeyFiles.contains(m_filename)) { m_ui->comboKeyFile->addItem(lastKeyFiles[m_filename].toString()); m_ui->comboKeyFile->setCurrentIndex(1); } } - QHash useTouchID = config()->get("UseTouchID").toHash(); + QHash useTouchID = config()->get(Config::UseTouchID).toHash(); m_ui->checkTouchID->setChecked(useTouchID.value(m_filename, false).toBool()); } @@ -207,7 +207,7 @@ void DatabaseOpenWidget::openDatabase() if (ok) { #ifdef WITH_XC_TOUCHID - QHash useTouchID = config()->get("UseTouchID").toHash(); + QHash useTouchID = config()->get(Config::UseTouchID).toHash(); // check if TouchID can & should be used to unlock the database next time if (m_ui->checkTouchID->isChecked() && TouchID::getInstance().isAvailable()) { @@ -221,7 +221,7 @@ void DatabaseOpenWidget::openDatabase() useTouchID.insert(m_filename, false); } - config()->set("UseTouchID", useTouchID); + config()->set(Config::UseTouchID, useTouchID); #endif if (m_ui->messageWidget->isVisible()) { @@ -293,7 +293,7 @@ QSharedPointer DatabaseOpenWidget::databaseKey() } #endif - QHash lastKeyFiles = config()->get("LastKeyFiles").toHash(); + QHash lastKeyFiles = config()->get(Config::LastKeyFiles).toHash(); lastKeyFiles.remove(m_filename); auto key = QSharedPointer::create(); @@ -304,7 +304,7 @@ QSharedPointer DatabaseOpenWidget::databaseKey() m_ui->messageWidget->showMessage(tr("Failed to open key file: %1").arg(errorMsg), MessageWidget::Error); return {}; } - if (key->type() != FileKey::Hashed && !config()->get("Messages/NoLegacyKeyFileWarning").toBool()) { + if (key->type() != FileKey::Hashed && !config()->get(Config::Messages_NoLegacyKeyFileWarning).toBool()) { QMessageBox legacyWarning; legacyWarning.setWindowTitle(tr("Legacy key file format")); legacyWarning.setText(tr("You are using a legacy key file format which may become\n" @@ -316,7 +316,7 @@ QSharedPointer DatabaseOpenWidget::databaseKey() legacyWarning.setCheckBox(new QCheckBox(tr("Don't show this warning again"))); connect(legacyWarning.checkBox(), &QCheckBox::stateChanged, [](int state) { - config()->set("Messages/NoLegacyKeyFileWarning", state == Qt::CheckState::Checked); + config()->set(Config::Messages_NoLegacyKeyFileWarning, state == Qt::CheckState::Checked); }); legacyWarning.exec(); @@ -325,12 +325,12 @@ QSharedPointer DatabaseOpenWidget::databaseKey() lastKeyFiles[m_filename] = keyFilename; } - if (config()->get("RememberLastKeyFiles").toBool()) { - config()->set("LastKeyFiles", lastKeyFiles); + if (config()->get(Config::RememberLastKeyFiles).toBool()) { + config()->set(Config::LastKeyFiles, lastKeyFiles); } #ifdef WITH_XC_YUBIKEY - QHash lastChallengeResponse = config()->get("LastChallengeResponse").toHash(); + QHash lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash(); lastChallengeResponse.remove(m_filename); int selectionIndex = m_ui->comboChallengeResponse->currentIndex(); @@ -345,8 +345,8 @@ QSharedPointer DatabaseOpenWidget::databaseKey() lastChallengeResponse[m_filename] = true; } - if (config()->get("RememberLastKeyFiles").toBool()) { - config()->set("LastChallengeResponse", lastChallengeResponse); + if (config()->get(Config::RememberLastKeyFiles).toBool()) { + config()->set(Config::LastChallengeResponse, lastChallengeResponse); } #endif @@ -361,7 +361,7 @@ void DatabaseOpenWidget::reject() void DatabaseOpenWidget::browseKeyFile() { QString filters = QString("%1 (*);;%2 (*.key)").arg(tr("All files"), tr("Key files")); - if (!config()->get("RememberLastKeyFiles").toBool()) { + if (!config()->get(Config::RememberLastKeyFiles).toBool()) { fileDialog()->setNextForgetDialog(); } QString filename = fileDialog()->getOpenFileName(this, tr("Select key file"), QString(), filters); @@ -418,8 +418,8 @@ void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking) // add detected YubiKey to combo box and encode blocking mode in LSB, slot number in second LSB m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant((slot << 1) | blocking)); - if (config()->get("RememberLastKeyFiles").toBool()) { - QHash lastChallengeResponse = config()->get("LastChallengeResponse").toHash(); + if (config()->get(Config::RememberLastKeyFiles).toBool()) { + QHash lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash(); if (lastChallengeResponse.contains(m_filename)) { m_ui->comboChallengeResponse->setCurrentIndex(1); } diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 6ea8789de..3df076fb2 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -667,7 +667,7 @@ void DatabaseTabWidget::unlockDatabaseInDialog(DatabaseWidget* dbWidget, */ void DatabaseTabWidget::relockPendingDatabase() { - if (!m_dbWidgetPendingLock || !config()->get("security/relockautotype").toBool()) { + if (!m_dbWidgetPendingLock || !config()->get(Config::Security_RelockAutoType).toBool()) { return; } @@ -682,17 +682,17 @@ void DatabaseTabWidget::relockPendingDatabase() void DatabaseTabWidget::updateLastDatabases(const QString& filename) { - if (!config()->get("RememberLastDatabases").toBool()) { - config()->set("LastDatabases", QVariant()); + if (!config()->get(Config::RememberLastDatabases).toBool()) { + config()->remove(Config::LastDatabases); } else { - QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList(); + QStringList lastDatabases = config()->get(Config::LastDatabases).toStringList(); lastDatabases.prepend(filename); lastDatabases.removeDuplicates(); - while (lastDatabases.count() > config()->get("NumberOfRememberedLastDatabases").toInt()) { + while (lastDatabases.count() > config()->get(Config::NumberOfRememberedLastDatabases).toInt()) { lastDatabases.removeLast(); } - config()->set("LastDatabases", lastDatabases); + config()->set(Config::LastDatabases, lastDatabases); } } @@ -731,7 +731,7 @@ void DatabaseTabWidget::performGlobalAutoType() if (!unlockedDatabases.isEmpty()) { autoType()->performGlobalAutoType(unlockedDatabases); } else if (count() > 0) { - if (config()->get("security/relockautotype").toBool()) { + if (config()->get(Config::Security_RelockAutoType).toBool()) { m_dbWidgetPendingLock = currentDatabaseWidget(); } unlockDatabaseInDialog(currentDatabaseWidget(), DatabaseOpenDialog::Intent::AutoType); diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 2078adca2..2b30d6e01 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -216,7 +216,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer db, QWidget* parent) m_blockAutoSave = false; m_EntrySearcher = new EntrySearcher(false); - m_searchLimitGroup = config()->get("SearchLimitGroup", false).toBool(); + m_searchLimitGroup = config()->get(Config::SearchLimitGroup).toBool(); #ifdef WITH_XC_SSHAGENT if (sshAgent()->isEnabled()) { @@ -690,10 +690,10 @@ void DatabaseWidget::showTotpKeyQrCode() void DatabaseWidget::setClipboardTextAndMinimize(const QString& text) { clipboard()->setText(text); - if (config()->get("HideWindowOnCopy").toBool()) { - if (config()->get("MinimizeOnCopy").toBool()) { + if (config()->get(Config::HideWindowOnCopy).toBool()) { + if (config()->get(Config::MinimizeOnCopy).toBool()) { getMainWindow()->minimizeOrHide(); - } else if (config()->get("DropToBackgroundOnCopy").toBool()) { + } else if (config()->get(Config::DropToBackgroundOnCopy).toBool()) { window()->lower(); } } @@ -840,7 +840,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) if (launch) { QProcess::startDetached(cmdString.mid(6)); - if (config()->get("MinimizeOnOpenUrl").toBool()) { + if (config()->get(Config::MinimizeOnOpenUrl).toBool()) { getMainWindow()->minimizeOrHide(); } } @@ -849,7 +849,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) if (!url.isEmpty()) { QDesktopServices::openUrl(url); - if (config()->get("MinimizeOnOpenUrl").toBool()) { + if (config()->get(Config::MinimizeOnOpenUrl).toBool()) { getMainWindow()->minimizeOrHide(); } } @@ -1030,7 +1030,7 @@ void DatabaseWidget::loadDatabase(bool accepted) processAutoOpen(); m_saveAttempts = 0; emit databaseUnlocked(); - if (config()->get("MinimizeAfterUnlock").toBool()) { + if (config()->get(Config::MinimizeAfterUnlock).toBool()) { getMainWindow()->minimizeOrHide(); } } else { @@ -1349,7 +1349,7 @@ void DatabaseWidget::onGroupChanged(Group* group) void DatabaseWidget::onDatabaseModified() { - if (!m_blockAutoSave && config()->get("AutoSaveAfterEveryChange").toBool() && !m_db->isReadOnly()) { + if (!m_blockAutoSave && config()->get(Config::AutoSaveAfterEveryChange).toBool() && !m_db->isReadOnly()) { save(); } else { // Only block once, then reset @@ -1462,7 +1462,8 @@ bool DatabaseWidget::lock() if (m_db->isModified()) { bool saved = false; // Attempt to save on exit, but don't block locking if it fails - if (config()->get("AutoSaveOnExit").toBool() || config()->get("AutoSaveAfterEveryChange").toBool()) { + if (config()->get(Config::AutoSaveOnExit).toBool() + || config()->get(Config::AutoSaveAfterEveryChange).toBool()) { saved = save(); } @@ -1520,7 +1521,7 @@ void DatabaseWidget::reloadDatabaseFile() m_blockAutoSave = true; - if (!config()->get("AutoReloadOnChange").toBool()) { + if (!config()->get(Config::AutoReloadOnChange).toBool()) { // Ask if we want to reload the db auto result = MessageBox::question(this, tr("File has changed"), @@ -1738,9 +1739,9 @@ bool DatabaseWidget::save() m_groupView->setDisabled(true); QApplication::processEvents(); - bool useAtomicSaves = config()->get("UseAtomicSaves", true).toBool(); + bool useAtomicSaves = config()->get(Config::UseAtomicSaves).toBool(); QString errorMessage; - bool ok = m_db->save(&errorMessage, useAtomicSaves, config()->get("BackupBeforeSave").toBool()); + bool ok = m_db->save(&errorMessage, useAtomicSaves, config()->get(Config::BackupBeforeSave).toBool()); // Return control m_entryView->setDisabled(false); @@ -1766,7 +1767,7 @@ bool DatabaseWidget::save() MessageBox::Disable | MessageBox::Cancel, MessageBox::Disable); if (result == MessageBox::Disable) { - config()->set("UseAtomicSaves", false); + config()->set(Config::UseAtomicSaves, false); return save(); } } @@ -1789,7 +1790,7 @@ bool DatabaseWidget::saveAs() while (true) { QString oldFilePath = m_db->filePath(); if (!QFileInfo::exists(oldFilePath)) { - oldFilePath = QDir::toNativeSeparators(config()->get("LastDir", QDir::homePath()).toString() + "/" + oldFilePath = QDir::toNativeSeparators(config()->get(Config::LastDir).toString() + "/" + tr("Passwords").append(".kdbx")); } const QString newFilePath = fileDialog()->getSaveFileName( diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp index df0e43ebc..8bb5c7143 100644 --- a/src/gui/DatabaseWidgetStateSync.cpp +++ b/src/gui/DatabaseWidgetStateSync.cpp @@ -27,12 +27,12 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent) , m_activeDbWidget(nullptr) , m_blockUpdates(false) { - m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState")); - m_previewSplitterSizes = variantToIntList(config()->get("GUI/PreviewSplitterState")); - m_hideUsernames = config()->get("GUI/HideUsernames").toBool(); - m_hidePasswords = config()->get("GUI/HidePasswords").toBool(); - m_listViewState = config()->get("GUI/ListViewState").toByteArray(); - m_searchViewState = config()->get("GUI/SearchViewState").toByteArray(); + m_mainSplitterSizes = variantToIntList(config()->get(Config::GUI_SplitterState)); + m_previewSplitterSizes = variantToIntList(config()->get(Config::GUI_PreviewSplitterState)); + m_hideUsernames = config()->get(Config::GUI_HideUsernames).toBool(); + m_hidePasswords = config()->get(Config::GUI_HidePasswords).toBool(); + m_listViewState = config()->get(Config::GUI_ListViewState).toByteArray(); + m_searchViewState = config()->get(Config::GUI_SearchViewState).toByteArray(); connect(qApp, &QCoreApplication::aboutToQuit, this, &DatabaseWidgetStateSync::sync); } @@ -46,12 +46,12 @@ DatabaseWidgetStateSync::~DatabaseWidgetStateSync() */ void DatabaseWidgetStateSync::sync() { - config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes)); - config()->set("GUI/PreviewSplitterState", intListToVariant(m_previewSplitterSizes)); - config()->set("GUI/HideUsernames", m_hideUsernames); - config()->set("GUI/HidePasswords", m_hidePasswords); - config()->set("GUI/ListViewState", m_listViewState); - config()->set("GUI/SearchViewState", m_searchViewState); + config()->set(Config::GUI_SplitterState, intListToVariant(m_mainSplitterSizes)); + config()->set(Config::GUI_PreviewSplitterState, intListToVariant(m_previewSplitterSizes)); + config()->set(Config::GUI_HideUsernames, m_hideUsernames); + config()->set(Config::GUI_HidePasswords, m_hidePasswords); + config()->set(Config::GUI_ListViewState, m_listViewState); + config()->set(Config::GUI_SearchViewState, m_searchViewState); config()->sync(); } diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp index d851e4d30..c9a0c0310 100644 --- a/src/gui/EditWidgetIcons.cpp +++ b/src/gui/EditWidgetIcons.cpp @@ -203,7 +203,7 @@ void EditWidgetIcons::iconReceived(const QString& url, const QImage& icon) Q_UNUSED(url); if (icon.isNull()) { QString message(tr("Unable to fetch favicon.")); - if (!config()->get("security/IconDownloadFallback", false).toBool()) { + if (!config()->get(Config::Security_IconDownloadFallback).toBool()) { message.append("\n").append( tr("You can enable the DuckDuckGo website icon service under Tools -> Settings -> Security")); } diff --git a/src/gui/EntryPreviewWidget.cpp b/src/gui/EntryPreviewWidget.cpp index 08627ac3c..f0301017c 100644 --- a/src/gui/EntryPreviewWidget.cpp +++ b/src/gui/EntryPreviewWidget.cpp @@ -106,7 +106,7 @@ void EntryPreviewWidget::setEntry(Entry* selectedEntry) updateEntryAdvancedTab(); updateEntryAutotypeTab(); - setVisible(!config()->get("GUI/HidePreviewPanel").toBool()); + setVisible(!config()->get(Config::GUI_HidePreviewPanel).toBool()); m_ui->stackedWidget->setCurrentWidget(m_ui->pageEntry); const int tabIndex = m_ui->entryTabWidget->isTabEnabled(m_selectedTabEntry) ? m_selectedTabEntry : GeneralTabIndex; @@ -129,7 +129,7 @@ void EntryPreviewWidget::setGroup(Group* selectedGroup) updateGroupSharingTab(); #endif - setVisible(!config()->get("GUI/HidePreviewPanel").toBool()); + setVisible(!config()->get(Config::GUI_HidePreviewPanel).toBool()); m_ui->stackedWidget->setCurrentWidget(m_ui->pageGroup); const int tabIndex = m_ui->groupTabWidget->isTabEnabled(m_selectedTabGroup) ? m_selectedTabGroup : GeneralTabIndex; @@ -186,7 +186,7 @@ void EntryPreviewWidget::setPasswordVisible(bool state) if (state) { m_ui->entryPasswordLabel->setText(password); m_ui->entryPasswordLabel->setCursorPosition(0); - } else if (password.isEmpty() && config()->get("security/passwordemptynodots").toBool()) { + } else if (password.isEmpty() && config()->get(Config::Security_PasswordEmptyNoDots).toBool()) { m_ui->entryPasswordLabel->setText(""); } else { m_ui->entryPasswordLabel->setText(QString("\u25cf").repeated(6)); @@ -222,7 +222,7 @@ void EntryPreviewWidget::updateEntryGeneralTab() m_ui->entryUsernameLabel->setText(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->username())); m_ui->entryUsernameLabel->setCursorPosition(0); - if (config()->get("security/HidePasswordPreviewPanel").toBool()) { + if (config()->get(Config::Security_HidePasswordPreviewPanel).toBool()) { // Hide password setPasswordVisible(false); // Show the password toggle button if there are dots in the label @@ -234,7 +234,7 @@ void EntryPreviewWidget::updateEntryGeneralTab() m_ui->togglePasswordButton->setVisible(false); } - if (config()->get("security/hidenotes").toBool()) { + if (config()->get(Config::Security_HideNotes).toBool()) { setEntryNotesVisible(false); m_ui->toggleEntryNotesButton->setVisible(!m_ui->entryNotesTextEdit->toPlainText().isEmpty()); m_ui->toggleEntryNotesButton->setChecked(false); @@ -243,7 +243,7 @@ void EntryPreviewWidget::updateEntryGeneralTab() m_ui->toggleEntryNotesButton->setVisible(false); } - if (config()->get("GUI/MonospaceNotes", false).toBool()) { + if (config()->get(Config::GUI_MonospaceNotes).toBool()) { m_ui->entryNotesTextEdit->setFont(Font::fixedFont()); } else { m_ui->entryNotesTextEdit->setFont(Font::defaultFont()); @@ -330,7 +330,7 @@ void EntryPreviewWidget::updateGroupGeneralTab() groupTime.expires() ? groupTime.expiryTime().toString(Qt::DefaultLocaleShortDate) : tr("Never"); m_ui->groupExpirationLabel->setText(expiresText); - if (config()->get("security/hidenotes").toBool()) { + if (config()->get(Config::Security_HideNotes).toBool()) { setGroupNotesVisible(false); m_ui->toggleGroupNotesButton->setVisible(!m_ui->groupNotesTextEdit->toPlainText().isEmpty()); m_ui->toggleGroupNotesButton->setChecked(false); @@ -339,7 +339,7 @@ void EntryPreviewWidget::updateGroupGeneralTab() m_ui->toggleGroupNotesButton->setVisible(false); } - if (config()->get("GUI/MonospaceNotes", false).toBool()) { + if (config()->get(Config::GUI_MonospaceNotes).toBool()) { m_ui->groupNotesTextEdit->setFont(Font::fixedFont()); } else { m_ui->groupNotesTextEdit->setFont(Font::defaultFont()); diff --git a/src/gui/FileDialog.cpp b/src/gui/FileDialog.cpp index c2b774ceb..9de07db7c 100644 --- a/src/gui/FileDialog.cpp +++ b/src/gui/FileDialog.cpp @@ -35,7 +35,7 @@ QString FileDialog::getOpenFileName(QWidget* parent, m_nextFileName.clear(); return result; } else { - const auto& workingDir = dir.isEmpty() ? config()->get("LastDir").toString() : dir; + const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators( QFileDialog::getOpenFileName(parent, caption, workingDir, filter, selectedFilter, options)); @@ -62,7 +62,7 @@ QStringList FileDialog::getOpenFileNames(QWidget* parent, m_nextFileNames.clear(); return results; } else { - const auto& workingDir = dir.isEmpty() ? config()->get("LastDir").toString() : dir; + const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; auto results = QFileDialog::getOpenFileNames(parent, caption, workingDir, filter, selectedFilter, options); for (auto& path : results) { @@ -94,7 +94,7 @@ QString FileDialog::getFileName(QWidget* parent, m_nextFileName.clear(); return result; } else { - const auto& workingDir = dir.isEmpty() ? config()->get("LastDir").toString() : dir; + const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators( QFileDialog::getSaveFileName(parent, caption, workingDir, filter, selectedFilter, options)); @@ -121,7 +121,7 @@ QString FileDialog::getSaveFileName(QWidget* parent, m_nextFileName.clear(); return result; } else { - const auto& workingDir = dir.isEmpty() ? config()->get("LastDir").toString() : dir; + const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators( QFileDialog::getSaveFileName(parent, caption, workingDir, filter, selectedFilter, options)); @@ -146,7 +146,7 @@ QString FileDialog::getExistingDirectory(QWidget* parent, m_nextDirName.clear(); return result; } else { - const auto& workingDir = dir.isEmpty() ? config()->get("LastDir").toString() : dir; + const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent, caption, workingDir, options)); @@ -188,7 +188,7 @@ FileDialog::FileDialog() void FileDialog::saveLastDir(const QString& dir) { if (!dir.isEmpty() && !m_forgetLastDir) { - config()->set("LastDir", QFileInfo(dir).absolutePath()); + config()->set(Config::LastDir, QFileInfo(dir).absolutePath()); } m_forgetLastDir = false; diff --git a/src/gui/IconDownloaderDialog.cpp b/src/gui/IconDownloaderDialog.cpp index b7c6567ff..1eb4b855c 100644 --- a/src/gui/IconDownloaderDialog.cpp +++ b/src/gui/IconDownloaderDialog.cpp @@ -159,7 +159,7 @@ void IconDownloaderDialog::downloadFinished(const QString& url, const QImage& ic void IconDownloaderDialog::showFallbackMessage(bool state) { // Show fallback message if the option is not active - bool show = state && !config()->get("security/IconDownloadFallback").toBool(); + bool show = state && !config()->get(Config::Security_IconDownloadFallback).toBool(); m_ui->fallbackLabel->setVisible(show); } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index af40c307f..675929c45 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -182,8 +182,8 @@ MainWindow::MainWindow() m_entryNewContextMenu = new QMenu(this); m_entryNewContextMenu->addAction(m_ui->actionEntryNew); - restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray()); - restoreState(config()->get("GUI/MainWindowState").toByteArray()); + restoreGeometry(config()->get(Config::GUI_MainWindowGeometry).toByteArray()); + restoreState(config()->get(Config::GUI_MainWindowState).toByteArray()); #ifdef WITH_XC_BROWSER m_ui->settingsWidget->addSettingsPage(new BrowserPlugin(m_ui->tabWidget)); #endif @@ -240,15 +240,15 @@ MainWindow::MainWindow() m_copyAdditionalAttributeActions, SIGNAL(triggered(QAction*)), SLOT(copyAttribute(QAction*))); connect(m_ui->menuEntryCopyAttribute, SIGNAL(aboutToShow()), this, SLOT(updateCopyAttributesMenu())); - Qt::Key globalAutoTypeKey = static_cast(config()->get("GlobalAutoTypeKey").toInt()); + Qt::Key globalAutoTypeKey = static_cast(config()->get(Config::GlobalAutoTypeKey).toInt()); Qt::KeyboardModifiers globalAutoTypeModifiers = - static_cast(config()->get("GlobalAutoTypeModifiers").toInt()); + static_cast(config()->get(Config::GlobalAutoTypeModifiers).toInt()); if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) { autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers); } m_ui->toolbarSeparator->setVisible(false); - m_showToolbarSeparator = config()->get("GUI/ApplicationTheme").toString() != "classic"; + m_showToolbarSeparator = config()->get(Config::GUI_ApplicationTheme).toString() != "classic"; m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable()); @@ -549,13 +549,13 @@ MainWindow::MainWindow() MessageWidget::Information, 15000); #elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0)) - if (!config()->get("QtErrorMessageShown", false).toBool()) { + if (!config()->get(Config::Messages_Qt55CompatibilityWarning).toBool()) { m_ui->globalMessageWidget->showMessage( tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n" "We recommend you use the AppImage available on our downloads page."), MessageWidget::Warning, -1); - config()->set("QtErrorMessageShown", true); + config()->set(Config::Messages_Qt55CompatibilityWarning, true); } #endif } @@ -579,7 +579,7 @@ void MainWindow::updateLastDatabasesMenu() { m_ui->menuRecentDatabases->clear(); - const QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList(); + const QStringList lastDatabases = config()->get(Config::LastDatabases).toStringList(); for (const QString& database : lastDatabases) { QAction* action = m_ui->menuRecentDatabases->addAction(database); action->setData(database); @@ -620,7 +620,7 @@ void MainWindow::openRecentDatabase(QAction* action) void MainWindow::clearLastDatabases() { - config()->set("LastDatabases", QVariant()); + config()->remove(Config::LastDatabases); bool inWelcomeWidget = (m_ui->stackedWidget->currentIndex() == 2); if (inWelcomeWidget) { @@ -868,7 +868,7 @@ void MainWindow::showAboutDialog() void MainWindow::showUpdateCheckStartup() { #ifdef WITH_XC_UPDATECHECK - if (!config()->get("UpdateCheckMessageShown", false).toBool()) { + if (!config()->get(Config::UpdateCheckMessageShown).toBool()) { auto result = MessageBox::question(this, tr("Check for updates on startup?"), @@ -877,11 +877,11 @@ void MainWindow::showUpdateCheckStartup() MessageBox::Yes | MessageBox::No, MessageBox::Yes); - config()->set("GUI/CheckForUpdates", (result == MessageBox::Yes)); - config()->set("UpdateCheckMessageShown", true); + config()->set(Config::GUI_CheckForUpdates, (result == MessageBox::Yes)); + config()->set(Config::UpdateCheckMessageShown, true); } - if (config()->get("GUI/CheckForUpdates", false).toBool()) { + if (config()->get(Config::GUI_CheckForUpdates).toBool()) { updateCheck()->checkForUpdates(false); } @@ -1096,7 +1096,8 @@ void MainWindow::closeEvent(QCloseEvent* event) // Ignore event and hide to tray if this is not an actual close // request by the system's session manager. - if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled && !isHidden() && !qApp->isSavingSession()) { + if (config()->get(Config::GUI_MinimizeOnClose).toBool() && !m_appExitCalled && !isHidden() + && !qApp->isSavingSession()) { event->ignore(); hideWindow(); return; @@ -1118,12 +1119,12 @@ void MainWindow::changeEvent(QEvent* event) { if ((event->type() == QEvent::WindowStateChange) && isMinimized()) { if (isTrayIconEnabled() && m_trayIcon && m_trayIcon->isVisible() - && config()->get("GUI/MinimizeToTray").toBool()) { + && config()->get(Config::GUI_MinimizeToTray).toBool()) { event->ignore(); hide(); } - if (config()->get("security/lockdatabaseminimize").toBool()) { + if (config()->get(Config::Security_LockDatabaseMinimize).toBool()) { m_ui->tabWidget->lockDatabases(); } } else { @@ -1134,19 +1135,19 @@ void MainWindow::changeEvent(QEvent* event) void MainWindow::saveWindowInformation() { if (isVisible()) { - config()->set("GUI/MainWindowGeometry", saveGeometry()); - config()->set("GUI/MainWindowState", saveState()); + config()->set(Config::GUI_MainWindowGeometry, saveGeometry()); + config()->set(Config::GUI_MainWindowState, saveState()); } } bool MainWindow::saveLastDatabases() { - if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) { + if (config()->get(Config::OpenPreviousDatabasesOnStartup).toBool()) { auto currentDbWidget = m_ui->tabWidget->currentDatabaseWidget(); if (currentDbWidget) { - config()->set("LastActiveDatabase", currentDbWidget->database()->filePath()); + config()->set(Config::LastActiveDatabase, currentDbWidget->database()->filePath()); } else { - config()->set("LastActiveDatabase", {}); + config()->remove(Config::LastActiveDatabase); } QStringList openDatabases; @@ -1155,10 +1156,10 @@ bool MainWindow::saveLastDatabases() openDatabases.append(dbWidget->database()->filePath()); } - config()->set("LastOpenedDatabases", openDatabases); + config()->set(Config::LastOpenedDatabases, openDatabases); } else { - config()->set("LastActiveDatabase", {}); - config()->set("LastOpenedDatabases", {}); + config()->remove(Config::LastActiveDatabase); + config()->remove(Config::LastOpenedDatabases); } return m_ui->tabWidget->closeAllDatabaseTabs(); @@ -1169,9 +1170,9 @@ void MainWindow::updateTrayIcon() if (isTrayIconEnabled()) { if (!m_trayIcon) { m_trayIcon = new QSystemTrayIcon(this); - QMenu* menu = new QMenu(this); + auto* menu = new QMenu(this); - QAction* actionToggle = new QAction(tr("Toggle window"), menu); + auto* actionToggle = new QAction(tr("Toggle window"), menu); menu->addAction(actionToggle); actionToggle->setIcon(resources()->icon("keepassxc-dark", false)); @@ -1257,13 +1258,13 @@ void MainWindow::setShortcut(QAction* action, QKeySequence::StandardKey standard void MainWindow::applySettingsChanges() { - int timeout = config()->get("security/lockdatabaseidlesec").toInt() * 1000; + int timeout = config()->get(Config::Security_LockDatabaseIdleSeconds).toInt() * 1000; if (timeout <= 0) { timeout = 60; } m_inactivityTimer->setInactivityTimeout(timeout); - if (config()->get("security/lockdatabaseidle").toBool()) { + if (config()->get(Config::Security_LockDatabaseIdle).toBool()) { m_inactivityTimer->activate(); } else { m_inactivityTimer->deactivate(); @@ -1271,24 +1272,25 @@ void MainWindow::applySettingsChanges() #ifdef WITH_XC_TOUCHID // forget TouchID (in minutes) - timeout = config()->get("security/resettouchidtimeout").toInt() * 60 * 1000; + timeout = config()->get(Config::Security_ResetTouchIdTimeout).toInt() * 60 * 1000; if (timeout <= 0) { timeout = 30 * 60 * 1000; } m_touchIDinactivityTimer->setInactivityTimeout(timeout); - if (config()->get("security/resettouchid").toBool()) { + if (config()->get(Config::Security_ResetTouchIdTimeout).toBool()) { m_touchIDinactivityTimer->activate(); } else { m_touchIDinactivityTimer->deactivate(); } #endif - m_ui->toolBar->setHidden(config()->get("GUI/HideToolbar").toBool()); - m_ui->toolBar->setMovable(config()->get("GUI/MovableToolbar").toBool()); + m_ui->toolBar->setHidden(config()->get(Config::GUI_HideToolbar).toBool()); + m_ui->toolBar->setMovable(config()->get(Config::GUI_MovableToolbar).toBool()); bool isOk = false; - const auto toolButtonStyle = static_cast(config()->get("GUI/ToolButtonStyle").toInt(&isOk)); + const auto toolButtonStyle = + static_cast(config()->get(Config::GUI_ToolButtonStyle).toInt(&isOk)); if (isOk) { m_ui->toolBar->setToolButtonStyle(toolButtonStyle); } @@ -1381,14 +1383,14 @@ void MainWindow::hideWindow() showMinimized(); } - if (config()->get("security/lockdatabaseminimize").toBool()) { + if (config()->get(Config::Security_LockDatabaseMinimize).toBool()) { m_ui->tabWidget->lockDatabases(); } } void MainWindow::minimizeOrHide() { - if (config()->get("GUI/MinimizeToTray").toBool()) { + if (config()->get(Config::GUI_MinimizeToTray).toBool()) { hideWindow(); } else { showMinimized(); @@ -1444,7 +1446,7 @@ void MainWindow::forgetTouchIDAfterInactivity() bool MainWindow::isTrayIconEnabled() const { - return config()->get("GUI/ShowTrayIcon").toBool() && QSystemTrayIcon::isSystemTrayAvailable(); + return config()->get(Config::GUI_ShowTrayIcon).toBool() && QSystemTrayIcon::isSystemTrayAvailable(); } void MainWindow::displayGlobalMessage(const QString& text, @@ -1495,12 +1497,12 @@ void MainWindow::bringToFront() void MainWindow::handleScreenLock() { - if (config()->get("security/lockdatabasescreenlock").toBool()) { + if (config()->get(Config::Security_LockDatabaseScreenLock).toBool()) { lockDatabasesAfterInactivity(); } #ifdef WITH_XC_TOUCHID - if (config()->get("security/resettouchidscreenlock").toBool()) { + if (config()->get(Config::Security_ResetTouchIdScreenlock).toBool()) { forgetTouchIDAfterInactivity(); } #endif diff --git a/src/gui/PasswordEdit.cpp b/src/gui/PasswordEdit.cpp index 83b5de36f..89c4fef51 100644 --- a/src/gui/PasswordEdit.cpp +++ b/src/gui/PasswordEdit.cpp @@ -106,7 +106,7 @@ void PasswordEdit::setShowPassword(bool show) if (m_repeatPasswordEdit) { m_repeatPasswordEdit->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); - if (config()->get("security/passwordsrepeat").toBool()) { + if (config()->get(Config::Security_PasswordsRepeat).toBool()) { m_repeatPasswordEdit->setEnabled(!show); m_repeatPasswordEdit->setText(text()); } else { @@ -161,7 +161,7 @@ void PasswordEdit::updateRepeatStatus() void PasswordEdit::autocompletePassword(const QString& password) { - if (config()->get("security/passwordsrepeat").toBool() && echoMode() == QLineEdit::Normal) { + if (config()->get(Config::Security_PasswordsRepeat).toBool() && echoMode() == QLineEdit::Normal) { setText(password); } } diff --git a/src/gui/PasswordGeneratorWidget.cpp b/src/gui/PasswordGeneratorWidget.cpp index 669a96d33..edcf41d6f 100644 --- a/src/gui/PasswordGeneratorWidget.cpp +++ b/src/gui/PasswordGeneratorWidget.cpp @@ -123,88 +123,76 @@ PasswordGeneratorWidget* PasswordGeneratorWidget::popupGenerator(QWidget* parent void PasswordGeneratorWidget::loadSettings() { // Password config - m_ui->checkBoxLower->setChecked(config()->get("generator/LowerCase", PasswordGenerator::DefaultLower).toBool()); - m_ui->checkBoxLowerAdv->setChecked(config()->get("generator/LowerCase", PasswordGenerator::DefaultLower).toBool()); - m_ui->checkBoxUpper->setChecked(config()->get("generator/UpperCase", PasswordGenerator::DefaultUpper).toBool()); - m_ui->checkBoxUpperAdv->setChecked(config()->get("generator/UpperCase", PasswordGenerator::DefaultUpper).toBool()); - m_ui->checkBoxNumbers->setChecked(config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool()); - m_ui->checkBoxSpecialChars->setChecked( - config()->get("generator/SpecialChars", PasswordGenerator::DefaultSpecial).toBool()); - m_ui->checkBoxNumbersAdv->setChecked( - config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool()); - m_ui->editAdditionalChars->setText( - config()->get("generator/AdditionalChars", PasswordGenerator::DefaultAdditionalChars).toString()); - m_ui->editExcludedChars->setText( - config()->get("generator/ExcludedChars", PasswordGenerator::DefaultExcludedChars).toString()); + m_ui->checkBoxLower->setChecked(config()->get(Config::PasswordGenerator_LowerCase).toBool()); + m_ui->checkBoxLowerAdv->setChecked(config()->get(Config::PasswordGenerator_LowerCase).toBool()); + m_ui->checkBoxUpper->setChecked(config()->get(Config::PasswordGenerator_UpperCase).toBool()); + m_ui->checkBoxUpperAdv->setChecked(config()->get(Config::PasswordGenerator_UpperCase).toBool()); + m_ui->checkBoxNumbers->setChecked(config()->get(Config::PasswordGenerator_Numbers).toBool()); + m_ui->checkBoxSpecialChars->setChecked(config()->get(Config::PasswordGenerator_SpecialChars).toBool()); + m_ui->checkBoxNumbersAdv->setChecked(config()->get(Config::PasswordGenerator_Numbers).toBool()); + m_ui->editAdditionalChars->setText(config()->get(Config::PasswordGenerator_AdditionalChars).toString()); + m_ui->editExcludedChars->setText(config()->get(Config::PasswordGenerator_ExcludedChars).toString()); - m_ui->buttonAdvancedMode->setChecked( - config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool()); + m_ui->buttonAdvancedMode->setChecked(config()->get(Config::PasswordGenerator_AdvancedMode).toBool()); setAdvancedMode(m_ui->buttonAdvancedMode->isChecked()); - m_ui->checkBoxBraces->setChecked(config()->get("generator/Braces", PasswordGenerator::DefaultBraces).toBool()); - m_ui->checkBoxQuotes->setChecked(config()->get("generator/Quotes", PasswordGenerator::DefaultQuotes).toBool()); - m_ui->checkBoxPunctuation->setChecked( - config()->get("generator/Punctuation", PasswordGenerator::DefaultPunctuation).toBool()); - m_ui->checkBoxDashes->setChecked(config()->get("generator/Dashes", PasswordGenerator::DefaultDashes).toBool()); - m_ui->checkBoxMath->setChecked(config()->get("generator/Math", PasswordGenerator::DefaultMath).toBool()); - m_ui->checkBoxLogograms->setChecked( - config()->get("generator/Logograms", PasswordGenerator::DefaultLogograms).toBool()); - m_ui->checkBoxExtASCII->setChecked(config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool()); - m_ui->checkBoxExtASCIIAdv->setChecked(config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool()); - m_ui->checkBoxExcludeAlike->setChecked( - config()->get("generator/ExcludeAlike", PasswordGenerator::DefaultLookAlike).toBool()); - m_ui->checkBoxEnsureEvery->setChecked( - config()->get("generator/EnsureEvery", PasswordGenerator::DefaultFromEveryGroup).toBool()); - m_ui->spinBoxLength->setValue(config()->get("generator/Length", PasswordGenerator::DefaultLength).toInt()); + m_ui->checkBoxBraces->setChecked(config()->get(Config::PasswordGenerator_Braces).toBool()); + m_ui->checkBoxQuotes->setChecked(config()->get(Config::PasswordGenerator_Quotes).toBool()); + m_ui->checkBoxPunctuation->setChecked(config()->get(Config::PasswordGenerator_Punctuation).toBool()); + m_ui->checkBoxDashes->setChecked(config()->get(Config::PasswordGenerator_Dashes).toBool()); + m_ui->checkBoxMath->setChecked(config()->get(Config::PasswordGenerator_Math).toBool()); + m_ui->checkBoxLogograms->setChecked(config()->get(Config::PasswordGenerator_Logograms).toBool()); + m_ui->checkBoxExtASCII->setChecked(config()->get(Config::PasswordGenerator_EASCII).toBool()); + m_ui->checkBoxExtASCIIAdv->setChecked(config()->get(Config::PasswordGenerator_EASCII).toBool()); + m_ui->checkBoxExcludeAlike->setChecked(config()->get(Config::PasswordGenerator_ExcludeAlike).toBool()); + m_ui->checkBoxEnsureEvery->setChecked(config()->get(Config::PasswordGenerator_EnsureEvery).toBool()); + m_ui->spinBoxLength->setValue(config()->get(Config::PasswordGenerator_Length).toInt()); // Diceware config - m_ui->spinBoxWordCount->setValue( - config()->get("generator/WordCount", PassphraseGenerator::DefaultWordCount).toInt()); - m_ui->editWordSeparator->setText( - config()->get("generator/WordSeparator", PassphraseGenerator::DefaultSeparator).toString()); - m_ui->comboBoxWordList->setCurrentText( - config()->get("generator/WordList", PassphraseGenerator::DefaultWordList).toString()); - m_ui->wordCaseComboBox->setCurrentIndex(config()->get("generator/WordCase", 0).toInt()); + m_ui->spinBoxWordCount->setValue(config()->get(Config::PasswordGenerator_WordCount).toInt()); + m_ui->editWordSeparator->setText(config()->get(Config::PasswordGenerator_WordSeparator).toString()); + m_ui->comboBoxWordList->setCurrentText(config()->get(Config::PasswordGenerator_WordList).toString()); + m_ui->wordCaseComboBox->setCurrentIndex(config()->get(Config::PasswordGenerator_WordCase).toInt()); // Password or diceware? - m_ui->tabWidget->setCurrentIndex(config()->get("generator/Type", 0).toInt()); + m_ui->tabWidget->setCurrentIndex(config()->get(Config::PasswordGenerator_Type).toInt()); } void PasswordGeneratorWidget::saveSettings() { // Password config if (m_ui->simpleBar->isVisible()) { - config()->set("generator/LowerCase", m_ui->checkBoxLower->isChecked()); - config()->set("generator/UpperCase", m_ui->checkBoxUpper->isChecked()); - config()->set("generator/Numbers", m_ui->checkBoxNumbers->isChecked()); - config()->set("generator/EASCII", m_ui->checkBoxExtASCII->isChecked()); + config()->set(Config::PasswordGenerator_LowerCase, m_ui->checkBoxLower->isChecked()); + config()->set(Config::PasswordGenerator_UpperCase, m_ui->checkBoxUpper->isChecked()); + config()->set(Config::PasswordGenerator_Numbers, m_ui->checkBoxNumbers->isChecked()); + config()->set(Config::PasswordGenerator_EASCII, m_ui->checkBoxExtASCII->isChecked()); } else { - config()->set("generator/LowerCase", m_ui->checkBoxLowerAdv->isChecked()); - config()->set("generator/UpperCase", m_ui->checkBoxUpperAdv->isChecked()); - config()->set("generator/Numbers", m_ui->checkBoxNumbersAdv->isChecked()); - config()->set("generator/EASCII", m_ui->checkBoxExtASCIIAdv->isChecked()); + config()->set(Config::PasswordGenerator_LowerCase, m_ui->checkBoxLowerAdv->isChecked()); + config()->set(Config::PasswordGenerator_UpperCase, m_ui->checkBoxUpperAdv->isChecked()); + config()->set(Config::PasswordGenerator_Numbers, m_ui->checkBoxNumbersAdv->isChecked()); + config()->set(Config::PasswordGenerator_EASCII, m_ui->checkBoxExtASCIIAdv->isChecked()); } - config()->set("generator/AdvancedMode", m_ui->buttonAdvancedMode->isChecked()); - config()->set("generator/SpecialChars", m_ui->checkBoxSpecialChars->isChecked()); - config()->set("generator/Braces", m_ui->checkBoxBraces->isChecked()); - config()->set("generator/Punctuation", m_ui->checkBoxPunctuation->isChecked()); - config()->set("generator/Quotes", m_ui->checkBoxQuotes->isChecked()); - config()->set("generator/Dashes", m_ui->checkBoxDashes->isChecked()); - config()->set("generator/Math", m_ui->checkBoxMath->isChecked()); - config()->set("generator/Logograms", m_ui->checkBoxLogograms->isChecked()); - config()->set("generator/ExcludedChars", m_ui->editExcludedChars->text()); - config()->set("generator/ExcludeAlike", m_ui->checkBoxExcludeAlike->isChecked()); - config()->set("generator/EnsureEvery", m_ui->checkBoxEnsureEvery->isChecked()); - config()->set("generator/Length", m_ui->spinBoxLength->value()); + config()->set(Config::PasswordGenerator_AdvancedMode, m_ui->buttonAdvancedMode->isChecked()); + config()->set(Config::PasswordGenerator_SpecialChars, m_ui->checkBoxSpecialChars->isChecked()); + config()->set(Config::PasswordGenerator_Braces, m_ui->checkBoxBraces->isChecked()); + config()->set(Config::PasswordGenerator_Punctuation, m_ui->checkBoxPunctuation->isChecked()); + config()->set(Config::PasswordGenerator_Quotes, m_ui->checkBoxQuotes->isChecked()); + config()->set(Config::PasswordGenerator_Dashes, m_ui->checkBoxDashes->isChecked()); + config()->set(Config::PasswordGenerator_Math, m_ui->checkBoxMath->isChecked()); + config()->set(Config::PasswordGenerator_Logograms, m_ui->checkBoxLogograms->isChecked()); + config()->set(Config::PasswordGenerator_ExcludedChars, m_ui->editExcludedChars->text()); + config()->set(Config::PasswordGenerator_ExcludeAlike, m_ui->checkBoxExcludeAlike->isChecked()); + config()->set(Config::PasswordGenerator_EnsureEvery, m_ui->checkBoxEnsureEvery->isChecked()); + config()->set(Config::PasswordGenerator_Length, m_ui->spinBoxLength->value()); // Diceware config - config()->set("generator/WordCount", m_ui->spinBoxWordCount->value()); - config()->set("generator/WordSeparator", m_ui->editWordSeparator->text()); - config()->set("generator/WordList", m_ui->comboBoxWordList->currentText()); - config()->set("generator/WordCase", m_ui->wordCaseComboBox->currentIndex()); + config()->set(Config::PasswordGenerator_WordCount, m_ui->spinBoxWordCount->value()); + config()->set(Config::PasswordGenerator_WordSeparator, m_ui->editWordSeparator->text()); + config()->set(Config::PasswordGenerator_WordList, m_ui->comboBoxWordList->currentText()); + config()->set(Config::PasswordGenerator_WordCase, m_ui->wordCaseComboBox->currentIndex()); // Password or diceware? - config()->set("generator/Type", m_ui->tabWidget->currentIndex()); + config()->set(Config::PasswordGenerator_Type, m_ui->tabWidget->currentIndex()); } void PasswordGeneratorWidget::setPasswordLength(int length) @@ -212,7 +200,7 @@ void PasswordGeneratorWidget::setPasswordLength(int length) if (length > 0) { m_ui->spinBoxLength->setValue(length); } else { - m_ui->spinBoxLength->setValue(config()->get("generator/Length", PasswordGenerator::DefaultLength).toInt()); + m_ui->spinBoxLength->setValue(config()->get(Config::PasswordGenerator_Length).toInt()); } } diff --git a/src/gui/SearchWidget.cpp b/src/gui/SearchWidget.cpp index 3702266b4..8425ab2d0 100644 --- a/src/gui/SearchWidget.cpp +++ b/src/gui/SearchWidget.cpp @@ -67,7 +67,7 @@ SearchWidget::SearchWidget(QWidget* parent) m_actionLimitGroup = m_searchMenu->addAction(tr("Limit search to selected group"), this, SLOT(updateLimitGroup())); m_actionLimitGroup->setObjectName("actionSearchLimitGroup"); m_actionLimitGroup->setCheckable(true); - m_actionLimitGroup->setChecked(config()->get("SearchLimitGroup", false).toBool()); + m_actionLimitGroup->setChecked(config()->get(Config::SearchLimitGroup).toBool()); m_ui->searchIcon->setIcon(resources()->icon("system-search")); m_ui->searchEdit->addAction(m_ui->searchIcon, QLineEdit::LeadingPosition); @@ -115,8 +115,8 @@ bool SearchWidget::eventFilter(QObject* obj, QEvent* event) } } } else if (event->type() == QEvent::FocusOut && !m_ui->searchEdit->text().isEmpty()) { - if (config()->get("security/clearsearch").toBool()) { - int timeout = config()->get("security/clearsearchtimeout").toInt(); + if (config()->get(Config::Security_ClearSearch).toBool()) { + int timeout = config()->get(Config::Security_ClearSearchTimeout).toInt(); if (timeout > 0) { // Auto-clear search after set timeout (5 minutes by default) m_clearSearchTimer->start(timeout * 60000); // 60 sec * 1000 ms @@ -200,7 +200,7 @@ void SearchWidget::setCaseSensitive(bool state) void SearchWidget::updateLimitGroup() { - config()->set("SearchLimitGroup", m_actionLimitGroup->isChecked()); + config()->set(Config::SearchLimitGroup, m_actionLimitGroup->isChecked()); emit limitGroupChanged(m_actionLimitGroup->isChecked()); } diff --git a/src/gui/TotpDialog.cpp b/src/gui/TotpDialog.cpp index 7292cfcd3..871c2863c 100644 --- a/src/gui/TotpDialog.cpp +++ b/src/gui/TotpDialog.cpp @@ -65,10 +65,10 @@ TotpDialog::~TotpDialog() void TotpDialog::copyToClipboard() { clipboard()->setText(m_entry->totp()); - if (config()->get("HideWindowOnCopy").toBool()) { - if (config()->get("MinimizeOnCopy").toBool()) { + if (config()->get(Config::HideWindowOnCopy).toBool()) { + if (config()->get(Config::MinimizeOnCopy).toBool()) { getMainWindow()->minimizeOrHide(); - } else if (config()->get("DropToBackgroundOnCopy").toBool()) { + } else if (config()->get(Config::DropToBackgroundOnCopy).toBool()) { getMainWindow()->lower(); window()->lower(); } diff --git a/src/gui/TotpExportSettingsDialog.cpp b/src/gui/TotpExportSettingsDialog.cpp index ea14eabdb..f73b9877a 100644 --- a/src/gui/TotpExportSettingsDialog.cpp +++ b/src/gui/TotpExportSettingsDialog.cpp @@ -103,10 +103,10 @@ TotpExportSettingsDialog::TotpExportSettingsDialog(DatabaseWidget* parent, Entry void TotpExportSettingsDialog::copyToClipboard() { clipboard()->setText(m_totpUri); - if (config()->get("HideWindowOnCopy").toBool()) { - if (config()->get("MinimizeOnCopy").toBool()) { + if (config()->get(Config::HideWindowOnCopy).toBool()) { + if (config()->get(Config::MinimizeOnCopy).toBool()) { getMainWindow()->minimizeOrHide(); - } else if (config()->get("DropToBackgroundOnCopy").toBool()) { + } else if (config()->get(Config::DropToBackgroundOnCopy).toBool()) { getMainWindow()->lower(); window()->lower(); } diff --git a/src/gui/WelcomeWidget.cpp b/src/gui/WelcomeWidget.cpp index 25d261ea7..75356979a 100644 --- a/src/gui/WelcomeWidget.cpp +++ b/src/gui/WelcomeWidget.cpp @@ -71,7 +71,7 @@ void WelcomeWidget::openDatabaseFromFile(QListWidgetItem* item) void WelcomeWidget::refreshLastDatabases() { m_ui->recentListWidget->clear(); - const QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList(); + const QStringList lastDatabases = config()->get(Config::LastDatabases).toStringList(); for (const QString& database : lastDatabases) { QListWidgetItem* itm = new QListWidgetItem; itm->setText(database); diff --git a/src/gui/dbsettings/DatabaseSettingsDialog.cpp b/src/gui/dbsettings/DatabaseSettingsDialog.cpp index d2eece319..bfb7031b4 100644 --- a/src/gui/dbsettings/DatabaseSettingsDialog.cpp +++ b/src/gui/dbsettings/DatabaseSettingsDialog.cpp @@ -123,7 +123,7 @@ void DatabaseSettingsDialog::load(const QSharedPointer& db) for (const ExtraPage& page : asConst(m_extraPages)) { page.loadSettings(db); } - m_ui->advancedSettingsToggle->setChecked(config()->get("GUI/AdvancedSettings", false).toBool()); + m_ui->advancedSettingsToggle->setChecked(config()->get(Config::GUI_AdvancedSettings).toBool()); m_db = db; } @@ -206,5 +206,5 @@ void DatabaseSettingsDialog::toggleAdvancedMode(bool advanced) m_encryptionWidget->setAdvancedMode(advanced); } - config()->set("GUI/AdvancedSettings", advanced); + config()->set(Config::GUI_AdvancedSettings, advanced); } diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 780f90996..90b49b3da 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -257,7 +257,7 @@ void EditEntryWidget::setupBrowser() { m_browserUi->setupUi(m_browserWidget); - if (config()->get("Browser/Enabled", false).toBool()) { + if (config()->get(Config::Browser_Enabled).toBool()) { addPage(tr("Browser Integration"), Resources::instance()->icon("internet-web-browser"), m_browserWidget); m_additionalURLsDataModel->setEntryAttributes(m_entryAttributes); m_browserUi->additionalURLsView->setModel(m_additionalURLsDataModel); @@ -459,7 +459,7 @@ void EditEntryWidget::setupEntryUpdate() #endif #ifdef WITH_XC_BROWSER - if (config()->get("Browser/Enabled", false).toBool()) { + if (config()->get(Config::Browser_Enabled).toBool()) { connect(m_browserUi->skipAutoSubmitCheckbox, SIGNAL(toggled(bool)), SLOT(setModified())); connect(m_browserUi->hideEntryCheckbox, SIGNAL(toggled(bool)), SLOT(setModified())); connect(m_browserUi->onlyHttpAuthCheckbox, SIGNAL(toggled(bool)), SLOT(setModified())); @@ -805,11 +805,11 @@ void EditEntryWidget::setForms(Entry* entry, bool restore) m_mainUi->passwordEdit->setReadOnly(m_history); m_mainUi->expireCheck->setEnabled(!m_history); m_mainUi->expireDatePicker->setReadOnly(m_history); - m_mainUi->notesEnabled->setChecked(!config()->get("security/hidenotes").toBool()); + m_mainUi->notesEnabled->setChecked(!config()->get(Config::Security_HideNotes).toBool()); m_mainUi->notesEdit->setReadOnly(m_history); - m_mainUi->notesEdit->setVisible(!config()->get("security/hidenotes").toBool()); - m_mainUi->notesHint->setVisible(config()->get("security/hidenotes").toBool()); - if (config()->get("GUI/MonospaceNotes", false).toBool()) { + m_mainUi->notesEdit->setVisible(!config()->get(Config::Security_HideNotes).toBool()); + m_mainUi->notesHint->setVisible(config()->get(Config::Security_HideNotes).toBool()); + if (config()->get(Config::GUI_MonospaceNotes).toBool()) { m_mainUi->notesEdit->setFont(Font::fixedFont()); } else { m_mainUi->notesEdit->setFont(Font::defaultFont()); @@ -839,7 +839,7 @@ void EditEntryWidget::setForms(Entry* entry, bool restore) m_mainUi->usernameComboBox->lineEdit()->setText(entry->username()); m_mainUi->urlEdit->setText(entry->url()); m_mainUi->passwordEdit->setText(entry->password()); - m_mainUi->passwordEdit->setShowPassword(config()->get("security/passwordscleartext").toBool()); + m_mainUi->passwordEdit->setShowPassword(config()->get(Config::Security_PasswordsCleartext).toBool()); if (!m_history) { m_mainUi->passwordEdit->enablePasswordGenerator(); } @@ -984,7 +984,7 @@ bool EditEntryWidget::commitEntry() #endif #ifdef WITH_XC_BROWSER - if (config()->get("Browser/Enabled", false).toBool()) { + if (config()->get(Config::Browser_Enabled).toBool()) { updateBrowser(); } #endif diff --git a/src/gui/entry/EntryAttachmentsWidget.cpp b/src/gui/entry/EntryAttachmentsWidget.cpp index 9610cc05b..8b77129e5 100644 --- a/src/gui/entry/EntryAttachmentsWidget.cpp +++ b/src/gui/entry/EntryAttachmentsWidget.cpp @@ -135,7 +135,7 @@ void EntryAttachmentsWidget::insertAttachments() return; } - QString defaultDirPath = config()->get("LastAttachmentDir").toString(); + QString defaultDirPath = config()->get(Config::LastAttachmentDir).toString(); const bool dirExists = !defaultDirPath.isEmpty() && QDir(defaultDirPath).exists(); if (!dirExists) { defaultDirPath = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(); @@ -146,7 +146,7 @@ void EntryAttachmentsWidget::insertAttachments() return; } - config()->set("LastAttachmentDir", QFileInfo(filenames.first()).absolutePath()); + config()->set(Config::LastAttachmentDir, QFileInfo(filenames.first()).absolutePath()); QString errorMessage; if (!insertAttachments(filenames, errorMessage)) { @@ -190,7 +190,7 @@ void EntryAttachmentsWidget::saveSelectedAttachments() return; } - QString defaultDirPath = config()->get("LastAttachmentDir").toString(); + QString defaultDirPath = config()->get(Config::LastAttachmentDir).toString(); const bool dirExists = !defaultDirPath.isEmpty() && QDir(defaultDirPath).exists(); if (!dirExists) { defaultDirPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); @@ -208,7 +208,7 @@ void EntryAttachmentsWidget::saveSelectedAttachments() return; } } - config()->set("LastAttachmentDir", QFileInfo(saveDir.absolutePath()).absolutePath()); + config()->set(Config::LastAttachmentDir, QFileInfo(saveDir.absolutePath()).absolutePath()); QStringList errors; for (const QModelIndex& index : indexes) { diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp index 82bbafc4f..ae520035e 100644 --- a/src/gui/entry/EntryModel.cpp +++ b/src/gui/entry/EntryModel.cpp @@ -174,7 +174,7 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const if (attr->isReference(EntryAttributes::PasswordKey)) { result.prepend(tr("Ref: ", "Reference abbreviation")); } - if (entry->password().isEmpty() && config()->get("security/passwordemptynodots").toBool()) { + if (entry->password().isEmpty() && config()->get(Config::Security_PasswordEmptyNoDots).toBool()) { result = ""; } return result; @@ -186,7 +186,7 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const return result; case Notes: // Display only first line of notes in simplified format if not hidden - if (config()->get("security/hidenotes").toBool()) { + if (config()->get(Config::Security_HideNotes).toBool()) { result = EntryModel::HiddenContentDisplay; } else { result = entry->notes().section("\n", 0, 0).simplified(); diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp index 8d8115649..f77ae92d8 100644 --- a/src/gui/group/EditGroupWidget.cpp +++ b/src/gui/group/EditGroupWidget.cpp @@ -153,7 +153,7 @@ void EditGroupWidget::loadGroup(Group* group, bool create, const QSharedPointer< } m_mainUi->autoTypeSequenceCustomEdit->setText(group->effectiveAutoTypeSequence()); - if (config()->get("GUI/MonospaceNotes", false).toBool()) { + if (config()->get(Config::GUI_MonospaceNotes).toBool()) { m_mainUi->editNotes->setFont(Font::fixedFont()); } else { m_mainUi->editNotes->setFont(Font::defaultFont()); diff --git a/src/keeshare/KeeShare.cpp b/src/keeshare/KeeShare.cpp index 3199f355c..567558bdc 100644 --- a/src/keeshare/KeeShare.cpp +++ b/src/keeshare/KeeShare.cpp @@ -16,7 +16,6 @@ */ #include "KeeShare.h" -#include "core/Config.h" #include "core/CustomData.h" #include "core/Database.h" #include "core/DatabaseIcons.h" @@ -33,10 +32,7 @@ namespace { static const QString KeeShare_Reference("KeeShare/Reference"); - static const QString KeeShare_Own("KeeShare/Settings.own"); - static const QString KeeShare_Foreign("KeeShare/Settings.foreign"); - static const QString KeeShare_Active("KeeShare/Settings.active"); -} // namespace +} KeeShare* KeeShare::m_instance = nullptr; @@ -52,7 +48,7 @@ KeeShare* KeeShare::instance() KeeShare::KeeShare(QObject* parent) : QObject(parent) { - connect(config(), SIGNAL(changed(QString)), SLOT(handleSettingsChanged(QString))); + connect(config(), SIGNAL(changed(Config::ConfigKey)), SLOT(handleSettingsChanged(Config::ConfigKey))); } void KeeShare::init(QObject* parent) @@ -63,32 +59,32 @@ void KeeShare::init(QObject* parent) KeeShareSettings::Own KeeShare::own() { - return KeeShareSettings::Own::deserialize(config()->get(KeeShare_Own).toString()); + return KeeShareSettings::Own::deserialize(config()->get(Config::KeeShare_Own).toString()); } KeeShareSettings::Active KeeShare::active() { - return KeeShareSettings::Active::deserialize(config()->get(KeeShare_Active).toString()); + return KeeShareSettings::Active::deserialize(config()->get(Config::KeeShare_Active).toString()); } KeeShareSettings::Foreign KeeShare::foreign() { - return KeeShareSettings::Foreign::deserialize(config()->get(KeeShare_Foreign).toString()); + return KeeShareSettings::Foreign::deserialize(config()->get(Config::KeeShare_Foreign).toString()); } void KeeShare::setForeign(const KeeShareSettings::Foreign& foreign) { - config()->set(KeeShare_Foreign, KeeShareSettings::Foreign::serialize(foreign)); + config()->set(Config::KeeShare_Foreign, KeeShareSettings::Foreign::serialize(foreign)); } void KeeShare::setActive(const KeeShareSettings::Active& active) { - config()->set(KeeShare_Active, KeeShareSettings::Active::serialize(active)); + config()->set(Config::KeeShare_Active, KeeShareSettings::Active::serialize(active)); } void KeeShare::setOwn(const KeeShareSettings::Own& own) { - config()->set(KeeShare_Own, KeeShareSettings::Own::serialize(own)); + config()->set(Config::KeeShare_Own, KeeShareSettings::Own::serialize(own)); } bool KeeShare::isShared(const Group* group) @@ -122,7 +118,6 @@ void KeeShare::setReferenceTo(Group* group, const KeeShareSettings::Reference& r } const auto serialized = KeeShareSettings::Reference::serialize(reference); const auto encoded = serialized.toUtf8().toBase64(); - customData->set(KeeShare_Reference, encoded); } bool KeeShare::isEnabled(const Group* group) @@ -263,9 +258,9 @@ bool KeeShare::isContainerType(const QFileInfo& fileInfo, const QString type) return fileInfo.fileName().endsWith(type, Qt::CaseInsensitive); } -void KeeShare::handleSettingsChanged(const QString& key) +void KeeShare::handleSettingsChanged(Config::ConfigKey key) { - if (key == KeeShare_Active) { + if (key == Config::KeeShare_Active) { emit activeChanged(); } } diff --git a/src/keeshare/KeeShare.h b/src/keeshare/KeeShare.h index 597ce73a6..952711dbf 100644 --- a/src/keeshare/KeeShare.h +++ b/src/keeshare/KeeShare.h @@ -21,6 +21,7 @@ #include #include +#include "core/Config.h" #include "gui/MessageWidget.h" #include "keeshare/KeeShareSettings.h" @@ -70,7 +71,7 @@ signals: void sharingMessage(QString, MessageWidget::MessageType); private slots: - void handleSettingsChanged(const QString&); + void handleSettingsChanged(Config::ConfigKey key); private: static KeeShare* m_instance; diff --git a/src/keeshare/SettingsWidgetKeeShare.cpp b/src/keeshare/SettingsWidgetKeeShare.cpp index 2ae8b0889..424e78c4b 100644 --- a/src/keeshare/SettingsWidgetKeeShare.cpp +++ b/src/keeshare/SettingsWidgetKeeShare.cpp @@ -120,7 +120,7 @@ void SettingsWidgetKeeShare::saveSettings() KeeShare::setForeign(m_foreign); KeeShare::setActive(active); - config()->set("KeeShare/QuietSuccess", m_ui->quietSuccessCheckBox->isChecked()); + config()->set(Config::KeeShare_QuietSuccess, m_ui->quietSuccessCheckBox->isChecked()); } void SettingsWidgetKeeShare::setVerificationExporter(const QString& signer) @@ -140,7 +140,7 @@ void SettingsWidgetKeeShare::generateCertificate() void SettingsWidgetKeeShare::importCertificate() { - QString defaultDirPath = config()->get("KeeShare/LastKeyDir").toString(); + QString defaultDirPath = config()->get(Config::KeeShare_LastKeyDir).toString(); const bool dirExists = !defaultDirPath.isEmpty() && QDir(defaultDirPath).exists(); if (!dirExists) { defaultDirPath = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(); @@ -157,7 +157,7 @@ void SettingsWidgetKeeShare::importCertificate() QTextStream stream(&file); m_own = KeeShareSettings::Own::deserialize(stream.readAll()); file.close(); - config()->set("KeeShare/LastKeyDir", QFileInfo(filename).absolutePath()); + config()->set(Config::KeeShare_LastKeyDir, QFileInfo(filename).absolutePath()); updateOwnCertificate(); } @@ -178,7 +178,7 @@ void SettingsWidgetKeeShare::exportCertificate() return; } } - QString defaultDirPath = config()->get("KeeShare/LastKeyDir").toString(); + QString defaultDirPath = config()->get(Config::KeeShare_LastKeyDir).toString(); const bool dirExists = !defaultDirPath.isEmpty() && QDir(defaultDirPath).exists(); if (!dirExists) { defaultDirPath = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(); @@ -197,7 +197,7 @@ void SettingsWidgetKeeShare::exportCertificate() stream << KeeShareSettings::Own::serialize(m_own); stream.flush(); file.close(); - config()->set("KeeShare/LastKeyDir", QFileInfo(filename).absolutePath()); + config()->set(Config::KeeShare_LastKeyDir, QFileInfo(filename).absolutePath()); } void SettingsWidgetKeeShare::trustSelectedCertificates() diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 80033bf3a..c4c37b916 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -154,7 +154,7 @@ void ShareObserver::notifyAbout(const QStringList& success, const QStringList& w { QStringList messages; MessageWidget::MessageType type = MessageWidget::Positive; - if (!(success.isEmpty() || config()->get("KeeShare/QuietSuccess", true).toBool())) { + if (!(success.isEmpty() || config()->get(Config::KeeShare_QuietSuccess).toBool())) { messages += success; } if (!warning.isEmpty()) { diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.cpp b/src/keeshare/group/EditGroupWidgetKeeShare.cpp index 806d75c1a..16fbce07f 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.cpp +++ b/src/keeshare/group/EditGroupWidgetKeeShare.cpp @@ -221,7 +221,7 @@ void EditGroupWidgetKeeShare::launchPathSelectionDialog() if (!m_temporaryGroup) { return; } - QString defaultDirPath = config()->get("KeeShare/LastShareDir").toString(); + QString defaultDirPath = config()->get(Config::KeeShare_LastShareDir).toString(); const bool dirExists = !defaultDirPath.isEmpty() && QDir(defaultDirPath).exists(); if (!dirExists) { defaultDirPath = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(); @@ -285,7 +285,7 @@ void EditGroupWidgetKeeShare::launchPathSelectionDialog() m_ui->pathEdit->setText(filename); selectPath(); - config()->set("KeeShare/LastShareDir", QFileInfo(filename).absolutePath()); + config()->set(Config::KeeShare_LastShareDir, QFileInfo(filename).absolutePath()); } void EditGroupWidgetKeeShare::selectPassword() diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index cf7fd2522..bde8520fb 100644 --- a/src/sshagent/SSHAgent.cpp +++ b/src/sshagent/SSHAgent.cpp @@ -43,7 +43,7 @@ SSHAgent* SSHAgent::instance() bool SSHAgent::isEnabled() const { - return config()->get("SSHAgent").toBool(); + return config()->get(Config::SSHAgent_Enabled).toBool(); } void SSHAgent::setEnabled(bool enabled) @@ -52,30 +52,30 @@ void SSHAgent::setEnabled(bool enabled) removeAllIdentities(); } - config()->set("SSHAgent", enabled); + config()->set(Config::SSHAgent_Enabled, enabled); emit enabledChanged(enabled); } QString SSHAgent::authSockOverride() const { - return config()->get("SSHAuthSockOverride").toString(); + return config()->get(Config::SSHAgent_AuthSockOverride).toString(); } void SSHAgent::setAuthSockOverride(QString& authSockOverride) { - config()->set("SSHAuthSockOverride", authSockOverride); + config()->set(Config::SSHAgent_AuthSockOverride, authSockOverride); } #ifdef Q_OS_WIN bool SSHAgent::useOpenSSH() const { - return config()->get("SSHAgentOpenSSH").toBool(); + return config()->get(Config::SSHAgent_UseOpenSSH).toBool(); } void SSHAgent::setUseOpenSSH(bool useOpenSSH) { - config()->set("SSHAgentOpenSSH", useOpenSSH); + config()->set(Config::SSHAgent_UseOpenSSH, useOpenSSH); } #endif diff --git a/src/updatecheck/UpdateChecker.cpp b/src/updatecheck/UpdateChecker.cpp index c36879707..48a8c98c7 100644 --- a/src/updatecheck/UpdateChecker.cpp +++ b/src/updatecheck/UpdateChecker.cpp @@ -42,7 +42,7 @@ UpdateChecker::~UpdateChecker() void UpdateChecker::checkForUpdates(bool manuallyRequested) { - auto nextCheck = config()->get("GUI/CheckForUpdatesNextCheck", 0).toULongLong(); + auto nextCheck = config()->get(Config::GUI_CheckForUpdatesNextCheck).toULongLong(); m_isManuallyRequested = manuallyRequested; if (m_isManuallyRequested || Clock::currentSecondsSinceEpoch() >= nextCheck) { @@ -50,7 +50,7 @@ void UpdateChecker::checkForUpdates(bool manuallyRequested) QString apiUrlStr = QString("https://api.github.com/repos/keepassxreboot/keepassxc/releases"); - if (!config()->get("GUI/CheckForUpdatesIncludeBetas", false).toBool()) { + if (!config()->get(Config::GUI_CheckForUpdatesIncludeBetas).toBool()) { apiUrlStr += "/latest"; } @@ -85,7 +85,7 @@ void UpdateChecker::fetchFinished() QJsonDocument jsonResponse = QJsonDocument::fromJson(m_bytesReceived); QJsonObject jsonObject = jsonResponse.object(); - if (config()->get("GUI/CheckForUpdatesIncludeBetas", false).toBool()) { + if (config()->get(Config::GUI_CheckForUpdatesIncludeBetas).toBool()) { QJsonArray jsonArray = jsonResponse.array(); jsonObject = jsonArray.at(0).toObject(); } @@ -97,7 +97,7 @@ void UpdateChecker::fetchFinished() // Check again in 7 days // TODO: change to toSecsSinceEpoch() when min Qt >= 5.8 - config()->set("GUI/CheckForUpdatesNextCheck", Clock::currentDateTime().addDays(7).toTime_t()); + config()->set(Config::GUI_CheckForUpdatesNextCheck, Clock::currentDateTime().addDays(7).toTime_t()); } else { version = "error"; } diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index e2ab5db1c..5898f0477 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -35,8 +35,8 @@ void TestAutoType::initTestCase() { QVERIFY(Crypto::init()); Config::createTempFileInstance(); - config()->set("AutoTypeDelay", 1); - config()->set("security/autotypeask", false); + config()->set(Config::AutoTypeDelay, 1); + config()->set(Config::Security_AutoTypeAsk, false); AutoType::createTestInstance(); QPluginLoader loader(resources()->pluginPath("keepassx-autotype-test")); @@ -54,7 +54,7 @@ void TestAutoType::initTestCase() void TestAutoType::init() { - config()->set("AutoTypeEntryTitleMatch", false); + config()->set(Config::AutoTypeEntryTitleMatch, false); m_test->clearActions(); m_db = QSharedPointer::create(); @@ -165,7 +165,7 @@ void TestAutoType::testGlobalAutoTypeWithOneMatch() void TestAutoType::testGlobalAutoTypeTitleMatch() { - config()->set("AutoTypeEntryTitleMatch", true); + config()->set(Config::AutoTypeEntryTitleMatch, true); m_test->setActiveWindowTitle("An Entry Title!"); m_test->triggerGlobalAutoType(); @@ -176,7 +176,7 @@ void TestAutoType::testGlobalAutoTypeTitleMatch() void TestAutoType::testGlobalAutoTypeUrlMatch() { - config()->set("AutoTypeEntryTitleMatch", true); + config()->set(Config::AutoTypeEntryTitleMatch, true); m_test->setActiveWindowTitle("Dummy - http://example.org/ - "); m_test->triggerGlobalAutoType(); @@ -187,7 +187,7 @@ void TestAutoType::testGlobalAutoTypeUrlMatch() void TestAutoType::testGlobalAutoTypeUrlSubdomainMatch() { - config()->set("AutoTypeEntryTitleMatch", true); + config()->set(Config::AutoTypeEntryTitleMatch, true); m_test->setActiveWindowTitle("Dummy - http://sub.example.org/ - "); m_test->triggerGlobalAutoType(); diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index f8fbfa7f1..3b97ffde8 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -99,14 +99,14 @@ void TestGui::initTestCase() QVERIFY(Crypto::init()); Config::createTempFileInstance(); // Disable autosave so we can test the modified file indicator - config()->set("AutoSaveAfterEveryChange", false); - config()->set("AutoSaveOnExit", false); + config()->set(Config::AutoSaveAfterEveryChange, false); + config()->set(Config::AutoSaveOnExit, false); // Enable the tray icon so we can test hiding/restoring the windowQByteArray - config()->set("GUI/ShowTrayIcon", true); + config()->set(Config::GUI_ShowTrayIcon, true); // Disable advanced settings mode (activate within individual tests to test advanced settings) - config()->set("GUI/AdvancedSettings", false); + config()->set(Config::GUI_AdvancedSettings, false); // Disable the update check first time alert - config()->set("UpdateCheckMessageShown", true); + config()->set(Config::UpdateCheckMessageShown, true); Bootstrap::bootstrapApplication(); @@ -342,7 +342,7 @@ void TestGui::testMergeDatabase() void TestGui::testAutoreloadDatabase() { - config()->set("AutoReloadOnChange", false); + config()->set(Config::AutoReloadOnChange, false); // Test accepting new file in autoreload MessageBox::setNextAnswer(MessageBox::Yes); @@ -375,7 +375,7 @@ void TestGui::testAutoreloadDatabase() // Test accepting a merge of edits into autoreload // Turn on autoload so we only get one messagebox (for the merge) - config()->set("AutoReloadOnChange", true); + config()->set(Config::AutoReloadOnChange, true); // Modify some entries testEditEntry(); diff --git a/tests/gui/TestGuiBrowser.cpp b/tests/gui/TestGuiBrowser.cpp index 1750caa80..7e5d89df4 100644 --- a/tests/gui/TestGuiBrowser.cpp +++ b/tests/gui/TestGuiBrowser.cpp @@ -69,14 +69,14 @@ void TestGuiBrowser::initTestCase() QVERIFY(Crypto::init()); Config::createTempFileInstance(); // Disable autosave so we can test the modified file indicator - config()->set("AutoSaveAfterEveryChange", false); - config()->set("AutoSaveOnExit", false); + config()->set(Config::AutoSaveAfterEveryChange, false); + config()->set(Config::AutoSaveOnExit, false); // Enable the tray icon so we can test hiding/restoring the windowQByteArray - config()->set("GUI/ShowTrayIcon", true); + config()->set(Config::GUI_ShowTrayIcon, true); // Disable advanced settings mode (activate within individual tests to test advanced settings) - config()->set("GUI/AdvancedSettings", false); + config()->set(Config::GUI_AdvancedSettings, false); // Disable the update check first time alert - config()->set("UpdateCheckMessageShown", true); + config()->set(Config::UpdateCheckMessageShown, true); m_mainWindow.reset(new MainWindow()); Bootstrap::restoreMainWindowState(*m_mainWindow); @@ -146,7 +146,7 @@ void TestGuiBrowser::cleanupTestCase() void TestGuiBrowser::testEntrySettings() { // Enable the Browser Integration - config()->set("Browser/Enabled", true); + config()->set(Config::Browser_Enabled, true); auto* toolBar = m_mainWindow->findChild("toolBar"); auto* entryView = m_dbWidget->findChild("entryView");