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