blob: 2bf3ac0c3888f9b0a8c52a18ddc378688d196381 [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'])
80 frameActionButtons = Frame(self, pady=2)
Steven M. Gavad721c482001-07-31 10:46:53 +000081 #action buttons
Ned Deily57847df2014-03-27 20:47:04 -070082 if macosxSupport.isAquaTk():
Ronald Oussorena97063a2009-03-04 21:35:05 +000083 # Changing the default padding on OSX results in unreadable
84 # text in the buttons
Terry Jan Reedyae410862014-08-03 23:02:53 -040085 paddingArgs = {}
Ronald Oussorena97063a2009-03-04 21:35:05 +000086 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -040087 paddingArgs = {'padx':6, 'pady':3}
Ronald Oussorena97063a2009-03-04 21:35:05 +000088
Terry Jan Reedy1d9b9212014-01-26 22:24:17 -050089# Comment out button creation and packing until implement self.Help
Terry Jan Reedyae410862014-08-03 23:02:53 -040090## self.buttonHelp = Button(frameActionButtons, text='Help',
91## command=self.Help, takefocus=FALSE,
Terry Jan Reedy1d9b9212014-01-26 22:24:17 -050092## **paddingArgs)
Terry Jan Reedyae410862014-08-03 23:02:53 -040093 self.buttonOk = Button(
94 frameActionButtons, text='Ok',
95 command=self.Ok, takefocus=FALSE, **paddingArgs)
96 self.buttonApply = Button(
97 frameActionButtons, text='Apply',
98 command=self.Apply, takefocus=FALSE, **paddingArgs)
99 self.buttonCancel = Button(
100 frameActionButtons, text='Cancel',
101 command=self.Cancel, takefocus=FALSE, **paddingArgs)
Steven M. Gava2d4e03b2001-12-05 07:54:07 +0000102 self.CreatePageFontTab()
103 self.CreatePageHighlight()
104 self.CreatePageKeys()
105 self.CreatePageGeneral()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400106## self.buttonHelp.pack(side=RIGHT, padx=5)
107 self.buttonOk.pack(side=LEFT, padx=5)
108 self.buttonApply.pack(side=LEFT, padx=5)
109 self.buttonCancel.pack(side=LEFT, padx=5)
Steven M. Gavad721c482001-07-31 10:46:53 +0000110 frameActionButtons.pack(side=BOTTOM)
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000111 Frame(self, height=2, borderwidth=0).pack(side=BOTTOM)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400112 self.tabPages.pack(side=TOP, expand=TRUE, fill=BOTH)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000113
Steven M. Gava60fc7072001-08-04 13:58:22 +0000114 def CreatePageFontTab(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400115 parent = self.parent
116 self.fontSize = StringVar(parent)
117 self.fontBold = BooleanVar(parent)
118 self.fontName = StringVar(parent)
119 self.spaceNum = IntVar(parent)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400120 self.editFont = tkFont.Font(parent, ('courier', 10, 'normal'))
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400121
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000122 ##widget creation
123 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400124 frame = self.tabPages.pages['Fonts/Tabs'].frame
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000125 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400126 frameFont = LabelFrame(
127 frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ')
128 frameIndent = LabelFrame(
129 frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ')
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000130 #frameFont
Terry Jan Reedyae410862014-08-03 23:02:53 -0400131 frameFontName = Frame(frameFont)
132 frameFontParam = Frame(frameFont)
133 labelFontNameTitle = Label(
134 frameFontName, justify=LEFT, text='Font Face :')
135 self.listFontName = Listbox(
136 frameFontName, height=5, takefocus=FALSE, exportselection=FALSE)
137 self.listFontName.bind(
138 '<ButtonRelease-1>', self.OnListFontButtonRelease)
139 scrollFont = Scrollbar(frameFontName)
Steven M. Gavac01e30f2001-08-11 15:48:13 +0000140 scrollFont.config(command=self.listFontName.yview)
141 self.listFontName.config(yscrollcommand=scrollFont.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400142 labelFontSizeTitle = Label(frameFontParam, text='Size :')
143 self.optMenuFontSize = DynOptionMenu(
144 frameFontParam, self.fontSize, None, command=self.SetFontSample)
145 checkFontBold = Checkbutton(
146 frameFontParam, variable=self.fontBold, onvalue=1,
147 offvalue=0, text='Bold', command=self.SetFontSample)
148 frameFontSample = Frame(frameFont, relief=SOLID, borderwidth=1)
149 self.labelFontSample = Label(
150 frameFontSample, justify=LEFT, font=self.editFont,
151 text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]')
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000152 #frameIndent
Terry Jan Reedyae410862014-08-03 23:02:53 -0400153 frameIndentSize = Frame(frameIndent)
154 labelSpaceNumTitle = Label(
155 frameIndentSize, justify=LEFT,
156 text='Python Standard: 4 Spaces!')
157 self.scaleSpaceNum = Scale(
158 frameIndentSize, variable=self.spaceNum,
159 orient='horizontal', tickinterval=2, from_=2, to=16)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400160
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000161 #widget packing
162 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400163 frameFont.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
164 frameIndent.pack(side=LEFT, padx=5, pady=5, fill=Y)
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000165 #frameFont
Terry Jan Reedyae410862014-08-03 23:02:53 -0400166 frameFontName.pack(side=TOP, padx=5, pady=5, fill=X)
167 frameFontParam.pack(side=TOP, padx=5, pady=5, fill=X)
168 labelFontNameTitle.pack(side=TOP, anchor=W)
169 self.listFontName.pack(side=LEFT, expand=TRUE, fill=X)
170 scrollFont.pack(side=LEFT, fill=Y)
171 labelFontSizeTitle.pack(side=LEFT, anchor=W)
172 self.optMenuFontSize.pack(side=LEFT, anchor=W)
173 checkFontBold.pack(side=LEFT, anchor=W, padx=20)
174 frameFontSample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
175 self.labelFontSample.pack(expand=TRUE, fill=BOTH)
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000176 #frameIndent
Terry Jan Reedyae410862014-08-03 23:02:53 -0400177 frameIndentSize.pack(side=TOP, fill=X)
178 labelSpaceNumTitle.pack(side=TOP, anchor=W, padx=5)
179 self.scaleSpaceNum.pack(side=TOP, padx=5, fill=X)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000180 return frame
181
182 def CreatePageHighlight(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400183 parent = self.parent
184 self.builtinTheme = StringVar(parent)
185 self.customTheme = StringVar(parent)
186 self.fgHilite = BooleanVar(parent)
187 self.colour = StringVar(parent)
188 self.fontName = StringVar(parent)
189 self.themeIsBuiltin = BooleanVar(parent)
190 self.highlightTarget = StringVar(parent)
191
Steven M. Gava952d0a52001-08-03 04:43:44 +0000192 ##widget creation
193 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400194 frame = self.tabPages.pages['Highlighting'].frame
Steven M. Gava952d0a52001-08-03 04:43:44 +0000195 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400196 frameCustom = LabelFrame(frame, borderwidth=2, relief=GROOVE,
197 text=' Custom Highlighting ')
198 frameTheme = LabelFrame(frame, borderwidth=2, relief=GROOVE,
199 text=' Highlighting Theme ')
Steven M. Gava952d0a52001-08-03 04:43:44 +0000200 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400201 self.textHighlightSample=Text(
202 frameCustom, relief=SOLID, borderwidth=1,
203 font=('courier', 12, ''), cursor='hand2', width=21, height=11,
204 takefocus=FALSE, highlightthickness=0, wrap=NONE)
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000205 text=self.textHighlightSample
Terry Jan Reedyae410862014-08-03 23:02:53 -0400206 text.bind('<Double-Button-1>', lambda e: 'break')
207 text.bind('<B1-Motion>', lambda e: 'break')
208 textAndTags=(
209 ('#you can click here', 'comment'), ('\n', 'normal'),
210 ('#to choose items', 'comment'), ('\n', 'normal'),
211 ('def', 'keyword'), (' ', 'normal'),
212 ('func', 'definition'), ('(param):\n ', 'normal'),
213 ('"""string"""', 'string'), ('\n var0 = ', 'normal'),
214 ("'string'", 'string'), ('\n var1 = ', 'normal'),
215 ("'selected'", 'hilite'), ('\n var2 = ', 'normal'),
216 ("'found'", 'hit'), ('\n var3 = ', 'normal'),
217 ('list', 'builtin'), ('(', 'normal'),
218 ('None', 'builtin'), (')\n\n', 'normal'),
219 (' error ', 'error'), (' ', 'normal'),
220 ('cursor |', 'cursor'), ('\n ', 'normal'),
221 ('shell', 'console'), (' ', 'normal'),
222 ('stdout', 'stdout'), (' ', 'normal'),
223 ('stderr', 'stderr'), ('\n', 'normal'))
Steven M. Gava9dd16b32001-11-03 14:54:25 +0000224 for txTa in textAndTags:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400225 text.insert(END, txTa[0], txTa[1])
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400226 for element in self.themeElements:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400227 def tem(event, elem=element):
228 event.widget.winfo_toplevel().highlightTarget.set(elem)
229 text.tag_bind(
230 self.themeElements[element][0], '<ButtonPress-1>', tem)
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000231 text.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400232 self.frameColourSet = Frame(frameCustom, relief=SOLID, borderwidth=1)
233 frameFgBg = Frame(frameCustom)
234 buttonSetColour = Button(
235 self.frameColourSet, text='Choose Colour for :',
236 command=self.GetColour, highlightthickness=0)
237 self.optMenuHighlightTarget = DynOptionMenu(
238 self.frameColourSet, self.highlightTarget, None,
239 highlightthickness=0) #, command=self.SetHighlightTargetBinding
240 self.radioFg = Radiobutton(
241 frameFgBg, variable=self.fgHilite, value=1,
242 text='Foreground', command=self.SetColourSampleBinding)
243 self.radioBg=Radiobutton(
244 frameFgBg, variable=self.fgHilite, value=0,
245 text='Background', command=self.SetColourSampleBinding)
Steven M. Gava7c017862001-10-29 11:19:46 +0000246 self.fgHilite.set(1)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400247 buttonSaveCustomTheme = Button(
248 frameCustom, text='Save as New Custom Theme',
249 command=self.SaveAsNewTheme)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000250 #frameTheme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400251 labelTypeTitle = Label(frameTheme, text='Select : ')
252 self.radioThemeBuiltin = Radiobutton(
253 frameTheme, variable=self.themeIsBuiltin, value=1,
254 command=self.SetThemeType, text='a Built-in Theme')
255 self.radioThemeCustom = Radiobutton(
256 frameTheme, variable=self.themeIsBuiltin, value=0,
257 command=self.SetThemeType, text='a Custom Theme')
258 self.optMenuThemeBuiltin = DynOptionMenu(
259 frameTheme, self.builtinTheme, None, command=None)
260 self.optMenuThemeCustom=DynOptionMenu(
261 frameTheme, self.customTheme, None, command=None)
262 self.buttonDeleteCustomTheme=Button(
263 frameTheme, text='Delete Custom Theme',
Steven M. Gava49745752002-02-18 01:43:11 +0000264 command=self.DeleteCustomTheme)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400265
Steven M. Gava952d0a52001-08-03 04:43:44 +0000266 ##widget packing
267 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400268 frameCustom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
269 frameTheme.pack(side=LEFT, padx=5, pady=5, fill=Y)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000270 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400271 self.frameColourSet.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X)
272 frameFgBg.pack(side=TOP, padx=5, pady=0)
273 self.textHighlightSample.pack(
274 side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
275 buttonSetColour.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4)
276 self.optMenuHighlightTarget.pack(
277 side=TOP, expand=TRUE, fill=X, padx=8, pady=3)
278 self.radioFg.pack(side=LEFT, anchor=E)
279 self.radioBg.pack(side=RIGHT, anchor=W)
280 buttonSaveCustomTheme.pack(side=BOTTOM, fill=X, padx=5, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000281 #frameTheme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400282 labelTypeTitle.pack(side=TOP, anchor=W, padx=5, pady=5)
283 self.radioThemeBuiltin.pack(side=TOP, anchor=W, padx=5)
284 self.radioThemeCustom.pack(side=TOP, anchor=W, padx=5, pady=2)
285 self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5)
286 self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5)
287 self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000288 return frame
289
290 def CreatePageKeys(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400291 parent = self.parent
292 self.bindingTarget = StringVar(parent)
293 self.builtinKeys = StringVar(parent)
294 self.customKeys = StringVar(parent)
295 self.keysAreBuiltin = BooleanVar(parent)
296 self.keyBinding = StringVar(parent)
297
Steven M. Gava60fc7072001-08-04 13:58:22 +0000298 ##widget creation
299 #body frame
Terry Jan Reedyae410862014-08-03 23:02:53 -0400300 frame = self.tabPages.pages['Keys'].frame
Steven M. Gava60fc7072001-08-04 13:58:22 +0000301 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400302 frameCustom = LabelFrame(
303 frame, borderwidth=2, relief=GROOVE,
304 text=' Custom Key Bindings ')
305 frameKeySets = LabelFrame(
306 frame, borderwidth=2, relief=GROOVE, text=' Key Set ')
Steven M. Gava60fc7072001-08-04 13:58:22 +0000307 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400308 frameTarget = Frame(frameCustom)
309 labelTargetTitle = Label(frameTarget, text='Action - Key(s)')
310 scrollTargetY = Scrollbar(frameTarget)
311 scrollTargetX = Scrollbar(frameTarget, orient=HORIZONTAL)
312 self.listBindings = Listbox(
313 frameTarget, takefocus=FALSE, exportselection=FALSE)
314 self.listBindings.bind('<ButtonRelease-1>', self.KeyBindingSelected)
Steven M. Gavafacfc092002-01-19 00:29:54 +0000315 scrollTargetY.config(command=self.listBindings.yview)
316 scrollTargetX.config(command=self.listBindings.xview)
317 self.listBindings.config(yscrollcommand=scrollTargetY.set)
318 self.listBindings.config(xscrollcommand=scrollTargetX.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400319 self.buttonNewKeys = Button(
320 frameCustom, text='Get New Keys for Selection',
321 command=self.GetNewKeys, state=DISABLED)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000322 #frameKeySets
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000323 frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0)
324 for i in range(2)]
Terry Jan Reedyae410862014-08-03 23:02:53 -0400325 self.radioKeysBuiltin = Radiobutton(
326 frames[0], variable=self.keysAreBuiltin, value=1,
327 command=self.SetKeysType, text='Use a Built-in Key Set')
328 self.radioKeysCustom = Radiobutton(
329 frames[0], variable=self.keysAreBuiltin, value=0,
330 command=self.SetKeysType, text='Use a Custom Key Set')
331 self.optMenuKeysBuiltin = DynOptionMenu(
332 frames[0], self.builtinKeys, None, command=None)
333 self.optMenuKeysCustom = DynOptionMenu(
334 frames[0], self.customKeys, None, command=None)
335 self.buttonDeleteCustomKeys = Button(
336 frames[1], text='Delete Custom Key Set',
Steven M. Gava49745752002-02-18 01:43:11 +0000337 command=self.DeleteCustomKeys)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400338 buttonSaveCustomKeys = Button(
339 frames[1], text='Save as New Custom Key Set',
340 command=self.SaveAsNewKeySet)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400341
Steven M. Gava60fc7072001-08-04 13:58:22 +0000342 ##widget packing
343 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400344 frameCustom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH)
345 frameKeySets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000346 #frameCustom
Terry Jan Reedyae410862014-08-03 23:02:53 -0400347 self.buttonNewKeys.pack(side=BOTTOM, fill=X, padx=5, pady=5)
348 frameTarget.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
Steven M. Gavafacfc092002-01-19 00:29:54 +0000349 #frame target
Terry Jan Reedyae410862014-08-03 23:02:53 -0400350 frameTarget.columnconfigure(0, weight=1)
351 frameTarget.rowconfigure(1, weight=1)
352 labelTargetTitle.grid(row=0, column=0, columnspan=2, sticky=W)
353 self.listBindings.grid(row=1, column=0, sticky=NSEW)
354 scrollTargetY.grid(row=1, column=1, sticky=NS)
355 scrollTargetX.grid(row=2, column=0, sticky=EW)
Steven M. Gava60fc7072001-08-04 13:58:22 +0000356 #frameKeySets
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000357 self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS)
358 self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS)
359 self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW)
360 self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400361 self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
362 buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
Kurt B. Kaiser28c7bcf2007-12-28 04:18:01 +0000363 frames[0].pack(side=TOP, fill=BOTH, expand=True)
364 frames[1].pack(side=TOP, fill=X, expand=True, pady=2)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000365 return frame
366
367 def CreatePageGeneral(self):
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400368 parent = self.parent
369 self.winWidth = StringVar(parent)
370 self.winHeight = StringVar(parent)
371 self.paraWidth = StringVar(parent)
372 self.startupEdit = IntVar(parent)
373 self.autoSave = IntVar(parent)
374 self.encoding = StringVar(parent)
375 self.userHelpBrowser = BooleanVar(parent)
376 self.helpBrowser = StringVar(parent)
377
Steven M. Gava230e5782001-08-07 03:28:25 +0000378 #widget creation
379 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400380 frame = self.tabPages.pages['General'].frame
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000381 #body section frames
Terry Jan Reedyae410862014-08-03 23:02:53 -0400382 frameRun = LabelFrame(frame, borderwidth=2, relief=GROOVE,
383 text=' Startup Preferences ')
384 frameSave = LabelFrame(frame, borderwidth=2, relief=GROOVE,
385 text=' Autosave Preferences ')
386 frameWinSize = Frame(frame, borderwidth=2, relief=GROOVE)
387 frameParaSize = Frame(frame, borderwidth=2, relief=GROOVE)
388 frameEncoding = Frame(frame, borderwidth=2, relief=GROOVE)
389 frameHelp = LabelFrame(frame, borderwidth=2, relief=GROOVE,
390 text=' Additional Help Sources ')
Steven M. Gava230e5782001-08-07 03:28:25 +0000391 #frameRun
Terry Jan Reedyae410862014-08-03 23:02:53 -0400392 labelRunChoiceTitle = Label(frameRun, text='At Startup')
393 radioStartupEdit = Radiobutton(
394 frameRun, variable=self.startupEdit, value=1,
395 command=self.SetKeysType, text="Open Edit Window")
396 radioStartupShell = Radiobutton(
397 frameRun, variable=self.startupEdit, value=0,
398 command=self.SetKeysType, text='Open Shell Window')
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000399 #frameSave
Terry Jan Reedyae410862014-08-03 23:02:53 -0400400 labelRunSaveTitle = Label(frameSave, text='At Start of Run (F5) ')
401 radioSaveAsk = Radiobutton(
402 frameSave, variable=self.autoSave, value=0,
403 command=self.SetKeysType, text="Prompt to Save")
404 radioSaveAuto = Radiobutton(
405 frameSave, variable=self.autoSave, value=1,
406 command=self.SetKeysType, text='No Prompt')
Steven M. Gava230e5782001-08-07 03:28:25 +0000407 #frameWinSize
Terry Jan Reedyae410862014-08-03 23:02:53 -0400408 labelWinSizeTitle = Label(
409 frameWinSize, text='Initial Window Size (in characters)')
410 labelWinWidthTitle = Label(frameWinSize, text='Width')
411 entryWinWidth = Entry(
412 frameWinSize, textvariable=self.winWidth, width=3)
413 labelWinHeightTitle = Label(frameWinSize, text='Height')
414 entryWinHeight = Entry(
415 frameWinSize, textvariable=self.winHeight, width=3)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000416 #paragraphFormatWidth
Terry Jan Reedyae410862014-08-03 23:02:53 -0400417 labelParaWidthTitle = Label(
418 frameParaSize, text='Paragraph reformat width (in characters)')
419 entryParaWidth = Entry(
420 frameParaSize, textvariable=self.paraWidth, width=3)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000421 #frameEncoding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400422 labelEncodingTitle = Label(
423 frameEncoding, text="Default Source Encoding")
424 radioEncLocale = Radiobutton(
425 frameEncoding, variable=self.encoding,
426 value="locale", text="Locale-defined")
427 radioEncUTF8 = Radiobutton(
428 frameEncoding, variable=self.encoding,
429 value="utf-8", text="UTF-8")
430 radioEncNone = Radiobutton(
431 frameEncoding, variable=self.encoding,
432 value="none", text="None")
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000433 #frameHelp
Terry Jan Reedyae410862014-08-03 23:02:53 -0400434 frameHelpList = Frame(frameHelp)
435 frameHelpListButtons = Frame(frameHelpList)
436 scrollHelpList = Scrollbar(frameHelpList)
437 self.listHelp = Listbox(
438 frameHelpList, height=5, takefocus=FALSE,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000439 exportselection=FALSE)
440 scrollHelpList.config(command=self.listHelp.yview)
441 self.listHelp.config(yscrollcommand=scrollHelpList.set)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400442 self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected)
443 self.buttonHelpListEdit = Button(
444 frameHelpListButtons, text='Edit', state=DISABLED,
445 width=8, command=self.HelpListItemEdit)
446 self.buttonHelpListAdd = Button(
447 frameHelpListButtons, text='Add',
448 width=8, command=self.HelpListItemAdd)
449 self.buttonHelpListRemove = Button(
450 frameHelpListButtons, text='Remove', state=DISABLED,
451 width=8, command=self.HelpListItemRemove)
Terry Jan Reedy19b7a752014-07-30 19:24:26 -0400452
Steven M. Gava230e5782001-08-07 03:28:25 +0000453 #widget packing
454 #body
Terry Jan Reedyae410862014-08-03 23:02:53 -0400455 frameRun.pack(side=TOP, padx=5, pady=5, fill=X)
456 frameSave.pack(side=TOP, padx=5, pady=5, fill=X)
457 frameWinSize.pack(side=TOP, padx=5, pady=5, fill=X)
458 frameParaSize.pack(side=TOP, padx=5, pady=5, fill=X)
459 frameEncoding.pack(side=TOP, padx=5, pady=5, fill=X)
460 frameHelp.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
Steven M. Gava230e5782001-08-07 03:28:25 +0000461 #frameRun
Terry Jan Reedyae410862014-08-03 23:02:53 -0400462 labelRunChoiceTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
463 radioStartupShell.pack(side=RIGHT, anchor=W, padx=5, pady=5)
464 radioStartupEdit.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000465 #frameSave
Terry Jan Reedyae410862014-08-03 23:02:53 -0400466 labelRunSaveTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
467 radioSaveAuto.pack(side=RIGHT, anchor=W, padx=5, pady=5)
468 radioSaveAsk.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Steven M. Gava230e5782001-08-07 03:28:25 +0000469 #frameWinSize
Terry Jan Reedyae410862014-08-03 23:02:53 -0400470 labelWinSizeTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
471 entryWinHeight.pack(side=RIGHT, anchor=E, padx=10, pady=5)
472 labelWinHeightTitle.pack(side=RIGHT, anchor=E, pady=5)
473 entryWinWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
474 labelWinWidthTitle.pack(side=RIGHT, anchor=E, pady=5)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000475 #paragraphFormatWidth
Terry Jan Reedyae410862014-08-03 23:02:53 -0400476 labelParaWidthTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
477 entryParaWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000478 #frameEncoding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400479 labelEncodingTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
480 radioEncNone.pack(side=RIGHT, anchor=E, pady=5)
481 radioEncUTF8.pack(side=RIGHT, anchor=E, pady=5)
482 radioEncLocale.pack(side=RIGHT, anchor=E, pady=5)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000483 #frameHelp
Terry Jan Reedyae410862014-08-03 23:02:53 -0400484 frameHelpListButtons.pack(side=RIGHT, padx=5, pady=5, fill=Y)
485 frameHelpList.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
486 scrollHelpList.pack(side=RIGHT, anchor=W, fill=Y)
487 self.listHelp.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)
488 self.buttonHelpListEdit.pack(side=TOP, anchor=W, pady=5)
489 self.buttonHelpListAdd.pack(side=TOP, anchor=W)
490 self.buttonHelpListRemove.pack(side=TOP, anchor=W, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000491 return frame
492
Steven M. Gavac112cd82002-01-22 05:56:40 +0000493 def AttachVarCallbacks(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400494 self.fontSize.trace_variable('w', self.VarChanged_fontSize)
495 self.fontName.trace_variable('w', self.VarChanged_fontName)
496 self.fontBold.trace_variable('w', self.VarChanged_fontBold)
497 self.spaceNum.trace_variable('w', self.VarChanged_spaceNum)
498 self.colour.trace_variable('w', self.VarChanged_colour)
499 self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme)
500 self.customTheme.trace_variable('w', self.VarChanged_customTheme)
501 self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin)
502 self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget)
503 self.keyBinding.trace_variable('w', self.VarChanged_keyBinding)
504 self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys)
505 self.customKeys.trace_variable('w', self.VarChanged_customKeys)
506 self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin)
507 self.winWidth.trace_variable('w', self.VarChanged_winWidth)
508 self.winHeight.trace_variable('w', self.VarChanged_winHeight)
509 self.paraWidth.trace_variable('w', self.VarChanged_paraWidth)
510 self.startupEdit.trace_variable('w', self.VarChanged_startupEdit)
511 self.autoSave.trace_variable('w', self.VarChanged_autoSave)
512 self.encoding.trace_variable('w', self.VarChanged_encoding)
Steven M. Gava052937f2002-02-11 02:20:53 +0000513
Terry Jan Reedyae410862014-08-03 23:02:53 -0400514 def VarChanged_fontSize(self, *params):
515 value = self.fontSize.get()
516 self.AddChangedItem('main', 'EditorWindow', 'font-size', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000517
Terry Jan Reedyae410862014-08-03 23:02:53 -0400518 def VarChanged_fontName(self, *params):
519 value = self.fontName.get()
520 self.AddChangedItem('main', 'EditorWindow', 'font', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000521
Terry Jan Reedyae410862014-08-03 23:02:53 -0400522 def VarChanged_fontBold(self, *params):
523 value = self.fontBold.get()
524 self.AddChangedItem('main', 'EditorWindow', 'font-bold', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000525
Terry Jan Reedyae410862014-08-03 23:02:53 -0400526 def VarChanged_spaceNum(self, *params):
527 value = self.spaceNum.get()
528 self.AddChangedItem('main', 'Indent', 'num-spaces', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000529
Terry Jan Reedyae410862014-08-03 23:02:53 -0400530 def VarChanged_colour(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000531 self.OnNewColourSet()
532
Terry Jan Reedyae410862014-08-03 23:02:53 -0400533 def VarChanged_builtinTheme(self, *params):
534 value = self.builtinTheme.get()
535 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000536 self.PaintThemeSample()
537
Terry Jan Reedyae410862014-08-03 23:02:53 -0400538 def VarChanged_customTheme(self, *params):
539 value = self.customTheme.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000540 if value != '- no custom themes -':
Terry Jan Reedyae410862014-08-03 23:02:53 -0400541 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000542 self.PaintThemeSample()
Steven M. Gava052937f2002-02-11 02:20:53 +0000543
Terry Jan Reedyae410862014-08-03 23:02:53 -0400544 def VarChanged_themeIsBuiltin(self, *params):
545 value = self.themeIsBuiltin.get()
546 self.AddChangedItem('main', 'Theme', 'default', value)
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000547 if value:
548 self.VarChanged_builtinTheme()
549 else:
550 self.VarChanged_customTheme()
Steven M. Gava052937f2002-02-11 02:20:53 +0000551
Terry Jan Reedyae410862014-08-03 23:02:53 -0400552 def VarChanged_highlightTarget(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000553 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000554
Terry Jan Reedyae410862014-08-03 23:02:53 -0400555 def VarChanged_keyBinding(self, *params):
556 value = self.keyBinding.get()
557 keySet = self.customKeys.get()
558 event = self.listBindings.get(ANCHOR).split()[0]
Steven M. Gavaa498af22002-02-01 01:33:36 +0000559 if idleConf.IsCoreBinding(event):
560 #this is a core keybinding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400561 self.AddChangedItem('keys', keySet, event, value)
Steven M. Gavaa498af22002-02-01 01:33:36 +0000562 else: #this is an extension key binding
Terry Jan Reedyae410862014-08-03 23:02:53 -0400563 extName = idleConf.GetExtnNameForEvent(event)
564 extKeybindSection = extName + '_cfgBindings'
565 self.AddChangedItem('extensions', extKeybindSection, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000566
Terry Jan Reedyae410862014-08-03 23:02:53 -0400567 def VarChanged_builtinKeys(self, *params):
568 value = self.builtinKeys.get()
569 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000570 self.LoadKeysList(value)
571
Terry Jan Reedyae410862014-08-03 23:02:53 -0400572 def VarChanged_customKeys(self, *params):
573 value = self.customKeys.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000574 if value != '- no custom keys -':
Terry Jan Reedyae410862014-08-03 23:02:53 -0400575 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000576 self.LoadKeysList(value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000577
Terry Jan Reedyae410862014-08-03 23:02:53 -0400578 def VarChanged_keysAreBuiltin(self, *params):
579 value = self.keysAreBuiltin.get()
580 self.AddChangedItem('main', 'Keys', 'default', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000581 if value:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000582 self.VarChanged_builtinKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000583 else:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000584 self.VarChanged_customKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000585
Terry Jan Reedyae410862014-08-03 23:02:53 -0400586 def VarChanged_winWidth(self, *params):
587 value = self.winWidth.get()
588 self.AddChangedItem('main', 'EditorWindow', 'width', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000589
Terry Jan Reedyae410862014-08-03 23:02:53 -0400590 def VarChanged_winHeight(self, *params):
591 value = self.winHeight.get()
592 self.AddChangedItem('main', 'EditorWindow', 'height', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000593
Terry Jan Reedyae410862014-08-03 23:02:53 -0400594 def VarChanged_paraWidth(self, *params):
595 value = self.paraWidth.get()
596 self.AddChangedItem('main', 'FormatParagraph', 'paragraph', value)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000597
Terry Jan Reedyae410862014-08-03 23:02:53 -0400598 def VarChanged_startupEdit(self, *params):
599 value = self.startupEdit.get()
600 self.AddChangedItem('main', 'General', 'editor-on-startup', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000601
Terry Jan Reedyae410862014-08-03 23:02:53 -0400602 def VarChanged_autoSave(self, *params):
603 value = self.autoSave.get()
604 self.AddChangedItem('main', 'General', 'autosave', value)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000605
Terry Jan Reedyae410862014-08-03 23:02:53 -0400606 def VarChanged_encoding(self, *params):
607 value = self.encoding.get()
608 self.AddChangedItem('main', 'EditorWindow', 'encoding', value)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000609
Steven M. Gavaa498af22002-02-01 01:33:36 +0000610 def ResetChangedItems(self):
Steven M. Gavab77d3432002-03-02 07:16:21 +0000611 #When any config item is changed in this dialog, an entry
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000612 #should be made in the relevant section (config type) of this
613 #dictionary. The key should be the config file section name and the
Steven M. Gavaa498af22002-02-01 01:33:36 +0000614 #value a dictionary, whose key:value pairs are item=value pairs for
615 #that config file section.
Terry Jan Reedyae410862014-08-03 23:02:53 -0400616 self.changedItems = {'main':{}, 'highlight':{}, 'keys':{},
617 'extensions':{}}
Steven M. Gavaa498af22002-02-01 01:33:36 +0000618
Terry Jan Reedyae410862014-08-03 23:02:53 -0400619 def AddChangedItem(self, typ, section, item, value):
620 value = str(value) #make sure we use a string
621 if section not in self.changedItems[typ]:
622 self.changedItems[typ][section] = {}
623 self.changedItems[typ][section][item] = value
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000624
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000625 def GetDefaultItems(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400626 dItems={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}}
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400627 for configType in dItems:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400628 sections = idleConf.GetSectionList('default', configType)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000629 for section in sections:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400630 dItems[configType][section] = {}
631 options = idleConf.defaultCfg[configType].GetOptionList(section)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000632 for option in options:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400633 dItems[configType][section][option] = (
634 idleConf.defaultCfg[configType].Get(section, option))
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000635 return dItems
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000636
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000637 def SetThemeType(self):
638 if self.themeIsBuiltin.get():
639 self.optMenuThemeBuiltin.config(state=NORMAL)
640 self.optMenuThemeCustom.config(state=DISABLED)
641 self.buttonDeleteCustomTheme.config(state=DISABLED)
642 else:
643 self.optMenuThemeBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000644 self.radioThemeCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000645 self.optMenuThemeCustom.config(state=NORMAL)
646 self.buttonDeleteCustomTheme.config(state=NORMAL)
647
648 def SetKeysType(self):
Steven M. Gava052937f2002-02-11 02:20:53 +0000649 if self.keysAreBuiltin.get():
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000650 self.optMenuKeysBuiltin.config(state=NORMAL)
651 self.optMenuKeysCustom.config(state=DISABLED)
652 self.buttonDeleteCustomKeys.config(state=DISABLED)
653 else:
654 self.optMenuKeysBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000655 self.radioKeysCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000656 self.optMenuKeysCustom.config(state=NORMAL)
657 self.buttonDeleteCustomKeys.config(state=NORMAL)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000658
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000659 def GetNewKeys(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400660 listIndex = self.listBindings.index(ANCHOR)
661 binding = self.listBindings.get(listIndex)
662 bindName = binding.split()[0] #first part, up to first space
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000663 if self.keysAreBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400664 currentKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000665 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400666 currentKeySetName = self.customKeys.get()
667 currentBindings = idleConf.GetCurrentKeySet()
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400668 if currentKeySetName in self.changedItems['keys']: #unsaved changes
Terry Jan Reedyae410862014-08-03 23:02:53 -0400669 keySetChanges = self.changedItems['keys'][currentKeySetName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400670 for event in keySetChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400671 currentBindings[event] = keySetChanges[event].split()
672 currentKeySequences = currentBindings.values()
673 newKeys = GetKeysDialog(self, 'Get New Keys', bindName,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000674 currentKeySequences).result
675 if newKeys: #new keys were specified
Steven M. Gava052937f2002-02-11 02:20:53 +0000676 if self.keysAreBuiltin.get(): #current key set is a built-in
Terry Jan Reedyae410862014-08-03 23:02:53 -0400677 message = ('Your changes will be saved as a new Custom Key Set.'
678 ' Enter a name for your new Custom Key Set below.')
679 newKeySet = self.GetNewKeysName(message)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000680 if not newKeySet: #user cancelled custom key set creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000681 self.listBindings.select_set(listIndex)
682 self.listBindings.select_anchor(listIndex)
683 return
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000684 else: #create new custom key set based on previously active key set
685 self.CreateNewKeySet(newKeySet)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000686 self.listBindings.delete(listIndex)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400687 self.listBindings.insert(listIndex, bindName+' - '+newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000688 self.listBindings.select_set(listIndex)
689 self.listBindings.select_anchor(listIndex)
Steven M. Gava052937f2002-02-11 02:20:53 +0000690 self.keyBinding.set(newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000691 else:
692 self.listBindings.select_set(listIndex)
693 self.listBindings.select_anchor(listIndex)
694
Terry Jan Reedyae410862014-08-03 23:02:53 -0400695 def GetNewKeysName(self, message):
696 usedNames = (idleConf.GetSectionList('user', 'keys') +
697 idleConf.GetSectionList('default', 'keys'))
698 newKeySet = GetCfgSectionNameDialog(
699 self, 'New Custom Key Set', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000700 return newKeySet
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000701
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000702 def SaveAsNewKeySet(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400703 newKeysName = self.GetNewKeysName('New Key Set Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000704 if newKeysName:
705 self.CreateNewKeySet(newKeysName)
706
Terry Jan Reedyae410862014-08-03 23:02:53 -0400707 def KeyBindingSelected(self, event):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000708 self.buttonNewKeys.config(state=NORMAL)
709
Terry Jan Reedyae410862014-08-03 23:02:53 -0400710 def CreateNewKeySet(self, newKeySetName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000711 #creates new custom key set based on the previously active key set,
712 #and makes the new key set active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000713 if self.keysAreBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400714 prevKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000715 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400716 prevKeySetName = self.customKeys.get()
717 prevKeys = idleConf.GetCoreKeys(prevKeySetName)
718 newKeys = {}
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400719 for event in prevKeys: #add key set to changed items
Terry Jan Reedyae410862014-08-03 23:02:53 -0400720 eventName = event[2:-2] #trim off the angle brackets
721 binding = ' '.join(prevKeys[event])
722 newKeys[eventName] = binding
Steven M. Gava052937f2002-02-11 02:20:53 +0000723 #handle any unsaved changes to prev key set
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400724 if prevKeySetName in self.changedItems['keys']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400725 keySetChanges = self.changedItems['keys'][prevKeySetName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400726 for event in keySetChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400727 newKeys[event] = keySetChanges[event]
Steven M. Gava052937f2002-02-11 02:20:53 +0000728 #save the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400729 self.SaveNewKeySet(newKeySetName, newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000730 #change gui over to the new key set
Terry Jan Reedyae410862014-08-03 23:02:53 -0400731 customKeyList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000732 customKeyList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400733 self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000734 self.keysAreBuiltin.set(0)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000735 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000736
Terry Jan Reedyae410862014-08-03 23:02:53 -0400737 def LoadKeysList(self, keySetName):
738 reselect = 0
739 newKeySet = 0
Steven M. Gava052937f2002-02-11 02:20:53 +0000740 if self.listBindings.curselection():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400741 reselect = 1
742 listIndex = self.listBindings.index(ANCHOR)
743 keySet = idleConf.GetKeySet(keySetName)
744 bindNames = keySet.keys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000745 bindNames.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400746 self.listBindings.delete(0, END)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000747 for bindName in bindNames:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400748 key = ' '.join(keySet[bindName]) #make key(s) into a string
749 bindName = bindName[2:-2] #trim off the angle brackets
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400750 if keySetName in self.changedItems['keys']:
Steven M. Gava052937f2002-02-11 02:20:53 +0000751 #handle any unsaved changes to this key set
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400752 if bindName in self.changedItems['keys'][keySetName]:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400753 key = self.changedItems['keys'][keySetName][bindName]
Steven M. Gava052937f2002-02-11 02:20:53 +0000754 self.listBindings.insert(END, bindName+' - '+key)
Steven M. Gava052937f2002-02-11 02:20:53 +0000755 if reselect:
756 self.listBindings.see(listIndex)
757 self.listBindings.select_set(listIndex)
758 self.listBindings.select_anchor(listIndex)
759
Steven M. Gava49745752002-02-18 01:43:11 +0000760 def DeleteCustomKeys(self):
761 keySetName=self.customKeys.get()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400762 delmsg = 'Are you sure you wish to delete the key set %r ?'
763 if not tkMessageBox.askyesno(
764 'Delete Key Set', delmsg % keySetName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000765 return
766 #remove key set from config
767 idleConf.userCfg['keys'].remove_section(keySetName)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +0000768 if keySetName in self.changedItems['keys']:
Steven M. Gava49745752002-02-18 01:43:11 +0000769 del(self.changedItems['keys'][keySetName])
770 #write changes
771 idleConf.userCfg['keys'].Save()
772 #reload user key set list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400773 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gava49745752002-02-18 01:43:11 +0000774 itemList.sort()
775 if not itemList:
776 self.radioKeysCustom.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400777 self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -')
Steven M. Gava49745752002-02-18 01:43:11 +0000778 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400779 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000780 #revert to default key set
Terry Jan Reedyae410862014-08-03 23:02:53 -0400781 self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
782 self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000783 #user can't back out of these changes, they must be applied now
784 self.Apply()
785 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000786
Steven M. Gava49745752002-02-18 01:43:11 +0000787 def DeleteCustomTheme(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400788 themeName = self.customTheme.get()
789 delmsg = 'Are you sure you wish to delete the theme %r ?'
790 if not tkMessageBox.askyesno(
791 'Delete Theme', delmsg % themeName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000792 return
793 #remove theme from config
794 idleConf.userCfg['highlight'].remove_section(themeName)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +0000795 if themeName in self.changedItems['highlight']:
Steven M. Gava49745752002-02-18 01:43:11 +0000796 del(self.changedItems['highlight'][themeName])
797 #write changes
798 idleConf.userCfg['highlight'].Save()
799 #reload user theme list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400800 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gava49745752002-02-18 01:43:11 +0000801 itemList.sort()
802 if not itemList:
803 self.radioThemeCustom.config(state=DISABLED)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400804 self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -')
Steven M. Gava49745752002-02-18 01:43:11 +0000805 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400806 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000807 #revert to default theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400808 self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
809 self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000810 #user can't back out of these changes, they must be applied now
811 self.Apply()
812 self.SetThemeType()
813
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000814 def GetColour(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400815 target = self.highlightTarget.get()
816 prevColour = self.frameColourSet.cget('bg')
817 rgbTuplet, colourString = tkColorChooser.askcolor(
818 parent=self, title='Pick new colour for : '+target,
819 initialcolor=prevColour)
820 if colourString and (colourString != prevColour):
Steven M. Gava052937f2002-02-11 02:20:53 +0000821 #user didn't cancel, and they chose a new colour
Terry Jan Reedyae410862014-08-03 23:02:53 -0400822 if self.themeIsBuiltin.get(): #current theme is a built-in
823 message = ('Your changes will be saved as a new Custom Theme. '
824 'Enter a name for your new Custom Theme below.')
825 newTheme = self.GetNewThemeName(message)
826 if not newTheme: #user cancelled custom theme creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000827 return
Terry Jan Reedyae410862014-08-03 23:02:53 -0400828 else: #create new custom theme based on previously active theme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000829 self.CreateNewTheme(newTheme)
Steven M. Gava052937f2002-02-11 02:20:53 +0000830 self.colour.set(colourString)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400831 else: #current theme is user defined
Steven M. Gava052937f2002-02-11 02:20:53 +0000832 self.colour.set(colourString)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000833
Steven M. Gava052937f2002-02-11 02:20:53 +0000834 def OnNewColourSet(self):
835 newColour=self.colour.get()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400836 self.frameColourSet.config(bg=newColour) #set sample
837 plane ='foreground' if self.fgHilite.get() else 'background'
838 sampleElement = self.themeElements[self.highlightTarget.get()][0]
Raymond Hettinger931237e2003-07-09 18:48:24 +0000839 self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
Terry Jan Reedyae410862014-08-03 23:02:53 -0400840 theme = self.customTheme.get()
841 themeElement = sampleElement + '-' + plane
842 self.AddChangedItem('highlight', theme, themeElement, newColour)
Steven M. Gava052937f2002-02-11 02:20:53 +0000843
Terry Jan Reedyae410862014-08-03 23:02:53 -0400844 def GetNewThemeName(self, message):
845 usedNames = (idleConf.GetSectionList('user', 'highlight') +
846 idleConf.GetSectionList('default', 'highlight'))
847 newTheme = GetCfgSectionNameDialog(
848 self, 'New Custom Theme', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000849 return newTheme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000850
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000851 def SaveAsNewTheme(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400852 newThemeName = self.GetNewThemeName('New Theme Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000853 if newThemeName:
854 self.CreateNewTheme(newThemeName)
855
Terry Jan Reedyae410862014-08-03 23:02:53 -0400856 def CreateNewTheme(self, newThemeName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000857 #creates new custom theme based on the previously active theme,
858 #and makes the new theme active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000859 if self.themeIsBuiltin.get():
Terry Jan Reedyae410862014-08-03 23:02:53 -0400860 themeType = 'default'
861 themeName = self.builtinTheme.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000862 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400863 themeType = 'user'
864 themeName = self.customTheme.get()
865 newTheme = idleConf.GetThemeDict(themeType, themeName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000866 #apply any of the old theme's unsaved changes to the new theme
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400867 if themeName in self.changedItems['highlight']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400868 themeChanges = self.changedItems['highlight'][themeName]
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400869 for element in themeChanges:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400870 newTheme[element] = themeChanges[element]
Steven M. Gava052937f2002-02-11 02:20:53 +0000871 #save the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400872 self.SaveNewTheme(newThemeName, newTheme)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000873 #change gui over to the new theme
Terry Jan Reedyae410862014-08-03 23:02:53 -0400874 customThemeList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000875 customThemeList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -0400876 self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000877 self.themeIsBuiltin.set(0)
878 self.SetThemeType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000879
Terry Jan Reedyae410862014-08-03 23:02:53 -0400880 def OnListFontButtonRelease(self, event):
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000881 font = self.listFontName.get(ANCHOR)
882 self.fontName.set(font.lower())
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000883 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000884
Terry Jan Reedyae410862014-08-03 23:02:53 -0400885 def SetFontSample(self, event=None):
886 fontName = self.fontName.get()
887 fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL
Ned Deilye3d47122012-10-22 15:13:01 -0700888 newFont = (fontName, self.fontSize.get(), fontWeight)
889 self.labelFontSample.config(font=newFont)
890 self.textHighlightSample.configure(font=newFont)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000891
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000892 def SetHighlightTarget(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400893 if self.highlightTarget.get() == 'Cursor': #bg not possible
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000894 self.radioFg.config(state=DISABLED)
895 self.radioBg.config(state=DISABLED)
896 self.fgHilite.set(1)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400897 else: #both fg and bg can be set
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000898 self.radioFg.config(state=NORMAL)
899 self.radioBg.config(state=NORMAL)
900 self.fgHilite.set(1)
901 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000902
Terry Jan Reedyae410862014-08-03 23:02:53 -0400903 def SetColourSampleBinding(self, *args):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000904 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000905
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000906 def SetColourSample(self):
907 #set the colour smaple area
Terry Jan Reedyae410862014-08-03 23:02:53 -0400908 tag = self.themeElements[self.highlightTarget.get()][0]
909 plane = 'foreground' if self.fgHilite.get() else 'background'
910 colour = self.textHighlightSample.tag_cget(tag, plane)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000911 self.frameColourSet.config(bg=colour)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000912
Steven M. Gava9dd16b32001-11-03 14:54:25 +0000913 def PaintThemeSample(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400914 if self.themeIsBuiltin.get(): #a default theme
915 theme = self.builtinTheme.get()
916 else: #a user theme
917 theme = self.customTheme.get()
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400918 for elementTitle in self.themeElements:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400919 element = self.themeElements[elementTitle][0]
920 colours = idleConf.GetHighlight(theme, element)
921 if element == 'cursor': #cursor sample needs special painting
922 colours['background'] = idleConf.GetHighlight(
923 theme, 'normal', fgBg='bg')
Steven M. Gava052937f2002-02-11 02:20:53 +0000924 #handle any unsaved changes to this theme
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400925 if theme in self.changedItems['highlight']:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400926 themeDict = self.changedItems['highlight'][theme]
927 if element + '-foreground' in themeDict:
928 colours['foreground'] = themeDict[element + '-foreground']
929 if element + '-background' in themeDict:
930 colours['background'] = themeDict[element + '-background']
Raymond Hettinger931237e2003-07-09 18:48:24 +0000931 self.textHighlightSample.tag_config(element, **colours)
Steven M. Gava052937f2002-02-11 02:20:53 +0000932 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000933
Terry Jan Reedyae410862014-08-03 23:02:53 -0400934 def HelpSourceSelected(self, event):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000935 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000936
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000937 def SetHelpListButtonStates(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400938 if self.listHelp.size() < 1: #no entries in list
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000939 self.buttonHelpListEdit.config(state=DISABLED)
940 self.buttonHelpListRemove.config(state=DISABLED)
941 else: #there are some entries
Terry Jan Reedyae410862014-08-03 23:02:53 -0400942 if self.listHelp.curselection(): #there currently is a selection
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000943 self.buttonHelpListEdit.config(state=NORMAL)
944 self.buttonHelpListRemove.config(state=NORMAL)
945 else: #there currently is not a selection
946 self.buttonHelpListEdit.config(state=DISABLED)
947 self.buttonHelpListRemove.config(state=DISABLED)
948
949 def HelpListItemAdd(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400950 helpSource = GetHelpSourceDialog(self, 'New Help Source').result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000951 if helpSource:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400952 self.userHelpList.append((helpSource[0], helpSource[1]))
953 self.listHelp.insert(END, helpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000954 self.UpdateUserHelpChangedItems()
955 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000956
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000957 def HelpListItemEdit(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400958 itemIndex = self.listHelp.index(ANCHOR)
959 helpSource = self.userHelpList[itemIndex]
960 newHelpSource = GetHelpSourceDialog(
961 self, 'Edit Help Source', menuItem=helpSource[0],
962 filePath=helpSource[1]).result
963 if (not newHelpSource) or (newHelpSource == helpSource):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000964 return #no changes
Terry Jan Reedyae410862014-08-03 23:02:53 -0400965 self.userHelpList[itemIndex] = newHelpSource
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000966 self.listHelp.delete(itemIndex)
Terry Jan Reedyae410862014-08-03 23:02:53 -0400967 self.listHelp.insert(itemIndex, newHelpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000968 self.UpdateUserHelpChangedItems()
969 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000970
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000971 def HelpListItemRemove(self):
Terry Jan Reedyae410862014-08-03 23:02:53 -0400972 itemIndex = self.listHelp.index(ANCHOR)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000973 del(self.userHelpList[itemIndex])
974 self.listHelp.delete(itemIndex)
975 self.UpdateUserHelpChangedItems()
976 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000977
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000978 def UpdateUserHelpChangedItems(self):
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +0000979 "Clear and rebuild the HelpFiles section in self.changedItems"
980 self.changedItems['main']['HelpFiles'] = {}
Terry Jan Reedyae410862014-08-03 23:02:53 -0400981 for num in range(1, len(self.userHelpList) + 1):
982 self.AddChangedItem(
983 'main', 'HelpFiles', str(num),
Terry Jan Reedy110796f2014-07-27 04:07:18 -0400984 ';'.join(self.userHelpList[num-1][:2]))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000985
Steven M. Gava429a86a2001-10-23 10:42:12 +0000986 def LoadFontCfg(self):
987 ##base editor font selection list
Terry Jan Reedyae410862014-08-03 23:02:53 -0400988 fonts = list(tkFont.families(self))
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000989 fonts.sort()
990 for font in fonts:
Terry Jan Reedyae410862014-08-03 23:02:53 -0400991 self.listFontName.insert(END, font)
992 configuredFont = idleConf.GetOption(
993 'main', 'EditorWindow', 'font', default='courier')
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000994 lc_configuredFont = configuredFont.lower()
995 self.fontName.set(lc_configuredFont)
996 lc_fonts = [s.lower() for s in fonts]
997 if lc_configuredFont in lc_fonts:
998 currentFontIndex = lc_fonts.index(lc_configuredFont)
Steven M. Gava429a86a2001-10-23 10:42:12 +0000999 self.listFontName.see(currentFontIndex)
1000 self.listFontName.select_set(currentFontIndex)
Steven M. Gavac112cd82002-01-22 05:56:40 +00001001 self.listFontName.select_anchor(currentFontIndex)
Steven M. Gava429a86a2001-10-23 10:42:12 +00001002 ##font size dropdown
Terry Jan Reedyae410862014-08-03 23:02:53 -04001003 fontSize = idleConf.GetOption(
1004 'main', 'EditorWindow', 'font-size', type='int', default='10')
1005 self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13',
1006 '14', '16', '18', '20', '22'), fontSize )
Steven M. Gavac112cd82002-01-22 05:56:40 +00001007 ##fontWeight
Terry Jan Reedyae410862014-08-03 23:02:53 -04001008 self.fontBold.set(idleConf.GetOption(
1009 'main', 'EditorWindow', 'font-bold', default=0, type='bool'))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001010 ##font sample
Steven M. Gava429a86a2001-10-23 10:42:12 +00001011 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001012
Steven M. Gava429a86a2001-10-23 10:42:12 +00001013 def LoadTabCfg(self):
Steven M. Gava429a86a2001-10-23 10:42:12 +00001014 ##indent sizes
Terry Jan Reedyae410862014-08-03 23:02:53 -04001015 spaceNum = idleConf.GetOption(
1016 'main', 'Indent', 'num-spaces', default=4, type='int')
Steven M. Gava429a86a2001-10-23 10:42:12 +00001017 self.spaceNum.set(spaceNum)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001018
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001019 def LoadThemeCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001020 ##current theme type radiobutton
Terry Jan Reedyae410862014-08-03 23:02:53 -04001021 self.themeIsBuiltin.set(idleConf.GetOption(
1022 'main', 'Theme', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001023 ##currently set theme
Terry Jan Reedyae410862014-08-03 23:02:53 -04001024 currentOption = idleConf.CurrentTheme()
Steven M. Gava7c017862001-10-29 11:19:46 +00001025 ##load available theme option menus
Steven M. Gavad0342cd2001-11-04 11:53:10 +00001026 if self.themeIsBuiltin.get(): #default theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001027 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001028 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001029 self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
1030 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001031 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001032 if not itemList:
1033 self.radioThemeCustom.config(state=DISABLED)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001034 self.customTheme.set('- no custom themes -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001035 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001036 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001037 else: #user theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001038 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001039 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001040 self.optMenuThemeCustom.SetMenu(itemList, currentOption)
1041 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001042 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001043 self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
Steven M. Gava7c017862001-10-29 11:19:46 +00001044 self.SetThemeType()
1045 ##load theme element option menu
Terry Jan Reedyae410862014-08-03 23:02:53 -04001046 themeNames = self.themeElements.keys()
Florent Xiclunaa7f242f2010-04-02 08:15:26 +00001047 themeNames.sort(key=lambda x: self.themeElements[x][1])
Terry Jan Reedyae410862014-08-03 23:02:53 -04001048 self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001049 self.PaintThemeSample()
Steven M. Gava0cae01c2002-01-04 07:53:06 +00001050 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001051
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001052 def LoadKeyCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001053 ##current keys type radiobutton
Terry Jan Reedyae410862014-08-03 23:02:53 -04001054 self.keysAreBuiltin.set(idleConf.GetOption(
1055 'main', 'Keys', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001056 ##currently set keys
Terry Jan Reedyae410862014-08-03 23:02:53 -04001057 currentOption = idleConf.CurrentKeys()
Steven M. Gava7c017862001-10-29 11:19:46 +00001058 ##load available keyset option menus
Steven M. Gava052937f2002-02-11 02:20:53 +00001059 if self.keysAreBuiltin.get(): #default theme selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001060 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001061 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001062 self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
1063 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001064 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001065 if not itemList:
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001066 self.radioKeysCustom.config(state=DISABLED)
1067 self.customKeys.set('- no custom keys -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001068 else:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001069 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gavaa498af22002-02-01 01:33:36 +00001070 else: #user key set selected
Terry Jan Reedyae410862014-08-03 23:02:53 -04001071 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001072 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001073 self.optMenuKeysCustom.SetMenu(itemList, currentOption)
1074 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001075 itemList.sort()
Terry Jan Reedyae410862014-08-03 23:02:53 -04001076 self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001077 self.SetKeysType()
Steven M. Gavafacfc092002-01-19 00:29:54 +00001078 ##load keyset element list
Terry Jan Reedyae410862014-08-03 23:02:53 -04001079 keySetName = idleConf.CurrentKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +00001080 self.LoadKeysList(keySetName)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001081
Steven M. Gavafacfc092002-01-19 00:29:54 +00001082 def LoadGeneralCfg(self):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001083 #startup state
Terry Jan Reedyae410862014-08-03 23:02:53 -04001084 self.startupEdit.set(idleConf.GetOption(
1085 'main', 'General', 'editor-on-startup', default=1, type='bool'))
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +00001086 #autosave state
Terry Jan Reedyae410862014-08-03 23:02:53 -04001087 self.autoSave.set(idleConf.GetOption(
1088 'main', 'General', 'autosave', default=0, type='bool'))
Steven M. Gavafacfc092002-01-19 00:29:54 +00001089 #initial window size
Terry Jan Reedyae410862014-08-03 23:02:53 -04001090 self.winWidth.set(idleConf.GetOption(
1091 'main', 'EditorWindow', 'width', type='int'))
1092 self.winHeight.set(idleConf.GetOption(
1093 'main', 'EditorWindow', 'height', type='int'))
Raymond Hettinger4e49b832004-06-04 06:31:08 +00001094 #initial paragraph reformat size
Terry Jan Reedyae410862014-08-03 23:02:53 -04001095 self.paraWidth.set(idleConf.GetOption(
1096 'main', 'FormatParagraph', 'paragraph', type='int'))
Kurt B. Kaisera053f332003-05-10 00:49:56 +00001097 # default source encoding
Terry Jan Reedyae410862014-08-03 23:02:53 -04001098 self.encoding.set(idleConf.GetOption(
1099 'main', 'EditorWindow', 'encoding', default='none'))
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001100 # additional help sources
1101 self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001102 for helpItem in self.userHelpList:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001103 self.listHelp.insert(END, helpItem[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001104 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001105
Steven M. Gava429a86a2001-10-23 10:42:12 +00001106 def LoadConfigs(self):
1107 """
1108 load configuration from default and user config files and populate
1109 the widgets on the config dialog pages.
1110 """
1111 ### fonts / tabs page
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001112 self.LoadFontCfg()
1113 self.LoadTabCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001114 ### highlighting page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001115 self.LoadThemeCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001116 ### keys page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001117 self.LoadKeyCfg()
Steven M. Gava429a86a2001-10-23 10:42:12 +00001118 ### general page
Steven M. Gavafacfc092002-01-19 00:29:54 +00001119 self.LoadGeneralCfg()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001120
Terry Jan Reedyae410862014-08-03 23:02:53 -04001121 def SaveNewKeySet(self, keySetName, keySet):
Steven M. Gava052937f2002-02-11 02:20:53 +00001122 """
1123 save a newly created core key set.
1124 keySetName - string, the name of the new key set
1125 keySet - dictionary containing the new key set
1126 """
1127 if not idleConf.userCfg['keys'].has_section(keySetName):
1128 idleConf.userCfg['keys'].add_section(keySetName)
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001129 for event in keySet:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001130 value = keySet[event]
1131 idleConf.userCfg['keys'].SetOption(keySetName, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001132
Terry Jan Reedyae410862014-08-03 23:02:53 -04001133 def SaveNewTheme(self, themeName, theme):
Steven M. Gava052937f2002-02-11 02:20:53 +00001134 """
1135 save a newly created theme.
1136 themeName - string, the name of the new theme
1137 theme - dictionary containing the new theme
1138 """
1139 if not idleConf.userCfg['highlight'].has_section(themeName):
1140 idleConf.userCfg['highlight'].add_section(themeName)
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001141 for element in theme:
Terry Jan Reedyae410862014-08-03 23:02:53 -04001142 value = theme[element]
1143 idleConf.userCfg['highlight'].SetOption(themeName, element, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001144
Terry Jan Reedyae410862014-08-03 23:02:53 -04001145 def SetUserValue(self, configType, section, item, value):
1146 if idleConf.defaultCfg[configType].has_option(section, item):
1147 if idleConf.defaultCfg[configType].Get(section, item) == value:
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001148 #the setting equals a default setting, remove it from user cfg
Terry Jan Reedyae410862014-08-03 23:02:53 -04001149 return idleConf.userCfg[configType].RemoveOption(section, item)
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001150 #if we got here set the option
Terry Jan Reedyae410862014-08-03 23:02:53 -04001151 return idleConf.userCfg[configType].SetOption(section, item, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001152
Steven M. Gava052937f2002-02-11 02:20:53 +00001153 def SaveAllChangedConfigs(self):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001154 "Save configuration changes to the user config file."
Steven M. Gava0c5bc8c2002-03-27 02:25:44 +00001155 idleConf.userCfg['main'].Save()
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001156 for configType in self.changedItems:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001157 cfgTypeHasChanges = False
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001158 for section in self.changedItems[configType]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001159 if section == 'HelpFiles':
1160 #this section gets completely replaced
1161 idleConf.userCfg['main'].remove_section('HelpFiles')
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001162 cfgTypeHasChanges = True
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001163 for item in self.changedItems[configType][section]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001164 value = self.changedItems[configType][section][item]
Terry Jan Reedyae410862014-08-03 23:02:53 -04001165 if self.SetUserValue(configType, section, item, value):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001166 cfgTypeHasChanges = True
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001167 if cfgTypeHasChanges:
1168 idleConf.userCfg[configType].Save()
Kurt B. Kaiser5acdf932004-11-16 21:28:36 +00001169 for configType in ['keys', 'highlight']:
1170 # save these even if unchanged!
1171 idleConf.userCfg[configType].Save()
Steven M. Gavaa498af22002-02-01 01:33:36 +00001172 self.ResetChangedItems() #clear the changed items dict
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001173
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001174 def DeactivateCurrentConfig(self):
1175 #Before a config is saved, some cleanup of current
1176 #config must be done - remove the previous keybindings
Terry Jan Reedyae410862014-08-03 23:02:53 -04001177 winInstances = self.parent.instance_dict
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001178 for instance in winInstances:
1179 instance.RemoveKeybindings()
1180
Steven M. Gava49745752002-02-18 01:43:11 +00001181 def ActivateConfigChanges(self):
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001182 "Dynamically apply configuration changes"
Terry Jan Reedy110796f2014-07-27 04:07:18 -04001183 winInstances = self.parent.instance_dict.keys()
Steven M. Gavab77d3432002-03-02 07:16:21 +00001184 for instance in winInstances:
1185 instance.ResetColorizer()
Steven M. Gavab1585412002-03-12 00:21:56 +00001186 instance.ResetFont()
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001187 instance.set_notabs_indentwidth()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001188 instance.ApplyKeybindings()
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001189 instance.reset_help_menu_entries()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001190
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001191 def Cancel(self):
1192 self.destroy()
1193
1194 def Ok(self):
1195 self.Apply()
1196 self.destroy()
1197
1198 def Apply(self):
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001199 self.DeactivateCurrentConfig()
Steven M. Gava052937f2002-02-11 02:20:53 +00001200 self.SaveAllChangedConfigs()
Steven M. Gava49745752002-02-18 01:43:11 +00001201 self.ActivateConfigChanges()
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001202
1203 def Help(self):
Steven M. Gavac11ccf32001-09-24 09:43:17 +00001204 pass
1205
Steven M. Gava44d3d1a2001-07-31 06:59:02 +00001206if __name__ == '__main__':
Terry Jan Reedyaf0dce92014-07-14 23:07:21 -04001207 import unittest
1208 unittest.main('idlelib.idle_test.test_configdialog',
1209 verbosity=2, exit=False)
1210
Terry Jan Reedy76916e82014-05-29 01:46:16 -04001211 from idlelib.idle_test.htest import run
1212 run(ConfigDialog)