Add flow view reordering via connection breaking
When a connection is broken in the flow view: 1. The node that lost its input moves to the end of the chain 2. The remaining nodes reconnect automatically 3. Tool model updates to reflect new order 4. Dependency validation warns about broken references Flow: Input → A → B → C → Output Break B's input: Input → A → C → B → Output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
260ebf1b2f
commit
d1f0c2f893
|
|
@ -241,6 +241,7 @@ class ToolBuilderPage(QWidget):
|
|||
self._flow_widget = FlowGraphWidget()
|
||||
self._flow_widget.node_double_clicked.connect(self._on_flow_node_double_clicked)
|
||||
self._flow_widget.steps_deleted.connect(self._on_flow_steps_deleted)
|
||||
self._flow_widget.steps_reordered.connect(self._on_flow_steps_reordered)
|
||||
|
||||
# Replace placeholder
|
||||
old_widget = self.steps_stack.widget(1)
|
||||
|
|
@ -282,6 +283,35 @@ class ToolBuilderPage(QWidget):
|
|||
# Refresh the list view (flow view will be refreshed by set_tool)
|
||||
self._refresh_steps()
|
||||
|
||||
def _on_flow_steps_reordered(self, new_order: list):
|
||||
"""Handle step reordering from flow view.
|
||||
|
||||
Args:
|
||||
new_order: List of old indices in new order.
|
||||
e.g., [0, 2, 1] means step 0 stays first,
|
||||
step 2 moves to second, step 1 moves to third.
|
||||
"""
|
||||
if not self._tool or not self._tool.steps:
|
||||
return
|
||||
|
||||
# Reorder steps according to new_order
|
||||
old_steps = self._tool.steps[:]
|
||||
new_steps = [old_steps[i] for i in new_order if i < len(old_steps)]
|
||||
|
||||
# Validate the new order
|
||||
warnings = self._validate_step_order(new_steps)
|
||||
|
||||
if warnings:
|
||||
# Show warning but allow the reorder
|
||||
warning_msg = "Variable dependency warnings:\n\n" + "\n".join(warnings)
|
||||
warning_msg += "\n\nThe reorder has been applied. You may need to fix these issues."
|
||||
QMessageBox.warning(self, "Dependency Warning", warning_msg)
|
||||
|
||||
self._tool.steps = new_steps
|
||||
|
||||
# Refresh both views
|
||||
self._refresh_steps()
|
||||
|
||||
def _load_tool(self, name: str):
|
||||
"""Load an existing tool for editing."""
|
||||
tool = load_tool(name)
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ class FlowGraphWidget(QWidget):
|
|||
# Emitted when steps are deleted from flow view (list of step indices)
|
||||
steps_deleted = Signal(list)
|
||||
|
||||
# Emitted when steps are reordered (new order as list of step indices)
|
||||
steps_reordered = Signal(list)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._tool: Optional[Tool] = None
|
||||
|
|
@ -153,6 +156,7 @@ class FlowGraphWidget(QWidget):
|
|||
# Connect signals
|
||||
self._graph.node_double_clicked.connect(self._on_node_double_clicked)
|
||||
self._graph.nodes_deleted.connect(self._on_nodes_deleted)
|
||||
self._graph.port_disconnected.connect(self._on_port_disconnected)
|
||||
|
||||
# Add graph widget
|
||||
layout.addWidget(self._graph.widget, 1)
|
||||
|
|
@ -427,6 +431,56 @@ class FlowGraphWidget(QWidget):
|
|||
self.steps_deleted.emit(deleted_indices)
|
||||
self.flow_changed.emit()
|
||||
|
||||
def _on_port_disconnected(self, input_port, output_port):
|
||||
"""Handle port disconnection - reorder steps.
|
||||
|
||||
When a connection is broken:
|
||||
1. The node that lost its input moves to the end
|
||||
2. The chain reconnects (previous node → next node)
|
||||
3. Disconnected node attaches at the end before Output
|
||||
"""
|
||||
if not self._tool or not self._tool.steps:
|
||||
return
|
||||
|
||||
# Get the nodes involved
|
||||
# input_port belongs to the node that lost its input
|
||||
# output_port belongs to the node that was providing the input
|
||||
disconnected_node = input_port.node()
|
||||
source_node = output_port.node()
|
||||
|
||||
# Only handle step nodes (not Input/Output)
|
||||
if not hasattr(disconnected_node, '_step_index') or disconnected_node._step_index < 0:
|
||||
return
|
||||
|
||||
disconnected_idx = disconnected_node._step_index
|
||||
|
||||
# Find the node that the disconnected node was connected to (its output target)
|
||||
next_node = None
|
||||
if disconnected_node.output_ports():
|
||||
out_port = disconnected_node.output_ports()[0]
|
||||
connected_ports = out_port.connected_ports()
|
||||
if connected_ports:
|
||||
next_node = connected_ports[0].node()
|
||||
|
||||
# Build new order: move disconnected step to end
|
||||
old_order = list(range(len(self._tool.steps)))
|
||||
old_order.remove(disconnected_idx)
|
||||
old_order.append(disconnected_idx)
|
||||
|
||||
# Reconnect the graph visually
|
||||
# Connect source to next (if next is a step node)
|
||||
if next_node and hasattr(next_node, '_step_index') and next_node._step_index >= 0:
|
||||
if source_node.output_ports() and next_node.input_ports():
|
||||
source_node.output_ports()[0].connect_to(next_node.input_ports()[0])
|
||||
|
||||
# Connect the last step (before disconnected) to disconnected node
|
||||
# and disconnected node to output
|
||||
# This will be handled by the rebuild after reorder
|
||||
|
||||
# Emit the new order
|
||||
self.steps_reordered.emit(old_order)
|
||||
self.flow_changed.emit()
|
||||
|
||||
def refresh(self):
|
||||
"""Refresh the graph from current tool data."""
|
||||
self._rebuild_graph()
|
||||
|
|
|
|||
Loading…
Reference in New Issue