0001 from Tkinter import * 0002 import SearchEngine 0003 from SearchDialogBase import SearchDialogBase 0004 0005 def replace(text): 0006 root = text._root() 0007 engine = SearchEngine.get(root) 0008 if not hasattr(engine, "_replacedialog"): 0009 engine._replacedialog = ReplaceDialog(root, engine) 0010 dialog = engine._replacedialog 0011 dialog.open(text) 0012 0013 class ReplaceDialog(SearchDialogBase): 0014 0015 title = "Replace Dialog" 0016 icon = "Replace" 0017 0018 def __init__(self, root, engine): 0019 SearchDialogBase.__init__(self, root, engine) 0020 self.replvar = StringVar(root) 0021 0022 def open(self, text): 0023 SearchDialogBase.open(self, text) 0024 try: 0025 first = text.index("sel.first") 0026 except TclError: 0027 first = None 0028 try: 0029 last = text.index("sel.last") 0030 except TclError: 0031 last = None 0032 first = first or text.index("insert") 0033 last = last or first 0034 self.show_hit(first, last) 0035 self.ok = 1 0036 0037 def create_entries(self): 0038 SearchDialogBase.create_entries(self) 0039 self.replent = self.make_entry("Replace with:", self.replvar) 0040 0041 def create_command_buttons(self): 0042 SearchDialogBase.create_command_buttons(self) 0043 self.make_button("Find", self.find_it) 0044 self.make_button("Replace", self.replace_it) 0045 self.make_button("Replace+Find", self.default_command, 1) 0046 self.make_button("Replace All", self.replace_all) 0047 0048 def find_it(self, event=None): 0049 self.do_find(0) 0050 0051 def replace_it(self, event=None): 0052 if self.do_find(self.ok): 0053 self.do_replace() 0054 0055 def default_command(self, event=None): 0056 if self.do_find(self.ok): 0057 self.do_replace() 0058 self.do_find(0) 0059 0060 def replace_all(self, event=None): 0061 prog = self.engine.getprog() 0062 if not prog: 0063 return 0064 repl = self.replvar.get() 0065 text = self.text 0066 res = self.engine.search_text(text, prog) 0067 if not res: 0068 text.bell() 0069 return 0070 text.tag_remove("sel", "1.0", "end") 0071 text.tag_remove("hit", "1.0", "end") 0072 line = res[0] 0073 col = res[1].start() 0074 if self.engine.iswrap(): 0075 line = 1 0076 col = 0 0077 ok = 1 0078 first = last = None 0079 # XXX ought to replace circular instead of top-to-bottom when wrapping 0080 text.undo_block_start() 0081 while 1: 0082 res = self.engine.search_forward(text, prog, line, col, 0, ok) 0083 if not res: 0084 break 0085 line, m = res 0086 chars = text.get("%d.0" % line, "%d.0" % (line+1)) 0087 orig = m.group() 0088 new = m.expand(repl) 0089 i, j = m.span() 0090 first = "%d.%d" % (line, i) 0091 last = "%d.%d" % (line, j) 0092 if new == orig: 0093 text.mark_set("insert", last) 0094 else: 0095 text.mark_set("insert", first) 0096 if first != last: 0097 text.delete(first, last) 0098 if new: 0099 text.insert(first, new) 0100 col = i + len(new) 0101 ok = 0 0102 text.undo_block_stop() 0103 if first and last: 0104 self.show_hit(first, last) 0105 self.close() 0106 0107 def do_find(self, ok=0): 0108 if not self.engine.getprog(): 0109 return False 0110 text = self.text 0111 res = self.engine.search_text(text, None, ok) 0112 if not res: 0113 text.bell() 0114 return False 0115 line, m = res 0116 i, j = m.span() 0117 first = "%d.%d" % (line, i) 0118 last = "%d.%d" % (line, j) 0119 self.show_hit(first, last) 0120 self.ok = 1 0121 return True 0122 0123 def do_replace(self): 0124 prog = self.engine.getprog() 0125 if not prog: 0126 return False 0127 text = self.text 0128 try: 0129 first = pos = text.index("sel.first") 0130 last = text.index("sel.last") 0131 except TclError: 0132 pos = None 0133 if not pos: 0134 first = last = pos = text.index("insert") 0135 line, col = SearchEngine.get_line_col(pos) 0136 chars = text.get("%d.0" % line, "%d.0" % (line+1)) 0137 m = prog.match(chars, col) 0138 if not prog: 0139 return False 0140 new = m.expand(self.replvar.get()) 0141 text.mark_set("insert", first) 0142 text.undo_block_start() 0143 if m.group(): 0144 text.delete(first, last) 0145 if new: 0146 text.insert(first, new) 0147 text.undo_block_stop() 0148 self.show_hit(first, text.index("insert")) 0149 self.ok = 0 0150 return True 0151 0152 def show_hit(self, first, last): 0153 text = self.text 0154 text.mark_set("insert", first) 0155 text.tag_remove("sel", "1.0", "end") 0156 text.tag_add("sel", first, last) 0157 text.tag_remove("hit", "1.0", "end") 0158 if first == last: 0159 text.tag_add("hit", first) 0160 else: 0161 text.tag_add("hit", first, last) 0162 text.see("insert") 0163 text.update_idletasks() 0164 0165 def close(self, event=None): 0166 SearchDialogBase.close(self, event) 0167 self.text.tag_remove("hit", "1.0", "end") 0168
Generated by PyXR 0.9.4