| 112 | self.update() |
| 113 | |
| 114 | def keyPressEvent(self, event: QKeyEvent): |
| 115 | # Handle undo/redo shortcuts |
| 116 | if event.modifiers() & Qt.ControlModifier: |
| 117 | if event.key() == Qt.Key_Z: |
| 118 | if event.modifiers() & Qt.ShiftModifier: |
| 119 | print(f"\n=== KEYBOARD REDO TRIGGERED ===") |
| 120 | self.redo_last_command() |
| 121 | else: |
| 122 | print(f"\n=== KEYBOARD UNDO TRIGGERED ===") |
| 123 | self.undo_last_command() |
| 124 | return |
| 125 | elif event.key() == Qt.Key_Y: |
| 126 | print(f"\n=== KEYBOARD REDO (Y) TRIGGERED ===") |
| 127 | self.redo_last_command() |
| 128 | return |
| 129 | elif event.key() == Qt.Key_G: |
| 130 | selected_nodes = [item for item in self.selectedItems() if isinstance(item, Node)] |
| 131 | if len(selected_nodes) >= 2: |
| 132 | self._create_group_from_selection(selected_nodes) |
| 133 | # If insufficient nodes, the validation in _create_group_from_selection will show an error |
| 134 | return |
| 135 | |
| 136 | # Handle delete operations |
| 137 | if event.key() == Qt.Key_Delete: |
| 138 | print(f"\n=== KEYBOARD DELETE TRIGGERED ===") |
| 139 | selected_items = list(self.selectedItems()) |
| 140 | print(f"DEBUG: Found {len(selected_items)} selected items") |
| 141 | |
| 142 | for i, item in enumerate(selected_items): |
| 143 | print(f"DEBUG: Selected item {i}: {type(item).__name__} - {getattr(item, 'title', 'No title')} (ID: {id(item)})") |
| 144 | |
| 145 | if selected_items: |
| 146 | commands = [] |
| 147 | |
| 148 | # Use the improved DeleteMultipleCommand that handles all item types including Groups |
| 149 | from commands.node.batch_operations import DeleteMultipleCommand |
| 150 | delete_cmd = DeleteMultipleCommand(self, selected_items) |
| 151 | print(f"DEBUG: Using DeleteMultipleCommand: {delete_cmd.get_description()}") |
| 152 | result = self.execute_command(delete_cmd) |
| 153 | print(f"DEBUG: DeleteMultipleCommand returned: {result}") |
| 154 | return |
| 155 | |
| 156 | print(f"DEBUG: Created {len(commands)} delete commands") |
| 157 | |
| 158 | # Execute as composite command if multiple items |
| 159 | if len(commands) > 1: |
| 160 | print(f"DEBUG: Executing composite command with {len(commands)} commands") |
| 161 | composite = CompositeCommand(f"Delete {len(commands)} items", commands) |
| 162 | result = self.execute_command(composite) |
| 163 | print(f"DEBUG: Composite command returned: {result}") |
| 164 | elif len(commands) == 1: |
| 165 | print(f"DEBUG: Executing single command") |
| 166 | result = self.execute_command(commands[0]) |
| 167 | print(f"DEBUG: Single command returned: {result}") |
| 168 | else: |
| 169 | print(f"DEBUG: No commands to execute") |
| 170 | else: |
| 171 | print(f"DEBUG: No items selected for deletion") |