class documentation

class UndoStackManager: (source)

View In Hierarchy

Undo stack implementation for TextBuffer. It records any changes to the buffer and allows undoing and redoing edits.

The stack undostack will be folded when you undo a few steps and then start editing again. This means that even the 'undo' action is recorded in the undo stakc and can always be undone itself; so no data is discarded.

Say you start with a certain buffer state "A", then make two edits ("B" and "C") and then undo the last one, so you get back in state "B":

  State A --> State B --> State C
                      <--
                      undo

when you now make a new edit ("D"), state "C" is not discarded, instead it is "folded" as follows:

  State A --> State B --> State C --> State B --> State D

so you can still go back to state "C" using Undo.

Undo actions

Each action is recorded as a 4-tuple of:

  • action_type: one of ACTION_INSERT, ACTION_DELETE, ACTION_APPLY_TAG, ACTION_REMOVE_TAG
  • start_iter: a Gtk.TextIter
  • end_iter: a Gtk.TextIter
  • data: either a (raw) ParseTree or a Gtk.TextTag

These actions are low level operations, so they are

Actions are collected as UndoActionGroups. When the user selects Undo or Redo we actually undo or redo a whole UndoActionGroup as a single step. E.g. inserting a link will consist of inserting the text and than applying the TextTag with the link data. These are technically two separate modifications of the TextBuffer, however when selecting Undo both are undone at once because they are combined in a single group.

Typically when recording modifications the action groups are delimited by the begin-user-action and end-user-action signals of the TextBuffer. (This is why we use the TextBuffer.user_action attribute context manager in the TextBuffer code.)

Also we try to group single-character inserts and deletes into words. This makes the stack more compact and makes the undo action more meaningful.

Method __init__ Constructor
Method block No summary
Method do_begin_insert_tree Undocumented
Method do_begin_user_action Undocumented
Method do_change_tag Undocumented
Method do_delete_range Undocumented
Method do_end_insert_tree Undocumented
Method do_end_user_action Undocumented
Method do_insert_pixbuf Undocumented
Method do_insert_text Undocumented
Method do_save_cursor Undocumented
Method flush_insert Flush all pending actions and store them on the stack
Method flush_redo_stack Fold the "redo" part of the stack, called before new actions are appended after some step was undone.
Method redo Redo one user action
Method unblock Start listening to events from the TextBuffer again
Method undo Undo one user action
Constant ACTION_APPLY_TAG Undocumented
Constant ACTION_DELETE Undocumented
Constant ACTION_INSERT Undocumented
Constant ACTION_REMOVE_TAG Undocumented
Constant MAX_UNDO Undocumented
Instance Variable block_count Undocumented
Instance Variable buffer Undocumented
Instance Variable group Undocumented
Instance Variable insert_pending Undocumented
Instance Variable interactive Undocumented
Instance Variable recording_handlers Undocumented
Instance Variable stack Undocumented
Instance Variable undo_count Undocumented
Method _replay Undocumented
Instance Variable _insert_tree_start Undocumented
def __init__(self, textbuffer): (source)
Constructor
Parameters
textbuffera Gtk.TextBuffer
def block(self): (source)

Stop listening to events from the TextBuffer until the next call to unblock(). Any change in between will not be undo-able (and mess up the undo stack) unless it is recorded explicitly.

The number of calls block() and unblock() is counted, so they can be called recursively.

def do_begin_insert_tree(self, buffer, interactive): (source)

Undocumented

def do_begin_user_action(self, buffer): (source)

Undocumented

def do_change_tag(self, buffer, tag, start, end, action): (source)

Undocumented

def do_delete_range(self, buffer, start, end): (source)

Undocumented

def do_end_insert_tree(self, buffer): (source)

Undocumented

def do_end_user_action(self, buffer): (source)

Undocumented

def do_insert_pixbuf(self, buffer, iter, pixbuf): (source)

Undocumented

def do_insert_text(self, buffer, iter, text, length): (source)

Undocumented

def do_save_cursor(self, buffer, iter): (source)

Undocumented

def flush_insert(self): (source)

Flush all pending actions and store them on the stack

The reason for this method is that because of the possibility of merging actions we do not immediatly request the parse tree for each single character insert. Instead we first group inserts based on cursor positions and then request the parse tree for the group at once. This method proceses all such delayed requests.

def flush_redo_stack(self): (source)
Fold the "redo" part of the stack, called before new actions are appended after some step was undone.
def redo(self): (source)
Redo one user action
def unblock(self): (source)
Start listening to events from the TextBuffer again
def undo(self): (source)
Undo one user action
ACTION_APPLY_TAG: int = (source)

Undocumented

Value
2
ACTION_DELETE: int = (source)

Undocumented

Value
-1
ACTION_INSERT: int = (source)

Undocumented

Value
1
ACTION_REMOVE_TAG: int = (source)

Undocumented

Value
-2
MAX_UNDO: int = (source)

Undocumented

Value
100
block_count: int = (source)

Undocumented

buffer = (source)

Undocumented

group = (source)

Undocumented

insert_pending: bool = (source)

Undocumented

interactive: bool = (source)

Undocumented

recording_handlers: list = (source)

Undocumented

stack: list = (source)

Undocumented

undo_count: int = (source)

Undocumented

def _replay(self, actiongroup): (source)

Undocumented

_insert_tree_start = (source)

Undocumented