1ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom Tkinter import * 2ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 3ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom idlelib import SearchEngine 4ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom idlelib.SearchDialogBase import SearchDialogBase 5ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport re 6ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 7ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 8ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef replace(text): 9ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot root = text._root() 10ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot engine = SearchEngine.get(root) 11ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not hasattr(engine, "_replacedialog"): 12ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot engine._replacedialog = ReplaceDialog(root, engine) 13ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot dialog = engine._replacedialog 14ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot dialog.open(text) 15ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 16ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 17ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass ReplaceDialog(SearchDialogBase): 18ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 19ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot title = "Replace Dialog" 20ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot icon = "Replace" 21ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 22ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __init__(self, root, engine): 23ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot SearchDialogBase.__init__(self, root, engine) 24ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.replvar = StringVar(root) 25ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 26ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def open(self, text): 27ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot SearchDialogBase.open(self, text) 28ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 29ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = text.index("sel.first") 30ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except TclError: 31ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = None 32ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 33ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = text.index("sel.last") 34ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except TclError: 35ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = None 36ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = first or text.index("insert") 37ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = last or first 38ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.show_hit(first, last) 39ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.ok = 1 40ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 41ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def create_entries(self): 42ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot SearchDialogBase.create_entries(self) 43ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.replent = self.make_entry("Replace with:", self.replvar) 44ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 45ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def create_command_buttons(self): 46ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot SearchDialogBase.create_command_buttons(self) 47ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.make_button("Find", self.find_it) 48ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.make_button("Replace", self.replace_it) 49ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.make_button("Replace+Find", self.default_command, 1) 50ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.make_button("Replace All", self.replace_all) 51ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 52ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def find_it(self, event=None): 53ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.do_find(0) 54ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 55ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def replace_it(self, event=None): 56ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.do_find(self.ok): 57ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.do_replace() 58ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 59ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def default_command(self, event=None): 60ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.do_find(self.ok): 61ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.do_replace(): # Only find next match if replace succeeded. 62ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # A bad re can cause a it to fail. 63ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.do_find(0) 64ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 65ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def _replace_expand(self, m, repl): 66ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot """ Helper function for expanding a regular expression 67ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot in the replace field, if needed. """ 68ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.engine.isre(): 69ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 70ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot new = m.expand(repl) 71ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except re.error: 72ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.engine.report_error(repl, 'Invalid Replace Expression') 73ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot new = None 74ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 75ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot new = repl 76ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return new 77ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 78ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def replace_all(self, event=None): 79ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot prog = self.engine.getprog() 80ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not prog: 81ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return 82ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot repl = self.replvar.get() 83ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text = self.text 84ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot res = self.engine.search_text(text, prog) 85ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not res: 86ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.bell() 87ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return 88ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_remove("sel", "1.0", "end") 89ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_remove("hit", "1.0", "end") 90ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot line = res[0] 91ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot col = res[1].start() 92ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.engine.iswrap(): 93ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot line = 1 94ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot col = 0 95ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ok = 1 96ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = last = None 97ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # XXX ought to replace circular instead of top-to-bottom when wrapping 98ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.undo_block_start() 99ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot while 1: 100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot res = self.engine.search_forward(text, prog, line, col, 0, ok) 101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not res: 102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot break 103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot line, m = res 104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot chars = text.get("%d.0" % line, "%d.0" % (line+1)) 105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot orig = m.group() 106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot new = self._replace_expand(m, repl) 107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if new is None: 108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot break 109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot i, j = m.span() 110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = "%d.%d" % (line, i) 111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = "%d.%d" % (line, j) 112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if new == orig: 113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.mark_set("insert", last) 114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.mark_set("insert", first) 116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if first != last: 117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.delete(first, last) 118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if new: 119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.insert(first, new) 120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot col = i + len(new) 121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ok = 0 122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.undo_block_stop() 123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if first and last: 124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.show_hit(first, last) 125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.close() 126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def do_find(self, ok=0): 128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not self.engine.getprog(): 129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return False 130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text = self.text 131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot res = self.engine.search_text(text, None, ok) 132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not res: 133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.bell() 134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return False 135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot line, m = res 136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot i, j = m.span() 137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = "%d.%d" % (line, i) 138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = "%d.%d" % (line, j) 139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.show_hit(first, last) 140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.ok = 1 141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return True 142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def do_replace(self): 144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot prog = self.engine.getprog() 145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not prog: 146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return False 147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text = self.text 148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = pos = text.index("sel.first") 150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot last = text.index("sel.last") 151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except TclError: 152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot pos = None 153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not pos: 154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot first = last = pos = text.index("insert") 155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot line, col = SearchEngine.get_line_col(pos) 156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot chars = text.get("%d.0" % line, "%d.0" % (line+1)) 157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot m = prog.match(chars, col) 158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not prog: 159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return False 160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot new = self._replace_expand(m, self.replvar.get()) 161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if new is None: 162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return False 163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.mark_set("insert", first) 164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.undo_block_start() 165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if m.group(): 166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.delete(first, last) 167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if new: 168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.insert(first, new) 169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.undo_block_stop() 170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.show_hit(first, text.index("insert")) 171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.ok = 0 172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return True 173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def show_hit(self, first, last): 175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text = self.text 176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.mark_set("insert", first) 177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_remove("sel", "1.0", "end") 178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_add("sel", first, last) 179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_remove("hit", "1.0", "end") 180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if first == last: 181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_add("hit", first) 182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.tag_add("hit", first, last) 184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.see("insert") 185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text.update_idletasks() 186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def close(self, event=None): 188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot SearchDialogBase.close(self, event) 189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.text.tag_remove("hit", "1.0", "end") 190