Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/idlelib/search.py @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 """Search dialog for Find, Find Again, and Find Selection | |
2 functionality. | |
3 | |
4 Inherits from SearchDialogBase for GUI and uses searchengine | |
5 to prepare search pattern. | |
6 """ | |
7 from tkinter import TclError | |
8 | |
9 from idlelib import searchengine | |
10 from idlelib.searchbase import SearchDialogBase | |
11 | |
12 def _setup(text): | |
13 """Return the new or existing singleton SearchDialog instance. | |
14 | |
15 The singleton dialog saves user entries and preferences | |
16 across instances. | |
17 | |
18 Args: | |
19 text: Text widget containing the text to be searched. | |
20 """ | |
21 root = text._root() | |
22 engine = searchengine.get(root) | |
23 if not hasattr(engine, "_searchdialog"): | |
24 engine._searchdialog = SearchDialog(root, engine) | |
25 return engine._searchdialog | |
26 | |
27 def find(text): | |
28 """Open the search dialog. | |
29 | |
30 Module-level function to access the singleton SearchDialog | |
31 instance and open the dialog. If text is selected, it is | |
32 used as the search phrase; otherwise, the previous entry | |
33 is used. No search is done with this command. | |
34 """ | |
35 pat = text.get("sel.first", "sel.last") | |
36 return _setup(text).open(text, pat) # Open is inherited from SDBase. | |
37 | |
38 def find_again(text): | |
39 """Repeat the search for the last pattern and preferences. | |
40 | |
41 Module-level function to access the singleton SearchDialog | |
42 instance to search again using the user entries and preferences | |
43 from the last dialog. If there was no prior search, open the | |
44 search dialog; otherwise, perform the search without showing the | |
45 dialog. | |
46 """ | |
47 return _setup(text).find_again(text) | |
48 | |
49 def find_selection(text): | |
50 """Search for the selected pattern in the text. | |
51 | |
52 Module-level function to access the singleton SearchDialog | |
53 instance to search using the selected text. With a text | |
54 selection, perform the search without displaying the dialog. | |
55 Without a selection, use the prior entry as the search phrase | |
56 and don't display the dialog. If there has been no prior | |
57 search, open the search dialog. | |
58 """ | |
59 return _setup(text).find_selection(text) | |
60 | |
61 | |
62 class SearchDialog(SearchDialogBase): | |
63 "Dialog for finding a pattern in text." | |
64 | |
65 def create_widgets(self): | |
66 "Create the base search dialog and add a button for Find Next." | |
67 SearchDialogBase.create_widgets(self) | |
68 # TODO - why is this here and not in a create_command_buttons? | |
69 self.make_button("Find Next", self.default_command, isdef=True) | |
70 | |
71 def default_command(self, event=None): | |
72 "Handle the Find Next button as the default command." | |
73 if not self.engine.getprog(): | |
74 return | |
75 self.find_again(self.text) | |
76 | |
77 def find_again(self, text): | |
78 """Repeat the last search. | |
79 | |
80 If no search was previously run, open a new search dialog. In | |
81 this case, no search is done. | |
82 | |
83 If a search was previously run, the search dialog won't be | |
84 shown and the options from the previous search (including the | |
85 search pattern) will be used to find the next occurrence | |
86 of the pattern. Next is relative based on direction. | |
87 | |
88 Position the window to display the located occurrence in the | |
89 text. | |
90 | |
91 Return True if the search was successful and False otherwise. | |
92 """ | |
93 if not self.engine.getpat(): | |
94 self.open(text) | |
95 return False | |
96 if not self.engine.getprog(): | |
97 return False | |
98 res = self.engine.search_text(text) | |
99 if res: | |
100 line, m = res | |
101 i, j = m.span() | |
102 first = "%d.%d" % (line, i) | |
103 last = "%d.%d" % (line, j) | |
104 try: | |
105 selfirst = text.index("sel.first") | |
106 sellast = text.index("sel.last") | |
107 if selfirst == first and sellast == last: | |
108 self.bell() | |
109 return False | |
110 except TclError: | |
111 pass | |
112 text.tag_remove("sel", "1.0", "end") | |
113 text.tag_add("sel", first, last) | |
114 text.mark_set("insert", self.engine.isback() and first or last) | |
115 text.see("insert") | |
116 return True | |
117 else: | |
118 self.bell() | |
119 return False | |
120 | |
121 def find_selection(self, text): | |
122 """Search for selected text with previous dialog preferences. | |
123 | |
124 Instead of using the same pattern for searching (as Find | |
125 Again does), this first resets the pattern to the currently | |
126 selected text. If the selected text isn't changed, then use | |
127 the prior search phrase. | |
128 """ | |
129 pat = text.get("sel.first", "sel.last") | |
130 if pat: | |
131 self.engine.setcookedpat(pat) | |
132 return self.find_again(text) | |
133 | |
134 | |
135 def _search_dialog(parent): # htest # | |
136 "Display search test box." | |
137 from tkinter import Toplevel, Text | |
138 from tkinter.ttk import Frame, Button | |
139 | |
140 top = Toplevel(parent) | |
141 top.title("Test SearchDialog") | |
142 x, y = map(int, parent.geometry().split('+')[1:]) | |
143 top.geometry("+%d+%d" % (x, y + 175)) | |
144 | |
145 frame = Frame(top) | |
146 frame.pack() | |
147 text = Text(frame, inactiveselectbackground='gray') | |
148 text.pack() | |
149 text.insert("insert","This is a sample string.\n"*5) | |
150 | |
151 def show_find(): | |
152 text.tag_add('sel', '1.0', 'end') | |
153 _setup(text).open(text) | |
154 text.tag_remove('sel', '1.0', 'end') | |
155 | |
156 button = Button(frame, text="Search (selection ignored)", command=show_find) | |
157 button.pack() | |
158 | |
159 if __name__ == '__main__': | |
160 from unittest import main | |
161 main('idlelib.idle_test.test_search', verbosity=2, exit=False) | |
162 | |
163 from idlelib.idle_test.htest import run | |
164 run(_search_dialog) |