[Python-checkins] bpo-40468: Split IDLE settings General tab (GH-26621)

terryjreedy webhook-mailer at python.org
Wed Jun 9 16:18:21 EDT 2021


https://github.com/python/cpython/commit/275d5f7957dbb56a6d5e1248addff210ee2e7270
commit: 275d5f7957dbb56a6d5e1248addff210ee2e7270
branch: main
author: Terry Jan Reedy <tjreedy at udel.edu>
committer: terryjreedy <tjreedy at udel.edu>
date: 2021-06-09T16:17:58-04:00
summary:

bpo-40468: Split IDLE settings General tab (GH-26621)

Replace it with Windows tab for Shell and Editor options
and Shell/Ed for options exclusive to one of them.

Create room for more options and make dialog shorter,
to better fit small windows.

files:
M Lib/idlelib/configdialog.py
M Lib/idlelib/idle_test/test_configdialog.py
M Misc/NEWS.d/next/IDLE/2021-06-08-03-04-51.bpo-40468.tUCGUb.rst

diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py
index 9c0153b1a7361..e3fa34f2090e4 100644
--- a/Lib/idlelib/configdialog.py
+++ b/Lib/idlelib/configdialog.py
@@ -116,11 +116,14 @@ def create_widgets(self):
         self.highpage = HighPage(note, self.extpage)
         self.fontpage = FontPage(note, self.highpage)
         self.keyspage = KeysPage(note, self.extpage)
-        self.genpage = GenPage(note)
+        self.winpage = WinPage(note)
+        self.shedpage = ShedPage(note)
+
         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.winpage, text=' Windows ')
+        note.add(self.shedpage, text=' Shell/Ed ')
         note.add(self.extpage, text='Extensions')
         note.enable_traversal()
         note.pack(side=TOP, expand=TRUE, fill=BOTH)
@@ -1594,14 +1597,14 @@ def delete_custom_keys(self):
         self.set_keys_type()
 
 
-class GenPage(Frame):
+class WinPage(Frame):
 
     def __init__(self, master):
         super().__init__(master)
 
         self.init_validators()
-        self.create_page_general()
-        self.load_general_cfg()
+        self.create_page_windows()
+        self.load_windows_cfg()
 
     def init_validators(self):
         digits_or_empty_re = re.compile(r'[0-9]*')
@@ -1610,26 +1613,17 @@ def is_digits_or_empty(s):
             return digits_or_empty_re.fullmatch(s) is not None
         self.digits_only = (self.register(is_digits_or_empty), '%P',)
 
-    def create_page_general(self):
-        """Return frame of widgets for General tab.
-
-        Enable users to provisionally change general options. Function
-        load_general_cfg initializes tk variables and helplist using
-        idleConf.  Radiobuttons startup_shell_on and startup_editor_on
-        set var startup_edit. Radiobuttons save_ask_on and save_auto_on
-        set var autosave. Entry boxes win_width_int and win_height_int
-        set var win_width and win_height.  Setting var_name invokes the
-        default callback that adds option to changes.
+    def create_page_windows(self):
+        """Return frame of widgets for Windows tab.
 
-        Helplist: load_general_cfg loads list user_helplist with
-        name, position pairs and copies names to listbox helplist.
-        Clicking a name invokes help_source selected. Clicking
-        button_helplist_name invokes helplist_item_name, which also
-        changes user_helplist.  These functions all call
-        set_add_delete_state. All but load call update_help_changes to
-        rewrite changes['main']['HelpFiles'].
+        Enable users to provisionally change general window options.
+        Function load_windows_cfg initializes tk variables idleConf.
+        Radiobuttons startup_shell_on and startup_editor_on set var
+        startup_edit. Entry boxes win_width_int and win_height_int set var
+        win_width and win_height.  Setting var_name invokes the default
+        callback that adds option to changes.
 
-        Widgets for GenPage(Frame):  (*) widgets bound to self
+        Widgets for WinPage(Frame):  (*) widgets bound to self
             frame_window: LabelFrame
                 frame_run: Frame
                     startup_title: Label
@@ -1654,24 +1648,9 @@ def create_page_general(self):
                     paren_time_title: Label
                     (*)paren_flash_time: Entry - flash_delay
                     (*)bell_on: Checkbutton - paren_bell
-            frame_editor: LabelFrame
-                frame_save: Frame
-                    run_save_title: Label
-                    (*)save_ask_on: Radiobutton - autosave
-                    (*)save_auto_on: Radiobutton - autosave
                 frame_format: Frame
                     format_width_title: Label
                     (*)format_width_int: Entry - format_width
-                frame_line_numbers_default: Frame
-                    line_numbers_default_title: Label
-                    (*)line_numbers_default_bool: Checkbutton - line_numbers_default
-                frame_context: Frame
-                    context_title: Label
-                    (*)context_int: Entry - context_lines
-            frame_shell: LabelFrame
-                frame_auto_squeeze_min_lines: Frame
-                    auto_squeeze_min_lines_title: Label
-                    (*)auto_squeeze_min_lines_int: Entry - auto_squeeze_min_lines
         """
         # Integer values need StringVar because int('') raises.
         self.startup_edit = tracers.add(
@@ -1690,29 +1669,13 @@ def create_page_general(self):
                 StringVar(self), ('extensions', 'ParenMatch', 'flash-delay'))
         self.paren_bell = tracers.add(
                 BooleanVar(self), ('extensions', 'ParenMatch', 'bell'))
-
-        self.auto_squeeze_min_lines = tracers.add(
-                StringVar(self), ('main', 'PyShell', 'auto-squeeze-min-lines'))
-
-        self.autosave = tracers.add(
-                IntVar(self), ('main', 'General', 'autosave'))
         self.format_width = tracers.add(
                 StringVar(self), ('extensions', 'FormatParagraph', 'max-width'))
-        self.line_numbers_default = tracers.add(
-                BooleanVar(self),
-                ('main', 'EditorWindow', 'line-numbers-default'))
-        self.context_lines = tracers.add(
-                StringVar(self), ('extensions', 'CodeContext', 'maxlines'))
 
         # Create widgets:
-        # Section frames.
         frame_window = LabelFrame(self, borderwidth=2, relief=GROOVE,
                                   text=' Window Preferences')
-        frame_editor = LabelFrame(self, borderwidth=2, relief=GROOVE,
-                                  text=' Editor Preferences')
-        frame_shell = LabelFrame(self, borderwidth=2, relief=GROOVE,
-                                 text=' Shell Preferences')
-        # Frame_window.
+
         frame_run = Frame(frame_window, borderwidth=0)
         startup_title = Label(frame_run, text='At Startup')
         self.startup_editor_on = Radiobutton(
@@ -1747,8 +1710,7 @@ def create_page_general(self):
         self.auto_wait_int = Entry(frame_autocomplete, width=6,
                                    textvariable=self.autocomplete_wait,
                                    validatecommand=self.digits_only,
-                                   validate='key',
-                                   )
+                                   validate='key')
 
         frame_paren1 = Frame(frame_window, borderwidth=0)
         paren_style_title = Label(frame_paren1, text='Paren Match Style')
@@ -1763,55 +1725,16 @@ def create_page_general(self):
                 frame_paren2, textvariable=self.flash_delay, width=6)
         self.bell_on = Checkbutton(
                 frame_paren2, text="Bell on Mismatch", variable=self.paren_bell)
-
-        # Frame_editor.
-        frame_save = Frame(frame_editor, borderwidth=0)
-        run_save_title = Label(frame_save, text='At Start of Run (F5)  ')
-        self.save_ask_on = Radiobutton(
-                frame_save, variable=self.autosave, value=0,
-                text="Prompt to Save")
-        self.save_auto_on = Radiobutton(
-                frame_save, variable=self.autosave, value=1,
-                text='No Prompt')
-
-        frame_format = Frame(frame_editor, borderwidth=0)
+        frame_format = Frame(frame_window, borderwidth=0)
         format_width_title = Label(frame_format,
                                    text='Format Paragraph Max Width')
         self.format_width_int = Entry(
                 frame_format, textvariable=self.format_width, width=4,
                 validatecommand=self.digits_only, validate='key',
-        )
-
-        frame_line_numbers_default = Frame(frame_editor, borderwidth=0)
-        line_numbers_default_title = Label(
-            frame_line_numbers_default, text='Show line numbers in new windows')
-        self.line_numbers_default_bool = Checkbutton(
-                frame_line_numbers_default,
-                variable=self.line_numbers_default,
-                width=1)
-
-        frame_context = Frame(frame_editor, borderwidth=0)
-        context_title = Label(frame_context, text='Max Context Lines :')
-        self.context_int = Entry(
-                frame_context, textvariable=self.context_lines, width=3,
-                validatecommand=self.digits_only, validate='key',
-        )
-
-        # Frame_shell.
-        frame_auto_squeeze_min_lines = Frame(frame_shell, borderwidth=0)
-        auto_squeeze_min_lines_title = Label(frame_auto_squeeze_min_lines,
-                                             text='Auto-Squeeze Min. Lines:')
-        self.auto_squeeze_min_lines_int = Entry(
-                frame_auto_squeeze_min_lines, width=4,
-                textvariable=self.auto_squeeze_min_lines,
-                validatecommand=self.digits_only, validate='key',
-        )
+                )
 
         # Pack widgets:
-        # Body.
         frame_window.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
-        frame_editor.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
-        frame_shell.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
         # frame_run.
         frame_run.pack(side=TOP, padx=5, pady=0, fill=X)
         startup_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
@@ -1840,34 +1763,10 @@ def create_page_general(self):
         paren_time_title.pack(side=LEFT, anchor=W, padx=5)
         self.bell_on.pack(side=RIGHT, anchor=E, padx=15, pady=5)
         self.paren_flash_time.pack(side=TOP, anchor=W, padx=15, pady=5)
-
-        # frame_save.
-        frame_save.pack(side=TOP, padx=5, pady=0, fill=X)
-        run_save_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
-        self.save_auto_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
-        self.save_ask_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
         # frame_format.
         frame_format.pack(side=TOP, padx=5, pady=0, fill=X)
         format_width_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
         self.format_width_int.pack(side=TOP, padx=10, pady=5)
-        # frame_line_numbers_default.
-        frame_line_numbers_default.pack(side=TOP, padx=5, pady=0, fill=X)
-        line_numbers_default_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
-        self.line_numbers_default_bool.pack(side=LEFT, padx=5, pady=5)
-        # frame_context.
-        frame_context.pack(side=TOP, padx=5, pady=0, fill=X)
-        context_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
-        self.context_int.pack(side=TOP, padx=5, pady=5)
-
-        # frame_auto_squeeze_min_lines
-        frame_auto_squeeze_min_lines.pack(side=TOP, padx=5, pady=0, fill=X)
-        auto_squeeze_min_lines_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
-        self.auto_squeeze_min_lines_int.pack(side=TOP, padx=5, pady=5)
-
-    def load_general_cfg(self):
-        "Load current configuration settings for the general options."
-        self.load_windows_cfg()
-        self.load_shelled_cfg()
 
     def load_windows_cfg(self):
         # Set variables for all windows.
@@ -1887,22 +1786,142 @@ def load_windows_cfg(self):
                 'extensions', 'ParenMatch', 'flash-delay', type='int'))
         self.paren_bell.set(idleConf.GetOption(
                 'extensions', 'ParenMatch', 'bell'))
+        self.format_width.set(idleConf.GetOption(
+                'extensions', 'FormatParagraph', 'max-width', type='int'))
+
+
+class ShedPage(Frame):
+
+    def __init__(self, master):
+        super().__init__(master)
+
+        self.init_validators()
+        self.create_page_shed()
+        self.load_shelled_cfg()
+
+    def init_validators(self):
+        digits_or_empty_re = re.compile(r'[0-9]*')
+        def is_digits_or_empty(s):
+            "Return 's is blank or contains only digits'"
+            return digits_or_empty_re.fullmatch(s) is not None
+        self.digits_only = (self.register(is_digits_or_empty), '%P',)
+
+    def create_page_shed(self):
+        """Return frame of widgets for Shell/Ed tab.
+
+        Enable users to provisionally change shell and editor options.
+        Function load_shed_cfg initializes tk variables using idleConf.
+        Entry box auto_squeeze_min_lines_int sets
+        auto_squeeze_min_lines_int.  Setting var_name invokes the
+        default callback that adds option to changes.
+
+        Widgets for ShedPage(Frame):  (*) widgets bound to self
+            frame_shell: LabelFrame
+                frame_auto_squeeze_min_lines: Frame
+                    auto_squeeze_min_lines_title: Label
+                    (*)auto_squeeze_min_lines_int: Entry -
+                       auto_squeeze_min_lines
+            frame_editor: LabelFrame
+                frame_save: Frame
+                    run_save_title: Label
+                    (*)save_ask_on: Radiobutton - autosave
+                    (*)save_auto_on: Radiobutton - autosave
+                frame_format: Frame
+                    format_width_title: Label
+                    (*)format_width_int: Entry - format_width
+                frame_line_numbers_default: Frame
+                    line_numbers_default_title: Label
+                    (*)line_numbers_default_bool: Checkbutton - line_numbers_default
+                frame_context: Frame
+                    context_title: Label
+                    (*)context_int: Entry - context_lines
+        """
+        # Integer values need StringVar because int('') raises.
+        self.auto_squeeze_min_lines = tracers.add(
+                StringVar(self), ('main', 'PyShell', 'auto-squeeze-min-lines'))
+
+        self.autosave = tracers.add(
+                IntVar(self), ('main', 'General', 'autosave'))
+        self.line_numbers_default = tracers.add(
+                BooleanVar(self),
+                ('main', 'EditorWindow', 'line-numbers-default'))
+        self.context_lines = tracers.add(
+                StringVar(self), ('extensions', 'CodeContext', 'maxlines'))
+
+        # Create widgets:
+        frame_shell = LabelFrame(self, borderwidth=2, relief=GROOVE,
+                                 text=' Shell Preferences')
+        frame_editor = LabelFrame(self, borderwidth=2, relief=GROOVE,
+                                  text=' Editor Preferences')
+        # Frame_shell.
+        frame_auto_squeeze_min_lines = Frame(frame_shell, borderwidth=0)
+        auto_squeeze_min_lines_title = Label(frame_auto_squeeze_min_lines,
+                                             text='Auto-Squeeze Min. Lines:')
+        self.auto_squeeze_min_lines_int = Entry(
+                frame_auto_squeeze_min_lines, width=4,
+                textvariable=self.auto_squeeze_min_lines,
+                validatecommand=self.digits_only, validate='key',
+        )
+        # Frame_editor.
+        frame_save = Frame(frame_editor, borderwidth=0)
+        run_save_title = Label(frame_save, text='At Start of Run (F5)  ')
+
+        self.save_ask_on = Radiobutton(
+                frame_save, variable=self.autosave, value=0,
+                text="Prompt to Save")
+        self.save_auto_on = Radiobutton(
+                frame_save, variable=self.autosave, value=1,
+                text='No Prompt')
+
+        frame_line_numbers_default = Frame(frame_editor, borderwidth=0)
+        line_numbers_default_title = Label(
+            frame_line_numbers_default, text='Show line numbers in new windows')
+        self.line_numbers_default_bool = Checkbutton(
+                frame_line_numbers_default,
+                variable=self.line_numbers_default,
+                width=1)
+
+        frame_context = Frame(frame_editor, borderwidth=0)
+        context_title = Label(frame_context, text='Max Context Lines :')
+        self.context_int = Entry(
+                frame_context, textvariable=self.context_lines, width=3,
+                validatecommand=self.digits_only, validate='key',
+        )
+
+        # Pack widgets:
+        frame_shell.pack(side=TOP, padx=5, pady=5, fill=BOTH)
+        Label(self).pack()  # Spacer -- better solution?
+        frame_editor.pack(side=TOP, padx=5, pady=5, fill=BOTH)
+        # frame_auto_squeeze_min_lines
+        frame_auto_squeeze_min_lines.pack(side=TOP, padx=5, pady=0, fill=X)
+        auto_squeeze_min_lines_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+        self.auto_squeeze_min_lines_int.pack(side=TOP, padx=5, pady=5)
+        # frame_save.
+        frame_save.pack(side=TOP, padx=5, pady=0, fill=X)
+        run_save_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+        self.save_auto_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
+        self.save_ask_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
+        # frame_line_numbers_default.
+        frame_line_numbers_default.pack(side=TOP, padx=5, pady=0, fill=X)
+        line_numbers_default_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+        self.line_numbers_default_bool.pack(side=LEFT, padx=5, pady=5)
+        # frame_context.
+        frame_context.pack(side=TOP, padx=5, pady=0, fill=X)
+        context_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+        self.context_int.pack(side=TOP, padx=5, pady=5)
 
     def load_shelled_cfg(self):
+        # Set variables for shell windows.
+        self.auto_squeeze_min_lines.set(idleConf.GetOption(
+                'main', 'PyShell', 'auto-squeeze-min-lines', type='int'))
         # Set variables for editor windows.
         self.autosave.set(idleConf.GetOption(
                 'main', 'General', 'autosave', default=0, type='bool'))
-        self.format_width.set(idleConf.GetOption(
-                'extensions', 'FormatParagraph', 'max-width', type='int'))
         self.line_numbers_default.set(idleConf.GetOption(
                 'main', 'EditorWindow', 'line-numbers-default', type='bool'))
         self.context_lines.set(idleConf.GetOption(
                 'extensions', 'CodeContext', 'maxlines', type='int'))
 
-        # Set variables for shell windows.
-        self.auto_squeeze_min_lines.set(idleConf.GetOption(
-                'main', 'PyShell', 'auto-squeeze-min-lines', type='int'))
-
 
 class ExtPage(Frame):
     def __init__(self, master):
diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py
index e01aa634473dc..f71d1b1bc09a0 100644
--- a/Lib/idlelib/idle_test/test_configdialog.py
+++ b/Lib/idlelib/idle_test/test_configdialog.py
@@ -1203,7 +1203,7 @@ def test_delete_custom_keys(self):
         del d.askyesno
 
 
-class GenPageTest(unittest.TestCase):
+class WinPageTest(unittest.TestCase):
     """Test that general tab widgets enable users to make changes.
 
     Test that widget actions set vars, that var changes add
@@ -1211,24 +1211,22 @@ class GenPageTest(unittest.TestCase):
     """
     @classmethod
     def setUpClass(cls):
-        page = cls.page = dialog.genpage
+        page = cls.page = dialog.winpage
         dialog.note.select(page)
         page.update()
 
     def setUp(self):
         changes.clear()
 
-    def test_load_general_cfg(self):
+    def test_load_windows_cfg(self):
         # Set to wrong values, load, check right values.
         eq = self.assertEqual
         d = self.page
         d.startup_edit.set(1)
-        d.autosave.set(1)
         d.win_width.set(1)
         d.win_height.set(1)
-        d.load_general_cfg()
+        d.load_windows_cfg()
         eq(d.startup_edit.get(), 0)
-        eq(d.autosave.get(), 0)
         eq(d.win_width.get(), '80')
         eq(d.win_height.get(), '40')
 
@@ -1274,6 +1272,35 @@ def test_parenmatch(self):
         d.bell_on.invoke()
         eq(extpage, {'ParenMatch': {'bell': 'False'}})
 
+    def test_paragraph(self):
+        self.page.format_width_int.delete(0, 'end')
+        self.page.format_width_int.insert(0, '11')
+        self.assertEqual(extpage, {'FormatParagraph': {'max-width': '11'}})
+
+
+class GenPageTest(unittest.TestCase):
+    """Test that shed tab widgets enable users to make changes.
+
+    Test that widget actions set vars, that var changes add
+    options to changes.
+    """
+    @classmethod
+    def setUpClass(cls):
+        page = cls.page = dialog.shedpage
+        dialog.note.select(page)
+        page.update()
+
+    def setUp(self):
+        changes.clear()
+
+    def test_load_shelled_cfg(self):
+        # Set to wrong values, load, check right values.
+        eq = self.assertEqual
+        d = self.page
+        d.autosave.set(1)
+        d.load_shelled_cfg()
+        eq(d.autosave.get(), 0)
+
     def test_autosave(self):
         d = self.page
         d.save_auto_on.invoke()
@@ -1281,11 +1308,6 @@ def test_autosave(self):
         d.save_ask_on.invoke()
         self.assertEqual(mainpage, {'General': {'autosave': '0'}})
 
-    def test_paragraph(self):
-        self.page.format_width_int.delete(0, 'end')
-        self.page.format_width_int.insert(0, '11')
-        self.assertEqual(extpage, {'FormatParagraph': {'max-width': '11'}})
-
     def test_context(self):
         self.page.context_int.delete(0, 'end')
         self.page.context_int.insert(0, '1')
diff --git a/Misc/NEWS.d/next/IDLE/2021-06-08-03-04-51.bpo-40468.tUCGUb.rst b/Misc/NEWS.d/next/IDLE/2021-06-08-03-04-51.bpo-40468.tUCGUb.rst
index 79cb1cca099ad..526036ccf841e 100644
--- a/Misc/NEWS.d/next/IDLE/2021-06-08-03-04-51.bpo-40468.tUCGUb.rst
+++ b/Misc/NEWS.d/next/IDLE/2021-06-08-03-04-51.bpo-40468.tUCGUb.rst
@@ -1,2 +1,4 @@
-Shorten settings dialog by moving help sources to extensions tab. This will
-improve issues with dialog being too tall for some screens.
+Split the settings dialog General tab into Windows and Shell/ED tabs.
+Move help sources, which extend the Help menu, to the Extensions tab.
+Make space for new options and shorten the dialog.
+The latter makes the dialog better fit small screens.



More information about the Python-checkins mailing list