search.py 3.14 KB
Newer Older
1
from tkinter import TclError
David Scherer's avatar
David Scherer committed
2

3 4
from idlelib import searchengine
from idlelib.searchbase import SearchDialogBase
David Scherer's avatar
David Scherer committed
5 6

def _setup(text):
7
    "Create or find the singleton SearchDialog instance."
David Scherer's avatar
David Scherer committed
8
    root = text._root()
9
    engine = searchengine.get(root)
David Scherer's avatar
David Scherer committed
10 11 12 13 14
    if not hasattr(engine, "_searchdialog"):
        engine._searchdialog = SearchDialog(root, engine)
    return engine._searchdialog

def 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.
David Scherer's avatar
David Scherer committed
18 19

def find_again(text):
20
    "Handle the editor edit menu item and corresponding event."
David Scherer's avatar
David Scherer committed
21 22 23
    return _setup(text).find_again(text)

def find_selection(text):
24
    "Handle the editor edit menu item and corresponding event."
David Scherer's avatar
David Scherer committed
25 26
    return _setup(text).find_selection(text)

27

David Scherer's avatar
David Scherer committed
28 29 30
class SearchDialog(SearchDialogBase):

    def create_widgets(self):
31
        SearchDialogBase.create_widgets(self)
32
        self.make_button("Find Next", self.default_command, 1)
David Scherer's avatar
David Scherer committed
33 34 35 36

    def default_command(self, event=None):
        if not self.engine.getprog():
            return
37
        self.find_again(self.text)
David Scherer's avatar
David Scherer committed
38 39 40 41

    def find_again(self, text):
        if not self.engine.getpat():
            self.open(text)
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
42
            return False
David Scherer's avatar
David Scherer committed
43
        if not self.engine.getprog():
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
44
            return False
David Scherer's avatar
David Scherer committed
45 46 47 48 49 50 51 52 53 54
        res = self.engine.search_text(text)
        if res:
            line, m = res
            i, j = m.span()
            first = "%d.%d" % (line, i)
            last = "%d.%d" % (line, j)
            try:
                selfirst = text.index("sel.first")
                sellast = text.index("sel.last")
                if selfirst == first and sellast == last:
55
                    self.bell()
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
56
                    return False
David Scherer's avatar
David Scherer committed
57 58 59 60 61 62
            except TclError:
                pass
            text.tag_remove("sel", "1.0", "end")
            text.tag_add("sel", first, last)
            text.mark_set("insert", self.engine.isback() and first or last)
            text.see("insert")
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
63
            return True
David Scherer's avatar
David Scherer committed
64
        else:
65
            self.bell()
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
66
            return False
David Scherer's avatar
David Scherer committed
67 68 69 70 71 72

    def find_selection(self, text):
        pat = text.get("sel.first", "sel.last")
        if pat:
            self.engine.setcookedpat(pat)
        return self.find_again(text)
73

74 75

def _search_dialog(parent):  # htest #
76 77
    "Display search test box."
    from tkinter import Toplevel, Text
78
    from tkinter.ttk import Frame, Button
79

80 81
    top = Toplevel(parent)
    top.title("Test SearchDialog")
82
    x, y = map(int, parent.geometry().split('+')[1:])
83 84 85 86 87
    top.geometry("+%d+%d" % (x, y + 175))

    frame = Frame(top)
    frame.pack()
    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 98 99
    button.pack()

if __name__ == '__main__':
100 101
    from unittest import main
    main('idlelib.idle_test.test_search', verbosity=2, exit=False)
102

103 104
    from idlelib.idle_test.htest import run
    run(_search_dialog)