diff --git a/src/Mod/Assembly/CommandInsertLink.py b/src/Mod/Assembly/CommandInsertLink.py index ab43123901..f817d0c891 100644 --- a/src/Mod/Assembly/CommandInsertLink.py +++ b/src/Mod/Assembly/CommandInsertLink.py @@ -96,6 +96,14 @@ class CommandInsertLink: Gui.Control.showDialog(self.panel) +class InsertLinkObserver: + def __init__(self, callback): + self.callback = callback + + def slotDeletedObject(self, obj): + self.callback(obj) + + class TaskAssemblyInsertLink(QtCore.QObject): def __init__(self, assembly, view): super().__init__() @@ -134,6 +142,10 @@ class TaskAssemblyInsertLink(QtCore.QObject): App.setActiveTransaction("Insert Component") + # Listen for external deletions to keep the list in sync + self.docObserver = InsertLinkObserver(self.onObjectDeleted) + App.addDocumentObserver(self.docObserver) + def accept(self): self.deactivated() @@ -182,6 +194,10 @@ class TaskAssemblyInsertLink(QtCore.QObject): return True def deactivated(self): + if hasattr(self, "docObserver") and self.docObserver: + App.removeDocumentObserver(self.docObserver) + self.docObserver = None + pref = Preferences.preferences() pref.SetBool("InsertShowOnlyParts", self.form.CheckBox_ShowOnlyParts.isChecked()) pref.SetBool("InsertRigidSubAssemblies", self.form.CheckBox_RigidSubAsm.isChecked()) @@ -563,16 +579,12 @@ class TaskAssemblyInsertLink(QtCore.QObject): stack_item = self.insertionStack[i] if stack_item["item"] == item: - - self.totalTranslation -= stack_item["translation"] obj = stack_item["addedObject"] - if self.groundedObj == obj: - self.groundedJoint.Document.removeObject(self.groundedJoint.Name) - UtilsAssembly.removeObjAndChilds(obj) - self.decrement_counter(item) - del self.insertionStack[i] - item.setSelected(False) + # ONLY remove the object from the document. + # The Observer (onObjectDeleted) will handle the rest. + if obj and obj.Document: + UtilsAssembly.removeObjAndChilds(obj) return True else: @@ -637,6 +649,41 @@ class TaskAssemblyInsertLink(QtCore.QObject): translation = 10 return App.Vector(translation, translation, translation) + def onObjectDeleted(self, obj): + """ + Handles cleanup when an object is deleted (via Right Click OR Tree View). + """ + # Iterate backwards to safely delete + for i in reversed(range(len(self.insertionStack))): + stack_item = self.insertionStack[i] + + if stack_item["addedObject"] == obj: + # 1. Revert translation + self.totalTranslation -= stack_item["translation"] + + # 2. Update UI counter + item = stack_item["item"] + self.decrement_counter(item) + + # 3. Handle Grounded Joint cleanup + if self.groundedObj == obj: + if self.groundedJoint: + try: + # Remove the joint if it still exists + if self.groundedJoint.Document: + self.groundedJoint.Document.removeObject(self.groundedJoint.Name) + except Exception: + pass + self.groundedObj = None + self.groundedJoint = None + + # 4. Remove from stack + del self.insertionStack[i] + + # 5. Clear selection + if item: + item.setSelected(False) + if App.GuiUp: Gui.addCommand("Assembly_InsertLink", CommandInsertLink())