summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/configdialog.py
diff options
context:
space:
mode:
authorterryjreedy <tjreedy@udel.edu>2017-07-07 20:00:57 (GMT)
committerGitHub <noreply@github.com>2017-07-07 20:00:57 (GMT)
commit349abd9e37dfdc077bc21f19e6ed2292c767f0e8 (patch)
treee06b11bc6d966506180914fbd928463867203265 /Lib/idlelib/configdialog.py
parent1881befb905553618f1e7ad2cef8f6ff07e1b8ef (diff)
downloadcpython-349abd9e37dfdc077bc21f19e6ed2292c767f0e8.zip
cpython-349abd9e37dfdc077bc21f19e6ed2292c767f0e8.tar.gz
cpython-349abd9e37dfdc077bc21f19e6ed2292c767f0e8.tar.bz2
bpo-30779: IDLE -- Factor ConfigChanges class from configdialog, put in config; test. (#2612)
* In config, put dump test code in a function; run it and unittest in 'if __name__ == '__main__'. * Add class config.ConfigChanges based on changes_class_v4.py on bpo issue. * Add class test_config.ChangesTest, partly based on configdialog_tests_v1.py on bpo issue. * Revise configdialog to use ConfigChanges, mostly as specified in tracker msg297804. * Revise test_configdialog to match configdialog changes. All tests pass in both files. * Remove configdialog functions unused or moved to ConfigChanges. Cheryl Sabella contributed parts of the patch.
Diffstat (limited to 'Lib/idlelib/configdialog.py')
-rw-r--r--Lib/idlelib/configdialog.py169
1 files changed, 51 insertions, 118 deletions
diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py
index 8409227..ade6710 100644
--- a/Lib/idlelib/configdialog.py
+++ b/Lib/idlelib/configdialog.py
@@ -20,7 +20,7 @@ import tkinter.colorchooser as tkColorChooser
import tkinter.font as tkFont
import tkinter.messagebox as tkMessageBox
-from idlelib.config import idleConf
+from idlelib.config import idleConf, ConfigChanges
from idlelib.config_key import GetKeysDialog
from idlelib.dynoption import DynOptionMenu
from idlelib import macosx
@@ -28,6 +28,8 @@ from idlelib.query import SectionName, HelpSource
from idlelib.tabbedpages import TabbedPageSet
from idlelib.textview import view_text
+changes = ConfigChanges()
+
class ConfigDialog(Toplevel):
"""Config dialog for IDLE.
@@ -71,7 +73,6 @@ class ConfigDialog(Toplevel):
'Shell Stdout Text': ('stdout', '12'),
'Shell Stderr Text': ('stderr', '13'),
}
- self.reset_changed_items() # Initialize changed_items dict.
self.create_widgets()
self.resizable(height=FALSE, width=FALSE)
self.transient(parent)
@@ -559,16 +560,16 @@ class ConfigDialog(Toplevel):
overriding the default font, we need to write out everything.
"""
value = self.font_name.get()
- self.add_changed_item('main', 'EditorWindow', 'font', value)
+ changes.add_option('main', 'EditorWindow', 'font', value)
value = self.font_size.get()
- self.add_changed_item('main', 'EditorWindow', 'font-size', value)
+ changes.add_option('main', 'EditorWindow', 'font-size', value)
value = self.font_bold.get()
- self.add_changed_item('main', 'EditorWindow', 'font-bold', value)
+ changes.add_option('main', 'EditorWindow', 'font-bold', value)
def var_changed_space_num(self, *params):
"Store change to indentation size."
value = self.space_num.get()
- self.add_changed_item('main', 'Indent', 'num-spaces', value)
+ changes.add_option('main', 'Indent', 'num-spaces', value)
def var_changed_colour(self, *params):
"Process change to color choice."
@@ -584,13 +585,13 @@ class ConfigDialog(Toplevel):
value = self.builtin_theme.get()
if value not in old_themes:
if idleConf.GetOption('main', 'Theme', 'name') not in old_themes:
- self.add_changed_item('main', 'Theme', 'name', old_themes[0])
- self.add_changed_item('main', 'Theme', 'name2', value)
+ changes.add_option('main', 'Theme', 'name', old_themes[0])
+ changes.add_option('main', 'Theme', 'name2', value)
self.new_custom_theme.config(text='New theme, see Help',
fg='#500000')
else:
- self.add_changed_item('main', 'Theme', 'name', value)
- self.add_changed_item('main', 'Theme', 'name2', '')
+ changes.add_option('main', 'Theme', 'name', value)
+ changes.add_option('main', 'Theme', 'name2', '')
self.new_custom_theme.config(text='', fg='black')
self.paint_theme_sample()
@@ -602,7 +603,7 @@ class ConfigDialog(Toplevel):
"""
value = self.custom_theme.get()
if value != '- no custom themes -':
- self.add_changed_item('main', 'Theme', 'name', value)
+ changes.add_option('main', 'Theme', 'name', value)
self.paint_theme_sample()
def var_changed_is_builtin_theme(self, *params):
@@ -612,7 +613,7 @@ class ConfigDialog(Toplevel):
selected theme type.
"""
value = self.is_builtin_theme.get()
- self.add_changed_item('main', 'Theme', 'default', value)
+ changes.add_option('main', 'Theme', 'default', value)
if value:
self.var_changed_builtin_theme()
else:
@@ -628,11 +629,11 @@ class ConfigDialog(Toplevel):
key_set = self.custom_keys.get()
event = self.list_bindings.get(ANCHOR).split()[0]
if idleConf.IsCoreBinding(event):
- self.add_changed_item('keys', key_set, event, value)
+ changes.add_option('keys', key_set, event, value)
else: # Event is an extension binding.
ext_name = idleConf.GetExtnNameForEvent(event)
ext_keybind_section = ext_name + '_cfgBindings'
- self.add_changed_item('extensions', ext_keybind_section, event, value)
+ changes.add_option('extensions', ext_keybind_section, event, value)
def var_changed_builtin_keys(self, *params):
"Process selection of builtin key set."
@@ -645,13 +646,13 @@ class ConfigDialog(Toplevel):
value = self.builtin_keys.get()
if value not in old_keys:
if idleConf.GetOption('main', 'Keys', 'name') not in old_keys:
- self.add_changed_item('main', 'Keys', 'name', old_keys[0])
- self.add_changed_item('main', 'Keys', 'name2', value)
+ changes.add_option('main', 'Keys', 'name', old_keys[0])
+ changes.add_option('main', 'Keys', 'name2', value)
self.new_custom_keys.config(text='New key set, see Help',
fg='#500000')
else:
- self.add_changed_item('main', 'Keys', 'name', value)
- self.add_changed_item('main', 'Keys', 'name2', '')
+ changes.add_option('main', 'Keys', 'name', value)
+ changes.add_option('main', 'Keys', 'name2', '')
self.new_custom_keys.config(text='', fg='black')
self.load_keys_list(value)
@@ -659,13 +660,13 @@ class ConfigDialog(Toplevel):
"Process selection of custom key set."
value = self.custom_keys.get()
if value != '- no custom keys -':
- self.add_changed_item('main', 'Keys', 'name', value)
+ changes.add_option('main', 'Keys', 'name', value)
self.load_keys_list(value)
def var_changed_are_keys_builtin(self, *params):
"Process toggle between builtin key set and custom key set."
value = self.are_keys_builtin.get()
- self.add_changed_item('main', 'Keys', 'default', value)
+ changes.add_option('main', 'Keys', 'default', value)
if value:
self.var_changed_builtin_keys()
else:
@@ -674,59 +675,27 @@ class ConfigDialog(Toplevel):
def var_changed_win_width(self, *params):
"Store change to window width."
value = self.win_width.get()
- self.add_changed_item('main', 'EditorWindow', 'width', value)
+ changes.add_option('main', 'EditorWindow', 'width', value)
def var_changed_win_height(self, *params):
"Store change to window height."
value = self.win_height.get()
- self.add_changed_item('main', 'EditorWindow', 'height', value)
+ changes.add_option('main', 'EditorWindow', 'height', value)
def var_changed_startup_edit(self, *params):
"Store change to toggle for starting IDLE in the editor or shell."
value = self.startup_edit.get()
- self.add_changed_item('main', 'General', 'editor-on-startup', value)
+ changes.add_option('main', 'General', 'editor-on-startup', value)
def var_changed_autosave(self, *params):
"Store change to autosave."
value = self.autosave.get()
- self.add_changed_item('main', 'General', 'autosave', value)
+ changes.add_option('main', 'General', 'autosave', value)
def var_changed_encoding(self, *params):
"Store change to encoding."
value = self.encoding.get()
- self.add_changed_item('main', 'EditorWindow', 'encoding', value)
-
- def reset_changed_items(self):
- """Reset dictionary containing the items changed on each tab.
-
- When any config item is changed in this dialog, an entry
- should be made in the relevant section (config type) of this
- dictionary. The key should be the config file section name and the
- value a dictionary, whose key:value pairs are item=value pairs for
- that config file section.
- """
- self.changed_items = {'main':{}, 'highlight':{}, 'keys':{},
- 'extensions':{}}
-
- def add_changed_item(self, typ, section, item, value):
- "Add item/value pair to changed items dictionary for typ and section."
- value = str(value) # Make sure we use a string.
- if section not in self.changed_items[typ]:
- self.changed_items[typ][section] = {}
- self.changed_items[typ][section][item] = value
-
- def GetDefaultItems(self):
- "Return dictionary of default configuration settings."
- d_items={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}}
- for config_type in d_items:
- sections = idleConf.GetSectionList('default', config_type)
- for section in sections:
- d_items[config_type][section] = {}
- options = idleConf.defaultCfg[config_type].GetOptionList(section)
- for option in options:
- d_items[config_type][section][option] = (
- idleConf.defaultCfg[config_type].Get(section, option))
- return d_items
+ changes.add_option('main', 'EditorWindow', 'encoding', value)
def set_theme_type(self):
"Set available screen options based on builtin or custom theme."
@@ -769,8 +738,8 @@ class ConfigDialog(Toplevel):
else:
current_key_set_name = self.custom_keys.get()
current_bindings = idleConf.GetCurrentKeySet()
- if current_key_set_name in self.changed_items['keys']: # unsaved changes
- key_set_changes = self.changed_items['keys'][current_key_set_name]
+ if current_key_set_name in changes['keys']: # unsaved changes
+ key_set_changes = changes['keys'][current_key_set_name]
for event in key_set_changes:
current_bindings[event] = key_set_changes[event].split()
current_key_sequences = list(current_bindings.values())
@@ -832,8 +801,8 @@ class ConfigDialog(Toplevel):
binding = ' '.join(prev_keys[event])
new_keys[event_name] = binding
# Handle any unsaved changes to prev key set.
- if prev_key_set_name in self.changed_items['keys']:
- key_set_changes = self.changed_items['keys'][prev_key_set_name]
+ if prev_key_set_name in changes['keys']:
+ key_set_changes = changes['keys'][prev_key_set_name]
for event in key_set_changes:
new_keys[event] = key_set_changes[event]
# Save the new key set.
@@ -863,10 +832,10 @@ class ConfigDialog(Toplevel):
for bind_name in bind_names:
key = ' '.join(keyset[bind_name])
bind_name = bind_name[2:-2] # Trim off the angle brackets.
- if keyset_name in self.changed_items['keys']:
+ if keyset_name in changes['keys']:
# Handle any unsaved changes to this key set.
- if bind_name in self.changed_items['keys'][keyset_name]:
- key = self.changed_items['keys'][keyset_name][bind_name]
+ if bind_name in changes['keys'][keyset_name]:
+ key = changes['keys'][keyset_name][bind_name]
self.list_bindings.insert(END, bind_name+' - '+key)
if reselect:
self.list_bindings.see(list_index)
@@ -886,12 +855,8 @@ class ConfigDialog(Toplevel):
'Delete Key Set', delmsg % keyset_name, parent=self):
return
self.deactivate_current_config()
- # Remove key set from config.
- idleConf.userCfg['keys'].remove_section(keyset_name)
- if keyset_name in self.changed_items['keys']:
- del(self.changed_items['keys'][keyset_name])
- # Write changes.
- idleConf.userCfg['keys'].Save()
+ # Remove key set from changes, config, and file.
+ changes.remove(keyset_name)
# Reload user key set list.
item_list = idleConf.GetSectionList('user', 'keys')
item_list.sort()
@@ -906,7 +871,8 @@ class ConfigDialog(Toplevel):
self.builtin_keys.set(idleConf.defaultCfg['main'].Get('Keys', 'name')
or idleConf.default_keys())
# User can't back out of these changes, they must be applied now.
- self.save_all_changed_configs()
+ changes.save_all()
+ self.save_all_changed_extensions()
self.activate_config_changes()
self.set_keys_type()
@@ -923,12 +889,8 @@ class ConfigDialog(Toplevel):
'Delete Theme', delmsg % theme_name, parent=self):
return
self.deactivate_current_config()
- # Remove theme from config.
- idleConf.userCfg['highlight'].remove_section(theme_name)
- if theme_name in self.changed_items['highlight']:
- del(self.changed_items['highlight'][theme_name])
- # Write changes.
- idleConf.userCfg['highlight'].Save()
+ # Remove theme from changes, config, and file.
+ changes.delete_section('highlight')
# Reload user theme list.
item_list = idleConf.GetSectionList('user', 'highlight')
item_list.sort()
@@ -941,7 +903,8 @@ class ConfigDialog(Toplevel):
self.is_builtin_theme.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
self.builtin_theme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
# User can't back out of these changes, they must be applied now.
- self.save_all_changed_configs()
+ changes.save_all()
+ self.save_all_changed_extensions()
self.activate_config_changes()
self.set_theme_type()
@@ -979,7 +942,7 @@ class ConfigDialog(Toplevel):
self.text_highlight_sample.tag_config(sample_element, **{plane:new_colour})
theme = self.custom_theme.get()
theme_element = sample_element + '-' + plane
- self.add_changed_item('highlight', theme, theme_element, new_colour)
+ changes.add_option('highlight', theme, theme_element, new_colour)
def get_new_theme_name(self, message):
"Return name of new theme from query popup."
@@ -1010,8 +973,8 @@ class ConfigDialog(Toplevel):
theme_name = self.custom_theme.get()
new_theme = idleConf.GetThemeDict(theme_type, theme_name)
# Apply any of the old theme's unsaved changes to the new theme.
- if theme_name in self.changed_items['highlight']:
- theme_changes = self.changed_items['highlight'][theme_name]
+ if theme_name in changes['highlight']:
+ theme_changes = changes['highlight'][theme_name]
for element in theme_changes:
new_theme[element] = theme_changes[element]
# Save the new theme.
@@ -1078,8 +1041,8 @@ class ConfigDialog(Toplevel):
colours['background'] = idleConf.GetHighlight(
theme, 'normal', fgBg='bg')
# Handle any unsaved changes to this theme.
- if theme in self.changed_items['highlight']:
- theme_dict = self.changed_items['highlight'][theme]
+ if theme in changes['highlight']:
+ theme_dict = changes['highlight'][theme]
if element + '-foreground' in theme_dict:
colours['foreground'] = theme_dict[element + '-foreground']
if element + '-background' in theme_dict:
@@ -1150,10 +1113,10 @@ class ConfigDialog(Toplevel):
self.set_helplist_button_states()
def update_user_help_changed_items(self):
- "Clear and rebuild the HelpFiles section in self.changed_items"
- self.changed_items['main']['HelpFiles'] = {}
+ "Clear and rebuild the HelpFiles section in changes"
+ changes['main']['HelpFiles'] = {}
for num in range(1, len(self.user_helplist) + 1):
- self.add_changed_item(
+ changes.add_option(
'main', 'HelpFiles', str(num),
';'.join(self.user_helplist[num-1][:2]))
@@ -1317,37 +1280,6 @@ class ConfigDialog(Toplevel):
value = theme[element]
idleConf.userCfg['highlight'].SetOption(theme_name, element, value)
- def set_user_value(self, config_type, section, item, value):
- "Return True if the configuration value was added or changed."
- if idleConf.defaultCfg[config_type].has_option(section, item):
- if idleConf.defaultCfg[config_type].Get(section, item) == value:
- # The setting equals a default setting, remove it from user cfg.
- return idleConf.userCfg[config_type].RemoveOption(section, item)
- # If we got here, set the option.
- return idleConf.userCfg[config_type].SetOption(section, item, value)
-
- def save_all_changed_configs(self):
- "Save all configuration changes to the user config file."
- idleConf.userCfg['main'].Save()
- for config_type in self.changed_items:
- cfg_type_changed = False
- for section in self.changed_items[config_type]:
- if section == 'HelpFiles':
- # This section gets completely replaced.
- idleConf.userCfg['main'].remove_section('HelpFiles')
- cfg_type_changed = True
- for item in self.changed_items[config_type][section]:
- value = self.changed_items[config_type][section][item]
- if self.set_user_value(config_type, section, item, value):
- cfg_type_changed = True
- if cfg_type_changed:
- idleConf.userCfg[config_type].Save()
- for config_type in ['keys', 'highlight']:
- # Save these even if unchanged!
- idleConf.userCfg[config_type].Save()
- self.reset_changed_items() # Clear the changed items dict.
- self.save_all_changed_extensions() # Uses a different mechanism.
-
def deactivate_current_config(self):
"Remove current key bindings."
# Before a config is saved, some cleanup of current
@@ -1378,7 +1310,8 @@ class ConfigDialog(Toplevel):
def apply(self):
"Apply config changes and leave dialog open."
self.deactivate_current_config()
- self.save_all_changed_configs()
+ changes.save_all()
+ self.save_all_changed_extensions()
self.activate_config_changes()
def help(self):