• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from idlelib.delegator import Delegator
2from idlelib.redirector import WidgetRedirector
3
4
5class Percolator:
6
7    def __init__(self, text):
8        # XXX would be nice to inherit from Delegator
9        self.text = text
10        self.redir = WidgetRedirector(text)
11        self.top = self.bottom = Delegator(text)
12        self.bottom.insert = self.redir.register("insert", self.insert)
13        self.bottom.delete = self.redir.register("delete", self.delete)
14        self.filters = []
15
16    def close(self):
17        while self.top is not self.bottom:
18            self.removefilter(self.top)
19        self.top = None
20        self.bottom.setdelegate(None)
21        self.bottom = None
22        self.redir.close()
23        self.redir = None
24        self.text = None
25
26    def insert(self, index, chars, tags=None):
27        # Could go away if inheriting from Delegator
28        self.top.insert(index, chars, tags)
29
30    def delete(self, index1, index2=None):
31        # Could go away if inheriting from Delegator
32        self.top.delete(index1, index2)
33
34    def insertfilter(self, filter):
35        # Perhaps rename to pushfilter()?
36        assert isinstance(filter, Delegator)
37        assert filter.delegate is None
38        filter.setdelegate(self.top)
39        self.top = filter
40
41    def insertfilterafter(self, filter, after):
42        assert isinstance(filter, Delegator)
43        assert isinstance(after, Delegator)
44        assert filter.delegate is None
45
46        f = self.top
47        f.resetcache()
48        while f is not after:
49            assert f is not self.bottom
50            f = f.delegate
51            f.resetcache()
52
53        filter.setdelegate(f.delegate)
54        f.setdelegate(filter)
55
56    def removefilter(self, filter):
57        # XXX Perhaps should only support popfilter()?
58        assert isinstance(filter, Delegator)
59        assert filter.delegate is not None
60        f = self.top
61        if f is filter:
62            self.top = filter.delegate
63            filter.setdelegate(None)
64        else:
65            while f.delegate is not filter:
66                assert f is not self.bottom
67                f.resetcache()
68                f = f.delegate
69            f.setdelegate(filter.delegate)
70            filter.setdelegate(None)
71
72
73def _percolator(parent):  # htest #
74    import tkinter as tk
75
76    class Tracer(Delegator):
77        def __init__(self, name):
78            self.name = name
79            Delegator.__init__(self, None)
80
81        def insert(self, *args):
82            print(self.name, ": insert", args)
83            self.delegate.insert(*args)
84
85        def delete(self, *args):
86            print(self.name, ": delete", args)
87            self.delegate.delete(*args)
88
89    box = tk.Toplevel(parent)
90    box.title("Test Percolator")
91    x, y = map(int, parent.geometry().split('+')[1:])
92    box.geometry("+%d+%d" % (x, y + 175))
93    text = tk.Text(box)
94    p = Percolator(text)
95    pin = p.insertfilter
96    pout = p.removefilter
97    t1 = Tracer("t1")
98    t2 = Tracer("t2")
99
100    def toggle1():
101        (pin if var1.get() else pout)(t1)
102    def toggle2():
103        (pin if var2.get() else pout)(t2)
104
105    text.pack()
106    var1 = tk.IntVar(parent)
107    cb1 = tk.Checkbutton(box, text="Tracer1", command=toggle1, variable=var1)
108    cb1.pack()
109    var2 = tk.IntVar(parent)
110    cb2 = tk.Checkbutton(box, text="Tracer2", command=toggle2, variable=var2)
111    cb2.pack()
112
113if __name__ == "__main__":
114    from unittest import main
115    main('idlelib.idle_test.test_percolator', verbosity=2, exit=False)
116
117    from idlelib.idle_test.htest import run
118    run(_percolator)
119