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