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")) {