Skip to content

Commit 5b59154

Browse files
csabellaterryjreedy
authored andcommitted
bpo-30853: IDLE: Convert font and general vars to use VarTrace (#2914)
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%.
1 parent 6fcb69d commit 5b59154

File tree

2 files changed

+47
-62
lines changed

2 files changed

+47
-62
lines changed

Lib/idlelib/configdialog.py

Lines changed: 42 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
changes = ConfigChanges()
3232

33+
3334
class ConfigDialog(Toplevel):
3435
"""Config dialog for IDLE.
3536
"""
@@ -75,13 +76,15 @@ def __init__(self, parent, title='', _htest=False, _utest=False):
7576
# self.bind('<Alt-a>', self.Apply) #apply changes, save
7677
# self.bind('<F1>', self.Help) #context help
7778
self.load_configs()
78-
self.attach_var_callbacks() # Avoid callbacks during load_configs.
79+
# Avoid callbacks during load_configs.
80+
tracers.attach()
7981

8082
if not _utest:
8183
self.grab_set()
8284
self.wm_deiconify()
8385
self.wait_window()
8486

87+
8588
def create_widgets(self):
8689
"""Create and place widgets for tabbed dialog.
8790
@@ -96,7 +99,6 @@ def create_widgets(self):
9699
create_page_extensions
97100
create_action_buttons
98101
load_configs: Load pages except for extensions.
99-
attach_var_callbacks
100102
remove_var_callbacks
101103
activate_config_changes: Tell editors to reload.
102104
"""
@@ -131,37 +133,9 @@ def load_configs(self):
131133
self.load_general_cfg()
132134
# note: extension page handled separately
133135

134-
def attach_var_callbacks(self):
135-
"Attach callbacks to variables that can be changed."
136-
self.font_size.trace_add('write', self.var_changed_font)
137-
self.font_name.trace_add('write', self.var_changed_font)
138-
self.font_bold.trace_add('write', self.var_changed_font)
139-
self.space_num.trace_add('write', self.var_changed_space_num)
140-
self.color.trace_add('write', self.var_changed_color)
141-
self.builtin_theme.trace_add('write', self.var_changed_builtin_theme)
142-
self.custom_theme.trace_add('write', self.var_changed_custom_theme)
143-
self.is_builtin_theme.trace_add('write', self.var_changed_is_builtin_theme)
144-
self.highlight_target.trace_add('write', self.var_changed_highlight_target)
145-
self.keybinding.trace_add('write', self.var_changed_keybinding)
146-
self.builtin_keys.trace_add('write', self.var_changed_builtin_keys)
147-
self.custom_keys.trace_add('write', self.var_changed_custom_keys)
148-
self.are_keys_builtin.trace_add('write', self.var_changed_are_keys_builtin)
149-
self.win_width.trace_add('write', self.var_changed_win_width)
150-
self.win_height.trace_add('write', self.var_changed_win_height)
151-
self.startup_edit.trace_add('write', self.var_changed_startup_edit)
152-
self.autosave.trace_add('write', self.var_changed_autosave)
153-
154136
def remove_var_callbacks(self):
155137
"Remove callbacks to prevent memory leaks."
156-
for var in (
157-
self.font_size, self.font_name, self.font_bold,
158-
self.space_num, self.color, self.builtin_theme,
159-
self.custom_theme, self.is_builtin_theme, self.highlight_target,
160-
self.keybinding, self.builtin_keys, self.custom_keys,
161-
self.are_keys_builtin, self.win_width, self.win_height,
162-
self.startup_edit, self.autosave,):
163-
var.trace_remove('write', var.trace_info()[0][1])
164-
138+
tracers.detach()
165139

166140
def create_action_buttons(self):
167141
"""Return frame of action buttons for dialog.
@@ -273,7 +247,7 @@ def create_page_font_tab(self):
273247
274248
Tabs: Enable users to change spaces entered for indent tabs.
275249
Changing indent_scale value with the mouse sets Var space_num,
276-
which invokes var_changed_space_num, which adds an entry to
250+
which invokes the default callback to add an entry to
277251
changes. Load_tab_cfg initializes space_num to default.
278252
279253
Widget Structure: (*) widgets bound to self
@@ -294,10 +268,10 @@ def create_page_font_tab(self):
294268
(*)indent_scale: Scale - space_num
295269
"""
296270
parent = self.parent
297-
self.font_name = StringVar(parent)
298-
self.font_size = StringVar(parent)
299-
self.font_bold = BooleanVar(parent)
300-
self.space_num = IntVar(parent)
271+
self.font_name = tracers.add(StringVar(parent), self.var_changed_font)
272+
self.font_size = tracers.add(StringVar(parent), self.var_changed_font)
273+
self.font_bold = tracers.add(BooleanVar(parent), self.var_changed_font)
274+
self.space_num = tracers.add(IntVar(parent), ('main', 'Indent', 'num-spaces'))
301275

302276
# Create widgets:
303277
# body and body section frames.
@@ -443,12 +417,6 @@ def load_tab_cfg(self):
443417
'main', 'Indent', 'num-spaces', default=4, type='int')
444418
self.space_num.set(space_num)
445419

446-
def var_changed_space_num(self, *params):
447-
"Store change to indentation size."
448-
value = self.space_num.get()
449-
changes.add_option('main', 'Indent', 'num-spaces', value)
450-
451-
452420
def create_page_highlight(self):
453421
"""Return frame of widgets for Highlighting tab.
454422
@@ -518,12 +486,17 @@ def create_page_highlight(self):
518486
'Shell Stderr Text': ('stderr', '13'),
519487
}
520488
parent = self.parent
521-
self.builtin_theme = StringVar(parent)
522-
self.custom_theme = StringVar(parent)
489+
self.builtin_theme = tracers.add(
490+
StringVar(parent), self.var_changed_builtin_theme)
491+
self.custom_theme = tracers.add(
492+
StringVar(parent), self.var_changed_custom_theme)
523493
self.fg_bg_toggle = BooleanVar(parent)
524-
self.color = StringVar(parent)
525-
self.is_builtin_theme = BooleanVar(parent)
526-
self.highlight_target = StringVar(parent)
494+
self.color = tracers.add(
495+
StringVar(parent), self.var_changed_color)
496+
self.is_builtin_theme = tracers.add(
497+
BooleanVar(parent), self.var_changed_is_builtin_theme)
498+
self.highlight_target = tracers.add(
499+
StringVar(parent), self.var_changed_highlight_target)
527500

528501
##widget creation
529502
#body frame
@@ -1062,10 +1035,14 @@ def create_page_keys(self):
10621035
button_save_custom_keys: Button
10631036
"""
10641037
parent = self.parent
1065-
self.builtin_keys = StringVar(parent)
1066-
self.custom_keys = StringVar(parent)
1067-
self.are_keys_builtin = BooleanVar(parent)
1068-
self.keybinding = StringVar(parent)
1038+
self.builtin_keys = tracers.add(
1039+
StringVar(parent), self.var_changed_builtin_keys)
1040+
self.custom_keys = tracers.add(
1041+
StringVar(parent), self.var_changed_custom_keys)
1042+
self.are_keys_builtin = tracers.add(
1043+
BooleanVar(parent), self.var_changed_are_keys_builtin)
1044+
self.keybinding = tracers.add(
1045+
StringVar(parent), self.var_changed_keybinding)
10691046

10701047
##widget creation
10711048
#body frame
@@ -1169,9 +1146,6 @@ def load_key_cfg(self):
11691146
keyset_name = idleConf.CurrentKeys()
11701147
self.load_keys_list(keyset_name)
11711148

1172-
1173-
1174-
11751149
def var_changed_builtin_keys(self, *params):
11761150
"Process selection of builtin key set."
11771151
old_keys = (
@@ -1434,7 +1408,7 @@ def create_page_general(self):
14341408
set var startup_edit. Radiobuttons save_ask_on and save_auto_on
14351409
set var autosave. Entry boxes win_width_int and win_height_int
14361410
set var win_width and win_height. Setting var_name invokes the
1437-
var_changed_var_name callback that adds option to changes.
1411+
default callback that adds option to changes.
14381412
14391413
Helplist: load_general_cfg loads list user_helplist with
14401414
name, position pairs and copies names to listbox helplist.
@@ -1470,10 +1444,14 @@ def create_page_general(self):
14701444
scroll_helplist: Scrollbar
14711445
"""
14721446
parent = self.parent
1473-
self.startup_edit = IntVar(parent)
1474-
self.autosave = IntVar(parent)
1475-
self.win_width = StringVar(parent)
1476-
self.win_height = StringVar(parent)
1447+
self.startup_edit = tracers.add(
1448+
IntVar(parent), ('main', 'General', 'editor-on-startup'))
1449+
self.autosave = tracers.add(
1450+
IntVar(parent), ('main', 'General', 'autosave'))
1451+
self.win_width = tracers.add(
1452+
StringVar(parent), ('main', 'EditorWindow', 'width'))
1453+
self.win_height = tracers.add(
1454+
StringVar(parent), ('main', 'EditorWindow', 'height'))
14771455

14781456
# Create widgets:
14791457
# body.
@@ -1873,9 +1851,9 @@ def add(self, var, callback):
18731851
18741852
Args:
18751853
var: Tk variable instance.
1876-
callback: Function to be used as a callback or
1877-
a tuple with IdleConf values for default
1878-
callback.
1854+
callback: Either function name to be used as a callback
1855+
or a tuple with IdleConf config-type, section, and
1856+
option names used in the default callback.
18791857
18801858
Return:
18811859
Tk variable instance.
@@ -1908,6 +1886,8 @@ def detach(self):
19081886
self.untraced.append((var, callback))
19091887

19101888

1889+
tracers = VarTrace()
1890+
19111891
help_common = '''\
19121892
When you click either the Apply or Ok buttons, settings in this
19131893
dialog that are different from IDLE's default are saved in
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
IDLE -- Factor a VarTrace class out of ConfigDialog.
2+
3+
Instance tracers manages pairs consisting of a tk variable and a
4+
callback function. When tracing is turned on, setting the variable
5+
calls the function. Test coverage for the new class is 100%.

0 commit comments

Comments
 (0)