1from tkinter import TclError 2 3from idlelib import searchengine 4from idlelib.searchbase import SearchDialogBase 5 6def _setup(text): 7 "Create or find the singleton SearchDialog instance." 8 root = text._root() 9 engine = searchengine.get(root) 10 if not hasattr(engine, "_searchdialog"): 11 engine._searchdialog = SearchDialog(root, engine) 12 return engine._searchdialog 13 14def find(text): 15 "Handle the editor edit menu item and corresponding event." 16 pat = text.get("sel.first", "sel.last") 17 return _setup(text).open(text, pat) # Open is inherited from SDBase. 18 19def find_again(text): 20 "Handle the editor edit menu item and corresponding event." 21 return _setup(text).find_again(text) 22 23def find_selection(text): 24 "Handle the editor edit menu item and corresponding event." 25 return _setup(text).find_selection(text) 26 27 28class SearchDialog(SearchDialogBase): 29 30 def create_widgets(self): 31 SearchDialogBase.create_widgets(self) 32 self.make_button("Find Next", self.default_command, 1) 33 34 def default_command(self, event=None): 35 if not self.engine.getprog(): 36 return 37 self.find_again(self.text) 38 39 def find_again(self, text): 40 if not self.engine.getpat(): 41 self.open(text) 42 return False 43 if not self.engine.getprog(): 44 return False 45 res = self.engine.search_text(text) 46 if res: 47 line, m = res 48 i, j = m.span() 49 first = "%d.%d" % (line, i) 50 last = "%d.%d" % (line, j) 51 try: 52 selfirst = text.index("sel.first") 53 sellast = text.index("sel.last") 54 if selfirst == first and sellast == last: 55 self.bell() 56 return False 57 except TclError: 58 pass 59 text.tag_remove("sel", "1.0", "end") 60 text.tag_add("sel", first, last) 61 text.mark_set("insert", self.engine.isback() and first or last) 62 text.see("insert") 63 return True 64 else: 65 self.bell() 66 return False 67 68 def find_selection(self, text): 69 pat = text.get("sel.first", "sel.last") 70 if pat: 71 self.engine.setcookedpat(pat) 72 return self.find_again(text) 73 74 75def _search_dialog(parent): # htest # 76 "Display search test box." 77 from tkinter import Toplevel, Text 78 from tkinter.ttk import Frame, Button 79 80 top = Toplevel(parent) 81 top.title("Test SearchDialog") 82 x, y = map(int, parent.geometry().split('+')[1:]) 83 top.geometry("+%d+%d" % (x, y + 175)) 84 85 frame = Frame(top) 86 frame.pack() 87 text = Text(frame, inactiveselectbackground='gray') 88 text.pack() 89 text.insert("insert","This is a sample string.\n"*5) 90 91 def show_find(): 92 text.tag_add('sel', '1.0', 'end') 93 _setup(text).open(text) 94 text.tag_remove('sel', '1.0', 'end') 95 96 button = Button(frame, text="Search (selection ignored)", command=show_find) 97 button.pack() 98 99if __name__ == '__main__': 100 from unittest import main 101 main('idlelib.idle_test.test_search', verbosity=2, exit=False) 102 103 from idlelib.idle_test.htest import run 104 run(_search_dialog) 105