comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/idlelib/searchbase.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 '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.'''
2
3 from tkinter import Toplevel
4 from tkinter.ttk import Frame, Entry, Label, Button, Checkbutton, Radiobutton
5
6
7 class SearchDialogBase:
8 '''Create most of a 3 or 4 row, 3 column search dialog.
9
10 The left and wide middle column contain:
11 1 or 2 labeled text entry lines (make_entry, create_entries);
12 a row of standard Checkbuttons (make_frame, create_option_buttons),
13 each of which corresponds to a search engine Variable;
14 a row of dialog-specific Check/Radiobuttons (create_other_buttons).
15
16 The narrow right column contains command buttons
17 (make_button, create_command_buttons).
18 These are bound to functions that execute the command.
19
20 Except for command buttons, this base class is not limited to items
21 common to all three subclasses. Rather, it is the Find dialog minus
22 the "Find Next" command, its execution function, and the
23 default_command attribute needed in create_widgets. The other
24 dialogs override attributes and methods, the latter to replace and
25 add widgets.
26 '''
27
28 title = "Search Dialog" # replace in subclasses
29 icon = "Search"
30 needwrapbutton = 1 # not in Find in Files
31
32 def __init__(self, root, engine):
33 '''Initialize root, engine, and top attributes.
34
35 top (level widget): set in create_widgets() called from open().
36 text (Text searched): set in open(), only used in subclasses().
37 ent (ry): created in make_entry() called from create_entry().
38 row (of grid): 0 in create_widgets(), +1 in make_entry/frame().
39 default_command: set in subclasses, used in create_widgets().
40
41 title (of dialog): class attribute, override in subclasses.
42 icon (of dialog): ditto, use unclear if cannot minimize dialog.
43 '''
44 self.root = root
45 self.bell = root.bell
46 self.engine = engine
47 self.top = None
48
49 def open(self, text, searchphrase=None):
50 "Make dialog visible on top of others and ready to use."
51 self.text = text
52 if not self.top:
53 self.create_widgets()
54 else:
55 self.top.deiconify()
56 self.top.tkraise()
57 self.top.transient(text.winfo_toplevel())
58 if searchphrase:
59 self.ent.delete(0,"end")
60 self.ent.insert("end",searchphrase)
61 self.ent.focus_set()
62 self.ent.selection_range(0, "end")
63 self.ent.icursor(0)
64 self.top.grab_set()
65
66 def close(self, event=None):
67 "Put dialog away for later use."
68 if self.top:
69 self.top.grab_release()
70 self.top.transient('')
71 self.top.withdraw()
72
73 def create_widgets(self):
74 '''Create basic 3 row x 3 col search (find) dialog.
75
76 Other dialogs override subsidiary create_x methods as needed.
77 Replace and Find-in-Files add another entry row.
78 '''
79 top = Toplevel(self.root)
80 top.bind("<Return>", self.default_command)
81 top.bind("<Escape>", self.close)
82 top.protocol("WM_DELETE_WINDOW", self.close)
83 top.wm_title(self.title)
84 top.wm_iconname(self.icon)
85 self.top = top
86
87 self.row = 0
88 self.top.grid_columnconfigure(0, pad=2, weight=0)
89 self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100)
90
91 self.create_entries() # row 0 (and maybe 1), cols 0, 1
92 self.create_option_buttons() # next row, cols 0, 1
93 self.create_other_buttons() # next row, cols 0, 1
94 self.create_command_buttons() # col 2, all rows
95
96 def make_entry(self, label_text, var):
97 '''Return (entry, label), .
98
99 entry - gridded labeled Entry for text entry.
100 label - Label widget, returned for testing.
101 '''
102 label = Label(self.top, text=label_text)
103 label.grid(row=self.row, column=0, sticky="nw")
104 entry = Entry(self.top, textvariable=var, exportselection=0)
105 entry.grid(row=self.row, column=1, sticky="nwe")
106 self.row = self.row + 1
107 return entry, label
108
109 def create_entries(self):
110 "Create one or more entry lines with make_entry."
111 self.ent = self.make_entry("Find:", self.engine.patvar)[0]
112
113 def make_frame(self,labeltext=None):
114 '''Return (frame, label).
115
116 frame - gridded labeled Frame for option or other buttons.
117 label - Label widget, returned for testing.
118 '''
119 if labeltext:
120 label = Label(self.top, text=labeltext)
121 label.grid(row=self.row, column=0, sticky="nw")
122 else:
123 label = ''
124 frame = Frame(self.top)
125 frame.grid(row=self.row, column=1, columnspan=1, sticky="nwe")
126 self.row = self.row + 1
127 return frame, label
128
129 def create_option_buttons(self):
130 '''Return (filled frame, options) for testing.
131
132 Options is a list of searchengine booleanvar, label pairs.
133 A gridded frame from make_frame is filled with a Checkbutton
134 for each pair, bound to the var, with the corresponding label.
135 '''
136 frame = self.make_frame("Options")[0]
137 engine = self.engine
138 options = [(engine.revar, "Regular expression"),
139 (engine.casevar, "Match case"),
140 (engine.wordvar, "Whole word")]
141 if self.needwrapbutton:
142 options.append((engine.wrapvar, "Wrap around"))
143 for var, label in options:
144 btn = Checkbutton(frame, variable=var, text=label)
145 btn.pack(side="left", fill="both")
146 return frame, options
147
148 def create_other_buttons(self):
149 '''Return (frame, others) for testing.
150
151 Others is a list of value, label pairs.
152 A gridded frame from make_frame is filled with radio buttons.
153 '''
154 frame = self.make_frame("Direction")[0]
155 var = self.engine.backvar
156 others = [(1, 'Up'), (0, 'Down')]
157 for val, label in others:
158 btn = Radiobutton(frame, variable=var, value=val, text=label)
159 btn.pack(side="left", fill="both")
160 return frame, others
161
162 def make_button(self, label, command, isdef=0):
163 "Return command button gridded in command frame."
164 b = Button(self.buttonframe,
165 text=label, command=command,
166 default=isdef and "active" or "normal")
167 cols,rows=self.buttonframe.grid_size()
168 b.grid(pady=1,row=rows,column=0,sticky="ew")
169 self.buttonframe.grid(rowspan=rows+1)
170 return b
171
172 def create_command_buttons(self):
173 "Place buttons in vertical command frame gridded on right."
174 f = self.buttonframe = Frame(self.top)
175 f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2)
176
177 b = self.make_button("Close", self.close)
178 b.lower()
179
180
181 class _searchbase(SearchDialogBase): # htest #
182 "Create auto-opening dialog with no text connection."
183
184 def __init__(self, parent):
185 import re
186 from idlelib import searchengine
187
188 self.root = parent
189 self.engine = searchengine.get(parent)
190 self.create_widgets()
191 print(parent.geometry())
192 width,height, x,y = list(map(int, re.split('[x+]', parent.geometry())))
193 self.top.geometry("+%d+%d" % (x + 40, y + 175))
194
195 def default_command(self, dummy): pass
196
197
198 if __name__ == '__main__':
199 from unittest import main
200 main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False)
201
202 from idlelib.idle_test.htest import run
203 run(_searchbase)