blob: ed639fa0cb0ec86481f9503e0bcde97a36badf4e [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()
248
249 def scriptswalk(self, top, menu):
250 import os, macfs, string
251 try:
252 names = os.listdir(top)
253 except os.error:
254 FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
255 return
256 savedir = os.getcwd()
257 os.chdir(top)
258 for name in names:
259 fss, isdir, isalias = macfs.ResolveAliasFile(name)
260 path = fss.as_pathname()
261 name = string.strip(name)
262 if name[-3:] == '---':
263 menu.addseparator()
264 elif isdir:
265 submenu = FrameWork.SubMenu(menu, name)
266 self.scriptswalk(path, submenu)
267 else:
268 creator, type = fss.GetCreatorType()
269 if type == 'TEXT':
270 if name[-3:] == '.py':
271 name = name[:-3]
272 item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
273 self._scripts[(menu.id, item.item)] = path
274 os.chdir(savedir)
275
276 def domenu_script(self, id, item, window, event):
277 (what, message, when, where, modifiers) = event
278 path = self._scripts[(id, item)]
279 import os
280 if not os.path.exists(path):
281 self.makescriptsmenu()
282 import W
283 raise W.AlertError, "File not found."
284 if ord(Evt.GetKeys()[7]) & 4:
285 self.openscript(path)
286 else:
287 import W, MacOS, sys
288 W.SetCursor("watch")
289 sys.argv = [path]
290 #cwd = os.getcwd()
291 #os.chdir(os.path.dirname(path) + ':')
292 try:
293 # xxx if there is a script window for this file,
294 # exec in that window's namespace.
295 # xxx what to do when it's not saved???
296 # promt to save?
297 MacOS.EnableAppswitch(0)
298 execfile(path, {'__name__': '__main__', '__file__': path})
299 except W.AlertError, detail:
300 MacOS.EnableAppswitch(-1)
301 raise W.AlertError, detail
302 except KeyboardInterrupt:
303 MacOS.EnableAppswitch(-1)
304 except:
305 MacOS.EnableAppswitch(-1)
306 import PyEdit
307 PyEdit.tracebackwindow.traceback(1)
308 else:
309 MacOS.EnableAppswitch(-1)
310 #os.chdir(cwd)
311
312 def openscript(self, filename, lineno=None, charoffset=0, modname=""):
313 import os, PyEdit, W
314 editor = self.getscript(filename)
315 if editor:
316 editor.select()
317 elif os.path.exists(filename):
318 editor = PyEdit.Editor(filename)
319 elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
320 import imp
321 if not modname:
322 if filename[-1] == 'c':
323 modname = os.path.basename(filename)[:-4]
324 else:
325 modname = os.path.basename(filename)[:-3]
326 try:
327 # XXX This does not work correctly with packages!
328 # XXX The docs say we should do it manually, pack, then sub, then sub2 etc.
329 # XXX It says we should use imp.load_module(), but that *reloads* a package,
330 # XXX and that's the last thing we want here.
331 f, filename, (suff, mode, dummy) = imp.find_module(modname)
332 except ImportError:
Just van Rossumedab9391999-02-02 22:31:05 +0000333 raise W.AlertError, "Can¹t find file for ³%s²" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000334 else:
335 if not f:
Just van Rossumedab9391999-02-02 22:31:05 +0000336 raise W.AlertError, "Can¹t find file for ³%s²" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000337 f.close()
338 if suff == '.py':
339 self.openscript(filename, lineno, charoffset)
340 return
341 else:
Just van Rossumedab9391999-02-02 22:31:05 +0000342 raise W.AlertError, "Can¹t find file for ³%s²" % modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000343 else:
Just van Rossumedab9391999-02-02 22:31:05 +0000344 raise W.AlertError, "Can¹t find file Œ%s¹" % filename
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000345 if lineno is not None:
346 editor.selectline(lineno, charoffset)
347 return editor
348
349 def getscript(self, filename):
350 if filename[:1] == '<' and filename[-1:] == '>':
351 filename = filename[1:-1]
352 import string
353 lowpath = string.lower(filename)
354 for wid, window in self._windows.items():
355 if hasattr(window, "path") and lowpath == string.lower(window.path):
356 return window
357 elif hasattr(window, "path") and filename == wid.GetWTitle():
358 return window
359
360 def getprefs(self):
361 import MacPrefs
362 return MacPrefs.GetPrefs(self.preffilepath)
Just van Rossum2a759091999-09-26 12:18:19 +0000363
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000364 def do_editorprefs(self, *args):
365 import PyEdit
366 PyEdit.EditorDefaultSettings()
367
Just van Rossum2a759091999-09-26 12:18:19 +0000368 def do_setwindowfont(self, *args):
369 import FontSettings, W
370 prefs = self.getprefs()
371 settings = FontSettings.FontDialog(prefs.defaultfont)
372 if settings:
373 prefs.defaultfont, tabsettings = settings
374 raise W.AlertError, "Note that changes will only affect new windows!"
375
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000376
377
378class MenuBar(FrameWork.MenuBar):
379
380 possibleIDs = range(10, 256)
381
382 def getnextid(self):
383 id = self.possibleIDs[0]
384 del self.possibleIDs[0]
385 return id
386
387 def __init__(self, parent = None):
388 self.bar = MenuToolbox.GetMenuBar()
389 MenuToolbox.ClearMenuBar()
390 self.menus = {}
391 self.parent = parent
392
393 def dispatch(self, id, item, window, event):
394 if self.menus.has_key(id):
395 self.menus[id].dispatch(id, item, window, event)
396
397 def delmenu(self, id):
398 MenuToolbox.DeleteMenu(id)
399 if id in self.possibleIDs:
400 print "XXX duplicate menu ID!", id
401 self.possibleIDs.append(id)
402
403
404class Menu(FrameWork.Menu):
405
406 def dispatch(self, id, item, window, event):
407 title, shortcut, callback, kind = self.items[item-1]
408 if type(callback) == StringType:
409 callback = self._getmenuhandler(callback)
410 if callback:
411 import W
412 W.CallbackCall(callback, 0, id, item, window, event)
413
414 def _getmenuhandler(self, callback):
415 menuhandler = None
416 wid = Win.FrontWindow()
417 if wid and self.bar.parent._windows.has_key(wid):
418 window = self.bar.parent._windows[wid]
419 if hasattr(window, "domenu_" + callback):
420 menuhandler = getattr(window, "domenu_" + callback)
421 elif hasattr(self.bar.parent, "domenu_" + callback):
422 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
423 elif hasattr(self.bar.parent, "domenu_" + callback):
424 menuhandler = getattr(self.bar.parent, "domenu_" + callback)
425 return menuhandler
426