From 88a6ecabae77854092a13e5cff070c62e6afaedf Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 15 Nov 2023 08:11:49 +0100 Subject: [PATCH 1/3] Add lookup index to editor settings category Prevent adding duplicate settings there. --- apps/opencs/model/prefs/category.cpp | 12 ++++++++---- apps/opencs/model/prefs/category.hpp | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/prefs/category.cpp b/apps/opencs/model/prefs/category.cpp index 5a82be08fc4..9c8923f042b 100644 --- a/apps/opencs/model/prefs/category.cpp +++ b/apps/opencs/model/prefs/category.cpp @@ -24,6 +24,9 @@ CSMPrefs::State* CSMPrefs::Category::getState() const void CSMPrefs::Category::addSetting(Setting* setting) { + if (!mIndex.emplace(setting->getKey(), setting).second) + throw std::logic_error("Category " + mKey + " already has setting: " + setting->getKey()); + mSettings.push_back(setting); } @@ -39,11 +42,12 @@ CSMPrefs::Category::Iterator CSMPrefs::Category::end() CSMPrefs::Setting& CSMPrefs::Category::operator[](const std::string& key) { - for (Iterator iter = mSettings.begin(); iter != mSettings.end(); ++iter) - if ((*iter)->getKey() == key) - return **iter; + const auto it = mIndex.find(key); + + if (it != mIndex.end()) + return *it->second; - throw std::logic_error("Invalid user setting: " + key); + throw std::logic_error("Invalid user setting in " + mKey + " category: " + key); } void CSMPrefs::Category::update() diff --git a/apps/opencs/model/prefs/category.hpp b/apps/opencs/model/prefs/category.hpp index 5c75f99067d..19b559b3844 100644 --- a/apps/opencs/model/prefs/category.hpp +++ b/apps/opencs/model/prefs/category.hpp @@ -3,6 +3,7 @@ #include #include +#include #include namespace CSMPrefs @@ -20,6 +21,7 @@ namespace CSMPrefs State* mParent; std::string mKey; Container mSettings; + std::unordered_map mIndex; public: Category(State* parent, const std::string& key); From 4c13ecea236bfe1ee7c0b5a554a198fff0d9831c Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 12 Nov 2023 00:52:09 +0100 Subject: [PATCH 2/3] Use settings values for editor --- apps/opencs/model/prefs/boolsetting.cpp | 16 ++---- apps/opencs/model/prefs/boolsetting.hpp | 6 +- apps/opencs/model/prefs/category.cpp | 6 ++ apps/opencs/model/prefs/category.hpp | 3 + apps/opencs/model/prefs/coloursetting.cpp | 17 ++---- apps/opencs/model/prefs/coloursetting.hpp | 7 ++- apps/opencs/model/prefs/doublesetting.cpp | 17 ++---- apps/opencs/model/prefs/doublesetting.hpp | 6 +- apps/opencs/model/prefs/enumsetting.cpp | 24 +++----- apps/opencs/model/prefs/enumsetting.hpp | 7 +-- apps/opencs/model/prefs/intsetting.cpp | 17 ++---- apps/opencs/model/prefs/intsetting.hpp | 6 +- apps/opencs/model/prefs/modifiersetting.cpp | 17 ++---- apps/opencs/model/prefs/modifiersetting.hpp | 6 +- apps/opencs/model/prefs/setting.cpp | 29 ++-------- apps/opencs/model/prefs/setting.hpp | 59 ++++++++++++++++--- apps/opencs/model/prefs/shortcutsetting.cpp | 17 ++---- apps/opencs/model/prefs/shortcutsetting.hpp | 6 +- apps/opencs/model/prefs/state.cpp | 64 ++++++--------------- apps/opencs/model/prefs/state.hpp | 2 +- apps/opencs/model/prefs/stringsetting.cpp | 17 ++---- apps/opencs/model/prefs/stringsetting.hpp | 8 +-- apps/opencs/model/prefs/subcategory.cpp | 4 +- apps/opencs/model/prefs/subcategory.hpp | 4 +- apps/opencs/model/world/actoradapter.cpp | 7 ++- 25 files changed, 164 insertions(+), 208 deletions(-) diff --git a/apps/opencs/model/prefs/boolsetting.cpp b/apps/opencs/model/prefs/boolsetting.cpp index c1eb6269694..2ca8315245b 100644 --- a/apps/opencs/model/prefs/boolsetting.cpp +++ b/apps/opencs/model/prefs/boolsetting.cpp @@ -11,9 +11,8 @@ #include "state.hpp" CSMPrefs::BoolSetting::BoolSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, bool default_) - : Setting(parent, mutex, key, label) - , mDefault(default_) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mWidget(nullptr) { } @@ -27,7 +26,7 @@ CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip(const std::string& tool CSMPrefs::SettingWidgets CSMPrefs::BoolSetting::makeWidgets(QWidget* parent) { mWidget = new QCheckBox(getLabel(), parent); - mWidget->setCheckState(mDefault ? Qt::Checked : Qt::Unchecked); + mWidget->setCheckState(getValue() ? Qt::Checked : Qt::Unchecked); if (!mTooltip.empty()) { @@ -44,17 +43,12 @@ void CSMPrefs::BoolSetting::updateWidget() { if (mWidget) { - mWidget->setCheckState( - Settings::Manager::getBool(getKey(), getParent()->getKey()) ? Qt::Checked : Qt::Unchecked); + mWidget->setCheckState(getValue() ? Qt::Checked : Qt::Unchecked); } } void CSMPrefs::BoolSetting::valueChanged(int value) { - { - QMutexLocker lock(getMutex()); - Settings::Manager::setBool(getKey(), getParent()->getKey(), value); - } - + setValue(value != Qt::Unchecked); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/boolsetting.hpp b/apps/opencs/model/prefs/boolsetting.hpp index 9d53f98e9e7..fd67019a785 100644 --- a/apps/opencs/model/prefs/boolsetting.hpp +++ b/apps/opencs/model/prefs/boolsetting.hpp @@ -12,16 +12,16 @@ namespace CSMPrefs { class Category; - class BoolSetting : public Setting + class BoolSetting final : public TypedSetting { Q_OBJECT std::string mTooltip; - bool mDefault; QCheckBox* mWidget; public: - BoolSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label, bool default_); + explicit BoolSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); BoolSetting& setTooltip(const std::string& tooltip); diff --git a/apps/opencs/model/prefs/category.cpp b/apps/opencs/model/prefs/category.cpp index 9c8923f042b..3ae48269531 100644 --- a/apps/opencs/model/prefs/category.cpp +++ b/apps/opencs/model/prefs/category.cpp @@ -5,6 +5,7 @@ #include "setting.hpp" #include "state.hpp" +#include "subcategory.hpp" CSMPrefs::Category::Category(State* parent, const std::string& key) : mParent(parent) @@ -30,6 +31,11 @@ void CSMPrefs::Category::addSetting(Setting* setting) mSettings.push_back(setting); } +void CSMPrefs::Category::addSubcategory(Subcategory* setting) +{ + mSettings.push_back(setting); +} + CSMPrefs::Category::Iterator CSMPrefs::Category::begin() { return mSettings.begin(); diff --git a/apps/opencs/model/prefs/category.hpp b/apps/opencs/model/prefs/category.hpp index 19b559b3844..ef67c82138c 100644 --- a/apps/opencs/model/prefs/category.hpp +++ b/apps/opencs/model/prefs/category.hpp @@ -10,6 +10,7 @@ namespace CSMPrefs { class State; class Setting; + class Subcategory; class Category { @@ -32,6 +33,8 @@ namespace CSMPrefs void addSetting(Setting* setting); + void addSubcategory(Subcategory* setting); + Iterator begin(); Iterator end(); diff --git a/apps/opencs/model/prefs/coloursetting.cpp b/apps/opencs/model/prefs/coloursetting.cpp index e2ece047229..61aa92063e2 100644 --- a/apps/opencs/model/prefs/coloursetting.cpp +++ b/apps/opencs/model/prefs/coloursetting.cpp @@ -14,9 +14,8 @@ #include "state.hpp" CSMPrefs::ColourSetting::ColourSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, QColor default_) - : Setting(parent, mutex, key, label) - , mDefault(std::move(default_)) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mWidget(nullptr) { } @@ -31,7 +30,7 @@ CSMPrefs::SettingWidgets CSMPrefs::ColourSetting::makeWidgets(QWidget* parent) { QLabel* label = new QLabel(getLabel(), parent); - mWidget = new CSVWidget::ColorEditor(mDefault, parent); + mWidget = new CSVWidget::ColorEditor(toColor(), parent); if (!mTooltip.empty()) { @@ -48,18 +47,12 @@ CSMPrefs::SettingWidgets CSMPrefs::ColourSetting::makeWidgets(QWidget* parent) void CSMPrefs::ColourSetting::updateWidget() { if (mWidget) - { - mWidget->setColor(QString::fromStdString(Settings::Manager::getString(getKey(), getParent()->getKey()))); - } + mWidget->setColor(toColor()); } void CSMPrefs::ColourSetting::valueChanged() { CSVWidget::ColorEditor& widget = dynamic_cast(*sender()); - { - QMutexLocker lock(getMutex()); - Settings::Manager::setString(getKey(), getParent()->getKey(), widget.color().name().toUtf8().data()); - } - + setValue(widget.color().name().toStdString()); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/coloursetting.hpp b/apps/opencs/model/prefs/coloursetting.hpp index 5a1a7a2df25..f5af627491c 100644 --- a/apps/opencs/model/prefs/coloursetting.hpp +++ b/apps/opencs/model/prefs/coloursetting.hpp @@ -20,16 +20,17 @@ namespace CSVWidget namespace CSMPrefs { class Category; - class ColourSetting : public Setting + + class ColourSetting final : public TypedSetting { Q_OBJECT std::string mTooltip; - QColor mDefault; CSVWidget::ColorEditor* mWidget; public: - ColourSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label, QColor default_); + explicit ColourSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); ColourSetting& setTooltip(const std::string& tooltip); diff --git a/apps/opencs/model/prefs/doublesetting.cpp b/apps/opencs/model/prefs/doublesetting.cpp index 153298ce572..b275c2e9b77 100644 --- a/apps/opencs/model/prefs/doublesetting.cpp +++ b/apps/opencs/model/prefs/doublesetting.cpp @@ -15,12 +15,11 @@ #include "state.hpp" CSMPrefs::DoubleSetting::DoubleSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, double default_) - : Setting(parent, mutex, key, label) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mPrecision(2) , mMin(0) , mMax(std::numeric_limits::max()) - , mDefault(default_) , mWidget(nullptr) { } @@ -63,7 +62,7 @@ CSMPrefs::SettingWidgets CSMPrefs::DoubleSetting::makeWidgets(QWidget* parent) mWidget = new QDoubleSpinBox(parent); mWidget->setDecimals(mPrecision); mWidget->setRange(mMin, mMax); - mWidget->setValue(mDefault); + mWidget->setValue(getValue()); if (!mTooltip.empty()) { @@ -80,17 +79,11 @@ CSMPrefs::SettingWidgets CSMPrefs::DoubleSetting::makeWidgets(QWidget* parent) void CSMPrefs::DoubleSetting::updateWidget() { if (mWidget) - { - mWidget->setValue(Settings::Manager::getFloat(getKey(), getParent()->getKey())); - } + mWidget->setValue(getValue()); } void CSMPrefs::DoubleSetting::valueChanged(double value) { - { - QMutexLocker lock(getMutex()); - Settings::Manager::setFloat(getKey(), getParent()->getKey(), value); - } - + setValue(value); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/doublesetting.hpp b/apps/opencs/model/prefs/doublesetting.hpp index 33342d2f5b7..add85cb9b3c 100644 --- a/apps/opencs/model/prefs/doublesetting.hpp +++ b/apps/opencs/model/prefs/doublesetting.hpp @@ -9,7 +9,7 @@ namespace CSMPrefs { class Category; - class DoubleSetting : public Setting + class DoubleSetting final : public TypedSetting { Q_OBJECT @@ -17,11 +17,11 @@ namespace CSMPrefs double mMin; double mMax; std::string mTooltip; - double mDefault; QDoubleSpinBox* mWidget; public: - DoubleSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label, double default_); + explicit DoubleSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); DoubleSetting& setPrecision(int precision); diff --git a/apps/opencs/model/prefs/enumsetting.cpp b/apps/opencs/model/prefs/enumsetting.cpp index d55e4005a44..1521c3cc137 100644 --- a/apps/opencs/model/prefs/enumsetting.cpp +++ b/apps/opencs/model/prefs/enumsetting.cpp @@ -45,9 +45,8 @@ CSMPrefs::EnumValues& CSMPrefs::EnumValues::add(const std::string& value, const } CSMPrefs::EnumSetting::EnumSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, const EnumValue& default_) - : Setting(parent, mutex, key, label) - , mDefault(default_) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mWidget(nullptr) { } @@ -83,16 +82,18 @@ CSMPrefs::SettingWidgets CSMPrefs::EnumSetting::makeWidgets(QWidget* parent) mWidget = new QComboBox(parent); size_t index = 0; + const std::string value = getValue(); for (size_t i = 0; i < mValues.mValues.size(); ++i) { - if (mDefault.mValue == mValues.mValues[i].mValue) + if (value == mValues.mValues[i].mValue) index = i; mWidget->addItem(QString::fromUtf8(mValues.mValues[i].mValue.c_str())); if (!mValues.mValues[i].mTooltip.empty()) - mWidget->setItemData(i, QString::fromUtf8(mValues.mValues[i].mTooltip.c_str()), Qt::ToolTipRole); + mWidget->setItemData( + static_cast(i), QString::fromUtf8(mValues.mValues[i].mTooltip.c_str()), Qt::ToolTipRole); } mWidget->setCurrentIndex(static_cast(index)); @@ -111,20 +112,11 @@ CSMPrefs::SettingWidgets CSMPrefs::EnumSetting::makeWidgets(QWidget* parent) void CSMPrefs::EnumSetting::updateWidget() { if (mWidget) - { - int index - = mWidget->findText(QString::fromStdString(Settings::Manager::getString(getKey(), getParent()->getKey()))); - - mWidget->setCurrentIndex(index); - } + mWidget->setCurrentIndex(mWidget->findText(QString::fromStdString(getValue()))); } void CSMPrefs::EnumSetting::valueChanged(int value) { - { - QMutexLocker lock(getMutex()); - Settings::Manager::setString(getKey(), getParent()->getKey(), mValues.mValues.at(value).mValue); - } - + setValue(mValues.mValues.at(value).mValue); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/enumsetting.hpp b/apps/opencs/model/prefs/enumsetting.hpp index f430988aa61..51241d593fc 100644 --- a/apps/opencs/model/prefs/enumsetting.hpp +++ b/apps/opencs/model/prefs/enumsetting.hpp @@ -34,18 +34,17 @@ namespace CSMPrefs EnumValues& add(const std::string& value, const std::string& tooltip); }; - class EnumSetting : public Setting + class EnumSetting final : public TypedSetting { Q_OBJECT std::string mTooltip; - EnumValue mDefault; EnumValues mValues; QComboBox* mWidget; public: - EnumSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, const EnumValue& default_); + explicit EnumSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); EnumSetting& setTooltip(const std::string& tooltip); diff --git a/apps/opencs/model/prefs/intsetting.cpp b/apps/opencs/model/prefs/intsetting.cpp index 7d0b40a45a4..023339b9c1e 100644 --- a/apps/opencs/model/prefs/intsetting.cpp +++ b/apps/opencs/model/prefs/intsetting.cpp @@ -15,11 +15,10 @@ #include "state.hpp" CSMPrefs::IntSetting::IntSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, int default_) - : Setting(parent, mutex, key, label) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mMin(0) , mMax(std::numeric_limits::max()) - , mDefault(default_) , mWidget(nullptr) { } @@ -55,7 +54,7 @@ CSMPrefs::SettingWidgets CSMPrefs::IntSetting::makeWidgets(QWidget* parent) mWidget = new QSpinBox(parent); mWidget->setRange(mMin, mMax); - mWidget->setValue(mDefault); + mWidget->setValue(getValue()); if (!mTooltip.empty()) { @@ -72,17 +71,11 @@ CSMPrefs::SettingWidgets CSMPrefs::IntSetting::makeWidgets(QWidget* parent) void CSMPrefs::IntSetting::updateWidget() { if (mWidget) - { - mWidget->setValue(Settings::Manager::getInt(getKey(), getParent()->getKey())); - } + mWidget->setValue(getValue()); } void CSMPrefs::IntSetting::valueChanged(int value) { - { - QMutexLocker lock(getMutex()); - Settings::Manager::setInt(getKey(), getParent()->getKey(), value); - } - + setValue(value); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/intsetting.hpp b/apps/opencs/model/prefs/intsetting.hpp index 8fb3bdb1f68..a1ed19ffd6e 100644 --- a/apps/opencs/model/prefs/intsetting.hpp +++ b/apps/opencs/model/prefs/intsetting.hpp @@ -12,18 +12,18 @@ namespace CSMPrefs { class Category; - class IntSetting : public Setting + class IntSetting final : public TypedSetting { Q_OBJECT int mMin; int mMax; std::string mTooltip; - int mDefault; QSpinBox* mWidget; public: - IntSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label, int default_); + explicit IntSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); // defaults to [0, std::numeric_limits::max()] IntSetting& setRange(int min, int max); diff --git a/apps/opencs/model/prefs/modifiersetting.cpp b/apps/opencs/model/prefs/modifiersetting.cpp index 173092dc2bc..53db4c8521f 100644 --- a/apps/opencs/model/prefs/modifiersetting.cpp +++ b/apps/opencs/model/prefs/modifiersetting.cpp @@ -19,8 +19,9 @@ class QWidget; namespace CSMPrefs { - ModifierSetting::ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label) - : Setting(parent, mutex, key, label) + ModifierSetting::ModifierSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mButton(nullptr) , mEditorActive(false) { @@ -53,7 +54,7 @@ namespace CSMPrefs { if (mButton) { - const std::string& shortcut = Settings::Manager::getString(getKey(), getParent()->getKey()); + const std::string& shortcut = getValue(); int modifier; State::get().getShortcutManager().convertFromString(shortcut, modifier); @@ -131,15 +132,7 @@ namespace CSMPrefs void ModifierSetting::storeValue(int modifier) { State::get().getShortcutManager().setModifier(getKey(), modifier); - - // Convert to string and assign - std::string value = State::get().getShortcutManager().convertToString(modifier); - - { - QMutexLocker lock(getMutex()); - Settings::Manager::setString(getKey(), getParent()->getKey(), value); - } - + setValue(State::get().getShortcutManager().convertToString(modifier)); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/modifiersetting.hpp b/apps/opencs/model/prefs/modifiersetting.hpp index 9e308875fd6..cf9ce8f1497 100644 --- a/apps/opencs/model/prefs/modifiersetting.hpp +++ b/apps/opencs/model/prefs/modifiersetting.hpp @@ -15,12 +15,14 @@ class QPushButton; namespace CSMPrefs { class Category; - class ModifierSetting : public Setting + + class ModifierSetting final : public TypedSetting { Q_OBJECT public: - ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label); + explicit ModifierSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); SettingWidgets makeWidgets(QWidget* parent) override; diff --git a/apps/opencs/model/prefs/setting.cpp b/apps/opencs/model/prefs/setting.cpp index 666b4ba1b14..cc5077dc83d 100644 --- a/apps/opencs/model/prefs/setting.cpp +++ b/apps/opencs/model/prefs/setting.cpp @@ -5,6 +5,7 @@ #include #include +#include #include "category.hpp" #include "state.hpp" @@ -14,12 +15,14 @@ QMutex* CSMPrefs::Setting::getMutex() return mMutex; } -CSMPrefs::Setting::Setting(Category* parent, QMutex* mutex, const std::string& key, const QString& label) +CSMPrefs::Setting::Setting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) : QObject(parent->getState()) , mParent(parent) , mMutex(mutex) , mKey(key) , mLabel(label) + , mIndex(index) { } @@ -33,30 +36,6 @@ const std::string& CSMPrefs::Setting::getKey() const return mKey; } -int CSMPrefs::Setting::toInt() const -{ - QMutexLocker lock(mMutex); - return Settings::Manager::getInt(mKey, mParent->getKey()); -} - -double CSMPrefs::Setting::toDouble() const -{ - QMutexLocker lock(mMutex); - return Settings::Manager::getFloat(mKey, mParent->getKey()); -} - -std::string CSMPrefs::Setting::toString() const -{ - QMutexLocker lock(mMutex); - return Settings::Manager::getString(mKey, mParent->getKey()); -} - -bool CSMPrefs::Setting::isTrue() const -{ - QMutexLocker lock(mMutex); - return Settings::Manager::getBool(mKey, mParent->getKey()); -} - QColor CSMPrefs::Setting::toColor() const { // toString() handles lock diff --git a/apps/opencs/model/prefs/setting.hpp b/apps/opencs/model/prefs/setting.hpp index 882add20ca7..f5d9e83ef1a 100644 --- a/apps/opencs/model/prefs/setting.hpp +++ b/apps/opencs/model/prefs/setting.hpp @@ -4,8 +4,13 @@ #include #include +#include #include +#include + +#include "category.hpp" + class QWidget; class QColor; class QMutex; @@ -14,8 +19,6 @@ class QLabel; namespace CSMPrefs { - class Category; - struct SettingWidgets { QLabel* mLabel; @@ -31,12 +34,35 @@ namespace CSMPrefs QMutex* mMutex; std::string mKey; QString mLabel; + Settings::Index& mIndex; protected: QMutex* getMutex(); + template + void resetValueImpl() + { + QMutexLocker lock(mMutex); + return mIndex.get(mParent->getKey(), mKey).reset(); + } + + template + T getValueImpl() const + { + QMutexLocker lock(mMutex); + return mIndex.get(mParent->getKey(), mKey).get(); + } + + template + void setValueImpl(const T& value) + { + QMutexLocker lock(mMutex); + return mIndex.get(mParent->getKey(), mKey).set(value); + } + public: - Setting(Category* parent, QMutex* mutex, const std::string& key, const QString& label); + explicit Setting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); ~Setting() override = default; @@ -47,23 +73,42 @@ namespace CSMPrefs /// \note If make_widgets() has not been called yet then nothing happens. virtual void updateWidget() = 0; + virtual void reset() = 0; + const Category* getParent() const; const std::string& getKey() const; const QString& getLabel() const { return mLabel; } - int toInt() const; + int toInt() const { return getValueImpl(); } - double toDouble() const; + double toDouble() const { return getValueImpl(); } - std::string toString() const; + std::string toString() const { return getValueImpl(); } - bool isTrue() const; + bool isTrue() const { return getValueImpl(); } QColor toColor() const; }; + template + class TypedSetting : public Setting + { + public: + using Setting::Setting; + + void reset() final + { + resetValueImpl(); + updateWidget(); + } + + T getValue() const { return getValueImpl(); } + + void setValue(const T& value) { return setValueImpl(value); } + }; + // note: fullKeys have the format categoryKey/settingKey bool operator==(const Setting& setting, const std::string& fullKey); bool operator==(const std::string& fullKey, const Setting& setting); diff --git a/apps/opencs/model/prefs/shortcutsetting.cpp b/apps/opencs/model/prefs/shortcutsetting.cpp index aae290b3f4b..42902f02cdd 100644 --- a/apps/opencs/model/prefs/shortcutsetting.cpp +++ b/apps/opencs/model/prefs/shortcutsetting.cpp @@ -18,8 +18,9 @@ namespace CSMPrefs { - ShortcutSetting::ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label) - : Setting(parent, mutex, key, label) + ShortcutSetting::ShortcutSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mButton(nullptr) , mEditorActive(false) , mEditorPos(0) @@ -57,7 +58,7 @@ namespace CSMPrefs { if (mButton) { - const std::string& shortcut = Settings::Manager::getString(getKey(), getParent()->getKey()); + const std::string shortcut = getValue(); QKeySequence sequence; State::get().getShortcutManager().convertFromString(shortcut, sequence); @@ -170,15 +171,7 @@ namespace CSMPrefs void ShortcutSetting::storeValue(const QKeySequence& sequence) { State::get().getShortcutManager().setSequence(getKey(), sequence); - - // Convert to string and assign - std::string value = State::get().getShortcutManager().convertToString(sequence); - - { - QMutexLocker lock(getMutex()); - Settings::Manager::setString(getKey(), getParent()->getKey(), value); - } - + setValue(State::get().getShortcutManager().convertToString(sequence)); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/shortcutsetting.hpp b/apps/opencs/model/prefs/shortcutsetting.hpp index 74cad995d45..84857a9bc7a 100644 --- a/apps/opencs/model/prefs/shortcutsetting.hpp +++ b/apps/opencs/model/prefs/shortcutsetting.hpp @@ -17,12 +17,14 @@ class QWidget; namespace CSMPrefs { class Category; - class ShortcutSetting : public Setting + + class ShortcutSetting final : public TypedSetting { Q_OBJECT public: - ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, const QString& label); + explicit ShortcutSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); SettingWidgets makeWidgets(QWidget* parent) override; diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index d74044f6d53..d55913fb3c3 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -465,9 +465,7 @@ CSMPrefs::IntSetting& CSMPrefs::State::declareInt(const std::string& key, const setDefault(key, std::to_string(default_)); - default_ = Settings::Manager::getInt(key, mCurrentCategory->second.getKey()); - - CSMPrefs::IntSetting* setting = new CSMPrefs::IntSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + CSMPrefs::IntSetting* setting = new CSMPrefs::IntSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -483,10 +481,8 @@ CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble(const std::string& key, stream << default_; setDefault(key, stream.str()); - default_ = Settings::Manager::getFloat(key, mCurrentCategory->second.getKey()); - CSMPrefs::DoubleSetting* setting - = new CSMPrefs::DoubleSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + = new CSMPrefs::DoubleSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -500,10 +496,7 @@ CSMPrefs::BoolSetting& CSMPrefs::State::declareBool(const std::string& key, cons setDefault(key, default_ ? "true" : "false"); - default_ = Settings::Manager::getBool(key, mCurrentCategory->second.getKey()); - - CSMPrefs::BoolSetting* setting - = new CSMPrefs::BoolSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + CSMPrefs::BoolSetting* setting = new CSMPrefs::BoolSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -517,10 +510,7 @@ CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum(const std::string& key, cons setDefault(key, default_.mValue); - default_.mValue = Settings::Manager::getString(key, mCurrentCategory->second.getKey()); - - CSMPrefs::EnumSetting* setting - = new CSMPrefs::EnumSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + CSMPrefs::EnumSetting* setting = new CSMPrefs::EnumSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -534,11 +524,8 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour(const std::string& key, setDefault(key, default_.name().toUtf8().data()); - default_.setNamedColor( - QString::fromUtf8(Settings::Manager::getString(key, mCurrentCategory->second.getKey()).c_str())); - CSMPrefs::ColourSetting* setting - = new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + = new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -557,28 +544,26 @@ CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut( // Setup with actual data QKeySequence sequence; - getShortcutManager().convertFromString( - Settings::Manager::getString(key, mCurrentCategory->second.getKey()), sequence); + getShortcutManager().convertFromString(mIndex->get(mCurrentCategory->second.getKey(), key), sequence); getShortcutManager().setSequence(key, sequence); - CSMPrefs::ShortcutSetting* setting = new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, key, label); + CSMPrefs::ShortcutSetting* setting + = new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::StringSetting& CSMPrefs::State::declareString( - const std::string& key, const QString& label, std::string default_) + const std::string& key, const QString& label, const std::string& default_) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); setDefault(key, default_); - default_ = Settings::Manager::getString(key, mCurrentCategory->second.getKey()); - CSMPrefs::StringSetting* setting - = new CSMPrefs::StringSetting(&mCurrentCategory->second, &mMutex, key, label, default_); + = new CSMPrefs::StringSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -596,11 +581,11 @@ CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& k // Setup with actual data int modifier; - getShortcutManager().convertFromString( - Settings::Manager::getString(key, mCurrentCategory->second.getKey()), modifier); + getShortcutManager().convertFromString(mIndex->get(mCurrentCategory->second.getKey(), key), modifier); getShortcutManager().setModifier(key, modifier); - CSMPrefs::ModifierSetting* setting = new CSMPrefs::ModifierSetting(&mCurrentCategory->second, &mMutex, key, label); + CSMPrefs::ModifierSetting* setting + = new CSMPrefs::ModifierSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; @@ -611,7 +596,8 @@ void CSMPrefs::State::declareSubcategory(const QString& label) if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - mCurrentCategory->second.addSetting(new CSMPrefs::Subcategory(&mCurrentCategory->second, &mMutex, label)); + mCurrentCategory->second.addSubcategory( + new CSMPrefs::Subcategory(&mCurrentCategory->second, &mMutex, label, *mIndex)); } void CSMPrefs::State::setDefault(const std::string& key, const std::string& default_) @@ -693,27 +679,13 @@ CSMPrefs::State& CSMPrefs::State::get() void CSMPrefs::State::resetCategory(const std::string& category) { - for (Settings::CategorySettingValueMap::iterator i = Settings::Manager::mUserSettings.begin(); - i != Settings::Manager::mUserSettings.end(); ++i) - { - // if the category matches - if (i->first.first == category) - { - // mark the setting as changed - Settings::Manager::mChangedSettings.insert(std::make_pair(i->first.first, i->first.second)); - // reset the value to the default - i->second = Settings::Manager::mDefaultSettings[i->first]; - } - } - Collection::iterator container = mCategories.find(category); if (container != mCategories.end()) { - Category settings = container->second; - for (Category::Iterator i = settings.begin(); i != settings.end(); ++i) + for (Setting* setting : container->second) { - (*i)->updateWidget(); - update(**i); + setting->reset(); + update(*setting); } } } diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index e398f06e4a6..97d657ddaf2 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -74,7 +74,7 @@ namespace CSMPrefs ShortcutSetting& declareShortcut(const std::string& key, const QString& label, const QKeySequence& default_); - StringSetting& declareString(const std::string& key, const QString& label, std::string default_); + StringSetting& declareString(const std::string& key, const QString& label, const std::string& default_); ModifierSetting& declareModifier(const std::string& key, const QString& label, int modifier_); diff --git a/apps/opencs/model/prefs/stringsetting.cpp b/apps/opencs/model/prefs/stringsetting.cpp index 0cba2d047db..d70324ba56c 100644 --- a/apps/opencs/model/prefs/stringsetting.cpp +++ b/apps/opencs/model/prefs/stringsetting.cpp @@ -12,9 +12,8 @@ #include "state.hpp" CSMPrefs::StringSetting::StringSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, std::string_view default_) - : Setting(parent, mutex, key, label) - , mDefault(default_) + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index) + : TypedSetting(parent, mutex, key, label, index) , mWidget(nullptr) { } @@ -27,7 +26,7 @@ CSMPrefs::StringSetting& CSMPrefs::StringSetting::setTooltip(const std::string& CSMPrefs::SettingWidgets CSMPrefs::StringSetting::makeWidgets(QWidget* parent) { - mWidget = new QLineEdit(QString::fromUtf8(mDefault.c_str()), parent); + mWidget = new QLineEdit(QString::fromStdString(getValue()), parent); if (!mTooltip.empty()) { @@ -43,17 +42,11 @@ CSMPrefs::SettingWidgets CSMPrefs::StringSetting::makeWidgets(QWidget* parent) void CSMPrefs::StringSetting::updateWidget() { if (mWidget) - { - mWidget->setText(QString::fromStdString(Settings::Manager::getString(getKey(), getParent()->getKey()))); - } + mWidget->setText(QString::fromStdString(getValue())); } void CSMPrefs::StringSetting::textChanged(const QString& text) { - { - QMutexLocker lock(getMutex()); - Settings::Manager::setString(getKey(), getParent()->getKey(), text.toStdString()); - } - + setValue(text.toStdString()); getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/stringsetting.hpp b/apps/opencs/model/prefs/stringsetting.hpp index 5c03a6ea128..25e1a362ff4 100644 --- a/apps/opencs/model/prefs/stringsetting.hpp +++ b/apps/opencs/model/prefs/stringsetting.hpp @@ -14,17 +14,17 @@ class QWidget; namespace CSMPrefs { class Category; - class StringSetting : public Setting + + class StringSetting final : public TypedSetting { Q_OBJECT std::string mTooltip; - std::string mDefault; QLineEdit* mWidget; public: - StringSetting( - Category* parent, QMutex* mutex, const std::string& key, const QString& label, std::string_view default_); + explicit StringSetting( + Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index); StringSetting& setTooltip(const std::string& tooltip); diff --git a/apps/opencs/model/prefs/subcategory.cpp b/apps/opencs/model/prefs/subcategory.cpp index cca558407c8..ac5b78ee2c7 100644 --- a/apps/opencs/model/prefs/subcategory.cpp +++ b/apps/opencs/model/prefs/subcategory.cpp @@ -6,8 +6,8 @@ namespace CSMPrefs { class Category; - Subcategory::Subcategory(Category* parent, QMutex* mutex, const QString& label) - : Setting(parent, mutex, "", label) + Subcategory::Subcategory(Category* parent, QMutex* mutex, const QString& label, Settings::Index& index) + : Setting(parent, mutex, "", label, index) { } diff --git a/apps/opencs/model/prefs/subcategory.hpp b/apps/opencs/model/prefs/subcategory.hpp index 4f62c1743c1..4c661ad0faa 100644 --- a/apps/opencs/model/prefs/subcategory.hpp +++ b/apps/opencs/model/prefs/subcategory.hpp @@ -15,11 +15,13 @@ namespace CSMPrefs Q_OBJECT public: - explicit Subcategory(Category* parent, QMutex* mutex, const QString& label); + explicit Subcategory(Category* parent, QMutex* mutex, const QString& label, Settings::Index& index); SettingWidgets makeWidgets(QWidget* parent) override; void updateWidget() override {} + + void reset() override {} }; } diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index e68d3e833ff..0e3725bbb73 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -132,11 +133,11 @@ namespace CSMWorld bool beast = mRaceData ? mRaceData->isBeast() : false; if (beast) - return Settings::Manager::getString("baseanimkna", "Models"); + return CSMPrefs::get()["Models"]["baseanimkna"].toString(); else if (mFemale) - return Settings::Manager::getString("baseanimfemale", "Models"); + return CSMPrefs::get()["Models"]["baseanimfemale"].toString(); else - return Settings::Manager::getString("baseanim", "Models"); + return CSMPrefs::get()["Models"]["baseanim"].toString(); } ESM::RefId ActorAdapter::ActorData::getPart(ESM::PartReferenceType index) const From e1a68d8cf598e25c5348a7b91b05dbe7ea854b69 Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 15 Nov 2023 08:14:16 +0100 Subject: [PATCH 3/3] Ignore absent default setting value --- apps/opencs/model/prefs/state.cpp | 35 +------------------ apps/opencs/model/prefs/state.hpp | 2 -- .../openmw_test_suite/settings/testvalues.cpp | 34 ++++++++++++++++++ components/settings/settings.hpp | 9 +++++ components/settings/settingvalue.hpp | 4 +-- 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index d55913fb3c3..364f7b3320d 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -463,8 +463,6 @@ CSMPrefs::IntSetting& CSMPrefs::State::declareInt(const std::string& key, const if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - setDefault(key, std::to_string(default_)); - CSMPrefs::IntSetting* setting = new CSMPrefs::IntSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -477,10 +475,6 @@ CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble(const std::string& key, if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - std::ostringstream stream; - stream << default_; - setDefault(key, stream.str()); - CSMPrefs::DoubleSetting* setting = new CSMPrefs::DoubleSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); @@ -494,8 +488,6 @@ CSMPrefs::BoolSetting& CSMPrefs::State::declareBool(const std::string& key, cons if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - setDefault(key, default_ ? "true" : "false"); - CSMPrefs::BoolSetting* setting = new CSMPrefs::BoolSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -508,8 +500,6 @@ CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum(const std::string& key, cons if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - setDefault(key, default_.mValue); - CSMPrefs::EnumSetting* setting = new CSMPrefs::EnumSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); @@ -522,8 +512,6 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour(const std::string& key, if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - setDefault(key, default_.name().toUtf8().data()); - CSMPrefs::ColourSetting* setting = new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); @@ -538,9 +526,6 @@ CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut( if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - std::string seqStr = getShortcutManager().convertToString(default_); - setDefault(key, seqStr); - // Setup with actual data QKeySequence sequence; @@ -560,8 +545,6 @@ CSMPrefs::StringSetting& CSMPrefs::State::declareString( if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - setDefault(key, default_); - CSMPrefs::StringSetting* setting = new CSMPrefs::StringSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); @@ -575,9 +558,6 @@ CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& k if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); - std::string modStr = getShortcutManager().convertToString(default_); - setDefault(key, modStr); - // Setup with actual data int modifier; @@ -600,33 +580,20 @@ void CSMPrefs::State::declareSubcategory(const QString& label) new CSMPrefs::Subcategory(&mCurrentCategory->second, &mMutex, label, *mIndex)); } -void CSMPrefs::State::setDefault(const std::string& key, const std::string& default_) -{ - Settings::CategorySetting fullKey(mCurrentCategory->second.getKey(), key); - - Settings::CategorySettingValueMap::iterator iter = Settings::Manager::mDefaultSettings.find(fullKey); - - if (iter == Settings::Manager::mDefaultSettings.end()) - Settings::Manager::mDefaultSettings.insert(std::make_pair(fullKey, default_)); -} - CSMPrefs::State::State(const Files::ConfigurationManager& configurationManager) : mConfigFile("openmw-cs.cfg") , mDefaultConfigFile("defaults-cs.bin") , mConfigurationManager(configurationManager) , mCurrentCategory(mCategories.end()) , mIndex(std::make_unique()) + , mValues(std::make_unique(*mIndex)) { if (sThis) throw std::logic_error("An instance of CSMPRefs::State already exists"); sThis = this; - Values values(*mIndex); - declare(); - - mValues = std::make_unique(std::move(values)); } CSMPrefs::State::~State() diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index 97d657ddaf2..018a81a8d92 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -80,8 +80,6 @@ namespace CSMPrefs void declareSubcategory(const QString& label); - void setDefault(const std::string& key, const std::string& default_); - public: State(const Files::ConfigurationManager& configurationManager); diff --git a/apps/openmw_test_suite/settings/testvalues.cpp b/apps/openmw_test_suite/settings/testvalues.cpp index 81af3087958..236417b559b 100644 --- a/apps/openmw_test_suite/settings/testvalues.cpp +++ b/apps/openmw_test_suite/settings/testvalues.cpp @@ -59,6 +59,33 @@ namespace Settings EXPECT_EQ(values.mCamera.mFieldOfView.get(), 1); } + TEST_F(SettingsValuesTest, constructorWithDefaultShouldDoLookup) + { + Manager::mUserSettings[std::make_pair("category", "value")] = "13"; + Index index; + SettingValue value{ index, "category", "value", 42 }; + EXPECT_EQ(value.get(), 13); + value.reset(); + EXPECT_EQ(value.get(), 42); + } + + TEST_F(SettingsValuesTest, constructorWithDefaultShouldSanitize) + { + Manager::mUserSettings[std::make_pair("category", "value")] = "2"; + Index index; + SettingValue value{ index, "category", "value", -1, Settings::makeClampSanitizerInt(0, 1) }; + EXPECT_EQ(value.get(), 1); + value.reset(); + EXPECT_EQ(value.get(), 0); + } + + TEST_F(SettingsValuesTest, constructorWithDefaultShouldFallbackToDefault) + { + Index index; + const SettingValue value{ index, "category", "value", 42 }; + EXPECT_EQ(value.get(), 42); + } + TEST_F(SettingsValuesTest, moveConstructorShouldSetDefaults) { Index index; @@ -79,6 +106,13 @@ namespace Settings EXPECT_EQ(values.mCamera.mFieldOfView.get(), 1); } + TEST_F(SettingsValuesTest, moveConstructorShouldThrowOnMissingSetting) + { + Index index; + SettingValue defaultValue{ index, "category", "value", 42 }; + EXPECT_THROW([&] { SettingValue value(std::move(defaultValue)); }(), std::runtime_error); + } + TEST_F(SettingsValuesTest, findShouldThrowExceptionOnTypeMismatch) { Index index; diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index c061755bc16..bcdcbb16d1a 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -77,6 +77,15 @@ namespace Settings static osg::Vec2f getVector2(std::string_view setting, std::string_view category); static osg::Vec3f getVector3(std::string_view setting, std::string_view category); + template + static T getOrDefault(std::string_view setting, std::string_view category, const T& defaultValue) + { + const auto key = std::make_pair(category, setting); + if (!mUserSettings.contains(key) && !mDefaultSettings.contains(key)) + return defaultValue; + return get(setting, category); + } + template static T get(std::string_view setting, std::string_view category) { diff --git a/components/settings/settingvalue.hpp b/components/settings/settingvalue.hpp index 392e5b646f5..8183e8c1ac5 100644 --- a/components/settings/settingvalue.hpp +++ b/components/settings/settingvalue.hpp @@ -339,8 +339,8 @@ namespace Settings std::unique_ptr>&& sanitizer = nullptr) : BaseSettingValue(getSettingValueType(), category, name, index) , mSanitizer(std::move(sanitizer)) - , mDefaultValue(defaultValue) - , mValue(defaultValue) + , mDefaultValue(sanitize(defaultValue)) + , mValue(sanitize(Settings::Manager::getOrDefault(mName, mCategory, mDefaultValue))) { }