diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index 28cb6ffa..e3befa14 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -388,7 +388,7 @@ bool ConfigHandler::setShortcut(const QString& actionName, bool error = false; - m_settings.beginGroup("Shortcuts"); + m_settings.beginGroup(CONFIG_GROUP_SHORTCUTS); if (shortcut.isEmpty()) { setValue(actionName, ""); } else if (reservedShortcuts.contains(QKeySequence(shortcut))) { @@ -418,12 +418,12 @@ done: QString ConfigHandler::shortcut(const QString& actionName) { - QString setting = "Shortcuts/" + actionName; + QString setting = CONFIG_GROUP_SHORTCUTS "/" + actionName; QString shortcut = value(setting).toString(); if (!m_settings.contains(setting)) { // The action uses a shortcut that is a flameshot default // (not set explicitly by user) - m_settings.beginGroup("Shortcuts"); + m_settings.beginGroup(CONFIG_GROUP_SHORTCUTS); for (auto& otherAction : m_settings.allKeys()) { if (m_settings.value(otherAction) == shortcut) { // We found an explicit shortcut - it will take precedence @@ -471,7 +471,6 @@ QVariant ConfigHandler::value(const QString& key) const QSet& ConfigHandler::recognizedGeneralOptions() { - #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto keys = ::recognizedGeneralOptions.keys(); static QSet options = QSet(keys.begin(), keys.end()); @@ -494,12 +493,13 @@ QSet& ConfigHandler::recognizedShortcutNames() return names; } -/// Return keys from group `group`. Use "General" for general settings. +// Return keys from group `group`. Use CONFIG_GROUP_GENERAL (General) for +// general settings. QSet ConfigHandler::keysFromGroup(const QString& group) const { QSet keys; for (const QString& key : m_settings.allKeys()) { - if (group == "General" && !key.contains('/')) { + if (group == CONFIG_GROUP_GENERAL && !key.contains('/')) { keys.insert(key); } else if (key.startsWith(group + "/")) { keys.insert(baseName(key)); @@ -516,6 +516,20 @@ bool ConfigHandler::checkForErrors(QTextStream* log) const checkSemantics(log); } +void ConfigHandler::cleanUnusedKeys(const QString& group, + const QSet& keys) const +{ + for (const QString& key : keys) { + if (group == CONFIG_GROUP_GENERAL && !key.contains('/')) { + m_settings.remove(key); + } else { + m_settings.beginGroup(group); + m_settings.remove(key); + m_settings.endGroup(); + } + } +} + /** * @brief Parse the config to find settings with unrecognized names. * @return Whether the config passes this check. @@ -527,8 +541,8 @@ bool ConfigHandler::checkForErrors(QTextStream* log) const bool ConfigHandler::checkUnrecognizedSettings(QTextStream* log) const { // sort the config keys by group - QSet generalKeys = keysFromGroup("General"), - shortcutKeys = keysFromGroup("Shortcuts"), + QSet generalKeys = keysFromGroup(CONFIG_GROUP_GENERAL), + shortcutKeys = keysFromGroup(CONFIG_GROUP_SHORTCUTS), recognizedGeneralKeys = recognizedGeneralOptions(), recognizedShortcutKeys = recognizedShortcutNames(); @@ -536,6 +550,29 @@ bool ConfigHandler::checkUnrecognizedSettings(QTextStream* log) const generalKeys.subtract(recognizedGeneralKeys); shortcutKeys.subtract(recognizedShortcutKeys); + // automatically clean up unused keys + if (!generalKeys.isEmpty()) { + cleanUnusedKeys(CONFIG_GROUP_GENERAL, generalKeys); + generalKeys = keysFromGroup(CONFIG_GROUP_GENERAL), + generalKeys.subtract(recognizedGeneralKeys); + } + if (!shortcutKeys.isEmpty()) { + cleanUnusedKeys(CONFIG_GROUP_SHORTCUTS, shortcutKeys); + shortcutKeys = keysFromGroup(CONFIG_GROUP_SHORTCUTS); + shortcutKeys.subtract(recognizedShortcutKeys); + } + + // clean up unused groups + QStringList settingsGroups = m_settings.childGroups(); + for (const auto& group : settingsGroups) { + if (group != QLatin1String(CONFIG_GROUP_SHORTCUTS) && + group != QLatin1String(CONFIG_GROUP_GENERAL)) { + m_settings.beginGroup(group); + m_settings.remove(""); + m_settings.endGroup(); + } + } + // what is left are the unrecognized keys - hopefully empty bool ok = generalKeys.isEmpty() && shortcutKeys.isEmpty(); if (log != nullptr) { @@ -561,7 +598,7 @@ bool ConfigHandler::checkUnrecognizedSettings(QTextStream* log) const bool ConfigHandler::checkShortcutConflicts(QTextStream* log) const { bool ok = true; - m_settings.beginGroup("Shortcuts"); + m_settings.beginGroup(CONFIG_GROUP_SHORTCUTS); QStringList shortcuts = m_settings.allKeys(); QStringList reportedInLog; for (auto key1 = shortcuts.begin(); key1 != shortcuts.end(); ++key1) { @@ -709,9 +746,10 @@ void ConfigHandler::ensureFileWatched() const * @brief Obtain a `ValueHandler` for the config option with the given key. * @return Smart pointer to the handler. * - * @note If the key is from the "General" group, the `recognizedGeneralOptions` - * map is looked up. If it is from "Shortcuts", a generic `KeySequence` value - * handler is returned. + * @note If the key is from the CONFIG_GROUP_GENERAL (General) group, the + * `recognizedGeneralOptions` map is looked up. If it is from + * CONFIG_GROUP_SHORTCUTS (Shortcuts), a generic `KeySequence` value handler is + * returned. */ QSharedPointer ConfigHandler::valueHandler( const QString& key) const @@ -752,8 +790,8 @@ void ConfigHandler::assertKeyRecognized(const QString& key) const bool ConfigHandler::isShortcut(const QString& key) const { - return m_settings.group() == QStringLiteral("Shortcuts") || - key.startsWith(QStringLiteral("Shortcuts/")); + return m_settings.group() == QStringLiteral(CONFIG_GROUP_SHORTCUTS) || + key.startsWith(QStringLiteral(CONFIG_GROUP_SHORTCUTS "/")); } QString ConfigHandler::baseName(QString key) const diff --git a/src/utils/confighandler.h b/src/utils/confighandler.h index b328febb..cca5c492 100644 --- a/src/utils/confighandler.h +++ b/src/utils/confighandler.h @@ -9,6 +9,9 @@ #include #include +#define CONFIG_GROUP_GENERAL "General" +#define CONFIG_GROUP_SHORTCUTS "Shortcuts" + class QFileSystemWatcher; class ValueHandler; template @@ -163,4 +166,5 @@ private: void assertKeyRecognized(const QString& key) const; bool isShortcut(const QString& key) const; QString baseName(QString key) const; + void cleanUnusedKeys(const QString& group, const QSet& keys) const; };