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