summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/SearchDialogBase.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/idlelib/SearchDialogBase.py')
-rw-r--r--Lib/idlelib/SearchDialogBase.py199
1 files changed, 113 insertions, 86 deletions
diff --git a/Lib/idlelib/SearchDialogBase.py b/Lib/idlelib/SearchDialogBase.py
index b8b49b2..5fa84e2 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)