10 changed files with 390 additions and 2 deletions
			
			
		@ -0,0 +1,6 @@ | 
				
			|||||
 | 
					#include "isettingsaccessor.h" | 
				
			||||
 | 
					using namespace QtMvvm; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					ISettingsAccessor::ISettingsAccessor(QObject *parent) : | 
				
			||||
 | 
						QObject{parent} | 
				
			||||
 | 
					{} | 
				
			||||
@ -0,0 +1,39 @@ | 
				
			|||||
 | 
					#ifndef QTMVVM_ISETTINGSACCESSOR_H | 
				
			||||
 | 
					#define QTMVVM_ISETTINGSACCESSOR_H | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include <QtCore/qobject.h> | 
				
			||||
 | 
					#include <QtCore/qstring.h> | 
				
			||||
 | 
					#include <QtCore/qvariant.h> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include "QtMvvmCore/qtmvvmcore_global.h" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					namespace QtMvvm { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class Q_MVVMCORE_EXPORT ISettingsAccessor : public QObject | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						Q_OBJECT | 
				
			||||
 | 
						Q_DISABLE_COPY(ISettingsAccessor) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public: | 
				
			||||
 | 
						ISettingsAccessor(QObject *parent = nullptr); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						virtual bool contains(const QString &key) const = 0; | 
				
			||||
 | 
						virtual QVariant load(const QString &key, const QVariant &defaultValue = {}) const = 0; | 
				
			||||
 | 
						virtual void save(const QString &key, const QVariant &value) = 0; | 
				
			||||
 | 
						virtual void remove(const QString &key) = 0; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public Q_SLOTS: | 
				
			||||
 | 
						virtual void sync() = 0; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Q_SIGNALS: | 
				
			||||
 | 
						void entryChanged(const QString &key, const QVariant &value); | 
				
			||||
 | 
						void entryRemoved(const QString &key); | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#define ISettingsAccessorIid "de.skycoder42.qtmvvm.core.ISettingsAccessor" | 
				
			||||
 | 
					Q_DECLARE_INTERFACE(QtMvvm::ISettingsAccessor, ISettingsAccessorIid) | 
				
			||||
 | 
					Q_DECLARE_METATYPE(QtMvvm::ISettingsAccessor*) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#endif // QTMVVM_ISETTINGSACCESSOR_H
 | 
				
			||||
@ -0,0 +1,60 @@ | 
				
			|||||
 | 
					#include "qsettingsaccessor.h" | 
				
			||||
 | 
					using namespace QtMvvm; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					namespace QtMvvm { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class QSettingsAccessorPrivate | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					public: | 
				
			||||
 | 
						QSettingsAccessorPrivate(QSettings *settings); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						QSettings *settings; | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QSettingsAccessor::QSettingsAccessor(QObject *parent) : | 
				
			||||
 | 
						QSettingsAccessor{new QSettings{}, parent} | 
				
			||||
 | 
					{} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QSettingsAccessor::QSettingsAccessor(QSettings *settings, QObject *parent) : | 
				
			||||
 | 
						ISettingsAccessor{parent}, | 
				
			||||
 | 
						d{new QSettingsAccessorPrivate{settings}} | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						d->settings->setParent(this); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QSettingsAccessor::~QSettingsAccessor() = default; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					bool QSettingsAccessor::contains(const QString &key) const | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						return d->settings->contains(key); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QVariant QSettingsAccessor::load(const QString &key, const QVariant &defaultValue) const | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						return d->settings->value(key, defaultValue); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void QSettingsAccessor::save(const QString &key, const QVariant &value) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						d->settings->setValue(key, value); | 
				
			||||
 | 
						emit entryChanged(key, value); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void QSettingsAccessor::remove(const QString &key) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						d->settings->remove(key); | 
				
			||||
 | 
						emit entryRemoved(key); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void QSettingsAccessor::sync() | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						d->settings->sync(); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QSettingsAccessorPrivate::QSettingsAccessorPrivate(QSettings *settings) : | 
				
			||||
 | 
						settings{settings} | 
				
			||||
 | 
					{} | 
				
			||||
@ -0,0 +1,37 @@ | 
				
			|||||
 | 
					#ifndef QTMVVM_QSETTINGSACCESSOR_H | 
				
			||||
 | 
					#define QTMVVM_QSETTINGSACCESSOR_H | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include <QtCore/qsettings.h> | 
				
			||||
 | 
					#include <QtCore/qscopedpointer.h> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include "QtMvvmCore/qtmvvmcore_global.h" | 
				
			||||
 | 
					#include "QtMvvmCore/isettingsaccessor.h" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					namespace QtMvvm { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class QSettingsAccessorPrivate; | 
				
			||||
 | 
					class Q_MVVMCORE_EXPORT QSettingsAccessor : public ISettingsAccessor | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						Q_OBJECT | 
				
			||||
 | 
						Q_INTERFACES(QtMvvm::ISettingsAccessor) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public: | 
				
			||||
 | 
						Q_INVOKABLE explicit QSettingsAccessor(QObject *parent = nullptr); | 
				
			||||
 | 
						explicit QSettingsAccessor(QSettings *settings, QObject *parent = nullptr); | 
				
			||||
 | 
						~QSettingsAccessor() override; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						bool contains(const QString &key) const override; | 
				
			||||
 | 
						QVariant load(const QString &key, const QVariant &defaultValue) const override; | 
				
			||||
 | 
						void save(const QString &key, const QVariant &value) override; | 
				
			||||
 | 
						void remove(const QString &key) override; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public Q_SLOTS: | 
				
			||||
 | 
						void sync() override; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					private: | 
				
			||||
 | 
						QScopedPointer<QSettingsAccessorPrivate> d; | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#endif // QTMVVM_QSETTINGSACCESSOR_H
 | 
				
			||||
@ -0,0 +1,124 @@ | 
				
			|||||
 | 
					#ifndef QTMVVM_SETTINGSENTRY_H | 
				
			||||
 | 
					#define QTMVVM_SETTINGSENTRY_H | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#include "QtMvvmCore/isettingsaccessor.h" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					namespace QtMvvm { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template <typename T> | 
				
			||||
 | 
					class SettingsEntry | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						Q_DISABLE_COPY(SettingsEntry) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public: | 
				
			||||
 | 
						SettingsEntry() = default; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						bool isSet() const; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						T get() const; | 
				
			||||
 | 
						void set(const T &value); | 
				
			||||
 | 
						void reset(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						SettingsEntry<T> &operator=(const T &value); | 
				
			||||
 | 
						operator const T() const; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						void addChangeCallback(const std::function<void(T)> &callback); | 
				
			||||
 | 
						void addChangeCallback(QObject *scope, const std::function<void(T)> &callback); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						// internal
 | 
				
			||||
 | 
						void setup(const QString &key, ISettingsAccessor *accessor, const QVariant &defaultValue = {}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					private: | 
				
			||||
 | 
						QString _key; | 
				
			||||
 | 
						ISettingsAccessor *_accessor = nullptr; | 
				
			||||
 | 
						QVariant _default; | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template <> | 
				
			||||
 | 
					class SettingsEntry<void> | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						Q_DISABLE_COPY(SettingsEntry) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public: | 
				
			||||
 | 
						SettingsEntry() = default; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						// internal
 | 
				
			||||
 | 
						void setup(const QString &, ISettingsAccessor *, const QVariant & = {}) {} | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// ------------- Generic Implementation -------------
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					bool SettingsEntry<T>::isSet() const | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						return _accessor->contains(_key); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					T SettingsEntry<T>::get() const | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						return _accessor->load(_key, _default).template value<T>(); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					void SettingsEntry<T>::set(const T &value) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						_accessor->save(_key, QVariant::fromValue(value)); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					void SettingsEntry<T>::reset() | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						_accessor->remove(_key); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					SettingsEntry<T> &SettingsEntry<T>::operator=(const T &value) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						set(value); | 
				
			||||
 | 
						return (*this); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					void SettingsEntry<T>::addChangeCallback(const std::function<void (T)> &callback) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						addChangeCallback(_accessor, callback); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					void SettingsEntry<T>::addChangeCallback(QObject *scope, const std::function<void (T)> &callback) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						auto mKey = _key; | 
				
			||||
 | 
						auto mDefault = _default; | 
				
			||||
 | 
						QObject::connect(_accessor, &ISettingsAccessor::entryChanged, | 
				
			||||
 | 
										 scope, [mKey, callback](const QString &key, const QVariant &value) { | 
				
			||||
 | 
							if(key == mKey) | 
				
			||||
 | 
								callback(value.template value<T>()); | 
				
			||||
 | 
						}); | 
				
			||||
 | 
						QObject::connect(_accessor, &ISettingsAccessor::entryRemoved, | 
				
			||||
 | 
										 scope, [mKey, mDefault, callback](const QString &key) { | 
				
			||||
 | 
							if(key == mKey) | 
				
			||||
 | 
								callback(mDefault.template value<T>()); | 
				
			||||
 | 
						}); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					SettingsEntry<T>::operator const T() const | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						return get(); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					template<typename T> | 
				
			||||
 | 
					void SettingsEntry<T>::setup(const QString &key, ISettingsAccessor *accessor, const QVariant &defaultValue) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						Q_ASSERT_X(accessor, Q_FUNC_INFO, "You must set a valid accessor before initializing the settings!"); | 
				
			||||
 | 
						_key  = key; | 
				
			||||
 | 
						_accessor = accessor; | 
				
			||||
 | 
						_default = defaultValue; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#endif // QTMVVM_SETTINGSENTRY_H
 | 
				
			||||
@ -0,0 +1,8 @@ | 
				
			|||||
 | 
					#include <QCoreApplication> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					int main(int argc, char *argv[]) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
						QCoreApplication a(argc, argv); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						return a.exec(); | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,69 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8"?> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> | 
				
			||||
 | 
						<!-- Type definitions --> | 
				
			||||
 | 
						<xs:complexType name="Include"> | 
				
			||||
 | 
							<xs:simpleContent> | 
				
			||||
 | 
								<xs:extension base="xs:string"> | 
				
			||||
 | 
									<xs:attribute default="false" name="local" type="xs:boolean" use="optional"/> | 
				
			||||
 | 
								</xs:extension> | 
				
			||||
 | 
							</xs:simpleContent> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
						 | 
				
			||||
 | 
						<xs:complexType name="Param"> | 
				
			||||
 | 
							<xs:simpleContent> | 
				
			||||
 | 
								<xs:extension base="xs:string"> | 
				
			||||
 | 
									<xs:attribute name="key" type="xs:string" use="required"/> | 
				
			||||
 | 
									<xs:attribute name="type" type="xs:string" use="required"/> | 
				
			||||
 | 
									<xs:attribute default="false" name="asStr" type="xs:boolean" use="optional"/> | 
				
			||||
 | 
								</xs:extension> | 
				
			||||
 | 
							</xs:simpleContent> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
						 | 
				
			||||
 | 
						<xs:complexType name="Backend"> | 
				
			||||
 | 
							<xs:sequence> | 
				
			||||
 | 
								<xs:element maxOccurs="unbounded" minOccurs="0" name="Param" type="Param"/> | 
				
			||||
 | 
							</xs:sequence> | 
				
			||||
 | 
							<xs:attribute name="class" type="xs:string" use="required"/> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
						 | 
				
			||||
 | 
						<xs:complexType name="Node"> | 
				
			||||
 | 
							<xs:sequence> | 
				
			||||
 | 
								<xs:choice maxOccurs="unbounded" minOccurs="0"> | 
				
			||||
 | 
									<xs:element name="Node" type="Node"/> | 
				
			||||
 | 
									<xs:element name="Entry" type="Entry"/> | 
				
			||||
 | 
								</xs:choice> | 
				
			||||
 | 
							</xs:sequence> | 
				
			||||
 | 
							<xs:attribute name="key" type="xs:string" use="required"/> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
						 | 
				
			||||
 | 
						<xs:complexType name="Entry"> | 
				
			||||
 | 
							<xs:complexContent> | 
				
			||||
 | 
								<xs:extension base="Node"> | 
				
			||||
 | 
									<xs:sequence> | 
				
			||||
 | 
										<xs:element maxOccurs="1" minOccurs="0" name="Code" type="xs:string"/> | 
				
			||||
 | 
									</xs:sequence> | 
				
			||||
 | 
									<xs:attribute name="type" type="xs:string" use="required"/> | 
				
			||||
 | 
									<xs:attribute name="qmlGroupKey" type="xs:string" use="optional"/> | 
				
			||||
 | 
									<xs:attribute name="default" type="xs:string" use="optional"/> | 
				
			||||
 | 
									<xs:attribute default="false" name="tr" type="xs:boolean" use="optional"/> | 
				
			||||
 | 
									<xs:attribute name="trcontext" type="xs:string" use="optional"/> | 
				
			||||
 | 
								</xs:extension> | 
				
			||||
 | 
							</xs:complexContent> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
						 | 
				
			||||
 | 
						<xs:complexType name="Settings"> | 
				
			||||
 | 
							<xs:sequence> | 
				
			||||
 | 
								<xs:element maxOccurs="unbounded" minOccurs="0" name="Include" type="Include"/> | 
				
			||||
 | 
								<xs:element maxOccurs="1" minOccurs="0" name="Backend" type="Backend"/> | 
				
			||||
 | 
								<xs:choice maxOccurs="unbounded" minOccurs="0"> | 
				
			||||
 | 
									<xs:element name="Node" type="Node"/> | 
				
			||||
 | 
									<xs:element name="Entry" type="Entry"/> | 
				
			||||
 | 
								</xs:choice> | 
				
			||||
 | 
							</xs:sequence> | 
				
			||||
 | 
							<xs:attribute name="name" type="xs:string" use="optional"/> | 
				
			||||
 | 
						</xs:complexType> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						<!-- root elements--> | 
				
			||||
 | 
						<xs:element name="Settings" type="Settings"/> | 
				
			||||
 | 
					</xs:schema> | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			|||||
 | 
					option(host_build) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					QT = core | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					TARGET = qsettingsgenerator | 
				
			||||
 | 
					VERSION = $$MODULE_VERSION | 
				
			||||
 | 
					COMPANY = Skycoder42 | 
				
			||||
 | 
					BUNDLE_PREFIX = de.skycoder42 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					DEFINES += BUILD_QSETTINGSGENERATOR | 
				
			||||
 | 
					DEFINES += "TARGET=\\\"$$TARGET\\\"" | 
				
			||||
 | 
					DEFINES += "VERSION=\\\"$$VERSION\\\"" | 
				
			||||
 | 
					DEFINES += "COMPANY=\\\"$$COMPANY\\\"" | 
				
			||||
 | 
					DEFINES += "BUNDLE_PREFIX=\\\"$$BUNDLE_PREFIX\\\"" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					HEADERS += | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					SOURCES += \ | 
				
			||||
 | 
						main.cpp | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					load(qt_tool) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					win32 { | 
				
			||||
 | 
						QMAKE_TARGET_PRODUCT = "Qt Settings Builder" | 
				
			||||
 | 
						QMAKE_TARGET_COMPANY = $$COMPANY | 
				
			||||
 | 
						QMAKE_TARGET_COPYRIGHT = "Felix Barz" | 
				
			||||
 | 
					} else:mac { | 
				
			||||
 | 
						QMAKE_TARGET_BUNDLE_PREFIX = $${BUNDLE_PREFIX}. | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					DISTFILES += qsettingsgenerator.xsd | 
				
			||||
@ -0,0 +1,9 @@ | 
				
			|||||
 | 
					TEMPLATE = subdirs | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					SUBDIRS += \ | 
				
			||||
 | 
						settingsgenerator | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					settingsgenerator.CONFIG += no_lrelease_target | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					prepareRecursiveTarget(lrelease) | 
				
			||||
 | 
					QMAKE_EXTRA_TARGETS += lrelease | 
				
			||||
					Loading…
					
					
				
		Reference in new issue