New release.
[rox-edit.git] / buffer.py
blob72fccf1d90df4aa8a4e53bd50552cfad1ccbbb50
1 import rox
2 from rox import g
4 DELETE = 1
5 INSERT = 2
7 class Buffer(g.TextBuffer):
8 "A buffer that deals with undo/redo."
10 def __init__(self):
11 g.TextBuffer.__init__(self, None)
12 self.undo_buffer = []
13 self.redo_buffer = [] # Will be None during undo or redo
15 def start_undo_history(self):
16 self.connect('delete-range', self.delete_range)
17 self.connect('insert-text', self.insert_text)
19 def delete_range(self, buffer, start, end):
20 self.undo_buffer.append((INSERT,
21 start.get_offset(),
22 buffer.get_slice(start, end, g.TRUE)))
23 if self.redo_buffer:
24 self.redo_buffer = []
26 def insert_text(self, buffer, where, text, len):
27 text = text[:len] # PyGtk bug?
28 start = where.get_offset()
29 self.undo_buffer.append((DELETE, start, start + len, text))
30 if self.redo_buffer:
31 self.redo_buffer = []
33 def do_action(self, op):
34 if op[0] == DELETE:
35 start = self.get_iter_at_offset(op[1])
36 end = self.get_iter_at_offset(op[2])
37 self.delete(start, end)
38 elif op[0] == INSERT:
39 start = self.get_iter_at_offset(op[1])
40 try:
41 self.insert(start, op[2])
42 except TypeError:
43 self.insert(start, op[2], -1)
44 else:
45 rox.alert('Unknown entry in undo buffer!\n' + `op`)
47 def undo(self):
48 if not self.undo_buffer:
49 g.gdk.beep()
50 return
51 op = self.undo_buffer.pop()
53 old_undo = self.undo_buffer
54 self.undo_buffer = self.redo_buffer # Put undos in redo buffer
55 self.redo_buffer = None # Don't clear redo buffer
57 try:
58 self.do_action(op)
59 finally:
60 self.redo_buffer = self.undo_buffer
61 self.undo_buffer = old_undo
63 def redo(self):
64 if not self.redo_buffer:
65 g.gdk.beep()
66 return
67 op = self.redo_buffer.pop()
69 old_redo = self.redo_buffer
70 self.redo_buffer = None # Don't clear redo buffer
72 try:
73 self.do_action(op)
74 finally:
75 self.redo_buffer = old_redo