Terry Jan Reedy | 6f7b0f5 | 2016-07-10 20:21:31 -0400 | [diff] [blame] | 1 | from tkinter import TclError |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 2 | |
Terry Jan Reedy | 6fa5bdc | 2016-05-28 13:22:31 -0400 | [diff] [blame] | 3 | from idlelib import searchengine |
| 4 | from idlelib.searchbase import SearchDialogBase |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 5 | |
| 6 | def _setup(text): |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 7 | "Create or find the singleton SearchDialog instance." |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 8 | root = text._root() |
Terry Jan Reedy | 6fa5bdc | 2016-05-28 13:22:31 -0400 | [diff] [blame] | 9 | engine = searchengine.get(root) |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 10 | if not hasattr(engine, "_searchdialog"): |
| 11 | engine._searchdialog = SearchDialog(root, engine) |
| 12 | return engine._searchdialog |
| 13 | |
| 14 | def find(text): |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 15 | "Handle the editor edit menu item and corresponding event." |
Chui Tey | 5a231c8f | 2002-11-06 02:18:45 +0000 | [diff] [blame] | 16 | pat = text.get("sel.first", "sel.last") |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 17 | return _setup(text).open(text, pat) # Open is inherited from SDBase. |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 18 | |
| 19 | def find_again(text): |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 20 | "Handle the editor edit menu item and corresponding event." |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 21 | return _setup(text).find_again(text) |
| 22 | |
| 23 | def find_selection(text): |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 24 | "Handle the editor edit menu item and corresponding event." |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 25 | return _setup(text).find_selection(text) |
| 26 | |
Terry Jan Reedy | bfbaa6b | 2016-08-31 00:50:55 -0400 | [diff] [blame] | 27 | |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 28 | class SearchDialog(SearchDialogBase): |
| 29 | |
| 30 | def create_widgets(self): |
Terry Jan Reedy | 2733618 | 2015-05-14 18:10:50 -0400 | [diff] [blame] | 31 | SearchDialogBase.create_widgets(self) |
Roger Serwy | 391f469 | 2013-06-10 23:01:20 -0500 | [diff] [blame] | 32 | self.make_button("Find Next", self.default_command, 1) |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 33 | |
| 34 | def default_command(self, event=None): |
| 35 | if not self.engine.getprog(): |
| 36 | return |
Roger Serwy | 391f469 | 2013-06-10 23:01:20 -0500 | [diff] [blame] | 37 | self.find_again(self.text) |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 38 | |
| 39 | def find_again(self, text): |
| 40 | if not self.engine.getpat(): |
| 41 | self.open(text) |
Kurt B. Kaiser | 0f4402d | 2002-09-18 03:10:10 +0000 | [diff] [blame] | 42 | return False |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 43 | if not self.engine.getprog(): |
Kurt B. Kaiser | 0f4402d | 2002-09-18 03:10:10 +0000 | [diff] [blame] | 44 | return False |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 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: |
Terry Jan Reedy | 3ff55a8 | 2016-08-10 23:44:54 -0400 | [diff] [blame] | 55 | self.bell() |
Kurt B. Kaiser | 0f4402d | 2002-09-18 03:10:10 +0000 | [diff] [blame] | 56 | return False |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 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") |
Kurt B. Kaiser | 0f4402d | 2002-09-18 03:10:10 +0000 | [diff] [blame] | 63 | return True |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 64 | else: |
Terry Jan Reedy | 3ff55a8 | 2016-08-10 23:44:54 -0400 | [diff] [blame] | 65 | self.bell() |
Kurt B. Kaiser | 0f4402d | 2002-09-18 03:10:10 +0000 | [diff] [blame] | 66 | return False |
David Scherer | 7aced17 | 2000-08-15 01:13:23 +0000 | [diff] [blame] | 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) |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 73 | |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 74 | |
| 75 | def _search_dialog(parent): # htest # |
Terry Jan Reedy | 6f7b0f5 | 2016-07-10 20:21:31 -0400 | [diff] [blame] | 76 | "Display search test box." |
| 77 | from tkinter import Toplevel, Text |
| 78 | from tkinter.ttk import Button |
| 79 | |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 80 | box = Toplevel(parent) |
| 81 | box.title("Test SearchDialog") |
Terry Jan Reedy | a748032 | 2016-07-10 17:28:10 -0400 | [diff] [blame] | 82 | x, y = map(int, parent.geometry().split('+')[1:]) |
| 83 | box.geometry("+%d+%d" % (x, y + 175)) |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 84 | text = Text(box, inactiveselectbackground='gray') |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 85 | text.pack() |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 86 | text.insert("insert","This is a sample string.\n"*5) |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 87 | |
| 88 | def show_find(): |
Terry Jan Reedy | 6f7b0f5 | 2016-07-10 20:21:31 -0400 | [diff] [blame] | 89 | text.tag_add('sel', '1.0', 'end') |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 90 | _setup(text).open(text) |
Terry Jan Reedy | 6f7b0f5 | 2016-07-10 20:21:31 -0400 | [diff] [blame] | 91 | text.tag_remove('sel', '1.0', 'end') |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 92 | |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 93 | button = Button(box, text="Search (selection ignored)", command=show_find) |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 94 | button.pack() |
| 95 | |
| 96 | if __name__ == '__main__': |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 97 | import unittest |
Terry Jan Reedy | a748032 | 2016-07-10 17:28:10 -0400 | [diff] [blame] | 98 | unittest.main('idlelib.idle_test.test_search', |
Terry Jan Reedy | b236fe4 | 2016-05-17 18:18:37 -0400 | [diff] [blame] | 99 | verbosity=2, exit=False) |
Terry Jan Reedy | a748032 | 2016-07-10 17:28:10 -0400 | [diff] [blame] | 100 | |
Terry Jan Reedy | 0a4d13e | 2014-05-27 03:30:54 -0400 | [diff] [blame] | 101 | from idlelib.idle_test.htest import run |
| 102 | run(_search_dialog) |