blob: 70b0b3bd9ccf6e3b481d870d4ef1f1d4c9c04847 [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 Brandl14fc4272008-05-17 18:39:55 +000012from tkinter import *
13import tkinter.messagebox as tkMessageBox
14import tkinter.colorchooser as tkColorChooser
15import tkinter.font as tkFont
Steven M. Gava44d3d1a2001-07-31 06:59:02 +000016
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000017from idlelib.configHandler import idleConf
18from idlelib.dynOptionMenuWidget import DynOptionMenu
Guido van Rossum8ce8a782007-11-01 19:42:39 +000019from idlelib.tabbedpages import TabbedPageSet
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000020from idlelib.keybindingDialog import GetKeysDialog
21from idlelib.configSectionNameDialog import GetCfgSectionNameDialog
22from idlelib.configHelpSourceEdit import GetHelpSourceDialog
Ronald Oussoren9e350042009-02-12 16:02:11 +000023from idlelib import macosxSupport
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +000024
Steven M. Gava44d3d1a2001-07-31 06:59:02 +000025class ConfigDialog(Toplevel):
Kurt B. Kaiseracdef852005-01-31 03:34:26 +000026
Terry Jan Reedycfa89502014-07-14 23:07:32 -040027 def __init__(self, parent, title, _htest=False, _utest=False):
Terry Jan Reedy2e8234a2014-05-29 01:46:26 -040028 """
29 _htest - bool, change box location when running htest
Terry Jan Reedycfa89502014-07-14 23:07:32 -040030 _utest - bool, don't wait_window when running unittest
Terry Jan Reedy2e8234a2014-05-29 01:46:26 -040031 """
Steven M. Gavad721c482001-07-31 10:46:53 +000032 Toplevel.__init__(self, parent)
Terry Jan Reedy22405332014-07-30 19:24:32 -040033 self.parent = parent
Terry Jan Reedy4036d872014-08-03 23:02:58 -040034 if _htest:
35 parent.instance_dict = {}
Guido van Rossum8ce8a782007-11-01 19:42:39 +000036 self.wm_withdraw()
37
Steven M. Gavad721c482001-07-31 10:46:53 +000038 self.configure(borderwidth=5)
Alexandre Vassalottie52e3782009-07-17 09:18:18 +000039 self.title('IDLE Preferences')
Terry Jan Reedy4036d872014-08-03 23:02:58 -040040 self.geometry(
41 "+%d+%d" % (parent.winfo_rootx() + 20,
42 parent.winfo_rooty() + (30 if not _htest else 150)))
Georg Brandl7eb4b7d2005-07-22 21:49:32 +000043 #Theme Elements. Each theme element key is its display name.
Steven M. Gava9dd16b32001-11-03 14:54:25 +000044 #The first value of the tuple is the sample area tag name.
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000045 #The second value is the display name list sort index.
Terry Jan Reedy4036d872014-08-03 23:02:58 -040046 self.themeElements={
47 'Normal Text':('normal', '00'),
48 'Python Keywords':('keyword', '01'),
49 'Python Definitions':('definition', '02'),
Kurt B. Kaiser73360a32004-03-08 18:15:31 +000050 'Python Builtins':('builtin', '03'),
Terry Jan Reedy4036d872014-08-03 23:02:58 -040051 'Python Comments':('comment', '04'),
52 'Python Strings':('string', '05'),
53 'Selected Text':('hilite', '06'),
54 'Found Text':('hit', '07'),
55 'Cursor':('cursor', '08'),
56 'Error Text':('error', '09'),
57 'Shell Normal Text':('console', '10'),
58 'Shell Stdout Text':('stdout', '11'),
59 'Shell Stderr Text':('stderr', '12'),
Kurt B. Kaiser73360a32004-03-08 18:15:31 +000060 }
Steven M. Gavaa498af22002-02-01 01:33:36 +000061 self.ResetChangedItems() #load initial values in changed items dict
Steven M. Gavad721c482001-07-31 10:46:53 +000062 self.CreateWidgets()
Terry Jan Reedy4036d872014-08-03 23:02:58 -040063 self.resizable(height=FALSE, width=FALSE)
Steven M. Gavad721c482001-07-31 10:46:53 +000064 self.transient(parent)
65 self.grab_set()
66 self.protocol("WM_DELETE_WINDOW", self.Cancel)
Steven M. Gava2d4e03b2001-12-05 07:54:07 +000067 self.tabPages.focus_set()
Steven M. Gavad721c482001-07-31 10:46:53 +000068 #key bindings for this dialog
Terry Jan Reedy4036d872014-08-03 23:02:58 -040069 #self.bind('<Escape>', self.Cancel) #dismiss dialog, no save
70 #self.bind('<Alt-a>', self.Apply) #apply changes, save
71 #self.bind('<F1>', self.Help) #context help
Steven M. Gava429a86af2001-10-23 10:42:12 +000072 self.LoadConfigs()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000073 self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
Guido van Rossum8ce8a782007-11-01 19:42:39 +000074
Terry Jan Reedycfa89502014-07-14 23:07:32 -040075 if not _utest:
76 self.wm_deiconify()
77 self.wait_window()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +000078
Steven M. Gavad721c482001-07-31 10:46:53 +000079 def CreateWidgets(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +000080 self.tabPages = TabbedPageSet(self,
Terry Jan Reedy4036d872014-08-03 23:02:58 -040081 page_names=['Fonts/Tabs', 'Highlighting', 'Keys', 'General'])
82 frameActionButtons = Frame(self, pady=2)
Steven M. Gavad721c482001-07-31 10:46:53 +000083 #action buttons
Ned Deilyb7601672014-03-27 20:49:14 -070084 if macosxSupport.isAquaTk():
Terry Jan Reedye3416e62014-07-26 19:40:16 -040085 # Changing the default padding on OSX results in unreadable
86 # text in the buttons
Terry Jan Reedy4036d872014-08-03 23:02:58 -040087 paddingArgs = {}
Ronald Oussoren9e350042009-02-12 16:02:11 +000088 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -040089 paddingArgs = {'padx':6, 'pady':3}
Ronald Oussoren9e350042009-02-12 16:02:11 +000090
Terry Jan Reedy91d42782014-01-26 22:24:26 -050091# Comment out button creation and packing until implement self.Help
Terry Jan Reedy4036d872014-08-03 23:02:58 -040092## self.buttonHelp = Button(frameActionButtons, text='Help',
93## command=self.Help, takefocus=FALSE,
Terry Jan Reedye3416e62014-07-26 19:40:16 -040094## **paddingArgs)
Terry Jan Reedy4036d872014-08-03 23:02:58 -040095 self.buttonOk = Button(
96 frameActionButtons, text='Ok',
97 command=self.Ok, takefocus=FALSE, **paddingArgs)
98 self.buttonApply = Button(
99 frameActionButtons, text='Apply',
100 command=self.Apply, takefocus=FALSE, **paddingArgs)
101 self.buttonCancel = Button(
102 frameActionButtons, text='Cancel',
103 command=self.Cancel, takefocus=FALSE, **paddingArgs)
Steven M. Gava2d4e03b2001-12-05 07:54:07 +0000104 self.CreatePageFontTab()
105 self.CreatePageHighlight()
106 self.CreatePageKeys()
107 self.CreatePageGeneral()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400108## self.buttonHelp.pack(side=RIGHT, padx=5)
109 self.buttonOk.pack(side=LEFT, padx=5)
110 self.buttonApply.pack(side=LEFT, padx=5)
111 self.buttonCancel.pack(side=LEFT, padx=5)
Steven M. Gavad721c482001-07-31 10:46:53 +0000112 frameActionButtons.pack(side=BOTTOM)
Christian Heimes9a371592007-12-28 14:08:13 +0000113 Frame(self, height=2, borderwidth=0).pack(side=BOTTOM)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400114 self.tabPages.pack(side=TOP, expand=TRUE, fill=BOTH)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000115
Steven M. Gava60fc7072001-08-04 13:58:22 +0000116 def CreatePageFontTab(self):
Terry Jan Reedy22405332014-07-30 19:24:32 -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 Reedy4036d872014-08-03 23:02:58 -0400122 self.editFont = tkFont.Font(parent, ('courier', 10, 'normal'))
Terry Jan Reedy22405332014-07-30 19:24:32 -0400123
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000124 ##widget creation
125 #body frame
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400126 frame = self.tabPages.pages['Fonts/Tabs'].frame
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000127 #body section frames
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy22405332014-07-30 19:24:32 -0400162
Steven M. Gavaf213ccb2001-08-05 08:00:28 +0000163 #widget packing
164 #body
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy22405332014-07-30 19:24:32 -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 Reedy4036d872014-08-03 23:02:58 -0400196 frame = self.tabPages.pages['Highlighting'].frame
Steven M. Gava952d0a52001-08-03 04:43:44 +0000197 #body section frames
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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', 'keyword'), (')\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 Reedy4036d872014-08-03 23:02:58 -0400227 text.insert(END, txTa[0], txTa[1])
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000228 for element in self.themeElements:
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy22405332014-07-30 19:24:32 -0400267
Steven M. Gava952d0a52001-08-03 04:43:44 +0000268 ##widget packing
269 #body
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy22405332014-07-30 19:24:32 -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 Reedy4036d872014-08-03 23:02:58 -0400302 frame = self.tabPages.pages['Keys'].frame
Steven M. Gava60fc7072001-08-04 13:58:22 +0000303 #body section frames
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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
Christian Heimes9a371592007-12-28 14:08:13 +0000325 frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0)
326 for i in range(2)]
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -0400340 buttonSaveCustomKeys = Button(
341 frames[1], text='Save as New Custom Key Set',
342 command=self.SaveAsNewKeySet)
Terry Jan Reedy22405332014-07-30 19:24:32 -0400343
Steven M. Gava60fc7072001-08-04 13:58:22 +0000344 ##widget packing
345 #body
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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 Reedy4036d872014-08-03 23:02:58 -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
Christian Heimes9a371592007-12-28 14:08:13 +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 Reedy4036d872014-08-03 23:02:58 -0400363 self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
364 buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
Christian Heimes9a371592007-12-28 14:08:13 +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 Reedy22405332014-07-30 19:24:32 -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 Reedy4036d872014-08-03 23:02:58 -0400382 frame = self.tabPages.pages['General'].frame
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000383 #body section frames
Terry Jan Reedy4036d872014-08-03 23:02:58 -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 frameHelp = LabelFrame(frame, borderwidth=2, relief=GROOVE,
391 text=' Additional Help Sources ')
Steven M. Gava230e5782001-08-07 03:28:25 +0000392 #frameRun
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400393 labelRunChoiceTitle = Label(frameRun, text='At Startup')
394 radioStartupEdit = Radiobutton(
395 frameRun, variable=self.startupEdit, value=1,
396 command=self.SetKeysType, text="Open Edit Window")
397 radioStartupShell = Radiobutton(
398 frameRun, variable=self.startupEdit, value=0,
399 command=self.SetKeysType, text='Open Shell Window')
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000400 #frameSave
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400401 labelRunSaveTitle = Label(frameSave, text='At Start of Run (F5) ')
402 radioSaveAsk = Radiobutton(
403 frameSave, variable=self.autoSave, value=0,
404 command=self.SetKeysType, text="Prompt to Save")
405 radioSaveAuto = Radiobutton(
406 frameSave, variable=self.autoSave, value=1,
407 command=self.SetKeysType, text='No Prompt')
Steven M. Gava230e5782001-08-07 03:28:25 +0000408 #frameWinSize
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400409 labelWinSizeTitle = Label(
410 frameWinSize, text='Initial Window Size (in characters)')
411 labelWinWidthTitle = Label(frameWinSize, text='Width')
412 entryWinWidth = Entry(
413 frameWinSize, textvariable=self.winWidth, width=3)
414 labelWinHeightTitle = Label(frameWinSize, text='Height')
415 entryWinHeight = Entry(
416 frameWinSize, textvariable=self.winHeight, width=3)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000417 #paragraphFormatWidth
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400418 labelParaWidthTitle = Label(
419 frameParaSize, text='Paragraph reformat width (in characters)')
420 entryParaWidth = Entry(
421 frameParaSize, textvariable=self.paraWidth, width=3)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000422 #frameHelp
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400423 frameHelpList = Frame(frameHelp)
424 frameHelpListButtons = Frame(frameHelpList)
425 scrollHelpList = Scrollbar(frameHelpList)
426 self.listHelp = Listbox(
427 frameHelpList, height=5, takefocus=FALSE,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000428 exportselection=FALSE)
429 scrollHelpList.config(command=self.listHelp.yview)
430 self.listHelp.config(yscrollcommand=scrollHelpList.set)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400431 self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected)
432 self.buttonHelpListEdit = Button(
433 frameHelpListButtons, text='Edit', state=DISABLED,
434 width=8, command=self.HelpListItemEdit)
435 self.buttonHelpListAdd = Button(
436 frameHelpListButtons, text='Add',
437 width=8, command=self.HelpListItemAdd)
438 self.buttonHelpListRemove = Button(
439 frameHelpListButtons, text='Remove', state=DISABLED,
440 width=8, command=self.HelpListItemRemove)
Terry Jan Reedy22405332014-07-30 19:24:32 -0400441
Steven M. Gava230e5782001-08-07 03:28:25 +0000442 #widget packing
443 #body
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400444 frameRun.pack(side=TOP, padx=5, pady=5, fill=X)
445 frameSave.pack(side=TOP, padx=5, pady=5, fill=X)
446 frameWinSize.pack(side=TOP, padx=5, pady=5, fill=X)
447 frameParaSize.pack(side=TOP, padx=5, pady=5, fill=X)
448 frameHelp.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
Steven M. Gava230e5782001-08-07 03:28:25 +0000449 #frameRun
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400450 labelRunChoiceTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
451 radioStartupShell.pack(side=RIGHT, anchor=W, padx=5, pady=5)
452 radioStartupEdit.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000453 #frameSave
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400454 labelRunSaveTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
455 radioSaveAuto.pack(side=RIGHT, anchor=W, padx=5, pady=5)
456 radioSaveAsk.pack(side=RIGHT, anchor=W, padx=5, pady=5)
Steven M. Gava230e5782001-08-07 03:28:25 +0000457 #frameWinSize
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400458 labelWinSizeTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
459 entryWinHeight.pack(side=RIGHT, anchor=E, padx=10, pady=5)
460 labelWinHeightTitle.pack(side=RIGHT, anchor=E, pady=5)
461 entryWinWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
462 labelWinWidthTitle.pack(side=RIGHT, anchor=E, pady=5)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000463 #paragraphFormatWidth
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400464 labelParaWidthTitle.pack(side=LEFT, anchor=W, padx=5, pady=5)
465 entryParaWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000466 #frameHelp
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400467 frameHelpListButtons.pack(side=RIGHT, padx=5, pady=5, fill=Y)
468 frameHelpList.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
469 scrollHelpList.pack(side=RIGHT, anchor=W, fill=Y)
470 self.listHelp.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)
471 self.buttonHelpListEdit.pack(side=TOP, anchor=W, pady=5)
472 self.buttonHelpListAdd.pack(side=TOP, anchor=W)
473 self.buttonHelpListRemove.pack(side=TOP, anchor=W, pady=5)
Steven M. Gava952d0a52001-08-03 04:43:44 +0000474 return frame
475
Steven M. Gavac112cd82002-01-22 05:56:40 +0000476 def AttachVarCallbacks(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400477 self.fontSize.trace_variable('w', self.VarChanged_fontSize)
478 self.fontName.trace_variable('w', self.VarChanged_fontName)
479 self.fontBold.trace_variable('w', self.VarChanged_fontBold)
480 self.spaceNum.trace_variable('w', self.VarChanged_spaceNum)
481 self.colour.trace_variable('w', self.VarChanged_colour)
482 self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme)
483 self.customTheme.trace_variable('w', self.VarChanged_customTheme)
484 self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin)
485 self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget)
486 self.keyBinding.trace_variable('w', self.VarChanged_keyBinding)
487 self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys)
488 self.customKeys.trace_variable('w', self.VarChanged_customKeys)
489 self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin)
490 self.winWidth.trace_variable('w', self.VarChanged_winWidth)
491 self.winHeight.trace_variable('w', self.VarChanged_winHeight)
492 self.paraWidth.trace_variable('w', self.VarChanged_paraWidth)
493 self.startupEdit.trace_variable('w', self.VarChanged_startupEdit)
494 self.autoSave.trace_variable('w', self.VarChanged_autoSave)
495 self.encoding.trace_variable('w', self.VarChanged_encoding)
Steven M. Gava052937f2002-02-11 02:20:53 +0000496
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400497 def VarChanged_fontSize(self, *params):
498 value = self.fontSize.get()
499 self.AddChangedItem('main', 'EditorWindow', 'font-size', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000500
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400501 def VarChanged_fontName(self, *params):
502 value = self.fontName.get()
503 self.AddChangedItem('main', 'EditorWindow', 'font', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000504
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400505 def VarChanged_fontBold(self, *params):
506 value = self.fontBold.get()
507 self.AddChangedItem('main', 'EditorWindow', 'font-bold', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000508
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400509 def VarChanged_spaceNum(self, *params):
510 value = self.spaceNum.get()
511 self.AddChangedItem('main', 'Indent', 'num-spaces', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000512
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400513 def VarChanged_colour(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000514 self.OnNewColourSet()
515
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400516 def VarChanged_builtinTheme(self, *params):
517 value = self.builtinTheme.get()
518 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000519 self.PaintThemeSample()
520
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400521 def VarChanged_customTheme(self, *params):
522 value = self.customTheme.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000523 if value != '- no custom themes -':
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400524 self.AddChangedItem('main', 'Theme', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000525 self.PaintThemeSample()
Steven M. Gava052937f2002-02-11 02:20:53 +0000526
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400527 def VarChanged_themeIsBuiltin(self, *params):
528 value = self.themeIsBuiltin.get()
529 self.AddChangedItem('main', 'Theme', 'default', value)
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000530 if value:
531 self.VarChanged_builtinTheme()
532 else:
533 self.VarChanged_customTheme()
Steven M. Gava052937f2002-02-11 02:20:53 +0000534
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400535 def VarChanged_highlightTarget(self, *params):
Steven M. Gava052937f2002-02-11 02:20:53 +0000536 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000537
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400538 def VarChanged_keyBinding(self, *params):
539 value = self.keyBinding.get()
540 keySet = self.customKeys.get()
541 event = self.listBindings.get(ANCHOR).split()[0]
Steven M. Gavaa498af22002-02-01 01:33:36 +0000542 if idleConf.IsCoreBinding(event):
543 #this is a core keybinding
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400544 self.AddChangedItem('keys', keySet, event, value)
Steven M. Gavaa498af22002-02-01 01:33:36 +0000545 else: #this is an extension key binding
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400546 extName = idleConf.GetExtnNameForEvent(event)
547 extKeybindSection = extName + '_cfgBindings'
548 self.AddChangedItem('extensions', extKeybindSection, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000549
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400550 def VarChanged_builtinKeys(self, *params):
551 value = self.builtinKeys.get()
552 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000553 self.LoadKeysList(value)
554
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400555 def VarChanged_customKeys(self, *params):
556 value = self.customKeys.get()
Steven M. Gava49745752002-02-18 01:43:11 +0000557 if value != '- no custom keys -':
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400558 self.AddChangedItem('main', 'Keys', 'name', value)
Steven M. Gava49745752002-02-18 01:43:11 +0000559 self.LoadKeysList(value)
Steven M. Gava052937f2002-02-11 02:20:53 +0000560
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400561 def VarChanged_keysAreBuiltin(self, *params):
562 value = self.keysAreBuiltin.get()
563 self.AddChangedItem('main', 'Keys', 'default', value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000564 if value:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000565 self.VarChanged_builtinKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000566 else:
Steven M. Gavaf31eec02002-03-05 00:25:58 +0000567 self.VarChanged_customKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +0000568
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400569 def VarChanged_winWidth(self, *params):
570 value = self.winWidth.get()
571 self.AddChangedItem('main', 'EditorWindow', 'width', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000572
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400573 def VarChanged_winHeight(self, *params):
574 value = self.winHeight.get()
575 self.AddChangedItem('main', 'EditorWindow', 'height', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000576
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400577 def VarChanged_paraWidth(self, *params):
578 value = self.paraWidth.get()
579 self.AddChangedItem('main', 'FormatParagraph', 'paragraph', value)
Raymond Hettinger4e49b832004-06-04 06:31:08 +0000580
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400581 def VarChanged_startupEdit(self, *params):
582 value = self.startupEdit.get()
583 self.AddChangedItem('main', 'General', 'editor-on-startup', value)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000584
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400585 def VarChanged_autoSave(self, *params):
586 value = self.autoSave.get()
587 self.AddChangedItem('main', 'General', 'autosave', value)
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +0000588
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400589 def VarChanged_encoding(self, *params):
590 value = self.encoding.get()
591 self.AddChangedItem('main', 'EditorWindow', 'encoding', value)
Kurt B. Kaisera053f332003-05-10 00:49:56 +0000592
Steven M. Gavaa498af22002-02-01 01:33:36 +0000593 def ResetChangedItems(self):
Steven M. Gavab77d3432002-03-02 07:16:21 +0000594 #When any config item is changed in this dialog, an entry
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000595 #should be made in the relevant section (config type) of this
596 #dictionary. The key should be the config file section name and the
Steven M. Gavaa498af22002-02-01 01:33:36 +0000597 #value a dictionary, whose key:value pairs are item=value pairs for
598 #that config file section.
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400599 self.changedItems = {'main':{}, 'highlight':{}, 'keys':{},
600 'extensions':{}}
Steven M. Gavaa498af22002-02-01 01:33:36 +0000601
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400602 def AddChangedItem(self, typ, section, item, value):
603 value = str(value) #make sure we use a string
604 if section not in self.changedItems[typ]:
605 self.changedItems[typ][section] = {}
606 self.changedItems[typ][section][item] = value
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000607
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000608 def GetDefaultItems(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400609 dItems={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}}
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000610 for configType in dItems:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400611 sections = idleConf.GetSectionList('default', configType)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000612 for section in sections:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400613 dItems[configType][section] = {}
614 options = idleConf.defaultCfg[configType].GetOptionList(section)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000615 for option in options:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400616 dItems[configType][section][option] = (
617 idleConf.defaultCfg[configType].Get(section, option))
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000618 return dItems
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000619
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000620 def SetThemeType(self):
621 if self.themeIsBuiltin.get():
622 self.optMenuThemeBuiltin.config(state=NORMAL)
623 self.optMenuThemeCustom.config(state=DISABLED)
624 self.buttonDeleteCustomTheme.config(state=DISABLED)
625 else:
626 self.optMenuThemeBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000627 self.radioThemeCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000628 self.optMenuThemeCustom.config(state=NORMAL)
629 self.buttonDeleteCustomTheme.config(state=NORMAL)
630
631 def SetKeysType(self):
Steven M. Gava052937f2002-02-11 02:20:53 +0000632 if self.keysAreBuiltin.get():
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000633 self.optMenuKeysBuiltin.config(state=NORMAL)
634 self.optMenuKeysCustom.config(state=DISABLED)
635 self.buttonDeleteCustomKeys.config(state=DISABLED)
636 else:
637 self.optMenuKeysBuiltin.config(state=DISABLED)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000638 self.radioKeysCustom.config(state=NORMAL)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000639 self.optMenuKeysCustom.config(state=NORMAL)
640 self.buttonDeleteCustomKeys.config(state=NORMAL)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000641
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000642 def GetNewKeys(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400643 listIndex = self.listBindings.index(ANCHOR)
644 binding = self.listBindings.get(listIndex)
645 bindName = binding.split()[0] #first part, up to first space
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000646 if self.keysAreBuiltin.get():
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400647 currentKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000648 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400649 currentKeySetName = self.customKeys.get()
650 currentBindings = idleConf.GetCurrentKeySet()
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000651 if currentKeySetName in self.changedItems['keys']: #unsaved changes
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400652 keySetChanges = self.changedItems['keys'][currentKeySetName]
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000653 for event in keySetChanges:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400654 currentBindings[event] = keySetChanges[event].split()
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000655 currentKeySequences = list(currentBindings.values())
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400656 newKeys = GetKeysDialog(self, 'Get New Keys', bindName,
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000657 currentKeySequences).result
658 if newKeys: #new keys were specified
Steven M. Gava052937f2002-02-11 02:20:53 +0000659 if self.keysAreBuiltin.get(): #current key set is a built-in
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400660 message = ('Your changes will be saved as a new Custom Key Set.'
661 ' Enter a name for your new Custom Key Set below.')
662 newKeySet = self.GetNewKeysName(message)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000663 if not newKeySet: #user cancelled custom key set creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000664 self.listBindings.select_set(listIndex)
665 self.listBindings.select_anchor(listIndex)
666 return
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000667 else: #create new custom key set based on previously active key set
668 self.CreateNewKeySet(newKeySet)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000669 self.listBindings.delete(listIndex)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400670 self.listBindings.insert(listIndex, bindName+' - '+newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000671 self.listBindings.select_set(listIndex)
672 self.listBindings.select_anchor(listIndex)
Steven M. Gava052937f2002-02-11 02:20:53 +0000673 self.keyBinding.set(newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000674 else:
675 self.listBindings.select_set(listIndex)
676 self.listBindings.select_anchor(listIndex)
677
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400678 def GetNewKeysName(self, message):
679 usedNames = (idleConf.GetSectionList('user', 'keys') +
680 idleConf.GetSectionList('default', 'keys'))
681 newKeySet = GetCfgSectionNameDialog(
682 self, 'New Custom Key Set', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000683 return newKeySet
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000684
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000685 def SaveAsNewKeySet(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400686 newKeysName = self.GetNewKeysName('New Key Set Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000687 if newKeysName:
688 self.CreateNewKeySet(newKeysName)
689
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400690 def KeyBindingSelected(self, event):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000691 self.buttonNewKeys.config(state=NORMAL)
692
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400693 def CreateNewKeySet(self, newKeySetName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000694 #creates new custom key set based on the previously active key set,
695 #and makes the new key set active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000696 if self.keysAreBuiltin.get():
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400697 prevKeySetName = self.builtinKeys.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000698 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400699 prevKeySetName = self.customKeys.get()
700 prevKeys = idleConf.GetCoreKeys(prevKeySetName)
701 newKeys = {}
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000702 for event in prevKeys: #add key set to changed items
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400703 eventName = event[2:-2] #trim off the angle brackets
704 binding = ' '.join(prevKeys[event])
705 newKeys[eventName] = binding
Steven M. Gava052937f2002-02-11 02:20:53 +0000706 #handle any unsaved changes to prev key set
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000707 if prevKeySetName in self.changedItems['keys']:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400708 keySetChanges = self.changedItems['keys'][prevKeySetName]
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000709 for event in keySetChanges:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400710 newKeys[event] = keySetChanges[event]
Steven M. Gava052937f2002-02-11 02:20:53 +0000711 #save the new theme
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400712 self.SaveNewKeySet(newKeySetName, newKeys)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000713 #change gui over to the new key set
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400714 customKeyList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000715 customKeyList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400716 self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000717 self.keysAreBuiltin.set(0)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000718 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000719
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400720 def LoadKeysList(self, keySetName):
721 reselect = 0
722 newKeySet = 0
Steven M. Gava052937f2002-02-11 02:20:53 +0000723 if self.listBindings.curselection():
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400724 reselect = 1
725 listIndex = self.listBindings.index(ANCHOR)
726 keySet = idleConf.GetKeySet(keySetName)
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000727 bindNames = list(keySet.keys())
Steven M. Gava052937f2002-02-11 02:20:53 +0000728 bindNames.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400729 self.listBindings.delete(0, END)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000730 for bindName in bindNames:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400731 key = ' '.join(keySet[bindName]) #make key(s) into a string
732 bindName = bindName[2:-2] #trim off the angle brackets
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000733 if keySetName in self.changedItems['keys']:
Steven M. Gava052937f2002-02-11 02:20:53 +0000734 #handle any unsaved changes to this key set
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000735 if bindName in self.changedItems['keys'][keySetName]:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400736 key = self.changedItems['keys'][keySetName][bindName]
Steven M. Gava052937f2002-02-11 02:20:53 +0000737 self.listBindings.insert(END, bindName+' - '+key)
Steven M. Gava052937f2002-02-11 02:20:53 +0000738 if reselect:
739 self.listBindings.see(listIndex)
740 self.listBindings.select_set(listIndex)
741 self.listBindings.select_anchor(listIndex)
742
Steven M. Gava49745752002-02-18 01:43:11 +0000743 def DeleteCustomKeys(self):
744 keySetName=self.customKeys.get()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400745 delmsg = 'Are you sure you wish to delete the key set %r ?'
746 if not tkMessageBox.askyesno(
747 'Delete Key Set', delmsg % keySetName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000748 return
749 #remove key set from config
750 idleConf.userCfg['keys'].remove_section(keySetName)
Guido van Rossum811c4e02006-08-22 15:45:46 +0000751 if keySetName in self.changedItems['keys']:
Steven M. Gava49745752002-02-18 01:43:11 +0000752 del(self.changedItems['keys'][keySetName])
753 #write changes
754 idleConf.userCfg['keys'].Save()
755 #reload user key set list
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400756 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gava49745752002-02-18 01:43:11 +0000757 itemList.sort()
758 if not itemList:
759 self.radioKeysCustom.config(state=DISABLED)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400760 self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -')
Steven M. Gava49745752002-02-18 01:43:11 +0000761 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400762 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000763 #revert to default key set
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400764 self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
765 self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000766 #user can't back out of these changes, they must be applied now
767 self.Apply()
768 self.SetKeysType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000769
Steven M. Gava49745752002-02-18 01:43:11 +0000770 def DeleteCustomTheme(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400771 themeName = self.customTheme.get()
772 delmsg = 'Are you sure you wish to delete the theme %r ?'
773 if not tkMessageBox.askyesno(
774 'Delete Theme', delmsg % themeName, parent=self):
Steven M. Gava49745752002-02-18 01:43:11 +0000775 return
776 #remove theme from config
777 idleConf.userCfg['highlight'].remove_section(themeName)
Guido van Rossum811c4e02006-08-22 15:45:46 +0000778 if themeName in self.changedItems['highlight']:
Steven M. Gava49745752002-02-18 01:43:11 +0000779 del(self.changedItems['highlight'][themeName])
780 #write changes
781 idleConf.userCfg['highlight'].Save()
782 #reload user theme list
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400783 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gava49745752002-02-18 01:43:11 +0000784 itemList.sort()
785 if not itemList:
786 self.radioThemeCustom.config(state=DISABLED)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400787 self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -')
Steven M. Gava49745752002-02-18 01:43:11 +0000788 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400789 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava49745752002-02-18 01:43:11 +0000790 #revert to default theme
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400791 self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
792 self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
Steven M. Gava49745752002-02-18 01:43:11 +0000793 #user can't back out of these changes, they must be applied now
794 self.Apply()
795 self.SetThemeType()
796
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000797 def GetColour(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400798 target = self.highlightTarget.get()
799 prevColour = self.frameColourSet.cget('bg')
800 rgbTuplet, colourString = tkColorChooser.askcolor(
801 parent=self, title='Pick new colour for : '+target,
802 initialcolor=prevColour)
803 if colourString and (colourString != prevColour):
Steven M. Gava052937f2002-02-11 02:20:53 +0000804 #user didn't cancel, and they chose a new colour
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400805 if self.themeIsBuiltin.get(): #current theme is a built-in
806 message = ('Your changes will be saved as a new Custom Theme. '
807 'Enter a name for your new Custom Theme below.')
808 newTheme = self.GetNewThemeName(message)
809 if not newTheme: #user cancelled custom theme creation
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000810 return
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400811 else: #create new custom theme based on previously active theme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000812 self.CreateNewTheme(newTheme)
Steven M. Gava052937f2002-02-11 02:20:53 +0000813 self.colour.set(colourString)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400814 else: #current theme is user defined
Steven M. Gava052937f2002-02-11 02:20:53 +0000815 self.colour.set(colourString)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000816
Steven M. Gava052937f2002-02-11 02:20:53 +0000817 def OnNewColourSet(self):
818 newColour=self.colour.get()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400819 self.frameColourSet.config(bg=newColour) #set sample
820 plane ='foreground' if self.fgHilite.get() else 'background'
821 sampleElement = self.themeElements[self.highlightTarget.get()][0]
Raymond Hettinger931237e2003-07-09 18:48:24 +0000822 self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400823 theme = self.customTheme.get()
824 themeElement = sampleElement + '-' + plane
825 self.AddChangedItem('highlight', theme, themeElement, newColour)
Steven M. Gava052937f2002-02-11 02:20:53 +0000826
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400827 def GetNewThemeName(self, message):
828 usedNames = (idleConf.GetSectionList('user', 'highlight') +
829 idleConf.GetSectionList('default', 'highlight'))
830 newTheme = GetCfgSectionNameDialog(
831 self, 'New Custom Theme', message, usedNames).result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000832 return newTheme
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000833
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000834 def SaveAsNewTheme(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400835 newThemeName = self.GetNewThemeName('New Theme Name:')
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000836 if newThemeName:
837 self.CreateNewTheme(newThemeName)
838
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400839 def CreateNewTheme(self, newThemeName):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000840 #creates new custom theme based on the previously active theme,
841 #and makes the new theme active
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000842 if self.themeIsBuiltin.get():
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400843 themeType = 'default'
844 themeName = self.builtinTheme.get()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000845 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400846 themeType = 'user'
847 themeName = self.customTheme.get()
848 newTheme = idleConf.GetThemeDict(themeType, themeName)
Steven M. Gava052937f2002-02-11 02:20:53 +0000849 #apply any of the old theme's unsaved changes to the new theme
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000850 if themeName in self.changedItems['highlight']:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400851 themeChanges = self.changedItems['highlight'][themeName]
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000852 for element in themeChanges:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400853 newTheme[element] = themeChanges[element]
Steven M. Gava052937f2002-02-11 02:20:53 +0000854 #save the new theme
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400855 self.SaveNewTheme(newThemeName, newTheme)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000856 #change gui over to the new theme
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400857 customThemeList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000858 customThemeList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400859 self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000860 self.themeIsBuiltin.set(0)
861 self.SetThemeType()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000862
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400863 def OnListFontButtonRelease(self, event):
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000864 font = self.listFontName.get(ANCHOR)
865 self.fontName.set(font.lower())
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000866 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000867
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400868 def SetFontSample(self, event=None):
869 fontName = self.fontName.get()
870 fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL
Ned Deilyfdf0f272012-10-22 15:14:31 -0700871 newFont = (fontName, self.fontSize.get(), fontWeight)
872 self.labelFontSample.config(font=newFont)
873 self.textHighlightSample.configure(font=newFont)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000874
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000875 def SetHighlightTarget(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400876 if self.highlightTarget.get() == 'Cursor': #bg not possible
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000877 self.radioFg.config(state=DISABLED)
878 self.radioBg.config(state=DISABLED)
879 self.fgHilite.set(1)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400880 else: #both fg and bg can be set
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000881 self.radioFg.config(state=NORMAL)
882 self.radioBg.config(state=NORMAL)
883 self.fgHilite.set(1)
884 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000885
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400886 def SetColourSampleBinding(self, *args):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000887 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000888
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000889 def SetColourSample(self):
890 #set the colour smaple area
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400891 tag = self.themeElements[self.highlightTarget.get()][0]
892 plane = 'foreground' if self.fgHilite.get() else 'background'
893 colour = self.textHighlightSample.tag_cget(tag, plane)
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000894 self.frameColourSet.config(bg=colour)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000895
Steven M. Gava9dd16b32001-11-03 14:54:25 +0000896 def PaintThemeSample(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400897 if self.themeIsBuiltin.get(): #a default theme
898 theme = self.builtinTheme.get()
899 else: #a user theme
900 theme = self.customTheme.get()
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000901 for elementTitle in self.themeElements:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400902 element = self.themeElements[elementTitle][0]
903 colours = idleConf.GetHighlight(theme, element)
904 if element == 'cursor': #cursor sample needs special painting
905 colours['background'] = idleConf.GetHighlight(
906 theme, 'normal', fgBg='bg')
Steven M. Gava052937f2002-02-11 02:20:53 +0000907 #handle any unsaved changes to this theme
Kurt B. Kaisere0712772007-08-23 05:25:55 +0000908 if theme in self.changedItems['highlight']:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400909 themeDict = self.changedItems['highlight'][theme]
910 if element + '-foreground' in themeDict:
911 colours['foreground'] = themeDict[element + '-foreground']
912 if element + '-background' in themeDict:
913 colours['background'] = themeDict[element + '-background']
Raymond Hettinger931237e2003-07-09 18:48:24 +0000914 self.textHighlightSample.tag_config(element, **colours)
Steven M. Gava052937f2002-02-11 02:20:53 +0000915 self.SetColourSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000916
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400917 def HelpSourceSelected(self, event):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000918 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000919
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000920 def SetHelpListButtonStates(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400921 if self.listHelp.size() < 1: #no entries in list
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000922 self.buttonHelpListEdit.config(state=DISABLED)
923 self.buttonHelpListRemove.config(state=DISABLED)
924 else: #there are some entries
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400925 if self.listHelp.curselection(): #there currently is a selection
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000926 self.buttonHelpListEdit.config(state=NORMAL)
927 self.buttonHelpListRemove.config(state=NORMAL)
928 else: #there currently is not a selection
929 self.buttonHelpListEdit.config(state=DISABLED)
930 self.buttonHelpListRemove.config(state=DISABLED)
931
932 def HelpListItemAdd(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400933 helpSource = GetHelpSourceDialog(self, 'New Help Source').result
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000934 if helpSource:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400935 self.userHelpList.append((helpSource[0], helpSource[1]))
936 self.listHelp.insert(END, helpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000937 self.UpdateUserHelpChangedItems()
938 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000939
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000940 def HelpListItemEdit(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400941 itemIndex = self.listHelp.index(ANCHOR)
942 helpSource = self.userHelpList[itemIndex]
943 newHelpSource = GetHelpSourceDialog(
944 self, 'Edit Help Source', menuItem=helpSource[0],
945 filePath=helpSource[1]).result
946 if (not newHelpSource) or (newHelpSource == helpSource):
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000947 return #no changes
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400948 self.userHelpList[itemIndex] = newHelpSource
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000949 self.listHelp.delete(itemIndex)
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400950 self.listHelp.insert(itemIndex, newHelpSource[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000951 self.UpdateUserHelpChangedItems()
952 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000953
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000954 def HelpListItemRemove(self):
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400955 itemIndex = self.listHelp.index(ANCHOR)
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000956 del(self.userHelpList[itemIndex])
957 self.listHelp.delete(itemIndex)
958 self.UpdateUserHelpChangedItems()
959 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000960
Steven M. Gava085eb1b2002-02-05 04:52:32 +0000961 def UpdateUserHelpChangedItems(self):
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +0000962 "Clear and rebuild the HelpFiles section in self.changedItems"
963 self.changedItems['main']['HelpFiles'] = {}
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400964 for num in range(1, len(self.userHelpList) + 1):
965 self.AddChangedItem(
966 'main', 'HelpFiles', str(num),
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000967 ';'.join(self.userHelpList[num-1][:2]))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000968
Steven M. Gava429a86af2001-10-23 10:42:12 +0000969 def LoadFontCfg(self):
970 ##base editor font selection list
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400971 fonts = list(tkFont.families(self))
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000972 fonts.sort()
973 for font in fonts:
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400974 self.listFontName.insert(END, font)
975 configuredFont = idleConf.GetOption(
976 'main', 'EditorWindow', 'font', default='courier')
Kurt B. Kaiser05391692003-05-26 20:35:53 +0000977 lc_configuredFont = configuredFont.lower()
978 self.fontName.set(lc_configuredFont)
979 lc_fonts = [s.lower() for s in fonts]
980 if lc_configuredFont in lc_fonts:
981 currentFontIndex = lc_fonts.index(lc_configuredFont)
Steven M. Gava429a86af2001-10-23 10:42:12 +0000982 self.listFontName.see(currentFontIndex)
983 self.listFontName.select_set(currentFontIndex)
Steven M. Gavac112cd82002-01-22 05:56:40 +0000984 self.listFontName.select_anchor(currentFontIndex)
Steven M. Gava429a86af2001-10-23 10:42:12 +0000985 ##font size dropdown
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400986 fontSize = idleConf.GetOption(
987 'main', 'EditorWindow', 'font-size', type='int', default='10')
988 self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13',
989 '14', '16', '18', '20', '22'), fontSize )
Steven M. Gavac112cd82002-01-22 05:56:40 +0000990 ##fontWeight
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400991 self.fontBold.set(idleConf.GetOption(
992 'main', 'EditorWindow', 'font-bold', default=0, type='bool'))
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000993 ##font sample
Steven M. Gava429a86af2001-10-23 10:42:12 +0000994 self.SetFontSample()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +0000995
Steven M. Gava429a86af2001-10-23 10:42:12 +0000996 def LoadTabCfg(self):
Steven M. Gava429a86af2001-10-23 10:42:12 +0000997 ##indent sizes
Terry Jan Reedy4036d872014-08-03 23:02:58 -0400998 spaceNum = idleConf.GetOption(
999 'main', 'Indent', 'num-spaces', default=4, type='int')
Steven M. Gava429a86af2001-10-23 10:42:12 +00001000 self.spaceNum.set(spaceNum)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001001
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001002 def LoadThemeCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001003 ##current theme type radiobutton
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001004 self.themeIsBuiltin.set(idleConf.GetOption(
1005 'main', 'Theme', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001006 ##currently set theme
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001007 currentOption = idleConf.CurrentTheme()
Steven M. Gava7c017862001-10-29 11:19:46 +00001008 ##load available theme option menus
Steven M. Gavad0342cd2001-11-04 11:53:10 +00001009 if self.themeIsBuiltin.get(): #default theme selected
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001010 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001011 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001012 self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
1013 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001014 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001015 if not itemList:
1016 self.radioThemeCustom.config(state=DISABLED)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001017 self.customTheme.set('- no custom themes -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001018 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001019 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001020 else: #user theme selected
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001021 itemList = idleConf.GetSectionList('user', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001022 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001023 self.optMenuThemeCustom.SetMenu(itemList, currentOption)
1024 itemList = idleConf.GetSectionList('default', 'highlight')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001025 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001026 self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
Steven M. Gava7c017862001-10-29 11:19:46 +00001027 self.SetThemeType()
1028 ##load theme element option menu
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001029 themeNames = list(self.themeElements.keys())
Kurt B. Kaiser4718bf82008-02-12 21:34:12 +00001030 themeNames.sort(key=lambda x: self.themeElements[x][1])
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001031 self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001032 self.PaintThemeSample()
Steven M. Gava0cae01c2002-01-04 07:53:06 +00001033 self.SetHighlightTarget()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001034
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001035 def LoadKeyCfg(self):
Steven M. Gava41a85322001-10-29 08:05:34 +00001036 ##current keys type radiobutton
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001037 self.keysAreBuiltin.set(idleConf.GetOption(
1038 'main', 'Keys', 'default', type='bool', default=1))
Steven M. Gava41a85322001-10-29 08:05:34 +00001039 ##currently set keys
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001040 currentOption = idleConf.CurrentKeys()
Steven M. Gava7c017862001-10-29 11:19:46 +00001041 ##load available keyset option menus
Steven M. Gava052937f2002-02-11 02:20:53 +00001042 if self.keysAreBuiltin.get(): #default theme selected
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001043 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001044 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001045 self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
1046 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001047 itemList.sort()
Steven M. Gava41a85322001-10-29 08:05:34 +00001048 if not itemList:
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001049 self.radioKeysCustom.config(state=DISABLED)
1050 self.customKeys.set('- no custom keys -')
Steven M. Gava41a85322001-10-29 08:05:34 +00001051 else:
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001052 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
Steven M. Gavaa498af22002-02-01 01:33:36 +00001053 else: #user key set selected
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001054 itemList = idleConf.GetSectionList('user', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001055 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001056 self.optMenuKeysCustom.SetMenu(itemList, currentOption)
1057 itemList = idleConf.GetSectionList('default', 'keys')
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +00001058 itemList.sort()
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001059 self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001060 self.SetKeysType()
Steven M. Gavafacfc092002-01-19 00:29:54 +00001061 ##load keyset element list
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001062 keySetName = idleConf.CurrentKeys()
Steven M. Gava052937f2002-02-11 02:20:53 +00001063 self.LoadKeysList(keySetName)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001064
Steven M. Gavafacfc092002-01-19 00:29:54 +00001065 def LoadGeneralCfg(self):
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001066 #startup state
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001067 self.startupEdit.set(idleConf.GetOption(
1068 'main', 'General', 'editor-on-startup', default=1, type='bool'))
Kurt B. Kaiser6c638b62003-05-26 06:23:10 +00001069 #autosave state
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001070 self.autoSave.set(idleConf.GetOption(
1071 'main', 'General', 'autosave', default=0, type='bool'))
Steven M. Gavafacfc092002-01-19 00:29:54 +00001072 #initial window size
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001073 self.winWidth.set(idleConf.GetOption(
1074 'main', 'EditorWindow', 'width', type='int'))
1075 self.winHeight.set(idleConf.GetOption(
1076 'main', 'EditorWindow', 'height', type='int'))
Raymond Hettinger4e49b832004-06-04 06:31:08 +00001077 #initial paragraph reformat size
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001078 self.paraWidth.set(idleConf.GetOption(
1079 'main', 'FormatParagraph', 'paragraph', type='int'))
Kurt B. Kaisera053f332003-05-10 00:49:56 +00001080 # default source encoding
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001081 self.encoding.set(idleConf.GetOption(
1082 'main', 'EditorWindow', 'encoding', default='none'))
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001083 # additional help sources
1084 self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001085 for helpItem in self.userHelpList:
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001086 self.listHelp.insert(END, helpItem[0])
Steven M. Gava085eb1b2002-02-05 04:52:32 +00001087 self.SetHelpListButtonStates()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001088
Steven M. Gava429a86af2001-10-23 10:42:12 +00001089 def LoadConfigs(self):
1090 """
1091 load configuration from default and user config files and populate
1092 the widgets on the config dialog pages.
1093 """
1094 ### fonts / tabs page
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001095 self.LoadFontCfg()
1096 self.LoadTabCfg()
Steven M. Gava429a86af2001-10-23 10:42:12 +00001097 ### highlighting page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001098 self.LoadThemeCfg()
Steven M. Gava429a86af2001-10-23 10:42:12 +00001099 ### keys page
Steven M. Gava9dd16b32001-11-03 14:54:25 +00001100 self.LoadKeyCfg()
Steven M. Gava429a86af2001-10-23 10:42:12 +00001101 ### general page
Steven M. Gavafacfc092002-01-19 00:29:54 +00001102 self.LoadGeneralCfg()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001103
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001104 def SaveNewKeySet(self, keySetName, keySet):
Steven M. Gava052937f2002-02-11 02:20:53 +00001105 """
1106 save a newly created core key set.
1107 keySetName - string, the name of the new key set
1108 keySet - dictionary containing the new key set
1109 """
1110 if not idleConf.userCfg['keys'].has_section(keySetName):
1111 idleConf.userCfg['keys'].add_section(keySetName)
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001112 for event in keySet:
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001113 value = keySet[event]
1114 idleConf.userCfg['keys'].SetOption(keySetName, event, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001115
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001116 def SaveNewTheme(self, themeName, theme):
Steven M. Gava052937f2002-02-11 02:20:53 +00001117 """
1118 save a newly created theme.
1119 themeName - string, the name of the new theme
1120 theme - dictionary containing the new theme
1121 """
1122 if not idleConf.userCfg['highlight'].has_section(themeName):
1123 idleConf.userCfg['highlight'].add_section(themeName)
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001124 for element in theme:
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001125 value = theme[element]
1126 idleConf.userCfg['highlight'].SetOption(themeName, element, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001127
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001128 def SetUserValue(self, configType, section, item, value):
1129 if idleConf.defaultCfg[configType].has_option(section, item):
1130 if idleConf.defaultCfg[configType].Get(section, item) == value:
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001131 #the setting equals a default setting, remove it from user cfg
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001132 return idleConf.userCfg[configType].RemoveOption(section, item)
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +00001133 #if we got here set the option
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001134 return idleConf.userCfg[configType].SetOption(section, item, value)
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001135
Steven M. Gava052937f2002-02-11 02:20:53 +00001136 def SaveAllChangedConfigs(self):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001137 "Save configuration changes to the user config file."
Steven M. Gava0c5bc8c2002-03-27 02:25:44 +00001138 idleConf.userCfg['main'].Save()
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001139 for configType in self.changedItems:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001140 cfgTypeHasChanges = False
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001141 for section in self.changedItems[configType]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001142 if section == 'HelpFiles':
1143 #this section gets completely replaced
1144 idleConf.userCfg['main'].remove_section('HelpFiles')
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001145 cfgTypeHasChanges = True
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001146 for item in self.changedItems[configType][section]:
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001147 value = self.changedItems[configType][section][item]
Terry Jan Reedy4036d872014-08-03 23:02:58 -04001148 if self.SetUserValue(configType, section, item, value):
Kurt B. Kaisere7a161e2003-01-10 20:13:57 +00001149 cfgTypeHasChanges = True
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001150 if cfgTypeHasChanges:
1151 idleConf.userCfg[configType].Save()
Kurt B. Kaiser5acdf932004-11-16 21:28:36 +00001152 for configType in ['keys', 'highlight']:
1153 # save these even if unchanged!
1154 idleConf.userCfg[configType].Save()
Steven M. Gavaa498af22002-02-01 01:33:36 +00001155 self.ResetChangedItems() #clear the changed items dict
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001156
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001157 def DeactivateCurrentConfig(self):
1158 #Before a config is saved, some cleanup of current
1159 #config must be done - remove the previous keybindings
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001160 winInstances = self.parent.instance_dict.keys()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001161 for instance in winInstances:
1162 instance.RemoveKeybindings()
1163
Steven M. Gava49745752002-02-18 01:43:11 +00001164 def ActivateConfigChanges(self):
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001165 "Dynamically apply configuration changes"
Kurt B. Kaisere0712772007-08-23 05:25:55 +00001166 winInstances = self.parent.instance_dict.keys()
Steven M. Gavab77d3432002-03-02 07:16:21 +00001167 for instance in winInstances:
1168 instance.ResetColorizer()
Steven M. Gavab1585412002-03-12 00:21:56 +00001169 instance.ResetFont()
Kurt B. Kaiseracdef852005-01-31 03:34:26 +00001170 instance.set_notabs_indentwidth()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001171 instance.ApplyKeybindings()
Kurt B. Kaiser8e92bf72003-01-14 22:03:31 +00001172 instance.reset_help_menu_entries()
Kurt B. Kaiser6655e4b2002-12-31 16:03:23 +00001173
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001174 def Cancel(self):
1175 self.destroy()
1176
1177 def Ok(self):
1178 self.Apply()
1179 self.destroy()
1180
1181 def Apply(self):
Kurt B. Kaiserb1754452005-11-18 22:05:48 +00001182 self.DeactivateCurrentConfig()
Steven M. Gava052937f2002-02-11 02:20:53 +00001183 self.SaveAllChangedConfigs()
Steven M. Gava49745752002-02-18 01:43:11 +00001184 self.ActivateConfigChanges()
Steven M. Gava5f28e8f2002-01-21 06:38:21 +00001185
1186 def Help(self):
Steven M. Gavac11ccf32001-09-24 09:43:17 +00001187 pass
1188
Steven M. Gava44d3d1a2001-07-31 06:59:02 +00001189if __name__ == '__main__':
Terry Jan Reedycfa89502014-07-14 23:07:32 -04001190 import unittest
1191 unittest.main('idlelib.idle_test.test_configdialog',
1192 verbosity=2, exit=False)
1193
Terry Jan Reedy2e8234a2014-05-29 01:46:26 -04001194 from idlelib.idle_test.htest import run
1195 run(ConfigDialog)