From 2257e62a24f3bc45d9717d9192c793c179b478d2 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Wed, 26 Jul 2017 20:35:19 -0400 Subject: [PATCH 01/10] bpo-31004: IDLE: Factor out FontPage class from configdialog (step 1) --- Lib/idlelib/configdialog.py | 212 +++++++++++++++++++++ Lib/idlelib/idle_test/test_configdialog.py | 167 ++++++++++++++++ 2 files changed, 379 insertions(+) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 67165298a9963eb..b322de8d0bc3431 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1829,6 +1829,218 @@ def save_all_changed_extensions(self): self.ext_userCfg.Save() +class FontPage: + + def __init__(self, parent, tab_pages): + self.parent = parent + self.tab_pages = tab_pages + self.create_page_font_tab() + self.load_font_cfg() + self.load_tab_cfg() + + def create_page_font_tab(self): + """Return frame of widgets for Font/Tabs tab. + + Fonts: Enable users to provisionally change font face, size, or + boldness and to see the consequence of proposed choices. Each + action set 3 options in changes structuree and changes the + corresponding aspect of the font sample on this page and + highlight sample on highlight page. + + Load_font_cfg initializes font vars and widgets from + idleConf entries and tk. + + Fontlist: mouse button 1 click or up or down key invoke + on_fontlist_select(), which sets var font_name. + + Sizelist: clicking the menubutton opens the dropdown menu. A + mouse button 1 click or return key sets var font_size. + + Bold_toggle: clicking the box toggles var font_bold. + + Changing any of the font vars invokes var_changed_font, which + adds all 3 font options to changes and calls set_samples. + Set_samples applies a new font constructed from the font vars to + font_sample and to highlight_sample on the hightlight page. + + 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_tab_cfg initializes space_num to default. + + Widget Structure: (*) widgets bound to self + frame (of tab_pages) + frame_font: LabelFrame + frame_font_name: Frame + font_name_title: Label + (*)fontlist: ListBox - font_name + scroll_font: Scrollbar + frame_font_param: Frame + font_size_title: Label + (*)sizelist: DynOptionMenu - font_size + (*)bold_toggle: Checkbutton - font_bold + frame_font_sample: Frame + (*)font_sample: Label + frame_indent: LabelFrame + indent_title: Label + (*)indent_scale: Scale - space_num + """ + parent = self.parent + self.font_name = StringVar(parent) + self.font_size = StringVar(parent) + self.font_bold = BooleanVar(parent) + self.space_num = IntVar(parent) + + # Create widgets: + # body and body section frames. + frame = self.tab_pages.pages['Fonts/Tabs'].frame + frame_font = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') + frame_indent = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') + # frame_font. + frame_font_name = Frame(frame_font) + frame_font_param = Frame(frame_font) + font_name_title = Label( + frame_font_name, justify=LEFT, text='Font Face :') + self.fontlist = Listbox(frame_font_name, height=5, + takefocus=FALSE, exportselection=FALSE) + self.fontlist.bind('', self.on_fontlist_select) + self.fontlist.bind('', self.on_fontlist_select) + self.fontlist.bind('', self.on_fontlist_select) + scroll_font = Scrollbar(frame_font_name) + scroll_font.config(command=self.fontlist.yview) + self.fontlist.config(yscrollcommand=scroll_font.set) + font_size_title = Label(frame_font_param, text='Size :') + self.sizelist = DynOptionMenu(frame_font_param, self.font_size, None) + self.bold_toggle = Checkbutton( + frame_font_param, variable=self.font_bold, + onvalue=1, offvalue=0, text='Bold') + frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1) + temp_font = tkFont.Font(parent, ('courier', 10, 'normal')) + self.font_sample = Label( + frame_font_sample, justify=LEFT, font=temp_font, + text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]') + # frame_indent. + indent_title = Label( + frame_indent, justify=LEFT, + text='Python Standard: 4 Spaces!') + self.indent_scale = Scale( + frame_indent, variable=self.space_num, + orient='horizontal', tickinterval=2, from_=2, to=16) + + # Pack widgets: + # body. + 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_font. + frame_font_name.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) + self.fontlist.pack(side=LEFT, expand=TRUE, fill=X) + scroll_font.pack(side=LEFT, fill=Y) + font_size_title.pack(side=LEFT, anchor=W) + self.sizelist.pack(side=LEFT, anchor=W) + self.bold_toggle.pack(side=LEFT, anchor=W, padx=20) + frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + self.font_sample.pack(expand=TRUE, fill=BOTH) + # frame_indent. + frame_indent.pack(side=TOP, fill=X) + indent_title.pack(side=TOP, anchor=W, padx=5) + self.indent_scale.pack(side=TOP, padx=5, fill=X) + + return frame + + def load_font_cfg(self): + """Load current configuration settings for the font options. + + Retrieve current font with idleConf.GetFont and font families + from tk. Setup fontlist and set font_name. Setup sizelist, + which sets font_size. Set font_bold. Setting font variables + calls set_samples (thrice). + """ + configured_font = idleConf.GetFont(self.parent, 'main', 'EditorWindow') + font_name = configured_font[0].lower() + font_size = configured_font[1] + font_bold = configured_font[2]=='bold' + + # Set editor font selection list and font_name. + fonts = list(tkFont.families(self.parent)) + fonts.sort() + for font in fonts: + self.fontlist.insert(END, font) + self.font_name.set(font_name) + lc_fonts = [s.lower() for s in fonts] + try: + current_font_index = lc_fonts.index(font_name) + self.fontlist.see(current_font_index) + self.fontlist.select_set(current_font_index) + self.fontlist.select_anchor(current_font_index) + self.fontlist.activate(current_font_index) + except ValueError: + pass + # Set font size dropdown. + self.sizelist.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', + '16', '18', '20', '22', '25', '29', '34', '40'), + font_size) + # Set font weight. + self.font_bold.set(font_bold) + + def on_fontlist_select(self, event): + """Handle selecting a font from the list. + + Event can result from either mouse click or Up or Down key. + Set font_name and example displays to selection. + """ + font = self.fontlist.get( + ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) + self.font_name.set(font.lower()) + + def var_changed_font(self, *params): + """Store changes to font attributes. + + When one font attribute changes, save them all, as they are + not independent from each other. In particular, when we are + overriding the default font, we need to write out everything. + """ + value = self.font_name.get() + changes.add_option('main', 'EditorWindow', 'font', value) + value = self.font_size.get() + changes.add_option('main', 'EditorWindow', 'font-size', value) + value = self.font_bold.get() + changes.add_option('main', 'EditorWindow', 'font-bold', value) + self.set_samples() + + def set_samples(self, event=None): + """Update update both screen samples with the font settings. + + Called on font initialization and change events. + Accesses font_name, font_size, and font_bold Variables. + Updates font_sample and hightlight page highlight_sample. + """ + font_name = self.font_name.get() + font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL + new_font = (font_name, self.font_size.get(), font_weight) + self.font_sample['font'] = new_font + # self.highlight_sample['font'] = new_font + + def load_tab_cfg(self): + """Load current configuration settings for the tab options. + + Attributes updated: + space_num: Set to value from idleConf. + """ + # Set indent sizes. + space_num = idleConf.GetOption( + 'main', 'Indent', 'num-spaces', default=4, type='int') + self.space_num.set(space_num) + + def var_changed_space_num(self, *params): + "Store change to indentation size." + value = self.space_num.get() + changes.add_option('main', 'Indent', 'num-spaces', value) + + class VarTrace: """Maintain Tk variables trace state.""" diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index aff3c2fdc3b2b04..6a0885fb83bc16b 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -199,6 +199,158 @@ def test_set_samples(self): d.set_samples = Func() # Re-mask for other tests. +class FontPageTest(unittest.TestCase): + """Test that font widgets enable users to make font changes. + + Test that widget actions set vars, that var changes add three + options to changes and call set_samples, and that set_samples + changes the font of both sample boxes. + """ + @classmethod + def setUpClass(cls): + dialog.set_samples = Func() # Mask instance method. + + @classmethod + def tearDownClass(cls): + del dialog.set_samples # Unmask instance method. + + def setUp(self): + changes.clear() + + def test_load_font_cfg(self): + # Leave widget load test to human visual check. + # TODO Improve checks when add IdleConf.get_font_values. + d = dialog + d.font_name.set('Fake') + d.font_size.set('1') + d.font_bold.set(True) + d.set_samples.called = 0 + d.load_font_cfg() + self.assertNotEqual(d.font_name.get(), 'Fake') + self.assertNotEqual(d.font_size.get(), '1') + self.assertFalse(d.font_bold.get()) + self.assertEqual(d.set_samples.called, 3) + + def test_fontlist_key(self): + # Up and Down keys should select a new font. + + if dialog.fontlist.size() < 2: + cls.skipTest('need at least 2 fonts') + fontlist = dialog.fontlist + fontlist.activate(0) + font = dialog.fontlist.get('active') + + # Test Down key. + fontlist.focus_force() + fontlist.update() + fontlist.event_generate('') + fontlist.event_generate('') + + down_font = fontlist.get('active') + self.assertNotEqual(down_font, font) + self.assertIn(dialog.font_name.get(), down_font.lower()) + + # Test Up key. + fontlist.focus_force() + fontlist.update() + fontlist.event_generate('') + fontlist.event_generate('') + + up_font = fontlist.get('active') + self.assertEqual(up_font, font) + self.assertIn(dialog.font_name.get(), up_font.lower()) + + def test_fontlist_mouse(self): + # Click on item should select that item. + + if dialog.fontlist.size() < 2: + cls.skipTest('need at least 2 fonts') + fontlist = dialog.fontlist + fontlist.activate(0) + + # Select next item in listbox + fontlist.focus_force() + fontlist.see(1) + fontlist.update() + x, y, dx, dy = fontlist.bbox(1) + x += dx // 2 + y += dy // 2 + fontlist.event_generate('', x=x, y=y) + fontlist.event_generate('', x=x, y=y) + + font1 = fontlist.get(1) + select_font = fontlist.get('anchor') + self.assertEqual(select_font, font1) + self.assertIn(dialog.font_name.get(), font1.lower()) + + def test_sizelist(self): + # Click on number shouod select that number + d = dialog + d.sizelist.variable.set(40) + self.assertEqual(d.font_size.get(), '40') + + def test_bold_toggle(self): + # Click on checkbutton should invert it. + d = dialog + d.font_bold.set(False) + d.bold_toggle.invoke() + self.assertTrue(d.font_bold.get()) + d.bold_toggle.invoke() + self.assertFalse(d.font_bold.get()) + + def test_font_set(self): + # Test that setting a font Variable results in 3 provisional + # change entries and a call to set_samples. Use values sure to + # not be defaults. + + default_font = idleConf.GetFont(root, 'main', 'EditorWindow') + default_size = str(default_font[1]) + default_bold = default_font[2] == 'bold' + d = dialog + d.font_size.set(default_size) + d.font_bold.set(default_bold) + d.set_samples.called = 0 + + d.font_name.set('Test Font') + expected = {'EditorWindow': {'font': 'Test Font', + 'font-size': default_size, + 'font-bold': str(default_bold)}} + self.assertEqual(mainpage, expected) + self.assertEqual(d.set_samples.called, 1) + changes.clear() + + d.font_size.set('20') + expected = {'EditorWindow': {'font': 'Test Font', + 'font-size': '20', + 'font-bold': str(default_bold)}} + self.assertEqual(mainpage, expected) + self.assertEqual(d.set_samples.called, 2) + changes.clear() + + d.font_bold.set(not default_bold) + expected = {'EditorWindow': {'font': 'Test Font', + 'font-size': '20', + 'font-bold': str(not default_bold)}} + self.assertEqual(mainpage, expected) + self.assertEqual(d.set_samples.called, 3) + + def test_set_samples(self): + d = dialog + del d.set_samples # Unmask method for test + d.font_sample, d.highlight_sample = {}, {} + d.font_name.set('test') + d.font_size.set('5') + d.font_bold.set(1) + expected = {'font': ('test', '5', 'bold')} + + # Test set_samples. + d.set_samples() + self.assertTrue(d.font_sample == d.highlight_sample == expected) + + del d.font_sample, d.highlight_sample + d.set_samples = Func() # Re-mask for other tests. + + class IndentTest(unittest.TestCase): def test_load_tab_cfg(self): @@ -214,6 +366,21 @@ def test_indent_scale(self): self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) +class IndentOptionTest(unittest.TestCase): + + def test_load_tab_cfg(self): + d = dialog + d.space_num.set(16) + d.load_tab_cfg() + self.assertEqual(d.space_num.get(), 4) + + def test_indent_scale(self): + changes.clear() + dialog.indent_scale.set(26) + self.assertEqual(dialog.space_num.get(), 16) + self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) + + class HighlightTest(unittest.TestCase): def setUp(self): From fdacf6da747ef41a7ba7db91c5fd58e492270895 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Wed, 26 Jul 2017 20:39:15 -0400 Subject: [PATCH 02/10] highlight_sample --- Lib/idlelib/configdialog.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index b322de8d0bc3431..40a0fbef0d1eb2f 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1831,9 +1831,10 @@ def save_all_changed_extensions(self): class FontPage: - def __init__(self, parent, tab_pages): + def __init__(self, parent, tab_pages, highlight_sample): self.parent = parent self.tab_pages = tab_pages + self.highlight_sample = highlight_sample self.create_page_font_tab() self.load_font_cfg() self.load_tab_cfg() @@ -2022,7 +2023,7 @@ def set_samples(self, event=None): font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL new_font = (font_name, self.font_size.get(), font_weight) self.font_sample['font'] = new_font - # self.highlight_sample['font'] = new_font + self.highlight_sample['font'] = new_font def load_tab_cfg(self): """Load current configuration settings for the tab options. From 136066b3993282e4ba08d72c4bfd03c10846c226 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Fri, 28 Jul 2017 15:57:08 -0400 Subject: [PATCH 03/10] New FontPage with changes from 30853 --- Lib/idlelib/configdialog.py | 39 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 40a0fbef0d1eb2f..0f43dc062ff42a5 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1848,7 +1848,7 @@ def create_page_font_tab(self): corresponding aspect of the font sample on this page and highlight sample on highlight page. - Load_font_cfg initializes font vars and widgets from + Funtion load_font_cfg initializes font vars and widgets from idleConf entries and tk. Fontlist: mouse button 1 click or up or down key invoke @@ -1866,7 +1866,7 @@ def create_page_font_tab(self): 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 + which invokes the default callback to add an entry to changes. Load_tab_cfg initializes space_num to default. Widget Structure: (*) widgets bound to self @@ -1887,10 +1887,10 @@ def create_page_font_tab(self): (*)indent_scale: Scale - space_num """ parent = self.parent - self.font_name = StringVar(parent) - self.font_size = StringVar(parent) - self.font_bold = BooleanVar(parent) - self.space_num = IntVar(parent) + self.font_name = tracers.add(StringVar(parent), self.var_changed_font) + self.font_size = tracers.add(StringVar(parent), self.var_changed_font) + self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font) + self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) # Create widgets: # body and body section frames. @@ -1963,7 +1963,7 @@ def load_font_cfg(self): configured_font = idleConf.GetFont(self.parent, 'main', 'EditorWindow') font_name = configured_font[0].lower() font_size = configured_font[1] - font_bold = configured_font[2]=='bold' + font_bold = configured_font[2]=='bold' # Set editor font selection list and font_name. fonts = list(tkFont.families(self.parent)) @@ -1987,16 +1987,6 @@ def load_font_cfg(self): # Set font weight. self.font_bold.set(font_bold) - def on_fontlist_select(self, event): - """Handle selecting a font from the list. - - Event can result from either mouse click or Up or Down key. - Set font_name and example displays to selection. - """ - font = self.fontlist.get( - ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) - self.font_name.set(font.lower()) - def var_changed_font(self, *params): """Store changes to font attributes. @@ -2012,6 +2002,16 @@ def var_changed_font(self, *params): changes.add_option('main', 'EditorWindow', 'font-bold', value) self.set_samples() + def on_fontlist_select(self, event): + """Handle selecting a font from the list. + + Event can result from either mouse click or Up or Down key. + Set font_name and example displays to selection. + """ + font = self.fontlist.get( + ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) + self.font_name.set(font.lower()) + def set_samples(self, event=None): """Update update both screen samples with the font settings. @@ -2036,11 +2036,6 @@ def load_tab_cfg(self): 'main', 'Indent', 'num-spaces', default=4, type='int') self.space_num.set(space_num) - def var_changed_space_num(self, *params): - "Store change to indentation size." - value = self.space_num.get() - changes.add_option('main', 'Indent', 'num-spaces', value) - class VarTrace: """Maintain Tk variables trace state.""" From 31a02ad58c78cc60950226e1b1a908a173c056a7 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sat, 29 Jul 2017 20:00:32 -0400 Subject: [PATCH 04/10] Step 2 --- Lib/idlelib/configdialog.py | 25 +++---- Lib/idlelib/idle_test/test_configdialog.py | 79 +++++++++++++++------- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 0f43dc062ff42a5..8237327de2cee2b 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -102,8 +102,8 @@ def create_widgets(self): activate_config_changes: Tell editors to reload. """ self.note = note = Notebook(self, width=450, height=450) - fontpage = self.create_page_font_tab() highpage = self.create_page_highlight() + fontpage = self.create_page_font_tab() keyspage = self.create_page_keys() genpage = self.create_page_general() extpage = self.create_page_extensions() @@ -228,7 +228,7 @@ def create_page_font_tab(self): corresponding aspect of the font sample on this page and highlight sample on highlight page. - Funtion load_font_cfg initializes font vars and widgets from + Function load_font_cfg initializes font vars and widgets from idleConf entries and tk. Fontlist: mouse button 1 click or up or down key invoke @@ -337,8 +337,7 @@ def load_font_cfg(self): Retrieve current font with idleConf.GetFont and font families from tk. Setup fontlist and set font_name. Setup sizelist, - which sets font_size. Set font_bold. Setting font variables - calls set_samples (thrice). + which sets font_size. Set font_bold. Call set_samples. """ configured_font = idleConf.GetFont(self, 'main', 'EditorWindow') font_name = configured_font[0].lower() @@ -366,6 +365,7 @@ def load_font_cfg(self): font_size) # Set font weight. self.font_bold.set(font_bold) + self.set_samples() def var_changed_font(self, *params): """Store changes to font attributes. @@ -1829,12 +1829,12 @@ def save_all_changed_extensions(self): self.ext_userCfg.Save() -class FontPage: +class FontPage(Frame): - def __init__(self, parent, tab_pages, highlight_sample): + def __init__(self, parent, highpage): + super().__init__(parent) self.parent = parent - self.tab_pages = tab_pages - self.highlight_sample = highlight_sample + self.highlight_sample = highpage.highlight_sample self.create_page_font_tab() self.load_font_cfg() self.load_tab_cfg() @@ -1848,7 +1848,7 @@ def create_page_font_tab(self): corresponding aspect of the font sample on this page and highlight sample on highlight page. - Funtion load_font_cfg initializes font vars and widgets from + Function load_font_cfg initializes font vars and widgets from idleConf entries and tk. Fontlist: mouse button 1 click or up or down key invoke @@ -1894,7 +1894,8 @@ def create_page_font_tab(self): # Create widgets: # body and body section frames. - frame = self.tab_pages.pages['Fonts/Tabs'].frame + # frame = self.tab_pages.pages['Fonts/Tabs'].frame + frame = self.parent frame_font = LabelFrame( frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') frame_indent = LabelFrame( @@ -1957,8 +1958,7 @@ def load_font_cfg(self): Retrieve current font with idleConf.GetFont and font families from tk. Setup fontlist and set font_name. Setup sizelist, - which sets font_size. Set font_bold. Setting font variables - calls set_samples (thrice). + which sets font_size. Set font_bold. Call set_samples. """ configured_font = idleConf.GetFont(self.parent, 'main', 'EditorWindow') font_name = configured_font[0].lower() @@ -1986,6 +1986,7 @@ def load_font_cfg(self): font_size) # Set font weight. self.font_bold.set(font_bold) + self.set_samples() def var_changed_font(self, *params): """Store changes to font attributes. diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 6a0885fb83bc16b..a25ccf8bfb25e75 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -9,7 +9,7 @@ import unittest from unittest import mock from idlelib.idle_test.mock_idle import Func -from tkinter import Tk, IntVar, BooleanVar, DISABLED, NORMAL +from tkinter import Tk, Frame, IntVar, BooleanVar, DISABLED, NORMAL from idlelib import config from idlelib.configdialog import idleConf, changes, tracers @@ -57,10 +57,12 @@ class FontTest(unittest.TestCase): @classmethod def setUpClass(cls): dialog.set_samples = Func() # Mask instance method. + tracers.attach() @classmethod def tearDownClass(cls): del dialog.set_samples # Unmask instance method. + tracers.detach() def setUp(self): changes.clear() @@ -77,7 +79,7 @@ def test_load_font_cfg(self): self.assertNotEqual(d.font_name.get(), 'Fake') self.assertNotEqual(d.font_size.get(), '1') self.assertFalse(d.font_bold.get()) - self.assertEqual(d.set_samples.called, 3) + self.assertEqual(d.set_samples.called, 4) def test_fontlist_key(self): # Up and Down keys should select a new font. @@ -208,11 +210,16 @@ class FontPageTest(unittest.TestCase): """ @classmethod def setUpClass(cls): - dialog.set_samples = Func() # Mask instance method. + hp = mock.Mock() + hp.highlight_sample = {} + cls.page = configdialog.FontPage(root, hp) + cls.page.set_samples = Func() # Mask instance method. + tracers.attach() @classmethod def tearDownClass(cls): - del dialog.set_samples # Unmask instance method. + del cls.page.set_samples # Unmask instance method. + tracers.detach() def setUp(self): changes.clear() @@ -220,7 +227,7 @@ def setUp(self): def test_load_font_cfg(self): # Leave widget load test to human visual check. # TODO Improve checks when add IdleConf.get_font_values. - d = dialog + d = self.page d.font_name.set('Fake') d.font_size.set('1') d.font_bold.set(True) @@ -229,16 +236,16 @@ def test_load_font_cfg(self): self.assertNotEqual(d.font_name.get(), 'Fake') self.assertNotEqual(d.font_size.get(), '1') self.assertFalse(d.font_bold.get()) - self.assertEqual(d.set_samples.called, 3) + self.assertEqual(d.set_samples.called, 4) def test_fontlist_key(self): # Up and Down keys should select a new font. - - if dialog.fontlist.size() < 2: - cls.skipTest('need at least 2 fonts') - fontlist = dialog.fontlist + d = self.page + if d.fontlist.size() < 2: + self.skipTest('need at least 2 fonts') + fontlist = d.fontlist fontlist.activate(0) - font = dialog.fontlist.get('active') + font = d.fontlist.get('active') # Test Down key. fontlist.focus_force() @@ -248,7 +255,7 @@ def test_fontlist_key(self): down_font = fontlist.get('active') self.assertNotEqual(down_font, font) - self.assertIn(dialog.font_name.get(), down_font.lower()) + self.assertIn(d.font_name.get(), down_font.lower()) # Test Up key. fontlist.focus_force() @@ -258,14 +265,14 @@ def test_fontlist_key(self): up_font = fontlist.get('active') self.assertEqual(up_font, font) - self.assertIn(dialog.font_name.get(), up_font.lower()) + self.assertIn(d.font_name.get(), up_font.lower()) def test_fontlist_mouse(self): # Click on item should select that item. - - if dialog.fontlist.size() < 2: + d = self.page + if d.fontlist.size() < 2: cls.skipTest('need at least 2 fonts') - fontlist = dialog.fontlist + fontlist = d.fontlist fontlist.activate(0) # Select next item in listbox @@ -281,17 +288,17 @@ def test_fontlist_mouse(self): font1 = fontlist.get(1) select_font = fontlist.get('anchor') self.assertEqual(select_font, font1) - self.assertIn(dialog.font_name.get(), font1.lower()) + self.assertIn(d.font_name.get(), font1.lower()) def test_sizelist(self): # Click on number shouod select that number - d = dialog + d = self.page d.sizelist.variable.set(40) self.assertEqual(d.font_size.get(), '40') def test_bold_toggle(self): # Click on checkbutton should invert it. - d = dialog + d = self.page d.font_bold.set(False) d.bold_toggle.invoke() self.assertTrue(d.font_bold.get()) @@ -306,7 +313,7 @@ def test_font_set(self): default_font = idleConf.GetFont(root, 'main', 'EditorWindow') default_size = str(default_font[1]) default_bold = default_font[2] == 'bold' - d = dialog + d = self.page d.font_size.set(default_size) d.font_bold.set(default_bold) d.set_samples.called = 0 @@ -335,7 +342,7 @@ def test_font_set(self): self.assertEqual(d.set_samples.called, 3) def test_set_samples(self): - d = dialog + d = self.page del d.set_samples # Unmask method for test d.font_sample, d.highlight_sample = {}, {} d.font_name.set('test') @@ -353,6 +360,14 @@ def test_set_samples(self): class IndentTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + tracers.attach() + + @classmethod + def tearDownClass(cls): + tracers.detach() + def test_load_tab_cfg(self): d = dialog d.space_num.set(16) @@ -368,16 +383,30 @@ def test_indent_scale(self): class IndentOptionTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + hp = mock.Mock() + hp.highlight_sample = {} + cls.page = configdialog.FontPage(root, hp) + cls.page.set_samples = Func() # Mask instance method. + tracers.attach() + + @classmethod + def tearDownClass(cls): + del cls.page.set_samples + tracers.detach() + def test_load_tab_cfg(self): - d = dialog + d = self.page d.space_num.set(16) d.load_tab_cfg() self.assertEqual(d.space_num.get(), 4) def test_indent_scale(self): + d = self.page changes.clear() - dialog.indent_scale.set(26) - self.assertEqual(dialog.space_num.get(), 16) + d.indent_scale.set(26) + self.assertEqual(d.space_num.get(), 16) self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) @@ -405,6 +434,7 @@ def setUpClass(cls): d = dialog d.set = d.set_add_delete_state = Func() d.upc = d.update_help_changes = Func() + tracers.attach() @classmethod def tearDownClass(cls): @@ -413,6 +443,7 @@ def tearDownClass(cls): del d.upc, d.update_help_changes d.helplist.delete(0, 'end') d.user_helplist.clear() + tracers.detach() def setUp(self): changes.clear() From 8aa4bd5e9ef52a96a9967b210734422f3b3f68b9 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sat, 29 Jul 2017 20:28:28 -0400 Subject: [PATCH 05/10] Step 2 corrections --- Lib/idlelib/configdialog.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 8237327de2cee2b..28b29c397bcd5a0 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1894,8 +1894,7 @@ def create_page_font_tab(self): # Create widgets: # body and body section frames. - # frame = self.tab_pages.pages['Fonts/Tabs'].frame - frame = self.parent + frame = Frame(self.parent) frame_font = LabelFrame( frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') frame_indent = LabelFrame( @@ -1906,7 +1905,7 @@ def create_page_font_tab(self): font_name_title = Label( frame_font_name, justify=LEFT, text='Font Face :') self.fontlist = Listbox(frame_font_name, height=5, - takefocus=FALSE, exportselection=FALSE) + takefocus=True, exportselection=FALSE) self.fontlist.bind('', self.on_fontlist_select) self.fontlist.bind('', self.on_fontlist_select) self.fontlist.bind('', self.on_fontlist_select) @@ -1922,7 +1921,7 @@ def create_page_font_tab(self): temp_font = tkFont.Font(parent, ('courier', 10, 'normal')) self.font_sample = Label( frame_font_sample, justify=LEFT, font=temp_font, - text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]') + text='AaBbCcDdEe\nFfGgHhIiJj\n1234567890\n#:+=(){}[]') # frame_indent. indent_title = Label( frame_indent, justify=LEFT, @@ -1960,13 +1959,13 @@ def load_font_cfg(self): from tk. Setup fontlist and set font_name. Setup sizelist, which sets font_size. Set font_bold. Call set_samples. """ - configured_font = idleConf.GetFont(self.parent, 'main', 'EditorWindow') + configured_font = idleConf.GetFont(self, 'main', 'EditorWindow') font_name = configured_font[0].lower() font_size = configured_font[1] font_bold = configured_font[2]=='bold' # Set editor font selection list and font_name. - fonts = list(tkFont.families(self.parent)) + fonts = list(tkFont.families(self)) fonts.sort() for font in fonts: self.fontlist.insert(END, font) From b376e764bfd952fb361fd7ac2c14cd1e4f05a6d9 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 30 Jul 2017 00:16:08 -0400 Subject: [PATCH 06/10] "Complete Step 2: test new class isolated." --- Lib/idlelib/configdialog.py | 20 ++++++++-- Lib/idlelib/idle_test/test_configdialog.py | 44 ++++++++-------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 28b29c397bcd5a0..6b35c7eb76a23d9 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -102,7 +102,8 @@ def create_widgets(self): activate_config_changes: Tell editors to reload. """ self.note = note = Notebook(self, width=450, height=450) - highpage = self.create_page_highlight() + # self.highpage is temporary for independent test of FontPage + self.highpage = highpage = self.create_page_highlight() fontpage = self.create_page_font_tab() keyspage = self.create_page_keys() genpage = self.create_page_general() @@ -416,6 +417,12 @@ def load_tab_cfg(self): 'main', 'Indent', 'num-spaces', default=4, type='int') self.space_num.set(space_num) + def var_changed_space_num(self, *params): + "Store change to indentation size." + value = self.space_num.get() + changes.add_option('main', 'Indent', 'num-spaces', value) + + def create_page_highlight(self): """Return frame of widgets for Highlighting tab. @@ -505,7 +512,7 @@ def create_page_highlight(self): frame_theme = LabelFrame(frame, borderwidth=2, relief=GROOVE, text=' Highlighting Theme ') #frame_custom - self.highlight_sample=Text( + text = self.highlight_sample = frame.highlight_sample = Text( frame_custom, relief=SOLID, borderwidth=1, font=('courier', 12, ''), cursor='hand2', width=21, height=13, takefocus=FALSE, highlightthickness=0, wrap=NONE) @@ -1890,11 +1897,11 @@ def create_page_font_tab(self): self.font_name = tracers.add(StringVar(parent), self.var_changed_font) self.font_size = tracers.add(StringVar(parent), self.var_changed_font) self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font) - self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) + self.space_num = tracers.add(IntVar(self), ('main', 'Indent', 'num-spaces')) # Create widgets: # body and body section frames. - frame = Frame(self.parent) + frame = self frame_font = LabelFrame( frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') frame_indent = LabelFrame( @@ -2036,6 +2043,11 @@ def load_tab_cfg(self): 'main', 'Indent', 'num-spaces', default=4, type='int') self.space_num.set(space_num) + def var_changed_space_num(self, *params): + "Store change to indentation size." + value = self.space_num.get() + changes.add_option('main', 'Indent', 'num-spaces', value) + class VarTrace: """Maintain Tk variables trace state.""" diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index a25ccf8bfb25e75..7fa0194033881ce 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -57,12 +57,10 @@ class FontTest(unittest.TestCase): @classmethod def setUpClass(cls): dialog.set_samples = Func() # Mask instance method. - tracers.attach() @classmethod def tearDownClass(cls): del dialog.set_samples # Unmask instance method. - tracers.detach() def setUp(self): changes.clear() @@ -210,16 +208,17 @@ class FontPageTest(unittest.TestCase): """ @classmethod def setUpClass(cls): - hp = mock.Mock() - hp.highlight_sample = {} - cls.page = configdialog.FontPage(root, hp) + page = cls.page = configdialog.FontPage(dialog.note, dialog.highpage) + dialog.note.insert(0, page, text='copy') + #dialog.note.add(page, text='copyfgfg') + dialog.note.select(page) cls.page.set_samples = Func() # Mask instance method. tracers.attach() @classmethod def tearDownClass(cls): del cls.page.set_samples # Unmask instance method. - tracers.detach() + cls.page.destroy() # delete when live def setUp(self): changes.clear() @@ -227,6 +226,7 @@ def setUp(self): def test_load_font_cfg(self): # Leave widget load test to human visual check. # TODO Improve checks when add IdleConf.get_font_values. + tracers.detach() d = self.page d.font_name.set('Fake') d.font_size.set('1') @@ -236,7 +236,8 @@ def test_load_font_cfg(self): self.assertNotEqual(d.font_name.get(), 'Fake') self.assertNotEqual(d.font_size.get(), '1') self.assertFalse(d.font_bold.get()) - self.assertEqual(d.set_samples.called, 4) + self.assertEqual(d.set_samples.called, 1) + tracers.attach() def test_fontlist_key(self): # Up and Down keys should select a new font. @@ -360,14 +361,6 @@ def test_set_samples(self): class IndentTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - tracers.attach() - - @classmethod - def tearDownClass(cls): - tracers.detach() - def test_load_tab_cfg(self): d = dialog d.space_num.set(16) @@ -385,16 +378,12 @@ class IndentOptionTest(unittest.TestCase): @classmethod def setUpClass(cls): - hp = mock.Mock() - hp.highlight_sample = {} - cls.page = configdialog.FontPage(root, hp) - cls.page.set_samples = Func() # Mask instance method. + cls.page = configdialog.FontPage(dialog.note, dialog.highpage) tracers.attach() @classmethod def tearDownClass(cls): - del cls.page.set_samples - tracers.detach() + cls.page.destroy() def test_load_tab_cfg(self): d = self.page @@ -405,7 +394,7 @@ def test_load_tab_cfg(self): def test_indent_scale(self): d = self.page changes.clear() - d.indent_scale.set(26) + d.indent_scale.set(20) self.assertEqual(d.space_num.get(), 16) self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) @@ -430,11 +419,12 @@ class GeneralTest(unittest.TestCase): """ @classmethod def setUpClass(cls): - # Mask instance methods used by help functions. d = dialog + # Select General tab so can force focus on helplist. + d.note.select(3) + # Mask instance methods used by help functions. d.set = d.set_add_delete_state = Func() d.upc = d.update_help_changes = Func() - tracers.attach() @classmethod def tearDownClass(cls): @@ -443,7 +433,6 @@ def tearDownClass(cls): del d.upc, d.update_help_changes d.helplist.delete(0, 'end') d.user_helplist.clear() - tracers.detach() def setUp(self): changes.clear() @@ -509,9 +498,8 @@ def test_source_selected(self): helplist.event_generate('', x=x, y=y) helplist.event_generate('', x=x, y=y) helplist.event_generate('', x=x, y=y) - # The following fail after the switch to - # self.assertEqual(helplist.get('anchor'), 'source') - # self.assertTrue(d.set.called) + self.assertEqual(helplist.get('anchor'), 'source') + self.assertTrue(d.set.called) self.assertFalse(d.upc.called) def test_set_add_delete_state(self): From 382bdbf2d29cabfafb712351be1ccb9de9463464 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 30 Jul 2017 00:38:50 -0400 Subject: [PATCH 07/10] "Step 3: Switch to Font Page class, diable test of old code" --- Lib/idlelib/configdialog.py | 27 +- Lib/idlelib/idle_test/test_configdialog.py | 349 ++++++++++----------- 2 files changed, 184 insertions(+), 192 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 6b35c7eb76a23d9..afad1da453a4139 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -69,7 +69,7 @@ def __init__(self, parent, title='', _htest=False, _utest=False): self.resizable(height=FALSE, width=FALSE) self.transient(parent) self.protocol("WM_DELETE_WINDOW", self.cancel) - self.fontlist.focus_set() + self.fontpage.fontlist.focus_set() # XXX Decide whether to keep or delete these key bindings. # Key bindings for this dialog. # self.bind('', self.Cancel) #dismiss dialog, no save @@ -102,17 +102,16 @@ def create_widgets(self): activate_config_changes: Tell editors to reload. """ self.note = note = Notebook(self, width=450, height=450) - # self.highpage is temporary for independent test of FontPage - self.highpage = highpage = self.create_page_highlight() - fontpage = self.create_page_font_tab() - keyspage = self.create_page_keys() - genpage = self.create_page_general() - extpage = self.create_page_extensions() - note.add(fontpage, text='Fonts/Tabs') - note.add(highpage, text='Highlights') - note.add(keyspage, text=' Keys ') - note.add(genpage, text=' General ') - note.add(extpage, text='Extensions') + self.highpage = self.create_page_highlight() + self.fontpage = FontPage(note, self.highpage) + self.keyspage = self.create_page_keys() + self.genpage = self.create_page_general() + self.extpage = self.create_page_extensions() + note.add(self.fontpage, text='Fonts/Tabs') + note.add(self.highpage, text='Highlights') + note.add(self.keyspage, text=' Keys ') + note.add(self.genpage, text=' General ') + note.add(self.extpage, text='Extensions') note.enable_traversal() note.pack(side=TOP, expand=TRUE, fill=BOTH) self.create_action_buttons().pack(side=BOTTOM) @@ -130,8 +129,8 @@ def load_configs(self): load_key_cfg load_general_cfg """ - self.load_font_cfg() - self.load_tab_cfg() + #self.load_font_cfg() + #self.load_tab_cfg() self.load_theme_cfg() self.load_key_cfg() self.load_general_cfg() diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 7fa0194033881ce..0498c35ea25c9ca 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -47,158 +47,158 @@ def tearDownModule(): del root -class FontTest(unittest.TestCase): - """Test that font widgets enable users to make font changes. - - Test that widget actions set vars, that var changes add three - options to changes and call set_samples, and that set_samples - changes the font of both sample boxes. - """ - @classmethod - def setUpClass(cls): - dialog.set_samples = Func() # Mask instance method. - - @classmethod - def tearDownClass(cls): - del dialog.set_samples # Unmask instance method. - - def setUp(self): - changes.clear() - - def test_load_font_cfg(self): - # Leave widget load test to human visual check. - # TODO Improve checks when add IdleConf.get_font_values. - d = dialog - d.font_name.set('Fake') - d.font_size.set('1') - d.font_bold.set(True) - d.set_samples.called = 0 - d.load_font_cfg() - self.assertNotEqual(d.font_name.get(), 'Fake') - self.assertNotEqual(d.font_size.get(), '1') - self.assertFalse(d.font_bold.get()) - self.assertEqual(d.set_samples.called, 4) - - def test_fontlist_key(self): - # Up and Down keys should select a new font. - - if dialog.fontlist.size() < 2: - cls.skipTest('need at least 2 fonts') - fontlist = dialog.fontlist - fontlist.activate(0) - font = dialog.fontlist.get('active') - - # Test Down key. - fontlist.focus_force() - fontlist.update() - fontlist.event_generate('') - fontlist.event_generate('') - - down_font = fontlist.get('active') - self.assertNotEqual(down_font, font) - self.assertIn(dialog.font_name.get(), down_font.lower()) - - # Test Up key. - fontlist.focus_force() - fontlist.update() - fontlist.event_generate('') - fontlist.event_generate('') - - up_font = fontlist.get('active') - self.assertEqual(up_font, font) - self.assertIn(dialog.font_name.get(), up_font.lower()) - - def test_fontlist_mouse(self): - # Click on item should select that item. - - if dialog.fontlist.size() < 2: - cls.skipTest('need at least 2 fonts') - fontlist = dialog.fontlist - fontlist.activate(0) - - # Select next item in listbox - fontlist.focus_force() - fontlist.see(1) - fontlist.update() - x, y, dx, dy = fontlist.bbox(1) - x += dx // 2 - y += dy // 2 - fontlist.event_generate('', x=x, y=y) - fontlist.event_generate('', x=x, y=y) - - font1 = fontlist.get(1) - select_font = fontlist.get('anchor') - self.assertEqual(select_font, font1) - self.assertIn(dialog.font_name.get(), font1.lower()) - - def test_sizelist(self): - # Click on number shouod select that number - d = dialog - d.sizelist.variable.set(40) - self.assertEqual(d.font_size.get(), '40') - - def test_bold_toggle(self): - # Click on checkbutton should invert it. - d = dialog - d.font_bold.set(False) - d.bold_toggle.invoke() - self.assertTrue(d.font_bold.get()) - d.bold_toggle.invoke() - self.assertFalse(d.font_bold.get()) - - def test_font_set(self): - # Test that setting a font Variable results in 3 provisional - # change entries and a call to set_samples. Use values sure to - # not be defaults. - - default_font = idleConf.GetFont(root, 'main', 'EditorWindow') - default_size = str(default_font[1]) - default_bold = default_font[2] == 'bold' - d = dialog - d.font_size.set(default_size) - d.font_bold.set(default_bold) - d.set_samples.called = 0 - - d.font_name.set('Test Font') - expected = {'EditorWindow': {'font': 'Test Font', - 'font-size': default_size, - 'font-bold': str(default_bold)}} - self.assertEqual(mainpage, expected) - self.assertEqual(d.set_samples.called, 1) - changes.clear() - - d.font_size.set('20') - expected = {'EditorWindow': {'font': 'Test Font', - 'font-size': '20', - 'font-bold': str(default_bold)}} - self.assertEqual(mainpage, expected) - self.assertEqual(d.set_samples.called, 2) - changes.clear() - - d.font_bold.set(not default_bold) - expected = {'EditorWindow': {'font': 'Test Font', - 'font-size': '20', - 'font-bold': str(not default_bold)}} - self.assertEqual(mainpage, expected) - self.assertEqual(d.set_samples.called, 3) - - def test_set_samples(self): - d = dialog - del d.set_samples # Unmask method for test - d.font_sample, d.highlight_sample = {}, {} - d.font_name.set('test') - d.font_size.set('5') - d.font_bold.set(1) - expected = {'font': ('test', '5', 'bold')} - - # Test set_samples. - d.set_samples() - self.assertTrue(d.font_sample == d.highlight_sample == expected) - - del d.font_sample, d.highlight_sample - d.set_samples = Func() # Re-mask for other tests. - - +##class FontTest(unittest.TestCase): +## """Test that font widgets enable users to make font changes. +## +## Test that widget actions set vars, that var changes add three +## options to changes and call set_samples, and that set_samples +## changes the font of both sample boxes. +## """ +## @classmethod +## def setUpClass(cls): +## dialog.set_samples = Func() # Mask instance method. +## +## @classmethod +## def tearDownClass(cls): +## del dialog.set_samples # Unmask instance method. +## +## def setUp(self): +## changes.clear() +## +## def test_load_font_cfg(self): +## # Leave widget load test to human visual check. +## # TODO Improve checks when add IdleConf.get_font_values. +## d = dialog +## d.font_name.set('Fake') +## d.font_size.set('1') +## d.font_bold.set(True) +## d.set_samples.called = 0 +## d.load_font_cfg() +## self.assertNotEqual(d.font_name.get(), 'Fake') +## self.assertNotEqual(d.font_size.get(), '1') +## self.assertFalse(d.font_bold.get()) +## self.assertEqual(d.set_samples.called, 4) +## +## def test_fontlist_key(self): +## # Up and Down keys should select a new font. +## +## if dialog.fontlist.size() < 2: +## cls.skipTest('need at least 2 fonts') +## fontlist = dialog.fontlist +## fontlist.activate(0) +## font = dialog.fontlist.get('active') +## +## # Test Down key. +## fontlist.focus_force() +## fontlist.update() +## fontlist.event_generate('') +## fontlist.event_generate('') +## +## down_font = fontlist.get('active') +## self.assertNotEqual(down_font, font) +## self.assertIn(dialog.font_name.get(), down_font.lower()) +## +## # Test Up key. +## fontlist.focus_force() +## fontlist.update() +## fontlist.event_generate('') +## fontlist.event_generate('') +## +## up_font = fontlist.get('active') +## self.assertEqual(up_font, font) +## self.assertIn(dialog.font_name.get(), up_font.lower()) +## +## def test_fontlist_mouse(self): +## # Click on item should select that item. +## +## if dialog.fontlist.size() < 2: +## cls.skipTest('need at least 2 fonts') +## fontlist = dialog.fontlist +## fontlist.activate(0) +## +## # Select next item in listbox +## fontlist.focus_force() +## fontlist.see(1) +## fontlist.update() +## x, y, dx, dy = fontlist.bbox(1) +## x += dx // 2 +## y += dy // 2 +## fontlist.event_generate('', x=x, y=y) +## fontlist.event_generate('', x=x, y=y) +## +## font1 = fontlist.get(1) +## select_font = fontlist.get('anchor') +## self.assertEqual(select_font, font1) +## self.assertIn(dialog.font_name.get(), font1.lower()) +## +## def test_sizelist(self): +## # Click on number shouod select that number +## d = dialog +## d.sizelist.variable.set(40) +## self.assertEqual(d.font_size.get(), '40') +## +## def test_bold_toggle(self): +## # Click on checkbutton should invert it. +## d = dialog +## d.font_bold.set(False) +## d.bold_toggle.invoke() +## self.assertTrue(d.font_bold.get()) +## d.bold_toggle.invoke() +## self.assertFalse(d.font_bold.get()) +## +## def test_font_set(self): +## # Test that setting a font Variable results in 3 provisional +## # change entries and a call to set_samples. Use values sure to +## # not be defaults. +## +## default_font = idleConf.GetFont(root, 'main', 'EditorWindow') +## default_size = str(default_font[1]) +## default_bold = default_font[2] == 'bold' +## d = dialog +## d.font_size.set(default_size) +## d.font_bold.set(default_bold) +## d.set_samples.called = 0 +## +## d.font_name.set('Test Font') +## expected = {'EditorWindow': {'font': 'Test Font', +## 'font-size': default_size, +## 'font-bold': str(default_bold)}} +## self.assertEqual(mainpage, expected) +## self.assertEqual(d.set_samples.called, 1) +## changes.clear() +## +## d.font_size.set('20') +## expected = {'EditorWindow': {'font': 'Test Font', +## 'font-size': '20', +## 'font-bold': str(default_bold)}} +## self.assertEqual(mainpage, expected) +## self.assertEqual(d.set_samples.called, 2) +## changes.clear() +## +## d.font_bold.set(not default_bold) +## expected = {'EditorWindow': {'font': 'Test Font', +## 'font-size': '20', +## 'font-bold': str(not default_bold)}} +## self.assertEqual(mainpage, expected) +## self.assertEqual(d.set_samples.called, 3) +## +## def test_set_samples(self): +## d = dialog +## del d.set_samples # Unmask method for test +## d.font_sample, d.highlight_sample = {}, {} +## d.font_name.set('test') +## d.font_size.set('5') +## d.font_bold.set(1) +## expected = {'font': ('test', '5', 'bold')} +## +## # Test set_samples. +## d.set_samples() +## self.assertTrue(d.font_sample == d.highlight_sample == expected) +## +## del d.font_sample, d.highlight_sample +## d.set_samples = Func() # Re-mask for other tests. +## +## class FontPageTest(unittest.TestCase): """Test that font widgets enable users to make font changes. @@ -208,17 +208,15 @@ class FontPageTest(unittest.TestCase): """ @classmethod def setUpClass(cls): - page = cls.page = configdialog.FontPage(dialog.note, dialog.highpage) - dialog.note.insert(0, page, text='copy') + page = cls.page = dialog.fontpage + #dialog.note.insert(0, page, text='copy') #dialog.note.add(page, text='copyfgfg') dialog.note.select(page) - cls.page.set_samples = Func() # Mask instance method. - tracers.attach() + page.set_samples = Func() # Mask instance method. @classmethod def tearDownClass(cls): del cls.page.set_samples # Unmask instance method. - cls.page.destroy() # delete when live def setUp(self): changes.clear() @@ -359,31 +357,26 @@ def test_set_samples(self): d.set_samples = Func() # Re-mask for other tests. -class IndentTest(unittest.TestCase): - - def test_load_tab_cfg(self): - d = dialog - d.space_num.set(16) - d.load_tab_cfg() - self.assertEqual(d.space_num.get(), 4) - - def test_indent_scale(self): - changes.clear() - dialog.indent_scale.set(26) - self.assertEqual(dialog.space_num.get(), 16) - self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) - - +##class IndentTest(unittest.TestCase): +## +## def test_load_tab_cfg(self): +## d = dialog +## d.space_num.set(16) +## d.load_tab_cfg() +## self.assertEqual(d.space_num.get(), 4) +## +## def test_indent_scale(self): +## changes.clear() +## dialog.indent_scale.set(26) +## self.assertEqual(dialog.space_num.get(), 16) +## self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) +## +## class IndentOptionTest(unittest.TestCase): @classmethod def setUpClass(cls): - cls.page = configdialog.FontPage(dialog.note, dialog.highpage) - tracers.attach() - - @classmethod - def tearDownClass(cls): - cls.page.destroy() + cls.page = dialog.fontpage def test_load_tab_cfg(self): d = self.page From c14bb1e4444461d1b188970c9591bc30cf55c953 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 30 Jul 2017 00:41:10 -0400 Subject: [PATCH 08/10] Complete Step 3: make sure tests pass, dialog ok, with old code disabled. --- Lib/idlelib/configdialog.py | 404 ++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 202 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index afad1da453a4139..8d2a8419269f956 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -219,208 +219,208 @@ def help(self): text=help_common+help_pages.get(page, '')) - def create_page_font_tab(self): - """Return frame of widgets for Font/Tabs tab. - - Fonts: Enable users to provisionally change font face, size, or - boldness and to see the consequence of proposed choices. Each - action set 3 options in changes structuree and changes the - corresponding aspect of the font sample on this page and - highlight sample on highlight page. - - Function load_font_cfg initializes font vars and widgets from - idleConf entries and tk. - - Fontlist: mouse button 1 click or up or down key invoke - on_fontlist_select(), which sets var font_name. - - Sizelist: clicking the menubutton opens the dropdown menu. A - mouse button 1 click or return key sets var font_size. - - Bold_toggle: clicking the box toggles var font_bold. - - Changing any of the font vars invokes var_changed_font, which - adds all 3 font options to changes and calls set_samples. - Set_samples applies a new font constructed from the font vars to - font_sample and to highlight_sample on the hightlight page. - - Tabs: Enable users to change spaces entered for indent tabs. - Changing indent_scale value with the mouse sets Var space_num, - which invokes the default callback to add an entry to - changes. Load_tab_cfg initializes space_num to default. - - Widget Structure: (*) widgets bound to self - frame (of tab_pages) - frame_font: LabelFrame - frame_font_name: Frame - font_name_title: Label - (*)fontlist: ListBox - font_name - scroll_font: Scrollbar - frame_font_param: Frame - font_size_title: Label - (*)sizelist: DynOptionMenu - font_size - (*)bold_toggle: Checkbutton - font_bold - frame_font_sample: Frame - (*)font_sample: Label - frame_indent: LabelFrame - indent_title: Label - (*)indent_scale: Scale - space_num - """ - parent = self.parent - self.font_name = tracers.add(StringVar(parent), self.var_changed_font) - self.font_size = tracers.add(StringVar(parent), self.var_changed_font) - self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font) - self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) - - # Create widgets: - # body and body section frames. - frame = Frame(self.note) - frame_font = LabelFrame( - frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') - frame_indent = LabelFrame( - frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') - # frame_font. - frame_font_name = Frame(frame_font) - frame_font_param = Frame(frame_font) - font_name_title = Label( - frame_font_name, justify=LEFT, text='Font Face :') - self.fontlist = Listbox(frame_font_name, height=5, - takefocus=True, exportselection=FALSE) - self.fontlist.bind('', self.on_fontlist_select) - self.fontlist.bind('', self.on_fontlist_select) - self.fontlist.bind('', self.on_fontlist_select) - scroll_font = Scrollbar(frame_font_name) - scroll_font.config(command=self.fontlist.yview) - self.fontlist.config(yscrollcommand=scroll_font.set) - font_size_title = Label(frame_font_param, text='Size :') - self.sizelist = DynOptionMenu(frame_font_param, self.font_size, None) - self.bold_toggle = Checkbutton( - frame_font_param, variable=self.font_bold, - onvalue=1, offvalue=0, text='Bold') - frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1) - temp_font = tkFont.Font(parent, ('courier', 10, 'normal')) - self.font_sample = Label( - frame_font_sample, justify=LEFT, font=temp_font, - text='AaBbCcDdEe\nFfGgHhIiJj\n1234567890\n#:+=(){}[]') - # frame_indent. - indent_title = Label( - frame_indent, justify=LEFT, - text='Python Standard: 4 Spaces!') - self.indent_scale = Scale( - frame_indent, variable=self.space_num, - orient='horizontal', tickinterval=2, from_=2, to=16) - - # Pack widgets: - # body. - 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_font. - frame_font_name.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) - self.fontlist.pack(side=LEFT, expand=TRUE, fill=X) - scroll_font.pack(side=LEFT, fill=Y) - font_size_title.pack(side=LEFT, anchor=W) - self.sizelist.pack(side=LEFT, anchor=W) - self.bold_toggle.pack(side=LEFT, anchor=W, padx=20) - frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) - self.font_sample.pack(expand=TRUE, fill=BOTH) - # frame_indent. - frame_indent.pack(side=TOP, fill=X) - indent_title.pack(side=TOP, anchor=W, padx=5) - self.indent_scale.pack(side=TOP, padx=5, fill=X) - - return frame - - def load_font_cfg(self): - """Load current configuration settings for the font options. - - Retrieve current font with idleConf.GetFont and font families - from tk. Setup fontlist and set font_name. Setup sizelist, - which sets font_size. Set font_bold. Call set_samples. - """ - configured_font = idleConf.GetFont(self, 'main', 'EditorWindow') - font_name = configured_font[0].lower() - font_size = configured_font[1] - font_bold = configured_font[2]=='bold' - - # Set editor font selection list and font_name. - fonts = list(tkFont.families(self)) - fonts.sort() - for font in fonts: - self.fontlist.insert(END, font) - self.font_name.set(font_name) - lc_fonts = [s.lower() for s in fonts] - try: - current_font_index = lc_fonts.index(font_name) - self.fontlist.see(current_font_index) - self.fontlist.select_set(current_font_index) - self.fontlist.select_anchor(current_font_index) - self.fontlist.activate(current_font_index) - except ValueError: - pass - # Set font size dropdown. - self.sizelist.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', - '16', '18', '20', '22', '25', '29', '34', '40'), - font_size) - # Set font weight. - self.font_bold.set(font_bold) - self.set_samples() - - def var_changed_font(self, *params): - """Store changes to font attributes. - - When one font attribute changes, save them all, as they are - not independent from each other. In particular, when we are - overriding the default font, we need to write out everything. - """ - value = self.font_name.get() - changes.add_option('main', 'EditorWindow', 'font', value) - value = self.font_size.get() - changes.add_option('main', 'EditorWindow', 'font-size', value) - value = self.font_bold.get() - changes.add_option('main', 'EditorWindow', 'font-bold', value) - self.set_samples() - - def on_fontlist_select(self, event): - """Handle selecting a font from the list. - - Event can result from either mouse click or Up or Down key. - Set font_name and example displays to selection. - """ - font = self.fontlist.get( - ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) - self.font_name.set(font.lower()) - - def set_samples(self, event=None): - """Update update both screen samples with the font settings. - - Called on font initialization and change events. - Accesses font_name, font_size, and font_bold Variables. - Updates font_sample and hightlight page highlight_sample. - """ - font_name = self.font_name.get() - font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL - new_font = (font_name, self.font_size.get(), font_weight) - self.font_sample['font'] = new_font - self.highlight_sample['font'] = new_font - - def load_tab_cfg(self): - """Load current configuration settings for the tab options. - - Attributes updated: - space_num: Set to value from idleConf. - """ - # Set indent sizes. - space_num = idleConf.GetOption( - 'main', 'Indent', 'num-spaces', default=4, type='int') - self.space_num.set(space_num) - - def var_changed_space_num(self, *params): - "Store change to indentation size." - value = self.space_num.get() - changes.add_option('main', 'Indent', 'num-spaces', value) - +## def create_page_font_tab(self): +## """Return frame of widgets for Font/Tabs tab. +## +## Fonts: Enable users to provisionally change font face, size, or +## boldness and to see the consequence of proposed choices. Each +## action set 3 options in changes structuree and changes the +## corresponding aspect of the font sample on this page and +## highlight sample on highlight page. +## +## Function load_font_cfg initializes font vars and widgets from +## idleConf entries and tk. +## +## Fontlist: mouse button 1 click or up or down key invoke +## on_fontlist_select(), which sets var font_name. +## +## Sizelist: clicking the menubutton opens the dropdown menu. A +## mouse button 1 click or return key sets var font_size. +## +## Bold_toggle: clicking the box toggles var font_bold. +## +## Changing any of the font vars invokes var_changed_font, which +## adds all 3 font options to changes and calls set_samples. +## Set_samples applies a new font constructed from the font vars to +## font_sample and to highlight_sample on the hightlight page. +## +## Tabs: Enable users to change spaces entered for indent tabs. +## Changing indent_scale value with the mouse sets Var space_num, +## which invokes the default callback to add an entry to +## changes. Load_tab_cfg initializes space_num to default. +## +## Widget Structure: (*) widgets bound to self +## frame (of tab_pages) +## frame_font: LabelFrame +## frame_font_name: Frame +## font_name_title: Label +## (*)fontlist: ListBox - font_name +## scroll_font: Scrollbar +## frame_font_param: Frame +## font_size_title: Label +## (*)sizelist: DynOptionMenu - font_size +## (*)bold_toggle: Checkbutton - font_bold +## frame_font_sample: Frame +## (*)font_sample: Label +## frame_indent: LabelFrame +## indent_title: Label +## (*)indent_scale: Scale - space_num +## """ +## parent = self.parent +## self.font_name = tracers.add(StringVar(parent), self.var_changed_font) +## self.font_size = tracers.add(StringVar(parent), self.var_changed_font) +## self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font) +## self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) +## +## # Create widgets: +## # body and body section frames. +## frame = Frame(self.note) +## frame_font = LabelFrame( +## frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') +## frame_indent = LabelFrame( +## frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') +## # frame_font. +## frame_font_name = Frame(frame_font) +## frame_font_param = Frame(frame_font) +## font_name_title = Label( +## frame_font_name, justify=LEFT, text='Font Face :') +## self.fontlist = Listbox(frame_font_name, height=5, +## takefocus=True, exportselection=FALSE) +## self.fontlist.bind('', self.on_fontlist_select) +## self.fontlist.bind('', self.on_fontlist_select) +## self.fontlist.bind('', self.on_fontlist_select) +## scroll_font = Scrollbar(frame_font_name) +## scroll_font.config(command=self.fontlist.yview) +## self.fontlist.config(yscrollcommand=scroll_font.set) +## font_size_title = Label(frame_font_param, text='Size :') +## self.sizelist = DynOptionMenu(frame_font_param, self.font_size, None) +## self.bold_toggle = Checkbutton( +## frame_font_param, variable=self.font_bold, +## onvalue=1, offvalue=0, text='Bold') +## frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1) +## temp_font = tkFont.Font(parent, ('courier', 10, 'normal')) +## self.font_sample = Label( +## frame_font_sample, justify=LEFT, font=temp_font, +## text='AaBbCcDdEe\nFfGgHhIiJj\n1234567890\n#:+=(){}[]') +## # frame_indent. +## indent_title = Label( +## frame_indent, justify=LEFT, +## text='Python Standard: 4 Spaces!') +## self.indent_scale = Scale( +## frame_indent, variable=self.space_num, +## orient='horizontal', tickinterval=2, from_=2, to=16) +## +## # Pack widgets: +## # body. +## 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_font. +## frame_font_name.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) +## self.fontlist.pack(side=LEFT, expand=TRUE, fill=X) +## scroll_font.pack(side=LEFT, fill=Y) +## font_size_title.pack(side=LEFT, anchor=W) +## self.sizelist.pack(side=LEFT, anchor=W) +## self.bold_toggle.pack(side=LEFT, anchor=W, padx=20) +## frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) +## self.font_sample.pack(expand=TRUE, fill=BOTH) +## # frame_indent. +## frame_indent.pack(side=TOP, fill=X) +## indent_title.pack(side=TOP, anchor=W, padx=5) +## self.indent_scale.pack(side=TOP, padx=5, fill=X) +## +## return frame +## +## def load_font_cfg(self): +## """Load current configuration settings for the font options. +## +## Retrieve current font with idleConf.GetFont and font families +## from tk. Setup fontlist and set font_name. Setup sizelist, +## which sets font_size. Set font_bold. Call set_samples. +## """ +## configured_font = idleConf.GetFont(self, 'main', 'EditorWindow') +## font_name = configured_font[0].lower() +## font_size = configured_font[1] +## font_bold = configured_font[2]=='bold' +## +## # Set editor font selection list and font_name. +## fonts = list(tkFont.families(self)) +## fonts.sort() +## for font in fonts: +## self.fontlist.insert(END, font) +## self.font_name.set(font_name) +## lc_fonts = [s.lower() for s in fonts] +## try: +## current_font_index = lc_fonts.index(font_name) +## self.fontlist.see(current_font_index) +## self.fontlist.select_set(current_font_index) +## self.fontlist.select_anchor(current_font_index) +## self.fontlist.activate(current_font_index) +## except ValueError: +## pass +## # Set font size dropdown. +## self.sizelist.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', +## '16', '18', '20', '22', '25', '29', '34', '40'), +## font_size) +## # Set font weight. +## self.font_bold.set(font_bold) +## self.set_samples() +## +## def var_changed_font(self, *params): +## """Store changes to font attributes. +## +## When one font attribute changes, save them all, as they are +## not independent from each other. In particular, when we are +## overriding the default font, we need to write out everything. +## """ +## value = self.font_name.get() +## changes.add_option('main', 'EditorWindow', 'font', value) +## value = self.font_size.get() +## changes.add_option('main', 'EditorWindow', 'font-size', value) +## value = self.font_bold.get() +## changes.add_option('main', 'EditorWindow', 'font-bold', value) +## self.set_samples() +## +## def on_fontlist_select(self, event): +## """Handle selecting a font from the list. +## +## Event can result from either mouse click or Up or Down key. +## Set font_name and example displays to selection. +## """ +## font = self.fontlist.get( +## ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) +## self.font_name.set(font.lower()) +## +## def set_samples(self, event=None): +## """Update update both screen samples with the font settings. +## +## Called on font initialization and change events. +## Accesses font_name, font_size, and font_bold Variables. +## Updates font_sample and hightlight page highlight_sample. +## """ +## font_name = self.font_name.get() +## font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL +## new_font = (font_name, self.font_size.get(), font_weight) +## self.font_sample['font'] = new_font +## self.highlight_sample['font'] = new_font +## +## def load_tab_cfg(self): +## """Load current configuration settings for the tab options. +## +## Attributes updated: +## space_num: Set to value from idleConf. +## """ +## # Set indent sizes. +## space_num = idleConf.GetOption( +## 'main', 'Indent', 'num-spaces', default=4, type='int') +## self.space_num.set(space_num) +## +## def var_changed_space_num(self, *params): +## "Store change to indentation size." +## value = self.space_num.get() +## changes.add_option('main', 'Indent', 'num-spaces', value) +## def create_page_highlight(self): """Return frame of widgets for Highlighting tab. From ebe28f8e8ac1d4b3fc9a842606eb1c9df9d9edca Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 30 Jul 2017 00:50:31 -0400 Subject: [PATCH 09/10] Step 4: delete old code. --- Lib/idlelib/configdialog.py | 203 --------------------- Lib/idlelib/idle_test/test_configdialog.py | 171 +---------------- 2 files changed, 2 insertions(+), 372 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 8d2a8419269f956..92bbc106344d944 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -219,209 +219,6 @@ def help(self): text=help_common+help_pages.get(page, '')) -## def create_page_font_tab(self): -## """Return frame of widgets for Font/Tabs tab. -## -## Fonts: Enable users to provisionally change font face, size, or -## boldness and to see the consequence of proposed choices. Each -## action set 3 options in changes structuree and changes the -## corresponding aspect of the font sample on this page and -## highlight sample on highlight page. -## -## Function load_font_cfg initializes font vars and widgets from -## idleConf entries and tk. -## -## Fontlist: mouse button 1 click or up or down key invoke -## on_fontlist_select(), which sets var font_name. -## -## Sizelist: clicking the menubutton opens the dropdown menu. A -## mouse button 1 click or return key sets var font_size. -## -## Bold_toggle: clicking the box toggles var font_bold. -## -## Changing any of the font vars invokes var_changed_font, which -## adds all 3 font options to changes and calls set_samples. -## Set_samples applies a new font constructed from the font vars to -## font_sample and to highlight_sample on the hightlight page. -## -## Tabs: Enable users to change spaces entered for indent tabs. -## Changing indent_scale value with the mouse sets Var space_num, -## which invokes the default callback to add an entry to -## changes. Load_tab_cfg initializes space_num to default. -## -## Widget Structure: (*) widgets bound to self -## frame (of tab_pages) -## frame_font: LabelFrame -## frame_font_name: Frame -## font_name_title: Label -## (*)fontlist: ListBox - font_name -## scroll_font: Scrollbar -## frame_font_param: Frame -## font_size_title: Label -## (*)sizelist: DynOptionMenu - font_size -## (*)bold_toggle: Checkbutton - font_bold -## frame_font_sample: Frame -## (*)font_sample: Label -## frame_indent: LabelFrame -## indent_title: Label -## (*)indent_scale: Scale - space_num -## """ -## parent = self.parent -## self.font_name = tracers.add(StringVar(parent), self.var_changed_font) -## self.font_size = tracers.add(StringVar(parent), self.var_changed_font) -## self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font) -## self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) -## -## # Create widgets: -## # body and body section frames. -## frame = Frame(self.note) -## frame_font = LabelFrame( -## frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') -## frame_indent = LabelFrame( -## frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') -## # frame_font. -## frame_font_name = Frame(frame_font) -## frame_font_param = Frame(frame_font) -## font_name_title = Label( -## frame_font_name, justify=LEFT, text='Font Face :') -## self.fontlist = Listbox(frame_font_name, height=5, -## takefocus=True, exportselection=FALSE) -## self.fontlist.bind('', self.on_fontlist_select) -## self.fontlist.bind('', self.on_fontlist_select) -## self.fontlist.bind('', self.on_fontlist_select) -## scroll_font = Scrollbar(frame_font_name) -## scroll_font.config(command=self.fontlist.yview) -## self.fontlist.config(yscrollcommand=scroll_font.set) -## font_size_title = Label(frame_font_param, text='Size :') -## self.sizelist = DynOptionMenu(frame_font_param, self.font_size, None) -## self.bold_toggle = Checkbutton( -## frame_font_param, variable=self.font_bold, -## onvalue=1, offvalue=0, text='Bold') -## frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1) -## temp_font = tkFont.Font(parent, ('courier', 10, 'normal')) -## self.font_sample = Label( -## frame_font_sample, justify=LEFT, font=temp_font, -## text='AaBbCcDdEe\nFfGgHhIiJj\n1234567890\n#:+=(){}[]') -## # frame_indent. -## indent_title = Label( -## frame_indent, justify=LEFT, -## text='Python Standard: 4 Spaces!') -## self.indent_scale = Scale( -## frame_indent, variable=self.space_num, -## orient='horizontal', tickinterval=2, from_=2, to=16) -## -## # Pack widgets: -## # body. -## 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_font. -## frame_font_name.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) -## self.fontlist.pack(side=LEFT, expand=TRUE, fill=X) -## scroll_font.pack(side=LEFT, fill=Y) -## font_size_title.pack(side=LEFT, anchor=W) -## self.sizelist.pack(side=LEFT, anchor=W) -## self.bold_toggle.pack(side=LEFT, anchor=W, padx=20) -## frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) -## self.font_sample.pack(expand=TRUE, fill=BOTH) -## # frame_indent. -## frame_indent.pack(side=TOP, fill=X) -## indent_title.pack(side=TOP, anchor=W, padx=5) -## self.indent_scale.pack(side=TOP, padx=5, fill=X) -## -## return frame -## -## def load_font_cfg(self): -## """Load current configuration settings for the font options. -## -## Retrieve current font with idleConf.GetFont and font families -## from tk. Setup fontlist and set font_name. Setup sizelist, -## which sets font_size. Set font_bold. Call set_samples. -## """ -## configured_font = idleConf.GetFont(self, 'main', 'EditorWindow') -## font_name = configured_font[0].lower() -## font_size = configured_font[1] -## font_bold = configured_font[2]=='bold' -## -## # Set editor font selection list and font_name. -## fonts = list(tkFont.families(self)) -## fonts.sort() -## for font in fonts: -## self.fontlist.insert(END, font) -## self.font_name.set(font_name) -## lc_fonts = [s.lower() for s in fonts] -## try: -## current_font_index = lc_fonts.index(font_name) -## self.fontlist.see(current_font_index) -## self.fontlist.select_set(current_font_index) -## self.fontlist.select_anchor(current_font_index) -## self.fontlist.activate(current_font_index) -## except ValueError: -## pass -## # Set font size dropdown. -## self.sizelist.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', -## '16', '18', '20', '22', '25', '29', '34', '40'), -## font_size) -## # Set font weight. -## self.font_bold.set(font_bold) -## self.set_samples() -## -## def var_changed_font(self, *params): -## """Store changes to font attributes. -## -## When one font attribute changes, save them all, as they are -## not independent from each other. In particular, when we are -## overriding the default font, we need to write out everything. -## """ -## value = self.font_name.get() -## changes.add_option('main', 'EditorWindow', 'font', value) -## value = self.font_size.get() -## changes.add_option('main', 'EditorWindow', 'font-size', value) -## value = self.font_bold.get() -## changes.add_option('main', 'EditorWindow', 'font-bold', value) -## self.set_samples() -## -## def on_fontlist_select(self, event): -## """Handle selecting a font from the list. -## -## Event can result from either mouse click or Up or Down key. -## Set font_name and example displays to selection. -## """ -## font = self.fontlist.get( -## ACTIVE if event.type.name == 'KeyRelease' else ANCHOR) -## self.font_name.set(font.lower()) -## -## def set_samples(self, event=None): -## """Update update both screen samples with the font settings. -## -## Called on font initialization and change events. -## Accesses font_name, font_size, and font_bold Variables. -## Updates font_sample and hightlight page highlight_sample. -## """ -## font_name = self.font_name.get() -## font_weight = tkFont.BOLD if self.font_bold.get() else tkFont.NORMAL -## new_font = (font_name, self.font_size.get(), font_weight) -## self.font_sample['font'] = new_font -## self.highlight_sample['font'] = new_font -## -## def load_tab_cfg(self): -## """Load current configuration settings for the tab options. -## -## Attributes updated: -## space_num: Set to value from idleConf. -## """ -## # Set indent sizes. -## space_num = idleConf.GetOption( -## 'main', 'Indent', 'num-spaces', default=4, type='int') -## self.space_num.set(space_num) -## -## def var_changed_space_num(self, *params): -## "Store change to indentation size." -## value = self.space_num.get() -## changes.add_option('main', 'Indent', 'num-spaces', value) -## - def create_page_highlight(self): """Return frame of widgets for Highlighting tab. diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 0498c35ea25c9ca..8da726b80c07737 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -47,158 +47,6 @@ def tearDownModule(): del root -##class FontTest(unittest.TestCase): -## """Test that font widgets enable users to make font changes. -## -## Test that widget actions set vars, that var changes add three -## options to changes and call set_samples, and that set_samples -## changes the font of both sample boxes. -## """ -## @classmethod -## def setUpClass(cls): -## dialog.set_samples = Func() # Mask instance method. -## -## @classmethod -## def tearDownClass(cls): -## del dialog.set_samples # Unmask instance method. -## -## def setUp(self): -## changes.clear() -## -## def test_load_font_cfg(self): -## # Leave widget load test to human visual check. -## # TODO Improve checks when add IdleConf.get_font_values. -## d = dialog -## d.font_name.set('Fake') -## d.font_size.set('1') -## d.font_bold.set(True) -## d.set_samples.called = 0 -## d.load_font_cfg() -## self.assertNotEqual(d.font_name.get(), 'Fake') -## self.assertNotEqual(d.font_size.get(), '1') -## self.assertFalse(d.font_bold.get()) -## self.assertEqual(d.set_samples.called, 4) -## -## def test_fontlist_key(self): -## # Up and Down keys should select a new font. -## -## if dialog.fontlist.size() < 2: -## cls.skipTest('need at least 2 fonts') -## fontlist = dialog.fontlist -## fontlist.activate(0) -## font = dialog.fontlist.get('active') -## -## # Test Down key. -## fontlist.focus_force() -## fontlist.update() -## fontlist.event_generate('') -## fontlist.event_generate('') -## -## down_font = fontlist.get('active') -## self.assertNotEqual(down_font, font) -## self.assertIn(dialog.font_name.get(), down_font.lower()) -## -## # Test Up key. -## fontlist.focus_force() -## fontlist.update() -## fontlist.event_generate('') -## fontlist.event_generate('') -## -## up_font = fontlist.get('active') -## self.assertEqual(up_font, font) -## self.assertIn(dialog.font_name.get(), up_font.lower()) -## -## def test_fontlist_mouse(self): -## # Click on item should select that item. -## -## if dialog.fontlist.size() < 2: -## cls.skipTest('need at least 2 fonts') -## fontlist = dialog.fontlist -## fontlist.activate(0) -## -## # Select next item in listbox -## fontlist.focus_force() -## fontlist.see(1) -## fontlist.update() -## x, y, dx, dy = fontlist.bbox(1) -## x += dx // 2 -## y += dy // 2 -## fontlist.event_generate('', x=x, y=y) -## fontlist.event_generate('', x=x, y=y) -## -## font1 = fontlist.get(1) -## select_font = fontlist.get('anchor') -## self.assertEqual(select_font, font1) -## self.assertIn(dialog.font_name.get(), font1.lower()) -## -## def test_sizelist(self): -## # Click on number shouod select that number -## d = dialog -## d.sizelist.variable.set(40) -## self.assertEqual(d.font_size.get(), '40') -## -## def test_bold_toggle(self): -## # Click on checkbutton should invert it. -## d = dialog -## d.font_bold.set(False) -## d.bold_toggle.invoke() -## self.assertTrue(d.font_bold.get()) -## d.bold_toggle.invoke() -## self.assertFalse(d.font_bold.get()) -## -## def test_font_set(self): -## # Test that setting a font Variable results in 3 provisional -## # change entries and a call to set_samples. Use values sure to -## # not be defaults. -## -## default_font = idleConf.GetFont(root, 'main', 'EditorWindow') -## default_size = str(default_font[1]) -## default_bold = default_font[2] == 'bold' -## d = dialog -## d.font_size.set(default_size) -## d.font_bold.set(default_bold) -## d.set_samples.called = 0 -## -## d.font_name.set('Test Font') -## expected = {'EditorWindow': {'font': 'Test Font', -## 'font-size': default_size, -## 'font-bold': str(default_bold)}} -## self.assertEqual(mainpage, expected) -## self.assertEqual(d.set_samples.called, 1) -## changes.clear() -## -## d.font_size.set('20') -## expected = {'EditorWindow': {'font': 'Test Font', -## 'font-size': '20', -## 'font-bold': str(default_bold)}} -## self.assertEqual(mainpage, expected) -## self.assertEqual(d.set_samples.called, 2) -## changes.clear() -## -## d.font_bold.set(not default_bold) -## expected = {'EditorWindow': {'font': 'Test Font', -## 'font-size': '20', -## 'font-bold': str(not default_bold)}} -## self.assertEqual(mainpage, expected) -## self.assertEqual(d.set_samples.called, 3) -## -## def test_set_samples(self): -## d = dialog -## del d.set_samples # Unmask method for test -## d.font_sample, d.highlight_sample = {}, {} -## d.font_name.set('test') -## d.font_size.set('5') -## d.font_bold.set(1) -## expected = {'font': ('test', '5', 'bold')} -## -## # Test set_samples. -## d.set_samples() -## self.assertTrue(d.font_sample == d.highlight_sample == expected) -## -## del d.font_sample, d.highlight_sample -## d.set_samples = Func() # Re-mask for other tests. -## -## class FontPageTest(unittest.TestCase): """Test that font widgets enable users to make font changes. @@ -357,22 +205,7 @@ def test_set_samples(self): d.set_samples = Func() # Re-mask for other tests. -##class IndentTest(unittest.TestCase): -## -## def test_load_tab_cfg(self): -## d = dialog -## d.space_num.set(16) -## d.load_tab_cfg() -## self.assertEqual(d.space_num.get(), 4) -## -## def test_indent_scale(self): -## changes.clear() -## dialog.indent_scale.set(26) -## self.assertEqual(dialog.space_num.get(), 16) -## self.assertEqual(mainpage, {'Indent': {'num-spaces': '16'}}) -## -## -class IndentOptionTest(unittest.TestCase): +class IndentTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -414,7 +247,7 @@ class GeneralTest(unittest.TestCase): def setUpClass(cls): d = dialog # Select General tab so can force focus on helplist. - d.note.select(3) + d.note.select(d.genpage) # Mask instance methods used by help functions. d.set = d.set_add_delete_state = Func() d.upc = d.update_help_changes = Func() From 6b92e75b92c5f20be7c4ecddc3308ddae8a63f1f Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 30 Jul 2017 01:01:23 -0400 Subject: [PATCH 10/10] News blurb. --- .../NEWS.d/next/IDLE/2017-07-30-01-00-58.bpo-31004.m8cc1t.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2017-07-30-01-00-58.bpo-31004.m8cc1t.rst diff --git a/Misc/NEWS.d/next/IDLE/2017-07-30-01-00-58.bpo-31004.m8cc1t.rst b/Misc/NEWS.d/next/IDLE/2017-07-30-01-00-58.bpo-31004.m8cc1t.rst new file mode 100644 index 000000000000000..47fed949d106fb8 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2017-07-30-01-00-58.bpo-31004.m8cc1t.rst @@ -0,0 +1,4 @@ +IDLE - Factor FontPage(Frame) class from ConfigDialog. + +Slightly modified tests continue to pass. Fix General tests. Patch mostly by +Cheryl Sabella.