[ui] Commands: handle undo stack while computing and submitting

Computing: lock the undo stack at the current index to avoid going back too far and potentially alter computing process.
Submitting: clear the undo stack.
This commit is contained in:
Julien-Haudegond 2020-09-02 11:30:12 +02:00
parent e0389ad957
commit 5f444e6810
3 changed files with 50 additions and 8 deletions

View file

@ -52,6 +52,10 @@ class UndoStack(QUndoStack):
self.canRedoChanged.connect(self._canRedoChanged)
self.undoTextChanged.connect(self._undoTextChanged)
self.redoTextChanged.connect(self._redoTextChanged)
self.indexChanged.connect(self._indexChanged)
self._undoableIndex = 0 # used to block the undo stack while computing
self._lockedRedo = False # used to avoid unwanted behaviors while computing
def tryAndPush(self, command):
# type: (UndoCommand) -> bool
@ -63,21 +67,54 @@ class UndoStack(QUndoStack):
if res is not False:
command.setEnabled(False)
self.push(command) # takes ownership
self.setLockedRedo(False) # make sure to unlock the redo action
command.setEnabled(True)
return res
def setUndoableIndex(self, value):
if self._undoableIndex == value:
return
self._undoableIndex = value
self.isUndoableIndexChanged.emit()
def setLockedRedo(self, value):
if self._lockedRedo == value:
return
self._lockedRedo = value
self.lockedRedoChanged.emit()
def lockAtThisIndex(self):
"""
Lock the undo stack at the current index and lock the redo action.
Note: should be used while starting a new compute to avoid problems.
"""
self.setUndoableIndex(self.index)
self.setLockedRedo(True)
def unlock(self):
""" Unlock both undo stack and redo action. """
self.setUndoableIndex(0)
self.setLockedRedo(False)
# Redeclare QUndoStack signal since original ones can not be used for properties notifying
_cleanChanged = Signal()
_canUndoChanged = Signal()
_canRedoChanged = Signal()
_undoTextChanged = Signal()
_redoTextChanged = Signal()
_indexChanged = Signal()
clean = Property(bool, QUndoStack.isClean, notify=_cleanChanged)
canUndo = Property(bool, QUndoStack.canUndo, notify=_canRedoChanged)
canRedo = Property(bool, QUndoStack.canRedo, notify=_canUndoChanged)
undoText = Property(str, QUndoStack.undoText, notify=_undoTextChanged)
redoText = Property(str, QUndoStack.redoText, notify=_redoTextChanged)
index = Property(int, QUndoStack.index, notify=_indexChanged)
isUndoableIndexChanged = Signal()
isUndoableIndex = Property(bool, lambda self: self.index > self._undoableIndex, notify=isUndoableIndexChanged)
lockedRedoChanged = Signal()
lockedRedo = Property(bool, lambda self: self._lockedRedo, setLockedRedo, notify=lockedRedoChanged)
class GraphCommand(UndoCommand):