From 3537ef87541a01816c8bb29d929c4a40c99daf42 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Thu, 27 Jul 2017 10:02:33 -0400 Subject: [PATCH 1/3] bpo-30853: IDLE: Convert font and general vars to use VarTrace --- Lib/idlelib/configdialog.py | 48 ++++++++----------- .../2017-07-27-10-01-14.bpo-30853.enPvvc.rst | 1 + 2 files changed, 20 insertions(+), 29 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index e359ec24cd3a5b..c66fae1d02ab69 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -51,6 +51,7 @@ def __init__(self, parent, title='', _htest=False, _utest=False): """ Toplevel.__init__(self, parent) self.parent = parent + self.tracers = VarTrace() if _htest: parent.instance_dict = {} if not _utest: @@ -76,6 +77,7 @@ def __init__(self, parent, title='', _htest=False, _utest=False): # self.bind('', self.Help) #context help self.load_configs() self.attach_var_callbacks() # Avoid callbacks during load_configs. + self.tracers.attach() if not _utest: self.grab_set() @@ -133,10 +135,6 @@ def load_configs(self): def attach_var_callbacks(self): "Attach callbacks to variables that can be changed." - self.font_size.trace_add('write', self.var_changed_font) - self.font_name.trace_add('write', self.var_changed_font) - self.font_bold.trace_add('write', self.var_changed_font) - self.space_num.trace_add('write', self.var_changed_space_num) self.color.trace_add('write', self.var_changed_color) self.builtin_theme.trace_add('write', self.var_changed_builtin_theme) self.custom_theme.trace_add('write', self.var_changed_custom_theme) @@ -146,22 +144,16 @@ def attach_var_callbacks(self): self.builtin_keys.trace_add('write', self.var_changed_builtin_keys) self.custom_keys.trace_add('write', self.var_changed_custom_keys) self.are_keys_builtin.trace_add('write', self.var_changed_are_keys_builtin) - self.win_width.trace_add('write', self.var_changed_win_width) - self.win_height.trace_add('write', self.var_changed_win_height) - self.startup_edit.trace_add('write', self.var_changed_startup_edit) - self.autosave.trace_add('write', self.var_changed_autosave) def remove_var_callbacks(self): "Remove callbacks to prevent memory leaks." for var in ( - self.font_size, self.font_name, self.font_bold, - self.space_num, self.color, self.builtin_theme, + self.color, self.builtin_theme, self.custom_theme, self.is_builtin_theme, self.highlight_target, self.keybinding, self.builtin_keys, self.custom_keys, - self.are_keys_builtin, self.win_width, self.win_height, - self.startup_edit, self.autosave,): + self.are_keys_builtin,): var.trace_remove('write', var.trace_info()[0][1]) - + self.tracers.detach() def create_action_buttons(self): """Return frame of action buttons for dialog. @@ -273,7 +265,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 @@ -294,10 +286,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 = self.tracers.add(StringVar(parent), self.var_changed_font) + self.font_size = self.tracers.add(StringVar(parent), self.var_changed_font) + self.font_bold = self.tracers.add(BooleanVar(parent), self.var_changed_font) + self.space_num = self.tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) # Create widgets: # body and body section frames. @@ -443,12 +435,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) - - def create_page_highlight(self): """Return frame of widgets for Highlighting tab. @@ -1434,7 +1420,7 @@ def create_page_general(self): 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 - var_changed_var_name callback that adds option to changes. + default callback that adds option to changes. Helplist: load_general_cfg loads list user_helplist with name, position pairs and copies names to listbox helplist. @@ -1470,10 +1456,14 @@ def create_page_general(self): scroll_helplist: Scrollbar """ parent = self.parent - self.startup_edit = IntVar(parent) - self.autosave = IntVar(parent) - self.win_width = StringVar(parent) - self.win_height = StringVar(parent) + self.startup_edit = self.tracers.add( + IntVar(parent), ('main', 'General', 'editor-on-startup')) + self.autosave = self.tracers.add( + IntVar(parent), ('main', 'General', 'autosave')) + self.win_width = self.tracers.add( + StringVar(parent), ('main', 'EditorWindow', 'width')) + self.win_height = self.tracers.add( + StringVar(parent), ('main', 'EditorWindow', 'height')) # Create widgets: # body. diff --git a/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst b/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst new file mode 100644 index 00000000000000..9c09ddb447e890 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst @@ -0,0 +1 @@ +Add VarTrace class to configdialog. From 8e1e5f81b32b937a4835535cbc28f4c3608b1065 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 27 Jul 2017 23:03:48 -0400 Subject: [PATCH 2/3] Make tracers global. Revise blurb. --- Lib/idlelib/configdialog.py | 29 ++++++++++--------- .../2017-07-27-10-01-14.bpo-30853.enPvvc.rst | 6 +++- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index c66fae1d02ab69..74b15bcefd942f 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -30,6 +30,7 @@ changes = ConfigChanges() + class ConfigDialog(Toplevel): """Config dialog for IDLE. """ @@ -51,7 +52,6 @@ def __init__(self, parent, title='', _htest=False, _utest=False): """ Toplevel.__init__(self, parent) self.parent = parent - self.tracers = VarTrace() if _htest: parent.instance_dict = {} if not _utest: @@ -77,13 +77,14 @@ def __init__(self, parent, title='', _htest=False, _utest=False): # self.bind('', self.Help) #context help self.load_configs() self.attach_var_callbacks() # Avoid callbacks during load_configs. - self.tracers.attach() + tracers.attach() if not _utest: self.grab_set() self.wm_deiconify() self.wait_window() + def create_widgets(self): """Create and place widgets for tabbed dialog. @@ -153,7 +154,8 @@ def remove_var_callbacks(self): self.keybinding, self.builtin_keys, self.custom_keys, self.are_keys_builtin,): var.trace_remove('write', var.trace_info()[0][1]) - self.tracers.detach() + tracers.detach() + def create_action_buttons(self): """Return frame of action buttons for dialog. @@ -286,10 +288,10 @@ def create_page_font_tab(self): (*)indent_scale: Scale - space_num """ parent = self.parent - self.font_name = self.tracers.add(StringVar(parent), self.var_changed_font) - self.font_size = self.tracers.add(StringVar(parent), self.var_changed_font) - self.font_bold = self.tracers.add(BooleanVar(parent), self.var_changed_font) - self.space_num = self.tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces')) + 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. @@ -1155,9 +1157,6 @@ def load_key_cfg(self): keyset_name = idleConf.CurrentKeys() self.load_keys_list(keyset_name) - - - def var_changed_builtin_keys(self, *params): "Process selection of builtin key set." old_keys = ( @@ -1456,13 +1455,13 @@ def create_page_general(self): scroll_helplist: Scrollbar """ parent = self.parent - self.startup_edit = self.tracers.add( + self.startup_edit = tracers.add( IntVar(parent), ('main', 'General', 'editor-on-startup')) - self.autosave = self.tracers.add( + self.autosave = tracers.add( IntVar(parent), ('main', 'General', 'autosave')) - self.win_width = self.tracers.add( + self.win_width = tracers.add( StringVar(parent), ('main', 'EditorWindow', 'width')) - self.win_height = self.tracers.add( + self.win_height = tracers.add( StringVar(parent), ('main', 'EditorWindow', 'height')) # Create widgets: @@ -1898,6 +1897,8 @@ def detach(self): self.untraced.append((var, callback)) +tracers = VarTrace() + help_common = '''\ When you click either the Apply or Ok buttons, settings in this dialog that are different from IDLE's default are saved in diff --git a/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst b/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst index 9c09ddb447e890..9cabca193b91cd 100644 --- a/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst +++ b/Misc/NEWS.d/next/IDLE/2017-07-27-10-01-14.bpo-30853.enPvvc.rst @@ -1 +1,5 @@ -Add VarTrace class to configdialog. +IDLE -- Factor a VarTrace class out of ConfigDialog. + +Instance tracers manages pairs consisting of a tk variable and a +callback function. When tracing is turned on, setting the variable +calls the function. Test coverage for the new class is 100%. From e45b95e9f5bd39c1634feee05582d789be4d5380 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Fri, 28 Jul 2017 09:50:38 -0400 Subject: [PATCH 3/3] Convert all vars to use VarTrace --- Lib/idlelib/configdialog.py | 55 +++++++++++++++---------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 74b15bcefd942f..92155e3726c16a 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -76,7 +76,7 @@ def __init__(self, parent, title='', _htest=False, _utest=False): # self.bind('', self.Apply) #apply changes, save # self.bind('', self.Help) #context help self.load_configs() - self.attach_var_callbacks() # Avoid callbacks during load_configs. + # Avoid callbacks during load_configs. tracers.attach() if not _utest: @@ -99,7 +99,6 @@ def create_widgets(self): create_page_extensions create_action_buttons load_configs: Load pages except for extensions. - attach_var_callbacks remove_var_callbacks activate_config_changes: Tell editors to reload. """ @@ -134,29 +133,10 @@ def load_configs(self): self.load_general_cfg() # note: extension page handled separately - def attach_var_callbacks(self): - "Attach callbacks to variables that can be changed." - self.color.trace_add('write', self.var_changed_color) - self.builtin_theme.trace_add('write', self.var_changed_builtin_theme) - self.custom_theme.trace_add('write', self.var_changed_custom_theme) - self.is_builtin_theme.trace_add('write', self.var_changed_is_builtin_theme) - self.highlight_target.trace_add('write', self.var_changed_highlight_target) - self.keybinding.trace_add('write', self.var_changed_keybinding) - self.builtin_keys.trace_add('write', self.var_changed_builtin_keys) - self.custom_keys.trace_add('write', self.var_changed_custom_keys) - self.are_keys_builtin.trace_add('write', self.var_changed_are_keys_builtin) - def remove_var_callbacks(self): "Remove callbacks to prevent memory leaks." - for var in ( - self.color, self.builtin_theme, - self.custom_theme, self.is_builtin_theme, self.highlight_target, - self.keybinding, self.builtin_keys, self.custom_keys, - self.are_keys_builtin,): - var.trace_remove('write', var.trace_info()[0][1]) tracers.detach() - def create_action_buttons(self): """Return frame of action buttons for dialog. @@ -506,12 +486,17 @@ def create_page_highlight(self): 'Shell Stderr Text': ('stderr', '13'), } parent = self.parent - self.builtin_theme = StringVar(parent) - self.custom_theme = StringVar(parent) + self.builtin_theme = tracers.add( + StringVar(parent), self.var_changed_builtin_theme) + self.custom_theme = tracers.add( + StringVar(parent), self.var_changed_custom_theme) self.fg_bg_toggle = BooleanVar(parent) - self.color = StringVar(parent) - self.is_builtin_theme = BooleanVar(parent) - self.highlight_target = StringVar(parent) + self.color = tracers.add( + StringVar(parent), self.var_changed_color) + self.is_builtin_theme = tracers.add( + BooleanVar(parent), self.var_changed_is_builtin_theme) + self.highlight_target = tracers.add( + StringVar(parent), self.var_changed_highlight_target) ##widget creation #body frame @@ -1050,10 +1035,14 @@ def create_page_keys(self): button_save_custom_keys: Button """ parent = self.parent - self.builtin_keys = StringVar(parent) - self.custom_keys = StringVar(parent) - self.are_keys_builtin = BooleanVar(parent) - self.keybinding = StringVar(parent) + self.builtin_keys = tracers.add( + StringVar(parent), self.var_changed_builtin_keys) + self.custom_keys = tracers.add( + StringVar(parent), self.var_changed_custom_keys) + self.are_keys_builtin = tracers.add( + BooleanVar(parent), self.var_changed_are_keys_builtin) + self.keybinding = tracers.add( + StringVar(parent), self.var_changed_keybinding) ##widget creation #body frame @@ -1862,9 +1851,9 @@ def add(self, var, callback): Args: var: Tk variable instance. - callback: Function to be used as a callback or - a tuple with IdleConf values for default - callback. + callback: Either function name to be used as a callback + or a tuple with IdleConf config-type, section, and + option names used in the default callback. Return: Tk variable instance.