6 changed files with 200 additions and 6 deletions
			
			
		@ -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<SettingsConfigLoader*>(this)->readDocument(filePath); | 
				
			||||
 | 
								if(!nonstd::holds_alternative<SettingsConfigType>(config)) | 
				
			||||
 | 
									throw SettingsConfigException{"Root Element of \"" + filePath.toUtf8() + "\" must be a SettingsConfig"}; | 
				
			||||
 | 
								_cache.insert(filePath, convertSettings(nonstd::get<SettingsConfigType>(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> setup{new Setup{}}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						setup->allowSearch = settings.allowSearch; | 
				
			||||
 | 
						setup->allowRestore = settings.allowRestore; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						for(const auto &element : settings.content) { | 
				
			||||
 | 
							if(nonstd::holds_alternative<CategoryType>(element)) {//holds categories -> read them
 | 
				
			||||
 | 
								const auto &category = nonstd::get<CategoryType>(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<typename... TContent> | 
				
			||||
 | 
					Category SettingsConfigLoader::convertCategory(const CategoryType &category, const QList<variant<TContent...>> &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<SectionType>(element)) {//holds sections -> read them
 | 
				
			||||
 | 
								const auto §ion = nonstd::get<SectionType>(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<typename... TContent> | 
				
			||||
 | 
					Section SettingsConfigLoader::convertSection(const SectionType §ion, const QList<variant<TContent...>> &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<GroupType>(element)) {//holds sections -> read them
 | 
				
			||||
 | 
								const auto &group = nonstd::get<GroupType>(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<typename... TContent> | 
				
			||||
 | 
					Group SettingsConfigLoader::convertGroup(const GroupType &group, const QList<variant<TContent...>> &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<EntryType>(element)) {//holds sections -> read them
 | 
				
			||||
 | 
								const auto &entry = nonstd::get<EntryType>(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}; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,55 @@ | 
				
			|||||
 | 
					#ifndef SETTINGSCONFIGLOADER_P_H | 
				
			||||
 | 
					#define SETTINGSCONFIGLOADER_P_H | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include <QtCore/QObject> | 
				
			||||
 | 
					#include <QtCore/QCache> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include "settingssetup.h" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include <settingsconfigimpl.h> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					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<QString, SettingsElements::Setup> _cache; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						SettingsElements::Setup *convertSettings(const SettingsConfigType &settings) const; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						template <typename... TContent> | 
				
			||||
 | 
						SettingsElements::Category convertCategory(const CategoryType &category, const QList<variant<TContent...>> &content) const; | 
				
			||||
 | 
						template <typename... TContent> | 
				
			||||
 | 
						SettingsElements::Section convertSection(const SectionType §ion, const QList<variant<TContent...>> &content) const; | 
				
			||||
 | 
						template <typename... TContent> | 
				
			||||
 | 
						SettingsElements::Group convertGroup(const GroupType &group, const QList<variant<TContent...>> &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
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue