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