Command for pasting nodes and connections as a single undo unit.
| 20 | |
| 21 | |
| 22 | class PasteNodesCommand(CompositeCommand): |
| 23 | """Command for pasting nodes and connections as a single undo unit.""" |
| 24 | |
| 25 | def __init__(self, node_graph, clipboard_data: Dict[str, Any], paste_position: QPointF): |
| 26 | """ |
| 27 | Initialize paste nodes command. |
| 28 | |
| 29 | Args: |
| 30 | node_graph: The NodeGraph instance |
| 31 | clipboard_data: Data from clipboard containing nodes, groups, and connections |
| 32 | paste_position: Position to paste nodes at |
| 33 | """ |
| 34 | # Parse clipboard data to determine operation description |
| 35 | node_count = len(clipboard_data.get('nodes', [])) |
| 36 | group_count = len(clipboard_data.get('groups', [])) |
| 37 | connection_count = len(clipboard_data.get('connections', [])) |
| 38 | |
| 39 | if node_count == 1 and group_count == 0 and connection_count == 0: |
| 40 | description = f"Paste '{clipboard_data['nodes'][0].get('title', 'node')}'" |
| 41 | elif node_count > 1 and group_count == 0 and connection_count == 0: |
| 42 | description = f"Paste {node_count} nodes" |
| 43 | elif node_count == 0 and group_count == 1 and connection_count == 0: |
| 44 | description = f"Paste group '{clipboard_data['groups'][0].get('name', 'Group')}'" |
| 45 | elif node_count > 0 and group_count > 0: |
| 46 | description = f"Paste {node_count} nodes and {group_count} groups" |
| 47 | elif group_count > 1: |
| 48 | description = f"Paste {group_count} groups" |
| 49 | else: |
| 50 | total_items = node_count + group_count |
| 51 | description = f"Paste {total_items} items with {connection_count} connections" |
| 52 | |
| 53 | # Store data for execute method to handle connection and group creation |
| 54 | self.node_graph = node_graph |
| 55 | self.clipboard_data = clipboard_data |
| 56 | self.paste_position = paste_position |
| 57 | self.uuid_mapping = {} # Map old UUIDs to new UUIDs |
| 58 | self.created_nodes = [] |
| 59 | self.created_groups = [] |
| 60 | |
| 61 | # Create only node creation commands initially |
| 62 | commands = [] |
| 63 | nodes_data = clipboard_data.get('nodes', []) |
| 64 | groups_data = clipboard_data.get('groups', []) |
| 65 | |
| 66 | # Check if we're pasting groups with nodes - use different positioning logic |
| 67 | has_groups = len(groups_data) > 0 |
| 68 | |
| 69 | for i, node_data in enumerate(nodes_data): |
| 70 | # Generate new UUID for this node |
| 71 | old_uuid = node_data.get('id', str(uuid.uuid4())) |
| 72 | new_uuid = str(uuid.uuid4()) |
| 73 | self.uuid_mapping[old_uuid] = new_uuid |
| 74 | |
| 75 | if has_groups: |
| 76 | # When pasting groups, preserve original absolute positions |
| 77 | # The group will handle positioning itself and its members |
| 78 | original_pos = node_data.get('pos', [0, 0]) |
| 79 | node_position = QPointF(original_pos[0], original_pos[1]) |
no outgoing calls