Browse Source

modified cpp settings gen part for list entries

pull/2/head
Skycoder42 7 years ago
parent
commit
19b36bcece
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 398
      src/mvvmcore/settingsentry.h
  2. 30
      tests/auto/mvvmcore/settingsgenerator/generatortest.xml
  3. 2
      tests/auto/mvvmcore/settingsgenerator/test_de.ts
  4. 4
      tests/auto/mvvmcore/settingsgenerator/testbackend.cpp
  5. 115
      tests/auto/mvvmcore/settingsgenerator/tst_settingsgenerator.cpp
  6. 99
      tools/settingsgenerator/cppsettingsgenerator.cpp
  7. 22
      tools/settingsgenerator/cppsettingsgenerator.h
  8. 9
      tools/settingsgenerator/qsettingsgenerator.xsd

398
src/mvvmcore/settingsentry.h

@ -1,8 +1,12 @@
#ifndef QTMVVM_SETTINGSENTRY_H #ifndef QTMVVM_SETTINGSENTRY_H
#define QTMVVM_SETTINGSENTRY_H #define QTMVVM_SETTINGSENTRY_H
#include <functional>
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtCore/qregularexpression.h> #include <QtCore/qregularexpression.h>
#include <QtCore/qhash.h>
#include <QtCore/qsharedpointer.h>
#include "QtMvvmCore/qtmvvmcore_global.h" #include "QtMvvmCore/qtmvvmcore_global.h"
#include "QtMvvmCore/isettingsaccessor.h" #include "QtMvvmCore/isettingsaccessor.h"
@ -52,71 +56,40 @@ public:
}; };
template <typename TType> template <typename TType>
class SettingsListEntry class SettingsListNode
{ {
Q_DISABLE_COPY(SettingsListEntry) Q_DISABLE_COPY(SettingsListNode)
public: public:
class ListElement class Deferred
{ {
Q_DISABLE_COPY(ListElement) Q_DISABLE_COPY(Deferred)
public:
inline ListElement(ListElement &&other) noexcept = default;
inline ListElement &operator=(ListElement &&other) noexcept = default;
TType get() const && { return _self->getAt(_index); }
void set(const TType &value) && { _self->setAt(_index, value); }
inline ListElement &operator=(const TType &value) && { _self->setAt(_index, value); return *this; }
inline operator TType() const && { return _self->getAt(_index); }
private:
friend class SettingsListEntry<TType>;
inline ListElement(SettingsListEntry<TType> *self, int index) : _self{self}, _index{index} {}
SettingsListEntry<TType> *_self;
int _index;
};
template <typename T>
class iterator_base;
class iterator_value
{
public: public:
TType get() const { return _self->getAt(_index); } inline Deferred(Deferred &&other) noexcept = default;
void set(const TType &value) { _self->setAt(_index, value); } inline Deferred &operator=(Deferred &&other) noexcept = default;
inline ~Deferred() { commit(); }
inline iterator_value &operator=(const TType &value) { _self->setAt(_index, value); return *this; }
inline operator TType() const { return _self->getAt(_index); }
inline friend void swap(iterator_value& lhs, iterator_value& rhs) { qSwap(lhs._self, rhs._self); qSwap(lhs._index, rhs._index); } inline TType &element() { return _element; }
inline friend bool operator==(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index == rhs._index; } inline TType &operator*() { return _element; }
inline friend bool operator!=(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index != rhs._index; } inline TType *operator->() { return &_element; }
inline friend bool operator<(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index < rhs._index; }
inline friend bool operator>(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index > rhs._index; }
inline friend bool operator<=(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index <= rhs._index; }
inline friend bool operator>=(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index >= rhs._index; }
inline friend iterator_value operator+(const iterator_value &value, int delta) { return iterator_value{value._self, value._index + delta}; } inline void commit() { if(!_commited) { _commited = true; _node->commit(_index);} }
inline friend iterator_value operator+(int delta, const iterator_value &value) { return iterator_value{value._self, value._index + delta}; }
inline friend iterator_value operator-(const iterator_value &value, int delta) { return iterator_value{value._self, value._index - delta}; }
inline friend int operator-(const iterator_value &lhs, const iterator_value &rhs) { assert(lhs._self == rhs._self); return lhs._index - rhs._index; }
private: private:
template <typename T> friend class SettingsListNode<TType>;
friend class SettingsListEntry<TType>::iterator_base;
inline iterator_value(SettingsListEntry<TType> *self, int index) : _self{self}, _index{index} {}
inline iterator_value(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 &operator=(iterator_value &&other) noexcept = default;
SettingsListEntry<TType> *_self; SettingsListNode<TType> *_node;
TType &_element;
bool _commited = false;
int _index; int _index;
inline Deferred(SettingsListNode<TType> *node, TType &element, int index) :
_node{node},
_element{element},
_index{index}
{}
}; };
template <typename T> template <typename T>
@ -129,73 +102,67 @@ public:
using pointer = value_type*; using pointer = value_type*;
using reference = value_type&; using reference = value_type&;
inline iterator_base() = default;
inline iterator_base(const iterator_base<T> &other) = default; inline iterator_base(const iterator_base<T> &other) = default;
inline iterator_base &operator=(const iterator_base<T> &other) = default; inline iterator_base &operator=(const iterator_base<T> &other) = default;
inline iterator_base(iterator_base<T> &&other) noexcept = default; inline iterator_base(iterator_base<T> &&other) noexcept = default;
inline iterator_base &operator=(iterator_base<T> &&other) noexcept = default; inline iterator_base &operator=(iterator_base<T> &&other) noexcept = default;
inline iterator_base<T> &operator++() { ++_value._index; return *this; } inline iterator_base<T> &operator++() { ++_index; return *this; }
inline iterator_base<T> operator++(int) { return iterator_base<T>{_value._self, _value._index++}; } inline iterator_base<T> operator++(int) { return iterator_base<T>{_node, _index++}; }
inline iterator_base<T> &operator--() { --_value._index; return *this; } inline iterator_base<T> &operator--() { --_index; return *this; }
inline iterator_base<T> operator--(int) { return iterator_base<T>{_value._self, _value._index--}; } inline iterator_base<T> operator--(int) { return iterator_base<T>{_node, _index--}; }
inline const value_type &operator*() const { return _value; } inline reference operator*() const { return _node->at(_index); }
inline value_type &operator*() { return _value; } inline pointer operator->() const { return &_node->at(_index); }
inline const value_type *operator->() const { return &_value; } inline friend void swap(iterator_base<T> &lhs, iterator_base<T> &rhs) noexcept { std::swap(lhs._node, rhs._node); std::swap(lhs._index, rhs._index); }
inline value_type *operator->() { return &_value; }
inline friend void swap(iterator_base<T> &lhs, iterator_base<T> &rhs) { swap(lhs._value, rhs._value); } inline friend bool operator==(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index == rhs._index; }
inline friend bool operator!=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index != rhs._index; }
inline friend bool operator==(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value == rhs._value; } inline friend bool operator<(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index < rhs._index; }
inline friend bool operator!=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value != rhs._value; } inline friend bool operator>(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index > rhs._index; }
inline friend bool operator<(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value < rhs._value; } inline friend bool operator<=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index <= rhs._index; }
inline friend bool operator>(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value > rhs._value; } inline friend bool operator>=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index >= rhs._index; }
inline friend bool operator<=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value <= rhs._value; }
inline friend bool operator>=(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value >= rhs._value; } inline iterator_base<T> &operator+=(difference_type delta) { _index += delta; return *this; }
inline friend iterator_base<T> operator+(const iterator_base<T> &iter, difference_type delta) { return iterator_base<T>{iter._node, iter._index + delta}; }
inline iterator_base<T> &operator+=(difference_type delta) { _value._index += delta; return *this; } inline friend iterator_base<T> operator+(difference_type delta, const iterator_base<T> &iter) { return iterator_base<T>{iter._node, iter._index + delta}; }
inline friend iterator_base<T> operator+(const iterator_base<T> &iter, difference_type delta) { return iterator_base<T>{iter._value + delta}; } inline iterator_base<T> &operator-=(difference_type delta) { _index -= delta; return *this; }
inline friend iterator_base<T> operator+(difference_type delta, const iterator_base<T> &iter) { return iterator_base<T>{iter._value + delta}; } inline friend iterator_base<T> operator-(const iterator_base<T> &iter, difference_type delta) { return iterator_base<T>{iter._node, iter._index - delta}; }
inline iterator_base<T> &operator-=(difference_type delta) { _value._index -= delta; return *this; } inline friend difference_type operator-(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { assert(lhs._node == rhs._node); return lhs._index - rhs._index; }
inline friend iterator_base<T> operator-(const iterator_base<T> &iter, difference_type delta) { return iterator_base<T>{iter._value - delta}; }
inline friend difference_type operator-(const iterator_base<T> &lhs, const iterator_base<T> &rhs) { return lhs._value - rhs._value; } inline reference operator[](difference_type delta) const { return _node->at(_index + delta); }
inline value_type operator[](difference_type delta) const { return iterator_value{_value._self, _value._index + delta}; }
private: private:
friend class SettingsListEntry<TType>; friend class SettingsListNode<TType>;
SettingsListNode<TType> *_node;
int _index;
inline iterator_base(SettingsListEntry<TType> *self, int index) : _value{self, index} {} inline iterator_base(SettingsListNode<TType> *node, int index) :
inline iterator_base(iterator_value value) : _value{std::move(value)} {} _node{node},
iterator_value _value; _index{index}
{}
}; };
using iterator = iterator_base<iterator_value>; using iterator = iterator_base<TType>;
using const_iterator = iterator_base<const iterator_value>; using const_iterator = iterator_base<const TType>;
SettingsListEntry() = default; SettingsListNode() = default;
bool isSet() const; bool isSet() const;
QString key() const; QString key() const;
int size() const;
const TType &at(int index) const;
TType &at(int index);
QList<TType> get() const; TType &push();
void set(const QList<TType> &value); Deferred push_deferred();
void reset(bool reInit = true); void pop(int count = 1);
void reset();
SettingsListEntry<TType> &operator=(const QList<TType> &value);
operator QList<TType>() const;
int size() const; TType &operator[](int index);
TType getAt(int index) const; const TType &operator[](int index) const;
void setAt(int index, const TType &value);
void push(const TType &value);
void push(const QList<TType> &values);
TType pop();
void chop(int count);
ListElement operator[](int index);
const ListElement operator[](int index) const;
SettingsListEntry<TType> &operator+=(const TType &value);
SettingsListEntry<TType> &operator+=(const QList<TType> &values);
iterator begin(); iterator begin();
iterator end(); iterator end();
@ -204,22 +171,26 @@ public:
const_iterator constBegin() const; const_iterator constBegin() const;
const_iterator constEnd() const; const_iterator constEnd() const;
void addChangeCallback(const std::function<void(QList<TType>)> &callback); void addChangeCallback(const std::function<void(int)> &callback); // size
void addChangeCallback(QObject *scope, const std::function<void(QList<TType>)> &callback); void addChangeCallback(QObject *scope, const std::function<void(int)> &callback);
void addChangeCallback(const std::function<void(int, TType)> &callback); // index, value
void addChangeCallback(QObject *scope, const std::function<void(int, TType)> &callback);
void addSizeChangeCallback(const std::function<void(int)> &callback); // size
void addSizeChangeCallback(QObject *scope, const std::function<void(int)> &callback);
// internal // internal
void setup(QString key, ISettingsAccessor *accessor, QVariant defaultValue = {}); void setup(QString key, ISettingsAccessor *accessor, std::function<void(int, TType&)> setupFn);
void setupInit(QList<TType> init);
private: private:
struct ElementHolder {
bool __initialized = false;
QSharedPointer<TType> _element;
inline ElementHolder() : _element{new TType{}} {}
};
QString _key; QString _key;
QString _sizeKey;
ISettingsAccessor *_accessor = nullptr; ISettingsAccessor *_accessor = nullptr;
QVariant _default; std::function<void(int, TType&)> _setupFn;
QList<TType> _init; mutable QHash<int, ElementHolder> _cache;
void commit(int index);
}; };
// ------------- Generic Implementation ------------- // ------------- Generic Implementation -------------
@ -308,259 +279,164 @@ void SettingsEntry<T>::setup(QString key, ISettingsAccessor *accessor, QVariant
_default = std::move(defaultValue); _default = std::move(defaultValue);
} }
// ------------- Generic Implementation ListNode -------------
// ------------- Generic Implementation ListEntry -------------
template<typename TType> template<typename TType>
bool SettingsListEntry<TType>::isSet() const bool SettingsListNode<TType>::isSet() const
{ {
return _accessor->contains(_key + QStringLiteral("/size")); return _accessor->contains(_sizeKey);
} }
template<typename TType> template<typename TType>
QString SettingsListEntry<TType>::key() const QString SettingsListNode<TType>::key() const
{ {
return _key; return _key;
} }
template<typename TType> template<typename TType>
QList<TType> SettingsListEntry<TType>::get() const int SettingsListNode<TType>::size() const
{
auto mSize = size();
QList<TType> resList;
resList.reserve(mSize);
for(auto i = 0; i < mSize; ++i)
resList.append(getAt(i));
return resList;
}
template<typename TType>
void SettingsListEntry<TType>::set(const QList<TType> &value)
{
reset(false);
push(value);
}
template<typename TType>
void SettingsListEntry<TType>::reset(bool reInit)
{
_accessor->remove(_key);
if(reInit && !_init.isEmpty())
push(_init);
}
template<typename TType>
SettingsListEntry<TType> &SettingsListEntry<TType>::operator=(const QList<TType> &value)
{
set(value);
return *this;
}
template<typename TType>
SettingsListEntry<TType>::operator QList<TType>() const
{
return get();
}
template<typename TType>
int SettingsListEntry<TType>::size() const
{
return _accessor->load(_key + QStringLiteral("/size"), 0).toInt();
}
template<typename TType>
TType SettingsListEntry<TType>::getAt(int index) const
{ {
return _accessor->load(_key + QStringLiteral("/%1/value").arg(index), _default).template value<TType>(); return _accessor->load(_sizeKey, 0).toInt();
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::setAt(int index, const TType &value) const TType &SettingsListNode<TType>::at(int index) const
{ {
_accessor->save(_key + QStringLiteral("/%1/value").arg(index), QVariant::fromValue(value)); auto &value = _cache[index];
if(!value.__initialized) {
_setupFn(index, *(value._element));
value.__initialized = true;
}
return *(value._element);
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::push(const TType &value) TType &SettingsListNode<TType>::at(int index)
{ {
push(QList<TType>{value}); auto &value = _cache[index];
if(!value.__initialized) {
_setupFn(index, *(value._element));
value.__initialized = true;
}
return *(value._element);
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::push(const QList<TType> &values) TType &SettingsListNode<TType>::push()
{ {
auto cIndex = size(); auto cIndex = size();
for(const auto &value : values) _accessor->save(_sizeKey, cIndex + 1);
setAt(cIndex++, value); return at(cIndex);
_accessor->save(_key + QStringLiteral("/size"), cIndex);
} }
template<typename TType> template<typename TType>
TType QtMvvm::SettingsListEntry<TType>::pop() typename SettingsListNode<TType>::Deferred SettingsListNode<TType>::push_deferred()
{ {
auto res = getAt(size() - 1); auto cIndex = size();
chop(1); return {this, at(cIndex), cIndex};
return res;
} }
template<typename TType> template<typename TType>
void QtMvvm::SettingsListEntry<TType>::chop(int count) void SettingsListNode<TType>::pop(int count)
{ {
auto cSize = size(); auto cSize = size();
auto nSize = qMax(size() - count, 0); auto nSize = qMax(size() - count, 0);
for(auto i = cSize - 1; i >= nSize; --i) for(auto i = cSize - 1; i >= nSize; --i)
_accessor->remove(_key + QStringLiteral("/%1/value").arg(i)); _accessor->remove(_key + QStringLiteral("/%1").arg(i));
_accessor->save(_key + QStringLiteral("/size"), nSize); _accessor->save(_sizeKey, nSize);
} }
template<typename TType> template<typename TType>
const typename SettingsListEntry<TType>::ListElement SettingsListEntry<TType>::operator[](int index) const void SettingsListNode<TType>::reset()
{ {
return ListElement{this, index}; _accessor->remove(_key);
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::ListElement SettingsListEntry<TType>::operator[](int index) const TType &SettingsListNode<TType>::operator[](int index) const
{ {
return ListElement{this, index}; return at(index);
} }
template<typename TType>
SettingsListEntry<TType> &SettingsListEntry<TType>::operator+=(const TType &value)
{
push(value);
return *this;
}
template<typename TType> template<typename TType>
SettingsListEntry<TType> &SettingsListEntry<TType>::operator+=(const QList<TType> &values) TType &SettingsListNode<TType>::operator[](int index)
{ {
push(values); return at(index);
return *this;
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::iterator SettingsListEntry<TType>::begin() typename SettingsListNode<TType>::iterator SettingsListNode<TType>::begin()
{ {
return iterator{this, 0}; return iterator{this, 0};
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::iterator QtMvvm::SettingsListEntry<TType>::end() typename SettingsListNode<TType>::iterator SettingsListNode<TType>::end()
{ {
return iterator{this, size()}; return iterator{this, size()};
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::begin() const typename SettingsListNode<TType>::const_iterator SettingsListNode<TType>::begin() const
{ {
return constBegin(); return constBegin();
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::end() const typename SettingsListNode<TType>::const_iterator SettingsListNode<TType>::end() const
{ {
return constEnd(); return constEnd();
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::constBegin() const typename SettingsListNode<TType>::const_iterator SettingsListNode<TType>::constBegin() const
{ {
return const_iterator{const_cast<SettingsListEntry<TType>*>(this), 0}; return const_iterator{const_cast<SettingsListNode<TType>*>(this), 0};
} }
template<typename TType> template<typename TType>
typename SettingsListEntry<TType>::const_iterator SettingsListEntry<TType>::constEnd() const typename SettingsListNode<TType>::const_iterator SettingsListNode<TType>::constEnd() const
{ {
return const_iterator{const_cast<SettingsListEntry<TType>*>(this), size()}; return const_iterator{const_cast<SettingsListNode<TType>*>(this), size()};
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::addChangeCallback(const std::function<void (QList<TType>)> &callback) void SettingsListNode<TType>::addChangeCallback(const std::function<void (int)> &callback)
{ {
addChangeCallback(_accessor, callback); addChangeCallback(_accessor, callback);
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::addChangeCallback(QObject *scope, const std::function<void (QList<TType>)> &callback) void SettingsListNode<TType>::addChangeCallback(QObject *scope, const std::function<void (int)> &callback)
{ {
QObject::connect(_accessor, &ISettingsAccessor::entryChanged, QString mKey = _sizeKey;
scope, [this, callback](const QString &key, const QVariant &) {
if(key.startsWith(_key))
callback(get());
});
QObject::connect(_accessor, &ISettingsAccessor::entryRemoved,
scope, [this, callback](const QString &key) {
if(key.startsWith(_key))
callback(get());
});
}
template<typename TType>
void SettingsListEntry<TType>::addChangeCallback(const std::function<void (int, TType)> &callback)
{
addChangeCallback(_accessor, callback);
}
template<typename TType>
void SettingsListEntry<TType>::addChangeCallback(QObject *scope, const std::function<void (int, TType)> &callback)
{
QRegularExpression mKey {QStringLiteral("^%1\\/\\d+\\/value$").arg(QRegularExpression::escape(_key))};
mKey.optimize();
auto mDefault = _default;
QObject::connect(_accessor, &ISettingsAccessor::entryChanged,
scope, [mKey, callback](const QString &key, const QVariant &value) {
auto match = mKey.match(key);
if(match.hasMatch())
callback(match.captured(1).toInt(), value.template value<TType>());
});
QObject::connect(_accessor, &ISettingsAccessor::entryRemoved,
scope, [mKey, mDefault, callback](const QString &key) {
auto match = mKey.match(key);
if(match.hasMatch())
callback(match.captured(1).toInt(), mDefault.template value<TType>());
});
}
template<typename TType>
void SettingsListEntry<TType>::addSizeChangeCallback(const std::function<void (int)> &callback)
{
addSizeChangeCallback(_accessor, callback);
}
template<typename TType>
void SettingsListEntry<TType>::addSizeChangeCallback(QObject *scope, const std::function<void (int)> &callback)
{
QString mKey = _key + QStringLiteral("/size");
auto mInit = _init;
QObject::connect(_accessor, &ISettingsAccessor::entryChanged, QObject::connect(_accessor, &ISettingsAccessor::entryChanged,
scope, [mKey, callback](const QString &key, const QVariant &value) { scope, [mKey, callback](const QString &key, const QVariant &value) {
if(key == mKey) if(key == mKey)
callback(value.toInt()); callback(value.toInt());
}); });
QObject::connect(_accessor, &ISettingsAccessor::entryRemoved, QObject::connect(_accessor, &ISettingsAccessor::entryRemoved,
scope, [mKey, mInit, callback](const QString &key) { scope, [mKey, callback](const QString &key) {
if(key == mKey) if(key == mKey)
callback(0); //is ok, as in case of a "reinit", the entry changed will be emitted next callback(0);
}); });
} }
template<typename TType> template<typename TType>
void SettingsListEntry<TType>::setup(QString key, ISettingsAccessor *accessor, QVariant defaultValue) void SettingsListNode<TType>::setup(QString key, ISettingsAccessor *accessor, std::function<void(int, TType&)> setupFn)
{ {
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);
_sizeKey = _key + QStringLiteral("/size");
_accessor = accessor; _accessor = accessor;
_default = std::move(defaultValue); _setupFn = std::move(setupFn);
} }
template<typename TType> template<typename TType>
void QtMvvm::SettingsListEntry<TType>::setupInit(QList<TType> init) void SettingsListNode<TType>::commit(int index)
{ {
_init = std::move(init); _accessor->save(_sizeKey, qMax(size(), index + 1));
if(!isSet())
push(_init);
} }
} }

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

@ -62,15 +62,25 @@
<Code>{42}</Code> <Code>{42}</Code>
</Entry> </Entry>
<ListEntry key="listEntry" <ListNode key="listNode">
type="QByteArray"> <Entry key="simpleChild"
<Entry key="dummyChild"
type="bool"/> type="bool"/>
<Code>&quot;Hello World&quot;</Code> <Node key="someNode">
<Init> { <Entry key="deepChild"
&quot;test1&quot;, type="int"
&quot;test2&quot;, default="22"/>
&quot;test3&quot; <Entry key="deepParent"
} </Init> type="QString"
</ListEntry> default="___">
<Entry key="simpleChild"
type="bool"
default="true"/>
</Entry>
</Node>
<ListNode key="childList">
<Entry key="valueEntry"
type="double"
default="4.2"/>
</ListNode>
</ListNode>
</Settings> </Settings>

2
tests/auto/mvvmcore/settingsgenerator/test_de.ts

@ -4,7 +4,7 @@
<context> <context>
<name>SettingsGeneratorTest</name> <name>SettingsGeneratorTest</name>
<message> <message>
<location filename="tst_settingsgenerator.cpp" line="+140"/> <location filename="tst_settingsgenerator.cpp" line="+171"/>
<source>somet translated text...</source> <source>somet translated text...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

4
tests/auto/mvvmcore/settingsgenerator/testbackend.cpp

@ -1,4 +1,5 @@
#include "testbackend.h" #include "testbackend.h"
#include <QDebug>
TestBackend::TestBackend(QString name, int code, QObject *parent) : TestBackend::TestBackend(QString name, int code, QObject *parent) :
ISettingsAccessor{parent}, ISettingsAccessor{parent},
@ -26,8 +27,9 @@ void TestBackend::remove(const QString &key)
{ {
for(auto it = _data.begin(); it != _data.end();) { for(auto it = _data.begin(); it != _data.end();) {
if(it.key().startsWith(key + QLatin1Char('/'))) { if(it.key().startsWith(key + QLatin1Char('/'))) {
auto rmKey = it.key();
it = _data.erase(it); it = _data.erase(it);
emit entryRemoved(key); emit entryRemoved(rmKey);
} else } else
++it; ++it;
} }

115
tests/auto/mvvmcore/settingsgenerator/tst_settingsgenerator.cpp

@ -41,8 +41,7 @@ void SettingsGeneratorTest::testSettingsGenerator()
QCOMPARE(settings->parentNode.parentEntry.leafEntry.key(), QStringLiteral("tests/parentNode/parentEntry/leafEntry")); QCOMPARE(settings->parentNode.parentEntry.leafEntry.key(), QStringLiteral("tests/parentNode/parentEntry/leafEntry"));
QCOMPARE(settings->variantEntry.key(), QStringLiteral("tests/variantEntry")); QCOMPARE(settings->variantEntry.key(), QStringLiteral("tests/variantEntry"));
QCOMPARE(settings->simpleListEntry.key(), QStringLiteral("tests/simpleListEntry")); QCOMPARE(settings->simpleListEntry.key(), QStringLiteral("tests/simpleListEntry"));
QCOMPARE(settings->listEntry.key(), QStringLiteral("tests/listEntry")); QCOMPARE(settings->listNode.key(), QStringLiteral("tests/listNode"));
QCOMPARE(settings->listEntry.dummyChild.key(), QStringLiteral("tests/listEntry/dummyChild"));
//verify defaults //verify defaults
QCOMPARE(settings->emptyEntry.get(), false); QCOMPARE(settings->emptyEntry.get(), false);
@ -54,9 +53,6 @@ void SettingsGeneratorTest::testSettingsGenerator()
QCOMPARE(settings->parentNode.parentEntry.leafEntry.get(), QStringLiteral("translate me")); QCOMPARE(settings->parentNode.parentEntry.leafEntry.get(), QStringLiteral("translate me"));
QCOMPARE(settings->variantEntry.get(), QVariant{}); QCOMPARE(settings->variantEntry.get(), QVariant{});
QCOMPARE(settings->simpleListEntry.get(), QList<int>{42}); QCOMPARE(settings->simpleListEntry.get(), QList<int>{42});
QByteArrayList iList{"test1", "test2", "test3"};
QCOMPARE(settings->listEntry.get(), iList);
QCOMPARE(settings->listEntry.dummyChild.get(), false);
//verify read/write (just on a single entry, they work all the same) //verify read/write (just on a single entry, they work all the same)
auto tKey = QStringLiteral("tests/advancedEntry"); auto tKey = QStringLiteral("tests/advancedEntry");
@ -74,44 +70,79 @@ void SettingsGeneratorTest::testSettingsGenerator()
QCOMPARE(settings->advancedEntry, tValue); QCOMPARE(settings->advancedEntry, tValue);
//verify list stuff //verify list stuff
QVERIFY(settings->listEntry.isSet()); QVERIFY(!settings->listNode.isSet());
QCOMPARE(settings->listEntry.size(), 3); QCOMPARE(settings->listNode.size(), 0);
QCOMPARE(settings->listEntry.getAt(0), "test1"); settings->listNode.push();
QCOMPARE(settings->listEntry[1].get(), "test2"); QVERIFY(settings->listNode.isSet());
QCOMPARE(static_cast<QByteArray>(settings->listEntry[2]), "test3"); QCOMPARE(settings->listNode.size(), 1);
QCOMPARE(settings->listEntry.getAt(3), "Hello World");
QCOMPARE(settings->listNode.at(0).simpleChild.key(), QStringLiteral("tests/listNode/0/simpleChild"));
settings->listEntry.push("baum"); QCOMPARE(settings->listNode[0].someNode.deepChild.key(), QStringLiteral("tests/listNode/0/someNode/deepChild"));
QCOMPARE(settings->listEntry.size(), 4); QCOMPARE(settings->listNode[0].someNode.deepParent.key(), QStringLiteral("tests/listNode/0/someNode/deepParent"));
QCOMPARE(settings->listEntry.getAt(3), "baum"); QCOMPARE(settings->listNode[0].someNode.deepParent.simpleChild.key(), QStringLiteral("tests/listNode/0/someNode/deepParent/simpleChild"));
settings->listEntry.setAt(1, "tree"); QCOMPARE(settings->listNode[0].childList.key(), QStringLiteral("tests/listNode/0/childList"));
settings->listEntry[2] = "eetr";
QCOMPARE(settings->listEntry.size(), 4); QCOMPARE(settings->listNode.at(0).simpleChild, false);
QCOMPARE(settings->listEntry.getAt(1), "tree"); QCOMPARE(settings->listNode[0].someNode.deepChild, 22);
QCOMPARE(settings->listEntry.getAt(2), "eetr"); QCOMPARE(settings->listNode[0].someNode.deepParent, QStringLiteral("___"));
settings->listEntry += "baum42"; QCOMPARE(settings->listNode[0].someNode.deepParent.simpleChild, true);
QCOMPARE(settings->listEntry.size(), 5); QVERIFY(!settings->listNode[0].childList.isSet());
QCOMPARE(settings->listEntry.getAt(4), "baum42"); QCOMPARE(settings->listNode[0].childList.size(), 0);
QCOMPARE(settings->listEntry.pop(), "baum42");
QCOMPARE(settings->listEntry.size(), 4); int resVal = -1;
QCOMPARE(settings->listEntry.getAt(4), "Hello World"); settings->listNode[0].someNode.deepChild.addChangeCallback([&](int val){
settings->listEntry.chop(10); resVal = val;
QCOMPARE(settings->listEntry.size(), 0); });
QVERIFY(settings->listEntry.isSet()); settings->listNode[0].someNode.deepChild = 47;
QCOMPARE(resVal, 47);
settings->listEntry.reset(false); resVal = -1;
QVERIFY(!settings->listEntry.isSet());
QCOMPARE(settings->listEntry.size(), 0); {
settings->listEntry.reset(true); auto &newEntry = settings->listNode.push();
QVERIFY(settings->listEntry.isSet()); QCOMPARE(settings->listNode.size(), 2);
QCOMPARE(settings->listEntry.size(), 3); QCOMPARE(newEntry.simpleChild, false);
QCOMPARE(settings->listNode[1].simpleChild.key(), QStringLiteral("tests/listNode/1/simpleChild"));
for(const auto &elem : qAsConst(settings->listEntry)) QCOMPARE(settings->listNode[1].simpleChild, false);
qDebug() << elem.get() << static_cast<QByteArray>(elem); newEntry.simpleChild = true;
for(auto &elem : settings->listEntry) { QCOMPARE(newEntry.simpleChild, true);
elem = "test1"; QCOMPARE(settings->listNode[1].simpleChild, true);
elem.set("test2"); QCOMPARE(settings->listNode[0].simpleChild, false);
}
{
auto newEntry = settings->listNode.push_deferred();
QCOMPARE(settings->listNode.size(), 2);
QCOMPARE(newEntry.element().someNode.deepChild, 22);
QCOMPARE(settings->listNode[2].simpleChild.key(), QStringLiteral("tests/listNode/2/simpleChild"));
QCOMPARE(settings->listNode[2].someNode.deepChild, 22);
newEntry->someNode.deepChild = 44;
QCOMPARE((*newEntry).someNode.deepChild, 44);
QCOMPARE(settings->listNode[2].someNode.deepChild, 44);
QCOMPARE(settings->listNode.size(), 2);
} }
QCOMPARE(settings->listNode.size(), 3);
QCOMPARE(resVal, -1); //should be unchanged
for(const auto &elem : qAsConst(settings->listNode))
qDebug() << elem.simpleChild.get();
for(auto &elem : settings->listNode)
elem.simpleChild = true;
auto sizeChanged = false;
settings->listNode.addChangeCallback([&](int size) {
sizeChanged = (size == 1);
});
settings->listNode.pop(2);
QVERIFY(sizeChanged);
QCOMPARE(settings->listNode.size(), 1);
QCOMPARE(settings->listNode[1].simpleChild, false);
QCOMPARE(settings->listNode[2].someNode.deepChild, 22);
settings->listNode.reset();
QVERIFY(!settings->listNode.isSet());
QCOMPARE(settings->listNode.size(), 0);
QCOMPARE(resVal, 22); //should be resetted
} }
void SettingsGeneratorTest::testImportedSettings() void SettingsGeneratorTest::testImportedSettings()

99
tools/settingsgenerator/cppsettingsgenerator.cpp

@ -18,6 +18,8 @@ void CppSettingsGenerator::process(const QString &inPath)
settings.name = QFileInfo{inPath}.baseName(); settings.name = QFileInfo{inPath}.baseName();
fixTrContext(settings, QFileInfo{inPath}.fileName()); fixTrContext(settings, QFileInfo{inPath}.fileName());
_typeMappings = settings.typeMappings;
if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text))
throw FileException{_hdrFile}; throw FileException{_hdrFile};
writeHeader(settings); writeHeader(settings);
@ -63,7 +65,7 @@ void CppSettingsGenerator::writeHeader(const SettingsType &settings)
<< "\tstatic " << settings.name.value() << " *instance();\n\n" << "\tstatic " << settings.name.value() << " *instance();\n\n"
<< "\tQtMvvm::ISettingsAccessor *accessor() const;\n\n"; << "\tQtMvvm::ISettingsAccessor *accessor() const;\n\n";
writeNodeElementDeclarations(settings, settings.typeMappings); writeNodeElementDeclarations(settings);
_hdr << "\nprivate:\n" _hdr << "\nprivate:\n"
<< "\tQtMvvm::ISettingsAccessor *_accessor;\n" << "\tQtMvvm::ISettingsAccessor *_accessor;\n"
@ -71,55 +73,48 @@ void CppSettingsGenerator::writeHeader(const SettingsType &settings)
<< "#endif //" << incGuard << '\n'; << "#endif //" << incGuard << '\n';
} }
void CppSettingsGenerator::writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent) void CppSettingsGenerator::writeNodeElementDeclarations(const NodeContentGroup &node, int intendent)
{ {
for(const auto &cNode : node.contentNodes) { for(const auto &cNode : node.contentNodes) {
if(nonstd::holds_alternative<NodeType>(cNode)) if(nonstd::holds_alternative<NodeType>(cNode))
writeNodeDeclaration(nonstd::get<NodeType>(cNode), typeMappings, intendent); writeNodeDeclaration(nonstd::get<NodeType>(cNode), intendent);
else if(nonstd::holds_alternative<EntryType>(cNode)) else if(nonstd::holds_alternative<EntryType>(cNode))
writeEntryDeclaration(nonstd::get<EntryType>(cNode), typeMappings, intendent); writeEntryDeclaration(nonstd::get<EntryType>(cNode), intendent);
else if(nonstd::holds_alternative<ListEntryType>(cNode)) else if(nonstd::holds_alternative<ListNodeType>(cNode))
writeListEntryDeclaration(nonstd::get<ListEntryType>(cNode), typeMappings, intendent); writeListNodeDeclaration(nonstd::get<ListNodeType>(cNode), intendent);
else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) else if(nonstd::holds_alternative<NodeContentGroup>(cNode))
writeNodeElementDeclarations(nonstd::get<NodeContentGroup>(cNode), typeMappings, intendent); writeNodeElementDeclarations(nonstd::get<NodeContentGroup>(cNode), intendent);
else else
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
void CppSettingsGenerator::writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent) void CppSettingsGenerator::writeNodeDeclaration(const NodeType &node, int intendent)
{ {
_hdr << TABS << "struct { //" << node.key << "\n"; _hdr << TABS << "struct { //" << node.key << "\n";
writeNodeElementDeclarations(node, typeMappings, intendent + 1); writeNodeElementDeclarations(node, intendent + 1);
_hdr << TABS << "} " << node.key << ";\n"; _hdr << TABS << "} " << node.key << ";\n";
} }
void CppSettingsGenerator::writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) void CppSettingsGenerator::writeEntryDeclaration(const EntryType &entry, int intendent)
{ {
if(entry.contentNodes.isEmpty()) if(entry.contentNodes.isEmpty())
_hdr << TABS << "QtMvvm::SettingsEntry<" << typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n"; _hdr << TABS << "QtMvvm::SettingsEntry<" << _typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n";
else { else {
const auto &mType = typeMappings.value(entry.type, entry.type); const auto &mType = _typeMappings.value(entry.type, entry.type);
_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; _hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n";
writeNodeElementDeclarations(entry, typeMappings, intendent + 1); writeNodeElementDeclarations(entry, intendent + 1);
_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; _hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n";
_hdr << TABS << "} " << entry.key << ";\n"; _hdr << TABS << "} " << entry.key << ";\n";
} }
} }
void CppSettingsGenerator::writeListEntryDeclaration(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) void CppSettingsGenerator::writeListNodeDeclaration(const ListNodeType &node, int intendent)
{ {
if(entry.contentNodes.isEmpty()) _hdr << TABS << "struct " << node.key << "_element {\n";
_hdr << TABS << "QtMvvm::SettingsListEntry<" << typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n"; writeNodeElementDeclarations(node, intendent + 1);
else { _hdr << TABS << "};\n";
const QString mType = typeMappings.value(entry.type, entry.type); _hdr << TABS << "QtMvvm::SettingsListNode<" << node.key << "_element> " << node.key << ";\n";
_hdr << TABS << "struct : QtMvvm::SettingsListEntry<" << mType << "> { //" << entry.key << "\n";
writeNodeElementDeclarations(entry, typeMappings, intendent + 1);
_hdr << TABS << "\tinline auto &operator=(const QList<" << mType << "> &__value) { SettingsListEntry<" << 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) { SettingsListEntry<" << mType << ">::operator+=(__value); return *this; }\n";
_hdr << TABS << "} " << entry.key << ";\n";
}
} }
void CppSettingsGenerator::writeSource(const SettingsType &settings) void CppSettingsGenerator::writeSource(const SettingsType &settings)
@ -188,7 +183,7 @@ void CppSettingsGenerator::writeSource(const SettingsType &settings)
<< "\tQObject{parent},\n" << "\tQObject{parent},\n"
<< "\t_accessor{accessor}\n" << "\t_accessor{accessor}\n"
<< "{\n"; << "{\n";
writeNodeElementDefinitions(settings, settings.typeMappings, settings.baseKey); writeNodeElementDefinitions(settings, settings.baseKey ? QStringList{settings.baseKey.value()} : QStringList{});
_src << "}\n\n"; _src << "}\n\n";
_src << settings.name.value() << " *" << settings.name.value() << "::instance()\n" _src << settings.name.value() << " *" << settings.name.value() << "::instance()\n"
@ -202,50 +197,62 @@ void CppSettingsGenerator::writeSource(const SettingsType &settings)
<< "}\n\n"; << "}\n\n";
} }
void CppSettingsGenerator::writeNodeElementDefinitions(const SettingsGeneratorBase::NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain) void CppSettingsGenerator::writeNodeElementDefinitions(const SettingsGeneratorBase::NodeContentGroup &node, const QStringList &keyChain, const QStringList &entryChain, int intendent, const QStringList &listTypeChain)
{ {
for(const auto &cNode : node.contentNodes) { for(const auto &cNode : node.contentNodes) {
if(nonstd::holds_alternative<NodeType>(cNode)) { if(nonstd::holds_alternative<NodeType>(cNode)) {
const auto &xNode = nonstd::get<NodeType>(cNode); const auto &xNode = nonstd::get<NodeType>(cNode);
writeNodeElementDefinitions(xNode, typeMappings, baseKey, QStringList{keyChain} << xNode.key); writeNodeElementDefinitions(xNode, QStringList{keyChain} << xNode.key, QStringList{entryChain} << xNode.key, intendent, listTypeChain);
} else if(nonstd::holds_alternative<EntryType>(cNode)) } else if(nonstd::holds_alternative<EntryType>(cNode))
writeEntryDefinition(nonstd::get<EntryType>(cNode), typeMappings, baseKey, keyChain); writeEntryDefinition(nonstd::get<EntryType>(cNode), keyChain, entryChain, intendent, listTypeChain);
else if(nonstd::holds_alternative<ListEntryType>(cNode)) else if(nonstd::holds_alternative<ListNodeType>(cNode))
writeListEntryDefinition(nonstd::get<ListEntryType>(cNode), typeMappings, baseKey, keyChain); writeListNodeDefinition(nonstd::get<ListNodeType>(cNode), keyChain, entryChain, intendent, listTypeChain);
else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) else if(nonstd::holds_alternative<NodeContentGroup>(cNode))
writeNodeElementDefinitions(nonstd::get<NodeContentGroup>(cNode), typeMappings, baseKey, keyChain); writeNodeElementDefinitions(nonstd::get<NodeContentGroup>(cNode), keyChain, entryChain, intendent, listTypeChain);
else else
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
void CppSettingsGenerator::writeEntryDefinition(const SettingsGeneratorBase::EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren) void CppSettingsGenerator::writeEntryDefinition(const SettingsGeneratorBase::EntryType &entry, QStringList keyChain, QStringList entryChain, int intendent, const QStringList &listTypeChain)
{ {
entryChain.append(entry.key);
keyChain.append(entry.key); keyChain.append(entry.key);
_src << "\t" << keyChain.join(QLatin1Char('.')) _src << TABS << entryChain.join(QLatin1Char('.'))
<< ".setup(QStringLiteral(\"" << (baseKey ? QStringList{baseKey.value()} + keyChain : keyChain).join(QLatin1Char('/')) << "\"), _accessor"; << ".setup(" << concatKeys(keyChain, intendent) << ", _accessor";
if(entry.code) if(entry.code)
_src << ", QVariant::fromValue<" << typeMappings.value(entry.type, entry.type) << ">(" << entry.code.value().trimmed() << ")"; _src << ", QVariant::fromValue<" << _typeMappings.value(entry.type, entry.type) << ">(" << entry.code.value().trimmed() << ")";
else if(entry.defaultValue) { else if(entry.defaultValue) {
_src << ", QVariant{"; _src << ", QVariant{";
if(entry.tr) if(entry.tr)
_src << "QCoreApplication::translate(\"" << entry.trContext.value() << "\", \"" << entry.defaultValue.value() << "\")"; _src << "QCoreApplication::translate(\"" << entry.trContext.value() << "\", \"" << entry.defaultValue.value() << "\")";
else else
_src << "QStringLiteral(\"" << entry.defaultValue.value() << "\")"; _src << "QStringLiteral(\"" << entry.defaultValue.value() << "\")";
_src << "}.value<" << typeMappings.value(entry.type, entry.type) << ">()"; _src << "}.value<" << _typeMappings.value(entry.type, entry.type) << ">()";
} }
_src << ");\n"; _src << ");\n";
if(!skipChildren) writeNodeElementDefinitions(entry, keyChain, entryChain, intendent, listTypeChain);
writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain);
} }
void CppSettingsGenerator::writeListEntryDefinition(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain) void CppSettingsGenerator::writeListNodeDefinition(const ListNodeType &node, QStringList keyChain, QStringList entryChain, int intendent, QStringList listTypeChain)
{ {
writeEntryDefinition(entry, typeMappings, baseKey, keyChain, entry.init.has_value()); keyChain.append(node.key);
if(entry.init) { entryChain.append(node.key);
keyChain.append(entry.key); listTypeChain.append(node.key + QStringLiteral("_element"));
_src << "\t" << keyChain.join(QLatin1Char('.')) << ".setupInit(" << entry.init.value().trimmed() << ");\n"; _src << TABS << entryChain.join(QLatin1Char('.'))
writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain); << ".setup(" << concatKeys(keyChain, intendent) << ", _accessor, [=](int __index_" << intendent << ", " << listTypeChain.join(QStringLiteral("::")) << " &__entry) {\n";
}
keyChain.append(QLatin1Char('%') + QString::number(intendent));
entryChain = QStringList{QStringLiteral("__entry")};
writeNodeElementDefinitions(node, keyChain, entryChain, intendent + 1, listTypeChain);
_src << TABS << "});\n";
}
QString CppSettingsGenerator::concatKeys(const QStringList &keyChain, int intendet) const
{
QString res = QStringLiteral("QStringLiteral(\"") + keyChain.join(QLatin1Char('/')) + QStringLiteral("\")");
for(auto i = 1; i < intendet; i++)
res.append(QStringLiteral(".arg(__index_%1)").arg(i));
return res;
} }

22
tools/settingsgenerator/cppsettingsgenerator.h

@ -18,16 +18,24 @@ private:
QTextStream _hdr; QTextStream _hdr;
QTextStream _src; QTextStream _src;
QHash<QString, QString> _typeMappings;
void writeHeader(const SettingsType &settings); void writeHeader(const SettingsType &settings);
void writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent = 1); void writeNodeElementDeclarations(const NodeContentGroup &node, int intendent = 1);
void writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent = 1); void writeNodeDeclaration(const NodeType &node, int intendent = 1);
void writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); void writeEntryDeclaration(const EntryType &entry, int intendent = 1);
void writeListEntryDeclaration(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); void writeListNodeDeclaration(const ListNodeType &node, int intendent = 1);
void writeSource(const SettingsType &settings); void writeSource(const SettingsType &settings);
void writeNodeElementDefinitions(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain = {}); void writeNodeElementDefinitions(const NodeContentGroup &node,
void writeEntryDefinition(const EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren = false); const QStringList &keyChain,
void writeListEntryDefinition(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain); const QStringList &entryChain = {},
int intendent = 1,
const QStringList &listTypeChain = {});
void writeEntryDefinition(const EntryType &entry, QStringList keyChain, QStringList entryChain, int intendent, const QStringList &listTypeChain);
void writeListNodeDefinition(const ListNodeType &node, QStringList keyChain, QStringList entryChain, int intendent, QStringList listTypeChain);
QString concatKeys(const QStringList &keyChain, int intendet) const;
}; };
#endif // CPPSETTINGSGENERATOR_H #endif // CPPSETTINGSGENERATOR_H

9
tools/settingsgenerator/qsettingsgenerator.xsd

@ -88,6 +88,7 @@
<xs:element name="Node" type="NodeType"/> <xs:element name="Node" type="NodeType"/>
<xs:element name="Entry" type="EntryType"/> <xs:element name="Entry" type="EntryType"/>
<xs:element name="ListEntry" type="ListEntryType"/> <xs:element name="ListEntry" type="ListEntryType"/>
<xs:element name="ListNode" type="ListNodeType"/>
<xs:element name="Import" type="ImportType" qxg:method="read_included_file"/> <xs:element name="Import" type="ImportType" qxg:method="read_included_file"/>
</xs:choice> </xs:choice>
</xs:sequence> </xs:sequence>
@ -98,6 +99,14 @@
<xs:attribute name="key" type="xs:string" use="required"/> <xs:attribute name="key" type="xs:string" use="required"/>
</xs:complexType> </xs:complexType>
<xs:complexType name="ListNodeType" qxg:declare="true">
<xs:complexContent>
<xs:extension base="NodeType">
<xs:attribute name="listEntry" type="xs:boolean" default="false" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="EntryType" qxg:declare="true"> <xs:complexType name="EntryType" qxg:declare="true">
<xs:complexContent> <xs:complexContent>
<xs:extension base="NodeType"> <xs:extension base="NodeType">

Loading…
Cancel
Save