percolator.py 3.1 KB

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