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
This commit is contained in:
Janek Bevendorff 2020-04-26 01:31:38 +02:00
parent 5add01243d
commit 596d2cf425
45 changed files with 1002 additions and 638 deletions

View File

@ -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<QSharedPointer<Database>>& 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<QString> 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());
}

View File

@ -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<AutoTypeMatch>& matchList)
void AutoTypeSelectDialog::done(int r)
{
config()->set("GUI/AutoTypeSelectDialogSize", size());
config()->set(Config::GUI_AutoTypeSelectDialogSize, size());
QDialog::done(r);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 <QCoreApplication>
#include <QDir>
#include <QHash>
#include <QSettings>
#include <QSize>
#include <QStandardPaths>
#include <QTemporaryFile>
/*
* 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<QString, QString> 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<Config::ConfigKey, ConfigDirective> 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> 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<QString, Config::ConfigKey> 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) {
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));
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)) {
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);
}
// 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);
}
}
// > 2.3.4
if (m_settings->value("AutoSaveAfterEveryChange").toBool()) {
m_settings->setValue("AutoSaveOnExit", true);
// 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 (m_settings->value("HideWindowOnCopy").isNull()) {
m_settings->setValue("HideWindowOnCopy", m_settings->value("MinimizeOnCopy").toBool());
m_settings->setValue("MinimizeOnCopy", true);
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);
}
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();
#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);
return;
}
userPath += "/keepassxc/";
QString configPath;
QString localConfigPath;
#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

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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<Config> m_instance;
QScopedPointer<QSettings> m_settings;
QScopedPointer<QSettings> m_localSettings;
QHash<QString, QVariant> m_defaults;
};

View File

@ -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;
}

View File

@ -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

View File

@ -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<PasswordGroup> passwordGroups() const;

View File

@ -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()

View File

@ -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

View File

@ -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<Database>& db) const

View File

@ -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)

View File

@ -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<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get(Config::GlobalAutoTypeKey).toInt());
m_globalAutoTypeModifiers =
static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
static_cast<Qt::KeyboardModifiers>(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<int>(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<int>(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)) {

View File

@ -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);

View File

@ -147,15 +147,15 @@ void DatabaseOpenWidget::load(const QString& filename)
m_ui->keyFileClearIcon->setVisible(false);
m_keyFileComboEdited = false;
if (config()->get("RememberLastKeyFiles").toBool()) {
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
if (config()->get(Config::RememberLastKeyFiles).toBool()) {
QHash<QString, QVariant> 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<QString, QVariant> useTouchID = config()->get("UseTouchID").toHash();
QHash<QString, QVariant> 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<QString, QVariant> useTouchID = config()->get("UseTouchID").toHash();
QHash<QString, QVariant> 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<CompositeKey> DatabaseOpenWidget::databaseKey()
}
#endif
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
QHash<QString, QVariant> lastKeyFiles = config()->get(Config::LastKeyFiles).toHash();
lastKeyFiles.remove(m_filename);
auto key = QSharedPointer<FileKey>::create();
@ -304,7 +304,7 @@ QSharedPointer<CompositeKey> 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<CompositeKey> 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<CompositeKey> 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<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
QHash<QString, QVariant> lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
lastChallengeResponse.remove(m_filename);
int selectionIndex = m_ui->comboChallengeResponse->currentIndex();
@ -345,8 +345,8 @@ QSharedPointer<CompositeKey> 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<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
if (config()->get(Config::RememberLastKeyFiles).toBool()) {
QHash<QString, QVariant> lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
if (lastChallengeResponse.contains(m_filename)) {
m_ui->comboChallengeResponse->setCurrentIndex(1);
}

View File

@ -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);

View File

@ -216,7 +216,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> 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(

View File

@ -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();
}

View File

@ -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"));
}

View File

@ -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());

View File

@ -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;

View File

@ -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);
}

View File

@ -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<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
Qt::Key globalAutoTypeKey = static_cast<Qt::Key>(config()->get(Config::GlobalAutoTypeKey).toInt());
Qt::KeyboardModifiers globalAutoTypeModifiers =
static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
static_cast<Qt::KeyboardModifiers>(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<Qt::ToolButtonStyle>(config()->get("GUI/ToolButtonStyle").toInt(&isOk));
const auto toolButtonStyle =
static_cast<Qt::ToolButtonStyle>(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

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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());
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);

View File

@ -123,7 +123,7 @@ void DatabaseSettingsDialog::load(const QSharedPointer<Database>& 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);
}

View File

@ -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

View File

@ -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) {

View File

@ -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();

View File

@ -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());

View File

@ -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();
}
}

View File

@ -21,6 +21,7 @@
#include <QMap>
#include <QUuid>
#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;

View File

@ -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()

View File

@ -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()) {

View File

@ -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()

View File

@ -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

View File

@ -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";
}

View File

@ -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<Database>::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/ - <My Browser>");
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/ - <My Browser>");
m_test->triggerGlobalAutoType();

View File

@ -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();

View File

@ -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<QToolBar*>("toolBar");
auto* entryView = m_dbWidget->findChild<EntryView*>("entryView");