summaryrefslogtreecommitdiff
path: root/src/settingsutilities.h
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-09-02 15:07:35 -0400
committerisanae <14251494+isanae@users.noreply.github.com>2019-09-02 15:07:35 -0400
commit3757aa3f532c943f8a47e997d0a4f250d9dacdd3 (patch)
tree65fa840ea06ba27b8a22f23db1089b9d20ff1f85 /src/settingsutilities.h
parente9dba260cb9548dd5863ac66da18c295f6499b92 (diff)
split into settingsutilities
Diffstat (limited to 'src/settingsutilities.h')
-rw-r--r--src/settingsutilities.h266
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