diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-09-02 15:07:35 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-09-02 15:07:35 -0400 |
| commit | 3757aa3f532c943f8a47e997d0a4f250d9dacdd3 (patch) | |
| tree | 65fa840ea06ba27b8a22f23db1089b9d20ff1f85 /src/settingsutilities.h | |
| parent | e9dba260cb9548dd5863ac66da18c295f6499b92 (diff) | |
split into settingsutilities
Diffstat (limited to 'src/settingsutilities.h')
| -rw-r--r-- | src/settingsutilities.h | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/src/settingsutilities.h b/src/settingsutilities.h new file mode 100644 index 00000000..b70e55ef --- /dev/null +++ b/src/settingsutilities.h @@ -0,0 +1,266 @@ +#ifndef SETTINGSUTILITIES_H +#define SETTINGSUTILITIES_H + +#include <log.h> + +class ExpanderWidget; + +template <class T, class=void> +struct ValueConverter +{ + static const T& convert(const T& t) + { + return t; + } +}; + +template <class T> +struct ValueConverter<T, std::enable_if_t<std::is_enum_v<T>>> +{ + static QString convert(const T& t) + { + return QString("%1").arg(static_cast<std::underlying_type_t<T>>(t)); + } +}; + + +template <class T> +void logChange( + const QString& displayName, std::optional<T> oldValue, const T& newValue) +{ + using VC = ValueConverter<T>; + + if (oldValue) { + log::debug( + "setting '{}' changed from '{}' to '{}'", + displayName, VC::convert(*oldValue), VC::convert(newValue)); + } else { + log::debug( + "setting '{}' set to '{}'", + displayName, VC::convert(newValue)); + } +} + +void logRemoval(const QString& name); + + +QString settingName(const QString& section, const QString& key); + +template <class T> +void setImpl( + QSettings& settings, const QString& displayName, + const QString& section, const QString& key, const T& value) +{ + const auto current = getOptional<T>(settings, section, key); + + if (current && *current == value) { + // no change + return; + } + + const auto name = settingName(section, key); + + logChange(displayName, current, value); + + if constexpr (std::is_enum_v<T>) { + settings.setValue( + name, static_cast<std::underlying_type_t<T>>(value)); + } else { + settings.setValue(name, value); + } +} + +void removeImpl( + QSettings& settings, const QString& displayName, + const QString& section, const QString& key); + + +template <class T> +std::optional<T> getOptional( + const QSettings& settings, + const QString& section, const QString& key, std::optional<T> def={}) +{ + if (settings.contains(settingName(section, key))) { + const auto v = settings.value(settingName(section, key)); + + if constexpr (std::is_enum_v<T>) { + return static_cast<T>(v.value<std::underlying_type_t<T>>()); + } else { + return v.value<T>(); + } + } + + return def; +} + +template <class T> +T get( + const QSettings& settings, + const QString& section, const QString& key, T def) +{ + if (auto v=getOptional<T>(settings, section, key)) { + return *v; + } else { + return def; + } +} + +template <class T> +void set( + QSettings& settings, + const QString& section, const QString& key, const T& value) +{ + setImpl(settings, settingName(section, key), section, key, value); +} + +void remove(QSettings& settings, const QString& section, const QString& key); +void removeSection(QSettings& settings, const QString& section); + + +class ScopedGroup +{ +public: + ScopedGroup(QSettings& s, const QString& name); + ~ScopedGroup(); + + ScopedGroup(const ScopedGroup&) = delete; + ScopedGroup& operator=(const ScopedGroup&) = delete; + + template <class T> + void set(const QString& key, const T& value) + { + setImpl(m_settings, settingName(m_name, key), "", key, value); + } + + void remove(const QString& key); + + QStringList keys() const; + + template <class F> + void for_each(F&& f) const + { + for (const QString& key : keys()) { + f(key); + } + } + + template <class T> + std::optional<T> getOptional(const QString& key, std::optional<T> def={}) const + { + return ::getOptional<T>(m_settings, "", key, def); + } + + template <class T> + T get(const QString& key, T def={}) const + { + return ::get<T>(m_settings, "", key, def); + } + +private: + QSettings& m_settings; + QString m_name; +}; + + +class ScopedReadArray +{ +public: + ScopedReadArray(QSettings& s, const QString& section); + ~ScopedReadArray(); + + ScopedReadArray(const ScopedReadArray&) = delete; + ScopedReadArray& operator=(const ScopedReadArray&) = delete; + + template <class F> + void for_each(F&& f) const + { + for (int i=0; i<count(); ++i) { + m_settings.setArrayIndex(i); + f(); + } + } + + template <class T> + std::optional<T> getOptional(const QString& key, std::optional<T> def={}) const + { + return ::getOptional<T>(m_settings, "", key, def); + } + + template <class T> + T get(const QString& key, T def={}) const + { + return ::get<T>(m_settings, "", key, def); + } + + int count() const; + QStringList keys() const; + +private: + QSettings& m_settings; + int m_count; +}; + + +class ScopedWriteArray +{ +public: + ScopedWriteArray(QSettings& s, const QString& section); + ~ScopedWriteArray(); + + ScopedWriteArray(const ScopedWriteArray&) = delete; + ScopedWriteArray& operator=(const ScopedWriteArray&) = delete; + + void next(); + + template <class T> + void set(const QString& key, const T& value) + { + const auto displayName = QString("%1/%2\\%3") + .arg(m_section) + .arg(m_i) + .arg(key); + + setImpl(m_settings, displayName, "", key, value); + } + +private: + QSettings& m_settings; + QString m_section; + int m_i; +}; + + +QString widgetNameWithTopLevel(const QWidget* widget); +QString widgetName(const QMainWindow* w); +QString widgetName(const QHeaderView* w); +QString widgetName(const ExpanderWidget* w); +QString widgetName(const QWidget* w); + +template <class Widget> +QString geoSettingName(const Widget* widget) +{ + return widgetName(widget) + "_geometry"; +} + +template <class Widget> +QString stateSettingName(const Widget* widget) +{ + return widgetName(widget) + "_state"; +} + +template <class Widget> +QString visibilitySettingName(const Widget* widget) +{ + return widgetName(widget) + "_visibility"; +} + +QString dockSettingName(const QDockWidget* dock); +QString indexSettingName(const QWidget* widget); +QString checkedSettingName(const QAbstractButton* b); + +void warnIfNotCheckable(const QAbstractButton* b); + +bool setWindowsCredential(const QString key, const QString data); +QString getWindowsCredential(const QString key); + +#endif // SETTINGSUTILITIES_H |
