QmlDesigner: Make form view react to node source changes properly

Implicit components lose/gain node source when reparented, so we need
to also potentially remove form editor items based on the node
source state of the node itself in addition to the state of the
parent.

Node source can also change without reparenting, and it's not
guaranteed the node source is up to date when nodeReparented is
called, so to make sure we always end up in correct state in form
editor, we do the same checks in nodeSourceChanged as we do in
nodeReparented.

Fixes: QDS-5230
Change-Id: Ib358ccb0db4c26e4857bad00e35930287c4149fb
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2021-10-07 15:05:10 +03:00
parent 7a76f7edbf
commit 3395cdfd26
2 changed files with 39 additions and 19 deletions

View File

@@ -339,26 +339,12 @@ static inline bool hasNodeSourceParent(const ModelNode &node)
void FormEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
// If node is not connected to scene root, don't do anything yet to avoid duplicated effort,
// as any removal or addition will remove or add descendants as well.
if (!node.isInHierarchy())
return;
addOrRemoveFormEditorItem(node);
}
QmlItemNode itemNode(node);
if (hasNodeSourceParent(node)) {
if (FormEditorItem *item = m_scene->itemForQmlItemNode(itemNode)) {
QList<FormEditorItem *> removed = scene()->itemsForQmlItemNodes(itemNode.allSubModelNodes());
removed.append(item);
m_currentTool->itemsAboutToRemoved(removed);
removeNodeFromScene(itemNode);
}
} else if (itemNode.isValid() && node.nodeSourceType() == ModelNode::NodeWithoutSource) {
if (!m_scene->itemForQmlItemNode(itemNode)) {
setupFormEditorItemTree(itemNode);
// Simulate selection change to refresh tools
selectedNodesChanged(selectedModelNodes(), {});
}
}
void FormEditorView::nodeSourceChanged(const ModelNode &node, const QString &newNodeSource)
{
addOrRemoveFormEditorItem(node);
}
WidgetInfo FormEditorView::widgetInfo()
@@ -863,6 +849,38 @@ void FormEditorView::resetNodeInstanceView()
resetPuppet();
}
void FormEditorView::addOrRemoveFormEditorItem(const ModelNode &node)
{
// If node is not connected to scene root, don't do anything yet to avoid duplicated effort,
// as any removal or addition will remove or add descendants as well.
if (!node.isInHierarchy())
return;
QmlItemNode itemNode(node);
auto removeItemFromScene = [this, &itemNode]() {
if (FormEditorItem *item = m_scene->itemForQmlItemNode(itemNode)) {
QList<FormEditorItem *> removed = scene()->itemsForQmlItemNodes(itemNode.allSubModelNodes());
removed.append(item);
m_currentTool->itemsAboutToRemoved(removed);
removeNodeFromScene(itemNode);
}
};
if (hasNodeSourceParent(node)) {
removeItemFromScene();
} else if (itemNode.isValid()) {
if (node.nodeSourceType() == ModelNode::NodeWithoutSource) {
if (!m_scene->itemForQmlItemNode(itemNode)) {
setupFormEditorItemTree(itemNode);
// Simulate selection change to refresh tools
selectedNodesChanged(selectedModelNodes(), {});
}
} else {
removeItemFromScene();
}
}
}
void FormEditorView::reset()
{
QTimer::singleShot(200, this, &FormEditorView::delayedReset);

View File

@@ -70,6 +70,7 @@ public:
void nodeCreated(const ModelNode &createdNode) override;
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override;
void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override;
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList) override;
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
@@ -147,6 +148,7 @@ private:
void createFormEditorWidget();
void temporaryBlockView(int duration = 1000);
void resetNodeInstanceView();
void addOrRemoveFormEditorItem(const ModelNode &node);
QPointer<FormEditorWidget> m_formEditorWidget;
QPointer<FormEditorScene> m_scene;