changes = ConfigChanges()
-
class ConfigDialog(Toplevel):
"""Config dialog for IDLE.
"""
self.create_page_extensions()
self.create_action_buttons().pack(side=BOTTOM)
+ def load_configs(self):
+ """Load configuration for each page.
+
+ Load configuration from default and user config files and populate
+ the widgets on the config dialog pages.
+
+ Methods:
+ load_font_cfg
+ load_tab_cfg
+ load_theme_cfg
+ load_key_cfg
+ load_general_cfg
+ """
+ self.load_font_cfg()
+ self.load_tab_cfg()
+ self.load_theme_cfg()
+ self.load_key_cfg()
+ self.load_general_cfg()
+ # note: extension page handled separately
+
+ 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)
+ 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)
+ 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.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,):
+ var.trace_remove('write', var.trace_info()[0][1])
+
+
def create_action_buttons(self):
"""Return frame of action buttons for dialog.
buttons.pack(side=BOTTOM)
return outer
+ def ok(self):
+ """Apply config changes, then dismiss dialog.
+
+ Methods:
+ apply
+ destroy: inherited
+ """
+ self.apply()
+ self.destroy()
+
+ def apply(self):
+ """Apply config changes and leave dialog open.
+
+ Methods:
+ deactivate_current_config
+ save_all_changed_extensions
+ activate_config_changes
+ """
+ self.deactivate_current_config()
+ changes.save_all()
+ self.save_all_changed_extensions()
+ self.activate_config_changes()
+
+ def cancel(self):
+ """Dismiss config dialog.
+
+ Methods:
+ destroy: inherited
+ """
+ self.destroy()
+
+ def help(self):
+ """Create textview for config dialog help.
+
+ Attrbutes accessed:
+ tab_pages
+
+ Methods:
+ view_text: Method from textview module.
+ """
+ page = self.tab_pages._current_page
+ view_text(self, title='Help for IDLE preferences',
+ text=help_common+help_pages.get(page, ''))
+
def create_page_font_tab(self):
"""Return frame of widgets for Font/Tabs tab.
# Set font weight.
self.font_bold.set(font_bold)
- def on_fontlist_select(self, event):
- """Handle selecting a font from the list.
-
- Event can result from either mouse click or Up or Down key.
- Set font_name and example displays to selection.
- """
- font = self.fontlist.get(
- ACTIVE if event.type.name == 'KeyRelease' else ANCHOR)
- self.font_name.set(font.lower())
-
def var_changed_font(self, *params):
"""Store changes to font attributes.
changes.add_option('main', 'EditorWindow', 'font-bold', value)
self.set_samples()
+ def on_fontlist_select(self, event):
+ """Handle selecting a font from the list.
+
+ Event can result from either mouse click or Up or Down key.
+ Set font_name and example displays to selection.
+ """
+ font = self.fontlist.get(
+ ACTIVE if event.type.name == 'KeyRelease' else ANCHOR)
+ self.font_name.set(font.lower())
+
def set_samples(self, event=None):
"""Update update both screen samples with the font settings.
self.new_custom_theme.pack(side=TOP, fill=X, pady=5)
return frame
- def create_page_keys(self):
- """Return frame of widgets for Keys tab.
+ def load_theme_cfg(self):
+ """Load current configuration settings for the theme options.
- Tk Variables:
- builtin_keys: Menu variable for built-in keybindings.
- custom_keys: Menu variable for custom keybindings.
- are_keys_builtin: Selector for built-in or custom keybindings.
- keybinding: Action/key bindings.
+ Based on the is_builtin_theme toggle, the theme is set as
+ either builtin or custom and the initial widget values
+ reflect the current settings from idleConf.
- Methods:
- load_key_config: Set table.
- load_keys_list: Reload active set.
- keybinding_selected: Bound to list_bindings button release.
- get_new_keys: Command for button_new_keys.
- get_new_keys_name: Call popup.
- create_new_key_set: Combine active keyset and changes.
- set_keys_type: Command for are_keys_builtin.
- delete_custom_keys: Command for button_delete_custom_keys.
- save_as_new_key_set: Command for button_save_custom_keys.
- save_new_key_set: Save to idleConf.userCfg['keys'] (is function).
- deactivate_current_config: Remove keys bindings in editors.
+ Attributes updated:
+ is_builtin_theme: Set from idleConf.
+ opt_menu_theme_builtin: List of default themes from idleConf.
+ opt_menu_theme_custom: List of custom themes from idleConf.
+ radio_theme_custom: Disabled if there are no custom themes.
+ custom_theme: Message with additional information.
+ opt_menu_highlight_target: Create menu from self.theme_elements.
- Widget Structure: (*) widgets bound to self
- frame
- frame_custom: LabelFrame
- frame_target: Frame
- target_title: Label
- scroll_target_y: Scrollbar
- scroll_target_x: Scrollbar
- (*)list_bindings: ListBox
- (*)button_new_keys: Button
- frame_key_sets: LabelFrame
- frames[0]: Frame
- (*)radio_keys_builtin: Radiobutton - are_keys_builtin
- (*)radio_keys_custom: Radiobutton - are_keys_builtin
- (*)opt_menu_keys_builtin: DynOptionMenu - builtin_keys
- (*)opt_menu_keys_custom: DynOptionMenu - custom_keys
- (*)new_custom_keys: Label
- frames[1]: Frame
- (*)button_delete_custom_keys: Button
- button_save_custom_keys: Button
+ Methods:
+ set_theme_type
+ paint_theme_sample
+ set_highlight_target
"""
- parent = self.parent
- self.builtin_keys = StringVar(parent)
- self.custom_keys = StringVar(parent)
- self.are_keys_builtin = BooleanVar(parent)
- self.keybinding = StringVar(parent)
+ # Set current theme type radiobutton.
+ self.is_builtin_theme.set(idleConf.GetOption(
+ 'main', 'Theme', 'default', type='bool', default=1))
+ # Set current theme.
+ current_option = idleConf.CurrentTheme()
+ # Load available theme option menus.
+ if self.is_builtin_theme.get(): # Default theme selected.
+ item_list = idleConf.GetSectionList('default', 'highlight')
+ item_list.sort()
+ self.opt_menu_theme_builtin.SetMenu(item_list, current_option)
+ item_list = idleConf.GetSectionList('user', 'highlight')
+ item_list.sort()
+ if not item_list:
+ self.radio_theme_custom['state'] = DISABLED
+ self.custom_theme.set('- no custom themes -')
+ else:
+ self.opt_menu_theme_custom.SetMenu(item_list, item_list[0])
+ else: # User theme selected.
+ item_list = idleConf.GetSectionList('user', 'highlight')
+ item_list.sort()
+ self.opt_menu_theme_custom.SetMenu(item_list, current_option)
+ item_list = idleConf.GetSectionList('default', 'highlight')
+ item_list.sort()
+ self.opt_menu_theme_builtin.SetMenu(item_list, item_list[0])
+ self.set_theme_type()
+ # Load theme element option menu.
+ theme_names = list(self.theme_elements.keys())
+ theme_names.sort(key=lambda x: self.theme_elements[x][1])
+ self.opt_menu_highlight_target.SetMenu(theme_names, theme_names[0])
+ self.paint_theme_sample()
+ self.set_highlight_target()
- ##widget creation
- #body frame
- frame = self.tab_pages.pages['Keys'].frame
- #body section frames
- frame_custom = LabelFrame(
- frame, borderwidth=2, relief=GROOVE,
- text=' Custom Key Bindings ')
- frame_key_sets = LabelFrame(
- frame, borderwidth=2, relief=GROOVE, text=' Key Set ')
- #frame_custom
- frame_target = Frame(frame_custom)
- target_title = Label(frame_target, text='Action - Key(s)')
- scroll_target_y = Scrollbar(frame_target)
- scroll_target_x = Scrollbar(frame_target, orient=HORIZONTAL)
- self.list_bindings = Listbox(
- frame_target, takefocus=FALSE, exportselection=FALSE)
- self.list_bindings.bind('<ButtonRelease-1>', self.keybinding_selected)
- scroll_target_y.config(command=self.list_bindings.yview)
- scroll_target_x.config(command=self.list_bindings.xview)
- self.list_bindings.config(yscrollcommand=scroll_target_y.set)
- self.list_bindings.config(xscrollcommand=scroll_target_x.set)
- self.button_new_keys = Button(
- frame_custom, text='Get New Keys for Selection',
- command=self.get_new_keys, state=DISABLED)
- #frame_key_sets
- frames = [Frame(frame_key_sets, padx=2, pady=2, borderwidth=0)
- for i in range(2)]
- self.radio_keys_builtin = Radiobutton(
- frames[0], variable=self.are_keys_builtin, value=1,
- command=self.set_keys_type, text='Use a Built-in Key Set')
- self.radio_keys_custom = Radiobutton(
- frames[0], variable=self.are_keys_builtin, value=0,
- command=self.set_keys_type, text='Use a Custom Key Set')
- self.opt_menu_keys_builtin = DynOptionMenu(
- frames[0], self.builtin_keys, None, command=None)
- self.opt_menu_keys_custom = DynOptionMenu(
- frames[0], self.custom_keys, None, command=None)
- self.button_delete_custom_keys = Button(
- frames[1], text='Delete Custom Key Set',
- command=self.delete_custom_keys)
- button_save_custom_keys = Button(
- frames[1], text='Save as New Custom Key Set',
- command=self.save_as_new_key_set)
- self.new_custom_keys = Label(frames[0], bd=2)
+ def var_changed_builtin_theme(self, *params):
+ """Process new builtin theme selection.
- ##widget packing
- #body
- frame_custom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH)
- frame_key_sets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH)
- #frame_custom
- self.button_new_keys.pack(side=BOTTOM, fill=X, padx=5, pady=5)
- frame_target.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
- #frame target
- frame_target.columnconfigure(0, weight=1)
- frame_target.rowconfigure(1, weight=1)
- target_title.grid(row=0, column=0, columnspan=2, sticky=W)
- self.list_bindings.grid(row=1, column=0, sticky=NSEW)
- scroll_target_y.grid(row=1, column=1, sticky=NS)
- scroll_target_x.grid(row=2, column=0, sticky=EW)
- #frame_key_sets
- self.radio_keys_builtin.grid(row=0, column=0, sticky=W+NS)
- self.radio_keys_custom.grid(row=1, column=0, sticky=W+NS)
- self.opt_menu_keys_builtin.grid(row=0, column=1, sticky=NSEW)
- self.opt_menu_keys_custom.grid(row=1, column=1, sticky=NSEW)
- self.new_custom_keys.grid(row=0, column=2, sticky=NSEW, padx=5, pady=5)
- self.button_delete_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
- button_save_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
- frames[0].pack(side=TOP, fill=BOTH, expand=True)
- frames[1].pack(side=TOP, fill=X, expand=True, pady=2)
- return frame
+ Add the changed theme's name to the changed_items and recreate
+ the sample with the values from the selected theme.
+ """
+ old_themes = ('IDLE Classic', 'IDLE New')
+ value = self.builtin_theme.get()
+ if value 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', 'name2', value)
+ self.new_custom_theme.config(text='New theme, see Help',
+ fg='#500000')
+ else:
+ 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()
+ def var_changed_custom_theme(self, *params):
+ """Process new custom theme selection.
- def create_page_general(self):
- """Return frame of widgets for General tab.
+ If a new custom theme is selected, add the name to the
+ changed_items and apply the theme to the sample.
+ """
+ value = self.custom_theme.get()
+ if value != '- no custom themes -':
+ changes.add_option('main', 'Theme', 'name', value)
+ self.paint_theme_sample()
- Enable users to provisionally change general options. Function
- load_general_cfg intializes 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
- var_changed_var_name callback that adds option to changes.
+ def var_changed_is_builtin_theme(self, *params):
+ """Process toggle between builtin and custom theme.
- 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'].
+ Update the default toggle value and apply the newly
+ selected theme type.
+ """
+ value = self.is_builtin_theme.get()
+ changes.add_option('main', 'Theme', 'default', value)
+ if value:
+ self.var_changed_builtin_theme()
+ else:
+ self.var_changed_custom_theme()
- Widget Structure: (*) widgets bound to self
- frame
- frame_run: LabelFrame
- startup_title: Label
- (*)startup_editor_on: Radiobutton - startup_edit
- (*)startup_shell_on: Radiobutton - startup_edit
- frame_save: LabelFrame
- run_save_title: Label
- (*)save_ask_on: Radiobutton - autosave
- (*)save_auto_on: Radiobutton - autosave
- frame_win_size: LabelFrame
- win_size_title: Label
- win_width_title: Label
- (*)win_width_int: Entry - win_width
- win_height_title: Label
- (*)win_height_int: Entry - win_height
- frame_help: LabelFrame
- frame_helplist: Frame
- frame_helplist_buttons: Frame
- (*)button_helplist_edit
- (*)button_helplist_add
- (*)button_helplist_remove
- (*)helplist: ListBox
- scroll_helplist: Scrollbar
+ def var_changed_color(self, *params):
+ "Process change to color choice."
+ self.on_new_color_set()
+
+ def var_changed_highlight_target(self, *params):
+ "Process selection of new target tag for highlighting."
+ self.set_highlight_target()
+
+ def set_theme_type(self):
+ """Set available screen options based on builtin or custom theme.
+
+ Attributes accessed:
+ is_builtin_theme
+
+ Attributes updated:
+ opt_menu_theme_builtin
+ opt_menu_theme_custom
+ button_delete_custom_theme
+ radio_theme_custom
+
+ Called from:
+ handler for radio_theme_builtin and radio_theme_custom
+ delete_custom_theme
+ create_new_theme
+ load_theme_cfg
"""
- parent = self.parent
- self.startup_edit = IntVar(parent)
- self.autosave = IntVar(parent)
- self.win_width = StringVar(parent)
- self.win_height = StringVar(parent)
+ if self.is_builtin_theme.get():
+ self.opt_menu_theme_builtin['state'] = NORMAL
+ self.opt_menu_theme_custom['state'] = DISABLED
+ self.button_delete_custom_theme['state'] = DISABLED
+ else:
+ self.opt_menu_theme_builtin['state'] = DISABLED
+ self.radio_theme_custom['state'] = NORMAL
+ self.opt_menu_theme_custom['state'] = NORMAL
+ self.button_delete_custom_theme['state'] = NORMAL
- # Create widgets:
- # body.
- frame = self.tab_pages.pages['General'].frame
- # body section frames.
- frame_run = LabelFrame(frame, borderwidth=2, relief=GROOVE,
- text=' Startup Preferences ')
- frame_save = LabelFrame(frame, borderwidth=2, relief=GROOVE,
- text=' autosave Preferences ')
- frame_win_size = Frame(frame, borderwidth=2, relief=GROOVE)
- frame_help = LabelFrame(frame, borderwidth=2, relief=GROOVE,
- text=' Additional Help Sources ')
- # frame_run.
- startup_title = Label(frame_run, text='At Startup')
- self.startup_editor_on = Radiobutton(
- frame_run, variable=self.startup_edit, value=1,
- text="Open Edit Window")
- self.startup_shell_on = Radiobutton(
- frame_run, variable=self.startup_edit, value=0,
- text='Open Shell Window')
- # frame_save.
- 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_win_size.
- win_size_title = Label(
- frame_win_size, text='Initial Window Size (in characters)')
- win_width_title = Label(frame_win_size, text='Width')
- self.win_width_int = Entry(
- frame_win_size, textvariable=self.win_width, width=3)
- win_height_title = Label(frame_win_size, text='Height')
- self.win_height_int = Entry(
- frame_win_size, textvariable=self.win_height, width=3)
- # frame_help.
- frame_helplist = Frame(frame_help)
- frame_helplist_buttons = Frame(frame_helplist)
- self.helplist = Listbox(
- frame_helplist, height=5, takefocus=FALSE,
- exportselection=FALSE)
- scroll_helplist = Scrollbar(frame_helplist)
- scroll_helplist['command'] = self.helplist.yview
- self.helplist['yscrollcommand'] = scroll_helplist.set
- self.helplist.bind('<ButtonRelease-1>', self.help_source_selected)
- self.button_helplist_edit = Button(
- frame_helplist_buttons, text='Edit', state=DISABLED,
- width=8, command=self.helplist_item_edit)
- self.button_helplist_add = Button(
- frame_helplist_buttons, text='Add',
- width=8, command=self.helplist_item_add)
- self.button_helplist_remove = Button(
- frame_helplist_buttons, text='Remove', state=DISABLED,
- width=8, command=self.helplist_item_remove)
+ def get_color(self):
+ """Handle button to select a new color for the target tag.
- # Pack widgets:
- # body.
- frame_run.pack(side=TOP, padx=5, pady=5, fill=X)
- frame_save.pack(side=TOP, padx=5, pady=5, fill=X)
- frame_win_size.pack(side=TOP, padx=5, pady=5, fill=X)
- frame_help.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
- # frame_run.
- startup_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
- self.startup_shell_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
- self.startup_editor_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
- # frame_save.
- 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_win_size.
- win_size_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
- self.win_height_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)
- win_height_title.pack(side=RIGHT, anchor=E, pady=5)
- self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)
- win_width_title.pack(side=RIGHT, anchor=E, pady=5)
- # frame_help.
- frame_helplist_buttons.pack(side=RIGHT, padx=5, pady=5, fill=Y)
- frame_helplist.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
- scroll_helplist.pack(side=RIGHT, anchor=W, fill=Y)
- self.helplist.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)
- self.button_helplist_edit.pack(side=TOP, anchor=W, pady=5)
- self.button_helplist_add.pack(side=TOP, anchor=W)
- self.button_helplist_remove.pack(side=TOP, anchor=W, pady=5)
+ If a new color is selected while using a builtin theme, a
+ name must be supplied to create a custom theme.
+
+ Attributes accessed:
+ highlight_target
+ frame_color_set
+ is_builtin_theme
+
+ Attributes updated:
+ color
+
+ Methods:
+ get_new_theme_name
+ create_new_theme
+ """
+ target = self.highlight_target.get()
+ prev_color = self.frame_color_set.cget('bg')
+ rgbTuplet, color_string = tkColorChooser.askcolor(
+ parent=self, title='Pick new color for : '+target,
+ initialcolor=prev_color)
+ if color_string and (color_string != prev_color):
+ # User didn't cancel and they chose a new color.
+ if self.is_builtin_theme.get(): # Current theme is a built-in.
+ message = ('Your changes will be saved as a new Custom Theme. '
+ 'Enter a name for your new Custom Theme below.')
+ new_theme = self.get_new_theme_name(message)
+ if not new_theme: # User cancelled custom theme creation.
+ return
+ else: # Create new custom theme based on previously active theme.
+ self.create_new_theme(new_theme)
+ self.color.set(color_string)
+ else: # Current theme is user defined.
+ self.color.set(color_string)
+
+ def on_new_color_set(self):
+ "Display sample of new color selection on the dialog."
+ new_color=self.color.get()
+ self.frame_color_set.config(bg=new_color) # Set sample.
+ plane ='foreground' if self.fg_bg_toggle.get() else 'background'
+ sample_element = self.theme_elements[self.highlight_target.get()][0]
+ self.highlight_sample.tag_config(sample_element, **{plane:new_color})
+ theme = self.custom_theme.get()
+ theme_element = sample_element + '-' + plane
+ changes.add_option('highlight', theme, theme_element, new_color)
+
+ def get_new_theme_name(self, message):
+ "Return name of new theme from query popup."
+ used_names = (idleConf.GetSectionList('user', 'highlight') +
+ idleConf.GetSectionList('default', 'highlight'))
+ new_theme = SectionName(
+ self, 'New Custom Theme', message, used_names).result
+ return new_theme
+
+ def save_as_new_theme(self):
+ """Prompt for new theme name and create the theme.
+
+ Methods:
+ get_new_theme_name
+ create_new_theme
+ """
+ new_theme_name = self.get_new_theme_name('New Theme Name:')
+ if new_theme_name:
+ self.create_new_theme(new_theme_name)
+
+ def create_new_theme(self, new_theme_name):
+ """Create a new custom theme with the given name.
- return frame
+ Create the new theme based on the previously active theme
+ with the current changes applied. Once it is saved, then
+ activate the new theme.
- def load_general_cfg(self):
- "Load current configuration settings for the general options."
- # Set startup state.
- self.startup_edit.set(idleConf.GetOption(
- 'main', 'General', 'editor-on-startup', default=0, type='bool'))
- # Set autosave state.
- self.autosave.set(idleConf.GetOption(
- 'main', 'General', 'autosave', default=0, type='bool'))
- # Set initial window size.
- self.win_width.set(idleConf.GetOption(
- 'main', 'EditorWindow', 'width', type='int'))
- self.win_height.set(idleConf.GetOption(
- 'main', 'EditorWindow', 'height', type='int'))
- # Set additional help sources.
- self.user_helplist = idleConf.GetAllExtraHelpSourcesList()
- self.helplist.delete(0, 'end')
- for help_item in self.user_helplist:
- self.helplist.insert(END, help_item[0])
- self.set_add_delete_state()
+ Attributes accessed:
+ builtin_theme
+ custom_theme
- def var_changed_startup_edit(self, *params):
- "Store change to toggle for starting IDLE in the editor or shell."
- value = self.startup_edit.get()
- changes.add_option('main', 'General', 'editor-on-startup', value)
+ Attributes updated:
+ opt_menu_theme_custom
+ is_builtin_theme
- def var_changed_autosave(self, *params):
- "Store change to autosave."
- value = self.autosave.get()
- changes.add_option('main', 'General', 'autosave', value)
+ Method:
+ save_new_theme
+ set_theme_type
+ """
+ if self.is_builtin_theme.get():
+ theme_type = 'default'
+ theme_name = self.builtin_theme.get()
+ else:
+ theme_type = 'user'
+ 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 changes['highlight']:
+ theme_changes = changes['highlight'][theme_name]
+ for element in theme_changes:
+ new_theme[element] = theme_changes[element]
+ # Save the new theme.
+ self.save_new_theme(new_theme_name, new_theme)
+ # Change GUI over to the new theme.
+ custom_theme_list = idleConf.GetSectionList('user', 'highlight')
+ custom_theme_list.sort()
+ self.opt_menu_theme_custom.SetMenu(custom_theme_list, new_theme_name)
+ self.is_builtin_theme.set(0)
+ self.set_theme_type()
- def var_changed_win_width(self, *params):
- "Store change to window width."
- value = self.win_width.get()
- changes.add_option('main', 'EditorWindow', 'width', value)
+ def set_highlight_target(self):
+ """Set fg/bg toggle and color based on highlight tag target.
- def var_changed_win_height(self, *params):
- "Store change to window height."
- value = self.win_height.get()
- changes.add_option('main', 'EditorWindow', 'height', value)
+ Instance variables accessed:
+ highlight_target
- def help_source_selected(self, event):
- "Handle event for selecting additional help."
- self.set_add_delete_state()
+ Attributes updated:
+ radio_fg
+ radio_bg
+ fg_bg_toggle
- def set_add_delete_state(self):
- "Toggle the state for the help list buttons based on list entries."
- if self.helplist.size() < 1: # No entries in list.
- self.button_helplist_edit['state'] = DISABLED
- self.button_helplist_remove['state'] = DISABLED
- else: # Some entries.
- if self.helplist.curselection(): # There currently is a selection.
- self.button_helplist_edit['state'] = NORMAL
- self.button_helplist_remove['state'] = NORMAL
- else: # There currently is not a selection.
- self.button_helplist_edit['state'] = DISABLED
- self.button_helplist_remove['state'] = DISABLED
+ Methods:
+ set_color_sample
- def helplist_item_add(self):
- """Handle add button for the help list.
+ Called from:
+ var_changed_highlight_target
+ load_theme_cfg
+ """
+ if self.highlight_target.get() == 'Cursor': # bg not possible
+ self.radio_fg['state'] = DISABLED
+ self.radio_bg['state'] = DISABLED
+ self.fg_bg_toggle.set(1)
+ else: # Both fg and bg can be set.
+ self.radio_fg['state'] = NORMAL
+ self.radio_bg['state'] = NORMAL
+ self.fg_bg_toggle.set(1)
+ self.set_color_sample()
- Query for name and location of new help sources and add
- them to the list.
+ def set_color_sample_binding(self, *args):
+ """Change color sample based on foreground/background toggle.
+
+ Methods:
+ set_color_sample
"""
- help_source = HelpSource(self, 'New Help Source').result
- if help_source:
- self.user_helplist.append(help_source)
- self.helplist.insert(END, help_source[0])
- self.update_help_changes()
+ self.set_color_sample()
- def helplist_item_edit(self):
- """Handle edit button for the help list.
+ def set_color_sample(self):
+ """Set the color of the frame background to reflect the selected target.
- Query with existing help source information and update
- config if the values are changed.
+ Instance variables accessed:
+ theme_elements
+ highlight_target
+ fg_bg_toggle
+ highlight_sample
+
+ Attributes updated:
+ frame_color_set
"""
- item_index = self.helplist.index(ANCHOR)
- help_source = self.user_helplist[item_index]
- new_help_source = HelpSource(
- self, 'Edit Help Source',
- menuitem=help_source[0],
- filepath=help_source[1],
- ).result
- if new_help_source and new_help_source != help_source:
- self.user_helplist[item_index] = new_help_source
- self.helplist.delete(item_index)
- self.helplist.insert(item_index, new_help_source[0])
- self.update_help_changes()
- self.set_add_delete_state() # Selected will be un-selected
+ # Set the color sample area.
+ tag = self.theme_elements[self.highlight_target.get()][0]
+ plane = 'foreground' if self.fg_bg_toggle.get() else 'background'
+ color = self.highlight_sample.tag_cget(tag, plane)
+ self.frame_color_set.config(bg=color)
- def helplist_item_remove(self):
- """Handle remove button for the help list.
+ def paint_theme_sample(self):
+ """Apply the theme colors to each element tag in the sample text.
- Delete the help list item from config.
+ Instance attributes accessed:
+ theme_elements
+ is_builtin_theme
+ builtin_theme
+ custom_theme
+
+ Attributes updated:
+ highlight_sample: Set the tag elements to the theme.
+
+ Methods:
+ set_color_sample
+
+ Called from:
+ var_changed_builtin_theme
+ var_changed_custom_theme
+ load_theme_cfg
"""
- item_index = self.helplist.index(ANCHOR)
- del(self.user_helplist[item_index])
- self.helplist.delete(item_index)
- self.update_help_changes()
- self.set_add_delete_state()
+ if self.is_builtin_theme.get(): # Default theme
+ theme = self.builtin_theme.get()
+ else: # User theme
+ theme = self.custom_theme.get()
+ for element_title in self.theme_elements:
+ element = self.theme_elements[element_title][0]
+ colors = idleConf.GetHighlight(theme, element)
+ if element == 'cursor': # Cursor sample needs special painting.
+ colors['background'] = idleConf.GetHighlight(
+ theme, 'normal', fgBg='bg')
+ # Handle any unsaved changes to this theme.
+ if theme in changes['highlight']:
+ theme_dict = changes['highlight'][theme]
+ if element + '-foreground' in theme_dict:
+ colors['foreground'] = theme_dict[element + '-foreground']
+ if element + '-background' in theme_dict:
+ colors['background'] = theme_dict[element + '-background']
+ self.highlight_sample.tag_config(element, **colors)
+ self.set_color_sample()
- def update_help_changes(self):
- "Clear and rebuild the HelpFiles section in changes"
- changes['main']['HelpFiles'] = {}
- for num in range(1, len(self.user_helplist) + 1):
- changes.add_option(
- 'main', 'HelpFiles', str(num),
- ';'.join(self.user_helplist[num-1][:2]))
+ def save_new_theme(self, theme_name, theme):
+ """Save a newly created theme to idleConf.
+
+ theme_name - string, the name of the new theme
+ theme - dictionary containing the new theme
+ """
+ if not idleConf.userCfg['highlight'].has_section(theme_name):
+ idleConf.userCfg['highlight'].add_section(theme_name)
+ for element in theme:
+ value = theme[element]
+ idleConf.userCfg['highlight'].SetOption(theme_name, element, value)
+
+ def delete_custom_theme(self):
+ """Handle event to delete custom theme.
+
+ The current theme is deactivated and the default theme is
+ activated. The custom theme is permanently removed from
+ the config file.
+ Attributes accessed:
+ custom_theme
+
+ Attributes updated:
+ radio_theme_custom
+ opt_menu_theme_custom
+ is_builtin_theme
+ builtin_theme
+
+ Methods:
+ deactivate_current_config
+ save_all_changed_extensions
+ activate_config_changes
+ set_theme_type
+ """
+ theme_name = self.custom_theme.get()
+ delmsg = 'Are you sure you wish to delete the theme %r ?'
+ if not tkMessageBox.askyesno(
+ 'Delete Theme', delmsg % theme_name, parent=self):
+ return
+ self.deactivate_current_config()
+ # Remove theme from changes, config, and file.
+ changes.delete_section('highlight', theme_name)
+ # Reload user theme list.
+ item_list = idleConf.GetSectionList('user', 'highlight')
+ item_list.sort()
+ if not item_list:
+ self.radio_theme_custom['state'] = DISABLED
+ self.opt_menu_theme_custom.SetMenu(item_list, '- no custom themes -')
+ else:
+ self.opt_menu_theme_custom.SetMenu(item_list, item_list[0])
+ # Revert to default theme.
+ 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.
+ changes.save_all()
+ self.save_all_changed_extensions()
+ self.activate_config_changes()
+ self.set_theme_type()
- 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)
- 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)
- 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.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,):
- var.trace_remove('write', var.trace_info()[0][1])
+ def create_page_keys(self):
+ """Return frame of widgets for Keys tab.
- def var_changed_color(self, *params):
- "Process change to color choice."
- self.on_new_color_set()
+ Tk Variables:
+ builtin_keys: Menu variable for built-in keybindings.
+ custom_keys: Menu variable for custom keybindings.
+ are_keys_builtin: Selector for built-in or custom keybindings.
+ keybinding: Action/key bindings.
- def var_changed_builtin_theme(self, *params):
- """Process new builtin theme selection.
+ Methods:
+ load_key_config: Set table.
+ load_keys_list: Reload active set.
+ keybinding_selected: Bound to list_bindings button release.
+ get_new_keys: Command for button_new_keys.
+ get_new_keys_name: Call popup.
+ create_new_key_set: Combine active keyset and changes.
+ set_keys_type: Command for are_keys_builtin.
+ delete_custom_keys: Command for button_delete_custom_keys.
+ save_as_new_key_set: Command for button_save_custom_keys.
+ save_new_key_set: Save to idleConf.userCfg['keys'] (is function).
+ deactivate_current_config: Remove keys bindings in editors.
- Add the changed theme's name to the changed_items and recreate
- the sample with the values from the selected theme.
+ Widget Structure: (*) widgets bound to self
+ frame
+ frame_custom: LabelFrame
+ frame_target: Frame
+ target_title: Label
+ scroll_target_y: Scrollbar
+ scroll_target_x: Scrollbar
+ (*)list_bindings: ListBox
+ (*)button_new_keys: Button
+ frame_key_sets: LabelFrame
+ frames[0]: Frame
+ (*)radio_keys_builtin: Radiobutton - are_keys_builtin
+ (*)radio_keys_custom: Radiobutton - are_keys_builtin
+ (*)opt_menu_keys_builtin: DynOptionMenu - builtin_keys
+ (*)opt_menu_keys_custom: DynOptionMenu - custom_keys
+ (*)new_custom_keys: Label
+ frames[1]: Frame
+ (*)button_delete_custom_keys: Button
+ button_save_custom_keys: Button
"""
- old_themes = ('IDLE Classic', 'IDLE New')
- value = self.builtin_theme.get()
- if value 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', 'name2', value)
- self.new_custom_theme.config(text='New theme, see Help',
- fg='#500000')
- else:
- 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()
+ parent = self.parent
+ self.builtin_keys = StringVar(parent)
+ self.custom_keys = StringVar(parent)
+ self.are_keys_builtin = BooleanVar(parent)
+ self.keybinding = StringVar(parent)
- def var_changed_custom_theme(self, *params):
- """Process new custom theme selection.
+ ##widget creation
+ #body frame
+ frame = self.tab_pages.pages['Keys'].frame
+ #body section frames
+ frame_custom = LabelFrame(
+ frame, borderwidth=2, relief=GROOVE,
+ text=' Custom Key Bindings ')
+ frame_key_sets = LabelFrame(
+ frame, borderwidth=2, relief=GROOVE, text=' Key Set ')
+ #frame_custom
+ frame_target = Frame(frame_custom)
+ target_title = Label(frame_target, text='Action - Key(s)')
+ scroll_target_y = Scrollbar(frame_target)
+ scroll_target_x = Scrollbar(frame_target, orient=HORIZONTAL)
+ self.list_bindings = Listbox(
+ frame_target, takefocus=FALSE, exportselection=FALSE)
+ self.list_bindings.bind('<ButtonRelease-1>', self.keybinding_selected)
+ scroll_target_y.config(command=self.list_bindings.yview)
+ scroll_target_x.config(command=self.list_bindings.xview)
+ self.list_bindings.config(yscrollcommand=scroll_target_y.set)
+ self.list_bindings.config(xscrollcommand=scroll_target_x.set)
+ self.button_new_keys = Button(
+ frame_custom, text='Get New Keys for Selection',
+ command=self.get_new_keys, state=DISABLED)
+ #frame_key_sets
+ frames = [Frame(frame_key_sets, padx=2, pady=2, borderwidth=0)
+ for i in range(2)]
+ self.radio_keys_builtin = Radiobutton(
+ frames[0], variable=self.are_keys_builtin, value=1,
+ command=self.set_keys_type, text='Use a Built-in Key Set')
+ self.radio_keys_custom = Radiobutton(
+ frames[0], variable=self.are_keys_builtin, value=0,
+ command=self.set_keys_type, text='Use a Custom Key Set')
+ self.opt_menu_keys_builtin = DynOptionMenu(
+ frames[0], self.builtin_keys, None, command=None)
+ self.opt_menu_keys_custom = DynOptionMenu(
+ frames[0], self.custom_keys, None, command=None)
+ self.button_delete_custom_keys = Button(
+ frames[1], text='Delete Custom Key Set',
+ command=self.delete_custom_keys)
+ button_save_custom_keys = Button(
+ frames[1], text='Save as New Custom Key Set',
+ command=self.save_as_new_key_set)
+ self.new_custom_keys = Label(frames[0], bd=2)
- If a new custom theme is selected, add the name to the
- changed_items and apply the theme to the sample.
- """
- value = self.custom_theme.get()
- if value != '- no custom themes -':
- changes.add_option('main', 'Theme', 'name', value)
- self.paint_theme_sample()
+ ##widget packing
+ #body
+ frame_custom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH)
+ frame_key_sets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH)
+ #frame_custom
+ self.button_new_keys.pack(side=BOTTOM, fill=X, padx=5, pady=5)
+ frame_target.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
+ #frame target
+ frame_target.columnconfigure(0, weight=1)
+ frame_target.rowconfigure(1, weight=1)
+ target_title.grid(row=0, column=0, columnspan=2, sticky=W)
+ self.list_bindings.grid(row=1, column=0, sticky=NSEW)
+ scroll_target_y.grid(row=1, column=1, sticky=NS)
+ scroll_target_x.grid(row=2, column=0, sticky=EW)
+ #frame_key_sets
+ self.radio_keys_builtin.grid(row=0, column=0, sticky=W+NS)
+ self.radio_keys_custom.grid(row=1, column=0, sticky=W+NS)
+ self.opt_menu_keys_builtin.grid(row=0, column=1, sticky=NSEW)
+ self.opt_menu_keys_custom.grid(row=1, column=1, sticky=NSEW)
+ self.new_custom_keys.grid(row=0, column=2, sticky=NSEW, padx=5, pady=5)
+ self.button_delete_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
+ button_save_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
+ frames[0].pack(side=TOP, fill=BOTH, expand=True)
+ frames[1].pack(side=TOP, fill=X, expand=True, pady=2)
+ return frame
- def var_changed_is_builtin_theme(self, *params):
- """Process toggle between builtin and custom theme.
+ def load_key_cfg(self):
+ "Load current configuration settings for the keybinding options."
+ # Set current keys type radiobutton.
+ self.are_keys_builtin.set(idleConf.GetOption(
+ 'main', 'Keys', 'default', type='bool', default=1))
+ # Set current keys.
+ current_option = idleConf.CurrentKeys()
+ # Load available keyset option menus.
+ if self.are_keys_builtin.get(): # Default theme selected.
+ item_list = idleConf.GetSectionList('default', 'keys')
+ item_list.sort()
+ self.opt_menu_keys_builtin.SetMenu(item_list, current_option)
+ item_list = idleConf.GetSectionList('user', 'keys')
+ item_list.sort()
+ if not item_list:
+ self.radio_keys_custom['state'] = DISABLED
+ self.custom_keys.set('- no custom keys -')
+ else:
+ self.opt_menu_keys_custom.SetMenu(item_list, item_list[0])
+ else: # User key set selected.
+ item_list = idleConf.GetSectionList('user', 'keys')
+ item_list.sort()
+ self.opt_menu_keys_custom.SetMenu(item_list, current_option)
+ item_list = idleConf.GetSectionList('default', 'keys')
+ item_list.sort()
+ self.opt_menu_keys_builtin.SetMenu(item_list, idleConf.default_keys())
+ self.set_keys_type()
+ # Load keyset element list.
+ keyset_name = idleConf.CurrentKeys()
+ self.load_keys_list(keyset_name)
- Update the default toggle value and apply the newly
- selected theme type.
- """
- value = self.is_builtin_theme.get()
- changes.add_option('main', 'Theme', 'default', value)
- if value:
- self.var_changed_builtin_theme()
- else:
- self.var_changed_custom_theme()
- def var_changed_highlight_target(self, *params):
- "Process selection of new target tag for highlighting."
- self.set_highlight_target()
- def var_changed_keybinding(self, *params):
- "Store change to a keybinding."
- value = self.keybinding.get()
- key_set = self.custom_keys.get()
- event = self.list_bindings.get(ANCHOR).split()[0]
- if idleConf.IsCoreBinding(event):
- 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'
- changes.add_option('extensions', ext_keybind_section, event, value)
def var_changed_builtin_keys(self, *params):
"Process selection of builtin key set."
def var_changed_custom_keys(self, *params):
"Process selection of custom key set."
value = self.custom_keys.get()
- if value != '- no custom keys -':
- 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()
- changes.add_option('main', 'Keys', 'default', value)
- if value:
- self.var_changed_builtin_keys()
- else:
- self.var_changed_custom_keys()
-
- def set_theme_type(self):
- """Set available screen options based on builtin or custom theme.
-
- Attributes accessed:
- is_builtin_theme
-
- Attributes updated:
- opt_menu_theme_builtin
- opt_menu_theme_custom
- button_delete_custom_theme
- radio_theme_custom
+ if value != '- no custom keys -':
+ changes.add_option('main', 'Keys', 'name', value)
+ self.load_keys_list(value)
- Called from:
- handler for radio_theme_builtin and radio_theme_custom
- delete_custom_theme
- create_new_theme
- load_theme_cfg
- """
- if self.is_builtin_theme.get():
- self.opt_menu_theme_builtin['state'] = NORMAL
- self.opt_menu_theme_custom['state'] = DISABLED
- self.button_delete_custom_theme['state'] = DISABLED
+ def var_changed_are_keys_builtin(self, *params):
+ "Process toggle between builtin key set and custom key set."
+ value = self.are_keys_builtin.get()
+ changes.add_option('main', 'Keys', 'default', value)
+ if value:
+ self.var_changed_builtin_keys()
else:
- self.opt_menu_theme_builtin['state'] = DISABLED
- self.radio_theme_custom['state'] = NORMAL
- self.opt_menu_theme_custom['state'] = NORMAL
- self.button_delete_custom_theme['state'] = NORMAL
+ self.var_changed_custom_keys()
+
+ def var_changed_keybinding(self, *params):
+ "Store change to a keybinding."
+ value = self.keybinding.get()
+ key_set = self.custom_keys.get()
+ event = self.list_bindings.get(ANCHOR).split()[0]
+ if idleConf.IsCoreBinding(event):
+ 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'
+ changes.add_option('extensions', ext_keybind_section, event, value)
def set_keys_type(self):
"Set available screen options based on builtin or custom key set."
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)
- self.list_bindings.select_set(list_index)
- self.list_bindings.select_anchor(list_index)
-
- def delete_custom_keys(self):
- """Handle event to delete a custom key set.
-
- Applying the delete deactivates the current configuration and
- reverts to the default. The custom key set is permanently
- deleted from the config file.
- """
- keyset_name=self.custom_keys.get()
- delmsg = 'Are you sure you wish to delete the key set %r ?'
- if not tkMessageBox.askyesno(
- 'Delete Key Set', delmsg % keyset_name, parent=self):
- return
- self.deactivate_current_config()
- # Remove key set from changes, config, and file.
- changes.delete_section('keys', keyset_name)
- # Reload user key set list.
- item_list = idleConf.GetSectionList('user', 'keys')
- item_list.sort()
- if not item_list:
- self.radio_keys_custom['state'] = DISABLED
- self.opt_menu_keys_custom.SetMenu(item_list, '- no custom keys -')
- else:
- self.opt_menu_keys_custom.SetMenu(item_list, item_list[0])
- # Revert to default key set.
- self.are_keys_builtin.set(idleConf.defaultCfg['main']
- .Get('Keys', 'default'))
- 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.
- changes.save_all()
- self.save_all_changed_extensions()
- self.activate_config_changes()
- self.set_keys_type()
-
- def delete_custom_theme(self):
- """Handle event to delete custom theme.
-
- The current theme is deactivated and the default theme is
- activated. The custom theme is permanently removed from
- the config file.
-
- Attributes accessed:
- custom_theme
-
- Attributes updated:
- radio_theme_custom
- opt_menu_theme_custom
- is_builtin_theme
- builtin_theme
-
- Methods:
- deactivate_current_config
- save_all_changed_extensions
- activate_config_changes
- set_theme_type
- """
- theme_name = self.custom_theme.get()
- delmsg = 'Are you sure you wish to delete the theme %r ?'
- if not tkMessageBox.askyesno(
- 'Delete Theme', delmsg % theme_name, parent=self):
- return
- self.deactivate_current_config()
- # Remove theme from changes, config, and file.
- changes.delete_section('highlight', theme_name)
- # Reload user theme list.
- item_list = idleConf.GetSectionList('user', 'highlight')
- item_list.sort()
- if not item_list:
- self.radio_theme_custom['state'] = DISABLED
- self.opt_menu_theme_custom.SetMenu(item_list, '- no custom themes -')
- else:
- self.opt_menu_theme_custom.SetMenu(item_list, item_list[0])
- # Revert to default theme.
- 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.
- changes.save_all()
- self.save_all_changed_extensions()
- self.activate_config_changes()
- self.set_theme_type()
-
- def get_color(self):
- """Handle button to select a new color for the target tag.
-
- If a new color is selected while using a builtin theme, a
- name must be supplied to create a custom theme.
-
- Attributes accessed:
- highlight_target
- frame_color_set
- is_builtin_theme
-
- Attributes updated:
- color
-
- Methods:
- get_new_theme_name
- create_new_theme
- """
- target = self.highlight_target.get()
- prev_color = self.frame_color_set.cget('bg')
- rgbTuplet, color_string = tkColorChooser.askcolor(
- parent=self, title='Pick new color for : '+target,
- initialcolor=prev_color)
- if color_string and (color_string != prev_color):
- # User didn't cancel and they chose a new color.
- if self.is_builtin_theme.get(): # Current theme is a built-in.
- message = ('Your changes will be saved as a new Custom Theme. '
- 'Enter a name for your new Custom Theme below.')
- new_theme = self.get_new_theme_name(message)
- if not new_theme: # User cancelled custom theme creation.
- return
- else: # Create new custom theme based on previously active theme.
- self.create_new_theme(new_theme)
- self.color.set(color_string)
- else: # Current theme is user defined.
- self.color.set(color_string)
-
- def on_new_color_set(self):
- "Display sample of new color selection on the dialog."
- new_color=self.color.get()
- self.frame_color_set.config(bg=new_color) # Set sample.
- plane ='foreground' if self.fg_bg_toggle.get() else 'background'
- sample_element = self.theme_elements[self.highlight_target.get()][0]
- self.highlight_sample.tag_config(sample_element, **{plane:new_color})
- theme = self.custom_theme.get()
- theme_element = sample_element + '-' + plane
- changes.add_option('highlight', theme, theme_element, new_color)
-
- def get_new_theme_name(self, message):
- "Return name of new theme from query popup."
- used_names = (idleConf.GetSectionList('user', 'highlight') +
- idleConf.GetSectionList('default', 'highlight'))
- new_theme = SectionName(
- self, 'New Custom Theme', message, used_names).result
- return new_theme
-
- def save_as_new_theme(self):
- """Prompt for new theme name and create the theme.
-
- Methods:
- get_new_theme_name
- create_new_theme
- """
- new_theme_name = self.get_new_theme_name('New Theme Name:')
- if new_theme_name:
- self.create_new_theme(new_theme_name)
-
- def create_new_theme(self, new_theme_name):
- """Create a new custom theme with the given name.
-
- Create the new theme based on the previously active theme
- with the current changes applied. Once it is saved, then
- activate the new theme.
-
- Attributes accessed:
- builtin_theme
- custom_theme
-
- Attributes updated:
- opt_menu_theme_custom
- is_builtin_theme
-
- Method:
- save_new_theme
- set_theme_type
- """
- if self.is_builtin_theme.get():
- theme_type = 'default'
- theme_name = self.builtin_theme.get()
- else:
- theme_type = 'user'
- 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 changes['highlight']:
- theme_changes = changes['highlight'][theme_name]
- for element in theme_changes:
- new_theme[element] = theme_changes[element]
- # Save the new theme.
- self.save_new_theme(new_theme_name, new_theme)
- # Change GUI over to the new theme.
- custom_theme_list = idleConf.GetSectionList('user', 'highlight')
- custom_theme_list.sort()
- self.opt_menu_theme_custom.SetMenu(custom_theme_list, new_theme_name)
- self.is_builtin_theme.set(0)
- self.set_theme_type()
-
- def set_highlight_target(self):
- """Set fg/bg toggle and color based on highlight tag target.
-
- Instance variables accessed:
- highlight_target
-
- Attributes updated:
- radio_fg
- radio_bg
- fg_bg_toggle
-
- Methods:
- set_color_sample
-
- Called from:
- var_changed_highlight_target
- load_theme_cfg
- """
- if self.highlight_target.get() == 'Cursor': # bg not possible
- self.radio_fg['state'] = DISABLED
- self.radio_bg['state'] = DISABLED
- self.fg_bg_toggle.set(1)
- else: # Both fg and bg can be set.
- self.radio_fg['state'] = NORMAL
- self.radio_bg['state'] = NORMAL
- self.fg_bg_toggle.set(1)
- self.set_color_sample()
+ if reselect:
+ self.list_bindings.see(list_index)
+ self.list_bindings.select_set(list_index)
+ self.list_bindings.select_anchor(list_index)
- def set_color_sample_binding(self, *args):
- """Change color sample based on foreground/background toggle.
+ def save_new_key_set(self, keyset_name, keyset):
+ """Save a newly created core key set.
- Methods:
- set_color_sample
+ keyset_name - string, the name of the new key set
+ keyset - dictionary containing the new key set
"""
- self.set_color_sample()
-
- def set_color_sample(self):
- """Set the color of the frame background to reflect the selected target.
+ if not idleConf.userCfg['keys'].has_section(keyset_name):
+ idleConf.userCfg['keys'].add_section(keyset_name)
+ for event in keyset:
+ value = keyset[event]
+ idleConf.userCfg['keys'].SetOption(keyset_name, event, value)
- Instance variables accessed:
- theme_elements
- highlight_target
- fg_bg_toggle
- highlight_sample
+ def delete_custom_keys(self):
+ """Handle event to delete a custom key set.
- Attributes updated:
- frame_color_set
+ Applying the delete deactivates the current configuration and
+ reverts to the default. The custom key set is permanently
+ deleted from the config file.
"""
- # Set the color sample area.
- tag = self.theme_elements[self.highlight_target.get()][0]
- plane = 'foreground' if self.fg_bg_toggle.get() else 'background'
- color = self.highlight_sample.tag_cget(tag, plane)
- self.frame_color_set.config(bg=color)
-
- def paint_theme_sample(self):
- """Apply the theme colors to each element tag in the sample text.
+ keyset_name=self.custom_keys.get()
+ delmsg = 'Are you sure you wish to delete the key set %r ?'
+ if not tkMessageBox.askyesno(
+ 'Delete Key Set', delmsg % keyset_name, parent=self):
+ return
+ self.deactivate_current_config()
+ # Remove key set from changes, config, and file.
+ changes.delete_section('keys', keyset_name)
+ # Reload user key set list.
+ item_list = idleConf.GetSectionList('user', 'keys')
+ item_list.sort()
+ if not item_list:
+ self.radio_keys_custom['state'] = DISABLED
+ self.opt_menu_keys_custom.SetMenu(item_list, '- no custom keys -')
+ else:
+ self.opt_menu_keys_custom.SetMenu(item_list, item_list[0])
+ # Revert to default key set.
+ self.are_keys_builtin.set(idleConf.defaultCfg['main']
+ .Get('Keys', 'default'))
+ 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.
+ changes.save_all()
+ self.save_all_changed_extensions()
+ self.activate_config_changes()
+ self.set_keys_type()
- Instance attributes accessed:
- theme_elements
- is_builtin_theme
- builtin_theme
- custom_theme
+ def deactivate_current_config(self):
+ """Remove current key bindings.
- Attributes updated:
- highlight_sample: Set the tag elements to the theme.
+ Iterate over window instances defined in parent and remove
+ the keybindings.
+ """
+ # Before a config is saved, some cleanup of current
+ # config must be done - remove the previous keybindings.
+ win_instances = self.parent.instance_dict.keys()
+ for instance in win_instances:
+ instance.RemoveKeybindings()
- Methods:
- set_color_sample
+ def activate_config_changes(self):
+ """Apply configuration changes to current windows.
- Called from:
- var_changed_builtin_theme
- var_changed_custom_theme
- load_theme_cfg
+ Dynamically update the current parent window instances
+ with some of the configuration changes.
"""
- if self.is_builtin_theme.get(): # Default theme
- theme = self.builtin_theme.get()
- else: # User theme
- theme = self.custom_theme.get()
- for element_title in self.theme_elements:
- element = self.theme_elements[element_title][0]
- colors = idleConf.GetHighlight(theme, element)
- if element == 'cursor': # Cursor sample needs special painting.
- colors['background'] = idleConf.GetHighlight(
- theme, 'normal', fgBg='bg')
- # Handle any unsaved changes to this theme.
- if theme in changes['highlight']:
- theme_dict = changes['highlight'][theme]
- if element + '-foreground' in theme_dict:
- colors['foreground'] = theme_dict[element + '-foreground']
- if element + '-background' in theme_dict:
- colors['background'] = theme_dict[element + '-background']
- self.highlight_sample.tag_config(element, **colors)
- self.set_color_sample()
-
- def load_theme_cfg(self):
- """Load current configuration settings for the theme options.
+ win_instances = self.parent.instance_dict.keys()
+ for instance in win_instances:
+ instance.ResetColorizer()
+ instance.ResetFont()
+ instance.set_notabs_indentwidth()
+ instance.ApplyKeybindings()
+ instance.reset_help_menu_entries()
- Based on the is_builtin_theme toggle, the theme is set as
- either builtin or custom and the initial widget values
- reflect the current settings from idleConf.
- Attributes updated:
- is_builtin_theme: Set from idleConf.
- opt_menu_theme_builtin: List of default themes from idleConf.
- opt_menu_theme_custom: List of custom themes from idleConf.
- radio_theme_custom: Disabled if there are no custom themes.
- custom_theme: Message with additional information.
- opt_menu_highlight_target: Create menu from self.theme_elements.
+ def create_page_general(self):
+ """Return frame of widgets for General tab.
- Methods:
- set_theme_type
- paint_theme_sample
- set_highlight_target
- """
- # Set current theme type radiobutton.
- self.is_builtin_theme.set(idleConf.GetOption(
- 'main', 'Theme', 'default', type='bool', default=1))
- # Set current theme.
- current_option = idleConf.CurrentTheme()
- # Load available theme option menus.
- if self.is_builtin_theme.get(): # Default theme selected.
- item_list = idleConf.GetSectionList('default', 'highlight')
- item_list.sort()
- self.opt_menu_theme_builtin.SetMenu(item_list, current_option)
- item_list = idleConf.GetSectionList('user', 'highlight')
- item_list.sort()
- if not item_list:
- self.radio_theme_custom['state'] = DISABLED
- self.custom_theme.set('- no custom themes -')
- else:
- self.opt_menu_theme_custom.SetMenu(item_list, item_list[0])
- else: # User theme selected.
- item_list = idleConf.GetSectionList('user', 'highlight')
- item_list.sort()
- self.opt_menu_theme_custom.SetMenu(item_list, current_option)
- item_list = idleConf.GetSectionList('default', 'highlight')
- item_list.sort()
- self.opt_menu_theme_builtin.SetMenu(item_list, item_list[0])
- self.set_theme_type()
- # Load theme element option menu.
- theme_names = list(self.theme_elements.keys())
- theme_names.sort(key=lambda x: self.theme_elements[x][1])
- self.opt_menu_highlight_target.SetMenu(theme_names, theme_names[0])
- self.paint_theme_sample()
- self.set_highlight_target()
+ Enable users to provisionally change general options. Function
+ load_general_cfg intializes 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
+ var_changed_var_name callback that adds option to changes.
- def load_key_cfg(self):
- "Load current configuration settings for the keybinding options."
- # Set current keys type radiobutton.
- self.are_keys_builtin.set(idleConf.GetOption(
- 'main', 'Keys', 'default', type='bool', default=1))
- # Set current keys.
- current_option = idleConf.CurrentKeys()
- # Load available keyset option menus.
- if self.are_keys_builtin.get(): # Default theme selected.
- item_list = idleConf.GetSectionList('default', 'keys')
- item_list.sort()
- self.opt_menu_keys_builtin.SetMenu(item_list, current_option)
- item_list = idleConf.GetSectionList('user', 'keys')
- item_list.sort()
- if not item_list:
- self.radio_keys_custom['state'] = DISABLED
- self.custom_keys.set('- no custom keys -')
- else:
- self.opt_menu_keys_custom.SetMenu(item_list, item_list[0])
- else: # User key set selected.
- item_list = idleConf.GetSectionList('user', 'keys')
- item_list.sort()
- self.opt_menu_keys_custom.SetMenu(item_list, current_option)
- item_list = idleConf.GetSectionList('default', 'keys')
- item_list.sort()
- self.opt_menu_keys_builtin.SetMenu(item_list, idleConf.default_keys())
- self.set_keys_type()
- # Load keyset element list.
- keyset_name = idleConf.CurrentKeys()
- self.load_keys_list(keyset_name)
+ 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'].
- def load_configs(self):
- """Load configuration for each page.
+ Widget Structure: (*) widgets bound to self
+ frame
+ frame_run: LabelFrame
+ startup_title: Label
+ (*)startup_editor_on: Radiobutton - startup_edit
+ (*)startup_shell_on: Radiobutton - startup_edit
+ frame_save: LabelFrame
+ run_save_title: Label
+ (*)save_ask_on: Radiobutton - autosave
+ (*)save_auto_on: Radiobutton - autosave
+ frame_win_size: LabelFrame
+ win_size_title: Label
+ win_width_title: Label
+ (*)win_width_int: Entry - win_width
+ win_height_title: Label
+ (*)win_height_int: Entry - win_height
+ frame_help: LabelFrame
+ frame_helplist: Frame
+ frame_helplist_buttons: Frame
+ (*)button_helplist_edit
+ (*)button_helplist_add
+ (*)button_helplist_remove
+ (*)helplist: ListBox
+ 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)
- Load configuration from default and user config files and populate
- the widgets on the config dialog pages.
+ # Create widgets:
+ # body.
+ frame = self.tab_pages.pages['General'].frame
+ # body section frames.
+ frame_run = LabelFrame(frame, borderwidth=2, relief=GROOVE,
+ text=' Startup Preferences ')
+ frame_save = LabelFrame(frame, borderwidth=2, relief=GROOVE,
+ text=' autosave Preferences ')
+ frame_win_size = Frame(frame, borderwidth=2, relief=GROOVE)
+ frame_help = LabelFrame(frame, borderwidth=2, relief=GROOVE,
+ text=' Additional Help Sources ')
+ # frame_run.
+ startup_title = Label(frame_run, text='At Startup')
+ self.startup_editor_on = Radiobutton(
+ frame_run, variable=self.startup_edit, value=1,
+ text="Open Edit Window")
+ self.startup_shell_on = Radiobutton(
+ frame_run, variable=self.startup_edit, value=0,
+ text='Open Shell Window')
+ # frame_save.
+ 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_win_size.
+ win_size_title = Label(
+ frame_win_size, text='Initial Window Size (in characters)')
+ win_width_title = Label(frame_win_size, text='Width')
+ self.win_width_int = Entry(
+ frame_win_size, textvariable=self.win_width, width=3)
+ win_height_title = Label(frame_win_size, text='Height')
+ self.win_height_int = Entry(
+ frame_win_size, textvariable=self.win_height, width=3)
+ # frame_help.
+ frame_helplist = Frame(frame_help)
+ frame_helplist_buttons = Frame(frame_helplist)
+ self.helplist = Listbox(
+ frame_helplist, height=5, takefocus=FALSE,
+ exportselection=FALSE)
+ scroll_helplist = Scrollbar(frame_helplist)
+ scroll_helplist['command'] = self.helplist.yview
+ self.helplist['yscrollcommand'] = scroll_helplist.set
+ self.helplist.bind('<ButtonRelease-1>', self.help_source_selected)
+ self.button_helplist_edit = Button(
+ frame_helplist_buttons, text='Edit', state=DISABLED,
+ width=8, command=self.helplist_item_edit)
+ self.button_helplist_add = Button(
+ frame_helplist_buttons, text='Add',
+ width=8, command=self.helplist_item_add)
+ self.button_helplist_remove = Button(
+ frame_helplist_buttons, text='Remove', state=DISABLED,
+ width=8, command=self.helplist_item_remove)
- Methods:
- load_font_cfg
- load_tab_cfg
- load_theme_cfg
- load_key_cfg
- load_general_cfg
- """
- self.load_font_cfg()
- self.load_tab_cfg()
- self.load_theme_cfg()
- self.load_key_cfg()
- self.load_general_cfg()
- # note: extension page handled separately
+ # Pack widgets:
+ # body.
+ frame_run.pack(side=TOP, padx=5, pady=5, fill=X)
+ frame_save.pack(side=TOP, padx=5, pady=5, fill=X)
+ frame_win_size.pack(side=TOP, padx=5, pady=5, fill=X)
+ frame_help.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
+ # frame_run.
+ startup_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+ self.startup_shell_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
+ self.startup_editor_on.pack(side=RIGHT, anchor=W, padx=5, pady=5)
+ # frame_save.
+ 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_win_size.
+ win_size_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+ self.win_height_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)
+ win_height_title.pack(side=RIGHT, anchor=E, pady=5)
+ self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)
+ win_width_title.pack(side=RIGHT, anchor=E, pady=5)
+ # frame_help.
+ frame_helplist_buttons.pack(side=RIGHT, padx=5, pady=5, fill=Y)
+ frame_helplist.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
+ scroll_helplist.pack(side=RIGHT, anchor=W, fill=Y)
+ self.helplist.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)
+ self.button_helplist_edit.pack(side=TOP, anchor=W, pady=5)
+ self.button_helplist_add.pack(side=TOP, anchor=W)
+ self.button_helplist_remove.pack(side=TOP, anchor=W, pady=5)
- def save_new_key_set(self, keyset_name, keyset):
- """Save a newly created core key set.
+ return frame
- keyset_name - string, the name of the new key set
- keyset - dictionary containing the new key set
- """
- if not idleConf.userCfg['keys'].has_section(keyset_name):
- idleConf.userCfg['keys'].add_section(keyset_name)
- for event in keyset:
- value = keyset[event]
- idleConf.userCfg['keys'].SetOption(keyset_name, event, value)
+ def load_general_cfg(self):
+ "Load current configuration settings for the general options."
+ # Set startup state.
+ self.startup_edit.set(idleConf.GetOption(
+ 'main', 'General', 'editor-on-startup', default=0, type='bool'))
+ # Set autosave state.
+ self.autosave.set(idleConf.GetOption(
+ 'main', 'General', 'autosave', default=0, type='bool'))
+ # Set initial window size.
+ self.win_width.set(idleConf.GetOption(
+ 'main', 'EditorWindow', 'width', type='int'))
+ self.win_height.set(idleConf.GetOption(
+ 'main', 'EditorWindow', 'height', type='int'))
+ # Set additional help sources.
+ self.user_helplist = idleConf.GetAllExtraHelpSourcesList()
+ self.helplist.delete(0, 'end')
+ for help_item in self.user_helplist:
+ self.helplist.insert(END, help_item[0])
+ self.set_add_delete_state()
- def save_new_theme(self, theme_name, theme):
- """Save a newly created theme to idleConf.
+ def var_changed_startup_edit(self, *params):
+ "Store change to toggle for starting IDLE in the editor or shell."
+ value = self.startup_edit.get()
+ changes.add_option('main', 'General', 'editor-on-startup', value)
- theme_name - string, the name of the new theme
- theme - dictionary containing the new theme
- """
- if not idleConf.userCfg['highlight'].has_section(theme_name):
- idleConf.userCfg['highlight'].add_section(theme_name)
- for element in theme:
- value = theme[element]
- idleConf.userCfg['highlight'].SetOption(theme_name, element, value)
+ def var_changed_autosave(self, *params):
+ "Store change to autosave."
+ value = self.autosave.get()
+ changes.add_option('main', 'General', 'autosave', value)
- def deactivate_current_config(self):
- """Remove current key bindings.
+ def var_changed_win_width(self, *params):
+ "Store change to window width."
+ value = self.win_width.get()
+ changes.add_option('main', 'EditorWindow', 'width', value)
- Iterate over window instances defined in parent and remove
- the keybindings.
- """
- # Before a config is saved, some cleanup of current
- # config must be done - remove the previous keybindings.
- win_instances = self.parent.instance_dict.keys()
- for instance in win_instances:
- instance.RemoveKeybindings()
+ def var_changed_win_height(self, *params):
+ "Store change to window height."
+ value = self.win_height.get()
+ changes.add_option('main', 'EditorWindow', 'height', value)
- def activate_config_changes(self):
- """Apply configuration changes to current windows.
+ def help_source_selected(self, event):
+ "Handle event for selecting additional help."
+ self.set_add_delete_state()
- Dynamically update the current parent window instances
- with some of the configuration changes.
- """
- win_instances = self.parent.instance_dict.keys()
- for instance in win_instances:
- instance.ResetColorizer()
- instance.ResetFont()
- instance.set_notabs_indentwidth()
- instance.ApplyKeybindings()
- instance.reset_help_menu_entries()
+ def set_add_delete_state(self):
+ "Toggle the state for the help list buttons based on list entries."
+ if self.helplist.size() < 1: # No entries in list.
+ self.button_helplist_edit['state'] = DISABLED
+ self.button_helplist_remove['state'] = DISABLED
+ else: # Some entries.
+ if self.helplist.curselection(): # There currently is a selection.
+ self.button_helplist_edit['state'] = NORMAL
+ self.button_helplist_remove['state'] = NORMAL
+ else: # There currently is not a selection.
+ self.button_helplist_edit['state'] = DISABLED
+ self.button_helplist_remove['state'] = DISABLED
- def cancel(self):
- """Dismiss config dialog.
+ def helplist_item_add(self):
+ """Handle add button for the help list.
- Methods:
- destroy: inherited
+ Query for name and location of new help sources and add
+ them to the list.
"""
- self.destroy()
+ help_source = HelpSource(self, 'New Help Source').result
+ if help_source:
+ self.user_helplist.append(help_source)
+ self.helplist.insert(END, help_source[0])
+ self.update_help_changes()
- def ok(self):
- """Apply config changes, then dismiss dialog.
+ def helplist_item_edit(self):
+ """Handle edit button for the help list.
- Methods:
- apply
- destroy: inherited
+ Query with existing help source information and update
+ config if the values are changed.
"""
- self.apply()
- self.destroy()
+ item_index = self.helplist.index(ANCHOR)
+ help_source = self.user_helplist[item_index]
+ new_help_source = HelpSource(
+ self, 'Edit Help Source',
+ menuitem=help_source[0],
+ filepath=help_source[1],
+ ).result
+ if new_help_source and new_help_source != help_source:
+ self.user_helplist[item_index] = new_help_source
+ self.helplist.delete(item_index)
+ self.helplist.insert(item_index, new_help_source[0])
+ self.update_help_changes()
+ self.set_add_delete_state() # Selected will be un-selected
- def apply(self):
- """Apply config changes and leave dialog open.
+ def helplist_item_remove(self):
+ """Handle remove button for the help list.
- Methods:
- deactivate_current_config
- save_all_changed_extensions
- activate_config_changes
+ Delete the help list item from config.
"""
- self.deactivate_current_config()
- changes.save_all()
- self.save_all_changed_extensions()
- self.activate_config_changes()
-
- def help(self):
- """Create textview for config dialog help.
+ item_index = self.helplist.index(ANCHOR)
+ del(self.user_helplist[item_index])
+ self.helplist.delete(item_index)
+ self.update_help_changes()
+ self.set_add_delete_state()
- Attrbutes accessed:
- tab_pages
+ def update_help_changes(self):
+ "Clear and rebuild the HelpFiles section in changes"
+ changes['main']['HelpFiles'] = {}
+ for num in range(1, len(self.user_helplist) + 1):
+ changes.add_option(
+ 'main', 'HelpFiles', str(num),
+ ';'.join(self.user_helplist[num-1][:2]))
- Methods:
- view_text: Method from textview module.
- """
- page = self.tab_pages._current_page
- view_text(self, title='Help for IDLE preferences',
- text=help_common+help_pages.get(page, ''))
def create_page_extensions(self):
"""Part of the config dialog used for configuring IDLE extensions.