]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/py/frame.py
fixed wxVsnprintf() to write as much as it can if the output buffer is too short
[wxWidgets.git] / wxPython / wx / py / frame.py
1 """Base frame with menu."""
2
3 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
4 __cvsid__ = "$Id$"
5 __revision__ = "$Revision$"[11:-2]
6
7 import wx
8 import os
9 from version import VERSION
10 import editwindow
11 import dispatcher
12
13 ID_NEW = wx.ID_NEW
14 ID_OPEN = wx.ID_OPEN
15 ID_REVERT = wx.ID_REVERT
16 ID_CLOSE = wx.ID_CLOSE
17 ID_SAVE = wx.ID_SAVE
18 ID_SAVEAS = wx.ID_SAVEAS
19 ID_PRINT = wx.ID_PRINT
20 ID_EXIT = wx.ID_EXIT
21 ID_UNDO = wx.ID_UNDO
22 ID_REDO = wx.ID_REDO
23 ID_CUT = wx.ID_CUT
24 ID_COPY = wx.ID_COPY
25 ID_PASTE = wx.ID_PASTE
26 ID_CLEAR = wx.ID_CLEAR
27 ID_SELECTALL = wx.ID_SELECTALL
28 ID_EMPTYBUFFER = wx.NewId()
29 ID_ABOUT = wx.ID_ABOUT
30 ID_HELP = wx.NewId()
31 ID_AUTOCOMP = wx.NewId()
32 ID_AUTOCOMP_SHOW = wx.NewId()
33 ID_AUTOCOMP_MAGIC = wx.NewId()
34 ID_AUTOCOMP_SINGLE = wx.NewId()
35 ID_AUTOCOMP_DOUBLE = wx.NewId()
36 ID_CALLTIPS = wx.NewId()
37 ID_CALLTIPS_SHOW = wx.NewId()
38 ID_CALLTIPS_INSERT = wx.NewId()
39 ID_COPY_PLUS = wx.NewId()
40 ID_NAMESPACE = wx.NewId()
41 ID_PASTE_PLUS = wx.NewId()
42 ID_WRAP = wx.NewId()
43 ID_TOGGLE_MAXIMIZE = wx.NewId()
44 ID_USEAA = wx.NewId()
45 ID_SHOW_LINENUMBERS = wx.NewId()
46 ID_AUTO_SAVESETTINGS = wx.NewId()
47 ID_SAVEHISTORY = wx.NewId()
48 ID_SAVEHISTORYNOW = wx.NewId()
49 ID_CLEARHISTORY = wx.NewId()
50 ID_SAVESETTINGS = wx.NewId()
51 ID_DELSETTINGSFILE = wx.NewId()
52 ID_EDITSTARTUPSCRIPT = wx.NewId()
53 ID_EXECSTARTUPSCRIPT = wx.NewId()
54 ID_STARTUP = wx.NewId()
55 ID_SETTINGS = wx.NewId()
56 ID_FIND = wx.ID_FIND
57 ID_FINDNEXT = wx.NewId()
58 ID_SHOWTOOLS = wx.NewId()
59
60
61
62 class Frame(wx.Frame):
63 """Frame with standard menu items."""
64
65 revision = __revision__
66
67 def __init__(self, parent=None, id=-1, title='Editor',
68 pos=wx.DefaultPosition, size=wx.DefaultSize,
69 style=wx.DEFAULT_FRAME_STYLE):
70 """Create a Frame instance."""
71 wx.Frame.__init__(self, parent, id, title, pos, size, style)
72 self.CreateStatusBar()
73 self.SetStatusText('Frame')
74 import images
75 self.SetIcon(images.getPyIcon())
76 self.__createMenus()
77
78 self.iconized = False
79 self.findDlg = None
80 self.findData = wx.FindReplaceData()
81 self.findData.SetFlags(wx.FR_DOWN)
82
83 self.Bind(wx.EVT_CLOSE, self.OnClose)
84 self.Bind(wx.EVT_ICONIZE, self.OnIconize)
85
86
87 def OnIconize(self, event):
88 """Event handler for Iconize."""
89 self.iconized = event.Iconized()
90
91
92 def OnClose(self, event):
93 """Event handler for closing."""
94 self.Destroy()
95
96
97 def __createMenus(self):
98 # File Menu
99 m = self.fileMenu = wx.Menu()
100 m.Append(ID_NEW, '&New \tCtrl+N',
101 'New file')
102 m.Append(ID_OPEN, '&Open... \tCtrl+O',
103 'Open file')
104 m.AppendSeparator()
105 m.Append(ID_REVERT, '&Revert \tCtrl+R',
106 'Revert to last saved version')
107 m.Append(ID_CLOSE, '&Close \tCtrl+W',
108 'Close file')
109 m.AppendSeparator()
110 m.Append(ID_SAVE, '&Save... \tCtrl+S',
111 'Save file')
112 m.Append(ID_SAVEAS, 'Save &As \tCtrl+Shift+S',
113 'Save file with new name')
114 m.AppendSeparator()
115 m.Append(ID_PRINT, '&Print... \tCtrl+P',
116 'Print file')
117 m.AppendSeparator()
118 m.Append(ID_NAMESPACE, '&Update Namespace \tCtrl+Shift+N',
119 'Update namespace for autocompletion and calltips')
120 m.AppendSeparator()
121 m.Append(ID_EXIT, 'E&xit\tCtrl+Q', 'Exit Program')
122
123 # Edit
124 m = self.editMenu = wx.Menu()
125 m.Append(ID_UNDO, '&Undo \tCtrl+Z',
126 'Undo the last action')
127 m.Append(ID_REDO, '&Redo \tCtrl+Y',
128 'Redo the last undone action')
129 m.AppendSeparator()
130 m.Append(ID_CUT, 'Cu&t \tCtrl+X',
131 'Cut the selection')
132 m.Append(ID_COPY, '&Copy \tCtrl+C',
133 'Copy the selection')
134 m.Append(ID_COPY_PLUS, 'Cop&y Plus \tCtrl+Shift+C',
135 'Copy the selection - retaining prompts')
136 m.Append(ID_PASTE, '&Paste \tCtrl+V', 'Paste from clipboard')
137 m.Append(ID_PASTE_PLUS, 'Past&e Plus \tCtrl+Shift+V',
138 'Paste and run commands')
139 m.AppendSeparator()
140 m.Append(ID_CLEAR, 'Cle&ar',
141 'Delete the selection')
142 m.Append(ID_SELECTALL, 'Select A&ll \tCtrl+A',
143 'Select all text')
144 m.AppendSeparator()
145 m.Append(ID_EMPTYBUFFER, 'E&mpty Buffer...',
146 'Delete all the contents of the edit buffer')
147 m.Append(ID_FIND, '&Find Text... \tCtrl+F',
148 'Search for text in the edit buffer')
149 m.Append(ID_FINDNEXT, 'Find &Next \tF3',
150 'Find next/previous instance of the search text')
151
152 # View
153 m = self.viewMenu = wx.Menu()
154 m.Append(ID_WRAP, '&Wrap Lines\tCtrl+Shift+W',
155 'Wrap lines at right edge', wx.ITEM_CHECK)
156 m.Append(ID_SHOW_LINENUMBERS, '&Show Line Numbers\tCtrl+Shift+L', 'Show Line Numbers', wx.ITEM_CHECK)
157 m.Append(ID_TOGGLE_MAXIMIZE, '&Toggle Maximize\tF11', 'Maximize/Restore Application')
158 if hasattr(self, 'ToggleTools'):
159 m.Append(ID_SHOWTOOLS,
160 'Show &Tools\tF4',
161 'Show the filling and other tools', wx.ITEM_CHECK)
162
163 # Options
164 m = self.autocompMenu = wx.Menu()
165 m.Append(ID_AUTOCOMP_SHOW, 'Show &Auto Completion\tCtrl+Shift+A',
166 'Show auto completion list', wx.ITEM_CHECK)
167 m.Append(ID_AUTOCOMP_MAGIC, 'Include &Magic Attributes\tCtrl+Shift+M',
168 'Include attributes visible to __getattr__ and __setattr__',
169 wx.ITEM_CHECK)
170 m.Append(ID_AUTOCOMP_SINGLE, 'Include Single &Underscores\tCtrl+Shift+U',
171 'Include attibutes prefixed by a single underscore', wx.ITEM_CHECK)
172 m.Append(ID_AUTOCOMP_DOUBLE, 'Include &Double Underscores\tCtrl+Shift+D',
173 'Include attibutes prefixed by a double underscore', wx.ITEM_CHECK)
174 m = self.calltipsMenu = wx.Menu()
175 m.Append(ID_CALLTIPS_SHOW, 'Show Call &Tips\tCtrl+Shift+T',
176 'Show call tips with argument signature and docstring', wx.ITEM_CHECK)
177 m.Append(ID_CALLTIPS_INSERT, '&Insert Call Tips\tCtrl+Shift+I',
178 '&Insert Call Tips', wx.ITEM_CHECK)
179
180 m = self.optionsMenu = wx.Menu()
181 m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu,
182 'Auto Completion Options')
183 m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu,
184 'Call Tip Options')
185
186 if wx.Platform == "__WXMAC__":
187 m.Append(ID_USEAA, '&Use AntiAliasing',
188 'Use anti-aliased fonts', wx.ITEM_CHECK)
189
190 m.AppendSeparator()
191
192 self.historyMenu = wx.Menu()
193 self.historyMenu.Append(ID_SAVEHISTORY, '&Autosave History',
194 'Automatically save history on close', wx.ITEM_CHECK)
195 self.historyMenu.Append(ID_SAVEHISTORYNOW, '&Save History Now',
196 'Save history')
197 self.historyMenu.Append(ID_CLEARHISTORY, '&Clear History ',
198 'Clear history')
199 m.AppendMenu(-1, "&History", self.historyMenu, "History Options")
200
201 self.startupMenu = wx.Menu()
202 self.startupMenu.Append(ID_EXECSTARTUPSCRIPT,
203 'E&xecute Startup Script',
204 'Execute Startup Script', wx.ITEM_CHECK)
205 self.startupMenu.Append(ID_EDITSTARTUPSCRIPT,
206 '&Edit Startup Script...',
207 'Edit Startup Script')
208 m.AppendMenu(ID_STARTUP, '&Startup', self.startupMenu, 'Startup Options')
209
210 self.settingsMenu = wx.Menu()
211 self.settingsMenu.Append(ID_AUTO_SAVESETTINGS,
212 '&Auto Save Settings',
213 'Automatically save settings on close', wx.ITEM_CHECK)
214 self.settingsMenu.Append(ID_SAVESETTINGS,
215 '&Save Settings',
216 'Save settings now')
217 self.settingsMenu.Append(ID_DELSETTINGSFILE,
218 '&Revert to default',
219 'Revert to the default settings')
220 m.AppendMenu(ID_SETTINGS, '&Settings', self.settingsMenu, 'Settings Options')
221
222 m = self.helpMenu = wx.Menu()
223 m.Append(ID_HELP, '&Help\tF1', 'Help!')
224 m.AppendSeparator()
225 m.Append(ID_ABOUT, '&About...', 'About this program')
226
227 b = self.menuBar = wx.MenuBar()
228 b.Append(self.fileMenu, '&File')
229 b.Append(self.editMenu, '&Edit')
230 b.Append(self.viewMenu, '&View')
231 b.Append(self.optionsMenu, '&Options')
232 b.Append(self.helpMenu, '&Help')
233 self.SetMenuBar(b)
234
235 self.Bind(wx.EVT_MENU, self.OnFileNew, id=ID_NEW)
236 self.Bind(wx.EVT_MENU, self.OnFileOpen, id=ID_OPEN)
237 self.Bind(wx.EVT_MENU, self.OnFileRevert, id=ID_REVERT)
238 self.Bind(wx.EVT_MENU, self.OnFileClose, id=ID_CLOSE)
239 self.Bind(wx.EVT_MENU, self.OnFileSave, id=ID_SAVE)
240 self.Bind(wx.EVT_MENU, self.OnFileSaveAs, id=ID_SAVEAS)
241 self.Bind(wx.EVT_MENU, self.OnFileUpdateNamespace, id=ID_NAMESPACE)
242 self.Bind(wx.EVT_MENU, self.OnFilePrint, id=ID_PRINT)
243 self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT)
244 self.Bind(wx.EVT_MENU, self.OnUndo, id=ID_UNDO)
245 self.Bind(wx.EVT_MENU, self.OnRedo, id=ID_REDO)
246 self.Bind(wx.EVT_MENU, self.OnCut, id=ID_CUT)
247 self.Bind(wx.EVT_MENU, self.OnCopy, id=ID_COPY)
248 self.Bind(wx.EVT_MENU, self.OnCopyPlus, id=ID_COPY_PLUS)
249 self.Bind(wx.EVT_MENU, self.OnPaste, id=ID_PASTE)
250 self.Bind(wx.EVT_MENU, self.OnPastePlus, id=ID_PASTE_PLUS)
251 self.Bind(wx.EVT_MENU, self.OnClear, id=ID_CLEAR)
252 self.Bind(wx.EVT_MENU, self.OnSelectAll, id=ID_SELECTALL)
253 self.Bind(wx.EVT_MENU, self.OnEmptyBuffer, id=ID_EMPTYBUFFER)
254 self.Bind(wx.EVT_MENU, self.OnAbout, id=ID_ABOUT)
255 self.Bind(wx.EVT_MENU, self.OnHelp, id=ID_HELP)
256 self.Bind(wx.EVT_MENU, self.OnAutoCompleteShow, id=ID_AUTOCOMP_SHOW)
257 self.Bind(wx.EVT_MENU, self.OnAutoCompleteMagic, id=ID_AUTOCOMP_MAGIC)
258 self.Bind(wx.EVT_MENU, self.OnAutoCompleteSingle, id=ID_AUTOCOMP_SINGLE)
259 self.Bind(wx.EVT_MENU, self.OnAutoCompleteDouble, id=ID_AUTOCOMP_DOUBLE)
260 self.Bind(wx.EVT_MENU, self.OnCallTipsShow, id=ID_CALLTIPS_SHOW)
261 self.Bind(wx.EVT_MENU, self.OnCallTipsInsert, id=ID_CALLTIPS_INSERT)
262 self.Bind(wx.EVT_MENU, self.OnWrap, id=ID_WRAP)
263 self.Bind(wx.EVT_MENU, self.OnUseAA, id=ID_USEAA)
264 self.Bind(wx.EVT_MENU, self.OnToggleMaximize, id=ID_TOGGLE_MAXIMIZE)
265 self.Bind(wx.EVT_MENU, self.OnShowLineNumbers, id=ID_SHOW_LINENUMBERS)
266 self.Bind(wx.EVT_MENU, self.OnAutoSaveSettings, id=ID_AUTO_SAVESETTINGS)
267 self.Bind(wx.EVT_MENU, self.OnSaveHistory, id=ID_SAVEHISTORY)
268 self.Bind(wx.EVT_MENU, self.OnSaveHistoryNow, id=ID_SAVEHISTORYNOW)
269 self.Bind(wx.EVT_MENU, self.OnClearHistory, id=ID_CLEARHISTORY)
270 self.Bind(wx.EVT_MENU, self.OnSaveSettings, id=ID_SAVESETTINGS)
271 self.Bind(wx.EVT_MENU, self.OnDelSettingsFile, id=ID_DELSETTINGSFILE)
272 self.Bind(wx.EVT_MENU, self.OnEditStartupScript, id=ID_EDITSTARTUPSCRIPT)
273 self.Bind(wx.EVT_MENU, self.OnExecStartupScript, id=ID_EXECSTARTUPSCRIPT)
274 self.Bind(wx.EVT_MENU, self.OnFindText, id=ID_FIND)
275 self.Bind(wx.EVT_MENU, self.OnFindNext, id=ID_FINDNEXT)
276 self.Bind(wx.EVT_MENU, self.OnToggleTools, id=ID_SHOWTOOLS)
277
278 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_NEW)
279 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_OPEN)
280 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_REVERT)
281 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLOSE)
282 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVE)
283 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEAS)
284 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_NAMESPACE)
285 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PRINT)
286 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_UNDO)
287 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_REDO)
288 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CUT)
289 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_COPY)
290 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_COPY_PLUS)
291 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PASTE)
292 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PASTE_PLUS)
293 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLEAR)
294 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SELECTALL)
295 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EMPTYBUFFER)
296 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_SHOW)
297 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_MAGIC)
298 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_SINGLE)
299 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_DOUBLE)
300 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CALLTIPS_SHOW)
301 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CALLTIPS_INSERT)
302 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_WRAP)
303 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_USEAA)
304 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SHOW_LINENUMBERS)
305 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTO_SAVESETTINGS)
306 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVESETTINGS)
307 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_DELSETTINGSFILE)
308 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EXECSTARTUPSCRIPT)
309 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEHISTORY)
310 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEHISTORYNOW)
311 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLEARHISTORY)
312 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EDITSTARTUPSCRIPT)
313 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_FIND)
314 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_FINDNEXT)
315 self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SHOWTOOLS)
316
317 self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
318 self.Bind(wx.EVT_FIND, self.OnFindNext)
319 self.Bind(wx.EVT_FIND_NEXT, self.OnFindNext)
320 self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
321
322
323
324 def OnShowLineNumbers(self, event):
325 win = wx.Window.FindFocus()
326 if hasattr(win, 'lineNumbers'):
327 win.lineNumbers = event.IsChecked()
328 win.setDisplayLineNumbers(win.lineNumbers)
329
330 def OnToggleMaximize(self, event):
331 self.Maximize(not self.IsMaximized())
332
333 def OnFileNew(self, event):
334 self.bufferNew()
335
336 def OnFileOpen(self, event):
337 self.bufferOpen()
338
339 def OnFileRevert(self, event):
340 self.bufferRevert()
341
342 def OnFileClose(self, event):
343 self.bufferClose()
344
345 def OnFileSave(self, event):
346 self.bufferSave()
347
348 def OnFileSaveAs(self, event):
349 self.bufferSaveAs()
350
351 def OnFileUpdateNamespace(self, event):
352 self.updateNamespace()
353
354 def OnFilePrint(self, event):
355 self.bufferPrint()
356
357 def OnExit(self, event):
358 self.Close(False)
359
360 def OnUndo(self, event):
361 win = wx.Window.FindFocus()
362 win.Undo()
363
364 def OnRedo(self, event):
365 win = wx.Window.FindFocus()
366 win.Redo()
367
368 def OnCut(self, event):
369 win = wx.Window.FindFocus()
370 win.Cut()
371
372 def OnCopy(self, event):
373 win = wx.Window.FindFocus()
374 win.Copy()
375
376 def OnCopyPlus(self, event):
377 win = wx.Window.FindFocus()
378 win.CopyWithPrompts()
379
380 def OnPaste(self, event):
381 win = wx.Window.FindFocus()
382 win.Paste()
383
384 def OnPastePlus(self, event):
385 win = wx.Window.FindFocus()
386 win.PasteAndRun()
387
388 def OnClear(self, event):
389 win = wx.Window.FindFocus()
390 win.Clear()
391
392 def OnEmptyBuffer(self, event):
393 win = wx.Window.FindFocus()
394 d = wx.MessageDialog(self,
395 "Are you sure you want to clear the edit buffer,\n"
396 "deleting all the text?",
397 "Empty Buffer", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
398 answer = d.ShowModal()
399 d.Destroy()
400 if (answer == wx.ID_OK):
401 win.ClearAll()
402 if hasattr(win,'prompt'):
403 win.prompt()
404
405 def OnSelectAll(self, event):
406 win = wx.Window.FindFocus()
407 win.SelectAll()
408
409 def OnAbout(self, event):
410 """Display an About window."""
411 title = 'About'
412 text = 'Your message here.'
413 dialog = wx.MessageDialog(self, text, title,
414 wx.OK | wx.ICON_INFORMATION)
415 dialog.ShowModal()
416 dialog.Destroy()
417
418 def OnHelp(self, event):
419 """Display a Help window."""
420 title = 'Help'
421 text = "Type 'shell.help()' in the shell window."
422 dialog = wx.MessageDialog(self, text, title,
423 wx.OK | wx.ICON_INFORMATION)
424 dialog.ShowModal()
425 dialog.Destroy()
426
427 def OnAutoCompleteShow(self, event):
428 win = wx.Window.FindFocus()
429 win.autoComplete = event.IsChecked()
430
431 def OnAutoCompleteMagic(self, event):
432 win = wx.Window.FindFocus()
433 win.autoCompleteIncludeMagic = event.IsChecked()
434
435 def OnAutoCompleteSingle(self, event):
436 win = wx.Window.FindFocus()
437 win.autoCompleteIncludeSingle = event.IsChecked()
438
439 def OnAutoCompleteDouble(self, event):
440 win = wx.Window.FindFocus()
441 win.autoCompleteIncludeDouble = event.IsChecked()
442
443 def OnCallTipsShow(self, event):
444 win = wx.Window.FindFocus()
445 win.autoCallTip = event.IsChecked()
446
447 def OnCallTipsInsert(self, event):
448 win = wx.Window.FindFocus()
449 win.callTipInsert = event.IsChecked()
450
451 def OnWrap(self, event):
452 win = wx.Window.FindFocus()
453 win.SetWrapMode(event.IsChecked())
454 wx.FutureCall(1, self.shell.EnsureCaretVisible)
455
456 def OnUseAA(self, event):
457 win = wx.Window.FindFocus()
458 win.SetUseAntiAliasing(event.IsChecked())
459
460 def OnSaveHistory(self, event):
461 self.autoSaveHistory = event.IsChecked()
462
463 def OnSaveHistoryNow(self, event):
464 self.SaveHistory()
465
466 def OnClearHistory(self, event):
467 self.shell.clearHistory()
468
469 def OnAutoSaveSettings(self, event):
470 self.autoSaveSettings = event.IsChecked()
471
472 def OnSaveSettings(self, event):
473 self.DoSaveSettings()
474
475 def OnDelSettingsFile(self, event):
476 if self.config is not None:
477 d = wx.MessageDialog(
478 self, "Do you want to revert to the default settings?\n" +
479 "A restart is needed for the change to take effect",
480 "Warning", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
481 answer = d.ShowModal()
482 d.Destroy()
483 if (answer == wx.ID_OK):
484 self.config.DeleteAll()
485 self.LoadSettings()
486
487
488 def OnEditStartupScript(self, event):
489 if hasattr(self, 'EditStartupScript'):
490 self.EditStartupScript()
491
492 def OnExecStartupScript(self, event):
493 self.execStartupScript = event.IsChecked()
494
495
496 def OnFindText(self, event):
497 if self.findDlg is not None:
498 return
499 win = wx.Window.FindFocus()
500 self.findDlg = wx.FindReplaceDialog(win, self.findData, "Find",
501 wx.FR_NOWHOLEWORD)
502 self.findDlg.Show()
503
504 def OnFindNext(self, event):
505 if not self.findData.GetFindString():
506 self.OnFindText(event)
507 return
508 if isinstance(event, wx.FindDialogEvent):
509 win = self.findDlg.GetParent()
510 else:
511 win = wx.Window.FindFocus()
512 win.DoFindNext(self.findData, self.findDlg)
513 if self.findDlg is not None:
514 self.OnFindClose(None)
515
516 def OnFindClose(self, event):
517 self.findDlg.Destroy()
518 self.findDlg = None
519
520 def OnToggleTools(self, event):
521 self.ToggleTools()
522
523
524 def OnUpdateMenu(self, event):
525 """Update menu items based on current status and context."""
526 win = wx.Window.FindFocus()
527 id = event.GetId()
528 event.Enable(True)
529 try:
530 if id == ID_NEW:
531 event.Enable(hasattr(self, 'bufferNew'))
532 elif id == ID_OPEN:
533 event.Enable(hasattr(self, 'bufferOpen'))
534 elif id == ID_REVERT:
535 event.Enable(hasattr(self, 'bufferRevert')
536 and self.hasBuffer())
537 elif id == ID_CLOSE:
538 event.Enable(hasattr(self, 'bufferClose')
539 and self.hasBuffer())
540 elif id == ID_SAVE:
541 event.Enable(hasattr(self, 'bufferSave')
542 and self.bufferHasChanged())
543 elif id == ID_SAVEAS:
544 event.Enable(hasattr(self, 'bufferSaveAs')
545 and self.hasBuffer())
546 elif id == ID_NAMESPACE:
547 event.Enable(hasattr(self, 'updateNamespace')
548 and self.hasBuffer())
549 elif id == ID_PRINT:
550 event.Enable(hasattr(self, 'bufferPrint')
551 and self.hasBuffer())
552 elif id == ID_UNDO:
553 event.Enable(win.CanUndo())
554 elif id == ID_REDO:
555 event.Enable(win.CanRedo())
556 elif id == ID_CUT:
557 event.Enable(win.CanCut())
558 elif id == ID_COPY:
559 event.Enable(win.CanCopy())
560 elif id == ID_COPY_PLUS:
561 event.Enable(win.CanCopy() and hasattr(win, 'CopyWithPrompts'))
562 elif id == ID_PASTE:
563 event.Enable(win.CanPaste())
564 elif id == ID_PASTE_PLUS:
565 event.Enable(win.CanPaste() and hasattr(win, 'PasteAndRun'))
566 elif id == ID_CLEAR:
567 event.Enable(win.CanCut())
568 elif id == ID_SELECTALL:
569 event.Enable(hasattr(win, 'SelectAll'))
570 elif id == ID_EMPTYBUFFER:
571 event.Enable(hasattr(win, 'ClearAll') and not win.GetReadOnly())
572 elif id == ID_AUTOCOMP_SHOW:
573 event.Check(win.autoComplete)
574 elif id == ID_AUTOCOMP_MAGIC:
575 event.Check(win.autoCompleteIncludeMagic)
576 elif id == ID_AUTOCOMP_SINGLE:
577 event.Check(win.autoCompleteIncludeSingle)
578 elif id == ID_AUTOCOMP_DOUBLE:
579 event.Check(win.autoCompleteIncludeDouble)
580 elif id == ID_CALLTIPS_SHOW:
581 event.Check(win.autoCallTip)
582 elif id == ID_CALLTIPS_INSERT:
583 event.Check(win.callTipInsert)
584 elif id == ID_WRAP:
585 event.Check(win.GetWrapMode())
586 elif id == ID_USEAA:
587 event.Check(win.GetUseAntiAliasing())
588
589 elif id == ID_SHOW_LINENUMBERS:
590 event.Check(win.lineNumbers)
591 elif id == ID_AUTO_SAVESETTINGS:
592 event.Check(self.autoSaveSettings)
593 event.Enable(self.config is not None)
594 elif id == ID_SAVESETTINGS:
595 event.Enable(self.config is not None and
596 hasattr(self, 'DoSaveSettings'))
597 elif id == ID_DELSETTINGSFILE:
598 event.Enable(self.config is not None)
599
600 elif id == ID_EXECSTARTUPSCRIPT:
601 event.Check(self.execStartupScript)
602 event.Enable(self.config is not None)
603
604 elif id == ID_SAVEHISTORY:
605 event.Check(self.autoSaveHistory)
606 event.Enable(self.dataDir is not None)
607 elif id == ID_SAVEHISTORYNOW:
608 event.Enable(self.dataDir is not None and
609 hasattr(self, 'SaveHistory'))
610 elif id == ID_CLEARHISTORY:
611 event.Enable(self.dataDir is not None)
612
613 elif id == ID_EDITSTARTUPSCRIPT:
614 event.Enable(hasattr(self, 'EditStartupScript'))
615 event.Enable(self.dataDir is not None)
616
617 elif id == ID_FIND:
618 event.Enable(hasattr(win, 'DoFindNext'))
619 elif id == ID_FINDNEXT:
620 event.Enable(hasattr(win, 'DoFindNext'))
621
622 elif id == ID_SHOWTOOLS:
623 event.Check(self.ToolsShown())
624
625 else:
626 event.Enable(False)
627 except AttributeError:
628 # This menu option is not supported in the current context.
629 event.Enable(False)
630
631
632 def OnActivate(self, event):
633 """
634 Event Handler for losing the focus of the Frame. Should close
635 Autocomplete listbox, if shown.
636 """
637 if not event.GetActive():
638 # If autocomplete active, cancel it. Otherwise, the
639 # autocomplete list will stay visible on top of the
640 # z-order after switching to another application
641 win = wx.Window.FindFocus()
642 if hasattr(win, 'AutoCompActive') and win.AutoCompActive():
643 win.AutoCompCancel()
644 event.Skip()
645
646
647
648 def LoadSettings(self, config):
649 """Called by derived classes to load settings specific to the Frame"""
650 pos = wx.Point(config.ReadInt('Window/PosX', -1),
651 config.ReadInt('Window/PosY', -1))
652
653 size = wx.Size(config.ReadInt('Window/Width', -1),
654 config.ReadInt('Window/Height', -1))
655
656 self.SetSize(size)
657 self.Move(pos)
658
659
660 def SaveSettings(self, config):
661 """Called by derived classes to save Frame settings to a wx.Config object"""
662
663 # TODO: track position/size so we can save it even if the
664 # frame is maximized or iconized.
665 if not self.iconized and not self.IsMaximized():
666 w, h = self.GetSize()
667 config.WriteInt('Window/Width', w)
668 config.WriteInt('Window/Height', h)
669
670 px, py = self.GetPosition()
671 config.WriteInt('Window/PosX', px)
672 config.WriteInt('Window/PosY', py)
673
674
675
676
677 class ShellFrameMixin:
678 """
679 A mix-in class for frames that will have a Shell or a Crust window
680 and that want to add history, startupScript and other common
681 functionality.
682 """
683 def __init__(self, config, dataDir):
684 self.config = config
685 self.dataDir = dataDir
686 self.startupScript = os.environ.get('PYTHONSTARTUP')
687 if not self.startupScript and self.dataDir:
688 self.startupScript = os.path.join(self.dataDir, 'startup')
689
690 self.autoSaveSettings = False
691 self.autoSaveHistory = False
692
693 # We need this one before we have a chance to load the settings...
694 self.execStartupScript = True
695 if self.config:
696 self.execStartupScript = self.config.ReadBool('Options/ExecStartupScript', True)
697
698
699 def OnHelp(self, event):
700 """Display a Help window."""
701 import wx.lib.dialogs
702 title = 'Help on key bindings'
703
704 text = wx.py.shell.HELP_TEXT
705
706 dlg = wx.lib.dialogs.ScrolledMessageDialog(self, text, title, size = ((700, 540)))
707 fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
708 dlg.GetChildren()[0].SetFont(fnt)
709 dlg.GetChildren()[0].SetInsertionPoint(0)
710 dlg.ShowModal()
711 dlg.Destroy()
712
713
714 def LoadSettings(self):
715 if self.config is not None:
716 self.autoSaveSettings = self.config.ReadBool('Options/AutoSaveSettings', False)
717 self.execStartupScript = self.config.ReadBool('Options/ExecStartupScript', True)
718 self.autoSaveHistory = self.config.ReadBool('Options/AutoSaveHistory', False)
719 self.LoadHistory()
720
721
722 def SaveSettings(self):
723 if self.config is not None:
724 # always save this one
725 self.config.WriteBool('Options/AutoSaveSettings', self.autoSaveSettings)
726 if self.autoSaveSettings:
727 self.config.WriteBool('Options/AutoSaveHistory', self.autoSaveHistory)
728 self.config.WriteBool('Options/ExecStartupScript', self.execStartupScript)
729 if self.autoSaveHistory:
730 self.SaveHistory()
731
732
733
734 def SaveHistory(self):
735 if self.dataDir:
736 try:
737 name = os.path.join(self.dataDir, 'history')
738 f = file(name, 'w')
739 hist = '\x00\n'.join(self.shell.history)
740 f.write(hist)
741 f.close()
742 except:
743 d = wx.MessageDialog(self, "Error saving history file.",
744 "Error", wx.ICON_EXCLAMATION)
745 d.ShowModal()
746 d.Destroy()
747 raise
748
749 def LoadHistory(self):
750 if self.dataDir:
751 name = os.path.join(self.dataDir, 'history')
752 if os.path.exists(name):
753 try:
754 f = file(name, 'U')
755 hist = f.read()
756 f.close()
757 self.shell.history = hist.split('\x00\n')
758 dispatcher.send(signal="Shell.loadHistory", history=self.shell.history)
759 except:
760 d = wx.MessageDialog(self, "Error loading history file.",
761 "Error", wx.ICON_EXCLAMATION)
762 d.ShowModal()
763 d.Destroy()
764
765
766 def bufferHasChanged(self):
767 # the shell buffers can always be saved
768 return True
769
770 def bufferSave(self):
771 import time
772 appname = wx.GetApp().GetAppName()
773 default = appname + '-' + time.strftime("%Y%m%d-%H%M.py")
774 fileName = wx.FileSelector("Save File As", "Saving",
775 default_filename=default,
776 default_extension="py",
777 wildcard="*.py",
778 flags = wx.SAVE | wx.OVERWRITE_PROMPT)
779 if not fileName:
780 return
781
782 text = self.shell.GetText()
783
784 ## This isn't working currently...
785 ## d = wx.MessageDialog(self,u'Save source code only?\nAnswering yes will only save lines starting with >>> and ...',u'Question', wx.YES_NO | wx.ICON_QUESTION)
786 ## yes_no = d.ShowModal()
787 ## if yes_no == wx.ID_YES:
788 ## m = re.findall('^[>\.]{3,3} (.*)\r', text, re.MULTILINE | re.LOCALE)
789 ## text = '\n'.join(m)
790 ## d.Destroy()
791
792 try:
793 f = open(fileName, "w")
794 f.write(text)
795 f.close()
796 except:
797 d = wx.MessageDialog(self, u'Error saving session',u'Error',
798 wx.OK | wx.ICON_ERROR)
799 d.ShowModal()
800 d.Destroy()
801
802
803 def EditStartupScript(self):
804 if os.path.exists(self.startupScript):
805 text = file(self.startupScript, 'U').read()
806 else:
807 text = ''
808
809 dlg = EditStartupScriptDialog(self, self.startupScript, text)
810 if dlg.ShowModal() == wx.ID_OK:
811 text = dlg.GetText()
812 try:
813 f = file(self.startupScript, 'w')
814 f.write(text)
815 f.close()
816 except:
817 d = wx.MessageDialog(self, "Error saving startup file.",
818 "Error", wx.ICON_EXCLAMATION)
819 d.ShowModal()
820 d.Destroy()
821
822
823
824 class EditStartupScriptDialog(wx.Dialog):
825 def __init__(self, parent, fileName, text):
826 wx.Dialog.__init__(self, parent, size=(425,350),
827 title="Edit Startup Script",
828 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
829
830 pst = wx.StaticText(self, -1, "Path:")
831 ptx = wx.TextCtrl(self, -1, fileName, style=wx.TE_READONLY)
832 self.editor = editwindow.EditWindow(self)
833 self.editor.SetText(text)
834 wx.CallAfter(self.editor.SetFocus)
835
836 ok = wx.Button(self, wx.ID_OK)
837 cancel = wx.Button(self, wx.ID_CANCEL)
838
839 mainSizer = wx.BoxSizer(wx.VERTICAL)
840
841 pthSizer = wx.BoxSizer(wx.HORIZONTAL)
842 pthSizer.Add(pst, flag=wx.ALIGN_CENTER_VERTICAL)
843 pthSizer.Add((5,5))
844 pthSizer.Add(ptx, 1)
845 mainSizer.Add(pthSizer, 0, wx.EXPAND|wx.ALL, 10)
846
847 mainSizer.Add(self.editor, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
848
849 btnSizer = wx.BoxSizer(wx.HORIZONTAL)
850 btnSizer.Add((5,5), 1)
851 btnSizer.Add(ok)
852 btnSizer.Add((5,5), 1)
853 btnSizer.Add(cancel)
854 btnSizer.Add((5,5), 1)
855 mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, 10)
856
857 self.SetSizer(mainSizer)
858 self.Layout()
859
860
861 def GetText(self):
862 return self.editor.GetText()