Undo Manager¶
Undo is a required feature in modern applications. Gaphor is no exception. Having an undo function in place means you can change the model and easily revert to an older state.
Overview of Transactions¶
The recording and playback of changes in Gaphor is handled by the the Undo
Manager. The Undo Manager works transactionally.
A transaction must succeed or fail as a complete unit. If
the transaction fails in the middle, it is rolled back. In Gaphor this is
achieved by the transaction
module, which provides a context manager
Transaction
.
When transactions take place, they emit events when the top-most transaction begins and is finished. The event notifications are for the begin of the transaction, and the commit of the transaction if it is successful or the rollback of the transaction if it fails.
The Undo Manager only allows changes to be made in a transaction. If a change is made outside a transaction, an exception is raised.
Start of a Transaction¶
A
Transaction
object is created.TransactionBegin
event is emitted.The
UndoManager
instantiates a newActionStack
which is the transaction object, and adds the undo action to the stack.
Nested transactions are supported to allow a transaction to be added inside of another transaction that is already in progress.
Successful Transaction¶
A
TransactionCommit
event is emittedThe
UndoManager
closes and stores the transaction.
Failed Transaction¶
A
TransactionRollback
event is emitted.The
UndoManager
plays back all the recorded actions, but does not store it.
Transaction API¶
Note
You only require transactions if the undo manager is active.
- class gaphor.transaction.Transaction(event_manager, context=None)[source]¶
The transaction.
On start and end of a transaction an event is emitted. Transactions can be nested. Events are only emitted when the outermost transaction begins and finishes.
Note that transactions are a global construct.
>>> import gaphor.core.eventmanager >>> event_manager = gaphor.core.eventmanager.EventManager()
Transactions can be nested. If the outermost transaction is committed or rolled back, an event is emitted.
It’s most convenient to use
Transaction
as a context manager:>>> with Transaction(event_manager) as ctx: ... ... # do actions ... # in case the transaction should be rolled back: ... ctx.rollback()
Events can be handled programmatically, although this is discouraged:
>>> tx = Transaction(event_manager) >>> tx.commit()
- commit()[source]¶
Commit the transaction.
The transaction is closed. A
TransactionCommit
event is emitted. If the transaction needs to be rolled back, aTransactionRollback
event is emitted instead.
- classmethod mark_rollback()[source]¶
Mark the transaction for rollback.
This operation itself will not close the transaction, instead it will allow you to elegantly revert changes.
- rollback()[source]¶
Roll-back the transaction.
First, the transaction is closed. A
TransactionRollback
event is emitted.
- class gaphor.event.TransactionBegin(context)[source]¶
This event denotes the beginning of a transaction.
Nested (sub-) transactions should not emit this signal.