Global undo/redo is currently the highest voted feature on the 3D Slicer Discourse feature requests board.
To test the undo/redo functionality currently available in Slicer, add the following code to ‘.slicerrc’ to test undo/redo with Markups:
slicer.mrmlScene.SetUndoOn()
undoEnabledNodeClassNames = [
"vtkMRMLMarkupsFiducialNode",
"vtkMRMLMarkupsLineNode",
"vtkMRMLMarkupsAngleNode",
"vtkMRMLMarkupsCurveNode",
"vtkMRMLMarkupsClosedCurveNode",
"vtkMRMLMarkupsPlaneNode",
"vtkMRMLMarkupsROINode",
]
for className in undoEnabledNodeClassNames:
node = slicer.mrmlScene.CreateNodeByClass(className)
node.SetUndoEnabled(True)
slicer.mrmlScene.AddDefaultNode(node)
def onRedo():
slicer.mrmlScene.Redo()
def onUndo():
slicer.mrmlScene.Undo()
redoShortcuts = []
redoKeyBindings = qt.QKeySequence.keyBindings(qt.QKeySequence.Redo)
for redoBinding in redoKeyBindings:
redoShortcut = qt.QShortcut(slicer.util.mainWindow())
redoShortcut.setKey(redoBinding)
redoShortcut.connect("activated()", onRedo)
redoShortcuts.append(redoShortcut)
undoShortcuts = []
undoKeyBindings = qt.QKeySequence.keyBindings(qt.QKeySequence.Undo)
for undoBinding in undoKeyBindings:
undoShortcut = qt.QShortcut(slicer.util.mainWindow())
undoShortcut.setKey(undoBinding)
undoShortcut.connect("activated()", onUndo)
undoShortcuts.append(undoShortcut)
toolBar = qt.QToolBar("Undo/Redo")
toolBar.addAction(qt.QIcon(":/Icons/Medium/SlicerUndo.png"), "Undo", onUndo)
toolBar.addAction(qt.QIcon(":/Icons/Medium/SlicerRedo.png"), "Redo", onRedo)
slicer.util.mainWindow().addToolBar(toolBar)