""" QCommand classes for every undoable user action performed in the MainWindow """ from PyQt6.QtGui import QUndoCommand import os import logging from copy import copy from ..core import Core log = logging.getLogger("AVP.Gui.Actions") # =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~ # COMPONENT ACTIONS # =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~ class AddComponent(QUndoCommand): def __init__(self, parent, compI, moduleI): super().__init__( "create new %s component" % parent.core.modules[moduleI].Component.name ) self.parent = parent self.moduleI = moduleI self.compI = compI self.comp = None self.valid = True def redo(self): if self.comp is None: i = self.parent.core.insertComponent(self.compI, self.moduleI, self.parent) if i != self.compI: self.valid = False if i is not None: log.error( f"Expected new component index to be {self.compI} but received {i}" ) else: # inserting previously-created component self.parent.core.insertComponent(self.compI, self.comp, self.parent) def undo(self): if not self.valid: return self.comp = self.parent.core.selectedComponents[self.compI] self.parent._removeComponent(self.compI) class RemoveComponent(QUndoCommand): def __init__(self, parent, selectedRows): super().__init__("remove component") self.parent = parent componentList = self.parent.listWidget_componentList self.selectedRows = [componentList.row(selected) for selected in selectedRows] self.components = [parent.core.selectedComponents[i] for i in self.selectedRows] def redo(self): self.parent._removeComponent(self.selectedRows[0]) def undo(self): componentList = self.parent.listWidget_componentList for index, comp in zip(self.selectedRows, self.components): self.parent.core.insertComponent(index, comp, self.parent) self.parent.drawPreview() class MoveComponent(QUndoCommand): def __init__(self, parent, row, newRow, tag): super().__init__("move component %s" % tag) self.parent = parent self.row = row self.newRow = newRow self.id_ = ord(tag[0]) def id(self): """If 2 consecutive updates have same id, Qt will call mergeWith()""" return self.id_ def mergeWith(self, other): self.newRow = other.newRow return True def do(self, rowa, rowb): componentList = self.parent.listWidget_componentList page = self.parent.pages.pop(rowa) self.parent.pages.insert(rowb, page) item = componentList.takeItem(rowa) componentList.insertItem(rowb, item) stackedWidget = self.parent.stackedWidget widget = stackedWidget.removeWidget(page) stackedWidget.insertWidget(rowb, page) componentList.setCurrentRow(rowb) stackedWidget.setCurrentIndex(rowb) self.parent.core.moveComponent(rowa, rowb) self.parent.drawPreview(True) def redo(self): self.do(self.row, self.newRow) def undo(self): self.do(self.newRow, self.row) # =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~ # PRESET ACTIONS # =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~ class ClearPreset(QUndoCommand): def __init__(self, parent, compI): super().__init__("clear preset") self.parent = parent self.compI = compI self.component = self.parent.core.selectedComponents[compI] self.store = self.component.savePreset() self.store["preset"] = self.component.currentPreset def redo(self): self.parent.core.clearPreset(self.compI) self.parent.updateComponentTitle(self.compI, False) def undo(self): self.parent.core.selectedComponents[self.compI].loadPreset(self.store) self.parent.updateComponentTitle(self.compI, self.store) class OpenPreset(QUndoCommand): def __init__(self, parent, presetName, compI): super().__init__("open %s preset" % presetName) self.parent = parent self.presetName = presetName self.compI = compI comp = self.parent.core.selectedComponents[compI] self.store = comp.savePreset() self.store["preset"] = copy(comp.currentPreset) def redo(self): self.parent._openPreset(self.presetName, self.compI) def undo(self): self.parent.core.selectedComponents[self.compI].loadPreset(self.store) self.parent.parent.updateComponentTitle(self.compI, self.store) class RenamePreset(QUndoCommand): def __init__(self, parent, path, oldName, newName): super().__init__("rename preset") self.parent = parent self.path = path self.oldName = oldName self.newName = newName def redo(self): self.parent.renamePreset(self.path, self.oldName, self.newName) def undo(self): self.parent.renamePreset(self.path, self.newName, self.oldName) class DeletePreset(QUndoCommand): def __init__(self, parent, compName, vers, presetFile): self.parent = parent self.preset = (compName, vers, presetFile) self.path = os.path.join(Core.presetDir, compName, str(vers), presetFile) self.store = self.parent.core.getPreset(self.path) self.presetName = self.store["preset"] super().__init__("delete %s preset (%s)" % (self.presetName, compName)) self.loadedPresets = [ i for i, comp in enumerate(self.parent.core.selectedComponents) if self.presetName == str(comp.currentPreset) ] def redo(self): os.remove(self.path) for i in self.loadedPresets: self.parent.core.clearPreset(i) self.parent.parent.updateComponentTitle(i, False) self.parent.findPresets() self.parent.drawPresetList() def undo(self): self.parent.createNewPreset(*self.preset, self.store) selectedComponents = self.parent.core.selectedComponents for i in self.loadedPresets: selectedComponents[i].currentPreset = self.presetName self.parent.parent.updateComponentTitle(i) self.parent.findPresets() self.parent.drawPresetList()