Marked strings as translatable and added Italian translation (Roberto
[rox-edit.git] / buffer.py
blob9f4a9c146323a6d5481d4d7bc1fc39ad76d18c09
1 import rox
2 from rox import g
4 DELETE = 1
5 INSERT = 2
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."
13 def __init__(self):
14 g.TextBuffer.__init__(self, None)
15 self.in_progress = None
16 self.undo_buffer = []
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
25 if self.in_progress:
26 self.undo_buffer.append(self.in_progress)
27 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,
35 start.get_offset(),
36 buffer.get_slice(start, end, g.TRUE)))
37 if self.redo_buffer:
38 self.redo_buffer = []
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))
45 if self.redo_buffer:
46 self.redo_buffer = []
48 try:
49 g.TextBuffer(None).insert_at_cursor('hello')
50 except:
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):
58 if op[0] == DELETE:
59 start = self.get_iter_at_offset(op[1])
60 end = self.get_iter_at_offset(op[2])
61 self.delete(start, end)
62 elif op[0] == INSERT:
63 start = self.get_iter_at_offset(op[1])
64 self.insert(start, op[2])
65 else:
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
71 if not hist:
72 g.gdk.beep()
73 return # Nothing to undo/redo
75 assert not self.in_progress
77 # List of actions to perform
78 group = hist.pop()
80 old_redo, self.redo_buffer = self.redo_buffer, None
82 try:
83 self.begin_user_action()
84 group.reverse()
85 for action in group:
86 self.do_action(action)
87 finally:
88 self.redo_buffer = old_redo
89 if hist is self.undo_buffer:
90 self.redo_buffer.append(self.in_progress)
91 else:
92 self.undo_buffer.append(self.in_progress)
93 self.in_progress = []
95 self.end_user_action()
97 def redo(self): self.undo(hist = self.redo_buffer)