diff --git a/src/mvvmcore/settingsentry.h b/src/mvvmcore/settingsentry.h index c58bc85..7f875d1 100644 --- a/src/mvvmcore/settingsentry.h +++ b/src/mvvmcore/settingsentry.h @@ -176,6 +176,7 @@ public: // internal void setup(QString key, ISettingsAccessor *accessor, std::function setupFn); + void commit(int index); private: struct ElementHolder { @@ -189,8 +190,6 @@ private: ISettingsAccessor *_accessor = nullptr; std::function _setupFn; mutable QHash _cache; - - void commit(int index); }; // ------------- Generic Implementation ------------- diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 4e1bf1a..7e7eed6 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs -SUBDIRS += cmake mvvmcore \ - qml +SUBDIRS += cmake \ + mvvmcore \ + qml diff --git a/tests/auto/qml/qmlsettingsgenerator/generatortest.xml b/tests/auto/qml/qmlsettingsgenerator/generatortest.xml index 42ee0fe..1ea7015 100644 --- a/tests/auto/qml/qmlsettingsgenerator/generatortest.xml +++ b/tests/auto/qml/qmlsettingsgenerator/generatortest.xml @@ -64,15 +64,25 @@ {42} - - + - "Hello World" - { - "test1", - "test2", - "test3" - } - + + + + + + + + + + diff --git a/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qml b/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qml index ba1e524..33469f2 100644 --- a/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qml +++ b/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qml @@ -5,9 +5,21 @@ import de.skycoder42.QtMvvm.Core.test 4.2 Item { id: root - Component { - id: listElement - TestSettings_ListElement_8 {} + property string changeData: "" + Connections { + target: TestSettings.parentNode.parentEntryGroup + onLeafEntryChanged: { + changeData = value; + } + } + + property bool ready: false + property int deepData: 0 + Connections { + target: ready ? TestSettings.listNode[0].someNode : null + onDeepChildChanged: { + deepData = value; + } } TestCase { @@ -28,39 +40,65 @@ Item { compare(TestSettings.parentNode.parentEntryGroup.leafEntry, qsTr("translate me")); compare(TestSettings.variantEntry, undefined); compare(TestSettings.simpleListEntry, [42]); - compare(TestSettings.listEntryGroup.dummyChild, false); } - function test_2_listEntry() { + function test_2_changeSignals() { + changeData = ""; + TestSettings.parentNode.parentEntryGroup.leafEntry = "test44"; + compare(TestSettings.parentNode.parentEntryGroup.leafEntry, "test44"); + compare(changeData, "test44"); + } + + function test_3_listEntry() { // test reading - compare(TestSettings.listEntry.length, 3); - verify(TestSettings.listEntry[0]); - compare(TestSettings.listEntry[0].value, "test1"); - verify(TestSettings.listEntry[1]); - compare(TestSettings.listEntry[1].value, "test2"); - verify(TestSettings.listEntry[2]); - compare(TestSettings.listEntry[2].value, "test3"); - verify(!TestSettings.listEntry[3]); + compare(TestSettings.listNode.length, 0); + verify(TestSettings.listNode_push()); + compare(TestSettings.listNode.length, 1); + + compare(TestSettings.listNode[0].simpleChild, false); + verify(TestSettings.listNode[0].someNode) + compare(TestSettings.listNode[0].someNode.deepChild, 22); + compare(TestSettings.listNode[0].someNode.deepParent, "___"); + verify(TestSettings.listNode[0].someNode.deepParentGroup) + compare(TestSettings.listNode[0].someNode.deepParentGroup.simpleChild, true); + compare(TestSettings.listNode[0].childList.length, 0); + + ready = true; + deepData = 0; + TestSettings.listNode[0].someNode.deepChild = 99; + compare(TestSettings.listNode[0].someNode.deepChild, 99); + compare(deepData, 99); + deepData = 0; + + compare(TestSettings.listNode.length, 1); + var newEntry = TestSettings.listNode_push(); + verify(newEntry); + compare(TestSettings.listNode.length, 2); + compare(TestSettings.listNode[1], newEntry); + compare(newEntry.simpleChild, false); + compare(TestSettings.listNode[1].simpleChild, false); + newEntry.simpleChild = true; + compare(newEntry.simpleChild, true); + compare(TestSettings.listNode[1].simpleChild, true); + compare(TestSettings.listNode[0].simpleChild, false); - // test appending - var elem = listElement.createObject(root, {value: "baum42"}); - verify(elem); - compare(elem.value, "baum42"); - TestSettings.listEntry.push(elem); - compare(TestSettings.listEntry.length, 4); - verify(TestSettings.listEntry[3]); - compare(TestSettings.listEntry[3].value, "baum42"); - verify(!TestSettings.listEntry[4]); + var newEntry2 = TestSettings.listNode_push_deferred(); + verify(newEntry2); + compare(TestSettings.listNode.length, 2); + verify(!TestSettings.listNode[2]); + compare(newEntry2.simpleChild, false); + newEntry2.simpleChild = true; + compare(newEntry2.simpleChild, true); + compare(TestSettings.listNode[0].simpleChild, false); + compare(TestSettings.listNode.length, 2); + TestSettings.listNode.push(newEntry2); + compare(TestSettings.listNode.length, 3); + compare(TestSettings.listNode[2], newEntry2); + compare(deepData, 0); - // test resetting - var elem2 = TestSettings.create_listEntry_element("newElem"); - verify(elem2); - compare(elem2.value, "newElem"); - TestSettings.listEntry = [elem2] - compare(TestSettings.listEntry.length, 1); - verify(TestSettings.listEntry[0]); - compare(TestSettings.listEntry[0].value, "newElem"); - verify(!TestSettings.listEntry[1]); + TestSettings.listNode = []; + compare(TestSettings.listNode.length, 0); + verify(!TestSettings.listNode[0]); } } diff --git a/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qmlc b/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qmlc index 6d97e5f..3be7102 100644 Binary files a/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qmlc and b/tests/auto/qml/qmlsettingsgenerator/tst_qmlsettingsgenerator.qmlc differ diff --git a/tools/settingsgenerator/qmlsettingsgenerator.cpp b/tools/settingsgenerator/qmlsettingsgenerator.cpp index 5d60e16..b336054 100644 --- a/tools/settingsgenerator/qmlsettingsgenerator.cpp +++ b/tools/settingsgenerator/qmlsettingsgenerator.cpp @@ -23,14 +23,12 @@ void QmlSettingsGenerator::process(const QString &inPath) if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) throw FileException{_hdrFile}; - _listTypes.clear(); auto typeNum = writeHeader(settings, QFileInfo{inPath}.completeBaseName() + QStringLiteral(".h")); _hdrFile.close(); if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) throw FileException{_srcFile}; writeSource(settings, typeNum); - _listTypes.clear(); _srcFile.close(); } @@ -71,19 +69,21 @@ int QmlSettingsGenerator::writeHeader(const SettingsType &settings, const QStrin _hdr << "class " << (settings.prefix ? settings.prefix.value() + QLatin1Char(' ') : QString{}) << _name << " : public QObject\n" << "{\n" << "\tQ_OBJECT\n\n" + << "\tusing SelfType = " << _name << ";\n" + << "\t" << _cppName << " *_settings;\n" + << "\tQList _indexMap;\n\n" << "\tQ_PROPERTY(QtMvvm::ISettingsAccessor *accessor READ accessor CONSTANT FINAL)\n\n"; QList> childConstructs; QList listEntries; writeProperties(settings, keyList, childOffsets, listEntries, childConstructs); - _hdr << "\t" << _cppName << " *_settings;\n\n" - << "public:\n" + _hdr << "public:\n" << "\texplicit " << _name << "(" << _cppName << " *settings, QObject *parent = nullptr) : \n" - << "\t\tQObject{parent},\n"; + << "\t\tQObject{parent}\n" + << "\t\t,_settings{settings}\n"; writeMemberInits(keyList, childConstructs); - _hdr << "\t\t_settings{settings}\n" - << "\t{\n"; + _hdr << "\t{\n"; writeEntryPropertySignalConnects(settings, keyList, -1, listEntries); _hdr << "\t}\n\n" << "\texplicit " << _name << "(QObject *parent = nullptr) :\n" @@ -103,109 +103,67 @@ int QmlSettingsGenerator::writeHeader(const SettingsType &settings, const QStrin void QmlSettingsGenerator::writeListTypeBaseClass() { // write the generic variant - _hdr << "template \n" - << "class " << _name << "_ListType : public QObject\n" + _hdr << "template \n" + << "struct " << _name << "_ListData\n" << "{\n" - << "public:\n" - << "\ttemplate \n" - << "\tstruct ListData {\n" - << "\t\tstatic_assert(std::is_base_of<" << _name << "_ListType, TList>::value, \"TList must extend " << _name << "_ListType\");\n" - << "\t\tQtMvvm::SettingsListEntry &entry;\n" - << "\t\tQList elements;\n" - << "\t};\n\n" - << "\t" << _name << "_ListType(QObject *parent) : \n" - << "\t\tQObject{parent}\n" - << "\t{}\n" - << "\tT value() const { return _entry ? _entry->getAt(_index) : _buffer; }\n" - << "\tvoid setValue(const T &value) { if(_entry) _entry->setAt(_index, value); else { _index = -2; _buffer = value; } }\n\n" + << "\tTNodeValue &node;\n" + << "\tQList elements;\n\n" - << "\ttemplate \n" - << "\tstatic void adjust(ListData *data, QObject *parent, int size) {\n" + << "\tstatic void adjust(" << _name << "_ListData *data, QObject *parent, int size) {\n" << "\t\twhile(data->elements.size() > size)\n" << "\t\t\tdata->elements.takeLast()->deleteLater();\n" - << "\t\tfor(auto index = data->elements.size(); index < size; index++) {\n" - << "\t\t\tauto elem = new TList{parent};\n" - << "\t\t\telem->_index = index;\n" - << "\t\t\telem->_entry = &data->entry;\n" - << "\t\t\tdata->elements.append(elem);\n" - << "\t\t\tdata->entry.addChangeCallback(elem, [index, elem](int i, const T &d) {\n" - << "\t\t\t\tif(i == index)\n" - << "\t\t\t\t\temit elem->valueChanged(d);\n" - << "\t\t\t});\n" - << "\t\t}\n" + << "\t\tfor(auto index = data->elements.size(); index < size; index++)\n" + << "\t\t\tdata->elements.append(new TList{static_cast(parent)->_settings, static_cast(parent)->_indexMap, index, parent});\n" << "\t}\n\n" - << "\ttemplate \n" << "\tstatic void append(QQmlListProperty *list, TList *element) {\n" - << "\t\tconst auto data = reinterpret_cast*>(list->data);\n" - << "\t\tconst auto maxIndex = data->entry.size();\n" - << "\t\tadjust(data, list->object, maxIndex);\n" + << "\t\tconst auto data = reinterpret_cast<" << _name << "_ListData*>(list->data);\n" + << "\t\tconst auto maxIndex = data->node.size();\n" + << "\t\tadjust(data, list->object, maxIndex);\n" << "\t\telement->setParent(list->object);\n" - << "\t\tconst auto copyDefault = element->_index == -2;\n" - << "\t\telement->_index = maxIndex;\n" - << "\t\telement->_entry = &data->entry;\n" << "\t\tdata->elements.append(element);\n" - << "\t\tif(copyDefault)\n" - << "\t\t\tdata->entry.push(T{std::move(element->_buffer)});\n" - << "\t\telse\n" - << "\t\t\tdata->entry.push(T{});\n" - << "\t\tdata->entry.addChangeCallback(element, [maxIndex, element](int i, const T &d) {\n" - << "\t\t\tif(i == maxIndex)\n" - << "\t\t\t\temit element->valueChanged(d);\n" - << "\t\t});\n" + << "\t\tdata->node.commit(maxIndex);\n" << "\t}\n\n" - << "\ttemplate \n" << "\tstatic TList *at(QQmlListProperty *list, int index) {\n" - << "\t\tconst auto data = reinterpret_cast*>(list->data);\n" + << "\t\tconst auto data = reinterpret_cast<" << _name << "_ListData*>(list->data);\n" << "\t\treturn data->elements.size() > index ? data->elements.value(index) : nullptr;\n" << "\t}\n\n" - << "\ttemplate \n" << "\tstatic int count(QQmlListProperty *list) {\n" - << "\t\treturn reinterpret_cast*>(list->data)->elements.size();\n" + << "\t\treturn reinterpret_cast<" << _name << "_ListData*>(list->data)->elements.size();\n" << "\t}\n\n" - << "\ttemplate \n" << "\tstatic void clear(QQmlListProperty *list) {\n" - << "\t\tconst auto data = reinterpret_cast*>(list->data);\n" + << "\t\tconst auto data = reinterpret_cast<" << _name << "_ListData*>(list->data);\n" << "\t\tfor(auto elem : qAsConst(data->elements))\n" << "\t\t\telem->deleteLater();\n" << "\t\tdata->elements.clear();\n" - << "\t\tdata->entry.reset(false);\n" + << "\t\tdata->node.reset();\n" << "\t}\n\n" - << "private:\n" - << "\tQtMvvm::SettingsListEntry *_entry = nullptr;\n" - << "\tint _index = -1;\n" - << "\tT _buffer{};\n" << "};\n\n"; } -std::tuple> QmlSettingsGenerator::writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset) +std::tuple> QmlSettingsGenerator::writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset, int listDepth) { QList offsetList; for(const auto &cNode : node.contentNodes) { if(nonstd::holds_alternative(cNode)) { - offset = writeNodeClass(nonstd::get(cNode), keyList, offset); + offset = writeNodeClass(nonstd::get(cNode), keyList, offset, listDepth); offsetList.append(offset - 1); } else if(nonstd::holds_alternative(cNode)) { if(!nonstd::get(cNode).contentNodes.isEmpty()) { - offset = writeNodeClass(nonstd::get(cNode), keyList, offset); - offsetList.append(offset - 1); - } else - offsetList.append(-1); - } else if(nonstd::holds_alternative(cNode)) { - offset = writeListEntryElementClass(nonstd::get(cNode), keyList, offset); - offsetList.append(offset - 1); //double offset!!! - if(!nonstd::get(cNode).contentNodes.isEmpty()) { - offset = writeNodeClass(nonstd::get(cNode), keyList, offset); + offset = writeNodeClass(nonstd::get(cNode), keyList, offset, listDepth); offsetList.append(offset - 1); } else offsetList.append(-1); + } else if(nonstd::holds_alternative(cNode)) { + offset = writeListNodeClass(nonstd::get(cNode), keyList, offset, listDepth); + offsetList.append(offset - 1); } else if(nonstd::holds_alternative(cNode)) { QList subList; - std::tie(offset, subList) = writeNodeContentClasses(nonstd::get(cNode), keyList, offset); + std::tie(offset, subList) = writeNodeContentClasses(nonstd::get(cNode), keyList, offset, listDepth); offsetList.append(subList); } else Q_UNREACHABLE(); @@ -213,27 +171,30 @@ std::tuple> QmlSettingsGenerator::writeNodeContentClasses(const return std::make_tuple(offset, offsetList); } -int QmlSettingsGenerator::writeNodeClass(const NodeType &node, QStringList keyList, int offset) +int QmlSettingsGenerator::writeNodeClass(const NodeType &node, QStringList keyList, int offset, int listDepth) { keyList.append(node.key); QList childOffsets; - std::tie(offset, childOffsets) = writeNodeContentClasses(node, keyList, offset); + std::tie(offset, childOffsets) = writeNodeContentClasses(node, keyList, offset, listDepth); _hdr << "class " << _name << "_" << offset << " : public QObject // " << keyList.join(QLatin1Char('/')) << "\n" << "{\n" - << "\tQ_OBJECT\n\n"; + << "\tQ_OBJECT\n\n" + << "\tusing SelfType = " << _name << "_" << offset << ";\n" + << "\t" << _cppName << " *_settings;\n" + << "\tconst QList &_indexMap;\n\n"; QList> childConstructs; QList listEntries; writeProperties(node, keyList, childOffsets, listEntries, childConstructs); - _hdr << "\t" << _cppName << " *_settings;\n\n" - << "public:\n" - << "\t" << _name << "_" << offset << "(" << _cppName << " *settings, QObject *parent) : \n" - << "\t\tQObject{parent},\n"; + _hdr << "public:\n" + << "\t" << _name << "_" << offset << "(" << _cppName << " *settings, const QList &indexMap, QObject *parent) : \n" + << "\t\tQObject{parent}\n" + << "\t\t,_settings{settings}\n" + << "\t\t,_indexMap{indexMap}\n"; writeMemberInits(keyList, childConstructs); - _hdr << "\t\t_settings{settings}\n" - << "\t{\n"; + _hdr << "\t{\n"; writeEntryPropertySignalConnects(node, keyList, offset, listEntries); _hdr << "\t}\n" << "};\n\n"; @@ -241,25 +202,32 @@ int QmlSettingsGenerator::writeNodeClass(const NodeType &node, QStringList keyLi return ++offset; } -int QmlSettingsGenerator::writeListEntryElementClass(const ListEntryType &entry, QStringList keyList, int offset) +int QmlSettingsGenerator::writeListNodeClass(const ListNodeType &node, QStringList keyList, int offset, int listDepth) { - keyList.append(entry.key); - const auto &mType = _typeMappings.value(entry.type, entry.type); - _hdr << "class " << _name << "_" << offset << " : public " << _name << "_ListType<" << mType << "> // " << keyList.join(QLatin1Char('/')) << " (list-element)\n" + keyList.append({node.key, QStringLiteral("at(_indexMap.at(%1))").arg(listDepth++)}); + QList childOffsets; + std::tie(offset, childOffsets) = writeNodeContentClasses(node, keyList, offset, listDepth); + + _hdr << "class " << _name << "_" << offset << " : public QObject // " << keyList.join(QLatin1Char('/')) << "\n" << "{\n" << "\tQ_OBJECT\n\n" - << "\tQ_PROPERTY(" << mType << " value READ value WRITE setValue NOTIFY valueChanged)\n\n" - << "public:\n" - << "\texplicit " << _name << "_" << offset << "(QObject *parent = nullptr) : \n" - << "\t\t" << _name << "_ListType{parent}\n" - << "\t{}\n\n" - << "\texplicit " << _name << "_" << offset << "(const " << mType << " &value, QObject *parent = nullptr) : \n" - << "\t\t" << _name << "_" << offset << "{parent}\n" - << "\t{\n" - << "\t\tsetValue(value);\n" - << "\t}\n\n" - << "Q_SIGNALS:\n" - << "\tvoid valueChanged(const " << mType << " &value);\n" + << "\tusing SelfType = " << _name << "_" << offset << ";\n" + << "\t" << _cppName << " *_settings;\n" + << "\tQList _indexMap;\n\n"; + + QList> childConstructs; + QList listEntries; + writeProperties(node, keyList, childOffsets, listEntries, childConstructs); + + _hdr << "public:\n" + << "\t" << _name << "_" << offset << "(" << _cppName << " *settings, const QList &indexMap, int index, QObject *parent) : \n" + << "\t\tQObject{parent}\n" + << "\t\t,_settings{settings}\n" + << "\t\t,_indexMap{QList{indexMap} << index}\n"; + writeMemberInits(keyList, childConstructs); + _hdr << "\t{\n"; + writeEntryPropertySignalConnects(node, keyList, offset, listEntries); + _hdr << "\t}\n" << "};\n\n"; return ++offset; @@ -272,11 +240,9 @@ void QmlSettingsGenerator::writeProperties(const NodeContentGroup &node, const Q writeNodeProperty(nonstd::get(cNode), childOffsets.takeFirst(), childConstructs); else if(nonstd::holds_alternative(cNode)) writeEntryProperty(nonstd::get(cNode), keyList, childOffsets.takeFirst(), childConstructs); - else if(nonstd::holds_alternative(cNode)) { - auto lIndex = childOffsets.takeFirst(); //done seperately because of undefine param call order - writeListEntryProperty(nonstd::get(cNode), keyList, lIndex, childOffsets.takeFirst(), childConstructs); - listEntries.append(lIndex); - _listTypes.insert(lIndex); + else if(nonstd::holds_alternative(cNode)) { + listEntries.append(childOffsets.first()); + writeListNodeProperty(nonstd::get(cNode), keyList, childOffsets.takeFirst(), childConstructs); } else if(nonstd::holds_alternative(cNode)) writeProperties(nonstd::get(cNode), keyList, childOffsets, listEntries, childConstructs); else @@ -301,12 +267,12 @@ void QmlSettingsGenerator::writeEntryProperty(const EntryType &entry, QStringLis _hdr << "\tQ_PROPERTY(" << mType << " " << entry.key << " READ get_" << entry.key << " WRITE set_" << entry.key - << " NOTIFY " << entry.key << "_changed)\n"; + << " NOTIFY " << entry.key << "Changed)\n"; _hdr << "\t" << mType << " get_" << entry.key << "() const { return _settings->" << keyList.join(QLatin1Char('.')) << ".get(); }\n" << "\tvoid set_" << entry.key << "(const " << mType << " &value) { _settings->" << keyList.join(QLatin1Char('.')) << ".set(value); }\n" << "Q_SIGNALS:\n" - << "\tvoid " << entry.key << "_changed(const " << mType << " &value);\n" + << "\tvoid " << entry.key << "Changed(const " << mType << " &value);\n" << "private:\n\n"; } @@ -314,40 +280,45 @@ void QmlSettingsGenerator::writeEntryProperty(const EntryType &entry, QStringLis writeNodeProperty(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group"))); } -void QmlSettingsGenerator::writeListEntryProperty(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList> &childConstructs) +void QmlSettingsGenerator::writeListNodeProperty(const ListNodeType &node, QStringList keyList, int classIndex, QList> &childConstructs) { - keyList.append(entry.key); - _hdr << "\tQ_PROPERTY(QQmlListProperty<" << _name << "_" << listIndex << "> " << entry.key - << " READ get_" << entry.key << " CONSTANT)\n" - << "\t" << _name << "_" << listIndex << "::ListData<" << _name << "_" << listIndex << "> _" << entry.key << ";\n" - << "\tQQmlListProperty<" << _name << "_" << listIndex << "> get_" << entry.key << "() {\n" + keyList.append(node.key); + _hdr << "\tusing ListData_" << classIndex << " = " << _name << "_ListData<" << _name << "_" << classIndex << ", SelfType, typename std::decay" << keyList.join(QLatin1Char('.')) << ")>::type>;\n" + << "\tfriend ListData_" << classIndex << ";\n" + << "\tQ_PROPERTY(QQmlListProperty<" << _name << "_" << classIndex << "> " << node.key + << " READ get_" << node.key << " CONSTANT)\n" + << "\tListData_" << classIndex << " _" << node.key << ";\n" + << "\tQQmlListProperty<" << _name << "_" << classIndex << "> get_" << node.key << "() {\n" << "\t\treturn {\n" - << "\t\t\tthis, &_" << entry.key << ",\n" - << "\t\t\t&" << _name << "_" << listIndex << "::append<" << _name << "_" << listIndex << ">,\n" - << "\t\t\t&" << _name << "_" << listIndex << "::count<" << _name << "_" << listIndex << ">,\n" - << "\t\t\t&" << _name << "_" << listIndex << "::at<" << _name << "_" << listIndex << ">,\n" - << "\t\t\t&" << _name << "_" << listIndex << "::clear<" << _name << "_" << listIndex << ">\n" + << "\t\t\tthis, &_" << node.key << ",\n" + << "\t\t\t&ListData_" << classIndex << "::append,\n" + << "\t\t\t&ListData_" << classIndex << "::count,\n" + << "\t\t\t&ListData_" << classIndex << "::at,\n" + << "\t\t\t&ListData_" << classIndex << "::clear\n" << "\t\t};\n" << "\t}\n" << "public:\n" - << "\tQ_INVOKABLE " << _name << "_" << listIndex << " *create_" << entry.key << "_element(const " << _typeMappings.value(entry.type, entry.type) << " &value) {\n" - << "\t\treturn new " << _name << "_" << listIndex << "{value, this};\n" + << "\tQ_INVOKABLE " << _name << "_" << classIndex << " *" << node.key << "_push_deferred() {\n" + << "\t\treturn new " << _name << "_" << classIndex << "{_settings, _indexMap, _" << node.key << ".node.size(), this};\n" + << "\t}\n" + << "\tQ_INVOKABLE " << _name << "_" << classIndex << " *" << node.key << "_push() {\n" + << "\t\tauto data = " << node.key << "_push_deferred();\n" + << "\t\tauto qmlList = get_" << node.key << "();\n" + << "\t\tListData_" << classIndex << "::append(&qmlList, data);\n" + << "\t\treturn data;\n" << "\t}\n" << "private:\n\n"; - childConstructs.append({entry.key, -1}); - - if(!entry.contentNodes.isEmpty()) - writeNodeProperty(entry, classIndex, childConstructs, entry.qmlGroupKey.value_or(entry.key + QStringLiteral("Group"))); + childConstructs.append({node.key, -1}); } void QmlSettingsGenerator::writeMemberInits(const QStringList &keyList, const QList> &childConstructs) { for(const auto &info : childConstructs) { if(info.second < 0) - _hdr << "\t\t_" << info.first << "{settings->" << (QStringList{keyList} << info.first).join(QLatin1Char('.')) << ", {}},\n"; + _hdr << "\t\t,_" << info.first << "{_settings->" << (QStringList{keyList} << info.first).join(QLatin1Char('.')) << ", {}}\n"; else - _hdr << "\t\t_" << info.first << "{new " << _name << "_" << info.second << "{settings, this}},\n"; + _hdr << "\t\t,_" << info.first << "{new " << _name << "_" << info.second << "{_settings, _indexMap, this}}\n"; } } @@ -358,8 +329,8 @@ void QmlSettingsGenerator::writeEntryPropertySignalConnects(const NodeContentGro continue; //nothing to be set else if(nonstd::holds_alternative(cNode)) writeEntryPropertySignalConnect(nonstd::get(cNode), keyList, classIndex); - else if(nonstd::holds_alternative(cNode)) - writeListEntryPropertySignalConnect(nonstd::get(cNode), keyList, listEntries); + else if(nonstd::holds_alternative(cNode)) + writeListNodePropertySignalConnect(nonstd::get(cNode), keyList, listEntries); else if(nonstd::holds_alternative(cNode)) writeEntryPropertySignalConnects(nonstd::get(cNode), keyList, classIndex, listEntries); else @@ -376,19 +347,18 @@ void QmlSettingsGenerator::writeEntryPropertySignalConnect(const EntryType &entr << ".addChangeCallback(this, std::bind(&" << _name; if(classIndex >= 0) _hdr << "_" << classIndex; - _hdr << "::" << entry.key << "_changed, this, std::placeholders::_1));\n"; + _hdr << "::" << entry.key << "Changed, this, std::placeholders::_1));\n"; } -void QmlSettingsGenerator::writeListEntryPropertySignalConnect(const SettingsGeneratorBase::ListEntryType &entry, QStringList keyList, QList &listEntries) +void QmlSettingsGenerator::writeListNodePropertySignalConnect(const ListNodeType &entry, QStringList keyList, QList &listEntries) { auto classIndex = listEntries.takeFirst(); keyList.append(entry.key); _hdr << "\t\t_settings->" << keyList.join(QLatin1Char('.')) - << ".addSizeChangeCallback(this, std::bind(&" - << _name << "_" << classIndex << "::adjust<" << _name << "_" << classIndex - << ">, &_" << entry.key << ", this, std::placeholders::_1));\n" - << "\t\t"<< _name << "_" << classIndex << "::adjust<" << _name << "_" << classIndex - << ">(&_" << entry.key << ", this, _settings->" << keyList.join(QLatin1Char('.')) << ".size());\n"; + << ".addChangeCallback(this, std::bind(&" + << "ListData_" << classIndex << "::adjust, &_" << entry.key << ", this, std::placeholders::_1));\n" + << "\t\t" << "ListData_" << classIndex << "::adjust" + << "(&_" << entry.key << ", this, _settings->" << keyList.join(QLatin1Char('.')) << ".size());\n"; } void QmlSettingsGenerator::writeSource(const SettingsType &settings, int typeNum) @@ -432,12 +402,9 @@ void QmlSettingsGenerator::writeQmlRegistration(QmlRegistrationMode mode, int ty _src << "void " << _name << "::registerQmlTypes(const char *uri, int major, int minor)\n" << "{\n" << "\tconst QString msg{QStringLiteral(\"Settings-Helpertypes cannot be created\")};\n\n"; - for(auto i = 0; i < typeNum; i++) { - if(_listTypes.contains(i)) - _src << "\tqmlRegisterType<" << _name << "_" << i << ">(uri, major, minor, \"" << _cppName << "_ListElement_" << i << "\");\n"; - else - _src << "\tqmlRegisterUncreatableType<" << _name << "_" << i << ">(uri, major, minor, \"" << _name << "_" << i << "\", msg);\n"; - } + for(auto i = 0; i < typeNum; i++) + _src << "\tqmlRegisterUncreatableType<" << _name << "_" << i << ">(uri, major, minor, \"" << _name << "_" << i << "\", msg);\n"; + switch(mode) { case Singleton: _src << "\n\tqmlRegisterSingletonType<" << _name << ">(uri, major, minor, \"" << _cppName << "\", __create_qml_singleton);\n"; diff --git a/tools/settingsgenerator/qmlsettingsgenerator.h b/tools/settingsgenerator/qmlsettingsgenerator.h index c2388dd..72e17fc 100644 --- a/tools/settingsgenerator/qmlsettingsgenerator.h +++ b/tools/settingsgenerator/qmlsettingsgenerator.h @@ -25,15 +25,13 @@ private: QString _prefixName; QHash _typeMappings; - QSet _listTypes; - int writeHeader(const SettingsType &settings, const QString &inHdrPath); void writeListTypeBaseClass(); - std::tuple> writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset = 0); - int writeNodeClass(const NodeType &node, QStringList keyList, int offset); - int writeListEntryElementClass(const ListEntryType &entry, QStringList keyList, int offset); + std::tuple> writeNodeContentClasses(const NodeContentGroup &node, const QStringList &keyList, int offset = 0, int listDepth = 0); + int writeNodeClass(const NodeType &node, QStringList keyList, int offset, int listDepth); + int writeListNodeClass(const ListNodeType &entry, QStringList keyList, int offset, int listDepth); void writeProperties(const NodeContentGroup &node, const QStringList &keyList, @@ -42,12 +40,12 @@ private: QList> &childConstructs); void writeNodeProperty(const NodeType &entry, int classIndex, QList> &childConstructs, const QString &overwriteName = {}); void writeEntryProperty(const EntryType &entry, QStringList keyList, int classIndex, QList> &childConstructs); - void writeListEntryProperty(const ListEntryType &entry, QStringList keyList, int listIndex, int classIndex, QList> &childConstructs); + void writeListNodeProperty(const ListNodeType &entry, QStringList keyList, int classIndex, QList> &childConstructs); void writeMemberInits(const QStringList &keyList, const QList> &childConstructs); void writeEntryPropertySignalConnects(const NodeContentGroup &node, const QStringList &keyList, int classIndex, QList &listEntries); void writeEntryPropertySignalConnect(const EntryType &entry, QStringList keyList, int classIndex); - void writeListEntryPropertySignalConnect(const ListEntryType &entry, QStringList keyList, QList &listEntries); + void writeListNodePropertySignalConnect(const ListNodeType &entry, QStringList keyList, QList &listEntries); void writeSource(const SettingsType &settings, int typeNum); diff --git a/tools/settingsgenerator/qsettingsgenerator.xsd b/tools/settingsgenerator/qsettingsgenerator.xsd index b8be4cc..8d7ce02 100644 --- a/tools/settingsgenerator/qsettingsgenerator.xsd +++ b/tools/settingsgenerator/qsettingsgenerator.xsd @@ -87,7 +87,6 @@ - @@ -122,16 +121,6 @@ - - - - - - - - - - diff --git a/tools/settingsgenerator/settingsgeneratorimpl.cpp b/tools/settingsgenerator/settingsgeneratorimpl.cpp index d5f1b5b..036e8ad 100644 --- a/tools/settingsgenerator/settingsgeneratorimpl.cpp +++ b/tools/settingsgenerator/settingsgeneratorimpl.cpp @@ -170,12 +170,9 @@ SettingsGeneratorBase::NodeContentGroup *SettingsGeneratorImpl::findContentGroup *isEntry = true; return &(nonstd::get(cNode)); } - } else if(nonstd::holds_alternative(cNode)) { - if(nonstd::get(cNode).key == key) { - if(isEntry) - *isEntry = true; - return &(nonstd::get(cNode)); - } + } else if(nonstd::holds_alternative(cNode)) { + if(nonstd::get(cNode).key == key) + return &(nonstd::get(cNode)); } else if(nonstd::holds_alternative(cNode)) { auto res = findContentGroup(&(nonstd::get(cNode)), key); if(res) @@ -214,11 +211,8 @@ void SettingsGeneratorImpl::fixTrContext(NodeContentGroup &group, const QString if(!entry.trContext) entry.trContext = context; fixTrContext(entry, context); - } else if(nonstd::holds_alternative(node)) { - auto &entry = nonstd::get(node); - if(!entry.trContext) - entry.trContext = context; - fixTrContext(entry, context); + } else if(nonstd::holds_alternative(node)) { + fixTrContext(nonstd::get(node), context); } else if(nonstd::holds_alternative(node)) fixTrContext(nonstd::get(node), context); }