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."
15 g
.TextBuffer
.__init
__(self
, None)
16 self
.in_progress
= None
18 self
.redo_buffer
= [] # Will be None during undo or redo
20 def start_undo_history(self
):
22 self
.action_nest_level
+= 1
23 if self
.action_nest_level
== 1:
24 assert self
.in_progress
is None
27 self
.connect('begin-user-action', begin
)
28 def end_action(buffer):
29 self
.action_nest_level
-= 1
30 assert self
.action_nest_level
>= 0
31 if self
.action_nest_level
== 0:
32 assert self
.in_progress
is not None
34 self
.undo_buffer
.append(self
.in_progress
)
35 self
.in_progress
= None
36 self
.connect('end-user-action', end_action
)
37 self
.connect('delete-range', self
.delete_range
)
38 self
.connect('insert-text', self
.insert_text
)
40 def delete_range(self
, buffer, start
, end
):
41 self
.in_progress
.append((INSERT
,
43 buffer.get_slice(start
, end
, g
.TRUE
)))
47 def insert_text(self
, buffer, where
, text
, len):
48 text
= text
[:len] # PyGtk bug?
49 start
= where
.get_offset()
50 self
.in_progress
.append((DELETE
,
51 start
, start
+ len, text
))
56 g
.TextBuffer(None).insert_at_cursor('hello')
58 # Old version of pygtk
59 def insert(self
, iter, text
):
60 g
.TextBuffer
.insert(self
, iter, text
, -1)
61 def insert_at_cursor(self
, text
):
62 g
.TextBuffer
.insert_at_cursor(self
, text
, -1)
64 def do_action(self
, op
):
66 start
= self
.get_iter_at_offset(op
[1])
67 end
= self
.get_iter_at_offset(op
[2])
68 self
.delete(start
, end
)
70 start
= self
.get_iter_at_offset(op
[1])
71 self
.insert(start
, op
[2])
73 rox
.alert('Unknown entry in undo buffer!\n' + `op`
)
75 def undo(self
, hist
= None):
76 if hist
is None: hist
= self
.undo_buffer
80 return # Nothing to undo/redo
82 assert not self
.in_progress
84 # List of actions to perform
87 old_redo
, self
.redo_buffer
= self
.redo_buffer
, None
90 self
.begin_user_action()
93 self
.do_action(action
)
95 self
.redo_buffer
= old_redo
96 if hist
is self
.undo_buffer
:
97 self
.redo_buffer
.append(self
.in_progress
)
99 self
.undo_buffer
.append(self
.in_progress
)
100 self
.in_progress
= []
102 self
.end_user_action()
104 def redo(self
): self
.undo(hist
= self
.redo_buffer
)