Making operations undoable#
SAMSON provides the possibility to Undo and Redo a number of the operations. Most functions of the SAMSON SDK that act on the data graph’s state are undoable. But just performing such operations does not make them undoable for the user, i.e. it won’t appear in the History. This is done in this way to not keep history when it is not needed, e.g. when doing operations on nodes that are not part of any document’s data graph.
To perform operations in an undoable way, it is necessary to use the SAMSON.holding
context manager that automatically turns the holding on upon entry and turns it off upon exit. Alternatively, you can also wrap an undoable code using the next commands:
SAMSON.beginHolding()
- turns the Undo system on; provide a descriptive name of the action that should be shown in the History,SAMSON.endHolding()
- turns the Undo system off.
In this way, this operation appears in the History and you or the user can undo it.
Please prefer the use of the SAMSON.holding
context manager since it automatically turns the holding off upon exit and hence it is safer: if your script exits/aborts within the context manager then the holding will be switched off automatically, but if you called SAMSON.beginHolding()
and your script exits/aborts before SAMSON.endHolding()
then SAMSON will still be holding which might pose some problems.
Note
Wrapping operations that are not undoable by their implementation cannot make them undoable.
Note
Most of the commands executed via SAMSON.runCommand()
are undoable via the internal use of SAMSON.beginHolding()
and SAMSON.endHolding()
. But for some you might need to call them from within the context manager SAMSON.holding
(or wrap them into SAMSON.beginHolding()
and SAMSON.endHolding()
directly).
Examples:
SAMSON.holding
context manager## make the operation within undoable
with SAMSON.holding('Select residues'):
# get a node indexer of all residues in the active document
residueIndexer = SAMSON.getNodes('node.type residue')
# set selectionFlag to True for residues in the indexer
for residue in residueIndexer:
residue.selectionFlag = True
SAMSON.beginHolding()
and SAMSON.endHolding()
## begin holding - turn the Undo system on
SAMSON.beginHolding('Select residues')
# get a node indexer of all residues in the active document
residueIndexer = SAMSON.getNodes('node.type residue')
# set selectionFlag to True for residues in the indexer
for residue in residueIndexer:
residue.selectionFlag = True
# end holding - turn the Undo system off
SAMSON.endHolding()
# get the active camera
camera = SAMSON.getActiveCamera()
# begin holding - turn the Undo system on
with SAMSON.holding('Change camera name'):
# change the camera name
camera.name = "New camera name"
When creating nodes not for some temporary use but in documents, it is necessary to make their creation undoable as well.
# create an instance of a structural model
structuralModel = SBStructuralModel()
# make the operation undoable
with SAMSON.holding("Add node"):
# hold the node to make it creation undoable
SAMSON.hold(structuralModel)
# create the node
structuralModel.create()
# add the visual model to the active document
SAMSON.getActiveDocument().addChild(structuralModel)
Note
When creating a hierarchy of nodes, e.g. a whole structural model, it is not necessary to call SAMSON.hold()
for each node - you can call it only for the root node, e.g. for the structural model, which will automatically make the creation of its children undoable as well.