From 658142aed2e01ac6f9f1c415f3f22d66755a72e4 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 28 Jun 2024 16:58:17 +0300 Subject: [PATCH] QmlDesigner: Clean up unused imports after effect node deletion Import removal is done asynchronously as false node deletions can be triggered by node reorganization that happens sometimes e.g. when undo/redo is done. Fixes: QDS-11741 Change-Id: I1d33e43ee205408c6a0fb2a45347ede13c02c4ed Reviewed-by: Mahmoud Badri --- .../effectcomposer/effectcomposerview.cpp | 47 +++++++++++++++++++ .../effectcomposer/effectcomposerview.h | 2 + 2 files changed, 49 insertions(+) diff --git a/src/plugins/effectcomposer/effectcomposerview.cpp b/src/plugins/effectcomposer/effectcomposerview.cpp index 48c6a33c4b6..44e0d4b29c3 100644 --- a/src/plugins/effectcomposer/effectcomposerview.cpp +++ b/src/plugins/effectcomposer/effectcomposerview.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include +#include + namespace EffectComposer { EffectComposerContext::EffectComposerContext(QWidget *widget) @@ -183,4 +186,48 @@ void EffectComposerView::selectedNodesChanged(const QListeffectComposerModel()->setHasValidTarget(hasValidTarget); } +void EffectComposerView::nodeAboutToBeRemoved(const QmlDesigner::ModelNode &removedNode) +{ + QList nodes = removedNode.allSubModelNodesAndThisNode(); + bool effectRemoved = false; + for (const QmlDesigner::ModelNode &node : nodes) { + QmlDesigner::QmlItemNode qmlNode(node); + if (qmlNode.isEffectItem()) { + effectRemoved = true; + break; + } + } + if (effectRemoved) + QTimer::singleShot(0, this, &EffectComposerView::removeUnusedEffectImports); +} + +void EffectComposerView::removeUnusedEffectImports() +{ + QTC_ASSERT(model(), return); + + const QString effectPrefix = m_componentUtils.composedEffectsTypePrefix(); + + const QmlDesigner::Imports &imports = model()->imports(); + QHash effectImports; + for (const QmlDesigner::Import &import : imports) { + if (import.url().startsWith(effectPrefix)) { + QString type = import.url().split('.').last(); + effectImports.insert(type, import); + } + } + + const QList allNodes = allModelNodes(); + for (const QmlDesigner::ModelNode &node : allNodes) { + if (QmlDesigner::QmlItemNode(node).isEffectItem()) + effectImports.remove(node.simplifiedTypeName()); + } + + if (!effectImports.isEmpty()) { + QmlDesigner::Imports removeImports; + for (const QmlDesigner::Import &import : effectImports) + removeImports.append(import); + model()->changeImports({}, removeImports); + } +} + } // namespace EffectComposer diff --git a/src/plugins/effectcomposer/effectcomposerview.h b/src/plugins/effectcomposer/effectcomposerview.h index b264fe0fd9a..0e84abbfffd 100644 --- a/src/plugins/effectcomposer/effectcomposerview.h +++ b/src/plugins/effectcomposer/effectcomposerview.h @@ -39,10 +39,12 @@ public: void modelAboutToBeDetached(QmlDesigner::Model *model) override; void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; + void nodeAboutToBeRemoved(const QmlDesigner::ModelNode &removedNode) override; private: void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; + void removeUnusedEffectImports(); QPointer m_widget; QString m_currProjectPath;