mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			481 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			481 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import FrameWork
 | 
						|
from Carbon import Win
 | 
						|
from Carbon import Qd
 | 
						|
from Carbon import Evt
 | 
						|
import MacOS
 | 
						|
from Carbon import Events
 | 
						|
import traceback
 | 
						|
from types import *
 | 
						|
from Carbon import Menu; MenuToolbox = Menu; del Menu
 | 
						|
import macresource
 | 
						|
from Carbon import File
 | 
						|
 | 
						|
if hasattr(Win, "FrontNonFloatingWindow"):
 | 
						|
    MyFrontWindow = Win.FrontNonFloatingWindow
 | 
						|
else:
 | 
						|
    MyFrontWindow = Win.FrontWindow
 | 
						|
 | 
						|
 | 
						|
KILLUNKNOWNWINDOWS = 0  # Set to 0 for debugging.
 | 
						|
 | 
						|
class Application(FrameWork.Application):
 | 
						|
 | 
						|
    def __init__(self, signature='Pyth'):
 | 
						|
        # Open our resource file, if it is not open yet
 | 
						|
        macresource.need('CURS', 468, "Widgets.rsrc")
 | 
						|
        import W
 | 
						|
        W.setapplication(self, signature)
 | 
						|
        FrameWork.Application.__init__(self)
 | 
						|
        self._suspended = 0
 | 
						|
        self.quitting = 0
 | 
						|
        self.debugger_quitting = 1
 | 
						|
        self.DebuggerQuit = 'DebuggerQuitDummyException'
 | 
						|
        self._idlefuncs = []
 | 
						|
        # map certain F key codes to equivalent command-letter combos (JJS)
 | 
						|
        self.fkeymaps = {122:"z", 120:"x", 99:"c", 118:"v"}
 | 
						|
 | 
						|
    def mainloop(self, mask=FrameWork.everyEvent, wait=None):
 | 
						|
        import W
 | 
						|
        self.quitting = 0
 | 
						|
        if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
            saveyield = MacOS.EnableAppswitch(-1)
 | 
						|
        try:
 | 
						|
            while not self.quitting:
 | 
						|
                try:
 | 
						|
                    self.do1event(mask, wait)
 | 
						|
                except W.AlertError, detail:
 | 
						|
                    if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                        MacOS.EnableAppswitch(-1)
 | 
						|
                    W.Message(detail)
 | 
						|
                except self.DebuggerQuit:
 | 
						|
                    if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                        MacOS.EnableAppswitch(-1)
 | 
						|
                except:
 | 
						|
                    if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                        MacOS.EnableAppswitch(-1)
 | 
						|
                    import PyEdit
 | 
						|
                    PyEdit.tracebackwindow.traceback()
 | 
						|
        finally:
 | 
						|
            if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                MacOS.EnableAppswitch(1)
 | 
						|
 | 
						|
    def debugger_mainloop(self, mask=FrameWork.everyEvent, wait=None):
 | 
						|
        import W
 | 
						|
        self.debugger_quitting = 0
 | 
						|
        if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
            saveyield = MacOS.EnableAppswitch(-1)
 | 
						|
        try:
 | 
						|
            while not self.quitting and not self.debugger_quitting:
 | 
						|
                try:
 | 
						|
                    self.do1event(mask, wait)
 | 
						|
                except W.AlertError, detail:
 | 
						|
                    W.Message(detail)
 | 
						|
                except:
 | 
						|
                    import PyEdit
 | 
						|
                    PyEdit.tracebackwindow.traceback()
 | 
						|
        finally:
 | 
						|
            if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                MacOS.EnableAppswitch(saveyield)
 | 
						|
 | 
						|
    def breathe(self, wait=1):
 | 
						|
        import W
 | 
						|
        ok, event = Evt.WaitNextEvent(FrameWork.updateMask |
 | 
						|
                        FrameWork.mDownMask | FrameWork.osMask |
 | 
						|
                        FrameWork.activMask,
 | 
						|
                        wait)
 | 
						|
        if ok:
 | 
						|
            (what, message, when, where, modifiers) = event
 | 
						|
            #print FrameWork.eventname[what]
 | 
						|
            if FrameWork.eventname[what] == 'mouseDown':
 | 
						|
                partcode, wid = Win.FindWindow(where)
 | 
						|
                if FrameWork.partname[partcode] <> 'inDesk':
 | 
						|
                    return
 | 
						|
            else:
 | 
						|
                W.SetCursor('watch')
 | 
						|
            self.dispatch(event)
 | 
						|
 | 
						|
    def refreshwindows(self, wait=1):
 | 
						|
        import W
 | 
						|
        while 1:
 | 
						|
            ok, event = Evt.WaitNextEvent(FrameWork.updateMask, wait)
 | 
						|
            if not ok:
 | 
						|
                break
 | 
						|
            self.dispatch(event)
 | 
						|
 | 
						|
    def addidlefunc(self, func):
 | 
						|
        self._idlefuncs.append(func)
 | 
						|
 | 
						|
    def removeidlefunc(self, func):
 | 
						|
        self._idlefuncs.remove(func)
 | 
						|
 | 
						|
    def idle(self, event):
 | 
						|
        if not self._suspended:
 | 
						|
            if not self.do_frontWindowMethod("idle", event):
 | 
						|
                Qd.InitCursor()
 | 
						|
        if self._idlefuncs:
 | 
						|
            for func in self._idlefuncs:
 | 
						|
                try:
 | 
						|
                    func()
 | 
						|
                except:
 | 
						|
                    import sys
 | 
						|
                    sys.stderr.write("exception in idle function %r; killed:\n" % (func,))
 | 
						|
                    traceback.print_exc()
 | 
						|
                    self._idlefuncs.remove(func)
 | 
						|
                    break
 | 
						|
 | 
						|
    def do_frontWindowMethod(self, attr, *args):
 | 
						|
        wid = MyFrontWindow()
 | 
						|
        if wid and self._windows.has_key(wid):
 | 
						|
            window = self._windows[wid]
 | 
						|
            if hasattr(window, attr):
 | 
						|
                handler = getattr(window, attr)
 | 
						|
                handler(*args)
 | 
						|
                return 1
 | 
						|
 | 
						|
    def getfrontwindow(self):
 | 
						|
        wid = MyFrontWindow()
 | 
						|
        if wid and self._windows.has_key(wid):
 | 
						|
            return self._windows[wid]
 | 
						|
        return None
 | 
						|
 | 
						|
    def appendwindow(self, wid, window):
 | 
						|
        self._windows[wid] = window
 | 
						|
        self.makeopenwindowsmenu()
 | 
						|
 | 
						|
    def removewindow(self, wid):
 | 
						|
        del self._windows[wid]
 | 
						|
        self.makeopenwindowsmenu()
 | 
						|
 | 
						|
    def makeopenwindowsmenu(self):
 | 
						|
        # dummy; could be the full version from PythonIDEMain.py
 | 
						|
        self._openwindows = {}
 | 
						|
        self._openwindowscheckmark = 0
 | 
						|
        if not hasattr(self, "_menustocheck"):
 | 
						|
            self._menustocheck = []
 | 
						|
 | 
						|
    def do_key(self, event):
 | 
						|
        (what, message, when, where, modifiers) = event
 | 
						|
        ch = chr(message & FrameWork.charCodeMask)
 | 
						|
        rest = message & ~FrameWork.charCodeMask
 | 
						|
        keycode = (message & FrameWork.keyCodeMask) >> 8
 | 
						|
        if keycode in self.fkeymaps.keys():             # JJS
 | 
						|
            ch = self.fkeymaps[keycode]
 | 
						|
            modifiers = modifiers | FrameWork.cmdKey
 | 
						|
        wid = MyFrontWindow()
 | 
						|
        if modifiers & FrameWork.cmdKey and not modifiers & FrameWork.shiftKey:
 | 
						|
            if wid and self._windows.has_key(wid):
 | 
						|
                self.checkmenus(self._windows[wid])
 | 
						|
            else:
 | 
						|
                self.checkmenus(None)
 | 
						|
            event = (what, ord(ch) | rest, when, where, modifiers)
 | 
						|
            result = MenuToolbox.MenuKey(ord(ch))
 | 
						|
            id = (result>>16) & 0xffff      # Hi word
 | 
						|
            item = result & 0xffff          # Lo word
 | 
						|
            if id:
 | 
						|
                self.do_rawmenu(id, item, None, event)
 | 
						|
                return  # here! we had a menukey!
 | 
						|
            #else:
 | 
						|
            #       print "XXX Command-%r" % ch
 | 
						|
        # See whether the front window wants it
 | 
						|
        if wid and self._windows.has_key(wid):
 | 
						|
            window = self._windows[wid]
 | 
						|
            try:
 | 
						|
                do_char = window.do_char
 | 
						|
            except AttributeError:
 | 
						|
                do_char = self.do_char
 | 
						|
            do_char(ch, event)
 | 
						|
        # else it wasn't for us, sigh...
 | 
						|
 | 
						|
    def do_inMenuBar(self, partcode, window, event):
 | 
						|
        Qd.InitCursor()
 | 
						|
        (what, message, when, where, modifiers) = event
 | 
						|
        self.checkopenwindowsmenu()
 | 
						|
        wid = MyFrontWindow()
 | 
						|
        if wid and self._windows.has_key(wid):
 | 
						|
            self.checkmenus(self._windows[wid])
 | 
						|
        else:
 | 
						|
            self.checkmenus(None)
 | 
						|
        result = MenuToolbox.MenuSelect(where)
 | 
						|
        id = (result>>16) & 0xffff      # Hi word
 | 
						|
        if id >= 0x8000:
 | 
						|
            id = -0x10000 + id
 | 
						|
        item = result & 0xffff          # Lo word
 | 
						|
        self.do_rawmenu(id, item, window, event)
 | 
						|
 | 
						|
    def do_updateEvt(self, event):
 | 
						|
        (what, message, when, where, modifiers) = event
 | 
						|
        wid = Win.WhichWindow(message)
 | 
						|
        if wid and self._windows.has_key(wid):
 | 
						|
            window = self._windows[wid]
 | 
						|
            window.do_rawupdate(wid, event)
 | 
						|
        else:
 | 
						|
            if KILLUNKNOWNWINDOWS and wid:
 | 
						|
                wid.HideWindow()
 | 
						|
                import sys
 | 
						|
                sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
 | 
						|
            else:
 | 
						|
                if hasattr(MacOS, 'HandleEvent'):
 | 
						|
                    MacOS.HandleEvent(event)
 | 
						|
                else:
 | 
						|
                    print 'Unexpected updateEvent:', event
 | 
						|
 | 
						|
    def suspendresume(self, onoff):
 | 
						|
        pass
 | 
						|
 | 
						|
    def do_suspendresume(self, event):
 | 
						|
        self._suspended = not event[1] & 1
 | 
						|
        FrameWork.Application.do_suspendresume(self, event)
 | 
						|
 | 
						|
    def checkopenwindowsmenu(self):
 | 
						|
        if self._openwindowscheckmark:
 | 
						|
            self.openwindowsmenu.menu.CheckMenuItem(self._openwindowscheckmark, 0)
 | 
						|
        window = MyFrontWindow()
 | 
						|
        if window:
 | 
						|
            for item, wid in self._openwindows.items():
 | 
						|
                if wid == window:
 | 
						|
                    #self.pythonwindowsmenuitem.check(1)
 | 
						|
                    self.openwindowsmenu.menu.CheckMenuItem(item, 1)
 | 
						|
                    self._openwindowscheckmark = item
 | 
						|
                    break
 | 
						|
        else:
 | 
						|
            self._openwindowscheckmark = 0
 | 
						|
        #if self._openwindows:
 | 
						|
        #       self.pythonwindowsmenuitem.enable(1)
 | 
						|
        #else:
 | 
						|
        #       self.pythonwindowsmenuitem.enable(0)
 | 
						|
 | 
						|
    def checkmenus(self, window):
 | 
						|
        for item in self._menustocheck:
 | 
						|
            callback = item.menu.items[item.item-1][2]
 | 
						|
            if type(callback) <> StringType:
 | 
						|
                item.enable(1)
 | 
						|
            elif hasattr(window, "domenu_" + callback):
 | 
						|
                if hasattr(window, "can_" + callback):
 | 
						|
                    canhandler = getattr(window, "can_" + callback)
 | 
						|
                    if canhandler(item):
 | 
						|
                        item.enable(1)
 | 
						|
                    else:
 | 
						|
                        item.enable(0)
 | 
						|
                else:
 | 
						|
                    item.enable(1)
 | 
						|
            else:
 | 
						|
                item.enable(0)
 | 
						|
 | 
						|
    def enablemenubar(self, onoff):
 | 
						|
        for m in self.menubar.menus.values():
 | 
						|
            if onoff:
 | 
						|
                m.menu.EnableMenuItem(0)
 | 
						|
            elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
 | 
						|
                m.menu.DisableMenuItem(0)
 | 
						|
        MenuToolbox.DrawMenuBar()
 | 
						|
 | 
						|
    def makemenubar(self):
 | 
						|
        self.menubar = MenuBar(self)
 | 
						|
        FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
 | 
						|
        self.makeusermenus()
 | 
						|
 | 
						|
    def scriptswalk(self, top, menu, done=None):
 | 
						|
        if menu.id > 200:
 | 
						|
            import W
 | 
						|
            W.Message("Scripts folder not completely traversed: running out of menus")
 | 
						|
            return False
 | 
						|
        if done is None:
 | 
						|
            done = {}
 | 
						|
        if done.has_key(top):
 | 
						|
            return True
 | 
						|
        done[top] = 1
 | 
						|
        import os, string
 | 
						|
        try:
 | 
						|
            names = os.listdir(top)
 | 
						|
        except os.error:
 | 
						|
            FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
 | 
						|
            return True
 | 
						|
        savedir = os.getcwd()
 | 
						|
        os.chdir(top)
 | 
						|
        for name in names:
 | 
						|
            if name == "CVS":
 | 
						|
                continue
 | 
						|
            try:
 | 
						|
                fsr, isdir, isalias = File.FSResolveAliasFile(name, 1)
 | 
						|
            except:
 | 
						|
                # maybe a broken alias
 | 
						|
                continue
 | 
						|
            path = fsr.as_pathname()
 | 
						|
            if done.has_key(path):
 | 
						|
                continue
 | 
						|
            name = string.strip(name)
 | 
						|
            if os.name == "posix":
 | 
						|
                name = unicode(name, "utf-8")
 | 
						|
            if name[-3:] == '---':
 | 
						|
                menu.addseparator()
 | 
						|
            elif isdir:
 | 
						|
                submenu = FrameWork.SubMenu(menu, name)
 | 
						|
                if not self.scriptswalk(path, submenu, done):
 | 
						|
                    return False
 | 
						|
            else:
 | 
						|
                creator, type = MacOS.GetCreatorAndType(path)
 | 
						|
                if type == 'TEXT':
 | 
						|
                    if name[-3:] == '.py':
 | 
						|
                        name = name[:-3]
 | 
						|
                    item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
 | 
						|
                    self._scripts[(menu.id, item.item)] = path
 | 
						|
            done[path] = 1
 | 
						|
        os.chdir(savedir)
 | 
						|
        return True
 | 
						|
 | 
						|
    def domenu_script(self, id, item, window, event):
 | 
						|
        (what, message, when, where, modifiers) = event
 | 
						|
        path = self._scripts[(id, item)]
 | 
						|
        import os
 | 
						|
        if not os.path.exists(path):
 | 
						|
            self.makescriptsmenu()
 | 
						|
            import W
 | 
						|
            raise W.AlertError, "File not found."
 | 
						|
        if ord(Evt.GetKeys()[7]) & 4:
 | 
						|
            self.openscript(path)
 | 
						|
        else:
 | 
						|
            import W, MacOS, sys
 | 
						|
            W.SetCursor("watch")
 | 
						|
            sys.argv = [path]
 | 
						|
            #cwd = os.getcwd()
 | 
						|
            #os.chdir(os.path.dirname(path) + ':')
 | 
						|
            try:
 | 
						|
                # xxx if there is a script window for this file,
 | 
						|
                # exec in that window's namespace.
 | 
						|
                # xxx what to do when it's not saved???
 | 
						|
                # promt to save?
 | 
						|
                if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                    MacOS.EnableAppswitch(0)
 | 
						|
                execfile(path, {'__name__': '__main__', '__file__': path})
 | 
						|
            except W.AlertError, detail:
 | 
						|
                if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                    MacOS.EnableAppswitch(-1)
 | 
						|
                raise W.AlertError, detail
 | 
						|
            except KeyboardInterrupt:
 | 
						|
                if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                    MacOS.EnableAppswitch(-1)
 | 
						|
            except:
 | 
						|
                if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                    MacOS.EnableAppswitch(-1)
 | 
						|
                import PyEdit
 | 
						|
                PyEdit.tracebackwindow.traceback(1)
 | 
						|
            else:
 | 
						|
                if hasattr(MacOS, 'EnableAppswitch'):
 | 
						|
                    MacOS.EnableAppswitch(-1)
 | 
						|
            #os.chdir(cwd)
 | 
						|
 | 
						|
    def openscript(self, filename, lineno=None, charoffset=0, modname=""):
 | 
						|
        import os, PyEdit, W
 | 
						|
        editor = self.getscript(filename)
 | 
						|
        if editor:
 | 
						|
            editor.select()
 | 
						|
        elif os.path.exists(filename):
 | 
						|
            editor = PyEdit.Editor(filename)
 | 
						|
        elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
 | 
						|
            import imp
 | 
						|
            if not modname:
 | 
						|
                if filename[-1] == 'c':
 | 
						|
                    modname = os.path.basename(filename)[:-4]
 | 
						|
                else:
 | 
						|
                    modname = os.path.basename(filename)[:-3]
 | 
						|
            try:
 | 
						|
                # XXX This does not work correctly with packages!
 | 
						|
                # XXX The docs say we should do it manually, pack, then sub, then sub2 etc.
 | 
						|
                # XXX It says we should use imp.load_module(), but that *reloads* a package,
 | 
						|
                # XXX and that's the last thing we want here.
 | 
						|
                f, filename, (suff, mode, dummy) = imp.find_module(modname)
 | 
						|
            except ImportError:
 | 
						|
                raise W.AlertError, "Can't find file for \"%s\"" % modname
 | 
						|
            else:
 | 
						|
                if not f:
 | 
						|
                    raise W.AlertError, "Can't find file for \"%s\"" % modname
 | 
						|
                f.close()
 | 
						|
            if suff == '.py':
 | 
						|
                self.openscript(filename, lineno, charoffset)
 | 
						|
                return
 | 
						|
            else:
 | 
						|
                raise W.AlertError, "Can't find file for \"%s\"" % modname
 | 
						|
        else:
 | 
						|
            raise W.AlertError, "Can't find file \"%s\"" % filename
 | 
						|
        if lineno is not None:
 | 
						|
            editor.selectline(lineno, charoffset)
 | 
						|
        return editor
 | 
						|
 | 
						|
    def getscript(self, filename):
 | 
						|
        if filename[:1] == '<' and filename[-1:] == '>':
 | 
						|
            filename = filename[1:-1]
 | 
						|
        import string
 | 
						|
        lowpath = string.lower(filename)
 | 
						|
        for wid, window in self._windows.items():
 | 
						|
            if hasattr(window, "path") and type(window.path) == StringType and \
 | 
						|
                            lowpath == string.lower(window.path):
 | 
						|
                return window
 | 
						|
            elif hasattr(window, "path") and filename == wid.GetWTitle():
 | 
						|
                return window
 | 
						|
 | 
						|
    def getprefs(self):
 | 
						|
        import MacPrefs
 | 
						|
        return MacPrefs.GetPrefs(self.preffilepath)
 | 
						|
 | 
						|
    def do_editorprefs(self, *args):
 | 
						|
        import PyEdit
 | 
						|
        PyEdit.EditorDefaultSettings()
 | 
						|
 | 
						|
    def do_setwindowfont(self, *args):
 | 
						|
        import FontSettings, W
 | 
						|
        prefs = self.getprefs()
 | 
						|
        settings = FontSettings.FontDialog(prefs.defaultfont)
 | 
						|
        if settings:
 | 
						|
            prefs.defaultfont, tabsettings = settings
 | 
						|
            raise W.AlertError, "Note that changes will only affect new windows!"
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class MenuBar(FrameWork.MenuBar):
 | 
						|
 | 
						|
    possibleIDs = range(10, 256)
 | 
						|
 | 
						|
    def getnextid(self):
 | 
						|
        id = self.possibleIDs[0]
 | 
						|
        del self.possibleIDs[0]
 | 
						|
        return id
 | 
						|
 | 
						|
    def __init__(self, parent = None):
 | 
						|
        self.bar = MenuToolbox.GetMenuBar()
 | 
						|
        MenuToolbox.ClearMenuBar()
 | 
						|
        self.menus = {}
 | 
						|
        self.parent = parent
 | 
						|
 | 
						|
    def dispatch(self, id, item, window, event):
 | 
						|
        if self.menus.has_key(id):
 | 
						|
            self.menus[id].dispatch(id, item, window, event)
 | 
						|
 | 
						|
    def delmenu(self, id):
 | 
						|
        MenuToolbox.DeleteMenu(id)
 | 
						|
        if id in self.possibleIDs:
 | 
						|
            print "XXX duplicate menu ID!", id
 | 
						|
        self.possibleIDs.append(id)
 | 
						|
 | 
						|
 | 
						|
class Menu(FrameWork.Menu):
 | 
						|
 | 
						|
    def dispatch(self, id, item, window, event):
 | 
						|
        title, shortcut, callback, kind = self.items[item-1]
 | 
						|
        if type(callback) == StringType:
 | 
						|
            callback = self._getmenuhandler(callback)
 | 
						|
        if callback:
 | 
						|
            import W
 | 
						|
            W.CallbackCall(callback, 0, id, item, window, event)
 | 
						|
 | 
						|
    def _getmenuhandler(self, callback):
 | 
						|
        menuhandler = None
 | 
						|
        wid = MyFrontWindow()
 | 
						|
        if wid and self.bar.parent._windows.has_key(wid):
 | 
						|
            window = self.bar.parent._windows[wid]
 | 
						|
            if hasattr(window, "domenu_" + callback):
 | 
						|
                menuhandler = getattr(window, "domenu_" + callback)
 | 
						|
            elif hasattr(self.bar.parent, "domenu_" + callback):
 | 
						|
                menuhandler = getattr(self.bar.parent, "domenu_" + callback)
 | 
						|
        elif hasattr(self.bar.parent, "domenu_" + callback):
 | 
						|
            menuhandler = getattr(self.bar.parent, "domenu_" + callback)
 | 
						|
        return menuhandler
 |