diff options
author | Dominik Holland <dominik.holland@qt.io> | 2019-12-09 10:22:31 +0100 |
---|---|---|
committer | Dominik Holland <dominik.holland@qt.io> | 2019-12-09 19:31:30 +0100 |
commit | af67d98291f65d7b200d5d603c728f857dba0376 (patch) | |
tree | 90e6e4e36a554fcf9f96dadd660d93697a2ed584 | |
parent | ab481603236b658bbb7e71231deec40554a9684a (diff) |
Fix creation of structs from simulationData
Due to a change in QtCore, it is not possible to call
QMetaObject::newInstance() on Q_GADGETS anymore.
Because of this, creating qface based structs from
simulationData resulted in the error:
QMetaObject::newInstance: type Contact does not inherit QObject
This commit changes the way how the structs are created
and is using QMetaType::create() instead and instead
of using a constructor taking a QVariant, it invokes a private
fromJSON() function, which now gets generated instead of
the QVariant constructor.
Fixes: AUTOSUITE-1374
Change-Id: Ibef59fcc0a209de3d98f055eaed4e4c04521575f
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r-- | src/ivicore/qiviqmlconversion_helper.cpp | 22 | ||||
-rw-r--r-- | src/tools/ivigenerator/templates_frontend/struct.cpp.tpl | 49 | ||||
-rw-r--r-- | src/tools/ivigenerator/templates_frontend/struct.h.tpl | 10 |
3 files changed, 51 insertions, 30 deletions
diff --git a/src/ivicore/qiviqmlconversion_helper.cpp b/src/ivicore/qiviqmlconversion_helper.cpp index 97c71b0..8745e31 100644 --- a/src/ivicore/qiviqmlconversion_helper.cpp +++ b/src/ivicore/qiviqmlconversion_helper.cpp @@ -144,7 +144,27 @@ QVariant qtivi_convertFromJSON(const QVariant &value) for (auto i = values.begin(); i != values.end(); ++i) *i = qtivi_convertFromJSON(*i); - void *gadget = mo->newInstance(Q_ARG(QVariant, QVariant(values))); + void *gadget = QMetaType::create(typeId); + if (!gadget) { + qWarning("Couldn't create a new instance of %s", QMetaType::typeName(typeId)); + return QVariant(); + } + + /* Left here for debugging + for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) + qDebug() << mo->method(i).methodSignature(); + */ + + int moIdx = mo->indexOfMethod("fromJSON(QVariant)"); + if (moIdx == -1) { + qWarning("Couldn't find method: %s::fromJSON(QVariant)\n" + "If your are using code created by the ivigenerator, please regenerate" + "your frontend code. See AUTOSUITE-1374 for why this is needed", + QMetaType::typeName(typeId)); + return QVariant(); + } + + mo->method(moIdx).invokeOnGadget(gadget, Q_ARG(QVariant, QVariant(values))); return QVariant(typeId, gadget); } } diff --git a/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl b/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl index de1715b..c67dbe2 100644 --- a/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl +++ b/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl @@ -109,31 +109,6 @@ public: { } -{{class}}::{{class}}(const QVariant &variant) - : {{class}}() -{ - QVariant value = qtivi_convertFromJSON(variant); - // First try to convert the values to a Map or a List - // This is needed as it could also store a QStringList or a Hash - if (value.canConvert(QVariant::Map)) - value.convert(QVariant::Map); - if (value.canConvert(QVariant::List)) - value.convert(QVariant::List); - - if (value.type() == QVariant::Map) { - QVariantMap map = value.toMap(); -{% for field in struct.fields %} - if (map.contains(QStringLiteral("{{field}}"))) - d->m_{{field}} = map.value(QStringLiteral("{{field}}")).value<{{field|return_type}}>(); -{% endfor %} - } else if (value.type() == QVariant::List) { - QVariantList values = value.toList(); -{% for field in struct.fields %} - d->m_{{field}} = values.value({{loop.index0}}).value<{{field|return_type}}>(); -{% endfor %} - } -} - /*! \internal */ {{class}}::~{{class}}() { @@ -167,6 +142,30 @@ QString {{class}}::type() const {% endfor %} +void {{class}}::fromJSON(const QVariant &variant) +{ + QVariant value = qtivi_convertFromJSON(variant); + // First try to convert the values to a Map or a List + // This is needed as it could also store a QStringList or a Hash + if (value.canConvert(QVariant::Map)) + value.convert(QVariant::Map); + if (value.canConvert(QVariant::List)) + value.convert(QVariant::List); + + if (value.type() == QVariant::Map) { + QVariantMap map = value.toMap(); +{% for field in struct.fields %} + if (map.contains(QStringLiteral("{{field}}"))) + d->m_{{field}} = map.value(QStringLiteral("{{field}}")).value<{{field|return_type}}>(); +{% endfor %} + } else if (value.type() == QVariant::List) { + QVariantList values = value.toList(); +{% for field in struct.fields %} + d->m_{{field}} = values.value({{loop.index0}}).value<{{field|return_type}}>(); +{% endfor %} + } +} + bool operator==(const {{class}} &left, const {{class}} &right) Q_DECL_NOTHROW { if (left.d == right.d) diff --git a/src/tools/ivigenerator/templates_frontend/struct.h.tpl b/src/tools/ivigenerator/templates_frontend/struct.h.tpl index 6e99119..1e266e4 100644 --- a/src/tools/ivigenerator/templates_frontend/struct.h.tpl +++ b/src/tools/ivigenerator/templates_frontend/struct.h.tpl @@ -73,11 +73,10 @@ class {{exportsymbol}} {{class}} : public QIviStandardItem Q_CLASSINFO("IviPropertyDomains", "{{ struct.fields|json_domain|replace("\"", "\\\"") }}") public: - Q_INVOKABLE {{class}}(); - Q_INVOKABLE {{class}}(const {{class}} &rhs); + {{class}}(); + {{class}}(const {{class}} &rhs); {{class}} &operator=(const {{class}} &); - Q_INVOKABLE {{class}}({{struct.fields|map('parameter_type')|join(', ')}}); - Q_INVOKABLE {{class}}(const QVariant &variant); + {{class}}({{struct.fields|map('parameter_type')|join(', ')}}); ~{{class}}(); QString type() const override; @@ -97,6 +96,9 @@ public: {% endif %} {% endfor %} +protected: + Q_INVOKABLE void fromJSON(const QVariant &variant); + private: QSharedDataPointer<{{class}}Private> d; friend {{exportsymbol}} bool operator==(const {{class}} &left, const {{class}} &right) Q_DECL_NOTHROW; |