1 | n/a | """IDLE Configuration Dialog: support user customization of IDLE by GUI |
---|
2 | n/a | |
---|
3 | n/a | Customize font faces, sizes, and colorization attributes. Set indentation |
---|
4 | n/a | defaults. Customize keybindings. Colorization and keybindings can be |
---|
5 | n/a | saved as user defined sets. Select startup options including shell/editor |
---|
6 | n/a | and default window size. Define additional help sources. |
---|
7 | n/a | |
---|
8 | n/a | Note that tab width in IDLE is currently fixed at eight due to Tk issues. |
---|
9 | n/a | Refer to comments in EditorWindow autoindent code for details. |
---|
10 | n/a | |
---|
11 | n/a | """ |
---|
12 | n/a | from tkinter import * |
---|
13 | n/a | import tkinter.messagebox as tkMessageBox |
---|
14 | n/a | import tkinter.colorchooser as tkColorChooser |
---|
15 | n/a | import tkinter.font as tkFont |
---|
16 | n/a | import copy |
---|
17 | n/a | |
---|
18 | n/a | from idlelib.configHandler import idleConf |
---|
19 | n/a | from idlelib.dynOptionMenuWidget import DynOptionMenu |
---|
20 | n/a | from idlelib.tabbedpages import TabbedPageSet |
---|
21 | n/a | from idlelib.keybindingDialog import GetKeysDialog |
---|
22 | n/a | from idlelib.configSectionNameDialog import GetCfgSectionNameDialog |
---|
23 | n/a | from idlelib.configHelpSourceEdit import GetHelpSourceDialog |
---|
24 | n/a | from idlelib import macosxSupport |
---|
25 | n/a | |
---|
26 | n/a | class ConfigDialog(Toplevel): |
---|
27 | n/a | |
---|
28 | n/a | def __init__(self,parent,title): |
---|
29 | n/a | Toplevel.__init__(self, parent) |
---|
30 | n/a | self.wm_withdraw() |
---|
31 | n/a | |
---|
32 | n/a | self.configure(borderwidth=5) |
---|
33 | n/a | self.title('IDLE Preferences') |
---|
34 | n/a | self.geometry("+%d+%d" % (parent.winfo_rootx()+20, |
---|
35 | n/a | parent.winfo_rooty()+30)) |
---|
36 | n/a | #Theme Elements. Each theme element key is its display name. |
---|
37 | n/a | #The first value of the tuple is the sample area tag name. |
---|
38 | n/a | #The second value is the display name list sort index. |
---|
39 | n/a | self.themeElements={'Normal Text':('normal','00'), |
---|
40 | n/a | 'Python Keywords':('keyword','01'), |
---|
41 | n/a | 'Python Definitions':('definition','02'), |
---|
42 | n/a | 'Python Builtins':('builtin', '03'), |
---|
43 | n/a | 'Python Comments':('comment','04'), |
---|
44 | n/a | 'Python Strings':('string','05'), |
---|
45 | n/a | 'Selected Text':('hilite','06'), |
---|
46 | n/a | 'Found Text':('hit','07'), |
---|
47 | n/a | 'Cursor':('cursor','08'), |
---|
48 | n/a | 'Error Text':('error','09'), |
---|
49 | n/a | 'Shell Normal Text':('console','10'), |
---|
50 | n/a | 'Shell Stdout Text':('stdout','11'), |
---|
51 | n/a | 'Shell Stderr Text':('stderr','12'), |
---|
52 | n/a | } |
---|
53 | n/a | self.ResetChangedItems() #load initial values in changed items dict |
---|
54 | n/a | self.CreateWidgets() |
---|
55 | n/a | self.resizable(height=FALSE,width=FALSE) |
---|
56 | n/a | self.transient(parent) |
---|
57 | n/a | self.grab_set() |
---|
58 | n/a | self.protocol("WM_DELETE_WINDOW", self.Cancel) |
---|
59 | n/a | self.parent = parent |
---|
60 | n/a | self.tabPages.focus_set() |
---|
61 | n/a | #key bindings for this dialog |
---|
62 | n/a | #self.bind('<Escape>',self.Cancel) #dismiss dialog, no save |
---|
63 | n/a | #self.bind('<Alt-a>',self.Apply) #apply changes, save |
---|
64 | n/a | #self.bind('<F1>',self.Help) #context help |
---|
65 | n/a | self.LoadConfigs() |
---|
66 | n/a | self.AttachVarCallbacks() #avoid callbacks during LoadConfigs |
---|
67 | n/a | |
---|
68 | n/a | self.wm_deiconify() |
---|
69 | n/a | self.wait_window() |
---|
70 | n/a | |
---|
71 | n/a | def CreateWidgets(self): |
---|
72 | n/a | self.tabPages = TabbedPageSet(self, |
---|
73 | n/a | page_names=['Fonts/Tabs','Highlighting','Keys','General']) |
---|
74 | n/a | frameActionButtons = Frame(self,pady=2) |
---|
75 | n/a | #action buttons |
---|
76 | n/a | |
---|
77 | n/a | if macosxSupport.runningAsOSXApp(): |
---|
78 | n/a | # Surpress the padx and pady arguments when |
---|
79 | n/a | # running as IDLE.app, otherwise the text |
---|
80 | n/a | # on these buttons will not be readable. |
---|
81 | n/a | extraKwds={} |
---|
82 | n/a | else: |
---|
83 | n/a | extraKwds=dict(padx=6, pady=3) |
---|
84 | n/a | |
---|
85 | n/a | self.buttonHelp = Button(frameActionButtons,text='Help', |
---|
86 | n/a | command=self.Help,takefocus=FALSE, |
---|
87 | n/a | **extraKwds) |
---|
88 | n/a | self.buttonOk = Button(frameActionButtons,text='Ok', |
---|
89 | n/a | command=self.Ok,takefocus=FALSE, |
---|
90 | n/a | **extraKwds) |
---|
91 | n/a | self.buttonApply = Button(frameActionButtons,text='Apply', |
---|
92 | n/a | command=self.Apply,takefocus=FALSE, |
---|
93 | n/a | **extraKwds) |
---|
94 | n/a | self.buttonCancel = Button(frameActionButtons,text='Cancel', |
---|
95 | n/a | command=self.Cancel,takefocus=FALSE, |
---|
96 | n/a | **extraKwds) |
---|
97 | n/a | self.CreatePageFontTab() |
---|
98 | n/a | self.CreatePageHighlight() |
---|
99 | n/a | self.CreatePageKeys() |
---|
100 | n/a | self.CreatePageGeneral() |
---|
101 | n/a | self.buttonHelp.pack(side=RIGHT,padx=5) |
---|
102 | n/a | self.buttonOk.pack(side=LEFT,padx=5) |
---|
103 | n/a | self.buttonApply.pack(side=LEFT,padx=5) |
---|
104 | n/a | self.buttonCancel.pack(side=LEFT,padx=5) |
---|
105 | n/a | frameActionButtons.pack(side=BOTTOM) |
---|
106 | n/a | Frame(self, height=2, borderwidth=0).pack(side=BOTTOM) |
---|
107 | n/a | self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH) |
---|
108 | n/a | |
---|
109 | n/a | def CreatePageFontTab(self): |
---|
110 | n/a | #tkVars |
---|
111 | n/a | self.fontSize=StringVar(self) |
---|
112 | n/a | self.fontBold=BooleanVar(self) |
---|
113 | n/a | self.fontName=StringVar(self) |
---|
114 | n/a | self.spaceNum=IntVar(self) |
---|
115 | n/a | self.editFont=tkFont.Font(self,('courier',10,'normal')) |
---|
116 | n/a | ##widget creation |
---|
117 | n/a | #body frame |
---|
118 | n/a | frame=self.tabPages.pages['Fonts/Tabs'].frame |
---|
119 | n/a | #body section frames |
---|
120 | n/a | frameFont=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
121 | n/a | text=' Base Editor Font ') |
---|
122 | n/a | frameIndent=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
123 | n/a | text=' Indentation Width ') |
---|
124 | n/a | #frameFont |
---|
125 | n/a | frameFontName=Frame(frameFont) |
---|
126 | n/a | frameFontParam=Frame(frameFont) |
---|
127 | n/a | labelFontNameTitle=Label(frameFontName,justify=LEFT, |
---|
128 | n/a | text='Font Face :') |
---|
129 | n/a | self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE, |
---|
130 | n/a | exportselection=FALSE) |
---|
131 | n/a | self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease) |
---|
132 | n/a | scrollFont=Scrollbar(frameFontName) |
---|
133 | n/a | scrollFont.config(command=self.listFontName.yview) |
---|
134 | n/a | self.listFontName.config(yscrollcommand=scrollFont.set) |
---|
135 | n/a | labelFontSizeTitle=Label(frameFontParam,text='Size :') |
---|
136 | n/a | self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None, |
---|
137 | n/a | command=self.SetFontSample) |
---|
138 | n/a | checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold, |
---|
139 | n/a | onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample) |
---|
140 | n/a | frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1) |
---|
141 | n/a | self.labelFontSample=Label(frameFontSample, |
---|
142 | n/a | text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', |
---|
143 | n/a | justify=LEFT,font=self.editFont) |
---|
144 | n/a | #frameIndent |
---|
145 | n/a | frameIndentSize=Frame(frameIndent) |
---|
146 | n/a | labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT, |
---|
147 | n/a | text='Python Standard: 4 Spaces!') |
---|
148 | n/a | self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum, |
---|
149 | n/a | orient='horizontal', |
---|
150 | n/a | tickinterval=2, from_=2, to=16) |
---|
151 | n/a | #widget packing |
---|
152 | n/a | #body |
---|
153 | n/a | frameFont.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
154 | n/a | frameIndent.pack(side=LEFT,padx=5,pady=5,fill=Y) |
---|
155 | n/a | #frameFont |
---|
156 | n/a | frameFontName.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
157 | n/a | frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
158 | n/a | labelFontNameTitle.pack(side=TOP,anchor=W) |
---|
159 | n/a | self.listFontName.pack(side=LEFT,expand=TRUE,fill=X) |
---|
160 | n/a | scrollFont.pack(side=LEFT,fill=Y) |
---|
161 | n/a | labelFontSizeTitle.pack(side=LEFT,anchor=W) |
---|
162 | n/a | self.optMenuFontSize.pack(side=LEFT,anchor=W) |
---|
163 | n/a | checkFontBold.pack(side=LEFT,anchor=W,padx=20) |
---|
164 | n/a | frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
165 | n/a | self.labelFontSample.pack(expand=TRUE,fill=BOTH) |
---|
166 | n/a | #frameIndent |
---|
167 | n/a | frameIndentSize.pack(side=TOP,fill=X) |
---|
168 | n/a | labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5) |
---|
169 | n/a | self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X) |
---|
170 | n/a | return frame |
---|
171 | n/a | |
---|
172 | n/a | def CreatePageHighlight(self): |
---|
173 | n/a | self.builtinTheme=StringVar(self) |
---|
174 | n/a | self.customTheme=StringVar(self) |
---|
175 | n/a | self.fgHilite=BooleanVar(self) |
---|
176 | n/a | self.colour=StringVar(self) |
---|
177 | n/a | self.fontName=StringVar(self) |
---|
178 | n/a | self.themeIsBuiltin=BooleanVar(self) |
---|
179 | n/a | self.highlightTarget=StringVar(self) |
---|
180 | n/a | ##widget creation |
---|
181 | n/a | #body frame |
---|
182 | n/a | frame=self.tabPages.pages['Highlighting'].frame |
---|
183 | n/a | #body section frames |
---|
184 | n/a | frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
185 | n/a | text=' Custom Highlighting ') |
---|
186 | n/a | frameTheme=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
187 | n/a | text=' Highlighting Theme ') |
---|
188 | n/a | #frameCustom |
---|
189 | n/a | self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1, |
---|
190 | n/a | font=('courier',12,''),cursor='hand2',width=21,height=11, |
---|
191 | n/a | takefocus=FALSE,highlightthickness=0,wrap=NONE) |
---|
192 | n/a | text=self.textHighlightSample |
---|
193 | n/a | text.bind('<Double-Button-1>',lambda e: 'break') |
---|
194 | n/a | text.bind('<B1-Motion>',lambda e: 'break') |
---|
195 | n/a | textAndTags=(('#you can click here','comment'),('\n','normal'), |
---|
196 | n/a | ('#to choose items','comment'),('\n','normal'),('def','keyword'), |
---|
197 | n/a | (' ','normal'),('func','definition'),('(param):','normal'), |
---|
198 | n/a | ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'), |
---|
199 | n/a | ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'), |
---|
200 | n/a | ('\n var2 = ','normal'),("'found'",'hit'), |
---|
201 | n/a | ('\n var3 = ','normal'),('list', 'builtin'), ('(','normal'), |
---|
202 | n/a | ('None', 'keyword'),(')\n\n','normal'), |
---|
203 | n/a | (' error ','error'),(' ','normal'),('cursor |','cursor'), |
---|
204 | n/a | ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'), |
---|
205 | n/a | (' ','normal'),('stderr','stderr'),('\n','normal')) |
---|
206 | n/a | for txTa in textAndTags: |
---|
207 | n/a | text.insert(END,txTa[0],txTa[1]) |
---|
208 | n/a | for element in self.themeElements: |
---|
209 | n/a | text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>', |
---|
210 | n/a | lambda event,elem=element: event.widget.winfo_toplevel() |
---|
211 | n/a | .highlightTarget.set(elem)) |
---|
212 | n/a | text.config(state=DISABLED) |
---|
213 | n/a | self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1) |
---|
214 | n/a | frameFgBg=Frame(frameCustom) |
---|
215 | n/a | buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :', |
---|
216 | n/a | command=self.GetColour,highlightthickness=0) |
---|
217 | n/a | self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet, |
---|
218 | n/a | self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding |
---|
219 | n/a | self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite, |
---|
220 | n/a | value=1,text='Foreground',command=self.SetColourSampleBinding) |
---|
221 | n/a | self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite, |
---|
222 | n/a | value=0,text='Background',command=self.SetColourSampleBinding) |
---|
223 | n/a | self.fgHilite.set(1) |
---|
224 | n/a | buttonSaveCustomTheme=Button(frameCustom, |
---|
225 | n/a | text='Save as New Custom Theme',command=self.SaveAsNewTheme) |
---|
226 | n/a | #frameTheme |
---|
227 | n/a | labelTypeTitle=Label(frameTheme,text='Select : ') |
---|
228 | n/a | self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin, |
---|
229 | n/a | value=1,command=self.SetThemeType,text='a Built-in Theme') |
---|
230 | n/a | self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin, |
---|
231 | n/a | value=0,command=self.SetThemeType,text='a Custom Theme') |
---|
232 | n/a | self.optMenuThemeBuiltin=DynOptionMenu(frameTheme, |
---|
233 | n/a | self.builtinTheme,None,command=None) |
---|
234 | n/a | self.optMenuThemeCustom=DynOptionMenu(frameTheme, |
---|
235 | n/a | self.customTheme,None,command=None) |
---|
236 | n/a | self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme', |
---|
237 | n/a | command=self.DeleteCustomTheme) |
---|
238 | n/a | ##widget packing |
---|
239 | n/a | #body |
---|
240 | n/a | frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
241 | n/a | frameTheme.pack(side=LEFT,padx=5,pady=5,fill=Y) |
---|
242 | n/a | #frameCustom |
---|
243 | n/a | self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X) |
---|
244 | n/a | frameFgBg.pack(side=TOP,padx=5,pady=0) |
---|
245 | n/a | self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE, |
---|
246 | n/a | fill=BOTH) |
---|
247 | n/a | buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4) |
---|
248 | n/a | self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3) |
---|
249 | n/a | self.radioFg.pack(side=LEFT,anchor=E) |
---|
250 | n/a | self.radioBg.pack(side=RIGHT,anchor=W) |
---|
251 | n/a | buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5) |
---|
252 | n/a | #frameTheme |
---|
253 | n/a | labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) |
---|
254 | n/a | self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5) |
---|
255 | n/a | self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2) |
---|
256 | n/a | self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5) |
---|
257 | n/a | self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5) |
---|
258 | n/a | self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5) |
---|
259 | n/a | return frame |
---|
260 | n/a | |
---|
261 | n/a | def CreatePageKeys(self): |
---|
262 | n/a | #tkVars |
---|
263 | n/a | self.bindingTarget=StringVar(self) |
---|
264 | n/a | self.builtinKeys=StringVar(self) |
---|
265 | n/a | self.customKeys=StringVar(self) |
---|
266 | n/a | self.keysAreBuiltin=BooleanVar(self) |
---|
267 | n/a | self.keyBinding=StringVar(self) |
---|
268 | n/a | ##widget creation |
---|
269 | n/a | #body frame |
---|
270 | n/a | frame=self.tabPages.pages['Keys'].frame |
---|
271 | n/a | #body section frames |
---|
272 | n/a | frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
273 | n/a | text=' Custom Key Bindings ') |
---|
274 | n/a | frameKeySets=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
275 | n/a | text=' Key Set ') |
---|
276 | n/a | #frameCustom |
---|
277 | n/a | frameTarget=Frame(frameCustom) |
---|
278 | n/a | labelTargetTitle=Label(frameTarget,text='Action - Key(s)') |
---|
279 | n/a | scrollTargetY=Scrollbar(frameTarget) |
---|
280 | n/a | scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) |
---|
281 | n/a | self.listBindings=Listbox(frameTarget,takefocus=FALSE, |
---|
282 | n/a | exportselection=FALSE) |
---|
283 | n/a | self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected) |
---|
284 | n/a | scrollTargetY.config(command=self.listBindings.yview) |
---|
285 | n/a | scrollTargetX.config(command=self.listBindings.xview) |
---|
286 | n/a | self.listBindings.config(yscrollcommand=scrollTargetY.set) |
---|
287 | n/a | self.listBindings.config(xscrollcommand=scrollTargetX.set) |
---|
288 | n/a | self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', |
---|
289 | n/a | command=self.GetNewKeys,state=DISABLED) |
---|
290 | n/a | #frameKeySets |
---|
291 | n/a | frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0) |
---|
292 | n/a | for i in range(2)] |
---|
293 | n/a | self.radioKeysBuiltin=Radiobutton(frames[0],variable=self.keysAreBuiltin, |
---|
294 | n/a | value=1,command=self.SetKeysType,text='Use a Built-in Key Set') |
---|
295 | n/a | self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin, |
---|
296 | n/a | value=0,command=self.SetKeysType,text='Use a Custom Key Set') |
---|
297 | n/a | self.optMenuKeysBuiltin=DynOptionMenu(frames[0], |
---|
298 | n/a | self.builtinKeys,None,command=None) |
---|
299 | n/a | self.optMenuKeysCustom=DynOptionMenu(frames[0], |
---|
300 | n/a | self.customKeys,None,command=None) |
---|
301 | n/a | self.buttonDeleteCustomKeys=Button(frames[1],text='Delete Custom Key Set', |
---|
302 | n/a | command=self.DeleteCustomKeys) |
---|
303 | n/a | buttonSaveCustomKeys=Button(frames[1], |
---|
304 | n/a | text='Save as New Custom Key Set',command=self.SaveAsNewKeySet) |
---|
305 | n/a | ##widget packing |
---|
306 | n/a | #body |
---|
307 | n/a | frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
308 | n/a | frameKeySets.pack(side=BOTTOM,padx=5,pady=5,fill=BOTH) |
---|
309 | n/a | #frameCustom |
---|
310 | n/a | self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5) |
---|
311 | n/a | frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
312 | n/a | #frame target |
---|
313 | n/a | frameTarget.columnconfigure(0,weight=1) |
---|
314 | n/a | frameTarget.rowconfigure(1,weight=1) |
---|
315 | n/a | labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W) |
---|
316 | n/a | self.listBindings.grid(row=1,column=0,sticky=NSEW) |
---|
317 | n/a | scrollTargetY.grid(row=1,column=1,sticky=NS) |
---|
318 | n/a | scrollTargetX.grid(row=2,column=0,sticky=EW) |
---|
319 | n/a | #frameKeySets |
---|
320 | n/a | self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS) |
---|
321 | n/a | self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS) |
---|
322 | n/a | self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW) |
---|
323 | n/a | self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW) |
---|
324 | n/a | self.buttonDeleteCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) |
---|
325 | n/a | buttonSaveCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) |
---|
326 | n/a | frames[0].pack(side=TOP, fill=BOTH, expand=True) |
---|
327 | n/a | frames[1].pack(side=TOP, fill=X, expand=True, pady=2) |
---|
328 | n/a | return frame |
---|
329 | n/a | |
---|
330 | n/a | def CreatePageGeneral(self): |
---|
331 | n/a | #tkVars |
---|
332 | n/a | self.winWidth=StringVar(self) |
---|
333 | n/a | self.winHeight=StringVar(self) |
---|
334 | n/a | self.paraWidth=StringVar(self) |
---|
335 | n/a | self.startupEdit=IntVar(self) |
---|
336 | n/a | self.autoSave=IntVar(self) |
---|
337 | n/a | self.encoding=StringVar(self) |
---|
338 | n/a | self.userHelpBrowser=BooleanVar(self) |
---|
339 | n/a | self.helpBrowser=StringVar(self) |
---|
340 | n/a | #widget creation |
---|
341 | n/a | #body |
---|
342 | n/a | frame=self.tabPages.pages['General'].frame |
---|
343 | n/a | #body section frames |
---|
344 | n/a | frameRun=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
345 | n/a | text=' Startup Preferences ') |
---|
346 | n/a | frameSave=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
347 | n/a | text=' Autosave Preferences ') |
---|
348 | n/a | frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) |
---|
349 | n/a | frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE) |
---|
350 | n/a | frameHelp=LabelFrame(frame,borderwidth=2,relief=GROOVE, |
---|
351 | n/a | text=' Additional Help Sources ') |
---|
352 | n/a | #frameRun |
---|
353 | n/a | labelRunChoiceTitle=Label(frameRun,text='At Startup') |
---|
354 | n/a | radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit, |
---|
355 | n/a | value=1,command=self.SetKeysType,text="Open Edit Window") |
---|
356 | n/a | radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit, |
---|
357 | n/a | value=0,command=self.SetKeysType,text='Open Shell Window') |
---|
358 | n/a | #frameSave |
---|
359 | n/a | labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5) ') |
---|
360 | n/a | radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave, |
---|
361 | n/a | value=0,command=self.SetKeysType,text="Prompt to Save") |
---|
362 | n/a | radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave, |
---|
363 | n/a | value=1,command=self.SetKeysType,text='No Prompt') |
---|
364 | n/a | #frameWinSize |
---|
365 | n/a | labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+ |
---|
366 | n/a | ' (in characters)') |
---|
367 | n/a | labelWinWidthTitle=Label(frameWinSize,text='Width') |
---|
368 | n/a | entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth, |
---|
369 | n/a | width=3) |
---|
370 | n/a | labelWinHeightTitle=Label(frameWinSize,text='Height') |
---|
371 | n/a | entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, |
---|
372 | n/a | width=3) |
---|
373 | n/a | #paragraphFormatWidth |
---|
374 | n/a | labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+ |
---|
375 | n/a | ' width (in characters)') |
---|
376 | n/a | entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth, |
---|
377 | n/a | width=3) |
---|
378 | n/a | #frameHelp |
---|
379 | n/a | frameHelpList=Frame(frameHelp) |
---|
380 | n/a | frameHelpListButtons=Frame(frameHelpList) |
---|
381 | n/a | scrollHelpList=Scrollbar(frameHelpList) |
---|
382 | n/a | self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE, |
---|
383 | n/a | exportselection=FALSE) |
---|
384 | n/a | scrollHelpList.config(command=self.listHelp.yview) |
---|
385 | n/a | self.listHelp.config(yscrollcommand=scrollHelpList.set) |
---|
386 | n/a | self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected) |
---|
387 | n/a | self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit', |
---|
388 | n/a | state=DISABLED,width=8,command=self.HelpListItemEdit) |
---|
389 | n/a | self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add', |
---|
390 | n/a | width=8,command=self.HelpListItemAdd) |
---|
391 | n/a | self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove', |
---|
392 | n/a | state=DISABLED,width=8,command=self.HelpListItemRemove) |
---|
393 | n/a | #widget packing |
---|
394 | n/a | #body |
---|
395 | n/a | frameRun.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
396 | n/a | frameSave.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
397 | n/a | frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
398 | n/a | frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X) |
---|
399 | n/a | frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
400 | n/a | #frameRun |
---|
401 | n/a | labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) |
---|
402 | n/a | radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5) |
---|
403 | n/a | radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5) |
---|
404 | n/a | #frameSave |
---|
405 | n/a | labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) |
---|
406 | n/a | radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5) |
---|
407 | n/a | radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5) |
---|
408 | n/a | #frameWinSize |
---|
409 | n/a | labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) |
---|
410 | n/a | entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5) |
---|
411 | n/a | labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) |
---|
412 | n/a | entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) |
---|
413 | n/a | labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) |
---|
414 | n/a | #paragraphFormatWidth |
---|
415 | n/a | labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) |
---|
416 | n/a | entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) |
---|
417 | n/a | #frameHelp |
---|
418 | n/a | frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) |
---|
419 | n/a | frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) |
---|
420 | n/a | scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y) |
---|
421 | n/a | self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) |
---|
422 | n/a | self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5) |
---|
423 | n/a | self.buttonHelpListAdd.pack(side=TOP,anchor=W) |
---|
424 | n/a | self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5) |
---|
425 | n/a | return frame |
---|
426 | n/a | |
---|
427 | n/a | def AttachVarCallbacks(self): |
---|
428 | n/a | self.fontSize.trace_variable('w',self.VarChanged_fontSize) |
---|
429 | n/a | self.fontName.trace_variable('w',self.VarChanged_fontName) |
---|
430 | n/a | self.fontBold.trace_variable('w',self.VarChanged_fontBold) |
---|
431 | n/a | self.spaceNum.trace_variable('w',self.VarChanged_spaceNum) |
---|
432 | n/a | self.colour.trace_variable('w',self.VarChanged_colour) |
---|
433 | n/a | self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme) |
---|
434 | n/a | self.customTheme.trace_variable('w',self.VarChanged_customTheme) |
---|
435 | n/a | self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin) |
---|
436 | n/a | self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget) |
---|
437 | n/a | self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) |
---|
438 | n/a | self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys) |
---|
439 | n/a | self.customKeys.trace_variable('w',self.VarChanged_customKeys) |
---|
440 | n/a | self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin) |
---|
441 | n/a | self.winWidth.trace_variable('w',self.VarChanged_winWidth) |
---|
442 | n/a | self.winHeight.trace_variable('w',self.VarChanged_winHeight) |
---|
443 | n/a | self.paraWidth.trace_variable('w',self.VarChanged_paraWidth) |
---|
444 | n/a | self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) |
---|
445 | n/a | self.autoSave.trace_variable('w',self.VarChanged_autoSave) |
---|
446 | n/a | self.encoding.trace_variable('w',self.VarChanged_encoding) |
---|
447 | n/a | |
---|
448 | n/a | def VarChanged_fontSize(self,*params): |
---|
449 | n/a | value=self.fontSize.get() |
---|
450 | n/a | self.AddChangedItem('main','EditorWindow','font-size',value) |
---|
451 | n/a | |
---|
452 | n/a | def VarChanged_fontName(self,*params): |
---|
453 | n/a | value=self.fontName.get() |
---|
454 | n/a | self.AddChangedItem('main','EditorWindow','font',value) |
---|
455 | n/a | |
---|
456 | n/a | def VarChanged_fontBold(self,*params): |
---|
457 | n/a | value=self.fontBold.get() |
---|
458 | n/a | self.AddChangedItem('main','EditorWindow','font-bold',value) |
---|
459 | n/a | |
---|
460 | n/a | def VarChanged_spaceNum(self,*params): |
---|
461 | n/a | value=self.spaceNum.get() |
---|
462 | n/a | self.AddChangedItem('main','Indent','num-spaces',value) |
---|
463 | n/a | |
---|
464 | n/a | def VarChanged_colour(self,*params): |
---|
465 | n/a | self.OnNewColourSet() |
---|
466 | n/a | |
---|
467 | n/a | def VarChanged_builtinTheme(self,*params): |
---|
468 | n/a | value=self.builtinTheme.get() |
---|
469 | n/a | self.AddChangedItem('main','Theme','name',value) |
---|
470 | n/a | self.PaintThemeSample() |
---|
471 | n/a | |
---|
472 | n/a | def VarChanged_customTheme(self,*params): |
---|
473 | n/a | value=self.customTheme.get() |
---|
474 | n/a | if value != '- no custom themes -': |
---|
475 | n/a | self.AddChangedItem('main','Theme','name',value) |
---|
476 | n/a | self.PaintThemeSample() |
---|
477 | n/a | |
---|
478 | n/a | def VarChanged_themeIsBuiltin(self,*params): |
---|
479 | n/a | value=self.themeIsBuiltin.get() |
---|
480 | n/a | self.AddChangedItem('main','Theme','default',value) |
---|
481 | n/a | if value: |
---|
482 | n/a | self.VarChanged_builtinTheme() |
---|
483 | n/a | else: |
---|
484 | n/a | self.VarChanged_customTheme() |
---|
485 | n/a | |
---|
486 | n/a | def VarChanged_highlightTarget(self,*params): |
---|
487 | n/a | self.SetHighlightTarget() |
---|
488 | n/a | |
---|
489 | n/a | def VarChanged_keyBinding(self,*params): |
---|
490 | n/a | value=self.keyBinding.get() |
---|
491 | n/a | keySet=self.customKeys.get() |
---|
492 | n/a | event=self.listBindings.get(ANCHOR).split()[0] |
---|
493 | n/a | if idleConf.IsCoreBinding(event): |
---|
494 | n/a | #this is a core keybinding |
---|
495 | n/a | self.AddChangedItem('keys',keySet,event,value) |
---|
496 | n/a | else: #this is an extension key binding |
---|
497 | n/a | extName=idleConf.GetExtnNameForEvent(event) |
---|
498 | n/a | extKeybindSection=extName+'_cfgBindings' |
---|
499 | n/a | self.AddChangedItem('extensions',extKeybindSection,event,value) |
---|
500 | n/a | |
---|
501 | n/a | def VarChanged_builtinKeys(self,*params): |
---|
502 | n/a | value=self.builtinKeys.get() |
---|
503 | n/a | self.AddChangedItem('main','Keys','name',value) |
---|
504 | n/a | self.LoadKeysList(value) |
---|
505 | n/a | |
---|
506 | n/a | def VarChanged_customKeys(self,*params): |
---|
507 | n/a | value=self.customKeys.get() |
---|
508 | n/a | if value != '- no custom keys -': |
---|
509 | n/a | self.AddChangedItem('main','Keys','name',value) |
---|
510 | n/a | self.LoadKeysList(value) |
---|
511 | n/a | |
---|
512 | n/a | def VarChanged_keysAreBuiltin(self,*params): |
---|
513 | n/a | value=self.keysAreBuiltin.get() |
---|
514 | n/a | self.AddChangedItem('main','Keys','default',value) |
---|
515 | n/a | if value: |
---|
516 | n/a | self.VarChanged_builtinKeys() |
---|
517 | n/a | else: |
---|
518 | n/a | self.VarChanged_customKeys() |
---|
519 | n/a | |
---|
520 | n/a | def VarChanged_winWidth(self,*params): |
---|
521 | n/a | value=self.winWidth.get() |
---|
522 | n/a | self.AddChangedItem('main','EditorWindow','width',value) |
---|
523 | n/a | |
---|
524 | n/a | def VarChanged_winHeight(self,*params): |
---|
525 | n/a | value=self.winHeight.get() |
---|
526 | n/a | self.AddChangedItem('main','EditorWindow','height',value) |
---|
527 | n/a | |
---|
528 | n/a | def VarChanged_paraWidth(self,*params): |
---|
529 | n/a | value=self.paraWidth.get() |
---|
530 | n/a | self.AddChangedItem('main','FormatParagraph','paragraph',value) |
---|
531 | n/a | |
---|
532 | n/a | def VarChanged_startupEdit(self,*params): |
---|
533 | n/a | value=self.startupEdit.get() |
---|
534 | n/a | self.AddChangedItem('main','General','editor-on-startup',value) |
---|
535 | n/a | |
---|
536 | n/a | def VarChanged_autoSave(self,*params): |
---|
537 | n/a | value=self.autoSave.get() |
---|
538 | n/a | self.AddChangedItem('main','General','autosave',value) |
---|
539 | n/a | |
---|
540 | n/a | def VarChanged_encoding(self,*params): |
---|
541 | n/a | value=self.encoding.get() |
---|
542 | n/a | self.AddChangedItem('main','EditorWindow','encoding',value) |
---|
543 | n/a | |
---|
544 | n/a | def ResetChangedItems(self): |
---|
545 | n/a | #When any config item is changed in this dialog, an entry |
---|
546 | n/a | #should be made in the relevant section (config type) of this |
---|
547 | n/a | #dictionary. The key should be the config file section name and the |
---|
548 | n/a | #value a dictionary, whose key:value pairs are item=value pairs for |
---|
549 | n/a | #that config file section. |
---|
550 | n/a | self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} |
---|
551 | n/a | |
---|
552 | n/a | def AddChangedItem(self,type,section,item,value): |
---|
553 | n/a | value=str(value) #make sure we use a string |
---|
554 | n/a | if section not in self.changedItems[type]: |
---|
555 | n/a | self.changedItems[type][section]={} |
---|
556 | n/a | self.changedItems[type][section][item]=value |
---|
557 | n/a | |
---|
558 | n/a | def GetDefaultItems(self): |
---|
559 | n/a | dItems={'main':{},'highlight':{},'keys':{},'extensions':{}} |
---|
560 | n/a | for configType in dItems: |
---|
561 | n/a | sections=idleConf.GetSectionList('default',configType) |
---|
562 | n/a | for section in sections: |
---|
563 | n/a | dItems[configType][section]={} |
---|
564 | n/a | options=idleConf.defaultCfg[configType].GetOptionList(section) |
---|
565 | n/a | for option in options: |
---|
566 | n/a | dItems[configType][section][option]=( |
---|
567 | n/a | idleConf.defaultCfg[configType].Get(section,option)) |
---|
568 | n/a | return dItems |
---|
569 | n/a | |
---|
570 | n/a | def SetThemeType(self): |
---|
571 | n/a | if self.themeIsBuiltin.get(): |
---|
572 | n/a | self.optMenuThemeBuiltin.config(state=NORMAL) |
---|
573 | n/a | self.optMenuThemeCustom.config(state=DISABLED) |
---|
574 | n/a | self.buttonDeleteCustomTheme.config(state=DISABLED) |
---|
575 | n/a | else: |
---|
576 | n/a | self.optMenuThemeBuiltin.config(state=DISABLED) |
---|
577 | n/a | self.radioThemeCustom.config(state=NORMAL) |
---|
578 | n/a | self.optMenuThemeCustom.config(state=NORMAL) |
---|
579 | n/a | self.buttonDeleteCustomTheme.config(state=NORMAL) |
---|
580 | n/a | |
---|
581 | n/a | def SetKeysType(self): |
---|
582 | n/a | if self.keysAreBuiltin.get(): |
---|
583 | n/a | self.optMenuKeysBuiltin.config(state=NORMAL) |
---|
584 | n/a | self.optMenuKeysCustom.config(state=DISABLED) |
---|
585 | n/a | self.buttonDeleteCustomKeys.config(state=DISABLED) |
---|
586 | n/a | else: |
---|
587 | n/a | self.optMenuKeysBuiltin.config(state=DISABLED) |
---|
588 | n/a | self.radioKeysCustom.config(state=NORMAL) |
---|
589 | n/a | self.optMenuKeysCustom.config(state=NORMAL) |
---|
590 | n/a | self.buttonDeleteCustomKeys.config(state=NORMAL) |
---|
591 | n/a | |
---|
592 | n/a | def GetNewKeys(self): |
---|
593 | n/a | listIndex=self.listBindings.index(ANCHOR) |
---|
594 | n/a | binding=self.listBindings.get(listIndex) |
---|
595 | n/a | bindName=binding.split()[0] #first part, up to first space |
---|
596 | n/a | if self.keysAreBuiltin.get(): |
---|
597 | n/a | currentKeySetName=self.builtinKeys.get() |
---|
598 | n/a | else: |
---|
599 | n/a | currentKeySetName=self.customKeys.get() |
---|
600 | n/a | currentBindings=idleConf.GetCurrentKeySet() |
---|
601 | n/a | if currentKeySetName in self.changedItems['keys']: #unsaved changes |
---|
602 | n/a | keySetChanges=self.changedItems['keys'][currentKeySetName] |
---|
603 | n/a | for event in keySetChanges: |
---|
604 | n/a | currentBindings[event]=keySetChanges[event].split() |
---|
605 | n/a | currentKeySequences = list(currentBindings.values()) |
---|
606 | n/a | newKeys=GetKeysDialog(self,'Get New Keys',bindName, |
---|
607 | n/a | currentKeySequences).result |
---|
608 | n/a | if newKeys: #new keys were specified |
---|
609 | n/a | if self.keysAreBuiltin.get(): #current key set is a built-in |
---|
610 | n/a | message=('Your changes will be saved as a new Custom Key Set. '+ |
---|
611 | n/a | 'Enter a name for your new Custom Key Set below.') |
---|
612 | n/a | newKeySet=self.GetNewKeysName(message) |
---|
613 | n/a | if not newKeySet: #user cancelled custom key set creation |
---|
614 | n/a | self.listBindings.select_set(listIndex) |
---|
615 | n/a | self.listBindings.select_anchor(listIndex) |
---|
616 | n/a | return |
---|
617 | n/a | else: #create new custom key set based on previously active key set |
---|
618 | n/a | self.CreateNewKeySet(newKeySet) |
---|
619 | n/a | self.listBindings.delete(listIndex) |
---|
620 | n/a | self.listBindings.insert(listIndex,bindName+' - '+newKeys) |
---|
621 | n/a | self.listBindings.select_set(listIndex) |
---|
622 | n/a | self.listBindings.select_anchor(listIndex) |
---|
623 | n/a | self.keyBinding.set(newKeys) |
---|
624 | n/a | else: |
---|
625 | n/a | self.listBindings.select_set(listIndex) |
---|
626 | n/a | self.listBindings.select_anchor(listIndex) |
---|
627 | n/a | |
---|
628 | n/a | def GetNewKeysName(self,message): |
---|
629 | n/a | usedNames=(idleConf.GetSectionList('user','keys')+ |
---|
630 | n/a | idleConf.GetSectionList('default','keys')) |
---|
631 | n/a | newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', |
---|
632 | n/a | message,usedNames).result |
---|
633 | n/a | return newKeySet |
---|
634 | n/a | |
---|
635 | n/a | def SaveAsNewKeySet(self): |
---|
636 | n/a | newKeysName=self.GetNewKeysName('New Key Set Name:') |
---|
637 | n/a | if newKeysName: |
---|
638 | n/a | self.CreateNewKeySet(newKeysName) |
---|
639 | n/a | |
---|
640 | n/a | def KeyBindingSelected(self,event): |
---|
641 | n/a | self.buttonNewKeys.config(state=NORMAL) |
---|
642 | n/a | |
---|
643 | n/a | def CreateNewKeySet(self,newKeySetName): |
---|
644 | n/a | #creates new custom key set based on the previously active key set, |
---|
645 | n/a | #and makes the new key set active |
---|
646 | n/a | if self.keysAreBuiltin.get(): |
---|
647 | n/a | prevKeySetName=self.builtinKeys.get() |
---|
648 | n/a | else: |
---|
649 | n/a | prevKeySetName=self.customKeys.get() |
---|
650 | n/a | prevKeys=idleConf.GetCoreKeys(prevKeySetName) |
---|
651 | n/a | newKeys={} |
---|
652 | n/a | for event in prevKeys: #add key set to changed items |
---|
653 | n/a | eventName=event[2:-2] #trim off the angle brackets |
---|
654 | n/a | binding=' '.join(prevKeys[event]) |
---|
655 | n/a | newKeys[eventName]=binding |
---|
656 | n/a | #handle any unsaved changes to prev key set |
---|
657 | n/a | if prevKeySetName in self.changedItems['keys']: |
---|
658 | n/a | keySetChanges=self.changedItems['keys'][prevKeySetName] |
---|
659 | n/a | for event in keySetChanges: |
---|
660 | n/a | newKeys[event]=keySetChanges[event] |
---|
661 | n/a | #save the new theme |
---|
662 | n/a | self.SaveNewKeySet(newKeySetName,newKeys) |
---|
663 | n/a | #change gui over to the new key set |
---|
664 | n/a | customKeyList=idleConf.GetSectionList('user','keys') |
---|
665 | n/a | customKeyList.sort() |
---|
666 | n/a | self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) |
---|
667 | n/a | self.keysAreBuiltin.set(0) |
---|
668 | n/a | self.SetKeysType() |
---|
669 | n/a | |
---|
670 | n/a | def LoadKeysList(self,keySetName): |
---|
671 | n/a | reselect=0 |
---|
672 | n/a | newKeySet=0 |
---|
673 | n/a | if self.listBindings.curselection(): |
---|
674 | n/a | reselect=1 |
---|
675 | n/a | listIndex=self.listBindings.index(ANCHOR) |
---|
676 | n/a | keySet=idleConf.GetKeySet(keySetName) |
---|
677 | n/a | bindNames = list(keySet.keys()) |
---|
678 | n/a | bindNames.sort() |
---|
679 | n/a | self.listBindings.delete(0,END) |
---|
680 | n/a | for bindName in bindNames: |
---|
681 | n/a | key=' '.join(keySet[bindName]) #make key(s) into a string |
---|
682 | n/a | bindName=bindName[2:-2] #trim off the angle brackets |
---|
683 | n/a | if keySetName in self.changedItems['keys']: |
---|
684 | n/a | #handle any unsaved changes to this key set |
---|
685 | n/a | if bindName in self.changedItems['keys'][keySetName]: |
---|
686 | n/a | key=self.changedItems['keys'][keySetName][bindName] |
---|
687 | n/a | self.listBindings.insert(END, bindName+' - '+key) |
---|
688 | n/a | if reselect: |
---|
689 | n/a | self.listBindings.see(listIndex) |
---|
690 | n/a | self.listBindings.select_set(listIndex) |
---|
691 | n/a | self.listBindings.select_anchor(listIndex) |
---|
692 | n/a | |
---|
693 | n/a | def DeleteCustomKeys(self): |
---|
694 | n/a | keySetName=self.customKeys.get() |
---|
695 | n/a | if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+ |
---|
696 | n/a | 'to delete the key set %r ?' % (keySetName), |
---|
697 | n/a | parent=self): |
---|
698 | n/a | return |
---|
699 | n/a | #remove key set from config |
---|
700 | n/a | idleConf.userCfg['keys'].remove_section(keySetName) |
---|
701 | n/a | if keySetName in self.changedItems['keys']: |
---|
702 | n/a | del(self.changedItems['keys'][keySetName]) |
---|
703 | n/a | #write changes |
---|
704 | n/a | idleConf.userCfg['keys'].Save() |
---|
705 | n/a | #reload user key set list |
---|
706 | n/a | itemList=idleConf.GetSectionList('user','keys') |
---|
707 | n/a | itemList.sort() |
---|
708 | n/a | if not itemList: |
---|
709 | n/a | self.radioKeysCustom.config(state=DISABLED) |
---|
710 | n/a | self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -') |
---|
711 | n/a | else: |
---|
712 | n/a | self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) |
---|
713 | n/a | #revert to default key set |
---|
714 | n/a | self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default')) |
---|
715 | n/a | self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name')) |
---|
716 | n/a | #user can't back out of these changes, they must be applied now |
---|
717 | n/a | self.Apply() |
---|
718 | n/a | self.SetKeysType() |
---|
719 | n/a | |
---|
720 | n/a | def DeleteCustomTheme(self): |
---|
721 | n/a | themeName=self.customTheme.get() |
---|
722 | n/a | if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+ |
---|
723 | n/a | 'to delete the theme %r ?' % (themeName,), |
---|
724 | n/a | parent=self): |
---|
725 | n/a | return |
---|
726 | n/a | #remove theme from config |
---|
727 | n/a | idleConf.userCfg['highlight'].remove_section(themeName) |
---|
728 | n/a | if themeName in self.changedItems['highlight']: |
---|
729 | n/a | del(self.changedItems['highlight'][themeName]) |
---|
730 | n/a | #write changes |
---|
731 | n/a | idleConf.userCfg['highlight'].Save() |
---|
732 | n/a | #reload user theme list |
---|
733 | n/a | itemList=idleConf.GetSectionList('user','highlight') |
---|
734 | n/a | itemList.sort() |
---|
735 | n/a | if not itemList: |
---|
736 | n/a | self.radioThemeCustom.config(state=DISABLED) |
---|
737 | n/a | self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -') |
---|
738 | n/a | else: |
---|
739 | n/a | self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) |
---|
740 | n/a | #revert to default theme |
---|
741 | n/a | self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default')) |
---|
742 | n/a | self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name')) |
---|
743 | n/a | #user can't back out of these changes, they must be applied now |
---|
744 | n/a | self.Apply() |
---|
745 | n/a | self.SetThemeType() |
---|
746 | n/a | |
---|
747 | n/a | def GetColour(self): |
---|
748 | n/a | target=self.highlightTarget.get() |
---|
749 | n/a | prevColour=self.frameColourSet.cget('bg') |
---|
750 | n/a | rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, |
---|
751 | n/a | title='Pick new colour for : '+target,initialcolor=prevColour) |
---|
752 | n/a | if colourString and (colourString!=prevColour): |
---|
753 | n/a | #user didn't cancel, and they chose a new colour |
---|
754 | n/a | if self.themeIsBuiltin.get(): #current theme is a built-in |
---|
755 | n/a | message=('Your changes will be saved as a new Custom Theme. '+ |
---|
756 | n/a | 'Enter a name for your new Custom Theme below.') |
---|
757 | n/a | newTheme=self.GetNewThemeName(message) |
---|
758 | n/a | if not newTheme: #user cancelled custom theme creation |
---|
759 | n/a | return |
---|
760 | n/a | else: #create new custom theme based on previously active theme |
---|
761 | n/a | self.CreateNewTheme(newTheme) |
---|
762 | n/a | self.colour.set(colourString) |
---|
763 | n/a | else: #current theme is user defined |
---|
764 | n/a | self.colour.set(colourString) |
---|
765 | n/a | |
---|
766 | n/a | def OnNewColourSet(self): |
---|
767 | n/a | newColour=self.colour.get() |
---|
768 | n/a | self.frameColourSet.config(bg=newColour)#set sample |
---|
769 | n/a | if self.fgHilite.get(): plane='foreground' |
---|
770 | n/a | else: plane='background' |
---|
771 | n/a | sampleElement=self.themeElements[self.highlightTarget.get()][0] |
---|
772 | n/a | self.textHighlightSample.tag_config(sampleElement, **{plane:newColour}) |
---|
773 | n/a | theme=self.customTheme.get() |
---|
774 | n/a | themeElement=sampleElement+'-'+plane |
---|
775 | n/a | self.AddChangedItem('highlight',theme,themeElement,newColour) |
---|
776 | n/a | |
---|
777 | n/a | def GetNewThemeName(self,message): |
---|
778 | n/a | usedNames=(idleConf.GetSectionList('user','highlight')+ |
---|
779 | n/a | idleConf.GetSectionList('default','highlight')) |
---|
780 | n/a | newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', |
---|
781 | n/a | message,usedNames).result |
---|
782 | n/a | return newTheme |
---|
783 | n/a | |
---|
784 | n/a | def SaveAsNewTheme(self): |
---|
785 | n/a | newThemeName=self.GetNewThemeName('New Theme Name:') |
---|
786 | n/a | if newThemeName: |
---|
787 | n/a | self.CreateNewTheme(newThemeName) |
---|
788 | n/a | |
---|
789 | n/a | def CreateNewTheme(self,newThemeName): |
---|
790 | n/a | #creates new custom theme based on the previously active theme, |
---|
791 | n/a | #and makes the new theme active |
---|
792 | n/a | if self.themeIsBuiltin.get(): |
---|
793 | n/a | themeType='default' |
---|
794 | n/a | themeName=self.builtinTheme.get() |
---|
795 | n/a | else: |
---|
796 | n/a | themeType='user' |
---|
797 | n/a | themeName=self.customTheme.get() |
---|
798 | n/a | newTheme=idleConf.GetThemeDict(themeType,themeName) |
---|
799 | n/a | #apply any of the old theme's unsaved changes to the new theme |
---|
800 | n/a | if themeName in self.changedItems['highlight']: |
---|
801 | n/a | themeChanges=self.changedItems['highlight'][themeName] |
---|
802 | n/a | for element in themeChanges: |
---|
803 | n/a | newTheme[element]=themeChanges[element] |
---|
804 | n/a | #save the new theme |
---|
805 | n/a | self.SaveNewTheme(newThemeName,newTheme) |
---|
806 | n/a | #change gui over to the new theme |
---|
807 | n/a | customThemeList=idleConf.GetSectionList('user','highlight') |
---|
808 | n/a | customThemeList.sort() |
---|
809 | n/a | self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) |
---|
810 | n/a | self.themeIsBuiltin.set(0) |
---|
811 | n/a | self.SetThemeType() |
---|
812 | n/a | |
---|
813 | n/a | def OnListFontButtonRelease(self,event): |
---|
814 | n/a | font = self.listFontName.get(ANCHOR) |
---|
815 | n/a | self.fontName.set(font.lower()) |
---|
816 | n/a | self.SetFontSample() |
---|
817 | n/a | |
---|
818 | n/a | def SetFontSample(self,event=None): |
---|
819 | n/a | fontName=self.fontName.get() |
---|
820 | n/a | if self.fontBold.get(): |
---|
821 | n/a | fontWeight=tkFont.BOLD |
---|
822 | n/a | else: |
---|
823 | n/a | fontWeight=tkFont.NORMAL |
---|
824 | n/a | newFont = (fontName, self.fontSize.get(), fontWeight) |
---|
825 | n/a | self.labelFontSample.config(font=newFont) |
---|
826 | n/a | self.textHighlightSample.configure(font=newFont) |
---|
827 | n/a | |
---|
828 | n/a | def SetHighlightTarget(self): |
---|
829 | n/a | if self.highlightTarget.get()=='Cursor': #bg not possible |
---|
830 | n/a | self.radioFg.config(state=DISABLED) |
---|
831 | n/a | self.radioBg.config(state=DISABLED) |
---|
832 | n/a | self.fgHilite.set(1) |
---|
833 | n/a | else: #both fg and bg can be set |
---|
834 | n/a | self.radioFg.config(state=NORMAL) |
---|
835 | n/a | self.radioBg.config(state=NORMAL) |
---|
836 | n/a | self.fgHilite.set(1) |
---|
837 | n/a | self.SetColourSample() |
---|
838 | n/a | |
---|
839 | n/a | def SetColourSampleBinding(self,*args): |
---|
840 | n/a | self.SetColourSample() |
---|
841 | n/a | |
---|
842 | n/a | def SetColourSample(self): |
---|
843 | n/a | #set the colour smaple area |
---|
844 | n/a | tag=self.themeElements[self.highlightTarget.get()][0] |
---|
845 | n/a | if self.fgHilite.get(): plane='foreground' |
---|
846 | n/a | else: plane='background' |
---|
847 | n/a | colour=self.textHighlightSample.tag_cget(tag,plane) |
---|
848 | n/a | self.frameColourSet.config(bg=colour) |
---|
849 | n/a | |
---|
850 | n/a | def PaintThemeSample(self): |
---|
851 | n/a | if self.themeIsBuiltin.get(): #a default theme |
---|
852 | n/a | theme=self.builtinTheme.get() |
---|
853 | n/a | else: #a user theme |
---|
854 | n/a | theme=self.customTheme.get() |
---|
855 | n/a | for elementTitle in self.themeElements: |
---|
856 | n/a | element=self.themeElements[elementTitle][0] |
---|
857 | n/a | colours=idleConf.GetHighlight(theme,element) |
---|
858 | n/a | if element=='cursor': #cursor sample needs special painting |
---|
859 | n/a | colours['background']=idleConf.GetHighlight(theme, |
---|
860 | n/a | 'normal', fgBg='bg') |
---|
861 | n/a | #handle any unsaved changes to this theme |
---|
862 | n/a | if theme in self.changedItems['highlight']: |
---|
863 | n/a | themeDict=self.changedItems['highlight'][theme] |
---|
864 | n/a | if element+'-foreground' in themeDict: |
---|
865 | n/a | colours['foreground']=themeDict[element+'-foreground'] |
---|
866 | n/a | if element+'-background' in themeDict: |
---|
867 | n/a | colours['background']=themeDict[element+'-background'] |
---|
868 | n/a | self.textHighlightSample.tag_config(element, **colours) |
---|
869 | n/a | self.SetColourSample() |
---|
870 | n/a | |
---|
871 | n/a | def HelpSourceSelected(self,event): |
---|
872 | n/a | self.SetHelpListButtonStates() |
---|
873 | n/a | |
---|
874 | n/a | def SetHelpListButtonStates(self): |
---|
875 | n/a | if self.listHelp.size()<1: #no entries in list |
---|
876 | n/a | self.buttonHelpListEdit.config(state=DISABLED) |
---|
877 | n/a | self.buttonHelpListRemove.config(state=DISABLED) |
---|
878 | n/a | else: #there are some entries |
---|
879 | n/a | if self.listHelp.curselection(): #there currently is a selection |
---|
880 | n/a | self.buttonHelpListEdit.config(state=NORMAL) |
---|
881 | n/a | self.buttonHelpListRemove.config(state=NORMAL) |
---|
882 | n/a | else: #there currently is not a selection |
---|
883 | n/a | self.buttonHelpListEdit.config(state=DISABLED) |
---|
884 | n/a | self.buttonHelpListRemove.config(state=DISABLED) |
---|
885 | n/a | |
---|
886 | n/a | def HelpListItemAdd(self): |
---|
887 | n/a | helpSource=GetHelpSourceDialog(self,'New Help Source').result |
---|
888 | n/a | if helpSource: |
---|
889 | n/a | self.userHelpList.append( (helpSource[0],helpSource[1]) ) |
---|
890 | n/a | self.listHelp.insert(END,helpSource[0]) |
---|
891 | n/a | self.UpdateUserHelpChangedItems() |
---|
892 | n/a | self.SetHelpListButtonStates() |
---|
893 | n/a | |
---|
894 | n/a | def HelpListItemEdit(self): |
---|
895 | n/a | itemIndex=self.listHelp.index(ANCHOR) |
---|
896 | n/a | helpSource=self.userHelpList[itemIndex] |
---|
897 | n/a | newHelpSource=GetHelpSourceDialog(self,'Edit Help Source', |
---|
898 | n/a | menuItem=helpSource[0],filePath=helpSource[1]).result |
---|
899 | n/a | if (not newHelpSource) or (newHelpSource==helpSource): |
---|
900 | n/a | return #no changes |
---|
901 | n/a | self.userHelpList[itemIndex]=newHelpSource |
---|
902 | n/a | self.listHelp.delete(itemIndex) |
---|
903 | n/a | self.listHelp.insert(itemIndex,newHelpSource[0]) |
---|
904 | n/a | self.UpdateUserHelpChangedItems() |
---|
905 | n/a | self.SetHelpListButtonStates() |
---|
906 | n/a | |
---|
907 | n/a | def HelpListItemRemove(self): |
---|
908 | n/a | itemIndex=self.listHelp.index(ANCHOR) |
---|
909 | n/a | del(self.userHelpList[itemIndex]) |
---|
910 | n/a | self.listHelp.delete(itemIndex) |
---|
911 | n/a | self.UpdateUserHelpChangedItems() |
---|
912 | n/a | self.SetHelpListButtonStates() |
---|
913 | n/a | |
---|
914 | n/a | def UpdateUserHelpChangedItems(self): |
---|
915 | n/a | "Clear and rebuild the HelpFiles section in self.changedItems" |
---|
916 | n/a | self.changedItems['main']['HelpFiles'] = {} |
---|
917 | n/a | for num in range(1,len(self.userHelpList)+1): |
---|
918 | n/a | self.AddChangedItem('main','HelpFiles',str(num), |
---|
919 | n/a | ';'.join(self.userHelpList[num-1][:2])) |
---|
920 | n/a | |
---|
921 | n/a | def LoadFontCfg(self): |
---|
922 | n/a | ##base editor font selection list |
---|
923 | n/a | fonts=list(tkFont.families(self)) |
---|
924 | n/a | fonts.sort() |
---|
925 | n/a | for font in fonts: |
---|
926 | n/a | self.listFontName.insert(END,font) |
---|
927 | n/a | configuredFont=idleConf.GetOption('main','EditorWindow','font', |
---|
928 | n/a | default='courier') |
---|
929 | n/a | lc_configuredFont = configuredFont.lower() |
---|
930 | n/a | self.fontName.set(lc_configuredFont) |
---|
931 | n/a | lc_fonts = [s.lower() for s in fonts] |
---|
932 | n/a | if lc_configuredFont in lc_fonts: |
---|
933 | n/a | currentFontIndex = lc_fonts.index(lc_configuredFont) |
---|
934 | n/a | self.listFontName.see(currentFontIndex) |
---|
935 | n/a | self.listFontName.select_set(currentFontIndex) |
---|
936 | n/a | self.listFontName.select_anchor(currentFontIndex) |
---|
937 | n/a | ##font size dropdown |
---|
938 | n/a | fontSize=idleConf.GetOption('main', 'EditorWindow', 'font-size', |
---|
939 | n/a | type='int', default='10') |
---|
940 | n/a | self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', |
---|
941 | n/a | '16','18','20','22'), fontSize ) |
---|
942 | n/a | ##fontWeight |
---|
943 | n/a | self.fontBold.set(idleConf.GetOption('main','EditorWindow', |
---|
944 | n/a | 'font-bold',default=0,type='bool')) |
---|
945 | n/a | ##font sample |
---|
946 | n/a | self.SetFontSample() |
---|
947 | n/a | |
---|
948 | n/a | def LoadTabCfg(self): |
---|
949 | n/a | ##indent sizes |
---|
950 | n/a | spaceNum=idleConf.GetOption('main','Indent','num-spaces', |
---|
951 | n/a | default=4,type='int') |
---|
952 | n/a | self.spaceNum.set(spaceNum) |
---|
953 | n/a | |
---|
954 | n/a | def LoadThemeCfg(self): |
---|
955 | n/a | ##current theme type radiobutton |
---|
956 | n/a | self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default', |
---|
957 | n/a | type='bool',default=1)) |
---|
958 | n/a | ##currently set theme |
---|
959 | n/a | currentOption=idleConf.CurrentTheme() |
---|
960 | n/a | ##load available theme option menus |
---|
961 | n/a | if self.themeIsBuiltin.get(): #default theme selected |
---|
962 | n/a | itemList=idleConf.GetSectionList('default','highlight') |
---|
963 | n/a | itemList.sort() |
---|
964 | n/a | self.optMenuThemeBuiltin.SetMenu(itemList,currentOption) |
---|
965 | n/a | itemList=idleConf.GetSectionList('user','highlight') |
---|
966 | n/a | itemList.sort() |
---|
967 | n/a | if not itemList: |
---|
968 | n/a | self.radioThemeCustom.config(state=DISABLED) |
---|
969 | n/a | self.customTheme.set('- no custom themes -') |
---|
970 | n/a | else: |
---|
971 | n/a | self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) |
---|
972 | n/a | else: #user theme selected |
---|
973 | n/a | itemList=idleConf.GetSectionList('user','highlight') |
---|
974 | n/a | itemList.sort() |
---|
975 | n/a | self.optMenuThemeCustom.SetMenu(itemList,currentOption) |
---|
976 | n/a | itemList=idleConf.GetSectionList('default','highlight') |
---|
977 | n/a | itemList.sort() |
---|
978 | n/a | self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0]) |
---|
979 | n/a | self.SetThemeType() |
---|
980 | n/a | ##load theme element option menu |
---|
981 | n/a | themeNames = list(self.themeElements.keys()) |
---|
982 | n/a | themeNames.sort(key=lambda x: self.themeElements[x][1]) |
---|
983 | n/a | self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0]) |
---|
984 | n/a | self.PaintThemeSample() |
---|
985 | n/a | self.SetHighlightTarget() |
---|
986 | n/a | |
---|
987 | n/a | def LoadKeyCfg(self): |
---|
988 | n/a | ##current keys type radiobutton |
---|
989 | n/a | self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default', |
---|
990 | n/a | type='bool',default=1)) |
---|
991 | n/a | ##currently set keys |
---|
992 | n/a | currentOption=idleConf.CurrentKeys() |
---|
993 | n/a | ##load available keyset option menus |
---|
994 | n/a | if self.keysAreBuiltin.get(): #default theme selected |
---|
995 | n/a | itemList=idleConf.GetSectionList('default','keys') |
---|
996 | n/a | itemList.sort() |
---|
997 | n/a | self.optMenuKeysBuiltin.SetMenu(itemList,currentOption) |
---|
998 | n/a | itemList=idleConf.GetSectionList('user','keys') |
---|
999 | n/a | itemList.sort() |
---|
1000 | n/a | if not itemList: |
---|
1001 | n/a | self.radioKeysCustom.config(state=DISABLED) |
---|
1002 | n/a | self.customKeys.set('- no custom keys -') |
---|
1003 | n/a | else: |
---|
1004 | n/a | self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) |
---|
1005 | n/a | else: #user key set selected |
---|
1006 | n/a | itemList=idleConf.GetSectionList('user','keys') |
---|
1007 | n/a | itemList.sort() |
---|
1008 | n/a | self.optMenuKeysCustom.SetMenu(itemList,currentOption) |
---|
1009 | n/a | itemList=idleConf.GetSectionList('default','keys') |
---|
1010 | n/a | itemList.sort() |
---|
1011 | n/a | self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) |
---|
1012 | n/a | self.SetKeysType() |
---|
1013 | n/a | ##load keyset element list |
---|
1014 | n/a | keySetName=idleConf.CurrentKeys() |
---|
1015 | n/a | self.LoadKeysList(keySetName) |
---|
1016 | n/a | |
---|
1017 | n/a | def LoadGeneralCfg(self): |
---|
1018 | n/a | #startup state |
---|
1019 | n/a | self.startupEdit.set(idleConf.GetOption('main','General', |
---|
1020 | n/a | 'editor-on-startup',default=1,type='bool')) |
---|
1021 | n/a | #autosave state |
---|
1022 | n/a | self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', |
---|
1023 | n/a | default=0, type='bool')) |
---|
1024 | n/a | #initial window size |
---|
1025 | n/a | self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', |
---|
1026 | n/a | type='int')) |
---|
1027 | n/a | self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', |
---|
1028 | n/a | type='int')) |
---|
1029 | n/a | #initial paragraph reformat size |
---|
1030 | n/a | self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', |
---|
1031 | n/a | type='int')) |
---|
1032 | n/a | # default source encoding |
---|
1033 | n/a | self.encoding.set(idleConf.GetOption('main', 'EditorWindow', |
---|
1034 | n/a | 'encoding', default='none')) |
---|
1035 | n/a | # additional help sources |
---|
1036 | n/a | self.userHelpList = idleConf.GetAllExtraHelpSourcesList() |
---|
1037 | n/a | for helpItem in self.userHelpList: |
---|
1038 | n/a | self.listHelp.insert(END,helpItem[0]) |
---|
1039 | n/a | self.SetHelpListButtonStates() |
---|
1040 | n/a | |
---|
1041 | n/a | def LoadConfigs(self): |
---|
1042 | n/a | """ |
---|
1043 | n/a | load configuration from default and user config files and populate |
---|
1044 | n/a | the widgets on the config dialog pages. |
---|
1045 | n/a | """ |
---|
1046 | n/a | ### fonts / tabs page |
---|
1047 | n/a | self.LoadFontCfg() |
---|
1048 | n/a | self.LoadTabCfg() |
---|
1049 | n/a | ### highlighting page |
---|
1050 | n/a | self.LoadThemeCfg() |
---|
1051 | n/a | ### keys page |
---|
1052 | n/a | self.LoadKeyCfg() |
---|
1053 | n/a | ### general page |
---|
1054 | n/a | self.LoadGeneralCfg() |
---|
1055 | n/a | |
---|
1056 | n/a | def SaveNewKeySet(self,keySetName,keySet): |
---|
1057 | n/a | """ |
---|
1058 | n/a | save a newly created core key set. |
---|
1059 | n/a | keySetName - string, the name of the new key set |
---|
1060 | n/a | keySet - dictionary containing the new key set |
---|
1061 | n/a | """ |
---|
1062 | n/a | if not idleConf.userCfg['keys'].has_section(keySetName): |
---|
1063 | n/a | idleConf.userCfg['keys'].add_section(keySetName) |
---|
1064 | n/a | for event in keySet: |
---|
1065 | n/a | value=keySet[event] |
---|
1066 | n/a | idleConf.userCfg['keys'].SetOption(keySetName,event,value) |
---|
1067 | n/a | |
---|
1068 | n/a | def SaveNewTheme(self,themeName,theme): |
---|
1069 | n/a | """ |
---|
1070 | n/a | save a newly created theme. |
---|
1071 | n/a | themeName - string, the name of the new theme |
---|
1072 | n/a | theme - dictionary containing the new theme |
---|
1073 | n/a | """ |
---|
1074 | n/a | if not idleConf.userCfg['highlight'].has_section(themeName): |
---|
1075 | n/a | idleConf.userCfg['highlight'].add_section(themeName) |
---|
1076 | n/a | for element in theme: |
---|
1077 | n/a | value=theme[element] |
---|
1078 | n/a | idleConf.userCfg['highlight'].SetOption(themeName,element,value) |
---|
1079 | n/a | |
---|
1080 | n/a | def SetUserValue(self,configType,section,item,value): |
---|
1081 | n/a | if idleConf.defaultCfg[configType].has_option(section,item): |
---|
1082 | n/a | if idleConf.defaultCfg[configType].Get(section,item)==value: |
---|
1083 | n/a | #the setting equals a default setting, remove it from user cfg |
---|
1084 | n/a | return idleConf.userCfg[configType].RemoveOption(section,item) |
---|
1085 | n/a | #if we got here set the option |
---|
1086 | n/a | return idleConf.userCfg[configType].SetOption(section,item,value) |
---|
1087 | n/a | |
---|
1088 | n/a | def SaveAllChangedConfigs(self): |
---|
1089 | n/a | "Save configuration changes to the user config file." |
---|
1090 | n/a | idleConf.userCfg['main'].Save() |
---|
1091 | n/a | for configType in self.changedItems: |
---|
1092 | n/a | cfgTypeHasChanges = False |
---|
1093 | n/a | for section in self.changedItems[configType]: |
---|
1094 | n/a | if section == 'HelpFiles': |
---|
1095 | n/a | #this section gets completely replaced |
---|
1096 | n/a | idleConf.userCfg['main'].remove_section('HelpFiles') |
---|
1097 | n/a | cfgTypeHasChanges = True |
---|
1098 | n/a | for item in self.changedItems[configType][section]: |
---|
1099 | n/a | value = self.changedItems[configType][section][item] |
---|
1100 | n/a | if self.SetUserValue(configType,section,item,value): |
---|
1101 | n/a | cfgTypeHasChanges = True |
---|
1102 | n/a | if cfgTypeHasChanges: |
---|
1103 | n/a | idleConf.userCfg[configType].Save() |
---|
1104 | n/a | for configType in ['keys', 'highlight']: |
---|
1105 | n/a | # save these even if unchanged! |
---|
1106 | n/a | idleConf.userCfg[configType].Save() |
---|
1107 | n/a | self.ResetChangedItems() #clear the changed items dict |
---|
1108 | n/a | |
---|
1109 | n/a | def DeactivateCurrentConfig(self): |
---|
1110 | n/a | #Before a config is saved, some cleanup of current |
---|
1111 | n/a | #config must be done - remove the previous keybindings |
---|
1112 | n/a | winInstances = self.parent.instance_dict.keys() |
---|
1113 | n/a | for instance in winInstances: |
---|
1114 | n/a | instance.RemoveKeybindings() |
---|
1115 | n/a | |
---|
1116 | n/a | def ActivateConfigChanges(self): |
---|
1117 | n/a | "Dynamically apply configuration changes" |
---|
1118 | n/a | winInstances = self.parent.instance_dict.keys() |
---|
1119 | n/a | for instance in winInstances: |
---|
1120 | n/a | instance.ResetColorizer() |
---|
1121 | n/a | instance.ResetFont() |
---|
1122 | n/a | instance.set_notabs_indentwidth() |
---|
1123 | n/a | instance.ApplyKeybindings() |
---|
1124 | n/a | instance.reset_help_menu_entries() |
---|
1125 | n/a | |
---|
1126 | n/a | def Cancel(self): |
---|
1127 | n/a | self.destroy() |
---|
1128 | n/a | |
---|
1129 | n/a | def Ok(self): |
---|
1130 | n/a | self.Apply() |
---|
1131 | n/a | self.destroy() |
---|
1132 | n/a | |
---|
1133 | n/a | def Apply(self): |
---|
1134 | n/a | self.DeactivateCurrentConfig() |
---|
1135 | n/a | self.SaveAllChangedConfigs() |
---|
1136 | n/a | self.ActivateConfigChanges() |
---|
1137 | n/a | |
---|
1138 | n/a | def Help(self): |
---|
1139 | n/a | pass |
---|
1140 | n/a | |
---|
1141 | n/a | if __name__ == '__main__': |
---|
1142 | n/a | #test the dialog |
---|
1143 | n/a | root=Tk() |
---|
1144 | n/a | Button(root,text='Dialog', |
---|
1145 | n/a | command=lambda:ConfigDialog(root,'Settings')).pack() |
---|
1146 | n/a | root.instance_dict={} |
---|
1147 | n/a | root.mainloop() |
---|