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 | |
| parent | e9dba260cb9548dd5863ac66da18c295f6499b92 (diff) | |
split into settingsutilities
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/settings.cpp | 452 | ||||
| -rw-r--r-- | src/settings.h | 3 | ||||
| -rw-r--r-- | src/settingsutilities.cpp | 247 | ||||
| -rw-r--r-- | src/settingsutilities.h | 266 |
5 files changed, 522 insertions, 455 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8316e7e..ea27184b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,7 @@ SET(organizer_SRCS settingsdialogsteam.cpp settingsdialogworkarounds.cpp settings.cpp + settingsutilities.cpp selfupdater.cpp selectiondialog.cpp queryoverwritedialog.cpp @@ -166,6 +167,7 @@ SET(organizer_HDRS settingsdialogsteam.h settingsdialogworkarounds.h settings.h + settingsutilities.h selfupdater.h selectiondialog.h queryoverwritedialog.h @@ -444,6 +446,10 @@ set(profiles set(settings settings + settingsutilities +) + +set(settingsdialog settingsdialog settingsdialogdiagnostics settingsdialoggeneral @@ -490,7 +496,8 @@ set(widgets set(src_filters application core browser dialogs downloads env executables locking modinfo - modinfo\\dialog modlist plugins previews profiles settings utilities widgets + modinfo\\dialog modlist plugins previews profiles settings settingsdialog + utilities widgets ) foreach(filter in list ${src_filters}) diff --git a/src/settings.cpp b/src/settings.cpp index 8b063efb..14189be3 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -18,6 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. */ #include "settings.h" +#include "settingsutilities.h" #include "serverinfo.h" #include "executableslist.h" #include "appconfig.h" @@ -27,310 +28,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase; -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) -{ - log::debug("setting '{}' removed", name); -} - - -QString settingName(const QString& section, const QString& key) -{ - if (section.isEmpty()) { - return key; - } else if (key.isEmpty()) { - return section; - } else { - if (section.compare("General", Qt::CaseInsensitive) == 0) { - return key; - } else { - return section + "/" + 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) -{ - if (key.isEmpty()) { - if (!settings.childGroups().contains(section, Qt::CaseInsensitive)) { - // not there - return; - } - } else { - if (!settings.contains(settingName(section, key))) { - // not there - return; - } - } - - logRemoval(displayName); - settings.remove(settingName(section, 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) -{ - removeImpl(settings, settingName(section, key), section, key); -} - -void removeSection(QSettings& settings, const QString& section) -{ - removeImpl(settings, section, section, ""); -} - - -class ScopedGroup -{ -public: - ScopedGroup(QSettings& s, const QString& name) - : m_settings(s), m_name(name) - { - m_settings.beginGroup(m_name); - } - - ~ScopedGroup() - { - m_settings.endGroup(); - } - - 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) - { - removeImpl(m_settings, settingName(m_name, key), "", key); - } - - QStringList keys() const - { - return m_settings.childKeys(); - } - - 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) - : m_settings(s), m_count(0) - { - m_count = m_settings.beginReadArray(section); - } - - ~ScopedReadArray() - { - m_settings.endArray(); - } - - 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 - { - return m_count; - } - - QStringList keys() const - { - return m_settings.childKeys(); - } - -private: - QSettings& m_settings; - int m_count; -}; - - -class ScopedWriteArray -{ -public: - ScopedWriteArray(QSettings& s, const QString& section) - : m_settings(s), m_section(section), m_i(0) - { - m_settings.beginWriteArray(section); - } - - ~ScopedWriteArray() - { - m_settings.endArray(); - } - - ScopedWriteArray(const ScopedWriteArray&) = delete; - ScopedWriteArray& operator=(const ScopedWriteArray&) = delete; - - void next() - { - m_settings.setArrayIndex(m_i); - ++m_i; - } - - 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; -}; - EndorsementState endorsementStateFromString(const QString& s) { @@ -360,153 +57,6 @@ QString toString(EndorsementState s) } -QString widgetNameWithTopLevel(const QWidget* widget) -{ - QStringList components; - - auto* tl = widget->window(); - - if (tl == widget) { - // this is a top level widget, such as a dialog - components.push_back(widget->objectName()); - } else { - // this is a widget - const auto toplevelName = tl->objectName(); - if (!toplevelName.isEmpty()) { - components.push_back(toplevelName); - } - - const auto widgetName = widget->objectName(); - if (!widgetName.isEmpty()) { - components.push_back(widgetName); - } - } - - if (components.isEmpty()) { - // can't do much - return "unknown_widget"; - } - - return components.join("_"); -} - -QString widgetName(const QMainWindow* w) -{ - return w->objectName(); -} - -QString widgetName(const QHeaderView* w) -{ - return widgetNameWithTopLevel(w->parentWidget()); -} - -QString widgetName(const ExpanderWidget* w) -{ - return widgetNameWithTopLevel(w->button()); -} - -QString widgetName(const QWidget* w) -{ - return widgetNameWithTopLevel(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) -{ - return "MainWindow_docks_" + dock->objectName() + "_size"; -} - -QString indexSettingName(const QWidget* widget) -{ - return widgetNameWithTopLevel(widget) + "_index"; -} - -QString checkedSettingName(const QAbstractButton* b) -{ - return widgetNameWithTopLevel(b) + "_checked"; -} - -void warnIfNotCheckable(const QAbstractButton* b) -{ - if (!b->isCheckable()) { - log::warn( - "button '{}' used in the settings as a checkbox or radio button " - "but is not checkable", b->objectName()); - } -} - - -bool setWindowsCredential(const QString key, const QString data) -{ - QString finalKey("ModOrganizer2_" + key); - wchar_t* keyData = new wchar_t[finalKey.size()+1]; - finalKey.toWCharArray(keyData); - keyData[finalKey.size()] = L'\0'; - bool result = false; - if (data.isEmpty()) { - result = CredDeleteW(keyData, CRED_TYPE_GENERIC, 0); - if (!result) - if (GetLastError() == ERROR_NOT_FOUND) - result = true; - } else { - wchar_t* charData = new wchar_t[data.size()]; - data.toWCharArray(charData); - - CREDENTIALW cred = {}; - cred.Flags = 0; - cred.Type = CRED_TYPE_GENERIC; - cred.TargetName = keyData; - cred.CredentialBlob = (LPBYTE)charData; - cred.CredentialBlobSize = sizeof(wchar_t) * data.size(); - cred.Persist = CRED_PERSIST_LOCAL_MACHINE; - - result = CredWriteW(&cred, 0); - delete[] charData; - } - delete[] keyData; - return result; -} - -QString getWindowsCredential(const QString key) -{ - QString result; - QString finalKey("ModOrganizer2_" + key); - wchar_t* keyData = new wchar_t[finalKey.size()+1]; - finalKey.toWCharArray(keyData); - keyData[finalKey.size()] = L'\0'; - PCREDENTIALW creds; - if (CredReadW(keyData, 1, 0, &creds)) { - wchar_t *charData = (wchar_t *)creds->CredentialBlob; - result = QString::fromWCharArray(charData, creds->CredentialBlobSize / sizeof(wchar_t)); - CredFree(creds); - } else { - const auto e = GetLastError(); - if (e != ERROR_NOT_FOUND) { - log::error("Retrieving encrypted data failed: {}", formatSystemMessage(e)); - } - } - delete[] keyData; - return result; -} - - Settings *Settings::s_Instance = nullptr; Settings::Settings(const QString& path) : diff --git a/src/settings.h b/src/settings.h index 5c0a2542..68cfb9b7 100644 --- a/src/settings.h +++ b/src/settings.h @@ -36,8 +36,6 @@ namespace MOBase { class QSplitter; -class PluginContainer; -class ServerInfo; class ServerList; class Settings; class ExpanderWidget; @@ -505,7 +503,6 @@ private: }; - /** * manages the settings for Mod Organizer. The settings are not cached * inside the class but read/written directly from/to disc diff --git a/src/settingsutilities.cpp b/src/settingsutilities.cpp new file mode 100644 index 00000000..7ac95b5f --- /dev/null +++ b/src/settingsutilities.cpp @@ -0,0 +1,247 @@ +#include "settingsutilities.h" +#include "expanderwidget.h" +#include <utility.h> + +using namespace MOBase; + +void logRemoval(const QString& name) +{ + log::debug("setting '{}' removed", name); +} + + +QString settingName(const QString& section, const QString& key) +{ + if (section.isEmpty()) { + return key; + } else if (key.isEmpty()) { + return section; + } else { + if (section.compare("General", Qt::CaseInsensitive) == 0) { + return key; + } else { + return section + "/" + key; + } + } +} + +void removeImpl( + QSettings& settings, const QString& displayName, + const QString& section, const QString& key) +{ + if (key.isEmpty()) { + if (!settings.childGroups().contains(section, Qt::CaseInsensitive)) { + // not there + return; + } + } else { + if (!settings.contains(settingName(section, key))) { + // not there + return; + } + } + + logRemoval(displayName); + settings.remove(settingName(section, key)); +} + +void remove(QSettings& settings, const QString& section, const QString& key) +{ + removeImpl(settings, settingName(section, key), section, key); +} + +void removeSection(QSettings& settings, const QString& section) +{ + removeImpl(settings, section, section, ""); +} + + +ScopedGroup::ScopedGroup(QSettings& s, const QString& name) + : m_settings(s), m_name(name) +{ + m_settings.beginGroup(m_name); +} + +ScopedGroup::~ScopedGroup() +{ + m_settings.endGroup(); +} + +void ScopedGroup::remove(const QString& key) +{ + removeImpl(m_settings, settingName(m_name, key), "", key); +} + +QStringList ScopedGroup::keys() const +{ + return m_settings.childKeys(); +} + + +ScopedReadArray::ScopedReadArray(QSettings& s, const QString& section) + : m_settings(s), m_count(0) +{ + m_count = m_settings.beginReadArray(section); +} + +ScopedReadArray::~ScopedReadArray() +{ + m_settings.endArray(); +} + +int ScopedReadArray::count() const +{ + return m_count; +} + +QStringList ScopedReadArray::keys() const +{ + return m_settings.childKeys(); +} + + +ScopedWriteArray::ScopedWriteArray(QSettings& s, const QString& section) + : m_settings(s), m_section(section), m_i(0) +{ + m_settings.beginWriteArray(section); +} + +ScopedWriteArray::~ScopedWriteArray() +{ + m_settings.endArray(); +} + +void ScopedWriteArray::next() +{ + m_settings.setArrayIndex(m_i); + ++m_i; +} + + +QString widgetNameWithTopLevel(const QWidget* widget) +{ + QStringList components; + + auto* tl = widget->window(); + + if (tl == widget) { + // this is a top level widget, such as a dialog + components.push_back(widget->objectName()); + } else { + // this is a widget + const auto toplevelName = tl->objectName(); + if (!toplevelName.isEmpty()) { + components.push_back(toplevelName); + } + + const auto widgetName = widget->objectName(); + if (!widgetName.isEmpty()) { + components.push_back(widgetName); + } + } + + if (components.isEmpty()) { + // can't do much + return "unknown_widget"; + } + + return components.join("_"); +} + +QString widgetName(const QMainWindow* w) +{ + return w->objectName(); +} + +QString widgetName(const QHeaderView* w) +{ + return widgetNameWithTopLevel(w->parentWidget()); +} + +QString widgetName(const ExpanderWidget* w) +{ + return widgetNameWithTopLevel(w->button()); +} + +QString widgetName(const QWidget* w) +{ + return widgetNameWithTopLevel(w); +} + +QString dockSettingName(const QDockWidget* dock) +{ + return "MainWindow_docks_" + dock->objectName() + "_size"; +} + +QString indexSettingName(const QWidget* widget) +{ + return widgetNameWithTopLevel(widget) + "_index"; +} + +QString checkedSettingName(const QAbstractButton* b) +{ + return widgetNameWithTopLevel(b) + "_checked"; +} + +void warnIfNotCheckable(const QAbstractButton* b) +{ + if (!b->isCheckable()) { + log::warn( + "button '{}' used in the settings as a checkbox or radio button " + "but is not checkable", b->objectName()); + } +} + + +bool setWindowsCredential(const QString key, const QString data) +{ + QString finalKey("ModOrganizer2_" + key); + wchar_t* keyData = new wchar_t[finalKey.size()+1]; + finalKey.toWCharArray(keyData); + keyData[finalKey.size()] = L'\0'; + bool result = false; + if (data.isEmpty()) { + result = CredDeleteW(keyData, CRED_TYPE_GENERIC, 0); + if (!result) + if (GetLastError() == ERROR_NOT_FOUND) + result = true; + } else { + wchar_t* charData = new wchar_t[data.size()]; + data.toWCharArray(charData); + + CREDENTIALW cred = {}; + cred.Flags = 0; + cred.Type = CRED_TYPE_GENERIC; + cred.TargetName = keyData; + cred.CredentialBlob = (LPBYTE)charData; + cred.CredentialBlobSize = sizeof(wchar_t) * data.size(); + cred.Persist = CRED_PERSIST_LOCAL_MACHINE; + + result = CredWriteW(&cred, 0); + delete[] charData; + } + delete[] keyData; + return result; +} + +QString getWindowsCredential(const QString key) +{ + QString result; + QString finalKey("ModOrganizer2_" + key); + wchar_t* keyData = new wchar_t[finalKey.size()+1]; + finalKey.toWCharArray(keyData); + keyData[finalKey.size()] = L'\0'; + PCREDENTIALW creds; + if (CredReadW(keyData, 1, 0, &creds)) { + wchar_t *charData = (wchar_t *)creds->CredentialBlob; + result = QString::fromWCharArray(charData, creds->CredentialBlobSize / sizeof(wchar_t)); + CredFree(creds); + } else { + const auto e = GetLastError(); + if (e != ERROR_NOT_FOUND) { + log::error("Retrieving encrypted data failed: {}", formatSystemMessage(e)); + } + } + delete[] keyData; + return result; +} 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 |
