[3.6] bpo-30993: IDLE - Improve configdialog font page and tests. (GH-2818) (#2826)

* Document causal event pathways in docstring.
* Simplify some attribute names.
* Rename test_bold_toggle_set_samples to make test_font_set fail.
* Fix test_font_set so not order dependent.
* Fix renamed test_indent_scale so it tests the widget.
(cherry picked from commit 07ba305)
This commit is contained in:
Terry Jan Reedy 2017-07-23 14:18:27 -04:00 committed by GitHub
parent 8de48fe046
commit 5aa3bf041d
3 changed files with 69 additions and 56 deletions

View File

@ -153,70 +153,73 @@ class ConfigDialog(Toplevel):
def create_page_font_tab(self): def create_page_font_tab(self):
"""Return frame of widgets for Font/Tabs tab. """Return frame of widgets for Font/Tabs tab.
Enable users to provisionally change font face, size, or Fonts: Enable users to provisionally change font face, size, or
boldness and to see the consequence of proposed choices. Each boldness and to see the consequence of proposed choices. Each
action set 3 options in changes structuree and changes the action set 3 options in changes structuree and changes the
corresponding aspect of the font sample on this page and corresponding aspect of the font sample on this page and
highlight sample on highlight page. highlight sample on highlight page.
Enable users to change spaces entered for indent tabs. Fontlist: mouse button 1 click or up or down key invoke
on_fontlist_select(), which sets Var font_name and calls
set_samples.
Tk Variables: Sizelist: clicking the menubutton opens the dropdown menu. A
font_name: Font face. mouse button 1 click or return key invokes an internal command
font_size: Font size. which sets Var font_size and calls set_samples.
font_bold: Select font bold or not.
Note: these 3 share var_changed_font callback.
space_num: Indentation width.
Data Attribute: Bold_toggle, clicking the box toggles font_bold and calls
edit_font: Font with default font name, size, and weight. set_samples.
Methods: Setting any of the font vars invokes var_changed_font, which
load_font_cfg: Set vars and fontlist. adds all 3 font options to changes. Set_samples applies a new
on_fontlist_select: Bound to fontlist button release font constructed from the font vars to font_sample and
or key release. highlight_sample on the hightlight page.
set_samples: Notify both samples of any font change.
load_tab_cfg: Get current. Tabs: Enable users to change spaces entered for indent tabs.
Changing indent_scale value with the mouse sets Var space_num,
which invokes var_changed_space_num, which adds an entry to
changes.
Load_font_cfg and load_tab_cfg initialize vars and widgets from
idleConf entries.
Widget Structure: (*) widgets bound to self Widget Structure: (*) widgets bound to self
frame frame (of tab_pages)
frame_font: LabelFrame frame_font: LabelFrame
frame_font_name: Frame frame_font_name: Frame
font_name_title: Label font_name_title: Label
(*)fontlist: ListBox (*)fontlist: ListBox - font_name
scroll_font: Scrollbar scroll_font: Scrollbar
frame_font_param: Frame frame_font_param: Frame
font_size_title: Label font_size_title: Label
(*)opt_menu_font_size: DynOptionMenu - font_size (*)sizelist: DynOptionMenu - font_size
(*)bold_toggle: Checkbutton - font_bold (*)bold_toggle: Checkbutton - font_bold
frame_font_sample: Frame frame_font_sample: Frame
(*)font_sample: Label (*)font_sample: Label
frame_indent: LabelFrame frame_indent: LabelFrame
frame_indent_size: Frame indent_title: Label
indent_size_title: Label (*)indent_scale: Scale - space_num
(*)scale_indent_size: Scale - space_num
""" """
parent = self.parent parent = self.parent
self.font_name = StringVar(parent) self.font_name = StringVar(parent)
self.font_size = StringVar(parent) self.font_size = StringVar(parent)
self.font_bold = BooleanVar(parent) self.font_bold = BooleanVar(parent)
self.space_num = IntVar(parent) self.space_num = IntVar(parent)
self.edit_font = tkFont.Font(parent, ('courier', 10, 'normal'))
# Create widgets. # Create widgets:
# body and body section frames. # body and body section frames.
frame = self.tab_pages.pages['Fonts/Tabs'].frame frame = self.tab_pages.pages['Fonts/Tabs'].frame
frame_font = LabelFrame( frame_font = LabelFrame(
frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ')
frame_indent = LabelFrame( frame_indent = LabelFrame(
frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ')
# frame_font # frame_font.
frame_font_name = Frame(frame_font) frame_font_name = Frame(frame_font)
frame_font_param = Frame(frame_font) frame_font_param = Frame(frame_font)
font_name_title = Label( font_name_title = Label(
frame_font_name, justify=LEFT, text='Font Face :') frame_font_name, justify=LEFT, text='Font Face :')
self.fontlist = Listbox( self.fontlist = Listbox(frame_font_name, height=5,
frame_font_name, height=5, takefocus=FALSE, exportselection=FALSE) takefocus=FALSE, exportselection=FALSE)
self.fontlist.bind('<ButtonRelease-1>', self.on_fontlist_select) self.fontlist.bind('<ButtonRelease-1>', self.on_fontlist_select)
self.fontlist.bind('<KeyRelease-Up>', self.on_fontlist_select) self.fontlist.bind('<KeyRelease-Up>', self.on_fontlist_select)
self.fontlist.bind('<KeyRelease-Down>', self.on_fontlist_select) self.fontlist.bind('<KeyRelease-Down>', self.on_fontlist_select)
@ -224,43 +227,43 @@ class ConfigDialog(Toplevel):
scroll_font.config(command=self.fontlist.yview) scroll_font.config(command=self.fontlist.yview)
self.fontlist.config(yscrollcommand=scroll_font.set) self.fontlist.config(yscrollcommand=scroll_font.set)
font_size_title = Label(frame_font_param, text='Size :') font_size_title = Label(frame_font_param, text='Size :')
self.opt_menu_font_size = DynOptionMenu( self.sizelist = DynOptionMenu(frame_font_param, self.font_size,
frame_font_param, self.font_size, None, command=self.set_samples) None, command=self.set_samples)
self.bold_toggle = Checkbutton( self.bold_toggle = Checkbutton(
frame_font_param, variable=self.font_bold, onvalue=1, frame_font_param, variable=self.font_bold, onvalue=1,
offvalue=0, text='Bold', command=self.set_samples) offvalue=0, text='Bold', command=self.set_samples)
frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1) frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1)
temp_font = tkFont.Font(parent, ('courier', 10, 'normal'))
self.font_sample = Label( self.font_sample = Label(
frame_font_sample, justify=LEFT, font=self.edit_font, frame_font_sample, justify=LEFT, font=temp_font,
text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]') text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]')
# frame_indent # frame_indent.
frame_indent_size = Frame(frame_indent) indent_title = Label(
indent_size_title = Label( frame_indent, justify=LEFT,
frame_indent_size, justify=LEFT,
text='Python Standard: 4 Spaces!') text='Python Standard: 4 Spaces!')
self.scale_indent_size = Scale( self.indent_scale = Scale(
frame_indent_size, variable=self.space_num, frame_indent, variable=self.space_num,
orient='horizontal', tickinterval=2, from_=2, to=16) orient='horizontal', tickinterval=2, from_=2, to=16)
# Pack widgets. # Pack widgets:
# body # body.
frame_font.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) frame_font.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
frame_indent.pack(side=LEFT, padx=5, pady=5, fill=Y) frame_indent.pack(side=LEFT, padx=5, pady=5, fill=Y)
# frame_font # frame_font.
frame_font_name.pack(side=TOP, padx=5, pady=5, fill=X) frame_font_name.pack(side=TOP, padx=5, pady=5, fill=X)
frame_font_param.pack(side=TOP, padx=5, pady=5, fill=X) frame_font_param.pack(side=TOP, padx=5, pady=5, fill=X)
font_name_title.pack(side=TOP, anchor=W) font_name_title.pack(side=TOP, anchor=W)
self.fontlist.pack(side=LEFT, expand=TRUE, fill=X) self.fontlist.pack(side=LEFT, expand=TRUE, fill=X)
scroll_font.pack(side=LEFT, fill=Y) scroll_font.pack(side=LEFT, fill=Y)
font_size_title.pack(side=LEFT, anchor=W) font_size_title.pack(side=LEFT, anchor=W)
self.opt_menu_font_size.pack(side=LEFT, anchor=W) self.sizelist.pack(side=LEFT, anchor=W)
self.bold_toggle.pack(side=LEFT, anchor=W, padx=20) self.bold_toggle.pack(side=LEFT, anchor=W, padx=20)
frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
self.font_sample.pack(expand=TRUE, fill=BOTH) self.font_sample.pack(expand=TRUE, fill=BOTH)
# frame_indent # frame_indent.
frame_indent_size.pack(side=TOP, fill=X) frame_indent.pack(side=TOP, fill=X)
indent_size_title.pack(side=TOP, anchor=W, padx=5) indent_title.pack(side=TOP, anchor=W, padx=5)
self.scale_indent_size.pack(side=TOP, padx=5, fill=X) self.indent_scale.pack(side=TOP, padx=5, fill=X)
return frame return frame
@ -1410,7 +1413,7 @@ class ConfigDialog(Toplevel):
Attributes updated: Attributes updated:
fontlist: Populate with fonts from tkinter.font. fontlist: Populate with fonts from tkinter.font.
font_name: Set to current font. font_name: Set to current font.
opt_menu_font_size: Populate valid options tuple and set sizelist: Populate valid options tuple and set
to current size. to current size.
font_bold: Set to current font weight. font_bold: Set to current font weight.
@ -1437,9 +1440,9 @@ class ConfigDialog(Toplevel):
except ValueError: except ValueError:
pass pass
# Set font size dropdown. # Set font size dropdown.
self.opt_menu_font_size.SetMenu(('7', '8', '9', '10', '11', '12', '13', self.sizelist.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14',
'14', '16', '18', '20', '22', '16', '18', '20', '22', '25', '29', '34', '40'),
'25', '29', '34', '40'), font_size ) font_size)
# Set font weight. # Set font weight.
self.font_bold.set(font_bold) self.font_bold.set(font_bold)
# Set font sample. # Set font sample.

View File

@ -59,25 +59,28 @@ class FontTabTest(unittest.TestCase):
default_font = idleConf.GetFont(root, 'main', 'EditorWindow') default_font = idleConf.GetFont(root, 'main', 'EditorWindow')
default_size = str(default_font[1]) default_size = str(default_font[1])
default_bold = default_font[2] == 'bold' default_bold = default_font[2] == 'bold'
dialog.font_name.set('Test Font') d = dialog
d.font_name.set('Test Font')
d.font_size.set(default_size)
d.font_bold.set(default_bold)
expected = {'EditorWindow': {'font': 'Test Font', expected = {'EditorWindow': {'font': 'Test Font',
'font-size': default_size, 'font-size': default_size,
'font-bold': str(default_bold)}} 'font-bold': str(default_bold)}}
self.assertEqual(mainpage, expected) self.assertEqual(mainpage, expected)
changes.clear() changes.clear()
dialog.font_size.set(20) d.font_size.set(20)
expected = {'EditorWindow': {'font': 'Test Font', expected = {'EditorWindow': {'font': 'Test Font',
'font-size': '20', 'font-size': '20',
'font-bold': str(default_bold)}} 'font-bold': str(default_bold)}}
self.assertEqual(mainpage, expected) self.assertEqual(mainpage, expected)
changes.clear() changes.clear()
dialog.font_bold.set(not default_bold) d.font_bold.set(not default_bold)
expected = {'EditorWindow': {'font': 'Test Font', expected = {'EditorWindow': {'font': 'Test Font',
'font-size': '20', 'font-size': '20',
'font-bold': str(not default_bold)}} 'font-bold': str(not default_bold)}}
self.assertEqual(mainpage, expected) self.assertEqual(mainpage, expected)
def test_set_samples_bold_toggle(self): def test_bold_toggle_set_samples(self):
# Set up. # Set up.
d = dialog d = dialog
d.font_sample, d.highlight_sample = {}, {} # Must undo this. d.font_sample, d.highlight_sample = {}, {} # Must undo this.
@ -91,7 +94,7 @@ class FontTabTest(unittest.TestCase):
d.set_samples() d.set_samples()
self.assertTrue(d.font_sample == d.highlight_sample == expected1) self.assertTrue(d.font_sample == d.highlight_sample == expected1)
# Test bold_toggle. # Test bold_toggle. If this fails, problem precedes set_samples.
d.bold_toggle.invoke() d.bold_toggle.invoke()
self.assertFalse(d.font_bold.get()) self.assertFalse(d.font_bold.get())
self.assertTrue(d.font_sample == d.highlight_sample == expected0) self.assertTrue(d.font_sample == d.highlight_sample == expected0)
@ -102,9 +105,10 @@ class FontTabTest(unittest.TestCase):
# Clean up. # Clean up.
del d.font_sample, d.highlight_sample del d.font_sample, d.highlight_sample
def test_tabspace(self): def test_indent_scale(self):
dialog.space_num.set(6) dialog.indent_scale.set(26)
self.assertEqual(mainpage, {'Indent': {'num-spaces': '6'}}) self.assertEqual(dialog.space_num.get(), 16)
self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}})
class FontSelectTest(unittest.TestCase): class FontSelectTest(unittest.TestCase):

View File

@ -0,0 +1,6 @@
IDLE - Improve configdialog font page and tests.
* Document causal pathways in docstring. * Simplify some attribute names. *
Rename test_bold_toggle_set_samples to make test_font_set fail. * Fix
test_font_set so not order dependent. * Fix renamed test_indent_scale so it
tests the widget.