mirror of
https://github.com/python/cpython.git
synced 2024-12-16 05:14:41 +08:00
ce86b10eb8
Rev 1.5 tim_one Convert a pile of obvious "yes/no" functions to return bool Rev 1.6 GvR Rev 1.7 Gvr (Already merged Idlefork ReplaceDialog.py 1.3.2.1 and 1.4) Rev 1.8 doerwalter (string methods) Rev 1.9 nnorwitz Remove unnecessary imports
168 lines
5.0 KiB
Python
168 lines
5.0 KiB
Python
from Tkinter import *
|
|
import SearchEngine
|
|
from SearchDialogBase import SearchDialogBase
|
|
|
|
def replace(text):
|
|
root = text._root()
|
|
engine = SearchEngine.get(root)
|
|
if not hasattr(engine, "_replacedialog"):
|
|
engine._replacedialog = ReplaceDialog(root, engine)
|
|
dialog = engine._replacedialog
|
|
dialog.open(text)
|
|
|
|
class ReplaceDialog(SearchDialogBase):
|
|
|
|
title = "Replace Dialog"
|
|
icon = "Replace"
|
|
|
|
def __init__(self, root, engine):
|
|
SearchDialogBase.__init__(self, root, engine)
|
|
self.replvar = StringVar(root)
|
|
|
|
def open(self, text):
|
|
SearchDialogBase.open(self, text)
|
|
try:
|
|
first = text.index("sel.first")
|
|
except TclError:
|
|
first = None
|
|
try:
|
|
last = text.index("sel.last")
|
|
except TclError:
|
|
last = None
|
|
first = first or text.index("insert")
|
|
last = last or first
|
|
self.show_hit(first, last)
|
|
self.ok = 1
|
|
|
|
def create_entries(self):
|
|
SearchDialogBase.create_entries(self)
|
|
self.replent = self.make_entry("Replace with:", self.replvar)
|
|
|
|
def create_command_buttons(self):
|
|
SearchDialogBase.create_command_buttons(self)
|
|
self.make_button("Find", self.find_it)
|
|
self.make_button("Replace", self.replace_it)
|
|
self.make_button("Replace+Find", self.default_command, 1)
|
|
self.make_button("Replace All", self.replace_all)
|
|
|
|
def find_it(self, event=None):
|
|
self.do_find(0)
|
|
|
|
def replace_it(self, event=None):
|
|
if self.do_find(self.ok):
|
|
self.do_replace()
|
|
|
|
def default_command(self, event=None):
|
|
if self.do_find(self.ok):
|
|
self.do_replace()
|
|
self.do_find(0)
|
|
|
|
def replace_all(self, event=None):
|
|
prog = self.engine.getprog()
|
|
if not prog:
|
|
return
|
|
repl = self.replvar.get()
|
|
text = self.text
|
|
res = self.engine.search_text(text, prog)
|
|
if not res:
|
|
text.bell()
|
|
return
|
|
text.tag_remove("sel", "1.0", "end")
|
|
text.tag_remove("hit", "1.0", "end")
|
|
line = res[0]
|
|
col = res[1].start()
|
|
if self.engine.iswrap():
|
|
line = 1
|
|
col = 0
|
|
ok = 1
|
|
first = last = None
|
|
# XXX ought to replace circular instead of top-to-bottom when wrapping
|
|
text.undo_block_start()
|
|
while 1:
|
|
res = self.engine.search_forward(text, prog, line, col, 0, ok)
|
|
if not res:
|
|
break
|
|
line, m = res
|
|
chars = text.get("%d.0" % line, "%d.0" % (line+1))
|
|
orig = m.group()
|
|
new = m.expand(repl)
|
|
i, j = m.span()
|
|
first = "%d.%d" % (line, i)
|
|
last = "%d.%d" % (line, j)
|
|
if new == orig:
|
|
text.mark_set("insert", last)
|
|
else:
|
|
text.mark_set("insert", first)
|
|
if first != last:
|
|
text.delete(first, last)
|
|
if new:
|
|
text.insert(first, new)
|
|
col = i + len(new)
|
|
ok = 0
|
|
text.undo_block_stop()
|
|
if first and last:
|
|
self.show_hit(first, last)
|
|
self.close()
|
|
|
|
def do_find(self, ok=0):
|
|
if not self.engine.getprog():
|
|
return False
|
|
text = self.text
|
|
res = self.engine.search_text(text, None, ok)
|
|
if not res:
|
|
text.bell()
|
|
return False
|
|
line, m = res
|
|
i, j = m.span()
|
|
first = "%d.%d" % (line, i)
|
|
last = "%d.%d" % (line, j)
|
|
self.show_hit(first, last)
|
|
self.ok = 1
|
|
return True
|
|
|
|
def do_replace(self):
|
|
prog = self.engine.getprog()
|
|
if not prog:
|
|
return False
|
|
text = self.text
|
|
try:
|
|
first = pos = text.index("sel.first")
|
|
last = text.index("sel.last")
|
|
except TclError:
|
|
pos = None
|
|
if not pos:
|
|
first = last = pos = text.index("insert")
|
|
line, col = SearchEngine.get_line_col(pos)
|
|
chars = text.get("%d.0" % line, "%d.0" % (line+1))
|
|
m = prog.match(chars, col)
|
|
if not prog:
|
|
return False
|
|
new = m.expand(self.replvar.get())
|
|
text.mark_set("insert", first)
|
|
text.undo_block_start()
|
|
if m.group():
|
|
text.delete(first, last)
|
|
if new:
|
|
text.insert(first, new)
|
|
text.undo_block_stop()
|
|
self.show_hit(first, text.index("insert"))
|
|
self.ok = 0
|
|
return True
|
|
|
|
def show_hit(self, first, last):
|
|
text = self.text
|
|
text.mark_set("insert", first)
|
|
text.tag_remove("sel", "1.0", "end")
|
|
text.tag_add("sel", first, last)
|
|
text.tag_remove("hit", "1.0", "end")
|
|
if first == last:
|
|
text.tag_add("hit", first)
|
|
else:
|
|
text.tag_add("hit", first, last)
|
|
text.see("insert")
|
|
text.update_idletasks()
|
|
|
|
def close(self, event=None):
|
|
SearchDialogBase.close(self, event)
|
|
self.text.tag_remove("hit", "1.0", "end")
|