/Lib/idlelib/ReplaceDialog.py

http://unladen-swallow.googlecode.com/ · Python · 167 lines · 151 code · 15 blank · 1 comment · 31 complexity · 07aa7c62e7f62454dd7df82857851a00 MD5 · raw file

  1. from Tkinter import *
  2. import SearchEngine
  3. from SearchDialogBase import SearchDialogBase
  4. def replace(text):
  5. root = text._root()
  6. engine = SearchEngine.get(root)
  7. if not hasattr(engine, "_replacedialog"):
  8. engine._replacedialog = ReplaceDialog(root, engine)
  9. dialog = engine._replacedialog
  10. dialog.open(text)
  11. class ReplaceDialog(SearchDialogBase):
  12. title = "Replace Dialog"
  13. icon = "Replace"
  14. def __init__(self, root, engine):
  15. SearchDialogBase.__init__(self, root, engine)
  16. self.replvar = StringVar(root)
  17. def open(self, text):
  18. SearchDialogBase.open(self, text)
  19. try:
  20. first = text.index("sel.first")
  21. except TclError:
  22. first = None
  23. try:
  24. last = text.index("sel.last")
  25. except TclError:
  26. last = None
  27. first = first or text.index("insert")
  28. last = last or first
  29. self.show_hit(first, last)
  30. self.ok = 1
  31. def create_entries(self):
  32. SearchDialogBase.create_entries(self)
  33. self.replent = self.make_entry("Replace with:", self.replvar)
  34. def create_command_buttons(self):
  35. SearchDialogBase.create_command_buttons(self)
  36. self.make_button("Find", self.find_it)
  37. self.make_button("Replace", self.replace_it)
  38. self.make_button("Replace+Find", self.default_command, 1)
  39. self.make_button("Replace All", self.replace_all)
  40. def find_it(self, event=None):
  41. self.do_find(0)
  42. def replace_it(self, event=None):
  43. if self.do_find(self.ok):
  44. self.do_replace()
  45. def default_command(self, event=None):
  46. if self.do_find(self.ok):
  47. self.do_replace()
  48. self.do_find(0)
  49. def replace_all(self, event=None):
  50. prog = self.engine.getprog()
  51. if not prog:
  52. return
  53. repl = self.replvar.get()
  54. text = self.text
  55. res = self.engine.search_text(text, prog)
  56. if not res:
  57. text.bell()
  58. return
  59. text.tag_remove("sel", "1.0", "end")
  60. text.tag_remove("hit", "1.0", "end")
  61. line = res[0]
  62. col = res[1].start()
  63. if self.engine.iswrap():
  64. line = 1
  65. col = 0
  66. ok = 1
  67. first = last = None
  68. # XXX ought to replace circular instead of top-to-bottom when wrapping
  69. text.undo_block_start()
  70. while 1:
  71. res = self.engine.search_forward(text, prog, line, col, 0, ok)
  72. if not res:
  73. break
  74. line, m = res
  75. chars = text.get("%d.0" % line, "%d.0" % (line+1))
  76. orig = m.group()
  77. new = m.expand(repl)
  78. i, j = m.span()
  79. first = "%d.%d" % (line, i)
  80. last = "%d.%d" % (line, j)
  81. if new == orig:
  82. text.mark_set("insert", last)
  83. else:
  84. text.mark_set("insert", first)
  85. if first != last:
  86. text.delete(first, last)
  87. if new:
  88. text.insert(first, new)
  89. col = i + len(new)
  90. ok = 0
  91. text.undo_block_stop()
  92. if first and last:
  93. self.show_hit(first, last)
  94. self.close()
  95. def do_find(self, ok=0):
  96. if not self.engine.getprog():
  97. return False
  98. text = self.text
  99. res = self.engine.search_text(text, None, ok)
  100. if not res:
  101. text.bell()
  102. return False
  103. line, m = res
  104. i, j = m.span()
  105. first = "%d.%d" % (line, i)
  106. last = "%d.%d" % (line, j)
  107. self.show_hit(first, last)
  108. self.ok = 1
  109. return True
  110. def do_replace(self):
  111. prog = self.engine.getprog()
  112. if not prog:
  113. return False
  114. text = self.text
  115. try:
  116. first = pos = text.index("sel.first")
  117. last = text.index("sel.last")
  118. except TclError:
  119. pos = None
  120. if not pos:
  121. first = last = pos = text.index("insert")
  122. line, col = SearchEngine.get_line_col(pos)
  123. chars = text.get("%d.0" % line, "%d.0" % (line+1))
  124. m = prog.match(chars, col)
  125. if not prog:
  126. return False
  127. new = m.expand(self.replvar.get())
  128. text.mark_set("insert", first)
  129. text.undo_block_start()
  130. if m.group():
  131. text.delete(first, last)
  132. if new:
  133. text.insert(first, new)
  134. text.undo_block_stop()
  135. self.show_hit(first, text.index("insert"))
  136. self.ok = 0
  137. return True
  138. def show_hit(self, first, last):
  139. text = self.text
  140. text.mark_set("insert", first)
  141. text.tag_remove("sel", "1.0", "end")
  142. text.tag_add("sel", first, last)
  143. text.tag_remove("hit", "1.0", "end")
  144. if first == last:
  145. text.tag_add("hit", first)
  146. else:
  147. text.tag_add("hit", first, last)
  148. text.see("insert")
  149. text.update_idletasks()
  150. def close(self, event=None):
  151. SearchDialogBase.close(self, event)
  152. self.text.tag_remove("hit", "1.0", "end")