Example #1
0
 def __init__(self, textbuffer):
     self.undo_stack = UndoStack(MAX_UNDOS)
     self._next_action = None
     self._buffer = textbuffer
     self.after_changed = Listeners()
Example #2
0
 def __init__(self, textbuffer):
     self.undo_stack = UndoStack(MAX_UNDOS)
     self._next_action = None
     self._buffer = textbuffer
     self.after_changed = Listeners()
Example #3
0
class UndoHandler(object):
    """TextBuffer Handler that provides undo/redo functionality"""
    def __init__(self, textbuffer):
        self.undo_stack = UndoStack(MAX_UNDOS)
        self._next_action = None
        self._buffer = textbuffer
        self.after_changed = Listeners()

    def on_insert_text(self, textbuffer, it, text, length):
        """Callback for text insert"""

        # NOTE: GTK does not give us a proper UTF string, so fix it
        text = unicode(text, "utf_8")
        length = len(text)

        # setup next action
        offset = it.get_offset()
        self._next_action = InsertAction(
            textbuffer,
            offset,
            text,
            length,
            cursor_insert=(offset == textbuffer.get_iter_at_mark(
                textbuffer.get_insert()).get_offset()))

    def on_delete_range(self, textbuffer, start, end):
        """Callback for delete range"""
        # setup next action
        self._next_action = DeleteAction(
            textbuffer, start.get_offset(), end.get_offset(),
            start.get_slice(end),
            textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset())

    def on_insert_pixbuf(self, textbuffer, it, pixbuf):
        """Callback for inserting a pixbuf"""
        pass

    def on_insert_child_anchor(self, textbuffer, it, anchor):
        """Callback for inserting a child anchor"""
        # setup next action
        self._next_action = InsertChildAction(textbuffer, it.get_offset(),
                                              anchor)

    def on_apply_tag(self, textbuffer, tag, start, end):
        """Callback for tag apply"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(),
                           end.get_offset(), True)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_remove_tag(self, textbuffer, tag, start, end):
        """Callback for tag remove"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(),
                           end.get_offset(), False)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_changed(self, textbuffer):
        """Callback for buffer change"""

        # process actions that have changed the buffer
        if not self._next_action:
            return

        textbuffer.begin_user_action()

        # add action to undo stack
        action = self._next_action
        self._next_action = None
        self.undo_stack.do(action.do, action.undo, False)

        # perfrom additional "clean-up" actions
        # note: only if undo/redo is not currently in progress
        if not self.undo_stack.is_in_progress():
            self.after_changed.notify(action)

        textbuffer.end_user_action()
Example #4
0
class UndoHandler(object):
    """TextBuffer Handler that provides undo/redo functionality"""

    def __init__(self, textbuffer):
        self.undo_stack = UndoStack(MAX_UNDOS)
        self._next_action = None
        self._buffer = textbuffer
        self.after_changed = Listeners()

    def on_insert_text(self, textbuffer, it, text, length):
        """Callback for text insert"""

        # NOTE: GTK does not give us a proper UTF string, so fix it
        text = unicode(text, "utf_8")
        length = len(text)

        # setup next action
        offset = it.get_offset()
        self._next_action = InsertAction(
            textbuffer,
            offset,
            text,
            length,
            cursor_insert=(offset == textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset()),
        )

    def on_delete_range(self, textbuffer, start, end):
        """Callback for delete range"""
        # setup next action
        self._next_action = DeleteAction(
            textbuffer,
            start.get_offset(),
            end.get_offset(),
            start.get_slice(end),
            textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset(),
        )

    def on_insert_pixbuf(self, textbuffer, it, pixbuf):
        """Callback for inserting a pixbuf"""
        pass

    def on_insert_child_anchor(self, textbuffer, it, anchor):
        """Callback for inserting a child anchor"""
        # setup next action
        self._next_action = InsertChildAction(textbuffer, it.get_offset(), anchor)

    def on_apply_tag(self, textbuffer, tag, start, end):
        """Callback for tag apply"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(), end.get_offset(), True)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_remove_tag(self, textbuffer, tag, start, end):
        """Callback for tag remove"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(), end.get_offset(), False)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_changed(self, textbuffer):
        """Callback for buffer change"""

        # process actions that have changed the buffer
        if not self._next_action:
            return

        textbuffer.begin_user_action()

        # add action to undo stack
        action = self._next_action
        self._next_action = None
        self.undo_stack.do(action.do, action.undo, False)

        # perfrom additional "clean-up" actions
        # note: only if undo/redo is not currently in progress
        if not self.undo_stack.is_in_progress():
            self.after_changed.notify(action)

        textbuffer.end_user_action()