percolator.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 insertfilterafter(self, filter, after):
  34. assert isinstance(filter, Delegator)
  35. assert isinstance(after, Delegator)
  36. assert filter.delegate is None
  37. f = self.top
  38. f.resetcache()
  39. while f is not after:
  40. assert f is not self.bottom
  41. f = f.delegate
  42. f.resetcache()
  43. filter.setdelegate(f.delegate)
  44. f.setdelegate(filter)
  45. def removefilter(self, filter):
  46. # XXX Perhaps should only support popfilter()?
  47. assert isinstance(filter, Delegator)
  48. assert filter.delegate is not None
  49. f = self.top
  50. if f is filter:
  51. self.top = filter.delegate
  52. filter.setdelegate(None)
  53. else:
  54. while f.delegate is not filter:
  55. assert f is not self.bottom
  56. f.resetcache()
  57. f = f.delegate
  58. f.setdelegate(filter.delegate)
  59. filter.setdelegate(None)
  60. def _percolator(parent): # htest #
  61. import tkinter as tk
  62. class Tracer(Delegator):
  63. def __init__(self, name):
  64. self.name = name
  65. Delegator.__init__(self, None)
  66. def insert(self, *args):
  67. print(self.name, ": insert", args)
  68. self.delegate.insert(*args)
  69. def delete(self, *args):
  70. print(self.name, ": delete", args)
  71. self.delegate.delete(*args)
  72. box = tk.Toplevel(parent)
  73. box.title("Test Percolator")
  74. x, y = map(int, parent.geometry().split('+')[1:])
  75. box.geometry("+%d+%d" % (x, y + 175))
  76. text = tk.Text(box)
  77. p = Percolator(text)
  78. pin = p.insertfilter
  79. pout = p.removefilter
  80. t1 = Tracer("t1")
  81. t2 = Tracer("t2")
  82. def toggle1():
  83. (pin if var1.get() else pout)(t1)
  84. def toggle2():
  85. (pin if var2.get() else pout)(t2)
  86. text.pack()
  87. var1 = tk.IntVar(parent)
  88. cb1 = tk.Checkbutton(box, text="Tracer1", command=toggle1, variable=var1)
  89. cb1.pack()
  90. var2 = tk.IntVar(parent)
  91. cb2 = tk.Checkbutton(box, text="Tracer2", command=toggle2, variable=var2)
  92. cb2.pack()
  93. if __name__ == "__main__":
  94. from unittest import main
  95. main('idlelib.idle_test.test_percolator', verbosity=2, exit=False)
  96. from idlelib.idle_test.htest import run
  97. run(_percolator)