|
1 from WidgetRedirector import WidgetRedirector |
|
2 from Delegator import Delegator |
|
3 |
|
4 class Percolator: |
|
5 |
|
6 def __init__(self, text): |
|
7 # XXX would be nice to inherit from Delegator |
|
8 self.text = text |
|
9 self.redir = WidgetRedirector(text) |
|
10 self.top = self.bottom = Delegator(text) |
|
11 self.bottom.insert = self.redir.register("insert", self.insert) |
|
12 self.bottom.delete = self.redir.register("delete", self.delete) |
|
13 self.filters = [] |
|
14 |
|
15 def close(self): |
|
16 while self.top is not self.bottom: |
|
17 self.removefilter(self.top) |
|
18 self.top = None |
|
19 self.bottom.setdelegate(None); self.bottom = None |
|
20 self.redir.close(); self.redir = None |
|
21 self.text = None |
|
22 |
|
23 def insert(self, index, chars, tags=None): |
|
24 # Could go away if inheriting from Delegator |
|
25 self.top.insert(index, chars, tags) |
|
26 |
|
27 def delete(self, index1, index2=None): |
|
28 # Could go away if inheriting from Delegator |
|
29 self.top.delete(index1, index2) |
|
30 |
|
31 def insertfilter(self, filter): |
|
32 # Perhaps rename to pushfilter()? |
|
33 assert isinstance(filter, Delegator) |
|
34 assert filter.delegate is None |
|
35 filter.setdelegate(self.top) |
|
36 self.top = filter |
|
37 |
|
38 def removefilter(self, filter): |
|
39 # XXX Perhaps should only support popfilter()? |
|
40 assert isinstance(filter, Delegator) |
|
41 assert filter.delegate is not None |
|
42 f = self.top |
|
43 if f is filter: |
|
44 self.top = filter.delegate |
|
45 filter.setdelegate(None) |
|
46 else: |
|
47 while f.delegate is not filter: |
|
48 assert f is not self.bottom |
|
49 f.resetcache() |
|
50 f = f.delegate |
|
51 f.setdelegate(filter.delegate) |
|
52 filter.setdelegate(None) |
|
53 |
|
54 |
|
55 def main(): |
|
56 class Tracer(Delegator): |
|
57 def __init__(self, name): |
|
58 self.name = name |
|
59 Delegator.__init__(self, None) |
|
60 def insert(self, *args): |
|
61 print self.name, ": insert", args |
|
62 self.delegate.insert(*args) |
|
63 def delete(self, *args): |
|
64 print self.name, ": delete", args |
|
65 self.delegate.delete(*args) |
|
66 root = Tk() |
|
67 root.wm_protocol("WM_DELETE_WINDOW", root.quit) |
|
68 text = Text() |
|
69 text.pack() |
|
70 text.focus_set() |
|
71 p = Percolator(text) |
|
72 t1 = Tracer("t1") |
|
73 t2 = Tracer("t2") |
|
74 p.insertfilter(t1) |
|
75 p.insertfilter(t2) |
|
76 root.mainloop() |
|
77 p.removefilter(t2) |
|
78 root.mainloop() |
|
79 p.insertfilter(t2) |
|
80 p.removefilter(t1) |
|
81 root.mainloop() |
|
82 |
|
83 if __name__ == "__main__": |
|
84 from Tkinter import * |
|
85 main() |