# commands.py from PySide6.QtGui import QUndoCommand from PySide6.QtWidgets import QTreeWidgetItem from PySide6.QtCore import Qt def clone_item_recursive(source_item: QTreeWidgetItem) -> QTreeWidgetItem: """ Rekurencyjnie klonuje QTreeWidgetItem wraz z jego dziećmi, zachowując tekst i ewentualne dane w kolumnach. """ cloned = QTreeWidgetItem([ source_item.text(0), source_item.text(1), source_item.text(2), source_item.text(3), ]) # Ewentualnie można kopiować Qt.UserRole itp.: # for col in range(source_item.columnCount()): # data_val = source_item.data(col, Qt.UserRole) # cloned.setData(col, Qt.UserRole, data_val) for i in range(source_item.childCount()): child = source_item.child(i) cloned_child = clone_item_recursive(child) cloned.addChild(cloned_child) return cloned class AddItemCommand(QUndoCommand): """ Dodaje nowy (już utworzony) węzeł (cloned_item) do tree: - jeśli parent_item is None -> top-level - w przeciwnym razie child w parent_item """ def __init__(self, tree, parent_item, index: int, cloned_item, description="Add Item"): super().__init__(description) self.tree = tree self.parent_item = parent_item self.index = index self.cloned_item = cloned_item def redo(self): if self.parent_item is None: self.tree.insertTopLevelItem(self.index, self.cloned_item) else: self.parent_item.insertChild(self.index, self.cloned_item) self.tree.expandItem(self.cloned_item) def undo(self): if self.parent_item: self.parent_item.removeChild(self.cloned_item) else: idx = self.tree.indexOfTopLevelItem(self.cloned_item) if idx >= 0: self.tree.takeTopLevelItem(idx) class RemoveItemCommand(QUndoCommand): """ Usuwa wybrany węzeł z drzewa i zapamiętuje jego kopię, by móc cofnąć (undo) i przywrócić go w to samo miejsce. """ def __init__(self, tree, item, description="Remove Item"): super().__init__(description) self.tree = tree self.item_original = item self.parent_item = item.parent() if self.parent_item: self.index = self.parent_item.indexOfChild(item) else: self.index = self.tree.indexOfTopLevelItem(item) # Tworzymy kopię rekurencyjną (z dziećmi) self.item_clone = clone_item_recursive(item) def redo(self): # usuwamy oryginalny węzeł z widoku if self.parent_item: self.parent_item.removeChild(self.item_original) else: idx = self.tree.indexOfTopLevelItem(self.item_original) if idx >= 0: self.tree.takeTopLevelItem(idx) def undo(self): # przywracamy klon w to samo miejsce if self.parent_item: self.parent_item.insertChild(self.index, self.item_clone) else: self.tree.insertTopLevelItem(self.index, self.item_clone) self.tree.expandItem(self.item_clone) class EditPunktyCommand(QUndoCommand): """ Cofalne/ponawialne ustawienie nowej wartości punktów w kolumnie 0. W 'redo()' dajemy new_val, w 'undo()' old_val. """ def __init__(self, item: QTreeWidgetItem, old_val: str, new_val: str, description="Edit punkty"): super().__init__(description) self.item = item self.old_val = old_val self.new_val = new_val def redo(self): self.item.setText(0, self.new_val) # Ewentualnie odśwież kolor: # from utils.colors import color_item_by_title # color_item_by_title(self.item) def undo(self): self.item.setText(0, self.old_val) # from utils.colors import color_item_by_title # color_item_by_title(self.item)