blob: abeee605abad5a403b15f1ed3c5b81c683e5cfd2 [file] [log] [blame]
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001import FrameWork
Jack Jansen5a6fdcd2001-08-25 12:15:04 +00002from Carbon import Win
3from Carbon import Qd
4from Carbon import Evt
Just van Rossum40f9b7b1999-01-30 22:39:17 +00005import MacOS
Jack Jansendc4d9252001-08-27 10:55:41 +00006from Carbon import Events
Just van Rossum40f9b7b1999-01-30 22:39:17 +00007import traceback
8from types import *
Jack Jansen5a6fdcd2001-08-25 12:15:04 +00009from Carbon import Menu; MenuToolbox = Menu; del Menu
Jack Jansene9c03582002-04-03 21:52:10 +000010import macresource
Jack Jansene7ee17c2003-02-06 22:32:35 +000011from Carbon import File
Just van Rossum40f9b7b1999-01-30 22:39:17 +000012
Just van Rossum40144012002-02-04 12:52:44 +000013if hasattr(Win, "FrontNonFloatingWindow"):
14 MyFrontWindow = Win.FrontNonFloatingWindow
15else:
16 MyFrontWindow = Win.FrontWindow
17
18
Just van Rossumf376ef02001-11-18 14:12:43 +000019KILLUNKNOWNWINDOWS = 0 # Set to 0 for debugging.
Just van Rossum40f9b7b1999-01-30 22:39:17 +000020
21class Application(FrameWork.Application):
22
23 def __init__(self, signature='Pyth'):
Jack Jansene9c03582002-04-03 21:52:10 +000024 # Open our resource file, if it is not open yet
25 macresource.need('CURS', 468, "Widgets.rsrc")
Just van Rossum40f9b7b1999-01-30 22:39:17 +000026 import W
27 W.setapplication(self, signature)
28 FrameWork.Application.__init__(self)
29 self._suspended = 0
30 self.quitting = 0
31 self.debugger_quitting = 1
32 self.DebuggerQuit = 'DebuggerQuitDummyException'
33 self._idlefuncs = []
34 # map certain F key codes to equivalent command-letter combos (JJS)
35 self.fkeymaps = {122:"z", 120:"x", 99:"c", 118:"v"}
36
Jack Jansene5c94742001-03-08 23:10:37 +000037 def mainloop(self, mask=FrameWork.everyEvent, wait=None):
Just van Rossum40f9b7b1999-01-30 22:39:17 +000038 import W
39 self.quitting = 0
Jack Jansen815d2bf2002-01-21 23:00:52 +000040 if hasattr(MacOS, 'EnableAppswitch'):
41 saveyield = MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000042 try:
43 while not self.quitting:
44 try:
45 self.do1event(mask, wait)
46 except W.AlertError, detail:
Jack Jansen815d2bf2002-01-21 23:00:52 +000047 if hasattr(MacOS, 'EnableAppswitch'):
48 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000049 W.Message(detail)
50 except self.DebuggerQuit:
Jack Jansen815d2bf2002-01-21 23:00:52 +000051 if hasattr(MacOS, 'EnableAppswitch'):
52 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000053 except:
Jack Jansen815d2bf2002-01-21 23:00:52 +000054 if hasattr(MacOS, 'EnableAppswitch'):
55 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000056 import PyEdit
57 PyEdit.tracebackwindow.traceback()
58 finally:
Jack Jansen815d2bf2002-01-21 23:00:52 +000059 if hasattr(MacOS, 'EnableAppswitch'):
60 MacOS.EnableAppswitch(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000061
Jack Jansene5c94742001-03-08 23:10:37 +000062 def debugger_mainloop(self, mask=FrameWork.everyEvent, wait=None):
Just van Rossum40f9b7b1999-01-30 22:39:17 +000063 import W
64 self.debugger_quitting = 0
Jack Jansen815d2bf2002-01-21 23:00:52 +000065 if hasattr(MacOS, 'EnableAppswitch'):
66 saveyield = MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000067 try:
68 while not self.quitting and not self.debugger_quitting:
69 try:
70 self.do1event(mask, wait)
71 except W.AlertError, detail:
72 W.Message(detail)
73 except:
74 import PyEdit
75 PyEdit.tracebackwindow.traceback()
76 finally:
Jack Jansen815d2bf2002-01-21 23:00:52 +000077 if hasattr(MacOS, 'EnableAppswitch'):
78 MacOS.EnableAppswitch(saveyield)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000079
80 def breathe(self, wait=1):
81 import W
82 ok, event = Evt.WaitNextEvent(FrameWork.updateMask |
83 FrameWork.mDownMask | FrameWork.osMask |
84 FrameWork.activMask,
85 wait)
86 if ok:
87 (what, message, when, where, modifiers) = event
88 #print FrameWork.eventname[what]
89 if FrameWork.eventname[what] == 'mouseDown':
90 partcode, wid = Win.FindWindow(where)
91 if FrameWork.partname[partcode] <> 'inDesk':
92 return
93 else:
94 W.SetCursor('watch')
95 self.dispatch(event)
96
97 def refreshwindows(self, wait=1):
98 import W
99 while 1:
100 ok, event = Evt.WaitNextEvent(FrameWork.updateMask, wait)
101 if not ok:
102 break
103 self.dispatch(event)
104
105 def addidlefunc(self, func):
106 self._idlefuncs.append(func)
107
108 def removeidlefunc(self, func):
109 self._idlefuncs.remove(func)
110
111 def idle(self, event):
112 if not self._suspended:
113 if not self.do_frontWindowMethod("idle", event):
114 Qd.InitCursor()
115 if self._idlefuncs:
116 for func in self._idlefuncs:
117 try:
118 func()
119 except:
120 import sys
121 sys.stderr.write("exception in idle function %s; killed:\n" % `func`)
122 traceback.print_exc()
123 self._idlefuncs.remove(func)
124 break
125
126 def do_frontWindowMethod(self, attr, *args):
Just van Rossum40144012002-02-04 12:52:44 +0000127 wid = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000128 if wid and self._windows.has_key(wid):
129 window = self._windows[wid]
130 if hasattr(window, attr):
131 handler = getattr(window, attr)
132 apply(handler, args)
133 return 1
134
135 def appendwindow(self, wid, window):
136 self._windows[wid] = window
137 self.makeopenwindowsmenu()
138
139 def removewindow(self, wid):
140 del self._windows[wid]
141 self.makeopenwindowsmenu()
142
Just van Rossumd4bdbf11999-02-26 21:30:19 +0000143 def makeopenwindowsmenu(self):
144 # dummy; could be the full version from PythonIDEMain.py
145 self._openwindows = {}
146 self._openwindowscheckmark = 0
147 if not hasattr(self, "_menustocheck"):
148 self._menustocheck = []
149
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000150 def do_key(self, event):
151 (what, message, when, where, modifiers) = event
152 ch = chr(message & FrameWork.charCodeMask)
153 rest = message & ~FrameWork.charCodeMask
154 keycode = (message & FrameWork.keyCodeMask) >> 8
155 if keycode in self.fkeymaps.keys(): # JJS
156 ch = self.fkeymaps[keycode]
157 modifiers = modifiers | FrameWork.cmdKey
Just van Rossum40144012002-02-04 12:52:44 +0000158 wid = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000159 if modifiers & FrameWork.cmdKey and not modifiers & FrameWork.shiftKey:
160 if wid and self._windows.has_key(wid):
161 self.checkmenus(self._windows[wid])
162 else:
163 self.checkmenus(None)
164 event = (what, ord(ch) | rest, when, where, modifiers)
165 result = MenuToolbox.MenuKey(ord(ch))
166 id = (result>>16) & 0xffff # Hi word
167 item = result & 0xffff # Lo word
168 if id:
169 self.do_rawmenu(id, item, None, event)
170 return # here! we had a menukey!
171 #else:
172 # print "XXX Command-" +`ch`
173 # See whether the front window wants it
174 if wid and self._windows.has_key(wid):
175 window = self._windows[wid]
176 try:
177 do_char = window.do_char
178 except AttributeError:
179 do_char = self.do_char
180 do_char(ch, event)
181 # else it wasn't for us, sigh...
182
183 def do_inMenuBar(self, partcode, window, event):
184 Qd.InitCursor()
185 (what, message, when, where, modifiers) = event
186 self.checkopenwindowsmenu()
Just van Rossum40144012002-02-04 12:52:44 +0000187 wid = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000188 if wid and self._windows.has_key(wid):
189 self.checkmenus(self._windows[wid])
190 else:
191 self.checkmenus(None)
192 result = MenuToolbox.MenuSelect(where)
193 id = (result>>16) & 0xffff # Hi word
Jack Jansenf94cadf2002-08-31 01:20:53 +0000194 if id >= 0x8000:
195 id = -0x10000 + id
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000196 item = result & 0xffff # Lo word
197 self.do_rawmenu(id, item, window, event)
198
199 def do_updateEvt(self, event):
200 (what, message, when, where, modifiers) = event
201 wid = Win.WhichWindow(message)
202 if wid and self._windows.has_key(wid):
203 window = self._windows[wid]
204 window.do_rawupdate(wid, event)
205 else:
Jack Jansendc4d9252001-08-27 10:55:41 +0000206 if KILLUNKNOWNWINDOWS and wid:
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000207 wid.HideWindow()
208 import sys
209 sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
210 else:
Jack Jansenb9e66612002-03-21 22:36:57 +0000211 if hasattr(MacOS, 'HandleEvent'):
212 MacOS.HandleEvent(event)
213 else:
214 print 'Unexpected updateEvent:', event
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000215
216 def suspendresume(self, onoff):
217 pass
218
219 def do_suspendresume(self, event):
220 self._suspended = not event[1] & 1
221 FrameWork.Application.do_suspendresume(self, event)
222
223 def checkopenwindowsmenu(self):
224 if self._openwindowscheckmark:
Jack Jansenafd0aa62001-01-29 13:29:47 +0000225 self.openwindowsmenu.menu.CheckMenuItem(self._openwindowscheckmark, 0)
Just van Rossum40144012002-02-04 12:52:44 +0000226 window = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000227 if window:
228 for item, wid in self._openwindows.items():
229 if wid == window:
230 #self.pythonwindowsmenuitem.check(1)
Jack Jansenafd0aa62001-01-29 13:29:47 +0000231 self.openwindowsmenu.menu.CheckMenuItem(item, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000232 self._openwindowscheckmark = item
233 break
234 else:
235 self._openwindowscheckmark = 0
236 #if self._openwindows:
237 # self.pythonwindowsmenuitem.enable(1)
238 #else:
239 # self.pythonwindowsmenuitem.enable(0)
240
241 def checkmenus(self, window):
242 for item in self._menustocheck:
243 callback = item.menu.items[item.item-1][2]
244 if type(callback) <> StringType:
245 item.enable(1)
246 elif hasattr(window, "domenu_" + callback):
247 if hasattr(window, "can_" + callback):
248 canhandler = getattr(window, "can_" + callback)
249 if canhandler(item):
250 item.enable(1)
251 else:
252 item.enable(0)
253 else:
254 item.enable(1)
255 else:
256 item.enable(0)
257
258 def enablemenubar(self, onoff):
259 for m in self.menubar.menus.values():
260 if onoff:
Jack Jansenafd0aa62001-01-29 13:29:47 +0000261 m.menu.EnableMenuItem(0)
Just van Rossum4798c4e1999-02-27 17:15:32 +0000262 elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
Jack Jansenafd0aa62001-01-29 13:29:47 +0000263 m.menu.DisableMenuItem(0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000264 MenuToolbox.DrawMenuBar()
265
266 def makemenubar(self):
267 self.menubar = MenuBar(self)
268 FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
269 self.makeusermenus()
Just van Rossum7171df31999-10-30 11:46:18 +0000270
271 def scriptswalk(self, top, menu, done=None):
272 if done is None:
273 done = {}
274 if done.has_key(top):
275 return
276 done[top] = 1
Jack Jansene7ee17c2003-02-06 22:32:35 +0000277 import os, string
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000278 try:
279 names = os.listdir(top)
280 except os.error:
281 FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
282 return
283 savedir = os.getcwd()
284 os.chdir(top)
285 for name in names:
Just van Rossum6dc2b571999-12-23 21:50:26 +0000286 if name == "CVS":
287 continue
288 try:
Jack Jansene7ee17c2003-02-06 22:32:35 +0000289 fsr, isdir, isalias = File.FSResolveAliasFile(name, 1)
Just van Rossum6dc2b571999-12-23 21:50:26 +0000290 except:
291 # maybe a broken alias
292 continue
Jack Jansene7ee17c2003-02-06 22:32:35 +0000293 path = fsr.as_pathname()
Just van Rossum7171df31999-10-30 11:46:18 +0000294 if done.has_key(path):
295 continue
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000296 name = string.strip(name)
Just van Rossumc1a9cab2003-01-09 23:20:31 +0000297 if os.name == "posix":
298 name = unicode(name, "utf-8")
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000299 if name[-3:] == '---':
300 menu.addseparator()
301 elif isdir:
302 submenu = FrameWork.SubMenu(menu, name)
Just van Rossum7171df31999-10-30 11:46:18 +0000303 self.scriptswalk(path, submenu, done)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000304 else:
Jack Jansene7ee17c2003-02-06 22:32:35 +0000305 creator, type = MacOS.GetCreatorAndType(path)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000306 if type == 'TEXT':
307 if name[-3:] == '.py':
308 name = name[:-3]
309 item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
310 self._scripts[(menu.id, item.item)] = path
Just van Rossum7171df31999-10-30 11:46:18 +0000311 done[path] = 1
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000312 os.chdir(savedir)
313
314 def domenu_script(self, id, item, window, event):
315 (what, message, when, where, modifiers) = event
316 path = self._scripts[(id, item)]
317 import os
318 if not os.path.exists(path):
319 self.makescriptsmenu()
320 import W
321 raise W.AlertError, "File not found."
322 if ord(Evt.GetKeys()[7]) & 4:
323 self.openscript(path)
324 else:
325 import W, MacOS, sys
326 W.SetCursor("watch")
327 sys.argv = [path]
328 #cwd = os.getcwd()
329 #os.chdir(os.path.dirname(path) + ':')
330 try:
331 # xxx if there is a script window for this file,
332 # exec in that window's namespace.
333 # xxx what to do when it's not saved???
334 # promt to save?
Jack Jansen815d2bf2002-01-21 23:00:52 +0000335 if hasattr(MacOS, 'EnableAppswitch'):
336 MacOS.EnableAppswitch(0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000337 execfile(path, {'__name__': '__main__', '__file__': path})
338 except W.AlertError, detail:
Jack Jansen815d2bf2002-01-21 23:00:52 +0000339 if hasattr(MacOS, 'EnableAppswitch'):
340 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000341 raise W.AlertError, detail
342 except KeyboardInterrupt:
Jack Jansen815d2bf2002-01-21 23:00:52 +0000343 if hasattr(MacOS, 'EnableAppswitch'):
344 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000345 except:
Jack Jansen815d2bf2002-01-21 23:00:52 +0000346 if hasattr(MacOS, 'EnableAppswitch'):
347 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000348 import PyEdit
349 PyEdit.tracebackwindow.traceback(1)
350 else:
Jack Jansen815d2bf2002-01-21 23:00:52 +0000351 if hasattr(MacOS, 'EnableAppswitch'):
352 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000353 #os.chdir(cwd)
354
355 def openscript(self, filename, lineno=None, charoffset=0, modname=""):
356 import os, PyEdit, W
357 editor = self.getscript(filename)
358 if editor:
359 editor.select()
360 elif os.path.exists(filename):
361 editor = PyEdit.Editor(filename)
362 elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
363 import imp
364 if not modname:
365 if filename[-1] == 'c':
366 modname = os.path.basename(filename)[:-4]
367 else:
368 modname = os.path.basename(filename)[:-3]
369 try:
370 # XXX This does not work correctly with packages!
371 # XXX The docs say we should do it manually, pack, then sub, then sub2 etc.
372 # XXX It says we should use imp.load_module(), but that *reloads* a package,
373 # XXX and that's the last thing we want here.
374 f, filename, (suff, mode, dummy) = imp.find_module(modname)
375 except ImportError:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000376 raise W.AlertError, "Can't find file for \"%s\"" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000377 else:
378 if not f:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000379 raise W.AlertError, "Can't find file for \"%s\"" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000380 f.close()
381 if suff == '.py':
382 self.openscript(filename, lineno, charoffset)
383 return
384 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000385 raise W.AlertError, "Can't find file for \"%s\"" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000386 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000387 raise W.AlertError, "Can't find file \"%s\"" % filename
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000388 if lineno is not None:
389 editor.selectline(lineno, charoffset)
390 return editor
391
392 def getscript(self, filename):
393 if filename[:1] == '<' and filename[-1:] == '>':
394 filename = filename[1:-1]
395 import string
396 lowpath = string.lower(filename)
397 for wid, window in self._windows.items():
Just van Rossum7171df31999-10-30 11:46:18 +0000398 if hasattr(window, "path") and type(window.path) == StringType and \
399 lowpath == string.lower(window.path):
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000400 return window
401 elif hasattr(window, "path") and filename == wid.GetWTitle():
402 return window
403
404 def getprefs(self):
405 import MacPrefs
406 return MacPrefs.GetPrefs(self.preffilepath)
Just van Rossum2a759091999-09-26 12:18:19 +0000407
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000408 def do_editorprefs(self, *args):
409 import PyEdit
410 PyEdit.EditorDefaultSettings()
411
Just van Rossum2a759091999-09-26 12:18:19 +0000412 def do_setwindowfont(self, *args):
413 import FontSettings, W
414 prefs = self.getprefs()
415 settings = FontSettings.FontDialog(prefs.defaultfont)
416 if settings:
417 prefs.defaultfont, tabsettings = settings
418 raise W.AlertError, "Note that changes will only affect new windows!"
419
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000420
421
422class MenuBar(FrameWork.MenuBar):
423
424 possibleIDs = range(10, 256)
425
426 def getnextid(self):
427 id = self.possibleIDs[0]
428 del self.possibleIDs[0]
429 return id
430
431 def __init__(self, parent = None):
432 self.bar = MenuToolbox.GetMenuBar()
433 MenuToolbox.ClearMenuBar()
434 self.menus = {}
435 self.parent = parent
436
437 def dispatch(self, id, item, window, event):
438 if self.menus.has_key(id):
439 self.menus[id].dispatch(id, item, window, event)
440
441 def delmenu(self, id):
442 MenuToolbox.DeleteMenu(id)
443 if id in self.possibleIDs:
444 print "XXX duplicate menu ID!", id
445 self.possibleIDs.append(id)
446
447
448class Menu(FrameWork.Menu):
449
450 def dispatch(self, id, item, window, event):
451 title, shortcut, callback, kind = self.items[item-1]
452 if type(callback) == StringType:
453 callback = self._getmenuhandler(callback)
454 if callback:
455 import W
456 W.CallbackCall(callback, 0, id, item, window, event)
457
458 def _getmenuhandler(self, callback):
459 menuhandler = None
Just van Rossum40144012002-02-04 12:52:44 +0000460 wid = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000461 if wid and self.bar.parent._windows.has_key(wid):
462 window = self.bar.parent._windows[wid]
463 if hasattr(window, "domenu_" + callback):
464 menuhandler = getattr(window, "domenu_" + callback)
465 elif hasattr(self.bar.parent, "domenu_" + callback):
466 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
467 elif hasattr(self.bar.parent, "domenu_" + callback):
468 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
469 return menuhandler
470