Support older versions of pygtk (reported by Alastair Porter).
[rox-edit.git] / buffer.py
blobe553c6fbc78c09c7fb5b624d132aeb747731b510
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 try:
34 g.TextBuffer(None).insert_at_cursor('hello')
35 except:
36 # Old version of pygtk
37 def insert(self, iter, text):
38 g.TextBuffer.insert(self, iter, text, -1)
39 def insert_at_cursor(self, text):
40 g.TextBuffer.insert_at_cursor(self, text, -1)
42 def do_action(self, op):
43 if op[0] == DELETE:
44 start = self.get_iter_at_offset(op[1])
45 end = self.get_iter_at_offset(op[2])
46 self.delete(start, end)
47 elif op[0] == INSERT:
48 start = self.get_iter_at_offset(op[1])
49 self.insert(start, op[2])
50 else:
51 rox.alert('Unknown entry in undo buffer!\n' + `op`)
53 def undo(self):
54 if not self.undo_buffer:
55 g.gdk.beep()
56 return
57 op = self.undo_buffer.pop()
59 old_undo = self.undo_buffer
60 self.undo_buffer = self.redo_buffer # Put undos in redo buffer
61 self.redo_buffer = None # Don't clear redo buffer
63 try:
64 self.do_action(op)
65 finally:
66 self.redo_buffer = self.undo_buffer
67 self.undo_buffer = old_undo
69 def redo(self):
70 if not self.redo_buffer:
71 g.gdk.beep()
72 return
73 op = self.redo_buffer.pop()
75 old_redo = self.redo_buffer
76 self.redo_buffer = None # Don't clear redo buffer
78 try:
79 self.do_action(op)
80 finally:
81 self.redo_buffer = old_redo