diff --git a/src/mvvmcore/mvvmcore.pro b/src/mvvmcore/mvvmcore.pro index 31d67ac..cf0ca24 100644 --- a/src/mvvmcore/mvvmcore.pro +++ b/src/mvvmcore/mvvmcore.pro @@ -25,7 +25,8 @@ HEADERS += \ injection.h \ isettingsaccessor.h \ qsettingsaccessor.h \ - settingsentry.h + settingsentry.h \ + settingsconfigloader_p.h SOURCES += \ viewmodel.cpp \ @@ -39,7 +40,8 @@ SOURCES += \ settingsviewmodel.cpp \ isettingsaccessor.cpp \ qsettingsaccessor.cpp \ - settingsentry.cpp + settingsentry.cpp \ + settingsconfigloader.cpp include(../settingsconfig/settingsconfig.pri) diff --git a/src/mvvmcore/qtmvvmcore_global.cpp b/src/mvvmcore/qtmvvmcore_global.cpp index 18f7c65..3be6655 100644 --- a/src/mvvmcore/qtmvvmcore_global.cpp +++ b/src/mvvmcore/qtmvvmcore_global.cpp @@ -1,7 +1,7 @@ #include "qtmvvmcore_global.h" #include "qtmvvm_logging_p.h" #include "serviceregistry.h" -#include "settingssetuploader_p.h" +#include "settingsconfigloader_p.h" #include @@ -12,7 +12,7 @@ void qtMvvmCoreStartup() using namespace QtMvvm; registerInterfaceConverter(); try { - ServiceRegistry::instance()->registerInterface(ServiceRegistry::DestroyOnAppDestroy, true); + ServiceRegistry::instance()->registerInterface(ServiceRegistry::DestroyOnAppDestroy, true); } catch(ServiceExistsException &e) { logDebug() << "Unable to register default ISettingsSetupLoader with error:" << e.what(); } diff --git a/src/mvvmcore/settingsconfigloader.cpp b/src/mvvmcore/settingsconfigloader.cpp new file mode 100644 index 0000000..26af00a --- /dev/null +++ b/src/mvvmcore/settingsconfigloader.cpp @@ -0,0 +1,137 @@ +#include "settingsconfigloader_p.h" +using namespace QtMvvm; +using namespace QtMvvm::SettingsElements; + +SettingsConfigLoader::SettingsConfigLoader(QObject *parent) : + QObject{parent}, + _defaultIcon{QStringLiteral("qrc:/de/skycoder42/qtmvvm/icons/settings.svg")} +{} + +void SettingsConfigLoader::changeDefaultIcon(const QUrl &defaultIcon) +{ + _defaultIcon = defaultIcon; +} + +Setup SettingsConfigLoader::loadSetup(const QString &filePath, const QString &frontend, const QFileSelector *selector) const +{ + Setup setup; + if(!_cache.contains(filePath)) { + try { + auto config = const_cast(this)->readDocument(filePath); + if(!nonstd::holds_alternative(config)) + throw SettingsConfigException{"Root Element of \"" + filePath.toUtf8() + "\" must be a SettingsConfig"}; + _cache.insert(filePath, convertSettings(nonstd::get(config))); + } catch (Exception &e) { + throw SettingsConfigException{e}; + } + } else + setup = *(_cache.object(filePath)); + + //TODO clearSetup(setup, frontend, selector->allSelectors()); + return setup; +} + +Setup *SettingsConfigLoader::convertSettings(const SettingsConfigType &settings) const +{ + QScopedPointer setup{new Setup{}}; + + setup->allowSearch = settings.allowSearch; + setup->allowRestore = settings.allowRestore; + + for(const auto &element : settings.content) { + if(nonstd::holds_alternative(element)) {//holds categories -> read them + const auto &category = nonstd::get(element); + setup->categories.append(convertCategory(category, category.content)); + } else { //hold anything else -> create default from all child and thus break + setup->categories.append(convertCategory({}, settings.content)); + break; + } + } + + return setup.take(); +} + +template +Category SettingsConfigLoader::convertCategory(const CategoryType &category, const QList> &content) const +{ + Category cat; + cat.title = category.title.value_or(tr("General Settings")); + cat.icon = category.icon ? QUrl{category.icon.value()} : _defaultIcon; + cat.tooltip = category.tooltip.value_or(QString{}); + cat.selectors = category.selectors.value_or(QString{}); + cat.frontends = category.frontends.value_or(QString{}); + for(const auto &element : content) { + if(nonstd::holds_alternative(element)) {//holds sections -> read them + const auto §ion = nonstd::get(element); + cat.sections.append(convertSection(section, section.content)); + } else { //hold anything else -> create default from all child and thus break + cat.sections.append(convertSection({}, content)); + break; + } + } + return cat; +} + +template +Section SettingsConfigLoader::convertSection(const SectionType §ion, const QList> &content) const +{ + Section sec; + sec.title = section.title.value_or(tr("General")); + sec.icon = section.icon ? QUrl{section.icon.value()} : QUrl{}; + sec.tooltip = section.tooltip.value_or(QString{}); + sec.selectors = section.selectors.value_or(QString{}); + sec.frontends = section.frontends.value_or(QString{}); + for(const auto &element : content) { + if(nonstd::holds_alternative(element)) {//holds sections -> read them + const auto &group = nonstd::get(element); + sec.groups.append(convertGroup(group, group.content)); + } else { //hold anything else -> create default from all child and thus break + sec.groups.append(convertGroup({}, content)); + break; + } + } + return sec; +} + +template +Group SettingsConfigLoader::convertGroup(const GroupType &group, const QList> &content) const +{ + Group grp; + grp.title = group.title.value_or(QString{}); + grp.tooltip = group.tooltip.value_or(QString{}); + grp.selectors = group.selectors.value_or(QString{}); + grp.frontends = group.frontends.value_or(QString{}); + for(const auto &element : content) { + if(nonstd::holds_alternative(element)) {//holds sections -> read them + const auto &entry = nonstd::get(element); + //TODO read it + } else + Q_UNREACHABLE(); + } + return grp; +} + + + +SettingsConfigException::SettingsConfigException(SettingsConfigBase::Exception &exception) : + _what{exception.qWhat().toUtf8()} +{} + +SettingsConfigException::SettingsConfigException(QByteArray what) : + _what{std::move(what)} +{} + +const char *SettingsConfigException::what() const noexcept +{ + return _what.constData(); +} + +void SettingsConfigException::raise() const +{ + throw *this; +} + +QException *SettingsConfigException::clone() const +{ + return new SettingsConfigException{_what}; +} diff --git a/src/mvvmcore/settingsconfigloader_p.h b/src/mvvmcore/settingsconfigloader_p.h new file mode 100644 index 0000000..42ba5ca --- /dev/null +++ b/src/mvvmcore/settingsconfigloader_p.h @@ -0,0 +1,55 @@ +#ifndef SETTINGSCONFIGLOADER_P_H +#define SETTINGSCONFIGLOADER_P_H + +#include +#include + +#include "settingssetup.h" + +#include + +namespace QtMvvm { + +class SettingsConfigLoader : public QObject, public ISettingsSetupLoader, public SettingsConfigImpl +{ + Q_OBJECT + Q_INTERFACES(QtMvvm::ISettingsSetupLoader) + +public: + Q_INVOKABLE SettingsConfigLoader(QObject *parent = nullptr); + + void changeDefaultIcon(const QUrl &defaultIcon) override; + SettingsElements::Setup loadSetup(const QString &filePath, const QString &frontend, const QFileSelector *selector) const override; + +private: + QUrl _defaultIcon; + mutable QCache _cache; + + SettingsElements::Setup *convertSettings(const SettingsConfigType &settings) const; + + template + SettingsElements::Category convertCategory(const CategoryType &category, const QList> &content) const; + template + SettingsElements::Section convertSection(const SectionType §ion, const QList> &content) const; + template + SettingsElements::Group convertGroup(const GroupType &group, const QList> &content) const; +}; + +class SettingsConfigException : public SettingsLoaderException +{ +public: + SettingsConfigException(SettingsConfigBase::Exception &exception); + SettingsConfigException(QByteArray what); + + const char *what() const noexcept override; + + void raise() const override; + QException *clone() const override; + +private: + const QByteArray _what; +}; + +} + +#endif // SETTINGSCONFIGLOADER_P_H diff --git a/src/mvvmcore/settingssetup.h b/src/mvvmcore/settingssetup.h index 35a97c5..6d94e68 100644 --- a/src/mvvmcore/settingssetup.h +++ b/src/mvvmcore/settingssetup.h @@ -122,7 +122,7 @@ public: //! Can be used to overwrite the default icon for categories virtual void changeDefaultIcon(const QUrl &defaultIcon) = 0; //! Loads the settings setup from the given file - virtual SettingsElements::Setup loadSetup(const QString &filePath, const QString &frontend, const QFileSelector *selector) const = 0; + virtual SettingsElements::Setup loadSetup(const QString &filePath, const QString &frontend, const QFileSelector *selector) const = 0; //MAJOR remove const }; } diff --git a/src/mvvmcore/settingssetuploader_p.h b/src/mvvmcore/settingssetuploader_p.h index dd8c573..144456e 100644 --- a/src/mvvmcore/settingssetuploader_p.h +++ b/src/mvvmcore/settingssetuploader_p.h @@ -14,7 +14,7 @@ namespace QtMvvm { -class Q_MVVMCORE_EXPORT SettingsSetupLoader : public QObject, public ISettingsSetupLoader +class Q_MVVMCORE_EXPORT Q_DECL_DEPRECATED SettingsSetupLoader : public QObject, public ISettingsSetupLoader { Q_OBJECT Q_INTERFACES(QtMvvm::ISettingsSetupLoader)