home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Tools / IDE / Wapplication.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  11.9 KB  |  427 lines

  1. import FrameWork
  2. import Win
  3. import Qd
  4. import Evt
  5. import MacOS
  6. import Events
  7. import traceback
  8. from types import *
  9.  
  10. import Menu; MenuToolbox = Menu; del Menu
  11.  
  12.  
  13. class 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.     
  126.     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.     
  133.     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)
  240.             elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
  241.                 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:
  333.                 raise W.AlertError, "Can’t find file for “%s”" % modname
  334.             else:
  335.                 if not f:
  336.                     raise W.AlertError, "Can’t find file for “%s”" % modname
  337.                 f.close()
  338.             if suff == '.py':
  339.                 self.openscript(filename, lineno, charoffset)
  340.                 return
  341.             else:
  342.                 raise W.AlertError, "Can’t find file for “%s”" % modname
  343.         else:
  344.             raise W.AlertError, "Can’t find file ‘%s’" % filename
  345.         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)
  363.     
  364.     def do_editorprefs(self, *args):
  365.         import PyEdit
  366.         PyEdit.EditorDefaultSettings()
  367.     
  368.     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.  
  376.  
  377.  
  378. class 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.  
  404. class 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.  
  427.