blob: 112f31c6db56f998b06ac7edabc40b0f7c8670d2 [file] [log] [blame]
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001"""IDLE Configuration Dialog: support user customization of IDLE by GUI
2
3Customize font faces, sizes, and colorization attributes. Set indentation
4defaults. Customize keybindings. Colorization and keybindings can be
5saved as user defined sets. Select startup options including shell/editor
6and default window size. Define additional help sources.
7
8Note that tab width in IDLE is currently fixed at eight due to Tk issues.
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00009Refer to comments in EditorWindow autoindent code for details.
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +000010
Steven M. Gava44d3d1a2001-07-31 06:59:02 +000011"""
Georg Brandl6634bf22008-05-20 07:13:37 +000012from Tkinter import *
13import tkMessageBox, tkColorChooser, tkFont
Steven M. Gava44d3d1a2001-07-31 06:59:02 +000014
Florent Xiclunad630c042010-04-02 07:24:52 +000015from idlelib.configHandler import idleConf
16from idlelib.dynOptionMenuWidget import DynOptionMenu
17from idlelib.tabbedpages import TabbedPageSet
18from idlelib.keybindingDialog import GetKeysDialog
19from idlelib.configSectionNameDialog import GetCfgSectionNameDialog
20from idlelib.configHelpSourceEdit import GetHelpSourceDialog
21from idlelib import macosxSupport
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +000022
Steven M. Gava44d3d1a2001-07-31 06:59:02 +000023class ConfigDialog(Toplevel):
Kurt B. Kaiseracdef852005-01-31 03:34:26 +000024
Terry Jan Reedyaf0dce92014-07-14 23:07:21 -040025 def __init__(self, parent, title, _htest=False, _utest=False):
Terry Jan Reedy76916e82014-05-29 01:46:16 -040026 """
27 _htest - bool, change box location when running htest
Terry Jan Reedyaf0dce92014-07-14 23:07:21 -040028 _utest - bool, don't wait_window when running unittest
Terry Jan Reedy76916e82014-05-29 01:46:16 -040029 """
Steven M. Gavad721c482001-07-31 10:46:53 +000030 Toplevel.__init__(self, parent)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -040031 self.parent = parent
Terry Jan Reedyae410862014-08-03 23:02:53 -040032 if _htest:
33 parent.instance_dict = {}
Kurt B. Kaisere3fde8f2007-10-04 03:11:12 +000034 self.wm_withdraw()
35
Steven M. Gavad721c482001-07-31 10:46:53 +000036 self.configure(borderwidth=5)
Amaury Forgeot d'Arcb9ee8812009-07-15 21:29:27 +000037 self.title('IDLE Preferences')
Terry Jan Reedyae410862014-08-03 23:02:53 -040038 self.geometry(
39 "+%d+%d" % (parent.winfo_rootx() + 20,
40 parent.winfo_rooty() + (30 if not _htest else 150)))
Georg Brandl7eb4b7d2005-07-22 21:49:32 +000041 #Theme Elements. Each theme element key is its display name.
Steven M. Gava9dd16b32001-11-03 14:54:25 +000042 #The first value of the tuple is the sample area tag name.
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000043 #The second value is the display name list sort index.
Terry Jan Reedyae410862014-08-03 23:02:53 -040044 self.themeElements={
45 'Normal Text':('normal', '00'),
46 'Python Keywords':('keyword', '01'),
47 'Python Definitions':('definition', '02'),
Kurt B. Kaiser73360a32004-03-08 18:15:31 +000048 'Python Builtins':('builtin', '03'),
Terry Jan Reedyae410862014-08-03 23:02:53 -040049 'Python Comments':('comment', '04'),
50 'Python Strings':('string', '05'),
51 'Selected Text':('hilite', '06'),
52 'Found Text':('hit', '07'),
53 'Cursor':('cursor', '08'),
54 'Error Text':('error', '09'),
55 'Shell Normal Text':('console', '10'),
56 'Shell Stdout Text':('stdout', '11'),
57 'Shell Stderr Text':('stderr', '12'),
Kurt B. Kaiser73360a32004-03-08 18:15:31 +000058 }
Steven M. Gavaa498af22002-02-01 01:33:36 +000059 self.ResetChangedItems() #load initial values in changed items dict
Steven M. Gavad721c482001-07-31 10:46:53 +000060 self.CreateWidgets()
Terry Jan Reedyae410862014-08-03 23:02:53 -040061 self.resizable(height=FALSE, width=FALSE)
Steven M. Gavad721c482001-07-31 10:46:53 +000062 self.transient(parent)
63 self.grab_set()
64 self.protocol("WM_DELETE_WINDOW", self.Cancel)
Steven M. Gava2d4e03b2001-12-05 07:54:07 +000065 self.tabPages.focus_set()
Steven M. Gavad721c482001-07-31 10:46:53 +000066 #key bindings for this dialog
Terry Jan Reedyae410862014-08-03 23:02:53 -040067 #self.bind('<Escape>', self.Cancel) #dismiss dialog, no save
68 #self.bind('<Alt-a>', self.Apply) #apply changes, save
69 #self.bind('<F1>', self.Help) #context help
Steven M. Gava429a86a2001-10-23 10:42:12 +000070 self.LoadConfigs()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000071 self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
Kurt B. Kaisere3fde8f2007-10-04 03:11:12 +000072
Terry Jan Reedyaf0dce92014-07-14 23:07:21 -040073 if not _utest:
74 self.wm_deiconify()
75 self.wait_window()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000076
Steven M. Gavad721c482001-07-31 10:46:53 +000077 def CreateWidgets(self):
Kurt B. Kaiser20172f92007-10-30 02:38:54 +000078 self.tabPages = TabbedPageSet(self,
Terry Jan Reedyae410862014-08-03 23:02:53 -040079 page_names=['Fonts/Tabs', 'Highlighting', 'Keys', 'General'])
Terry Jan Reedy23030db2014-10-08 20:29:05 -040080 self.tabPages.pack(side=TOP, expand=TRUE, fill=BOTH)
81 self.CreatePageFontTab()
82 self.CreatePageHighlight()
83 self.CreatePageKeys()
84 self.CreatePageGeneral()
85 self.create_action_buttons().pack(side=BOTTOM)
86 Frame(self, height=2, borderwidth=0).pack(side=BOTTOM)
87
88 def create_action_buttons(self):
Ned Deily57847df2014-03-27 20:47:04 -070089 if macosxSupport.isAquaTk():
Ronald Oussorena97063a2009-03-04 21:35:05 +000090 # Changing the default padding on OSX results in unreadable
91 # text in the buttons
Terry Jan Reedyae410862014-08-03 23:02:53 -040092 paddingArgs = {}
Ronald Oussorena97063a2009-03-04 21:35:05 +000093 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -040094 paddingArgs = {'padx':6, 'pady':3}
Ronald Oussorena97063a2009-03-04 21:35:05 +000095
Terry Jan Reedy23030db2014-10-08 20:29:05 -040096 frame = Frame(self, pady=2)
Terry Jan Reedyae410862014-08-03 23:02:53 -040097 self.buttonOk = Button(
Terry Jan Reedy23030db2014-10-08 20:29:05 -040098 frame, text='Ok', command=self.Ok,
99 takefocus=FALSE, **paddingArgs)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400100 self.buttonApply = Button(
Terry Jan Reedy23030db2014-10-08 20:29:05 -0400101 frame, text='Apply', command=self.Apply,
102 takefocus=FALSE, **paddingArgs)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400103 self.buttonCancel = Button(
Terry Jan Reedy23030db2014-10-08 20:29:05 -0400104 frame, text='Cancel', command=self.Cancel,
105 takefocus=FALSE, **paddingArgs)
106# Comment out Help button creation and packing until implement self.Help
107## self.buttonHelp = Button(
108## frame, text='Help', command=self.Help,
109## takefocus=FALSE, **paddingArgs)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400110## self.buttonHelp.pack(side=RIGHT, padx=5)
111 self.buttonOk.pack(side=LEFT, padx=5)
112 self.buttonApply.pack(side=LEFT, padx=5)
113 self.buttonCancel.pack(side=LEFT, padx=5)
Terry Jan Reedy23030db2014-10-08 20:29:05 -0400114 return frame
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000115
Steven M. Gava60fc7072001-08-04 13:58:22 +0000116 def CreatePageFontTab(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400117 parent = self.parent
118 self.fontSize = StringVar(parent)
119 self.fontBold = BooleanVar(parent)
120 self.fontName = StringVar(parent)
121 self.spaceNum = IntVar(parent)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400122 self.editFont = tkFont.Font(parent, ('courier', 10, 'normal'))
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400123
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000124 ##widget creation
125 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400126 frame = self.tabPages.pages['Fonts/Tabs'].frame
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000127 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400128 frameFont = LabelFrame(
129 frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ')
130 frameIndent = LabelFrame(
131 frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ')
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000132 #frameFont
Terry Jan Reedyae410862014-08-03 23:02:53 -0400133 frameFontName = Frame(frameFont)
134 frameFontParam = Frame(frameFont)
135 labelFontNameTitle = Label(
136 frameFontName, justify=LEFT, text='Font Face :')
137 self.listFontName = Listbox(
138 frameFontName, height=5, takefocus=FALSE, exportselection=FALSE)
139 self.listFontName.bind(
140 '<ButtonRelease-1>', self.OnListFontButtonRelease)
141 scrollFont = Scrollbar(frameFontName)
Steven M. Gavac01e30f2001-08-11 15:48:13 +0000142 scrollFont.config(command=self.listFontName.yview)
143 self.listFontName.config(yscrollcommand=scrollFont.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400144 labelFontSizeTitle = Label(frameFontParam, text='Size :')
145 self.optMenuFontSize = DynOptionMenu(
146 frameFontParam, self.fontSize, None, command=self.SetFontSample)
147 checkFontBold = Checkbutton(
148 frameFontParam, variable=self.fontBold, onvalue=1,
149 offvalue=0, text='Bold', command=self.SetFontSample)
150 frameFontSample = Frame(frameFont, relief=SOLID, borderwidth=1)
151 self.labelFontSample = Label(
152 frameFontSample, justify=LEFT, font=self.editFont,
153 text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]')
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000154 #frameIndent
Terry Jan Reedyae410862014-08-03 23:02:53 -0400155 frameIndentSize = Frame(frameIndent)
156 labelSpaceNumTitle = Label(
157 frameIndentSize, justify=LEFT,
158 text='Python Standard: 4 Spaces!')
159 self.scaleSpaceNum = Scale(
160 frameIndentSize, variable=self.spaceNum,
161 orient='horizontal', tickinterval=2, from_=2, to=16)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400162
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000163 #widget packing
164 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400165 frameFont.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
166 frameIndent.pack(side=LEFT, padx=5, pady=5, fill=Y)
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000167 #frameFont
Terry Jan Reedyae410862014-08-03 23:02:53 -0400168 frameFontName.pack(side=TOP, padx=5, pady=5, fill=X)
169 frameFontParam.pack(side=TOP, padx=5, pady=5, fill=X)
170 labelFontNameTitle.pack(side=TOP, anchor=W)
171 self.listFontName.pack(side=LEFT, expand=TRUE, fill=X)
172 scrollFont.pack(side=LEFT, fill=Y)
173 labelFontSizeTitle.pack(side=LEFT, anchor=W)
174 self.optMenuFontSize.pack(side=LEFT, anchor=W)
175 checkFontBold.pack(side=LEFT, anchor=W, padx=20)
176 frameFontSample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
177 self.labelFontSample.pack(expand=TRUE, fill=BOTH)
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000178 #frameIndent
Terry Jan Reedyae410862014-08-03 23:02:53 -0400179 frameIndentSize.pack(side=TOP, fill=X)
180 labelSpaceNumTitle.pack(side=TOP, anchor=W, padx=5)
181 self.scaleSpaceNum.pack(side=TOP, padx=5, fill=X)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000182 return frame
183
184 def CreatePageHighlight(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400185 parent = self.parent
186 self.builtinTheme = StringVar(parent)
187 self.customTheme = StringVar(parent)
188 self.fgHilite = BooleanVar(parent)
189 self.colour = StringVar(parent)
190 self.fontName = StringVar(parent)
191 self.themeIsBuiltin = BooleanVar(parent)
192 self.highlightTarget = StringVar(parent)
193
Steven M. Gava952d0a52001-08-03 04:43:44 +0000194 ##widget creation
195 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400196 frame = self.tabPages.pages['Highlighting'].frame
Steven M. Gava952d0a52001-08-03 04:43:44 +0000197 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400198 frameCustom = LabelFrame(frame, borderwidth=2, relief=GROOVE,
199 text=' Custom Highlighting ')
200 frameTheme = LabelFrame(frame, borderwidth=2, relief=GROOVE,
201 text=' Highlighting Theme ')
Steven M. Gava952d0a52001-08-03 04:43:44 +0000202 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400203 self.textHighlightSample=Text(
204 frameCustom, relief=SOLID, borderwidth=1,
205 font=('courier', 12, ''), cursor='hand2', width=21, height=11,
206 takefocus=FALSE, highlightthickness=0, wrap=NONE)
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000207 text=self.textHighlightSample
Terry Jan Reedyae410862014-08-03 23:02:53 -0400208 text.bind('<Double-Button-1>', lambda e: 'break')
209 text.bind('<B1-Motion>', lambda e: 'break')
210 textAndTags=(
211 ('#you can click here', 'comment'), ('\n', 'normal'),
212 ('#to choose items', 'comment'), ('\n', 'normal'),
213 ('def', 'keyword'), (' ', 'normal'),
214 ('func', 'definition'), ('(param):\n ', 'normal'),
215 ('"""string"""', 'string'), ('\n var0 = ', 'normal'),
216 ("'string'", 'string'), ('\n var1 = ', 'normal'),
217 ("'selected'", 'hilite'), ('\n var2 = ', 'normal'),
218 ("'found'", 'hit'), ('\n var3 = ', 'normal'),
219 ('list', 'builtin'), ('(', 'normal'),
220 ('None', 'builtin'), (')\n\n', 'normal'),
221 (' error ', 'error'), (' ', 'normal'),
222 ('cursor |', 'cursor'), ('\n ', 'normal'),
223 ('shell', 'console'), (' ', 'normal'),
224 ('stdout', 'stdout'), (' ', 'normal'),
225 ('stderr', 'stderr'), ('\n', 'normal'))
Steven M. Gava9dd16b32001-11-03 14:54:25 +0000226 for txTa in textAndTags:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400227 text.insert(END, txTa[0], txTa[1])
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400228 for element in self.themeElements:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400229 def tem(event, elem=element):
230 event.widget.winfo_toplevel().highlightTarget.set(elem)
231 text.tag_bind(
232 self.themeElements[element][0], '<ButtonPress-1>', tem)
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000233 text.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400234 self.frameColourSet = Frame(frameCustom, relief=SOLID, borderwidth=1)
235 frameFgBg = Frame(frameCustom)
236 buttonSetColour = Button(
237 self.frameColourSet, text='Choose Colour for :',
238 command=self.GetColour, highlightthickness=0)
239 self.optMenuHighlightTarget = DynOptionMenu(
240 self.frameColourSet, self.highlightTarget, None,
241 highlightthickness=0) #, command=self.SetHighlightTargetBinding
242 self.radioFg = Radiobutton(
243 frameFgBg, variable=self.fgHilite, value=1,
244 text='Foreground', command=self.SetColourSampleBinding)
245 self.radioBg=Radiobutton(
246 frameFgBg, variable=self.fgHilite, value=0,
247 text='Background', command=self.SetColourSampleBinding)
Steven M. Gava7c017862001-10-29 11:19:46 +0000248 self.fgHilite.set(1)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400249 buttonSaveCustomTheme = Button(
250 frameCustom, text='Save as New Custom Theme',
251 command=self.SaveAsNewTheme)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000252 #frameTheme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400253 labelTypeTitle = Label(frameTheme, text='Select : ')
254 self.radioThemeBuiltin = Radiobutton(
255 frameTheme, variable=self.themeIsBuiltin, value=1,
256 command=self.SetThemeType, text='a Built-in Theme')
257 self.radioThemeCustom = Radiobutton(
258 frameTheme, variable=self.themeIsBuiltin, value=0,
259 command=self.SetThemeType, text='a Custom Theme')
260 self.optMenuThemeBuiltin = DynOptionMenu(
261 frameTheme, self.builtinTheme, None, command=None)
262 self.optMenuThemeCustom=DynOptionMenu(
263 frameTheme, self.customTheme, None, command=None)
264 self.buttonDeleteCustomTheme=Button(
265 frameTheme, text='Delete Custom Theme',
Steven M. Gava49745752002-02-18 01:43:11 +0000266 command=self.DeleteCustomTheme)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400267
Steven M. Gava952d0a52001-08-03 04:43:44 +0000268 ##widget packing
269 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400270 frameCustom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
271 frameTheme.pack(side=LEFT, padx=5, pady=5, fill=Y)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000272 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400273 self.frameColourSet.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X)
274 frameFgBg.pack(side=TOP, padx=5, pady=0)
275 self.textHighlightSample.pack(
276 side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
277 buttonSetColour.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4)
278 self.optMenuHighlightTarget.pack(
279 side=TOP, expand=TRUE, fill=X, padx=8, pady=3)
280 self.radioFg.pack(side=LEFT, anchor=E)
281 self.radioBg.pack(side=RIGHT, anchor=W)
282 buttonSaveCustomTheme.pack(side=BOTTOM, fill=X, padx=5, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000283 #frameTheme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400284 labelTypeTitle.pack(side=TOP, anchor=W, padx=5, pady=5)
285 self.radioThemeBuiltin.pack(side=TOP, anchor=W, padx=5)
286 self.radioThemeCustom.pack(side=TOP, anchor=W, padx=5, pady=2)
287 self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5)
288 self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5)
289 self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000290 return frame
291
292 def CreatePageKeys(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400293 parent = self.parent
294 self.bindingTarget = StringVar(parent)
295 self.builtinKeys = StringVar(parent)
296 self.customKeys = StringVar(parent)
297 self.keysAreBuiltin = BooleanVar(parent)
298 self.keyBinding = StringVar(parent)
299
Steven M. Gava60fc7072001-08-04 13:58:22 +0000300 ##widget creation
301 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400302 frame = self.tabPages.pages['Keys'].frame
Steven M. Gava60fc7072001-08-04 13:58:22 +0000303 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400304 frameCustom = LabelFrame(
305 frame, borderwidth=2, relief=GROOVE,
306 text=' Custom Key Bindings ')
307 frameKeySets = LabelFrame(
308 frame, borderwidth=2, relief=GROOVE, text=' Key Set ')
Steven M. Gava60fc7072001-08-04 13:58:22 +0000309 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400310 frameTarget = Frame(frameCustom)
311 labelTargetTitle = Label(frameTarget, text='Action - Key(s)')
312 scrollTargetY = Scrollbar(frameTarget)
313 scrollTargetX = Scrollbar(frameTarget, orient=HORIZONTAL)
314 self.listBindings = Listbox(
315 frameTarget, takefocus=FALSE, exportselection=FALSE)
316 self.listBindings.bind('<ButtonRelease-1>', self.KeyBindingSelected)
Steven M. Gavafacfc092002-01-19 00:29:54 +0000317 scrollTargetY.config(command=self.listBindings.yview)
318 scrollTargetX.config(command=self.listBindings.xview)
319 self.listBindings.config(yscrollcommand=scrollTargetY.set)
320 self.listBindings.config(xscrollcommand=scrollTargetX.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400321 self.buttonNewKeys = Button(
322 frameCustom, text='Get New Keys for Selection',
323 command=self.GetNewKeys, state=DISABLED)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000324 #frameKeySets
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000325 frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0)
326 for i in range(2)]
Terry Jan Reedyae410862014-08-03 23:02:53 -0400327 self.radioKeysBuiltin = Radiobutton(
328 frames[0], variable=self.keysAreBuiltin, value=1,
329 command=self.SetKeysType, text='Use a Built-in Key Set')
330 self.radioKeysCustom = Radiobutton(
331 frames[0], variable=self.keysAreBuiltin, value=0,
332 command=self.SetKeysType, text='Use a Custom Key Set')
333 self.optMenuKeysBuiltin = DynOptionMenu(
334 frames[0], self.builtinKeys, None, command=None)
335 self.optMenuKeysCustom = DynOptionMenu(
336 frames[0], self.customKeys, None, command=None)
337 self.buttonDeleteCustomKeys = Button(
338 frames[1], text='Delete Custom Key Set',
Steven M. Gava49745752002-02-18 01:43:11 +0000339 command=self.DeleteCustomKeys)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400340 buttonSaveCustomKeys = Button(
341 frames[1], text='Save as New Custom Key Set',
342 command=self.SaveAsNewKeySet)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400343
Steven M. Gava60fc7072001-08-04 13:58:22 +0000344 ##widget packing
345 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400346 frameCustom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH)
347 frameKeySets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000348 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400349 self.buttonNewKeys.pack(side=BOTTOM, fill=X, padx=5, pady=5)
350 frameTarget.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
Steven M. Gavafacfc092002-01-19 00:29:54 +0000351 #frame target
Terry Jan Reedyae410862014-08-03 23:02:53 -0400352 frameTarget.columnconfigure(0, weight=1)
353 frameTarget.rowconfigure(1, weight=1)
354 labelTargetTitle.grid(row=0, column=0, columnspan=2, sticky=W)
355 self.listBindings.grid(row=1, column=0, sticky=NSEW)
356 scrollTargetY.grid(row=1, column=1, sticky=NS)
357 scrollTargetX.grid(row=2, column=0, sticky=EW)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000358 #frameKeySets
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000359 self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS)
360 self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS)
361 self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW)
362 self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400363 self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
364 buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000365 frames[0].pack(side=TOP, fill=BOTH, expand=True)
366 frames[1].pack(side=TOP, fill=X, expand=True, pady=2)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000367 return frame
368
369 def CreatePageGeneral(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400370 parent = self.parent
371 self.winWidth = StringVar(parent)
372 self.winHeight = StringVar(parent)
373 self.paraWidth = StringVar(parent)
374 self.startupEdit = IntVar(parent)
375 self.autoSave = IntVar(parent)
376 self.encoding = StringVar(parent)
377 self.userHelpBrowser = BooleanVar(parent)
378 self.helpBrowser = StringVar(parent)
379
Steven M. Gava230e5782001-08-07 03:28:25 +0000380 #widget creation
381 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400382 frame = self.tabPages.pages['General'].frame
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000383 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400384 frameRun = LabelFrame(frame, borderwidth=2, relief=GROOVE,
385 text=' Startup Preferences ')
386 frameSave = LabelFrame(frame, borderwidth=2, relief=GROOVE,
387 text=' Autosave Preferences ')
388 frameWinSize = Frame(frame, borderwidth=2, relief=GROOVE)
389 frameParaSize = Frame(frame, borderwidth=2, relief=GROOVE)
390 frameEncoding = Frame(frame, borderwidth=2, relief=GROOVE)
391 frameHelp = LabelFrame(frame, borderwidth=2, relief=GROOVE,
392 text=' Additional Help Sources ')
Steven M. Gava230e5782001-08-07 03:28:25 +0000393 #frameRun
Terry Jan Reedyae410862014-08-03 23:02:53 -0400394 labelRunChoiceTitle = Label(frameRun, text='At Startup')
395 radioStartupEdit = Radiobutton(
396 frameRun, variable=self.startupEdit, value=1,
397 command=self.SetKeysType, text="Open Edit Window")
398 radioStartupShell = Radiobutton(
399 frameRun, variable=self.startupEdit, value=0,
400 command=self.SetKeysType, text='Open Shell Window')
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000401 #frameSave
Terry Jan Reedyae410862014-08-03 23:02:53 -0400402 labelRunSaveTitle = Label(frameSave, text='At Start of Run (F5) ')
403 radioSaveAsk = Radiobutton(
404 frameSave, variable=self.autoSave, value=0,
405 command=self.SetKeysType, text="Prompt to Save")
406 radioSaveAuto = Radiobutton(
407 frameSave, variable=self.autoSave, value=1,
408 command=self.SetKeysType, text='No Prompt')
Steven M. Gava230e5782001-08-07 03:28:25 +0000409 #frameWinSize
Terry Jan Reedyae410862014-08-03 23:02:53 -0400410 labelWinSizeTitle = Label(
411 frameWinSize, text='Initial Window Size (in characters)')
412 labelWinWidthTitle = Label(frameWinSize, text='Width')
413 entryWinWidth = Entry(
414 frameWinSize, textvariable=self.winWidth, width=3)
415 labelWinHeightTitle = Label(frameWinSize, text='Height')
416 entryWinHeight = Entry(
417 frameWinSize, textvariable=self.winHeight, width=3)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000418 #paragraphFormatWidth
Terry Jan Reedyae410862014-08-03 23:02:53 -0400419 labelParaWidthTitle = Label(
420 frameParaSize, text='Paragraph reformat width (in characters)')
421 entryParaWidth = Entry(
422 frameParaSize, textvariable=self.paraWidth, width=3)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000423 #frameEncoding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400424 labelEncodingTitle = Label(
425 frameEncoding, text="Default Source Encoding")
426 radioEncLocale = Radiobutton(
427 frameEncoding, variable=self.encoding,
428 value="locale", text="Locale-defined")
429 radioEncUTF8 = Radiobutton(
430 frameEncoding, variable=self.encoding,
431 value="utf-8", text="UTF-8")
432 radioEncNone = Radiobutton(
433 frameEncoding, variable=self.encoding,
434 value="none", text="None")
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000435 #frameHelp
Terry Jan Reedyae410862014-08-03 23:02:53 -0400436 frameHelpList = Frame(frameHelp)
437 frameHelpListButtons = Frame(frameHelpList)
438 scrollHelpList = Scrollbar(frameHelpList)
439 self.listHelp = Listbox(
440 frameHelpList, height=5, takefocus=FALSE,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000441 exportselection=FALSE)
442 scrollHelpList.config(command=self.listHelp.yview)
443 self.listHelp.config(yscrollcommand=scrollHelpList.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400444 self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected)
445 self.buttonHelpListEdit = Button(
446 frameHelpListButtons, text='Edit', state=DISABLED,
447 width=8, command=self.HelpListItemEdit)
448 self.buttonHelpListAdd = Button(
449 frameHelpListButtons, text='Add',
450 width=8, command=self.HelpListItemAdd)
451 self.buttonHelpListRemove = Button(
452 frameHelpListButtons, text='Remove', state=DISABLED,
453 width=8, command=self.HelpListItemRemove)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400454
Steven M. Gava230e5782001-08-07 03:28:25 +0000455 #widget packing
456 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400457 frameRun.pack(side=TOP, padx=5, pady=5, fill=X)
458 frameSave.pack(side=TOP, padx=5, pady=5, fill=X)
459 frameWinSize.pack(side=TOP, padx=5, pady=5, fill=X)
460 frameParaSize.pack(side=TOP, padx=5, pady=5, fill=X)
461 frameEncoding.pack(side=TOP, padx=5, pady=5, fill=X)
462 frameHelp.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
Steven M. Gava230e5782001-08-07 03:28:25 +0000463 #frameRun
Terry Jan Reedyae410862014-08-03 23:02:53 -0400464 labelRunChoiceTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
465 radioStartupShell.pack(side=RIGHT, anchor=W, padx=5, pady=5)
466 radioStartupEdit.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000467 #frameSave
Terry Jan Reedyae410862014-08-03 23:02:53 -0400468 labelRunSaveTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
469 radioSaveAuto.pack(side=RIGHT, anchor=W, padx=5, pady=5)
470 radioSaveAsk.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Steven M. Gava230e5782001-08-07 03:28:25 +0000471 #frameWinSize
Terry Jan Reedyae410862014-08-03 23:02:53 -0400472 labelWinSizeTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
473 entryWinHeight.pack(side=RIGHT, anchor=E, padx=10, pady=5)
474 labelWinHeightTitle.pack(side=RIGHT, anchor=E, pady=5)
475 entryWinWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
476 labelWinWidthTitle.pack(side=RIGHT, anchor=E, pady=5)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000477 #paragraphFormatWidth
Terry Jan Reedyae410862014-08-03 23:02:53 -0400478 labelParaWidthTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
479 entryParaWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000480 #frameEncoding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400481 labelEncodingTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
482 radioEncNone.pack(side=RIGHT, anchor=E, pady=5)
483 radioEncUTF8.pack(side=RIGHT, anchor=E, pady=5)
484 radioEncLocale.pack(side=RIGHT, anchor=E, pady=5)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000485 #frameHelp
Terry Jan Reedyae410862014-08-03 23:02:53 -0400486 frameHelpListButtons.pack(side=RIGHT, padx=5, pady=5, fill=Y)
487 frameHelpList.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
488 scrollHelpList.pack(side=RIGHT, anchor=W, fill=Y)
489 self.listHelp.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)
490 self.buttonHelpListEdit.pack(side=TOP, anchor=W, pady=5)
491 self.buttonHelpListAdd.pack(side=TOP, anchor=W)
492 self.buttonHelpListRemove.pack(side=TOP, anchor=W, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000493 return frame
494
Steven M. Gavac112cd82002-01-22 05:56:40 +0000495 def AttachVarCallbacks(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400496 self.fontSize.trace_variable('w', self.VarChanged_fontSize)
497 self.fontName.trace_variable('w', self.VarChanged_fontName)
498 self.fontBold.trace_variable('w', self.VarChanged_fontBold)
499 self.spaceNum.trace_variable('w', self.VarChanged_spaceNum)
500 self.colour.trace_variable('w', self.VarChanged_colour)
501 self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme)
502 self.customTheme.trace_variable('w', self.VarChanged_customTheme)
503 self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin)
504 self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget)
505 self.keyBinding.trace_variable('w', self.VarChanged_keyBinding)
506 self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys)
507 self.customKeys.trace_variable('w', self.VarChanged_customKeys)
508 self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin)
509 self.winWidth.trace_variable('w', self.VarChanged_winWidth)
510 self.winHeight.trace_variable('w', self.VarChanged_winHeight)
511 self.paraWidth.trace_variable('w', self.VarChanged_paraWidth)
512 self.startupEdit.trace_variable('w', self.VarChanged_startupEdit)
513 self.autoSave.trace_variable('w', self.VarChanged_autoSave)
514 self.encoding.trace_variable('w', self.VarChanged_encoding)
Steven M. Gava052937f2002-02-11 02:20:53 +0000515
Terry Jan Reedyae410862014-08-03 23:02:53 -0400516 def VarChanged_fontSize(self, *params):
517 value = self.fontSize.get()
518 self.AddChangedItem('main', 'EditorWindow', 'font-size', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000519
Terry Jan Reedyae410862014-08-03 23:02:53 -0400520 def VarChanged_fontName(self, *params):
521 value = self.fontName.get()
522 self.AddChangedItem('main', 'EditorWindow', 'font', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000523
Terry Jan Reedyae410862014-08-03 23:02:53 -0400524 def VarChanged_fontBold(self, *params):
525 value = self.fontBold.get()
526 self.AddChangedItem('main', 'EditorWindow', 'font-bold', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000527
Terry Jan Reedyae410862014-08-03 23:02:53 -0400528 def VarChanged_spaceNum(self, *params):
529 value = self.spaceNum.get()
530 self.AddChangedItem('main', 'Indent', 'num-spaces', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000531
Terry Jan Reedyae410862014-08-03 23:02:53 -0400532 def VarChanged_colour(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000533 self.OnNewColourSet()
534
Terry Jan Reedyae410862014-08-03 23:02:53 -0400535 def VarChanged_builtinTheme(self, *params):
536 value = self.builtinTheme.get()
537 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000538 self.PaintThemeSample()
539
Terry Jan Reedyae410862014-08-03 23:02:53 -0400540 def VarChanged_customTheme(self, *params):
541 value = self.customTheme.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000542 if value != '- no custom themes -':
Terry Jan Reedyae410862014-08-03 23:02:53 -0400543 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000544 self.PaintThemeSample()
Steven M. Gava052937f2002-02-11 02:20:53 +0000545
Terry Jan Reedyae410862014-08-03 23:02:53 -0400546 def VarChanged_themeIsBuiltin(self, *params):
547 value = self.themeIsBuiltin.get()
548 self.AddChangedItem('main', 'Theme', 'default', value)
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000549 if value:
550 self.VarChanged_builtinTheme()
551 else:
552 self.VarChanged_customTheme()
Steven M. Gava052937f2002-02-11 02:20:53 +0000553
Terry Jan Reedyae410862014-08-03 23:02:53 -0400554 def VarChanged_highlightTarget(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000555 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000556
Terry Jan Reedyae410862014-08-03 23:02:53 -0400557 def VarChanged_keyBinding(self, *params):
558 value = self.keyBinding.get()
559 keySet = self.customKeys.get()
560 event = self.listBindings.get(ANCHOR).split()[0]
Steven M. Gavaa498af22002-02-01 01:33:36 +0000561 if idleConf.IsCoreBinding(event):
562 #this is a core keybinding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400563 self.AddChangedItem('keys', keySet, event, value)
Steven M. Gavaa498af22002-02-01 01:33:36 +0000564 else: #this is an extension key binding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400565 extName = idleConf.GetExtnNameForEvent(event)
566 extKeybindSection = extName + '_cfgBindings'
567 self.AddChangedItem('extensions', extKeybindSection, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000568
Terry Jan Reedyae410862014-08-03 23:02:53 -0400569 def VarChanged_builtinKeys(self, *params):
570 value = self.builtinKeys.get()
571 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000572 self.LoadKeysList(value)
573
Terry Jan Reedyae410862014-08-03 23:02:53 -0400574 def VarChanged_customKeys(self, *params):
575 value = self.customKeys.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000576 if value != '- no custom keys -':
Terry Jan Reedyae410862014-08-03 23:02:53 -0400577 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000578 self.LoadKeysList(value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000579
Terry Jan Reedyae410862014-08-03 23:02:53 -0400580 def VarChanged_keysAreBuiltin(self, *params):
581 value = self.keysAreBuiltin.get()
582 self.AddChangedItem('main', 'Keys', 'default', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000583 if value:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000584 self.VarChanged_builtinKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000585 else:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000586 self.VarChanged_customKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000587
Terry Jan Reedyae410862014-08-03 23:02:53 -0400588 def VarChanged_winWidth(self, *params):
589 value = self.winWidth.get()
590 self.AddChangedItem('main', 'EditorWindow', 'width', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000591
Terry Jan Reedyae410862014-08-03 23:02:53 -0400592 def VarChanged_winHeight(self, *params):
593 value = self.winHeight.get()
594 self.AddChangedItem('main', 'EditorWindow', 'height', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000595
Terry Jan Reedyae410862014-08-03 23:02:53 -0400596 def VarChanged_paraWidth(self, *params):
597 value = self.paraWidth.get()
598 self.AddChangedItem('main', 'FormatParagraph', 'paragraph', value)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000599
Terry Jan Reedyae410862014-08-03 23:02:53 -0400600 def VarChanged_startupEdit(self, *params):
601 value = self.startupEdit.get()
602 self.AddChangedItem('main', 'General', 'editor-on-startup', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000603
Terry Jan Reedyae410862014-08-03 23:02:53 -0400604 def VarChanged_autoSave(self, *params):
605 value = self.autoSave.get()
606 self.AddChangedItem('main', 'General', 'autosave', value)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000607
Terry Jan Reedyae410862014-08-03 23:02:53 -0400608 def VarChanged_encoding(self, *params):
609 value = self.encoding.get()
610 self.AddChangedItem('main', 'EditorWindow', 'encoding', value)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000611
Steven M. Gavaa498af22002-02-01 01:33:36 +0000612 def ResetChangedItems(self):
Steven M. Gavab77d3432002-03-02 07:16:21 +0000613 #When any config item is changed in this dialog, an entry
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000614 #should be made in the relevant section (config type) of this
615 #dictionary. The key should be the config file section name and the
Steven M. Gavaa498af22002-02-01 01:33:36 +0000616 #value a dictionary, whose key:value pairs are item=value pairs for
617 #that config file section.
Terry Jan Reedyae410862014-08-03 23:02:53 -0400618 self.changedItems = {'main':{}, 'highlight':{}, 'keys':{},
619 'extensions':{}}
Steven M. Gavaa498af22002-02-01 01:33:36 +0000620
Terry Jan Reedyae410862014-08-03 23:02:53 -0400621 def AddChangedItem(self, typ, section, item, value):
622 value = str(value) #make sure we use a string
623 if section not in self.changedItems[typ]:
624 self.changedItems[typ][section] = {}
625 self.changedItems[typ][section][item] = value
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000626
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000627 def GetDefaultItems(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400628 dItems={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}}
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400629 for configType in dItems:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400630 sections = idleConf.GetSectionList('default', configType)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000631 for section in sections:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400632 dItems[configType][section] = {}
633 options = idleConf.defaultCfg[configType].GetOptionList(section)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000634 for option in options:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400635 dItems[configType][section][option] = (
636 idleConf.defaultCfg[configType].Get(section, option))
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000637 return dItems
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000638
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000639 def SetThemeType(self):
640 if self.themeIsBuiltin.get():
641 self.optMenuThemeBuiltin.config(state=NORMAL)
642 self.optMenuThemeCustom.config(state=DISABLED)
643 self.buttonDeleteCustomTheme.config(state=DISABLED)
644 else:
645 self.optMenuThemeBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000646 self.radioThemeCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000647 self.optMenuThemeCustom.config(state=NORMAL)
648 self.buttonDeleteCustomTheme.config(state=NORMAL)
649
650 def SetKeysType(self):
Steven M. Gava052937f2002-02-11 02:20:53 +0000651 if self.keysAreBuiltin.get():
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000652 self.optMenuKeysBuiltin.config(state=NORMAL)
653 self.optMenuKeysCustom.config(state=DISABLED)
654 self.buttonDeleteCustomKeys.config(state=DISABLED)
655 else:
656 self.optMenuKeysBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000657 self.radioKeysCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000658 self.optMenuKeysCustom.config(state=NORMAL)
659 self.buttonDeleteCustomKeys.config(state=NORMAL)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000660
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000661 def GetNewKeys(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400662 listIndex = self.listBindings.index(ANCHOR)
663 binding = self.listBindings.get(listIndex)
664 bindName = binding.split()[0] #first part, up to first space
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000665 if self.keysAreBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400666 currentKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000667 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400668 currentKeySetName = self.customKeys.get()
669 currentBindings = idleConf.GetCurrentKeySet()
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400670 if currentKeySetName in self.changedItems['keys']: #unsaved changes
Terry Jan Reedyae410862014-08-03 23:02:53 -0400671 keySetChanges = self.changedItems['keys'][currentKeySetName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400672 for event in keySetChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400673 currentBindings[event] = keySetChanges[event].split()
674 currentKeySequences = currentBindings.values()
675 newKeys = GetKeysDialog(self, 'Get New Keys', bindName,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000676 currentKeySequences).result
677 if newKeys: #new keys were specified
Steven M. Gava052937f2002-02-11 02:20:53 +0000678 if self.keysAreBuiltin.get(): #current key set is a built-in
Terry Jan Reedyae410862014-08-03 23:02:53 -0400679 message = ('Your changes will be saved as a new Custom Key Set.'
680 ' Enter a name for your new Custom Key Set below.')
681 newKeySet = self.GetNewKeysName(message)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000682 if not newKeySet: #user cancelled custom key set creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000683 self.listBindings.select_set(listIndex)
684 self.listBindings.select_anchor(listIndex)
685 return
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000686 else: #create new custom key set based on previously active key set
687 self.CreateNewKeySet(newKeySet)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000688 self.listBindings.delete(listIndex)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400689 self.listBindings.insert(listIndex, bindName+' - '+newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000690 self.listBindings.select_set(listIndex)
691 self.listBindings.select_anchor(listIndex)
Steven M. Gava052937f2002-02-11 02:20:53 +0000692 self.keyBinding.set(newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000693 else:
694 self.listBindings.select_set(listIndex)
695 self.listBindings.select_anchor(listIndex)
696
Terry Jan Reedyae410862014-08-03 23:02:53 -0400697 def GetNewKeysName(self, message):
698 usedNames = (idleConf.GetSectionList('user', 'keys') +
699 idleConf.GetSectionList('default', 'keys'))
700 newKeySet = GetCfgSectionNameDialog(
701 self, 'New Custom Key Set', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000702 return newKeySet
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000703
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000704 def SaveAsNewKeySet(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400705 newKeysName = self.GetNewKeysName('New Key Set Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000706 if newKeysName:
707 self.CreateNewKeySet(newKeysName)
708
Terry Jan Reedyae410862014-08-03 23:02:53 -0400709 def KeyBindingSelected(self, event):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000710 self.buttonNewKeys.config(state=NORMAL)
711
Terry Jan Reedyae410862014-08-03 23:02:53 -0400712 def CreateNewKeySet(self, newKeySetName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000713 #creates new custom key set based on the previously active key set,
714 #and makes the new key set active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000715 if self.keysAreBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400716 prevKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000717 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400718 prevKeySetName = self.customKeys.get()
719 prevKeys = idleConf.GetCoreKeys(prevKeySetName)
720 newKeys = {}
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400721 for event in prevKeys: #add key set to changed items
Terry Jan Reedyae410862014-08-03 23:02:53 -0400722 eventName = event[2:-2] #trim off the angle brackets
723 binding = ' '.join(prevKeys[event])
724 newKeys[eventName] = binding
Steven M. Gava052937f2002-02-11 02:20:53 +0000725 #handle any unsaved changes to prev key set
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400726 if prevKeySetName in self.changedItems['keys']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400727 keySetChanges = self.changedItems['keys'][prevKeySetName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400728 for event in keySetChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400729 newKeys[event] = keySetChanges[event]
Steven M. Gava052937f2002-02-11 02:20:53 +0000730 #save the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400731 self.SaveNewKeySet(newKeySetName, newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000732 #change gui over to the new key set
Terry Jan Reedyae410862014-08-03 23:02:53 -0400733 customKeyList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000734 customKeyList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400735 self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000736 self.keysAreBuiltin.set(0)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000737 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000738
Terry Jan Reedyae410862014-08-03 23:02:53 -0400739 def LoadKeysList(self, keySetName):
740 reselect = 0
741 newKeySet = 0
Steven M. Gava052937f2002-02-11 02:20:53 +0000742 if self.listBindings.curselection():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400743 reselect = 1
744 listIndex = self.listBindings.index(ANCHOR)
745 keySet = idleConf.GetKeySet(keySetName)
746 bindNames = keySet.keys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000747 bindNames.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400748 self.listBindings.delete(0, END)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000749 for bindName in bindNames:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400750 key = ' '.join(keySet[bindName]) #make key(s) into a string
751 bindName = bindName[2:-2] #trim off the angle brackets
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400752 if keySetName in self.changedItems['keys']:
Steven M. Gava052937f2002-02-11 02:20:53 +0000753 #handle any unsaved changes to this key set
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400754 if bindName in self.changedItems['keys'][keySetName]:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400755 key = self.changedItems['keys'][keySetName][bindName]
Steven M. Gava052937f2002-02-11 02:20:53 +0000756 self.listBindings.insert(END, bindName+' - '+key)
Steven M. Gava052937f2002-02-11 02:20:53 +0000757 if reselect:
758 self.listBindings.see(listIndex)
759 self.listBindings.select_set(listIndex)
760 self.listBindings.select_anchor(listIndex)
761
Steven M. Gava49745752002-02-18 01:43:11 +0000762 def DeleteCustomKeys(self):
763 keySetName=self.customKeys.get()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400764 delmsg = 'Are you sure you wish to delete the key set %r ?'
765 if not tkMessageBox.askyesno(
766 'Delete Key Set', delmsg % keySetName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000767 return
768 #remove key set from config
769 idleConf.userCfg['keys'].remove_section(keySetName)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +0000770 if keySetName in self.changedItems['keys']:
Steven M. Gava49745752002-02-18 01:43:11 +0000771 del(self.changedItems['keys'][keySetName])
772 #write changes
773 idleConf.userCfg['keys'].Save()
774 #reload user key set list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400775 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gava49745752002-02-18 01:43:11 +0000776 itemList.sort()
777 if not itemList:
778 self.radioKeysCustom.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400779 self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -')
Steven M. Gava49745752002-02-18 01:43:11 +0000780 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400781 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000782 #revert to default key set
Terry Jan Reedyae410862014-08-03 23:02:53 -0400783 self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
784 self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000785 #user can't back out of these changes, they must be applied now
786 self.Apply()
787 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000788
Steven M. Gava49745752002-02-18 01:43:11 +0000789 def DeleteCustomTheme(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400790 themeName = self.customTheme.get()
791 delmsg = 'Are you sure you wish to delete the theme %r ?'
792 if not tkMessageBox.askyesno(
793 'Delete Theme', delmsg % themeName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000794 return
795 #remove theme from config
796 idleConf.userCfg['highlight'].remove_section(themeName)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +0000797 if themeName in self.changedItems['highlight']:
Steven M. Gava49745752002-02-18 01:43:11 +0000798 del(self.changedItems['highlight'][themeName])
799 #write changes
800 idleConf.userCfg['highlight'].Save()
801 #reload user theme list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400802 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gava49745752002-02-18 01:43:11 +0000803 itemList.sort()
804 if not itemList:
805 self.radioThemeCustom.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400806 self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -')
Steven M. Gava49745752002-02-18 01:43:11 +0000807 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400808 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000809 #revert to default theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400810 self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
811 self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000812 #user can't back out of these changes, they must be applied now
813 self.Apply()
814 self.SetThemeType()
815
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000816 def GetColour(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400817 target = self.highlightTarget.get()
818 prevColour = self.frameColourSet.cget('bg')
819 rgbTuplet, colourString = tkColorChooser.askcolor(
820 parent=self, title='Pick new colour for : '+target,
821 initialcolor=prevColour)
822 if colourString and (colourString != prevColour):
Steven M. Gava052937f2002-02-11 02:20:53 +0000823 #user didn't cancel, and they chose a new colour
Terry Jan Reedyae410862014-08-03 23:02:53 -0400824 if self.themeIsBuiltin.get(): #current theme is a built-in
825 message = ('Your changes will be saved as a new Custom Theme. '
826 'Enter a name for your new Custom Theme below.')
827 newTheme = self.GetNewThemeName(message)
828 if not newTheme: #user cancelled custom theme creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000829 return
Terry Jan Reedyae410862014-08-03 23:02:53 -0400830 else: #create new custom theme based on previously active theme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000831 self.CreateNewTheme(newTheme)
Steven M. Gava052937f2002-02-11 02:20:53 +0000832 self.colour.set(colourString)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400833 else: #current theme is user defined
Steven M. Gava052937f2002-02-11 02:20:53 +0000834 self.colour.set(colourString)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000835
Steven M. Gava052937f2002-02-11 02:20:53 +0000836 def OnNewColourSet(self):
837 newColour=self.colour.get()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400838 self.frameColourSet.config(bg=newColour) #set sample
839 plane ='foreground' if self.fgHilite.get() else 'background'
840 sampleElement = self.themeElements[self.highlightTarget.get()][0]
Raymond Hettinger931237e2003-07-09 18:48:24 +0000841 self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
Terry Jan Reedyae410862014-08-03 23:02:53 -0400842 theme = self.customTheme.get()
843 themeElement = sampleElement + '-' + plane
844 self.AddChangedItem('highlight', theme, themeElement, newColour)
Steven M. Gava052937f2002-02-11 02:20:53 +0000845
Terry Jan Reedyae410862014-08-03 23:02:53 -0400846 def GetNewThemeName(self, message):
847 usedNames = (idleConf.GetSectionList('user', 'highlight') +
848 idleConf.GetSectionList('default', 'highlight'))
849 newTheme = GetCfgSectionNameDialog(
850 self, 'New Custom Theme', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000851 return newTheme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000852
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000853 def SaveAsNewTheme(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400854 newThemeName = self.GetNewThemeName('New Theme Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000855 if newThemeName:
856 self.CreateNewTheme(newThemeName)
857
Terry Jan Reedyae410862014-08-03 23:02:53 -0400858 def CreateNewTheme(self, newThemeName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000859 #creates new custom theme based on the previously active theme,
860 #and makes the new theme active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000861 if self.themeIsBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400862 themeType = 'default'
863 themeName = self.builtinTheme.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000864 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400865 themeType = 'user'
866 themeName = self.customTheme.get()
867 newTheme = idleConf.GetThemeDict(themeType, themeName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000868 #apply any of the old theme's unsaved changes to the new theme
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400869 if themeName in self.changedItems['highlight']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400870 themeChanges = self.changedItems['highlight'][themeName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400871 for element in themeChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400872 newTheme[element] = themeChanges[element]
Steven M. Gava052937f2002-02-11 02:20:53 +0000873 #save the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400874 self.SaveNewTheme(newThemeName, newTheme)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000875 #change gui over to the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400876 customThemeList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000877 customThemeList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400878 self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000879 self.themeIsBuiltin.set(0)
880 self.SetThemeType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000881
Terry Jan Reedyae410862014-08-03 23:02:53 -0400882 def OnListFontButtonRelease(self, event):
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000883 font = self.listFontName.get(ANCHOR)
884 self.fontName.set(font.lower())
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000885 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000886
Terry Jan Reedyae410862014-08-03 23:02:53 -0400887 def SetFontSample(self, event=None):
888 fontName = self.fontName.get()
889 fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL
Ned Deilye3d47122012-10-22 15:13:01 -0700890 newFont = (fontName, self.fontSize.get(), fontWeight)
891 self.labelFontSample.config(font=newFont)
892 self.textHighlightSample.configure(font=newFont)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000893
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000894 def SetHighlightTarget(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400895 if self.highlightTarget.get() == 'Cursor': #bg not possible
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000896 self.radioFg.config(state=DISABLED)
897 self.radioBg.config(state=DISABLED)
898 self.fgHilite.set(1)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400899 else: #both fg and bg can be set
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000900 self.radioFg.config(state=NORMAL)
901 self.radioBg.config(state=NORMAL)
902 self.fgHilite.set(1)
903 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000904
Terry Jan Reedyae410862014-08-03 23:02:53 -0400905 def SetColourSampleBinding(self, *args):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000906 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000907
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000908 def SetColourSample(self):
909 #set the colour smaple area
Terry Jan Reedyae410862014-08-03 23:02:53 -0400910 tag = self.themeElements[self.highlightTarget.get()][0]
911 plane = 'foreground' if self.fgHilite.get() else 'background'
912 colour = self.textHighlightSample.tag_cget(tag, plane)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000913 self.frameColourSet.config(bg=colour)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000914
Steven M. Gava9dd16b32001-11-03 14:54:25 +0000915 def PaintThemeSample(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400916 if self.themeIsBuiltin.get(): #a default theme
917 theme = self.builtinTheme.get()
918 else: #a user theme
919 theme = self.customTheme.get()
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400920 for elementTitle in self.themeElements:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400921 element = self.themeElements[elementTitle][0]
922 colours = idleConf.GetHighlight(theme, element)
923 if element == 'cursor': #cursor sample needs special painting
924 colours['background'] = idleConf.GetHighlight(
925 theme, 'normal', fgBg='bg')
Steven M. Gava052937f2002-02-11 02:20:53 +0000926 #handle any unsaved changes to this theme
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400927 if theme in self.changedItems['highlight']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400928 themeDict = self.changedItems['highlight'][theme]
929 if element + '-foreground' in themeDict:
930 colours['foreground'] = themeDict[element + '-foreground']
931 if element + '-background' in themeDict:
932 colours['background'] = themeDict[element + '-background']
Raymond Hettinger931237e2003-07-09 18:48:24 +0000933 self.textHighlightSample.tag_config(element, **colours)
Steven M. Gava052937f2002-02-11 02:20:53 +0000934 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000935
Terry Jan Reedyae410862014-08-03 23:02:53 -0400936 def HelpSourceSelected(self, event):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000937 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000938
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000939 def SetHelpListButtonStates(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400940 if self.listHelp.size() < 1: #no entries in list
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000941 self.buttonHelpListEdit.config(state=DISABLED)
942 self.buttonHelpListRemove.config(state=DISABLED)
943 else: #there are some entries
Terry Jan Reedyae410862014-08-03 23:02:53 -0400944 if self.listHelp.curselection(): #there currently is a selection
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000945 self.buttonHelpListEdit.config(state=NORMAL)
946 self.buttonHelpListRemove.config(state=NORMAL)
947 else: #there currently is not a selection
948 self.buttonHelpListEdit.config(state=DISABLED)
949 self.buttonHelpListRemove.config(state=DISABLED)
950
951 def HelpListItemAdd(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400952 helpSource = GetHelpSourceDialog(self, 'New Help Source').result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000953 if helpSource:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400954 self.userHelpList.append((helpSource[0], helpSource[1]))
955 self.listHelp.insert(END, helpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000956 self.UpdateUserHelpChangedItems()
957 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000958
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000959 def HelpListItemEdit(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400960 itemIndex = self.listHelp.index(ANCHOR)
961 helpSource = self.userHelpList[itemIndex]
962 newHelpSource = GetHelpSourceDialog(
963 self, 'Edit Help Source', menuItem=helpSource[0],
964 filePath=helpSource[1]).result
965 if (not newHelpSource) or (newHelpSource == helpSource):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000966 return #no changes
Terry Jan Reedyae410862014-08-03 23:02:53 -0400967 self.userHelpList[itemIndex] = newHelpSource
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000968 self.listHelp.delete(itemIndex)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400969 self.listHelp.insert(itemIndex, newHelpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000970 self.UpdateUserHelpChangedItems()
971 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000972
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000973 def HelpListItemRemove(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400974 itemIndex = self.listHelp.index(ANCHOR)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000975 del(self.userHelpList[itemIndex])
976 self.listHelp.delete(itemIndex)
977 self.UpdateUserHelpChangedItems()
978 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000979
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000980 def UpdateUserHelpChangedItems(self):
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +0000981 "Clear and rebuild the HelpFiles section in self.changedItems"
982 self.changedItems['main']['HelpFiles'] = {}
Terry Jan Reedyae410862014-08-03 23:02:53 -0400983 for num in range(1, len(self.userHelpList) + 1):
984 self.AddChangedItem(
985 'main', 'HelpFiles', str(num),
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400986 ';'.join(self.userHelpList[num-1][:2]))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000987
Steven M. Gava429a86a2001-10-23 10:42:12 +0000988 def LoadFontCfg(self):
989 ##base editor font selection list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400990 fonts = list(tkFont.families(self))
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000991 fonts.sort()
992 for font in fonts:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400993 self.listFontName.insert(END, font)
994 configuredFont = idleConf.GetOption(
995 'main', 'EditorWindow', 'font', default='courier')
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000996 lc_configuredFont = configuredFont.lower()
997 self.fontName.set(lc_configuredFont)
998 lc_fonts = [s.lower() for s in fonts]
999 if lc_configuredFont in lc_fonts:
1000 currentFontIndex = lc_fonts.index(lc_configuredFont)
Steven M. Gava429a86a2001-10-23 10:42:12 +00001001 self.listFontName.see(currentFontIndex)
1002 self.listFontName.select_set(currentFontIndex)
Steven M. Gavac112cd82002-01-22 05:56:40 +00001003 self.listFontName.select_anchor(currentFontIndex)
Steven M. Gava429a86a2001-10-23 10:42:12 +00001004 ##font size dropdown
Terry Jan Reedyae410862014-08-03 23:02:53 -04001005 fontSize = idleConf.GetOption(
1006 'main', 'EditorWindow', 'font-size', type='int', default='10')
1007 self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13',
1008 '14', '16', '18', '20', '22'), fontSize )
Steven M. Gavac112cd82002-01-22 05:56:40 +00001009 ##fontWeight
Terry Jan Reedyae410862014-08-03 23:02:53 -04001010 self.fontBold.set(idleConf.GetOption(
1011 'main', 'EditorWindow', 'font-bold', default=0, type='bool'))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001012 ##font sample
Steven M. Gava429a86a2001-10-23 10:42:12 +00001013 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001014
Steven M. Gava429a86a2001-10-23 10:42:12 +00001015 def LoadTabCfg(self):
Steven M. Gava429a86a2001-10-23 10:42:12 +00001016 ##indent sizes
Terry Jan Reedyae410862014-08-03 23:02:53 -04001017 spaceNum = idleConf.GetOption(
1018 'main', 'Indent', 'num-spaces', default=4, type='int')
Steven M. Gava429a86a2001-10-23 10:42:12 +00001019 self.spaceNum.set(spaceNum)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001020
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001021 def LoadThemeCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001022 ##current theme type radiobutton
Terry Jan Reedyae410862014-08-03 23:02:53 -04001023 self.themeIsBuiltin.set(idleConf.GetOption(
1024 'main', 'Theme', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001025 ##currently set theme
Terry Jan Reedyae410862014-08-03 23:02:53 -04001026 currentOption = idleConf.CurrentTheme()
Steven M. Gava7c017862001-10-29 11:19:46 +00001027 ##load available theme option menus
Steven M. Gavad0342cd2001-11-04 11:53:10 +00001028 if self.themeIsBuiltin.get(): #default theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001029 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001030 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001031 self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
1032 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001033 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001034 if not itemList:
1035 self.radioThemeCustom.config(state=DISABLED)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001036 self.customTheme.set('- no custom themes -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001037 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001038 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001039 else: #user theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001040 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001041 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001042 self.optMenuThemeCustom.SetMenu(itemList, currentOption)
1043 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001044 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001045 self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
Steven M. Gava7c017862001-10-29 11:19:46 +00001046 self.SetThemeType()
1047 ##load theme element option menu
Terry Jan Reedyae410862014-08-03 23:02:53 -04001048 themeNames = self.themeElements.keys()
Florent Xiclunaa7f242f2010-04-02 08:15:26 +00001049 themeNames.sort(key=lambda x: self.themeElements[x][1])
Terry Jan Reedyae410862014-08-03 23:02:53 -04001050 self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001051 self.PaintThemeSample()
Steven M. Gava0cae01c2002-01-04 07:53:06 +00001052 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001053
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001054 def LoadKeyCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001055 ##current keys type radiobutton
Terry Jan Reedyae410862014-08-03 23:02:53 -04001056 self.keysAreBuiltin.set(idleConf.GetOption(
1057 'main', 'Keys', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001058 ##currently set keys
Terry Jan Reedyae410862014-08-03 23:02:53 -04001059 currentOption = idleConf.CurrentKeys()
Steven M. Gava7c017862001-10-29 11:19:46 +00001060 ##load available keyset option menus
Steven M. Gava052937f2002-02-11 02:20:53 +00001061 if self.keysAreBuiltin.get(): #default theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001062 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001063 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001064 self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
1065 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001066 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001067 if not itemList:
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001068 self.radioKeysCustom.config(state=DISABLED)
1069 self.customKeys.set('- no custom keys -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001070 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001071 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gavaa498af22002-02-01 01:33:36 +00001072 else: #user key set selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001073 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001074 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001075 self.optMenuKeysCustom.SetMenu(itemList, currentOption)
1076 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001077 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001078 self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001079 self.SetKeysType()
Steven M. Gavafacfc092002-01-19 00:29:54 +00001080 ##load keyset element list
Terry Jan Reedyae410862014-08-03 23:02:53 -04001081 keySetName = idleConf.CurrentKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +00001082 self.LoadKeysList(keySetName)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001083
Steven M. Gavafacfc092002-01-19 00:29:54 +00001084 def LoadGeneralCfg(self):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001085 #startup state
Terry Jan Reedyae410862014-08-03 23:02:53 -04001086 self.startupEdit.set(idleConf.GetOption(
1087 'main', 'General', 'editor-on-startup', default=1, type='bool'))
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +00001088 #autosave state
Terry Jan Reedyae410862014-08-03 23:02:53 -04001089 self.autoSave.set(idleConf.GetOption(
1090 'main', 'General', 'autosave', default=0, type='bool'))
Steven M. Gavafacfc092002-01-19 00:29:54 +00001091 #initial window size
Terry Jan Reedyae410862014-08-03 23:02:53 -04001092 self.winWidth.set(idleConf.GetOption(
1093 'main', 'EditorWindow', 'width', type='int'))
1094 self.winHeight.set(idleConf.GetOption(
1095 'main', 'EditorWindow', 'height', type='int'))
Raymond Hettinger4e49b832004-06-04 06:31:08 +00001096 #initial paragraph reformat size
Terry Jan Reedyae410862014-08-03 23:02:53 -04001097 self.paraWidth.set(idleConf.GetOption(
1098 'main', 'FormatParagraph', 'paragraph', type='int'))
Kurt B. Kaisera053f332003-05-10 00:49:56 +00001099 # default source encoding
Terry Jan Reedyae410862014-08-03 23:02:53 -04001100 self.encoding.set(idleConf.GetOption(
1101 'main', 'EditorWindow', 'encoding', default='none'))
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001102 # additional help sources
1103 self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001104 for helpItem in self.userHelpList:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001105 self.listHelp.insert(END, helpItem[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001106 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001107
Steven M. Gava429a86a2001-10-23 10:42:12 +00001108 def LoadConfigs(self):
1109 """
1110 load configuration from default and user config files and populate
1111 the widgets on the config dialog pages.
1112 """
1113 ### fonts / tabs page
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001114 self.LoadFontCfg()
1115 self.LoadTabCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001116 ### highlighting page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001117 self.LoadThemeCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001118 ### keys page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001119 self.LoadKeyCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001120 ### general page
Steven M. Gavafacfc092002-01-19 00:29:54 +00001121 self.LoadGeneralCfg()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001122
Terry Jan Reedyae410862014-08-03 23:02:53 -04001123 def SaveNewKeySet(self, keySetName, keySet):
Steven M. Gava052937f2002-02-11 02:20:53 +00001124 """
1125 save a newly created core key set.
1126 keySetName - string, the name of the new key set
1127 keySet - dictionary containing the new key set
1128 """
1129 if not idleConf.userCfg['keys'].has_section(keySetName):
1130 idleConf.userCfg['keys'].add_section(keySetName)
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001131 for event in keySet:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001132 value = keySet[event]
1133 idleConf.userCfg['keys'].SetOption(keySetName, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001134
Terry Jan Reedyae410862014-08-03 23:02:53 -04001135 def SaveNewTheme(self, themeName, theme):
Steven M. Gava052937f2002-02-11 02:20:53 +00001136 """
1137 save a newly created theme.
1138 themeName - string, the name of the new theme
1139 theme - dictionary containing the new theme
1140 """
1141 if not idleConf.userCfg['highlight'].has_section(themeName):
1142 idleConf.userCfg['highlight'].add_section(themeName)
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001143 for element in theme:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001144 value = theme[element]
1145 idleConf.userCfg['highlight'].SetOption(themeName, element, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001146
Terry Jan Reedyae410862014-08-03 23:02:53 -04001147 def SetUserValue(self, configType, section, item, value):
1148 if idleConf.defaultCfg[configType].has_option(section, item):
1149 if idleConf.defaultCfg[configType].Get(section, item) == value:
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001150 #the setting equals a default setting, remove it from user cfg
Terry Jan Reedyae410862014-08-03 23:02:53 -04001151 return idleConf.userCfg[configType].RemoveOption(section, item)
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001152 #if we got here set the option
Terry Jan Reedyae410862014-08-03 23:02:53 -04001153 return idleConf.userCfg[configType].SetOption(section, item, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001154
Steven M. Gava052937f2002-02-11 02:20:53 +00001155 def SaveAllChangedConfigs(self):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001156 "Save configuration changes to the user config file."
Steven M. Gava0c5bc8c2002-03-27 02:25:44 +00001157 idleConf.userCfg['main'].Save()
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001158 for configType in self.changedItems:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001159 cfgTypeHasChanges = False
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001160 for section in self.changedItems[configType]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001161 if section == 'HelpFiles':
1162 #this section gets completely replaced
1163 idleConf.userCfg['main'].remove_section('HelpFiles')
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001164 cfgTypeHasChanges = True
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001165 for item in self.changedItems[configType][section]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001166 value = self.changedItems[configType][section][item]
Terry Jan Reedyae410862014-08-03 23:02:53 -04001167 if self.SetUserValue(configType, section, item, value):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001168 cfgTypeHasChanges = True
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001169 if cfgTypeHasChanges:
1170 idleConf.userCfg[configType].Save()
Kurt B. Kaiser5acdf932004-11-16 21:28:36 +00001171 for configType in ['keys', 'highlight']:
1172 # save these even if unchanged!
1173 idleConf.userCfg[configType].Save()
Steven M. Gavaa498af22002-02-01 01:33:36 +00001174 self.ResetChangedItems() #clear the changed items dict
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001175
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001176 def DeactivateCurrentConfig(self):
1177 #Before a config is saved, some cleanup of current
1178 #config must be done - remove the previous keybindings
Terry Jan Reedyae410862014-08-03 23:02:53 -04001179 winInstances = self.parent.instance_dict
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001180 for instance in winInstances:
1181 instance.RemoveKeybindings()
1182
Steven M. Gava49745752002-02-18 01:43:11 +00001183 def ActivateConfigChanges(self):
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001184 "Dynamically apply configuration changes"
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001185 winInstances = self.parent.instance_dict.keys()
Steven M. Gavab77d3432002-03-02 07:16:21 +00001186 for instance in winInstances:
1187 instance.ResetColorizer()
Steven M. Gavab1585412002-03-12 00:21:56 +00001188 instance.ResetFont()
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001189 instance.set_notabs_indentwidth()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001190 instance.ApplyKeybindings()
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001191 instance.reset_help_menu_entries()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001192
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001193 def Cancel(self):
1194 self.destroy()
1195
1196 def Ok(self):
1197 self.Apply()
1198 self.destroy()
1199
1200 def Apply(self):
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001201 self.DeactivateCurrentConfig()
Steven M. Gava052937f2002-02-11 02:20:53 +00001202 self.SaveAllChangedConfigs()
Steven M. Gava49745752002-02-18 01:43:11 +00001203 self.ActivateConfigChanges()
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001204
1205 def Help(self):
Steven M. Gavac11ccf32001-09-24 09:43:17 +00001206 pass
1207
Steven M. Gava44d3d1a2001-07-31 06:59:02 +00001208if __name__ == '__main__':
Terry Jan Reedyaf0dce92014-07-14 23:07:21 -04001209 import unittest
1210 unittest.main('idlelib.idle_test.test_configdialog',
1211 verbosity=2, exit=False)
1212
Terry Jan Reedy76916e82014-05-29 01:46:16 -04001213 from idlelib.idle_test.htest import run
1214 run(ConfigDialog)