From 90e5ca47480f1eec6cd479a975923f52a14cadac Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 25 Oct 2022 18:06:43 +0300 Subject: QmlDesigner: Fix duplicating materials with dynamic properties Fixes: QDS-8091 Change-Id: I0f9a710214850326d1cda179c1a2aa6332b98510 Reviewed-by: Reviewed-by: Thomas Hartmann Reviewed-by: Tim Jenssen --- .../materialeditor/materialeditorview.cpp | 50 ++++++++++++++++++---- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 9352e200d1..c8c42b2fa9 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -1022,6 +1022,8 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) TypeName matType = material.type(); QmlObjectNode sourceMat(material); + ModelNode duplicateMatNode; + QList dynamicProps; executeInTransaction(__FUNCTION__, [&] { ModelNode matLib = materialLibraryNode(); @@ -1032,25 +1034,57 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) NodeMetaInfo metaInfo = model()->metaInfo(matType); QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); + duplicateMatNode = duplicateMat.modelNode(); + // set name and id QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; - duplicateMat.modelNode().variantProperty("objectName").setValue(newName); - duplicateMat.modelNode().setIdWithoutRefactoring(model()->generateIdFromName(newName, "material")); + duplicateMatNode.variantProperty("objectName").setValue(newName); + duplicateMatNode.setIdWithoutRefactoring(model()->generateIdFromName(newName, "material")); - // sync properties + // sync properties. Only the base state is duplicated. const QList props = material.properties(); for (const AbstractProperty &prop : props) { - if (prop.name() == "objectName") + if (prop.name() == "objectName" || prop.name() == "data") continue; - if (prop.isVariantProperty()) - duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); - else if (prop.isBindingProperty()) - duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); + if (prop.isVariantProperty()) { + if (prop.isDynamic()) { + dynamicProps.append(prop); + } else { + duplicateMatNode.variantProperty(prop.name()) + .setValue(prop.toVariantProperty().value()); + } + } else if (prop.isBindingProperty()) { + if (prop.isDynamic()) { + dynamicProps.append(prop); + } else { + duplicateMatNode.bindingProperty(prop.name()) + .setExpression(prop.toBindingProperty().expression()); + } + } } matLib.defaultNodeListProperty().reparentHere(duplicateMat); }); + + // For some reason, creating dynamic properties in the same transaction doesn't work, so + // let's do it in separate transaction. + // TODO: Fix the issue and merge transactions (QDS-8094) + if (!dynamicProps.isEmpty()) { + executeInTransaction(__FUNCTION__, [&] { + for (const AbstractProperty &prop : std::as_const(dynamicProps)) { + if (prop.isVariantProperty()) { + duplicateMatNode.variantProperty(prop.name()) + .setDynamicTypeNameAndValue(prop.dynamicTypeName(), + prop.toVariantProperty().value()); + } else if (prop.isBindingProperty()) { + duplicateMatNode.bindingProperty(prop.name()) + .setDynamicTypeNameAndExpression(prop.dynamicTypeName(), + prop.toBindingProperty().expression()); + } + } + }); + } } void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier, -- cgit v1.2.3