bpo-31001: IDLE: Add tests for configdialog highlight tab (#3123)

This commit is contained in:
Cheryl Sabella 2017-08-17 20:39:00 -04:00 committed by Terry Jan Reedy
parent f6ebd838f0
commit 82aff62462
3 changed files with 671 additions and 157 deletions

View File

@ -222,13 +222,79 @@ class ConfigDialog(Toplevel):
def create_page_highlight(self): def create_page_highlight(self):
"""Return frame of widgets for Highlighting tab. """Return frame of widgets for Highlighting tab.
Enable users to provisionally change foreground and background
colors applied to textual tags. Color mappings are stored in
complete listings called themes. Built-in themes in
idlelib/config-highlight.def are fixed as far as the dialog is
concerned. Any theme can be used as the base for a new custom
theme, stored in .idlerc/config-highlight.cfg.
Function load_theme_cfg() initializes tk variables and theme
lists and calls paint_theme_sample() and set_highlight_target()
for the current theme. Radiobuttons builtin_theme_on and
custom_theme_on toggle var theme_source, which controls if the
current set of colors are from a builtin or custom theme.
DynOptionMenus builtinlist and customlist contain lists of the
builtin and custom themes, respectively, and the current item
from each list is stored in vars builtin_name and custom_name.
Function paint_theme_sample() applies the colors from the theme
to the tags in text widget highlight_sample and then invokes
set_color_sample(). Function set_highlight_target() sets the state
of the radiobuttons fg_on and bg_on based on the tag and it also
invokes set_color_sample().
Function set_color_sample() sets the background color for the frame
holding the color selector. This provides a larger visual of the
color for the current tag and plane (foreground/background).
Note: set_color_sample() is called from many places and is often
called more than once when a change is made. It is invoked when
foreground or background is selected (radiobuttons), from
paint_theme_sample() (theme is changed or load_cfg is called), and
from set_highlight_target() (target tag is changed or load_cfg called).
Button delete_custom invokes delete_custom() to delete
a custom theme from idleConf.userCfg['highlight'] and changes.
Button save_custom invokes save_as_new_theme() which calls
get_new_theme_name() and create_new() to save a custom theme
and its colors to idleConf.userCfg['highlight'].
Radiobuttons fg_on and bg_on toggle var fg_bg_toggle to control
if the current selected color for a tag is for the foreground or
background.
DynOptionMenu targetlist contains a readable description of the
tags applied to Python source within IDLE. Selecting one of the
tags from this list populates highlight_target, which has a callback
function set_highlight_target().
Text widget highlight_sample displays a block of text (which is
mock Python code) in which is embedded the defined tags and reflects
the color attributes of the current theme and changes for those tags.
Mouse button 1 allows for selection of a tag and updates
highlight_target with that tag value.
Note: The font in highlight_sample is set through the config in
the fonts tab.
In other words, a tag can be selected either from targetlist or
by clicking on the sample text within highlight_sample. The
plane (foreground/background) is selected via the radiobutton.
Together, these two (tag and plane) control what color is
shown in set_color_sample() for the current theme. Button set_color
invokes get_color() which displays a ColorChooser to change the
color for the selected tag/plane. If a new color is picked,
it will be saved to changes and the highlight_sample and
frame background will be updated.
Tk Variables: Tk Variables:
color: Color of selected target. color: Color of selected target.
builtin_theme: Menu variable for built-in theme. builtin_name: Menu variable for built-in theme.
custom_theme: Menu variable for custom theme. custom_name: Menu variable for custom theme.
fg_bg_toggle: Toggle for foreground/background color. fg_bg_toggle: Toggle for foreground/background color.
Note: this has no callback. Note: this has no callback.
is_builtin_theme: Selector for built-in or custom theme. theme_source: Selector for built-in or custom theme.
highlight_target: Menu variable for the highlight tag target. highlight_target: Menu variable for the highlight tag target.
Instance Data Attributes: Instance Data Attributes:
@ -245,30 +311,30 @@ class ConfigDialog(Toplevel):
on_new_color_set: Set new color and add option. on_new_color_set: Set new color and add option.
paint_theme_sample: Recolor sample. paint_theme_sample: Recolor sample.
get_new_theme_name: Get from popup. get_new_theme_name: Get from popup.
create_new_theme: Combine theme with changes and save. create_new: Combine theme with changes and save.
save_as_new_theme: Save [button_save_custom_theme]. save_as_new_theme: Save [button_save_custom].
set_theme_type: Command for [is_builtin_theme]. set_theme_type: Command for [theme_source].
delete_custom_theme: Ativate default [button_delete_custom_theme]. delete_custom: Activate default [button_delete_custom].
save_new_theme: Save to userCfg['theme'] (is function). save_new: Save to userCfg['theme'] (is function).
Widgets of highlights page frame: (*) widgets bound to self Widgets of highlights page frame: (*) widgets bound to self
frame_custom: LabelFrame frame_custom: LabelFrame
(*)highlight_sample: Text (*)highlight_sample: Text
(*)frame_color_set: Frame (*)frame_color_set: Frame
button_set_color: Button (*)button_set_color: Button
(*)opt_menu_highlight_target: DynOptionMenu - highlight_target (*)targetlist: DynOptionMenu - highlight_target
frame_fg_bg_toggle: Frame frame_fg_bg_toggle: Frame
(*)radio_fg: Radiobutton - fg_bg_toggle (*)fg_on: Radiobutton - fg_bg_toggle
(*)radio_bg: Radiobutton - fg_bg_toggle (*)bg_on: Radiobutton - fg_bg_toggle
button_save_custom_theme: Button (*)button_save_custom: Button
frame_theme: LabelFrame frame_theme: LabelFrame
theme_type_title: Label theme_type_title: Label
(*)radio_theme_builtin: Radiobutton - is_builtin_theme (*)builtin_theme_on: Radiobutton - theme_source
(*)radio_theme_custom: Radiobutton - is_builtin_theme (*)custom_theme_on: Radiobutton - theme_source
(*)opt_menu_theme_builtin: DynOptionMenu - builtin_theme (*)builtinlist: DynOptionMenu - builtin_name
(*)opt_menu_theme_custom: DynOptionMenu - custom_theme (*)customlist: DynOptionMenu - custom_name
(*)button_delete_custom_theme: Button (*)button_delete_custom: Button
(*)new_custom_theme: Label (*)theme_message: Label
""" """
self.theme_elements={ self.theme_elements={
'Normal Text': ('normal', '00'), 'Normal Text': ('normal', '00'),
@ -287,31 +353,30 @@ class ConfigDialog(Toplevel):
'Shell Stderr Text': ('stderr', '13'), 'Shell Stderr Text': ('stderr', '13'),
} }
parent = self.parent parent = self.parent
self.builtin_theme = tracers.add( self.builtin_name = tracers.add(
StringVar(parent), self.var_changed_builtin_theme) StringVar(parent), self.var_changed_builtin_name)
self.custom_theme = tracers.add( self.custom_name = tracers.add(
StringVar(parent), self.var_changed_custom_theme) StringVar(parent), self.var_changed_custom_name)
self.fg_bg_toggle = BooleanVar(parent) self.fg_bg_toggle = BooleanVar(parent)
self.color = tracers.add( self.color = tracers.add(
StringVar(parent), self.var_changed_color) StringVar(parent), self.var_changed_color)
self.is_builtin_theme = tracers.add( self.theme_source = tracers.add(
BooleanVar(parent), self.var_changed_is_builtin_theme) BooleanVar(parent), self.var_changed_theme_source)
self.highlight_target = tracers.add( self.highlight_target = tracers.add(
StringVar(parent), self.var_changed_highlight_target) StringVar(parent), self.var_changed_highlight_target)
# Widget creation: # Create widgets:
# body frame and section frames # body frame and section frames.
frame = Frame(self.note) frame = Frame(self.note)
frame_custom = LabelFrame(frame, borderwidth=2, relief=GROOVE, frame_custom = LabelFrame(frame, borderwidth=2, relief=GROOVE,
text=' Custom Highlighting ') text=' Custom Highlighting ')
frame_theme = LabelFrame(frame, borderwidth=2, relief=GROOVE, frame_theme = LabelFrame(frame, borderwidth=2, relief=GROOVE,
text=' Highlighting Theme ') text=' Highlighting Theme ')
#frame_custom # frame_custom.
text = self.highlight_sample = frame.highlight_sample = Text( text = self.highlight_sample = frame.highlight_sample = Text(
frame_custom, relief=SOLID, borderwidth=1, frame_custom, relief=SOLID, borderwidth=1,
font=('courier', 12, ''), cursor='hand2', width=21, height=13, font=('courier', 12, ''), cursor='hand2', width=21, height=13,
takefocus=FALSE, highlightthickness=0, wrap=NONE) takefocus=FALSE, highlightthickness=0, wrap=NONE)
text=self.highlight_sample
text.bind('<Double-Button-1>', lambda e: 'break') text.bind('<Double-Button-1>', lambda e: 'break')
text.bind('<B1-Motion>', lambda e: 'break') text.bind('<B1-Motion>', lambda e: 'break')
text_and_tags=(('\n', 'normal'), text_and_tags=(('\n', 'normal'),
@ -341,78 +406,77 @@ class ConfigDialog(Toplevel):
text['state'] = DISABLED text['state'] = DISABLED
self.frame_color_set = Frame(frame_custom, relief=SOLID, borderwidth=1) self.frame_color_set = Frame(frame_custom, relief=SOLID, borderwidth=1)
frame_fg_bg_toggle = Frame(frame_custom) frame_fg_bg_toggle = Frame(frame_custom)
button_set_color = Button( self.button_set_color = Button(
self.frame_color_set, text='Choose Color for :', self.frame_color_set, text='Choose Color for :',
command=self.get_color, highlightthickness=0) command=self.get_color, highlightthickness=0)
self.opt_menu_highlight_target = DynOptionMenu( self.targetlist = DynOptionMenu(
self.frame_color_set, self.highlight_target, None, self.frame_color_set, self.highlight_target, None,
highlightthickness=0) #, command=self.set_highlight_targetBinding highlightthickness=0) #, command=self.set_highlight_targetBinding
self.radio_fg = Radiobutton( self.fg_on = Radiobutton(
frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=1, frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=1,
text='Foreground', command=self.set_color_sample_binding) text='Foreground', command=self.set_color_sample_binding)
self.radio_bg=Radiobutton( self.bg_on = Radiobutton(
frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=0, frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=0,
text='Background', command=self.set_color_sample_binding) text='Background', command=self.set_color_sample_binding)
self.fg_bg_toggle.set(1) self.fg_bg_toggle.set(1)
button_save_custom_theme = Button( self.button_save_custom = Button(
frame_custom, text='Save as New Custom Theme', frame_custom, text='Save as New Custom Theme',
command=self.save_as_new_theme) command=self.save_as_new_theme)
#frame_theme # frame_theme.
theme_type_title = Label(frame_theme, text='Select : ') theme_type_title = Label(frame_theme, text='Select : ')
self.radio_theme_builtin = Radiobutton( self.builtin_theme_on = Radiobutton(
frame_theme, variable=self.is_builtin_theme, value=1, frame_theme, variable=self.theme_source, value=1,
command=self.set_theme_type, text='a Built-in Theme') command=self.set_theme_type, text='a Built-in Theme')
self.radio_theme_custom = Radiobutton( self.custom_theme_on = Radiobutton(
frame_theme, variable=self.is_builtin_theme, value=0, frame_theme, variable=self.theme_source, value=0,
command=self.set_theme_type, text='a Custom Theme') command=self.set_theme_type, text='a Custom Theme')
self.opt_menu_theme_builtin = DynOptionMenu( self.builtinlist = DynOptionMenu(
frame_theme, self.builtin_theme, None, command=None) frame_theme, self.builtin_name, None, command=None)
self.opt_menu_theme_custom=DynOptionMenu( self.customlist = DynOptionMenu(
frame_theme, self.custom_theme, None, command=None) frame_theme, self.custom_name, None, command=None)
self.button_delete_custom_theme=Button( self.button_delete_custom = Button(
frame_theme, text='Delete Custom Theme', frame_theme, text='Delete Custom Theme',
command=self.delete_custom_theme) command=self.delete_custom)
self.new_custom_theme = Label(frame_theme, bd=2) self.theme_message = Label(frame_theme, bd=2)
##widget packing # Pack widgets:
#body # body.
frame_custom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) frame_custom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
frame_theme.pack(side=LEFT, padx=5, pady=5, fill=Y) frame_theme.pack(side=LEFT, padx=5, pady=5, fill=Y)
#frame_custom # frame_custom.
self.frame_color_set.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X) self.frame_color_set.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X)
frame_fg_bg_toggle.pack(side=TOP, padx=5, pady=0) frame_fg_bg_toggle.pack(side=TOP, padx=5, pady=0)
self.highlight_sample.pack( self.highlight_sample.pack(
side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
button_set_color.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4) self.button_set_color.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4)
self.opt_menu_highlight_target.pack( self.targetlist.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=3)
side=TOP, expand=TRUE, fill=X, padx=8, pady=3) self.fg_on.pack(side=LEFT, anchor=E)
self.radio_fg.pack(side=LEFT, anchor=E) self.bg_on.pack(side=RIGHT, anchor=W)
self.radio_bg.pack(side=RIGHT, anchor=W) self.button_save_custom.pack(side=BOTTOM, fill=X, padx=5, pady=5)
button_save_custom_theme.pack(side=BOTTOM, fill=X, padx=5, pady=5) # frame_theme.
#frame_theme
theme_type_title.pack(side=TOP, anchor=W, padx=5, pady=5) theme_type_title.pack(side=TOP, anchor=W, padx=5, pady=5)
self.radio_theme_builtin.pack(side=TOP, anchor=W, padx=5) self.builtin_theme_on.pack(side=TOP, anchor=W, padx=5)
self.radio_theme_custom.pack(side=TOP, anchor=W, padx=5, pady=2) self.custom_theme_on.pack(side=TOP, anchor=W, padx=5, pady=2)
self.opt_menu_theme_builtin.pack(side=TOP, fill=X, padx=5, pady=5) self.builtinlist.pack(side=TOP, fill=X, padx=5, pady=5)
self.opt_menu_theme_custom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) self.customlist.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5)
self.button_delete_custom_theme.pack(side=TOP, fill=X, padx=5, pady=5) self.button_delete_custom.pack(side=TOP, fill=X, padx=5, pady=5)
self.new_custom_theme.pack(side=TOP, fill=X, pady=5) self.theme_message.pack(side=TOP, fill=X, pady=5)
return frame return frame
def load_theme_cfg(self): def load_theme_cfg(self):
"""Load current configuration settings for the theme options. """Load current configuration settings for the theme options.
Based on the is_builtin_theme toggle, the theme is set as Based on the theme_source toggle, the theme is set as
either builtin or custom and the initial widget values either builtin or custom and the initial widget values
reflect the current settings from idleConf. reflect the current settings from idleConf.
Attributes updated: Attributes updated:
is_builtin_theme: Set from idleConf. theme_source: Set from idleConf.
opt_menu_theme_builtin: List of default themes from idleConf. builtinlist: List of default themes from idleConf.
opt_menu_theme_custom: List of custom themes from idleConf. customlist: List of custom themes from idleConf.
radio_theme_custom: Disabled if there are no custom themes. custom_theme_on: Disabled if there are no custom themes.
custom_theme: Message with additional information. custom_theme: Message with additional information.
opt_menu_highlight_target: Create menu from self.theme_elements. targetlist: Create menu from self.theme_elements.
Methods: Methods:
set_theme_type set_theme_type
@ -420,80 +484,81 @@ class ConfigDialog(Toplevel):
set_highlight_target set_highlight_target
""" """
# Set current theme type radiobutton. # Set current theme type radiobutton.
self.is_builtin_theme.set(idleConf.GetOption( self.theme_source.set(idleConf.GetOption(
'main', 'Theme', 'default', type='bool', default=1)) 'main', 'Theme', 'default', type='bool', default=1))
# Set current theme. # Set current theme.
current_option = idleConf.CurrentTheme() current_option = idleConf.CurrentTheme()
# Load available theme option menus. # Load available theme option menus.
if self.is_builtin_theme.get(): # Default theme selected. if self.theme_source.get(): # Default theme selected.
item_list = idleConf.GetSectionList('default', 'highlight') item_list = idleConf.GetSectionList('default', 'highlight')
item_list.sort() item_list.sort()
self.opt_menu_theme_builtin.SetMenu(item_list, current_option) self.builtinlist.SetMenu(item_list, current_option)
item_list = idleConf.GetSectionList('user', 'highlight') item_list = idleConf.GetSectionList('user', 'highlight')
item_list.sort() item_list.sort()
if not item_list: if not item_list:
self.radio_theme_custom['state'] = DISABLED self.custom_theme_on['state'] = DISABLED
self.custom_theme.set('- no custom themes -') self.custom_name.set('- no custom themes -')
else: else:
self.opt_menu_theme_custom.SetMenu(item_list, item_list[0]) self.customlist.SetMenu(item_list, item_list[0])
else: # User theme selected. else: # User theme selected.
item_list = idleConf.GetSectionList('user', 'highlight') item_list = idleConf.GetSectionList('user', 'highlight')
item_list.sort() item_list.sort()
self.opt_menu_theme_custom.SetMenu(item_list, current_option) self.customlist.SetMenu(item_list, current_option)
item_list = idleConf.GetSectionList('default', 'highlight') item_list = idleConf.GetSectionList('default', 'highlight')
item_list.sort() item_list.sort()
self.opt_menu_theme_builtin.SetMenu(item_list, item_list[0]) self.builtinlist.SetMenu(item_list, item_list[0])
self.set_theme_type() self.set_theme_type()
# Load theme element option menu. # Load theme element option menu.
theme_names = list(self.theme_elements.keys()) theme_names = list(self.theme_elements.keys())
theme_names.sort(key=lambda x: self.theme_elements[x][1]) theme_names.sort(key=lambda x: self.theme_elements[x][1])
self.opt_menu_highlight_target.SetMenu(theme_names, theme_names[0]) self.targetlist.SetMenu(theme_names, theme_names[0])
self.paint_theme_sample() self.paint_theme_sample()
self.set_highlight_target() self.set_highlight_target()
def var_changed_builtin_theme(self, *params): def var_changed_builtin_name(self, *params):
"""Process new builtin theme selection. """Process new builtin theme selection.
Add the changed theme's name to the changed_items and recreate Add the changed theme's name to the changed_items and recreate
the sample with the values from the selected theme. the sample with the values from the selected theme.
""" """
old_themes = ('IDLE Classic', 'IDLE New') old_themes = ('IDLE Classic', 'IDLE New')
value = self.builtin_theme.get() value = self.builtin_name.get()
if value not in old_themes: if value not in old_themes:
if idleConf.GetOption('main', 'Theme', 'name') not in old_themes: if idleConf.GetOption('main', 'Theme', 'name') not in old_themes:
changes.add_option('main', 'Theme', 'name', old_themes[0]) changes.add_option('main', 'Theme', 'name', old_themes[0])
changes.add_option('main', 'Theme', 'name2', value) changes.add_option('main', 'Theme', 'name2', value)
self.new_custom_theme.config(text='New theme, see Help', self.theme_message['text'] = 'New theme, see Help'
fg='#500000') self.theme_message['fg'] = '#500000'
else: else:
changes.add_option('main', 'Theme', 'name', value) changes.add_option('main', 'Theme', 'name', value)
changes.add_option('main', 'Theme', 'name2', '') changes.add_option('main', 'Theme', 'name2', '')
self.new_custom_theme.config(text='', fg='black') self.theme_message['text'] = ''
self.theme_message['fg'] = 'black'
self.paint_theme_sample() self.paint_theme_sample()
def var_changed_custom_theme(self, *params): def var_changed_custom_name(self, *params):
"""Process new custom theme selection. """Process new custom theme selection.
If a new custom theme is selected, add the name to the If a new custom theme is selected, add the name to the
changed_items and apply the theme to the sample. changed_items and apply the theme to the sample.
""" """
value = self.custom_theme.get() value = self.custom_name.get()
if value != '- no custom themes -': if value != '- no custom themes -':
changes.add_option('main', 'Theme', 'name', value) changes.add_option('main', 'Theme', 'name', value)
self.paint_theme_sample() self.paint_theme_sample()
def var_changed_is_builtin_theme(self, *params): def var_changed_theme_source(self, *params):
"""Process toggle between builtin and custom theme. """Process toggle between builtin and custom theme.
Update the default toggle value and apply the newly Update the default toggle value and apply the newly
selected theme type. selected theme type.
""" """
value = self.is_builtin_theme.get() value = self.theme_source.get()
changes.add_option('main', 'Theme', 'default', value) changes.add_option('main', 'Theme', 'default', value)
if value: if value:
self.var_changed_builtin_theme() self.var_changed_builtin_name()
else: else:
self.var_changed_custom_theme() self.var_changed_custom_name()
def var_changed_color(self, *params): def var_changed_color(self, *params):
"Process change to color choice." "Process change to color choice."
@ -507,29 +572,29 @@ class ConfigDialog(Toplevel):
"""Set available screen options based on builtin or custom theme. """Set available screen options based on builtin or custom theme.
Attributes accessed: Attributes accessed:
is_builtin_theme theme_source
Attributes updated: Attributes updated:
opt_menu_theme_builtin builtinlist
opt_menu_theme_custom customlist
button_delete_custom_theme button_delete_custom
radio_theme_custom custom_theme_on
Called from: Called from:
handler for radio_theme_builtin and radio_theme_custom handler for builtin_theme_on and custom_theme_on
delete_custom_theme delete_custom
create_new_theme create_new
load_theme_cfg load_theme_cfg
""" """
if self.is_builtin_theme.get(): if self.theme_source.get():
self.opt_menu_theme_builtin['state'] = NORMAL self.builtinlist['state'] = NORMAL
self.opt_menu_theme_custom['state'] = DISABLED self.customlist['state'] = DISABLED
self.button_delete_custom_theme['state'] = DISABLED self.button_delete_custom['state'] = DISABLED
else: else:
self.opt_menu_theme_builtin['state'] = DISABLED self.builtinlist['state'] = DISABLED
self.radio_theme_custom['state'] = NORMAL self.custom_theme_on['state'] = NORMAL
self.opt_menu_theme_custom['state'] = NORMAL self.customlist['state'] = NORMAL
self.button_delete_custom_theme['state'] = NORMAL self.button_delete_custom['state'] = NORMAL
def get_color(self): def get_color(self):
"""Handle button to select a new color for the target tag. """Handle button to select a new color for the target tag.
@ -540,14 +605,14 @@ class ConfigDialog(Toplevel):
Attributes accessed: Attributes accessed:
highlight_target highlight_target
frame_color_set frame_color_set
is_builtin_theme theme_source
Attributes updated: Attributes updated:
color color
Methods: Methods:
get_new_theme_name get_new_theme_name
create_new_theme create_new
""" """
target = self.highlight_target.get() target = self.highlight_target.get()
prev_color = self.frame_color_set.cget('bg') prev_color = self.frame_color_set.cget('bg')
@ -556,26 +621,26 @@ class ConfigDialog(Toplevel):
initialcolor=prev_color) initialcolor=prev_color)
if color_string and (color_string != prev_color): if color_string and (color_string != prev_color):
# User didn't cancel and they chose a new color. # User didn't cancel and they chose a new color.
if self.is_builtin_theme.get(): # Current theme is a built-in. if self.theme_source.get(): # Current theme is a built-in.
message = ('Your changes will be saved as a new Custom Theme. ' message = ('Your changes will be saved as a new Custom Theme. '
'Enter a name for your new Custom Theme below.') 'Enter a name for your new Custom Theme below.')
new_theme = self.get_new_theme_name(message) new_theme = self.get_new_theme_name(message)
if not new_theme: # User cancelled custom theme creation. if not new_theme: # User cancelled custom theme creation.
return return
else: # Create new custom theme based on previously active theme. else: # Create new custom theme based on previously active theme.
self.create_new_theme(new_theme) self.create_new(new_theme)
self.color.set(color_string) self.color.set(color_string)
else: # Current theme is user defined. else: # Current theme is user defined.
self.color.set(color_string) self.color.set(color_string)
def on_new_color_set(self): def on_new_color_set(self):
"Display sample of new color selection on the dialog." "Display sample of new color selection on the dialog."
new_color=self.color.get() new_color = self.color.get()
self.frame_color_set.config(bg=new_color) # Set sample. self.frame_color_set['bg'] = new_color # Set sample.
plane ='foreground' if self.fg_bg_toggle.get() else 'background' plane = 'foreground' if self.fg_bg_toggle.get() else 'background'
sample_element = self.theme_elements[self.highlight_target.get()][0] sample_element = self.theme_elements[self.highlight_target.get()][0]
self.highlight_sample.tag_config(sample_element, **{plane:new_color}) self.highlight_sample.tag_config(sample_element, **{plane: new_color})
theme = self.custom_theme.get() theme = self.custom_name.get()
theme_element = sample_element + '-' + plane theme_element = sample_element + '-' + plane
changes.add_option('highlight', theme, theme_element, new_color) changes.add_option('highlight', theme, theme_element, new_color)
@ -592,13 +657,13 @@ class ConfigDialog(Toplevel):
Methods: Methods:
get_new_theme_name get_new_theme_name
create_new_theme create_new
""" """
new_theme_name = self.get_new_theme_name('New Theme Name:') new_theme_name = self.get_new_theme_name('New Theme Name:')
if new_theme_name: if new_theme_name:
self.create_new_theme(new_theme_name) self.create_new(new_theme_name)
def create_new_theme(self, new_theme_name): def create_new(self, new_theme_name):
"""Create a new custom theme with the given name. """Create a new custom theme with the given name.
Create the new theme based on the previously active theme Create the new theme based on the previously active theme
@ -606,23 +671,23 @@ class ConfigDialog(Toplevel):
activate the new theme. activate the new theme.
Attributes accessed: Attributes accessed:
builtin_theme builtin_name
custom_theme custom_name
Attributes updated: Attributes updated:
opt_menu_theme_custom customlist
is_builtin_theme theme_source
Method: Method:
save_new_theme save_new
set_theme_type set_theme_type
""" """
if self.is_builtin_theme.get(): if self.theme_source.get():
theme_type = 'default' theme_type = 'default'
theme_name = self.builtin_theme.get() theme_name = self.builtin_name.get()
else: else:
theme_type = 'user' theme_type = 'user'
theme_name = self.custom_theme.get() theme_name = self.custom_name.get()
new_theme = idleConf.GetThemeDict(theme_type, theme_name) new_theme = idleConf.GetThemeDict(theme_type, theme_name)
# Apply any of the old theme's unsaved changes to the new theme. # Apply any of the old theme's unsaved changes to the new theme.
if theme_name in changes['highlight']: if theme_name in changes['highlight']:
@ -630,12 +695,12 @@ class ConfigDialog(Toplevel):
for element in theme_changes: for element in theme_changes:
new_theme[element] = theme_changes[element] new_theme[element] = theme_changes[element]
# Save the new theme. # Save the new theme.
self.save_new_theme(new_theme_name, new_theme) self.save_new(new_theme_name, new_theme)
# Change GUI over to the new theme. # Change GUI over to the new theme.
custom_theme_list = idleConf.GetSectionList('user', 'highlight') custom_theme_list = idleConf.GetSectionList('user', 'highlight')
custom_theme_list.sort() custom_theme_list.sort()
self.opt_menu_theme_custom.SetMenu(custom_theme_list, new_theme_name) self.customlist.SetMenu(custom_theme_list, new_theme_name)
self.is_builtin_theme.set(0) self.theme_source.set(0)
self.set_theme_type() self.set_theme_type()
def set_highlight_target(self): def set_highlight_target(self):
@ -645,8 +710,8 @@ class ConfigDialog(Toplevel):
highlight_target highlight_target
Attributes updated: Attributes updated:
radio_fg fg_on
radio_bg bg_on
fg_bg_toggle fg_bg_toggle
Methods: Methods:
@ -657,12 +722,12 @@ class ConfigDialog(Toplevel):
load_theme_cfg load_theme_cfg
""" """
if self.highlight_target.get() == 'Cursor': # bg not possible if self.highlight_target.get() == 'Cursor': # bg not possible
self.radio_fg['state'] = DISABLED self.fg_on['state'] = DISABLED
self.radio_bg['state'] = DISABLED self.bg_on['state'] = DISABLED
self.fg_bg_toggle.set(1) self.fg_bg_toggle.set(1)
else: # Both fg and bg can be set. else: # Both fg and bg can be set.
self.radio_fg['state'] = NORMAL self.fg_on['state'] = NORMAL
self.radio_bg['state'] = NORMAL self.bg_on['state'] = NORMAL
self.fg_bg_toggle.set(1) self.fg_bg_toggle.set(1)
self.set_color_sample() self.set_color_sample()
@ -690,16 +755,16 @@ class ConfigDialog(Toplevel):
tag = self.theme_elements[self.highlight_target.get()][0] tag = self.theme_elements[self.highlight_target.get()][0]
plane = 'foreground' if self.fg_bg_toggle.get() else 'background' plane = 'foreground' if self.fg_bg_toggle.get() else 'background'
color = self.highlight_sample.tag_cget(tag, plane) color = self.highlight_sample.tag_cget(tag, plane)
self.frame_color_set.config(bg=color) self.frame_color_set['bg'] = color
def paint_theme_sample(self): def paint_theme_sample(self):
"""Apply the theme colors to each element tag in the sample text. """Apply the theme colors to each element tag in the sample text.
Instance attributes accessed: Instance attributes accessed:
theme_elements theme_elements
is_builtin_theme theme_source
builtin_theme builtin_name
custom_theme custom_name
Attributes updated: Attributes updated:
highlight_sample: Set the tag elements to the theme. highlight_sample: Set the tag elements to the theme.
@ -708,14 +773,14 @@ class ConfigDialog(Toplevel):
set_color_sample set_color_sample
Called from: Called from:
var_changed_builtin_theme var_changed_builtin_name
var_changed_custom_theme var_changed_custom_name
load_theme_cfg load_theme_cfg
""" """
if self.is_builtin_theme.get(): # Default theme if self.theme_source.get(): # Default theme
theme = self.builtin_theme.get() theme = self.builtin_name.get()
else: # User theme else: # User theme
theme = self.custom_theme.get() theme = self.custom_name.get()
for element_title in self.theme_elements: for element_title in self.theme_elements:
element = self.theme_elements[element_title][0] element = self.theme_elements[element_title][0]
colors = idleConf.GetHighlight(theme, element) colors = idleConf.GetHighlight(theme, element)
@ -732,7 +797,7 @@ class ConfigDialog(Toplevel):
self.highlight_sample.tag_config(element, **colors) self.highlight_sample.tag_config(element, **colors)
self.set_color_sample() self.set_color_sample()
def save_new_theme(self, theme_name, theme): def save_new(self, theme_name, theme):
"""Save a newly created theme to idleConf. """Save a newly created theme to idleConf.
theme_name - string, the name of the new theme theme_name - string, the name of the new theme
@ -744,7 +809,7 @@ class ConfigDialog(Toplevel):
value = theme[element] value = theme[element]
idleConf.userCfg['highlight'].SetOption(theme_name, element, value) idleConf.userCfg['highlight'].SetOption(theme_name, element, value)
def delete_custom_theme(self): def delete_custom(self):
"""Handle event to delete custom theme. """Handle event to delete custom theme.
The current theme is deactivated and the default theme is The current theme is deactivated and the default theme is
@ -752,13 +817,13 @@ class ConfigDialog(Toplevel):
the config file. the config file.
Attributes accessed: Attributes accessed:
custom_theme custom_name
Attributes updated: Attributes updated:
radio_theme_custom custom_theme_on
opt_menu_theme_custom customlist
is_builtin_theme theme_source
builtin_theme builtin_name
Methods: Methods:
deactivate_current_config deactivate_current_config
@ -766,7 +831,7 @@ class ConfigDialog(Toplevel):
activate_config_changes activate_config_changes
set_theme_type set_theme_type
""" """
theme_name = self.custom_theme.get() theme_name = self.custom_name.get()
delmsg = 'Are you sure you wish to delete the theme %r ?' delmsg = 'Are you sure you wish to delete the theme %r ?'
if not tkMessageBox.askyesno( if not tkMessageBox.askyesno(
'Delete Theme', delmsg % theme_name, parent=self): 'Delete Theme', delmsg % theme_name, parent=self):
@ -778,13 +843,13 @@ class ConfigDialog(Toplevel):
item_list = idleConf.GetSectionList('user', 'highlight') item_list = idleConf.GetSectionList('user', 'highlight')
item_list.sort() item_list.sort()
if not item_list: if not item_list:
self.radio_theme_custom['state'] = DISABLED self.custom_theme_on['state'] = DISABLED
self.opt_menu_theme_custom.SetMenu(item_list, '- no custom themes -') self.customlist.SetMenu(item_list, '- no custom themes -')
else: else:
self.opt_menu_theme_custom.SetMenu(item_list, item_list[0]) self.customlist.SetMenu(item_list, item_list[0])
# Revert to default theme. # Revert to default theme.
self.is_builtin_theme.set(idleConf.defaultCfg['main'].Get('Theme', 'default')) self.theme_source.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
self.builtin_theme.set(idleConf.defaultCfg['main'].Get('Theme', 'name')) self.builtin_name.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
# User can't back out of these changes, they must be applied now. # User can't back out of these changes, they must be applied now.
changes.save_all() changes.save_all()
self.save_all_changed_extensions() self.save_all_changed_extensions()
@ -1270,7 +1335,7 @@ class KeysPage(Frame):
get_new_keys(). Function get_new_keys() gets the key mappings from the get_new_keys(). Function get_new_keys() gets the key mappings from the
current keyset for the binding event item that was selected. The current keyset for the binding event item that was selected. The
function then displays another dialog, GetKeysDialog, with the function then displays another dialog, GetKeysDialog, with the
selected binding event and current keys and always new key sequences selected binding event and current keys and allows new key sequences
to be entered for that binding event. If the keys aren't to be entered for that binding event. If the keys aren't
changed, nothing happens. If the keys are changed and the keyset changed, nothing happens. If the keys are changed and the keyset
is a builtin, function get_new_keys_name() will be called is a builtin, function get_new_keys_name() will be called

View File

@ -139,7 +139,7 @@ class FontPageTest(unittest.TestCase):
self.assertIn(d.font_name.get(), font1.lower()) self.assertIn(d.font_name.get(), font1.lower())
def test_sizelist(self): def test_sizelist(self):
# Click on number shouod select that number # Click on number should select that number
d = self.page d = self.page
d.sizelist.variable.set(40) d.sizelist.variable.set(40)
self.assertEqual(d.font_size.get(), '40') self.assertEqual(d.font_size.get(), '40')
@ -227,9 +227,457 @@ class IndentTest(unittest.TestCase):
class HighlightTest(unittest.TestCase): class HighlightTest(unittest.TestCase):
"""Test that highlight tab widgets enable users to make changes.
Test that widget actions set vars, that var changes add
options to changes and that themes work correctly.
"""
@classmethod
def setUpClass(cls):
d = dialog
dialog.note.select(d.highpage)
d.set_theme_type = Func()
d.paint_theme_sample = Func()
d.set_highlight_target = Func()
d.set_color_sample = Func()
@classmethod
def tearDownClass(cls):
d = dialog
del d.set_theme_type, d.paint_theme_sample
del d.set_highlight_target, d.set_color_sample
def setUp(self): def setUp(self):
d = dialog
# The following is needed for test_load_key_cfg, _delete_custom_keys.
# This may indicate a defect in some test or function.
for section in idleConf.GetSectionList('user', 'highlight'):
idleConf.userCfg['highlight'].remove_section(section)
changes.clear() changes.clear()
d.set_theme_type.called = 0
d.paint_theme_sample.called = 0
d.set_highlight_target.called = 0
d.set_color_sample.called = 0
def test_load_theme_cfg(self):
tracers.detach()
d = dialog
eq = self.assertEqual
# Use builtin theme with no user themes created.
idleConf.CurrentTheme = mock.Mock(return_value='IDLE Classic')
d.load_theme_cfg()
self.assertTrue(d.theme_source.get())
# builtinlist sets variable builtin_name to the CurrentTheme default.
eq(d.builtin_name.get(), 'IDLE Classic')
eq(d.custom_name.get(), '- no custom themes -')
eq(d.custom_theme_on['state'], DISABLED)
eq(d.set_theme_type.called, 1)
eq(d.paint_theme_sample.called, 1)
eq(d.set_highlight_target.called, 1)
# Builtin theme with non-empty user theme list.
idleConf.SetOption('highlight', 'test1', 'option', 'value')
idleConf.SetOption('highlight', 'test2', 'option2', 'value2')
d.load_theme_cfg()
eq(d.builtin_name.get(), 'IDLE Classic')
eq(d.custom_name.get(), 'test1')
eq(d.set_theme_type.called, 2)
eq(d.paint_theme_sample.called, 2)
eq(d.set_highlight_target.called, 2)
# Use custom theme.
idleConf.CurrentTheme = mock.Mock(return_value='test2')
idleConf.SetOption('main', 'Theme', 'default', '0')
d.load_theme_cfg()
self.assertFalse(d.theme_source.get())
eq(d.builtin_name.get(), 'IDLE Classic')
eq(d.custom_name.get(), 'test2')
eq(d.set_theme_type.called, 3)
eq(d.paint_theme_sample.called, 3)
eq(d.set_highlight_target.called, 3)
del idleConf.CurrentTheme
tracers.attach()
def test_theme_source(self):
eq = self.assertEqual
d = dialog
# Test these separately.
d.var_changed_builtin_name = Func()
d.var_changed_custom_name = Func()
# Builtin selected.
d.builtin_theme_on.invoke()
eq(mainpage, {'Theme': {'default': 'True'}})
eq(d.var_changed_builtin_name.called, 1)
eq(d.var_changed_custom_name.called, 0)
changes.clear()
# Custom selected.
d.custom_theme_on['state'] = NORMAL
d.custom_theme_on.invoke()
self.assertEqual(mainpage, {'Theme': {'default': 'False'}})
eq(d.var_changed_builtin_name.called, 1)
eq(d.var_changed_custom_name.called, 1)
del d.var_changed_builtin_name, d.var_changed_custom_name
def test_builtin_name(self):
eq = self.assertEqual
d = dialog
item_list = ['IDLE Classic', 'IDLE Dark', 'IDLE New']
# Not in old_themes, defaults name to first item.
idleConf.SetOption('main', 'Theme', 'name', 'spam')
d.builtinlist.SetMenu(item_list, 'IDLE Dark')
eq(mainpage, {'Theme': {'name': 'IDLE Classic',
'name2': 'IDLE Dark'}})
eq(d.theme_message['text'], 'New theme, see Help')
eq(d.paint_theme_sample.called, 1)
# Not in old themes - uses name2.
changes.clear()
idleConf.SetOption('main', 'Theme', 'name', 'IDLE New')
d.builtinlist.SetMenu(item_list, 'IDLE Dark')
eq(mainpage, {'Theme': {'name2': 'IDLE Dark'}})
eq(d.theme_message['text'], 'New theme, see Help')
eq(d.paint_theme_sample.called, 2)
# Builtin name in old_themes.
changes.clear()
d.builtinlist.SetMenu(item_list, 'IDLE Classic')
eq(mainpage, {'Theme': {'name': 'IDLE Classic', 'name2': ''}})
eq(d.theme_message['text'], '')
eq(d.paint_theme_sample.called, 3)
def test_custom_name(self):
d = dialog
# If no selections, doesn't get added.
d.customlist.SetMenu([], '- no custom themes -')
self.assertNotIn('Theme', mainpage)
self.assertEqual(d.paint_theme_sample.called, 0)
# Custom name selected.
changes.clear()
d.customlist.SetMenu(['a', 'b', 'c'], 'c')
self.assertEqual(mainpage, {'Theme': {'name': 'c'}})
self.assertEqual(d.paint_theme_sample.called, 1)
def test_color(self):
d = dialog
d.on_new_color_set = Func()
# self.color is only set in get_color through ColorChooser.
d.color.set('green')
self.assertEqual(d.on_new_color_set.called, 1)
del d.on_new_color_set
def test_highlight_target_list_mouse(self):
# Set highlight_target through targetlist.
eq = self.assertEqual
d = dialog
d.targetlist.SetMenu(['a', 'b', 'c'], 'c')
eq(d.highlight_target.get(), 'c')
eq(d.set_highlight_target.called, 1)
def test_highlight_target_text_mouse(self):
# Set highlight_target through clicking highlight_sample.
eq = self.assertEqual
d = dialog
elem = {}
count = 0
hs = d.highlight_sample
hs.focus_force()
hs.see(1.0)
hs.update_idletasks()
def tag_to_element(elem):
for element, tag in d.theme_elements.items():
elem[tag[0]] = element
def click_it(start):
x, y, dx, dy = hs.bbox(start)
x += dx // 2
y += dy // 2
hs.event_generate('<Enter>', x=0, y=0)
hs.event_generate('<Motion>', x=x, y=y)
hs.event_generate('<ButtonPress-1>', x=x, y=y)
hs.event_generate('<ButtonRelease-1>', x=x, y=y)
# Flip theme_elements to make the tag the key.
tag_to_element(elem)
# If highlight_sample has a tag that isn't in theme_elements, there
# will be a KeyError in the test run.
for tag in hs.tag_names():
for start_index in hs.tag_ranges(tag)[0::2]:
count += 1
click_it(start_index)
eq(d.highlight_target.get(), elem[tag])
eq(d.set_highlight_target.called, count)
def test_set_theme_type(self):
eq = self.assertEqual
d = dialog
del d.set_theme_type
# Builtin theme selected.
d.theme_source.set(True)
d.set_theme_type()
eq(d.builtinlist['state'], NORMAL)
eq(d.customlist['state'], DISABLED)
eq(d.button_delete_custom['state'], DISABLED)
# Custom theme selected.
d.theme_source.set(False)
d.set_theme_type()
eq(d.builtinlist['state'], DISABLED)
eq(d.custom_theme_on['state'], NORMAL)
eq(d.customlist['state'], NORMAL)
eq(d.button_delete_custom['state'], NORMAL)
d.set_theme_type = Func()
def test_get_color(self):
eq = self.assertEqual
d = dialog
orig_chooser = configdialog.tkColorChooser.askcolor
chooser = configdialog.tkColorChooser.askcolor = Func()
gntn = d.get_new_theme_name = Func()
d.highlight_target.set('Editor Breakpoint')
d.color.set('#ffffff')
# Nothing selected.
chooser.result = (None, None)
d.button_set_color.invoke()
eq(d.color.get(), '#ffffff')
# Selection same as previous color.
chooser.result = ('', d.frame_color_set.cget('bg'))
d.button_set_color.invoke()
eq(d.color.get(), '#ffffff')
# Select different color.
chooser.result = ((222.8671875, 0.0, 0.0), '#de0000')
# Default theme.
d.color.set('#ffffff')
d.theme_source.set(True)
# No theme name selected therefore color not saved.
gntn.result = ''
d.button_set_color.invoke()
eq(gntn.called, 1)
eq(d.color.get(), '#ffffff')
# Theme name selected.
gntn.result = 'My New Theme'
d.button_set_color.invoke()
eq(d.custom_name.get(), gntn.result)
eq(d.color.get(), '#de0000')
# Custom theme.
d.color.set('#ffffff')
d.theme_source.set(False)
d.button_set_color.invoke()
eq(d.color.get(), '#de0000')
del d.get_new_theme_name
configdialog.tkColorChooser.askcolor = orig_chooser
def test_on_new_color_set(self):
d = dialog
color = '#3f7cae'
d.custom_name.set('Python')
d.highlight_target.set('Selected Text')
d.fg_bg_toggle.set(True)
d.color.set(color)
self.assertEqual(d.frame_color_set.cget('bg'), color)
self.assertEqual(d.highlight_sample.tag_cget('hilite', 'foreground'), color)
self.assertEqual(highpage,
{'Python': {'hilite-foreground': color}})
def test_get_new_theme_name(self):
orig_sectionname = configdialog.SectionName
sn = configdialog.SectionName = Func(return_self=True)
d = dialog
sn.result = 'New Theme'
self.assertEqual(d.get_new_theme_name(''), 'New Theme')
configdialog.SectionName = orig_sectionname
def test_save_as_new_theme(self):
d = dialog
gntn = d.get_new_theme_name = Func()
d.theme_source.set(True)
# No name entered.
gntn.result = ''
d.button_save_custom.invoke()
self.assertNotIn(gntn.result, idleConf.userCfg['highlight'])
# Name entered.
gntn.result = 'my new theme'
gntn.called = 0
self.assertNotIn(gntn.result, idleConf.userCfg['highlight'])
d.button_save_custom.invoke()
self.assertIn(gntn.result, idleConf.userCfg['highlight'])
del d.get_new_theme_name
def test_create_new_and_save_new(self):
eq = self.assertEqual
d = dialog
# Use default as previously active theme.
d.theme_source.set(True)
d.builtin_name.set('IDLE Classic')
first_new = 'my new custom theme'
second_new = 'my second custom theme'
# No changes, so themes are an exact copy.
self.assertNotIn(first_new, idleConf.userCfg)
d.create_new(first_new)
eq(idleConf.GetSectionList('user', 'highlight'), [first_new])
eq(idleConf.GetThemeDict('default', 'IDLE Classic'),
idleConf.GetThemeDict('user', first_new))
eq(d.custom_name.get(), first_new)
self.assertFalse(d.theme_source.get()) # Use custom set.
eq(d.set_theme_type.called, 1)
# Test that changed targets are in new theme.
changes.add_option('highlight', first_new, 'hit-background', 'yellow')
self.assertNotIn(second_new, idleConf.userCfg)
d.create_new(second_new)
eq(idleConf.GetSectionList('user', 'highlight'), [first_new, second_new])
self.assertNotEqual(idleConf.GetThemeDict('user', first_new),
idleConf.GetThemeDict('user', second_new))
# Check that difference in themes was in `hit-background` from `changes`.
idleConf.SetOption('highlight', first_new, 'hit-background', 'yellow')
eq(idleConf.GetThemeDict('user', first_new),
idleConf.GetThemeDict('user', second_new))
def test_set_highlight_target(self):
eq = self.assertEqual
d = dialog
del d.set_highlight_target
# Target is cursor.
d.highlight_target.set('Cursor')
eq(d.fg_on['state'], DISABLED)
eq(d.bg_on['state'], DISABLED)
self.assertTrue(d.fg_bg_toggle)
eq(d.set_color_sample.called, 1)
# Target is not cursor.
d.highlight_target.set('Comment')
eq(d.fg_on['state'], NORMAL)
eq(d.bg_on['state'], NORMAL)
self.assertTrue(d.fg_bg_toggle)
eq(d.set_color_sample.called, 2)
d.set_highlight_target = Func()
def test_set_color_sample_binding(self):
d = dialog
scs = d.set_color_sample
d.fg_on.invoke()
self.assertEqual(scs.called, 1)
d.bg_on.invoke()
self.assertEqual(scs.called, 2)
def test_set_color_sample(self):
d = dialog
del d.set_color_sample
d.highlight_target.set('Selected Text')
d.fg_bg_toggle.set(True)
d.set_color_sample()
self.assertEqual(d.frame_color_set.cget('bg'),
d.highlight_sample.tag_cget('hilite', 'foreground'))
d.set_color_sample = Func()
def test_paint_theme_sample(self):
eq = self.assertEqual
d = dialog
del d.paint_theme_sample
hs_tag = d.highlight_sample.tag_cget
gh = idleConf.GetHighlight
fg = 'foreground'
bg = 'background'
# Create custom theme based on IDLE Dark.
d.theme_source.set(True)
d.builtin_name.set('IDLE Dark')
theme = 'IDLE Test'
d.create_new(theme)
d.set_color_sample.called = 0
# Base theme with nothing in `changes`.
d.paint_theme_sample()
eq(hs_tag('break', fg), gh(theme, 'break', fgBg='fg'))
eq(hs_tag('cursor', bg), gh(theme, 'normal', fgBg='bg'))
self.assertNotEqual(hs_tag('console', fg), 'blue')
self.assertNotEqual(hs_tag('console', bg), 'yellow')
eq(d.set_color_sample.called, 1)
# Apply changes.
changes.add_option('highlight', theme, 'console-foreground', 'blue')
changes.add_option('highlight', theme, 'console-background', 'yellow')
d.paint_theme_sample()
eq(hs_tag('break', fg), gh(theme, 'break', fgBg='fg'))
eq(hs_tag('cursor', bg), gh(theme, 'normal', fgBg='bg'))
eq(hs_tag('console', fg), 'blue')
eq(hs_tag('console', bg), 'yellow')
eq(d.set_color_sample.called, 2)
d.paint_theme_sample = Func()
def test_delete_custom(self):
eq = self.assertEqual
d = dialog
d.button_delete_custom['state'] = NORMAL
yesno = configdialog.tkMessageBox.askyesno = Func()
dialog.deactivate_current_config = Func()
dialog.activate_config_changes = Func()
theme_name = 'spam theme'
idleConf.userCfg['highlight'].SetOption(theme_name, 'name', 'value')
highpage[theme_name] = {'option': 'True'}
# Force custom theme.
d.theme_source.set(False)
d.custom_name.set(theme_name)
# Cancel deletion.
yesno.result = False
d.button_delete_custom.invoke()
eq(yesno.called, 1)
eq(highpage[theme_name], {'option': 'True'})
eq(idleConf.GetSectionList('user', 'highlight'), ['spam theme'])
eq(dialog.deactivate_current_config.called, 0)
eq(dialog.activate_config_changes.called, 0)
eq(d.set_theme_type.called, 0)
# Confirm deletion.
yesno.result = True
d.button_delete_custom.invoke()
eq(yesno.called, 2)
self.assertNotIn(theme_name, highpage)
eq(idleConf.GetSectionList('user', 'highlight'), [])
eq(d.custom_theme_on['state'], DISABLED)
eq(d.custom_name.get(), '- no custom themes -')
eq(dialog.deactivate_current_config.called, 1)
eq(dialog.activate_config_changes.called, 1)
eq(d.set_theme_type.called, 1)
del dialog.activate_config_changes, dialog.deactivate_current_config
del configdialog.tkMessageBox.askyesno
class KeysPageTest(unittest.TestCase): class KeysPageTest(unittest.TestCase):

View File

@ -0,0 +1 @@
Add tests for configdialog highlight tab. Patch by Cheryl Sabella.