From cc1bf95dc2d14d4fdce32bb87938108e55c5e63c Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 22 Jun 2022 14:46:27 +0300 Subject: [PATCH] QmlDesigner: Ensure material lib node exists on project launch In this commit material library node is created on model attach. A timer keeps monitoring until it is suitable to create the node. This will properly move materials into material library for projects created with previous QDS versions. Also removed unnecessary handling on new material dragging, as rewriter now works properly with material library creation. Fixes: QDS-7178 Change-Id: Idf6f41906e02bc064961d8de9841ba1644bd3552 Reviewed-by: Thomas Hartmann --- .../materialeditor/materialeditorview.cpp | 7 ++- .../navigator/navigatortreemodel.cpp | 11 ----- .../designercore/include/abstractview.h | 1 + .../designercore/model/abstractview.cpp | 45 +++++++++++-------- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 49cebb3dd4b..7ab7cc090c5 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -74,8 +74,11 @@ MaterialEditorView::MaterialEditorView(QWidget *parent) connect(m_updateShortcut, &QShortcut::activated, this, &MaterialEditorView::reloadQml); m_ensureMatLibTimer.callOnTimeout([this] { - if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation()) { - materialLibraryNode(); // create the material library node + if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation() + && model()->rewriterView()->errors().isEmpty()) { + executeInTransaction("MaterialEditorView::MaterialEditorView", [this] { + ensureMaterialLibraryNode(); + }); m_ensureMatLibTimer.stop(); } }); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index d610014d5bf..38c32f65cd8 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -697,17 +697,6 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in newQmlObjectNode.destroy(); return; } - // We can't have material initially parented if material library is created in this - // same transaction (rewriter will not allow it for some reason) - ModelNode matLib = m_view->modelNodeForId(Constants::MATERIAL_LIB_ID); - if (!matLib.isValid()) { - newQmlObjectNode.destroy(); - newQmlObjectNode = QmlItemNode::createQmlObjectNode( - m_view, itemLibraryEntry, QPointF(), NodeAbstractProperty(), false); - newModelNode = newQmlObjectNode.modelNode(); - if (!newModelNode.isValid()) - return; - } m_view->assignMaterialTo3dModel(targetNode, newModelNode); } diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 18380aadb1a..2eecf8df5aa 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -259,6 +259,7 @@ public: void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); + void ensureMaterialLibraryNode(); ModelNode materialLibraryNode(); void assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode = {}); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 86dab970316..6826c9ed4dd 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -809,16 +809,14 @@ void AbstractView::changeRootNodeType(const TypeName &type, int majorVersion, in m_model.data()->d->changeRootNodeType(type, majorVersion, minorVersion); } -// Returns ModelNode for project's material library. -// If the material library doesn't exist yet, it is created and all existing materials are moved -// under material library. -// This function should be called only form inside a transaction, as it potentially does many -// changes to model. -ModelNode AbstractView::materialLibraryNode() +// Creates material library if it doesn't exist and moves any existing materials into it +// This function should be called only from inside a transaction, as it potentially does many +// changes to model, or undo stack should be cleared after the call. +void AbstractView::ensureMaterialLibraryNode() { ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); if (matLib.isValid()) - return matLib; + return; // Create material library node TypeName nodeType = rootModelNode().isSubclassOf("QtQuick3D.Node") ? "QtQuick3D.Node" @@ -830,20 +828,28 @@ ModelNode AbstractView::materialLibraryNode() rootModelNode().defaultNodeListProperty().reparentHere(matLib); const QList materials = rootModelNode().subModelNodesOfType("QtQuick3D.Material"); - if (materials.isEmpty()) - return matLib; + if (!materials.isEmpty()) { + // Move all materials to under material library node + for (const ModelNode &node : materials) { + // If material has no name, set name to id + QString matName = node.variantProperty("objectName").value().toString(); + if (matName.isEmpty()) { + VariantProperty objNameProp = node.variantProperty("objectName"); + objNameProp.setValue(node.id()); + } - // Move all materials to under material library node - for (const ModelNode &node : materials) { - // If material has no name, set name to id - QString matName = node.variantProperty("objectName").value().toString(); - if (matName.isEmpty()) { - VariantProperty objNameProp = node.variantProperty("objectName"); - objNameProp.setValue(node.id()); + matLib.defaultNodeListProperty().reparentHere(node); } - - matLib.defaultNodeListProperty().reparentHere(node); } +} + +// Returns ModelNode for project's material library. +ModelNode AbstractView::materialLibraryNode() +{ + ensureMaterialLibraryNode(); + + ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); + QTC_ASSERT(matLib.isValid(), return {}); return matLib; } @@ -859,6 +865,9 @@ void AbstractView::assignMaterialTo3dModel(const ModelNode &modelNode, const Mod QTC_ASSERT(modelNode.isValid() && modelNode.isSubclassOf("QtQuick3D.Model"), return); ModelNode matLib = materialLibraryNode(); + + QTC_ASSERT(matLib.isValid(), return); + ModelNode newMaterialNode; if (materialNode.isValid() && materialNode.isSubclassOf("QtQuick3D.Material")) {