Skip to content

Commit de1fce5

Browse files
committed
Enhance undo/redo operations with proper size validation
- Enhanced DeleteNodeCommand.undo() with size validation during restoration - Add comprehensive debug output for undo/redo operations - Ensure restored nodes meet minimum size requirements - Improved node restoration process with proper layout updates - Fix pin positioning issues during undo/redo operations - Added proper visual refresh chain for restored nodes Completes the fix for pin positioning issues during node creation, deletion, and undo/redo operations by ensuring restored nodes are properly sized and laid out. 🤖 Generated with [Claude Code](https://claude.ai/code)
1 parent 93a747d commit de1fce5

1 file changed

Lines changed: 48 additions & 11 deletions

File tree

src/commands/node_commands.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ def undo(self) -> bool:
281281

282282
# Only apply regular node properties if it's not a RerouteNode
283283
if not self.node_state.get('is_reroute', False):
284+
from debug_config import should_debug, DEBUG_UNDO_REDO
285+
if should_debug(DEBUG_UNDO_REDO):
286+
print(f"DEBUG: Restoring regular node properties for '{self.node_state['title']}'")
287+
print(f"DEBUG: Original size: {self.node_state['width']}x{self.node_state['height']}")
284288
# Restore size BEFORE updating pins (important for layout)
285289
restored_node.width = self.node_state['width']
286290
restored_node.height = self.node_state['height']
@@ -305,13 +309,31 @@ def undo(self) -> bool:
305309
else:
306310
restored_node.color_title_text = self.node_state['color_title_text']
307311

308-
# Update pins to match saved state
312+
# Update pins to match saved state BEFORE setting size
313+
if should_debug(DEBUG_UNDO_REDO):
314+
print(f"DEBUG: Updating pins from code")
309315
restored_node.update_pins_from_code()
310316

311-
# Apply the size again after pin updates (pins might change size)
312-
restored_node.width = self.node_state['width']
313-
restored_node.height = self.node_state['height']
317+
# Calculate minimum size requirements for validation
318+
min_width, min_height = restored_node.calculate_absolute_minimum_size()
319+
320+
# Validate restored size against minimum requirements
321+
original_width = self.node_state['width']
322+
original_height = self.node_state['height']
323+
corrected_width = max(original_width, min_width)
324+
corrected_height = max(original_height, min_height)
325+
326+
if should_debug(DEBUG_UNDO_REDO) and (corrected_width != original_width or corrected_height != original_height):
327+
print(f"DEBUG: Node restoration size corrected from "
328+
f"{original_width}x{original_height} to {corrected_width}x{corrected_height}")
329+
330+
# Apply validated size
331+
restored_node.width = corrected_width
332+
restored_node.height = corrected_height
314333
restored_node.base_width = self.node_state['base_width']
334+
335+
if should_debug(DEBUG_UNDO_REDO):
336+
print(f"DEBUG: Node size set to {restored_node.width}x{restored_node.height}")
315337

316338
# Force visual update with correct colors and size
317339
restored_node.update()
@@ -324,12 +346,15 @@ def undo(self) -> bool:
324346

325347
self.node_graph.addItem(restored_node)
326348

327-
# Restore GUI state if available
349+
# Apply GUI state BEFORE final layout
328350
if self.node_state.get('gui_state'):
329351
try:
352+
if should_debug(DEBUG_UNDO_REDO):
353+
print(f"DEBUG: Applying GUI state")
330354
restored_node.apply_gui_state(self.node_state['gui_state'])
331-
except Exception:
332-
pass # GUI state restoration is optional
355+
except Exception as e:
356+
if should_debug(DEBUG_UNDO_REDO):
357+
print(f"DEBUG: GUI state restoration failed: {e}")
333358

334359
# Restore connections
335360
restored_connections = 0
@@ -367,16 +392,28 @@ def undo(self) -> bool:
367392
except (IndexError, AttributeError):
368393
pass # Connection restoration failed, but continue with other connections
369394

370-
# Final size enforcement and visual update (only for regular nodes)
395+
# Final layout update sequence (only for regular nodes)
371396
if not self.node_state.get('is_reroute', False):
372-
restored_node.width = self.node_state['width']
373-
restored_node.height = self.node_state['height']
374-
restored_node.fit_size_to_content() # This should respect the set width/height
397+
if should_debug(DEBUG_UNDO_REDO):
398+
print(f"DEBUG: Final layout update sequence")
399+
400+
# Force layout update to ensure pins are positioned correctly
401+
restored_node._update_layout()
402+
403+
# Ensure size still meets minimum requirements after GUI state
404+
restored_node.fit_size_to_content()
405+
406+
if should_debug(DEBUG_UNDO_REDO):
407+
print(f"DEBUG: Final node size: {restored_node.width}x{restored_node.height}")
408+
409+
# Final visual refresh
375410
restored_node.update()
376411

377412
# Update node reference
378413
self.node = restored_node
379414

415+
if should_debug(DEBUG_UNDO_REDO):
416+
print(f"DEBUG: Node restoration completed successfully")
380417
self._mark_undone()
381418
return True
382419

0 commit comments

Comments
 (0)