7 # As operations are performed, they are added to 'in_progress'.
8 # When complete, the whole group is added to undo_buffer.
10 class Buffer(g
.TextBuffer
):
11 "A buffer that deals with undo/redo."
14 g
.TextBuffer
.__init
__(self
, None)
15 self
.in_progress
= None
17 self
.redo_buffer
= [] # Will be None during undo or redo
19 def start_undo_history(self
):
20 def begin(buffer): self
.in_progress
= []
22 self
.connect('begin-user-action', begin
)
23 def end_action(buffer):
24 assert self
.in_progress
is not None
26 self
.undo_buffer
.append(self
.in_progress
)
28 self
.in_progress
= None
29 self
.connect('end-user-action', end_action
)
30 self
.connect('delete-range', self
.delete_range
)
31 self
.connect('insert-text', self
.insert_text
)
33 def delete_range(self
, buffer, start
, end
):
34 self
.in_progress
.append((INSERT
,
36 buffer.get_slice(start
, end
, g
.TRUE
)))
40 def insert_text(self
, buffer, where
, text
, len):
41 text
= text
[:len] # PyGtk bug?
42 start
= where
.get_offset()
43 self
.in_progress
.append((DELETE
,
44 start
, start
+ len, text
))
49 g
.TextBuffer(None).insert_at_cursor('hello')
51 # Old version of pygtk
52 def insert(self
, iter, text
):
53 g
.TextBuffer
.insert(self
, iter, text
, -1)
54 def insert_at_cursor(self
, text
):
55 g
.TextBuffer
.insert_at_cursor(self
, text
, -1)
57 def do_action(self
, op
):
59 start
= self
.get_iter_at_offset(op
[1])
60 end
= self
.get_iter_at_offset(op
[2])
61 self
.delete(start
, end
)
63 start
= self
.get_iter_at_offset(op
[1])
64 self
.insert(start
, op
[2])
66 rox
.alert('Unknown entry in undo buffer!\n' + `op`
)
68 def undo(self
, hist
= None):
69 if hist
is None: hist
= self
.undo_buffer
73 return # Nothing to undo/redo
75 assert not self
.in_progress
77 # List of actions to perform
80 old_redo
, self
.redo_buffer
= self
.redo_buffer
, None
83 self
.begin_user_action()
86 self
.do_action(action
)
88 self
.redo_buffer
= old_redo
89 if hist
is self
.undo_buffer
:
90 self
.redo_buffer
.append(self
.in_progress
)
92 self
.undo_buffer
.append(self
.in_progress
)
95 self
.end_user_action()
97 def redo(self
): self
.undo(hist
= self
.redo_buffer
)