diff options
Diffstat (limited to 'Lib/idlelib/SearchDialogBase.py')
-rw-r--r-- | Lib/idlelib/SearchDialogBase.py | 199 |
1 files changed, 113 insertions, 86 deletions
diff --git a/Lib/idlelib/SearchDialogBase.py b/Lib/idlelib/SearchDialogBase.py index b8b49b2a1e..5fa84e238b 100644 --- a/Lib/idlelib/SearchDialogBase.py +++ b/Lib/idlelib/SearchDialogBase.py @@ -1,34 +1,51 @@ '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.''' -from tkinter import * + +from tkinter import (Toplevel, Frame, Entry, Label, Button, + Checkbutton, Radiobutton) class SearchDialogBase: - '''Create most of a modal search dialog (make_frame, create_widgets). + '''Create most of a 3 or 4 row, 3 column search dialog. - The wide left column contains: - 1 or 2 text entry lines (create_entries, make_entry); - a row of standard radiobuttons (create_option_buttons); - a row of dialog specific radiobuttons (create_other_buttons). + The left and wide middle column contain: + 1 or 2 labeled text entry lines (make_entry, create_entries); + a row of standard Checkbuttons (make_frame, create_option_buttons), + each of which corresponds to a search engine Variable; + a row of dialog-specific Check/Radiobuttons (create_other_buttons). The narrow right column contains command buttons - (create_command_buttons, make_button). + (make_button, create_command_buttons). These are bound to functions that execute the command. - Except for command buttons, this base class is not limited to - items common to all three subclasses. Rather, it is the Find dialog - minus the "Find Next" command and its execution function. - The other dialogs override methods to replace and add widgets. + Except for command buttons, this base class is not limited to items + common to all three subclasses. Rather, it is the Find dialog minus + the "Find Next" command, its execution function, and the + default_command attribute needed in create_widgets. The other + dialogs override attributes and methods, the latter to replace and + add widgets. ''' - title = "Search Dialog" + title = "Search Dialog" # replace in subclasses icon = "Search" - needwrapbutton = 1 + needwrapbutton = 1 # not in Find in Files def __init__(self, root, engine): + '''Initialize root, engine, and top attributes. + + top (level widget): set in create_widgets() called from open(). + text (Text searched): set in open(), only used in subclasses(). + ent (ry): created in make_entry() called from create_entry(). + row (of grid): 0 in create_widgets(), +1 in make_entry/frame(). + default_command: set in subclasses, used in create_widgers(). + + title (of dialog): class attribute, override in subclasses. + icon (of dialog): ditto, use unclear if cannot minimize dialog. + ''' self.root = root self.engine = engine self.top = None def open(self, text, searchphrase=None): + "Make dialog visible on top of others and ready to use." self.text = text if not self.top: self.create_widgets() @@ -44,11 +61,17 @@ class SearchDialogBase: self.top.grab_set() def close(self, event=None): + "Put dialog away for later use." if self.top: self.top.grab_release() self.top.withdraw() def create_widgets(self): + '''Create basic 3 row x 3 col search (find) dialog. + + Other dialogs override subsidiary create_x methods as needed. + Replace and Find-in-Files add another entry row. + ''' top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) @@ -61,29 +84,84 @@ class SearchDialogBase: self.top.grid_columnconfigure(0, pad=2, weight=0) self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) - self.create_entries() - self.create_option_buttons() - self.create_other_buttons() - return self.create_command_buttons() - - def make_entry(self, label, var): - l = Label(self.top, text=label) - l.grid(row=self.row, column=0, sticky="nw") - e = Entry(self.top, textvariable=var, exportselection=0) - e.grid(row=self.row, column=1, sticky="nwe") + self.create_entries() # row 0 (and maybe 1), cols 0, 1 + self.create_option_buttons() # next row, cols 0, 1 + self.create_other_buttons() # next row, cols 0, 1 + self.create_command_buttons() # col 2, all rows + + def make_entry(self, label_text, var): + '''Return (entry, label), . + + entry - gridded labeled Entry for text entry. + label - Label widget, returned for testing. + ''' + label = Label(self.top, text=label_text) + label.grid(row=self.row, column=0, sticky="nw") + entry = Entry(self.top, textvariable=var, exportselection=0) + entry.grid(row=self.row, column=1, sticky="nwe") self.row = self.row + 1 - return e + return entry, label + + def create_entries(self): + "Create one or more entry lines with make_entry." + self.ent = self.make_entry("Find:", self.engine.patvar)[0] def make_frame(self,labeltext=None): + '''Return (frame, label). + + frame - gridded labeled Frame for option or other buttons. + label - Label widget, returned for testing. + ''' if labeltext: - l = Label(self.top, text=labeltext) - l.grid(row=self.row, column=0, sticky="nw") - f = Frame(self.top) - f.grid(row=self.row, column=1, columnspan=1, sticky="nwe") + label = Label(self.top, text=labeltext) + label.grid(row=self.row, column=0, sticky="nw") + else: + label = '' + frame = Frame(self.top) + frame.grid(row=self.row, column=1, columnspan=1, sticky="nwe") self.row = self.row + 1 - return f + return frame, label + + def create_option_buttons(self): + '''Return (filled frame, options) for testing. + + Options is a list of SearchEngine booleanvar, label pairs. + A gridded frame from make_frame is filled with a Checkbutton + for each pair, bound to the var, with the corresponding label. + ''' + frame = self.make_frame("Options")[0] + engine = self.engine + options = [(engine.revar, "Regular expression"), + (engine.casevar, "Match case"), + (engine.wordvar, "Whole word")] + if self.needwrapbutton: + options.append((engine.wrapvar, "Wrap around")) + for var, label in options: + btn = Checkbutton(frame, anchor="w", variable=var, text=label) + btn.pack(side="left", fill="both") + if var.get(): + btn.select() + return frame, options + + def create_other_buttons(self): + '''Return (frame, others) for testing. + + Others is a list of value, label pairs. + A gridded frame from make_frame is filled with radio buttons. + ''' + frame = self.make_frame("Direction")[0] + var = self.engine.backvar + others = [(1, 'Up'), (0, 'Down')] + for val, label in others: + btn = Radiobutton(frame, anchor="w", + variable=var, value=val, text=label) + btn.pack(side="left", fill="both") + if var.get() == val: + btn.select() + return frame, others def make_button(self, label, command, isdef=0): + "Return command button gridded in command frame." b = Button(self.buttonframe, text=label, command=command, default=isdef and "active" or "normal") @@ -92,66 +170,15 @@ class SearchDialogBase: self.buttonframe.grid(rowspan=rows+1) return b - def create_entries(self): - self.ent = self.make_entry("Find:", self.engine.patvar) - - def create_option_buttons(self): - f = self.make_frame("Options") - - btn = Checkbutton(f, anchor="w", - variable=self.engine.revar, - text="Regular expression") - btn.pack(side="left", fill="both") - if self.engine.isre(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.casevar, - text="Match case") - btn.pack(side="left", fill="both") - if self.engine.iscase(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.wordvar, - text="Whole word") - btn.pack(side="left", fill="both") - if self.engine.isword(): - btn.select() - - if self.needwrapbutton: - btn = Checkbutton(f, anchor="w", - variable=self.engine.wrapvar, - text="Wrap around") - btn.pack(side="left", fill="both") - if self.engine.iswrap(): - btn.select() - - def create_other_buttons(self): - f = self.make_frame("Direction") - - #lbl = Label(f, text="Direction: ") - #lbl.pack(side="left") - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=1, - text="Up") - btn.pack(side="left", fill="both") - if self.engine.isback(): - btn.select() - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=0, - text="Down") - btn.pack(side="left", fill="both") - if not self.engine.isback(): - btn.select() - def create_command_buttons(self): - # - # place button frame on the right + "Place buttons in vertical command frame gridded on right." f = self.buttonframe = Frame(self.top) f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) b = self.make_button("close", self.close) b.lower() + +if __name__ == '__main__': + import unittest + unittest.main( + 'idlelib.idle_test.test_searchdialogbase', verbosity=2) |