Browse Source

update to use xsd enums

pull/2/head
Skycoder42 7 years ago
parent
commit
72c060639d
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 120
      src/mvvmcore/settingsentry.h
  2. 5
      tests/auto/mvvmcore/settingsgenerator/generatortest.xml
  3. 35
      tools/settingsgenerator/cppsettingsgenerator.cpp
  4. 77
      tools/settingsgenerator/qmlsettingsgenerator.cpp
  5. 16
      tools/settingsgenerator/qmlsettingsgenerator.h
  6. 2
      tools/settingsgenerator/qpmx.json
  7. 22
      tools/settingsgenerator/qsettingsgenerator.xsd

120
src/mvvmcore/settingsentry.h

@ -39,11 +39,23 @@ private:
QVariant _default; QVariant _default;
}; };
template <typename TType> template <>
class SettingsEntry<QList<TType>> class SettingsEntry<void>
{ {
Q_DISABLE_COPY(SettingsEntry) Q_DISABLE_COPY(SettingsEntry)
public:
inline SettingsEntry() = default;
// internal
inline void setup(const QString &, ISettingsAccessor *, const QVariant & = {}) {}
};
template <typename TType>
class SettingsListEntry
{
Q_DISABLE_COPY(SettingsListEntry)
public: public:
class ListElement class ListElement
{ {
@ -60,10 +72,10 @@ public:
inline operator TType() const && { return _self->getAt(_index); } inline operator TType() const && { return _self->getAt(_index); }
private: private:
friend class SettingsEntry<QList<TType>>; friend class SettingsListEntry<TType>;
inline ListElement(SettingsEntry<QList<TType>> *self, int index) : _self{self}, _index{index} {} inline ListElement(SettingsListEntry<TType> *self, int index) : _self{self}, _index{index} {}
SettingsEntry<QList<TType>> *_self; SettingsListEntry<TType> *_self;
int _index; int _index;
}; };
@ -95,15 +107,15 @@ public:
private: private:
template <typename T> template <typename T>
friend class SettingsEntry<QList<TType>>::iterator_base; friend class SettingsListEntry<TType>::iterator_base;
inline iterator_value(SettingsEntry<QList<TType>> *self, int index) : _self{self}, _index{index} {} inline iterator_value(SettingsListEntry<TType> *self, int index) : _self{self}, _index{index} {}
inline iterator_value(const iterator_value &other) = default; inline iterator_value(const iterator_value &other) = default;
inline iterator_value &operator=(const iterator_value &other) = default; inline iterator_value &operator=(const iterator_value &other) = default;
inline iterator_value(iterator_value &&other) noexcept = default; inline iterator_value(iterator_value &&other) noexcept = default;
inline iterator_value &operator=(iterator_value &&other) noexcept = default; inline iterator_value &operator=(iterator_value &&other) noexcept = default;
SettingsEntry<QList<TType>> *_self; SettingsListEntry<TType> *_self;
int _index; int _index;
}; };
@ -150,9 +162,9 @@ public:
inline value_type operator[](difference_type delta) const { return iterator_value{_value._self, _value._index + delta}; } inline value_type operator[](difference_type delta) const { return iterator_value{_value._self, _value._index + delta}; }
private: private:
friend class SettingsEntry<QList<TType>>; friend class SettingsListEntry<TType>;
inline iterator_base(SettingsEntry<QList<TType>> *self, int index) : _value{self, index} {} inline iterator_base(SettingsListEntry<TType> *self, int index) : _value{self, index} {}
inline iterator_base(iterator_value value) : _value{std::move(value)} {} inline iterator_base(iterator_value value) : _value{std::move(value)} {}
iterator_value _value; iterator_value _value;
}; };
@ -160,7 +172,7 @@ public:
using iterator = iterator_base<iterator_value>; using iterator = iterator_base<iterator_value>;
using const_iterator = iterator_base<const iterator_value>; using const_iterator = iterator_base<const iterator_value>;
SettingsEntry() = default; SettingsListEntry() = default;
bool isSet() const; bool isSet() const;
QString key() const; QString key() const;
@ -169,7 +181,7 @@ public:
void set(const QList<TType> &value); void set(const QList<TType> &value);
void reset(bool reInit = true); void reset(bool reInit = true);
SettingsEntry<QList<TType>> &operator=(const QList<TType> &value); SettingsListEntry<TType> &operator=(const QList<TType> &value);
operator QList<TType>() const; operator QList<TType>() const;
int size() const; int size() const;
@ -182,8 +194,8 @@ public:
ListElement operator[](int index); ListElement operator[](int index);
const ListElement operator[](int index) const; const ListElement operator[](int index) const;
SettingsEntry<QList<TType>> &operator+=(const TType &value); SettingsListEntry<TType> &operator+=(const TType &value);
SettingsEntry<QList<TType>> &operator+=(const QList<TType> &values); SettingsListEntry<TType> &operator+=(const QList<TType> &values);
iterator begin(); iterator begin();
iterator end(); iterator end();
@ -210,18 +222,6 @@ private:
QList<TType> _init; QList<TType> _init;
}; };
template <>
class SettingsEntry<void>
{
Q_DISABLE_COPY(SettingsEntry)
public:
inline SettingsEntry() = default;
// internal
inline void setup(const QString &, ISettingsAccessor *, const QVariant & = {}) {}
};
// ------------- Generic Implementation ------------- // ------------- Generic Implementation -------------
template<typename T> template<typename T>
@ -312,19 +312,19 @@ void SettingsEntry<T>::setup(QString key, ISettingsAccessor *accessor, QVariant
// ------------- Generic Implementation ListEntry ------------- // ------------- Generic Implementation ListEntry -------------
template<typename TType> template<typename TType>
bool SettingsEntry<QList<TType>>::isSet() const bool SettingsListEntry<TType>::isSet() const
{ {
return _accessor->contains(_key + QStringLiteral("/size")); return _accessor->contains(_key + QStringLiteral("/size"));
} }
template<typename TType> template<typename TType>
QString SettingsEntry<QList<TType>>::key() const QString SettingsListEntry<TType>::key() const
{ {
return _key; return _key;
} }
template<typename TType> template<typename TType>
QList<TType> SettingsEntry<QList<TType>>::get() const QList<TType> SettingsListEntry<TType>::get() const
{ {
auto mSize = size(); auto mSize = size();
QList<TType> resList; QList<TType> resList;
@ -335,14 +335,14 @@ QList<TType> SettingsEntry<QList<TType>>::get() const
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::set(const QList<TType> &value) void SettingsListEntry<TType>::set(const QList<TType> &value)
{ {
reset(false); reset(false);
push(value); push(value);
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::reset(bool reInit) void SettingsListEntry<TType>::reset(bool reInit)
{ {
_accessor->remove(_key); _accessor->remove(_key);
if(reInit && !_init.isEmpty()) if(reInit && !_init.isEmpty())
@ -350,44 +350,44 @@ void SettingsEntry<QList<TType>>::reset(bool reInit)
} }
template<typename TType> template<typename TType>
SettingsEntry<QList<TType>> &SettingsEntry<QList<TType>>::operator=(const QList<TType> &value) SettingsListEntry<TType> &SettingsListEntry<TType>::operator=(const QList<TType> &value)
{ {
set(value); set(value);
return *this; return *this;
} }
template<typename TType> template<typename TType>
SettingsEntry<QList<TType>>::operator QList<TType>() const SettingsListEntry<TType>::operator QList<TType>() const
{ {
return get(); return get();
} }
template<typename TType> template<typename TType>
int SettingsEntry<QList<TType>>::size() const int SettingsListEntry<TType>::size() const
{ {
return _accessor->load(_key + QStringLiteral("/size"), 0).toInt(); return _accessor->load(_key + QStringLiteral("/size"), 0).toInt();
} }
template<typename TType> template<typename TType>
TType SettingsEntry<QList<TType>>::getAt(int index) const TType SettingsListEntry<TType>::getAt(int index) const
{ {
return _accessor->load(_key + QStringLiteral("/%1/value").arg(index), _default).template value<TType>(); return _accessor->load(_key + QStringLiteral("/%1/value").arg(index), _default).template value<TType>();
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::setAt(int index, const TType &value) void SettingsListEntry<TType>::setAt(int index, const TType &value)
{ {
_accessor->save(_key + QStringLiteral("/%1/value").arg(index), QVariant::fromValue(value)); _accessor->save(_key + QStringLiteral("/%1/value").arg(index), QVariant::fromValue(value));
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::push(const TType &value) void SettingsListEntry<TType>::push(const TType &value)
{ {
push(QList<TType>{value}); push(QList<TType>{value});
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::push(const QList<TType> &values) void SettingsListEntry<TType>::push(const QList<TType> &values)
{ {
auto cIndex = size(); auto cIndex = size();
for(const auto &value : values) for(const auto &value : values)
@ -396,7 +396,7 @@ void SettingsEntry<QList<TType>>::push(const QList<TType> &values)
} }
template<typename TType> template<typename TType>
TType QtMvvm::SettingsEntry<QList<TType>>::pop() TType QtMvvm::SettingsListEntry<TType>::pop()
{ {
auto res = getAt(size() - 1); auto res = getAt(size() - 1);
chop(1); chop(1);
@ -404,7 +404,7 @@ TType QtMvvm::SettingsEntry<QList<TType>>::pop()
} }
template<typename TType> template<typename TType>
void QtMvvm::SettingsEntry<QList<TType>>::chop(int count) void QtMvvm::SettingsListEntry<TType>::chop(int count)
{ {
auto cSize = size(); auto cSize = size();
auto nSize = qMax(size() - count, 0); auto nSize = qMax(size() - count, 0);
@ -414,76 +414,76 @@ void QtMvvm::SettingsEntry<QList<TType>>::chop(int count)
} }
template<typename TType> template<typename TType>
const typename SettingsEntry<QList<TType>>::ListElement SettingsEntry<QList<TType>>::operator[](int index) const const typename SettingsListEntry<TType>::ListElement SettingsListEntry<TType>::operator[](int index) const
{ {
return ListElement{this, index}; return ListElement{this, index};
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::ListElement SettingsEntry<QList<TType>>::operator[](int index) typename SettingsListEntry<TType>::ListElement SettingsListEntry<TType>::operator[](int index)
{ {
return ListElement{this, index}; return ListElement{this, index};
} }
template<typename TType> template<typename TType>
SettingsEntry<QList<TType>> &SettingsEntry<QList<TType>>::operator+=(const TType &value) SettingsListEntry<TType> &SettingsListEntry<TType>::operator+=(const TType &value)
{ {
push(value); push(value);
return *this; return *this;
} }
template<typename TType> template<typename TType>
SettingsEntry<QList<TType>> &SettingsEntry<QList<TType>>::operator+=(const QList<TType> &values) SettingsListEntry<TType> &SettingsListEntry<TType>::operator+=(const QList<TType> &values)
{ {
push(values); push(values);
return *this; return *this;
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::iterator SettingsEntry<QList<TType>>::begin() typename SettingsListEntry<TType>::iterator SettingsListEntry<TType>::begin()
{ {
return iterator{this, 0}; return iterator{this, 0};
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::iterator QtMvvm::SettingsEntry<QList<TType>>::end() typename SettingsListEntry<TType>::iterator QtMvvm::SettingsListEntry<TType>::end()
{ {
return iterator{this, size()}; return iterator{this, size()};
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::const_iterator SettingsEntry<QList<TType>>::begin() const typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::begin() const
{ {
return constBegin(); return constBegin();
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::const_iterator SettingsEntry<QList<TType>>::end() const typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::end() const
{ {
return constEnd(); return constEnd();
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::const_iterator SettingsEntry<QList<TType>>::constBegin() const typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::constBegin() const
{ {
return const_iterator{const_cast<SettingsEntry<QList<TType>>*>(this), 0}; return const_iterator{const_cast<SettingsListEntry<TType>*>(this), 0};
} }
template<typename TType> template<typename TType>
typename SettingsEntry<QList<TType>>::const_iterator SettingsEntry<QList<TType>>::constEnd() const typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::constEnd() const
{ {
return const_iterator{const_cast<SettingsEntry<QList<TType>>*>(this), size()}; return const_iterator{const_cast<SettingsListEntry<TType>*>(this), size()};
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addChangeCallback(const std::function<void (QList<TType>)> &callback) void SettingsListEntry<TType>::addChangeCallback(const std::function<void (QList<TType>)> &callback)
{ {
addChangeCallback(_accessor, callback); addChangeCallback(_accessor, callback);
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addChangeCallback(QObject *scope, const std::function<void (QList<TType>)> &callback) void SettingsListEntry<TType>::addChangeCallback(QObject *scope, const std::function<void (QList<TType>)> &callback)
{ {
QObject::connect(_accessor, &ISettingsAccessor::entryChanged, QObject::connect(_accessor, &ISettingsAccessor::entryChanged,
scope, [this, callback](const QString &key, const QVariant &) { scope, [this, callback](const QString &key, const QVariant &) {
@ -498,13 +498,13 @@ void SettingsEntry<QList<TType>>::addChangeCallback(QObject *scope, const std::f
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addChangeCallback(const std::function<void (int, TType)> &callback) void SettingsListEntry<TType>::addChangeCallback(const std::function<void (int, TType)> &callback)
{ {
addChangeCallback(_accessor, callback); addChangeCallback(_accessor, callback);
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addChangeCallback(QObject *scope, const std::function<void (int, TType)> &callback) void SettingsListEntry<TType>::addChangeCallback(QObject *scope, const std::function<void (int, TType)> &callback)
{ {
QRegularExpression mKey {QStringLiteral("^%1\\/\\d+\\/value$").arg(QRegularExpression::escape(_key))}; QRegularExpression mKey {QStringLiteral("^%1\\/\\d+\\/value$").arg(QRegularExpression::escape(_key))};
mKey.optimize(); mKey.optimize();
@ -524,13 +524,13 @@ void SettingsEntry<QList<TType>>::addChangeCallback(QObject *scope, const std::f
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addSizeChangeCallback(const std::function<void (int)> &callback) void SettingsListEntry<TType>::addSizeChangeCallback(const std::function<void (int)> &callback)
{ {
addSizeChangeCallback(_accessor, callback); addSizeChangeCallback(_accessor, callback);
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::addSizeChangeCallback(QObject *scope, const std::function<void (int)> &callback) void SettingsListEntry<TType>::addSizeChangeCallback(QObject *scope, const std::function<void (int)> &callback)
{ {
QString mKey = _key + QStringLiteral("/size"); QString mKey = _key + QStringLiteral("/size");
auto mInit = _init; auto mInit = _init;
@ -547,7 +547,7 @@ void SettingsEntry<QList<TType>>::addSizeChangeCallback(QObject *scope, const st
} }
template<typename TType> template<typename TType>
void SettingsEntry<QList<TType>>::setup(QString key, ISettingsAccessor *accessor, QVariant defaultValue) void SettingsListEntry<TType>::setup(QString key, ISettingsAccessor *accessor, QVariant defaultValue)
{ {
Q_ASSERT_X(accessor, Q_FUNC_INFO, "You must set a valid accessor before initializing the settings!"); Q_ASSERT_X(accessor, Q_FUNC_INFO, "You must set a valid accessor before initializing the settings!");
_key = std::move(key); _key = std::move(key);
@ -556,7 +556,7 @@ void SettingsEntry<QList<TType>>::setup(QString key, ISettingsAccessor *accessor
} }
template<typename TType> template<typename TType>
void QtMvvm::SettingsEntry<QList<TType> >::setupInit(QList<TType> init) void QtMvvm::SettingsListEntry<TType>::setupInit(QList<TType> init)
{ {
_init = std::move(init); _init = std::move(init);
if(!isSet()) if(!isSet())

5
tests/auto/mvvmcore/settingsgenerator/generatortest.xml

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Settings name="TestSettings" <Settings name="TestSettings"
prefix="SOME_EXPORT" prefix="SOME_EXPORT"
baseKey="tests"> baseKey="tests"
scope="DestroyOnAppQuit">
<Include>QtCore/QDateTime</Include> <Include>QtCore/QDateTime</Include>
<Include local="false">QtCore/QUrl</Include> <Include local="false">QtCore/QUrl</Include>
<Include local="true">testbackend.h</Include> <Include local="true">testbackend.h</Include>
<Backend class="TestBackend" scope="DestroyOnAppQuit"> <Backend class="TestBackend">
<Param type="QString" asStr="true">Test Backend</Param> <Param type="QString" asStr="true">Test Backend</Param>
<Param type="int">42</Param> <Param type="int">42</Param>
</Backend> </Backend>

35
tools/settingsgenerator/cppsettingsgenerator.cpp

@ -110,14 +110,14 @@ void CppSettingsGenerator::writeEntryDeclaration(const EntryType &entry, const Q
void CppSettingsGenerator::writeListEntryDeclaration(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) void CppSettingsGenerator::writeListEntryDeclaration(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent)
{ {
if(entry.contentNodes.isEmpty()) if(entry.contentNodes.isEmpty())
_hdr << TABS << "QtMvvm::SettingsEntry<QList<" << typeMappings.value(entry.type, entry.type) << ">> " << entry.key << ";\n"; _hdr << TABS << "QtMvvm::SettingsListEntry<" << typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n";
else { else {
const QString mType = QStringLiteral("QList<") + typeMappings.value(entry.type, entry.type) + QLatin1Char('>'); const QString mType = typeMappings.value(entry.type, entry.type);
_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; _hdr << TABS << "struct : QtMvvm::SettingsListEntry<" << mType << "> { //" << entry.key << "\n";
writeNodeElementDeclarations(entry, typeMappings, intendent + 1); writeNodeElementDeclarations(entry, typeMappings, intendent + 1);
_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; _hdr << TABS << "\tinline auto &operator=(const QList<" << mType << "> &__value) { SettingsListEntry<" << mType << ">::operator=(__value); return *this; }\n";
_hdr << TABS << "\tinline auto &operator+=(const " << typeMappings.value(entry.type, entry.type) << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; _hdr << TABS << "\tinline auto &operator+=(const QList<" << mType << "> &__value) { SettingsListEntry<" << mType << ">::operator+=(__value); return *this; }\n";
_hdr << TABS << "\tinline auto &operator+=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; _hdr << TABS << "\tinline auto &operator+=(const " << mType << " &__value) { SettingsListEntry<" << mType << ">::operator+=(__value); return *this; }\n";
_hdr << TABS << "} " << entry.key << ";\n"; _hdr << TABS << "} " << entry.key << ";\n";
} }
} }
@ -131,14 +131,31 @@ void CppSettingsGenerator::writeSource(const SettingsType &settings)
_src << "#include <QtMvvmCore/QSettingsAccessor>\n"; _src << "#include <QtMvvmCore/QSettingsAccessor>\n";
_src << "\n"; _src << "\n";
auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}, {}}); auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}});
_src << "namespace {\n\n" _src << "namespace {\n\n"
<< "void __generated_settings_setup()\n" << "void __generated_settings_setup()\n"
<< "{\n" << "{\n"
<< "\tQtMvvm::ServiceRegistry::instance()->registerObject<" << settings.name.value() << ">("; << "\tQtMvvm::ServiceRegistry::instance()->registerObject<" << settings.name.value() << ">(";
if(backend.scope) if(settings.scope) {
_src << "QtMvvm::ServiceRegistry::" << backend.scope.value(); switch(settings.scope.value()) {
case SettingsGeneratorBase::DestroyOnAppQuit:
_src << "QtMvvm::ServiceRegistry::DestroyOnAppQuit";
break;
case SettingsGeneratorBase::DestroyOnAppDestroy:
_src << "QtMvvm::ServiceRegistry::DestroyOnAppDestroy";
break;
case SettingsGeneratorBase::DestroyOnRegistryDestroy:
_src << "QtMvvm::ServiceRegistry::DestroyOnRegistryDestroy";
break;
case SettingsGeneratorBase::DestroyNever:
_src << "QtMvvm::ServiceRegistry::DestroyNever";
break;
default:
Q_UNREACHABLE();
break;
}
}
_src << ");\n" _src << ");\n"
<< "}\n\n" << "}\n\n"
<< "}\n" << "}\n"

77
tools/settingsgenerator/qmlsettingsgenerator.cpp

@ -64,7 +64,7 @@ void QmlSettingsGenerator::writeHeader(const SettingsType &settings, const QStri
auto keyList = settings.baseKey ? QStringList{settings.baseKey.value()} : QStringList{}; auto keyList = settings.baseKey ? QStringList{settings.baseKey.value()} : QStringList{};
int offset; int offset;
QList<int> childOffsets; QList<int> childOffsets;
std::tie(offset, childOffsets) = writeNodeContentClassesDeclarations(settings, keyList); std::tie(offset, childOffsets) = writeNodeContentClasses(settings, keyList);
// create the class // create the class
_hdr << "class " << _name << " : public QObject\n" _hdr << "class " << _name << " : public QObject\n"
@ -74,7 +74,7 @@ void QmlSettingsGenerator::writeHeader(const SettingsType &settings, const QStri
QList<QPair<QString, int>> childConstructs; QList<QPair<QString, int>> childConstructs;
QList<int> listEntries; QList<int> listEntries;
writeNodeClassPropertiesDeclarations(settings, keyList, childOffsets, listEntries, childConstructs); writeProperties(settings, keyList, childOffsets, listEntries, childConstructs);
_hdr << "\t" << _cppName << " *_settings;\n\n" _hdr << "\t" << _cppName << " *_settings;\n\n"
<< "public:\n" << "public:\n"
@ -89,8 +89,11 @@ void QmlSettingsGenerator::writeHeader(const SettingsType &settings, const QStri
<< "\t\t" << _name << "{" << _cppName << "::instance(), parent}\n" << "\t\t" << _name << "{" << _cppName << "::instance(), parent}\n"
<< "\t{}\n\n" << "\t{}\n\n"
<< "\tQtMvvm::ISettingsAccessor *accessor() const { return _settings->accessor(); }\n" << "\tQtMvvm::ISettingsAccessor *accessor() const { return _settings->accessor(); }\n"
<< "\t" << _cppName << " *settings() const { return _settings; }\n" << "\t" << _cppName << " *settings() const { return _settings; }\n\n"
<< "};\n\n" << "\t" << (settings.prefix ? settings.prefix.value() + QLatin1Char(' ') : QString{}) << "static void registerQmlTypes(const char *uri, int major, int minor);\n";
if(settings.qml)
_hdr << "\t" << (settings.prefix ? settings.prefix.value() + QLatin1Char(' ') : QString{}) << "static void registerQmlTypes();\n";
_hdr << "};\n\n"
<< "#endif //" << incGuard << '\n'; << "#endif //" << incGuard << '\n';
} }
@ -104,7 +107,7 @@ void QmlSettingsGenerator::writeListTypeBaseClass()
<< "\ttemplate <typename TList>\n" << "\ttemplate <typename TList>\n"
<< "\tstruct ListData {\n" << "\tstruct ListData {\n"
<< "\t\tstatic_assert(std::is_base_of<" << _name << "_ListType<T>, TList>::value, \"TList must extend " << _name << "_ListType<T>\");\n" << "\t\tstatic_assert(std::is_base_of<" << _name << "_ListType<T>, TList>::value, \"TList must extend " << _name << "_ListType<T>\");\n"
<< "\t\tQtMvvm::SettingsEntry<QList<T>> &entry;\n" << "\t\tQtMvvm::SettingsListEntry<T> &entry;\n"
<< "\t\tQList<TList*> elements;\n" << "\t\tQList<TList*> elements;\n"
<< "\t};\n\n" << "\t};\n\n"
<< "\t" << _name << "_ListType(QObject *parent) : \n" << "\t" << _name << "_ListType(QObject *parent) : \n"
@ -168,36 +171,36 @@ void QmlSettingsGenerator::writeListTypeBaseClass()
<< "\t}\n\n" << "\t}\n\n"
<< "private:\n" << "private:\n"
<< "\tQtMvvm::SettingsEntry<QList<T>> *_entry = nullptr;\n" << "\tQtMvvm::SettingsListEntry<T> *_entry = nullptr;\n"
<< "\tint _index = -1;\n" << "\tint _index = -1;\n"
<< "\tT _buffer{};\n" << "\tT _buffer{};\n"
<< "};\n\n"; << "};\n\n";
} }
std::tuple<int, QList<int>> QmlSettingsGenerator::writeNodeContentClassesDeclarations(const NodeContentGroup &node, const QStringList &keyList, int offset) std::tuple<int, QList<int>> QmlSettingsGenerator::writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset)
{ {
QList<int> offsetList; QList<int> offsetList;
for(const auto &cNode : node.contentNodes) { for(const auto &cNode : node.contentNodes) {
if(nonstd::holds_alternative<NodeType>(cNode)) { if(nonstd::holds_alternative<NodeType>(cNode)) {
offset = writeNodeClassDeclaration(nonstd::get<NodeType>(cNode), keyList, offset); offset = writeNodeClass(nonstd::get<NodeType>(cNode), keyList, offset);
offsetList.append(offset - 1); offsetList.append(offset - 1);
} else if(nonstd::holds_alternative<EntryType>(cNode)) { } else if(nonstd::holds_alternative<EntryType>(cNode)) {
if(!nonstd::get<EntryType>(cNode).contentNodes.isEmpty()) { if(!nonstd::get<EntryType>(cNode).contentNodes.isEmpty()) {
offset = writeNodeClassDeclaration(nonstd::get<EntryType>(cNode), keyList, offset); offset = writeNodeClass(nonstd::get<EntryType>(cNode), keyList, offset);
offsetList.append(offset - 1); offsetList.append(offset - 1);
} else } else
offsetList.append(-1); offsetList.append(-1);
} else if(nonstd::holds_alternative<ListEntryType>(cNode)) { } else if(nonstd::holds_alternative<ListEntryType>(cNode)) {
offset = writeListEntryListClass(nonstd::get<ListEntryType>(cNode), offset); offset = writeListEntryElementClass(nonstd::get<ListEntryType>(cNode), keyList, offset);
offsetList.append(offset - 1); //double offset!!! offsetList.append(offset - 1); //double offset!!!
if(!nonstd::get<ListEntryType>(cNode).contentNodes.isEmpty()) { if(!nonstd::get<ListEntryType>(cNode).contentNodes.isEmpty()) {
offset = writeNodeClassDeclaration(nonstd::get<ListEntryType>(cNode), keyList, offset); offset = writeNodeClass(nonstd::get<ListEntryType>(cNode), keyList, offset);
offsetList.append(offset - 1); offsetList.append(offset - 1);
} else } else
offsetList.append(-1); offsetList.append(-1);
} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) { } else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) {
QList<int> subList; QList<int> subList;
std::tie(offset, subList) = writeNodeContentClassesDeclarations(nonstd::get<NodeContentGroup>(cNode), keyList, offset); std::tie(offset, subList) = writeNodeContentClasses(nonstd::get<NodeContentGroup>(cNode), keyList, offset);
offsetList.append(subList); offsetList.append(subList);
} else } else
Q_UNREACHABLE(); Q_UNREACHABLE();
@ -205,19 +208,19 @@ std::tuple<int, QList<int>> QmlSettingsGenerator::writeNodeContentClassesDeclara
return std::make_tuple(offset, offsetList); return std::make_tuple(offset, offsetList);
} }
int QmlSettingsGenerator::writeNodeClassDeclaration(const NodeType &node, QStringList keyList, int offset) int QmlSettingsGenerator::writeNodeClass(const NodeType &node, QStringList keyList, int offset)
{ {
keyList.append(node.key); keyList.append(node.key);
QList<int> childOffsets; QList<int> childOffsets;
std::tie(offset, childOffsets) = writeNodeContentClassesDeclarations(node, keyList, offset); std::tie(offset, childOffsets) = writeNodeContentClasses(node, keyList, offset);
_hdr << "class " << _name << "_" << offset << " : public QObject // " << node.key << "\n" _hdr << "class " << _name << "_" << offset << " : public QObject // " << keyList.join(QLatin1Char('/')) << "\n"
<< "{\n" << "{\n"
<< "\tQ_OBJECT\n\n"; << "\tQ_OBJECT\n\n";
QList<QPair<QString, int>> childConstructs; QList<QPair<QString, int>> childConstructs;
QList<int> listEntries; QList<int> listEntries;
writeNodeClassPropertiesDeclarations(node, keyList, childOffsets, listEntries, childConstructs); writeProperties(node, keyList, childOffsets, listEntries, childConstructs);
_hdr << "\t" << _cppName << " *_settings;\n\n" _hdr << "\t" << _cppName << " *_settings;\n\n"
<< "public:\n" << "public:\n"
@ -233,10 +236,11 @@ int QmlSettingsGenerator::writeNodeClassDeclaration(const NodeType &node, QStrin
return ++offset; return ++offset;
} }
int QmlSettingsGenerator::writeListEntryListClass(const ListEntryType &entry, int offset) int QmlSettingsGenerator::writeListEntryElementClass(const ListEntryType &entry, QStringList keyList, int offset)
{ {
keyList.append(entry.key);
const auto &mType = _typeMappings.value(entry.type, entry.type); const auto &mType = _typeMappings.value(entry.type, entry.type);
_hdr << "class " << _name << "_" << offset << " : public " << _name << "_ListType<" << mType << "> // " << entry.key << "\n" _hdr << "class " << _name << "_" << offset << " : public " << _name << "_ListType<" << mType << "> // " << keyList.join(QLatin1Char('/')) << " (list-element)\n"
<< "{\n" << "{\n"
<< "\tQ_OBJECT\n\n" << "\tQ_OBJECT\n\n"
<< "\tQ_PROPERTY(" << mType << " value READ value WRITE setValue NOTIFY valueChanged)\n\n" << "\tQ_PROPERTY(" << mType << " value READ value WRITE setValue NOTIFY valueChanged)\n\n"
@ -251,25 +255,25 @@ int QmlSettingsGenerator::writeListEntryListClass(const ListEntryType &entry, in
return ++offset; return ++offset;
} }
void QmlSettingsGenerator::writeNodeClassPropertiesDeclarations(const NodeContentGroup &node, const QStringList &keyList, QList<int> &childOffsets, QList<int> &listEntries, QList<QPair<QString, int>> &childConstructs) void QmlSettingsGenerator::writeProperties(const NodeContentGroup &node, const QStringList &keyList, QList<int> &childOffsets, QList<int> &listEntries, QList<QPair<QString, int>> &childConstructs)
{ {
for(const auto &cNode : node.contentNodes) { for(const auto &cNode : node.contentNodes) {
if(nonstd::holds_alternative<NodeType>(cNode)) if(nonstd::holds_alternative<NodeType>(cNode))
writeNodePropertyDeclaration(nonstd::get<NodeType>(cNode), childOffsets.takeFirst(), childConstructs); writeNodeProperty(nonstd::get<NodeType>(cNode), childOffsets.takeFirst(), childConstructs);
else if(nonstd::holds_alternative<EntryType>(cNode)) else if(nonstd::holds_alternative<EntryType>(cNode))
writeEntryPropertyDeclaration(nonstd::get<EntryType>(cNode), keyList, childOffsets.takeFirst(), childConstructs); writeEntryProperty(nonstd::get<EntryType>(cNode), keyList, childOffsets.takeFirst(), childConstructs);
else if(nonstd::holds_alternative<ListEntryType>(cNode)) { else if(nonstd::holds_alternative<ListEntryType>(cNode)) {
auto lIndex = childOffsets.takeFirst(); //done seperately because of undefine param call order auto lIndex = childOffsets.takeFirst(); //done seperately because of undefine param call order
writeListEntryPropertyDeclaration(nonstd::get<ListEntryType>(cNode), keyList, lIndex, childOffsets.takeFirst(), childConstructs); writeListEntryProperty(nonstd::get<ListEntryType>(cNode), keyList, lIndex, childOffsets.takeFirst(), childConstructs);
listEntries.append(lIndex); listEntries.append(lIndex);
} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) } else if(nonstd::holds_alternative<NodeContentGroup>(cNode))
writeNodeClassPropertiesDeclarations(nonstd::get<NodeContentGroup>(cNode), keyList, childOffsets, listEntries, childConstructs); writeProperties(nonstd::get<NodeContentGroup>(cNode), keyList, childOffsets, listEntries, childConstructs);
else else
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
void QmlSettingsGenerator::writeNodePropertyDeclaration(const NodeType &entry, int classIndex, QList<QPair<QString, int>> &childConstructs, const QString &overwriteName) void QmlSettingsGenerator::writeNodeProperty(const NodeType &entry, int classIndex, QList<QPair<QString, int>> &childConstructs, const QString &overwriteName)
{ {
const auto &mName = overwriteName.isNull() ? entry.key : overwriteName; const auto &mName = overwriteName.isNull() ? entry.key : overwriteName;
_hdr << "\tQ_PROPERTY(" << _name << "_" << classIndex << "* " << mName _hdr << "\tQ_PROPERTY(" << _name << "_" << classIndex << "* " << mName
@ -278,7 +282,7 @@ void QmlSettingsGenerator::writeNodePropertyDeclaration(const NodeType &entry, i
childConstructs.append({mName, classIndex}); childConstructs.append({mName, classIndex});
} }
void QmlSettingsGenerator::writeEntryPropertyDeclaration(const EntryType &entry, QStringList keyList, int classIndex, QList<QPair<QString, int>> &childConstructs) void QmlSettingsGenerator::writeEntryProperty(const EntryType &entry, QStringList keyList, int classIndex, QList<QPair<QString, int>> &childConstructs)
{ {
keyList.append(entry.key); keyList.append(entry.key);
const auto &mType = _typeMappings.value(entry.type, entry.type); const auto &mType = _typeMappings.value(entry.type, entry.type);
@ -296,10 +300,10 @@ void QmlSettingsGenerator::writeEntryPropertyDeclaration(const EntryType &entry,
} }
if(!entry.contentNodes.isEmpty()) if(!entry.contentNodes.isEmpty())
writeNodePropertyDeclaration(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group"))); writeNodeProperty(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group")));
} }
void QmlSettingsGenerator::writeListEntryPropertyDeclaration(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList<QPair<QString, int>> &childConstructs) void QmlSettingsGenerator::writeListEntryProperty(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList<QPair<QString, int>> &childConstructs)
{ {
keyList.append(entry.key); keyList.append(entry.key);
_hdr << "\tQ_PROPERTY(QQmlListProperty<" << _name << "_" << listIndex << "> " << entry.key _hdr << "\tQ_PROPERTY(QQmlListProperty<" << _name << "_" << listIndex << "> " << entry.key
@ -318,7 +322,7 @@ void QmlSettingsGenerator::writeListEntryPropertyDeclaration(const ListEntryType
childConstructs.append({entry.key, -1}); childConstructs.append({entry.key, -1});
if(!entry.contentNodes.isEmpty()) if(!entry.contentNodes.isEmpty())
writeNodePropertyDeclaration(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group"))); writeNodeProperty(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group")));
} }
void QmlSettingsGenerator::writeMemberInits(const QStringList &keyList, const QList<QPair<QString, int>> &childConstructs) void QmlSettingsGenerator::writeMemberInits(const QStringList &keyList, const QList<QPair<QString, int>> &childConstructs)
@ -372,4 +376,21 @@ void QmlSettingsGenerator::writeListEntryPropertySignalConnect(const SettingsGen
void QmlSettingsGenerator::writeSource(const SettingsType &settings) void QmlSettingsGenerator::writeSource(const SettingsType &settings)
{ {
_src << "#include \"" << _hdrFile.fileName() << "\"\n\n"; _src << "#include \"" << _hdrFile.fileName() << "\"\n\n";
writeQmlRegistration(settings);
if(settings.qml) {
const auto &qml = settings.qml.value();
_src << "\nvoid " << _name << "::registerQmlTypes()\n"
<< "{\n"
<< "\tregisterQmlTypes(\"" << qml.uri << "\", " << qml.major << ", " << qml.minor << ");\n"
<< "}\n";
}
}
void QmlSettingsGenerator::writeQmlRegistration(const SettingsType &settings)
{
_src << "\nvoid " << _name << "::registerQmlTypes(const char *uri, int major, int minor)\n"
<< "{\n"
<< "}\n";
} }

16
tools/settingsgenerator/qmlsettingsgenerator.h

@ -28,18 +28,18 @@ private:
void writeListTypeBaseClass(); void writeListTypeBaseClass();
std::tuple<int, QList<int>> writeNodeContentClassesDeclarations(const NodeContentGroup &node, const QStringList &keyList, int offset = 0); std::tuple<int, QList<int>> writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset = 0);
int writeNodeClassDeclaration(const NodeType &node, QStringList keyList, int offset); int writeNodeClass(const NodeType &node, QStringList keyList, int offset);
int writeListEntryListClass(const ListEntryType &entry, int offset); int writeListEntryElementClass(const ListEntryType &entry, QStringList keyList, int offset);
void writeNodeClassPropertiesDeclarations(const NodeContentGroup &node, void writeProperties(const NodeContentGroup &node,
const QStringList &keyList, const QStringList &keyList,
QList<int> &childOffsets, QList<int> &childOffsets,
QList<int> &listEntries, QList<int> &listEntries,
QList<QPair<QString, int>> &childConstructs); QList<QPair<QString, int>> &childConstructs);
void writeNodePropertyDeclaration(const NodeType &entry, int classIndex, QList<QPair<QString, int>> &childConstructs, const QString &overwriteName = {}); void writeNodeProperty(const NodeType &entry, int classIndex, QList<QPair<QString, int>> &childConstructs, const QString &overwriteName = {});
void writeEntryPropertyDeclaration(const EntryType &entry, QStringList keyList, int classIndex, QList<QPair<QString, int>> &childConstructs); void writeEntryProperty(const EntryType &entry, QStringList keyList, int classIndex, QList<QPair<QString, int>> &childConstructs);
void writeListEntryPropertyDeclaration(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList<QPair<QString, int>> &childConstructs); void writeListEntryProperty(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList<QPair<QString, int>> &childConstructs);
void writeMemberInits(const QStringList &keyList, const QList<QPair<QString, int>> &childConstructs); void writeMemberInits(const QStringList &keyList, const QList<QPair<QString, int>> &childConstructs);
void writeEntryPropertySignalConnects(const NodeContentGroup &node, const QStringList &keyList, int classIndex, QList<int> &listEntries); void writeEntryPropertySignalConnects(const NodeContentGroup &node, const QStringList &keyList, int classIndex, QList<int> &listEntries);
@ -47,6 +47,8 @@ private:
void writeListEntryPropertySignalConnect(const ListEntryType &entry, QStringList keyList, QList<int> &listEntries); void writeListEntryPropertySignalConnect(const ListEntryType &entry, QStringList keyList, QList<int> &listEntries);
void writeSource(const SettingsType &settings); void writeSource(const SettingsType &settings);
void writeQmlRegistration(const SettingsType &settings);
}; };
#endif // QMLSETTINGSGENERATOR_H #endif // QMLSETTINGSGENERATOR_H

2
tools/settingsgenerator/qpmx.json

@ -3,7 +3,7 @@
{ {
"package": "de.skycoder42.qxmlcodegen", "package": "de.skycoder42.qxmlcodegen",
"provider": "qpm", "provider": "qpm",
"version": "1.1.7" "version": "1.2.0"
} }
], ],
"license": { "license": {

22
tools/settingsgenerator/qsettingsgenerator.xsd

@ -10,6 +10,24 @@
<qxg:method name="read_type_mapping" type="QHash&lt;QString, QString&gt;" asGroup="true"/> <qxg:method name="read_type_mapping" type="QHash&lt;QString, QString&gt;" asGroup="true"/>
<qxg:method name="read_included_file" type="NodeContentGroup"/> <qxg:method name="read_included_file" type="NodeContentGroup"/>
<!-- Basic Types -->
<xs:simpleType name="QmlRegistrationMode">
<xs:restriction base="xs:string">
<xs:enumeration value="Singleton"/>
<xs:enumeration value="Uncreatable"/>
<xs:enumeration value="Creatable"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="InstanceScope">
<xs:restriction base="xs:string">
<xs:enumeration value="DestroyOnAppQuit"/>
<xs:enumeration value="DestroyOnAppDestroy"/>
<xs:enumeration value="DestroyOnRegistryDestroy"/>
<xs:enumeration value="DestroyNever"/>
</xs:restriction>
</xs:simpleType>
<!-- Type definitions --> <!-- Type definitions -->
<xs:complexType name="IncludeType"> <xs:complexType name="IncludeType">
<xs:simpleContent> <xs:simpleContent>
@ -23,7 +41,7 @@
<xs:attribute name="uri" type="xs:string" use="required"/> <xs:attribute name="uri" type="xs:string" use="required"/>
<xs:attribute name="major" type="xs:integer" use="optional" default="1"/> <xs:attribute name="major" type="xs:integer" use="optional" default="1"/>
<xs:attribute name="minor" type="xs:integer" use="optional" default="0"/> <xs:attribute name="minor" type="xs:integer" use="optional" default="0"/>
<xs:attribute name="type" type="xs:string" use="optional" default="Singleton"/> <!-- TODO enum --> <xs:attribute name="type" type="QmlRegistrationMode" use="optional" default="Singleton"/>
<xs:attribute name="register" type="xs:boolean" use="optional" default="true" qxg:member="autoRegister"/> <xs:attribute name="register" type="xs:boolean" use="optional" default="true" qxg:member="autoRegister"/>
<xs:attribute name="header" type="xs:string" use="optional"/> <xs:attribute name="header" type="xs:string" use="optional"/>
</xs:complexType> </xs:complexType>
@ -62,7 +80,6 @@
<xs:element maxOccurs="unbounded" minOccurs="0" name="Param" type="ParamType"/> <xs:element maxOccurs="unbounded" minOccurs="0" name="Param" type="ParamType"/>
</xs:sequence> </xs:sequence>
<xs:attribute name="class" type="xs:string" use="required" qxg:member="className"/> <xs:attribute name="class" type="xs:string" use="required" qxg:member="className"/>
<xs:attribute name="scope" type="xs:string" use="optional"/> <!-- TODO make an enum -->
</xs:complexType> </xs:complexType>
<xs:group name="NodeContentGroup"> <xs:group name="NodeContentGroup">
@ -117,6 +134,7 @@
<xs:attribute name="name" type="xs:string" use="optional"/> <xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="prefix" type="xs:string" use="optional"/> <xs:attribute name="prefix" type="xs:string" use="optional"/>
<xs:attribute name="baseKey" type="xs:string" use="optional"/> <xs:attribute name="baseKey" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="InstanceScope" use="optional"/>
</xs:complexType> </xs:complexType>
<!-- root elements--> <!-- root elements-->

Loading…
Cancel
Save