QmlDesigner: Fix duplicating materials with dynamic properties

Fixes: QDS-8091
Change-Id: I0f9a710214850326d1cda179c1a2aa6332b98510
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Miikka Heikkinen
2022-10-25 18:06:43 +03:00
parent 565bb8052f
commit 90e5ca4748

View File

@@ -1022,6 +1022,8 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material)
TypeName matType = material.type(); TypeName matType = material.type();
QmlObjectNode sourceMat(material); QmlObjectNode sourceMat(material);
ModelNode duplicateMatNode;
QList<AbstractProperty> dynamicProps;
executeInTransaction(__FUNCTION__, [&] { executeInTransaction(__FUNCTION__, [&] {
ModelNode matLib = materialLibraryNode(); ModelNode matLib = materialLibraryNode();
@@ -1032,25 +1034,57 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material)
NodeMetaInfo metaInfo = model()->metaInfo(matType); NodeMetaInfo metaInfo = model()->metaInfo(matType);
QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion());
duplicateMatNode = duplicateMat.modelNode();
// set name and id // set name and id
QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy";
duplicateMat.modelNode().variantProperty("objectName").setValue(newName); duplicateMatNode.variantProperty("objectName").setValue(newName);
duplicateMat.modelNode().setIdWithoutRefactoring(model()->generateIdFromName(newName, "material")); duplicateMatNode.setIdWithoutRefactoring(model()->generateIdFromName(newName, "material"));
// sync properties // sync properties. Only the base state is duplicated.
const QList<AbstractProperty> props = material.properties(); const QList<AbstractProperty> props = material.properties();
for (const AbstractProperty &prop : props) { for (const AbstractProperty &prop : props) {
if (prop.name() == "objectName") if (prop.name() == "objectName" || prop.name() == "data")
continue; continue;
if (prop.isVariantProperty()) if (prop.isVariantProperty()) {
duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); if (prop.isDynamic()) {
else if (prop.isBindingProperty()) dynamicProps.append(prop);
duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); } 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); 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, void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier,