This commit was manufactured by cvs2svn to create tag 'r22b2-mac'.
[python/dscho.git] / Mac / Tools / IDE / Wapplication.py
blob8839c90a8b90d804f617dbef12025250218eb833
1 import FrameWork
2 from Carbon import Win
3 from Carbon import Qd
4 from Carbon import Evt
5 import MacOS
6 from Carbon import Events
7 import traceback
8 from types import *
10 from Carbon import Menu; MenuToolbox = Menu; del Menu
12 KILLUNKNOWNWINDOWS = 0 # Set to 0 for debugging.
14 class Application(FrameWork.Application):
16 def __init__(self, signature='Pyth'):
17 import W
18 W.setapplication(self, signature)
19 FrameWork.Application.__init__(self)
20 self._suspended = 0
21 self.quitting = 0
22 self.debugger_quitting = 1
23 self.DebuggerQuit = 'DebuggerQuitDummyException'
24 self._idlefuncs = []
25 # map certain F key codes to equivalent command-letter combos (JJS)
26 self.fkeymaps = {122:"z", 120:"x", 99:"c", 118:"v"}
28 def mainloop(self, mask=FrameWork.everyEvent, wait=None):
29 import W
30 self.quitting = 0
31 saveyield = MacOS.EnableAppswitch(-1)
32 try:
33 while not self.quitting:
34 try:
35 self.do1event(mask, wait)
36 except W.AlertError, detail:
37 MacOS.EnableAppswitch(-1)
38 W.Message(detail)
39 except self.DebuggerQuit:
40 MacOS.EnableAppswitch(-1)
41 except:
42 MacOS.EnableAppswitch(-1)
43 import PyEdit
44 PyEdit.tracebackwindow.traceback()
45 finally:
46 MacOS.EnableAppswitch(1)
48 def debugger_mainloop(self, mask=FrameWork.everyEvent, wait=None):
49 import W
50 self.debugger_quitting = 0
51 saveyield = MacOS.EnableAppswitch(-1)
52 try:
53 while not self.quitting and not self.debugger_quitting:
54 try:
55 self.do1event(mask, wait)
56 except W.AlertError, detail:
57 W.Message(detail)
58 except:
59 import PyEdit
60 PyEdit.tracebackwindow.traceback()
61 finally:
62 MacOS.EnableAppswitch(saveyield)
64 def breathe(self, wait=1):
65 import W
66 ok, event = Evt.WaitNextEvent(FrameWork.updateMask |
67 FrameWork.mDownMask | FrameWork.osMask |
68 FrameWork.activMask,
69 wait)
70 if ok:
71 (what, message, when, where, modifiers) = event
72 #print FrameWork.eventname[what]
73 if FrameWork.eventname[what] == 'mouseDown':
74 partcode, wid = Win.FindWindow(where)
75 if FrameWork.partname[partcode] <> 'inDesk':
76 return
77 else:
78 W.SetCursor('watch')
79 self.dispatch(event)
81 def refreshwindows(self, wait=1):
82 import W
83 while 1:
84 ok, event = Evt.WaitNextEvent(FrameWork.updateMask, wait)
85 if not ok:
86 break
87 self.dispatch(event)
89 def addidlefunc(self, func):
90 self._idlefuncs.append(func)
92 def removeidlefunc(self, func):
93 self._idlefuncs.remove(func)
95 def idle(self, event):
96 if not self._suspended:
97 if not self.do_frontWindowMethod("idle", event):
98 Qd.InitCursor()
99 if self._idlefuncs:
100 for func in self._idlefuncs:
101 try:
102 func()
103 except:
104 import sys
105 sys.stderr.write("exception in idle function %s; killed:\n" % `func`)
106 traceback.print_exc()
107 self._idlefuncs.remove(func)
108 break
110 def do_frontWindowMethod(self, attr, *args):
111 wid = Win.FrontWindow()
112 if wid and self._windows.has_key(wid):
113 window = self._windows[wid]
114 if hasattr(window, attr):
115 handler = getattr(window, attr)
116 apply(handler, args)
117 return 1
119 def appendwindow(self, wid, window):
120 self._windows[wid] = window
121 self.makeopenwindowsmenu()
123 def removewindow(self, wid):
124 del self._windows[wid]
125 self.makeopenwindowsmenu()
127 def makeopenwindowsmenu(self):
128 # dummy; could be the full version from PythonIDEMain.py
129 self._openwindows = {}
130 self._openwindowscheckmark = 0
131 if not hasattr(self, "_menustocheck"):
132 self._menustocheck = []
134 def do_key(self, event):
135 (what, message, when, where, modifiers) = event
136 ch = chr(message & FrameWork.charCodeMask)
137 rest = message & ~FrameWork.charCodeMask
138 keycode = (message & FrameWork.keyCodeMask) >> 8
139 if keycode in self.fkeymaps.keys(): # JJS
140 ch = self.fkeymaps[keycode]
141 modifiers = modifiers | FrameWork.cmdKey
142 wid = Win.FrontWindow()
143 if modifiers & FrameWork.cmdKey and not modifiers & FrameWork.shiftKey:
144 if wid and self._windows.has_key(wid):
145 self.checkmenus(self._windows[wid])
146 else:
147 self.checkmenus(None)
148 event = (what, ord(ch) | rest, when, where, modifiers)
149 result = MenuToolbox.MenuKey(ord(ch))
150 id = (result>>16) & 0xffff # Hi word
151 item = result & 0xffff # Lo word
152 if id:
153 self.do_rawmenu(id, item, None, event)
154 return # here! we had a menukey!
155 #else:
156 # print "XXX Command-" +`ch`
157 # See whether the front window wants it
158 if wid and self._windows.has_key(wid):
159 window = self._windows[wid]
160 try:
161 do_char = window.do_char
162 except AttributeError:
163 do_char = self.do_char
164 do_char(ch, event)
165 # else it wasn't for us, sigh...
167 def do_inMenuBar(self, partcode, window, event):
168 Qd.InitCursor()
169 (what, message, when, where, modifiers) = event
170 self.checkopenwindowsmenu()
171 wid = Win.FrontWindow()
172 if wid and self._windows.has_key(wid):
173 self.checkmenus(self._windows[wid])
174 else:
175 self.checkmenus(None)
176 result = MenuToolbox.MenuSelect(where)
177 id = (result>>16) & 0xffff # Hi word
178 item = result & 0xffff # Lo word
179 self.do_rawmenu(id, item, window, event)
181 def do_updateEvt(self, event):
182 (what, message, when, where, modifiers) = event
183 wid = Win.WhichWindow(message)
184 if wid and self._windows.has_key(wid):
185 window = self._windows[wid]
186 window.do_rawupdate(wid, event)
187 else:
188 if KILLUNKNOWNWINDOWS and wid:
189 wid.HideWindow()
190 import sys
191 sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
192 else:
193 MacOS.HandleEvent(event)
195 def suspendresume(self, onoff):
196 pass
198 def do_suspendresume(self, event):
199 self._suspended = not event[1] & 1
200 FrameWork.Application.do_suspendresume(self, event)
202 def checkopenwindowsmenu(self):
203 if self._openwindowscheckmark:
204 self.openwindowsmenu.menu.CheckMenuItem(self._openwindowscheckmark, 0)
205 window = Win.FrontWindow()
206 if window:
207 for item, wid in self._openwindows.items():
208 if wid == window:
209 #self.pythonwindowsmenuitem.check(1)
210 self.openwindowsmenu.menu.CheckMenuItem(item, 1)
211 self._openwindowscheckmark = item
212 break
213 else:
214 self._openwindowscheckmark = 0
215 #if self._openwindows:
216 # self.pythonwindowsmenuitem.enable(1)
217 #else:
218 # self.pythonwindowsmenuitem.enable(0)
220 def checkmenus(self, window):
221 for item in self._menustocheck:
222 callback = item.menu.items[item.item-1][2]
223 if type(callback) <> StringType:
224 item.enable(1)
225 elif hasattr(window, "domenu_" + callback):
226 if hasattr(window, "can_" + callback):
227 canhandler = getattr(window, "can_" + callback)
228 if canhandler(item):
229 item.enable(1)
230 else:
231 item.enable(0)
232 else:
233 item.enable(1)
234 else:
235 item.enable(0)
237 def enablemenubar(self, onoff):
238 for m in self.menubar.menus.values():
239 if onoff:
240 m.menu.EnableMenuItem(0)
241 elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
242 m.menu.DisableMenuItem(0)
243 MenuToolbox.DrawMenuBar()
245 def makemenubar(self):
246 self.menubar = MenuBar(self)
247 FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
248 self.makeusermenus()
250 def scriptswalk(self, top, menu, done=None):
251 if done is None:
252 done = {}
253 if done.has_key(top):
254 return
255 done[top] = 1
256 import os, macfs, string
257 try:
258 names = os.listdir(top)
259 except os.error:
260 FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
261 return
262 savedir = os.getcwd()
263 os.chdir(top)
264 for name in names:
265 if name == "CVS":
266 continue
267 try:
268 fss, isdir, isalias = macfs.ResolveAliasFile(name)
269 except:
270 # maybe a broken alias
271 continue
272 path = fss.as_pathname()
273 if done.has_key(path):
274 continue
275 name = string.strip(name)
276 if name[-3:] == '---':
277 menu.addseparator()
278 elif isdir:
279 submenu = FrameWork.SubMenu(menu, name)
280 self.scriptswalk(path, submenu, done)
281 else:
282 creator, type = fss.GetCreatorType()
283 if type == 'TEXT':
284 if name[-3:] == '.py':
285 name = name[:-3]
286 item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
287 self._scripts[(menu.id, item.item)] = path
288 done[path] = 1
289 os.chdir(savedir)
291 def domenu_script(self, id, item, window, event):
292 (what, message, when, where, modifiers) = event
293 path = self._scripts[(id, item)]
294 import os
295 if not os.path.exists(path):
296 self.makescriptsmenu()
297 import W
298 raise W.AlertError, "File not found."
299 if ord(Evt.GetKeys()[7]) & 4:
300 self.openscript(path)
301 else:
302 import W, MacOS, sys
303 W.SetCursor("watch")
304 sys.argv = [path]
305 #cwd = os.getcwd()
306 #os.chdir(os.path.dirname(path) + ':')
307 try:
308 # xxx if there is a script window for this file,
309 # exec in that window's namespace.
310 # xxx what to do when it's not saved???
311 # promt to save?
312 MacOS.EnableAppswitch(0)
313 execfile(path, {'__name__': '__main__', '__file__': path})
314 except W.AlertError, detail:
315 MacOS.EnableAppswitch(-1)
316 raise W.AlertError, detail
317 except KeyboardInterrupt:
318 MacOS.EnableAppswitch(-1)
319 except:
320 MacOS.EnableAppswitch(-1)
321 import PyEdit
322 PyEdit.tracebackwindow.traceback(1)
323 else:
324 MacOS.EnableAppswitch(-1)
325 #os.chdir(cwd)
327 def openscript(self, filename, lineno=None, charoffset=0, modname=""):
328 import os, PyEdit, W
329 editor = self.getscript(filename)
330 if editor:
331 editor.select()
332 elif os.path.exists(filename):
333 editor = PyEdit.Editor(filename)
334 elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
335 import imp
336 if not modname:
337 if filename[-1] == 'c':
338 modname = os.path.basename(filename)[:-4]
339 else:
340 modname = os.path.basename(filename)[:-3]
341 try:
342 # XXX This does not work correctly with packages!
343 # XXX The docs say we should do it manually, pack, then sub, then sub2 etc.
344 # XXX It says we should use imp.load_module(), but that *reloads* a package,
345 # XXX and that's the last thing we want here.
346 f, filename, (suff, mode, dummy) = imp.find_module(modname)
347 except ImportError:
348 raise W.AlertError, "Can't find file for \"%s\"" % modname
349 else:
350 if not f:
351 raise W.AlertError, "Can't find file for \"%s\"" % modname
352 f.close()
353 if suff == '.py':
354 self.openscript(filename, lineno, charoffset)
355 return
356 else:
357 raise W.AlertError, "Can't find file for \"%s\"" % modname
358 else:
359 raise W.AlertError, "Can't find file \"%s\"" % filename
360 if lineno is not None:
361 editor.selectline(lineno, charoffset)
362 return editor
364 def getscript(self, filename):
365 if filename[:1] == '<' and filename[-1:] == '>':
366 filename = filename[1:-1]
367 import string
368 lowpath = string.lower(filename)
369 for wid, window in self._windows.items():
370 if hasattr(window, "path") and type(window.path) == StringType and \
371 lowpath == string.lower(window.path):
372 return window
373 elif hasattr(window, "path") and filename == wid.GetWTitle():
374 return window
376 def getprefs(self):
377 import MacPrefs
378 return MacPrefs.GetPrefs(self.preffilepath)
380 def do_editorprefs(self, *args):
381 import PyEdit
382 PyEdit.EditorDefaultSettings()
384 def do_setwindowfont(self, *args):
385 import FontSettings, W
386 prefs = self.getprefs()
387 settings = FontSettings.FontDialog(prefs.defaultfont)
388 if settings:
389 prefs.defaultfont, tabsettings = settings
390 raise W.AlertError, "Note that changes will only affect new windows!"
394 class MenuBar(FrameWork.MenuBar):
396 possibleIDs = range(10, 256)
398 def getnextid(self):
399 id = self.possibleIDs[0]
400 del self.possibleIDs[0]
401 return id
403 def __init__(self, parent = None):
404 self.bar = MenuToolbox.GetMenuBar()
405 MenuToolbox.ClearMenuBar()
406 self.menus = {}
407 self.parent = parent
409 def dispatch(self, id, item, window, event):
410 if self.menus.has_key(id):
411 self.menus[id].dispatch(id, item, window, event)
413 def delmenu(self, id):
414 MenuToolbox.DeleteMenu(id)
415 if id in self.possibleIDs:
416 print "XXX duplicate menu ID!", id
417 self.possibleIDs.append(id)
420 class Menu(FrameWork.Menu):
422 def dispatch(self, id, item, window, event):
423 title, shortcut, callback, kind = self.items[item-1]
424 if type(callback) == StringType:
425 callback = self._getmenuhandler(callback)
426 if callback:
427 import W
428 W.CallbackCall(callback, 0, id, item, window, event)
430 def _getmenuhandler(self, callback):
431 menuhandler = None
432 wid = Win.FrontWindow()
433 if wid and self.bar.parent._windows.has_key(wid):
434 window = self.bar.parent._windows[wid]
435 if hasattr(window, "domenu_" + callback):
436 menuhandler = getattr(window, "domenu_" + callback)
437 elif hasattr(self.bar.parent, "domenu_" + callback):
438 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
439 elif hasattr(self.bar.parent, "domenu_" + callback):
440 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
441 return menuhandler