Add link management: create, select, delete with undo/redo
Implement full link workflow between component slots on the wiresheet: - Link Mark / Link From / Link To context menu items for creating links - Link dialog with slot type validation and source/target swap button - Selectable link wires (click to highlight in red) with right-click delete - Undo/redo support for both add and delete link operations - Component deletion already cascades to remove related links Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+56
@@ -65,12 +65,15 @@ def reset_to_startup_state():
|
||||
app_state.current_sheet_parent = None
|
||||
app_state.selected_canvas_tag = None
|
||||
app_state.selected_tree_item_id = None
|
||||
app_state.link_mark_element = None
|
||||
app_state.selected_link_tag = None
|
||||
|
||||
app_state.active_components_list.clear()
|
||||
app_state.tree_element_map.clear()
|
||||
app_state.canvas_comp_map.clear()
|
||||
app_state.canvas_tag_by_element.clear()
|
||||
app_state.component_slot_offsets.clear()
|
||||
app_state.canvas_link_map.clear()
|
||||
app_state.final_components_registry.clear()
|
||||
app_state.active_schema_kits.clear()
|
||||
|
||||
@@ -423,6 +426,59 @@ def add_component(kit_name, type_name, grid_x, grid_y):
|
||||
return element
|
||||
|
||||
|
||||
def remove_link(link_element):
|
||||
"""Removes a <link> element from the <links> section and repaints."""
|
||||
if app_state.xml_root_element is None:
|
||||
return
|
||||
|
||||
links_elem = app_state.xml_root_element.find("links")
|
||||
if links_elem is None:
|
||||
return
|
||||
|
||||
try:
|
||||
index = list(links_elem).index(link_element)
|
||||
links_elem.remove(link_element)
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
from_ref = link_element.get("from", "")
|
||||
to_ref = link_element.get("to", "")
|
||||
from_slot = from_ref.rsplit(".", 1)[-1] if "." in from_ref else from_ref
|
||||
to_slot = to_ref.rsplit(".", 1)[-1] if "." in to_ref else to_ref
|
||||
undo.push(undo.DeleteLinkCommand(
|
||||
links_elem, index, link_element,
|
||||
label=f"delete link {from_slot}→{to_slot}"
|
||||
))
|
||||
|
||||
app_state.selected_link_tag = None
|
||||
app_state.mark_dirty()
|
||||
wiresheet.render_current_sheet()
|
||||
|
||||
|
||||
def add_link(from_path_slot, to_path_slot):
|
||||
"""Adds a <link> element to the <links> section of the SAX DOM."""
|
||||
if app_state.xml_root_element is None:
|
||||
return
|
||||
|
||||
links_elem = app_state.xml_root_element.find("links")
|
||||
if links_elem is None:
|
||||
links_elem = ET.SubElement(app_state.xml_root_element, "links")
|
||||
|
||||
link_elem = ET.SubElement(links_elem, "link")
|
||||
link_elem.set("from", from_path_slot)
|
||||
link_elem.set("to", to_path_slot)
|
||||
|
||||
from_slot = from_path_slot.rsplit(".", 1)[-1] if "." in from_path_slot else from_path_slot
|
||||
to_slot = to_path_slot.rsplit(".", 1)[-1] if "." in to_path_slot else to_path_slot
|
||||
undo.push(undo.AddLinkCommand(
|
||||
links_elem, link_elem,
|
||||
label=f"add link {from_slot}→{to_slot}"
|
||||
))
|
||||
|
||||
app_state.mark_dirty()
|
||||
wiresheet.render_current_sheet()
|
||||
|
||||
|
||||
def execute_cascading_deletion(comp_element):
|
||||
"""Shared application logic to wipe an element, its children, and related links from DOM and runtime lists."""
|
||||
comp_name = comp_element.get("name", "Unknown")
|
||||
|
||||
Reference in New Issue
Block a user