mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00

code (if it isn't open already). PythonIDE still opens the resource file "manually" because it also uses presence of the CURS resource to determine whether it needs to adjust sys.path.
465 lines
13 KiB
Python
465 lines
13 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
|
|
|
|
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 %s; 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)
|
|
apply(handler, args)
|
|
return 1
|
|
|
|
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-" +`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
|
|
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 done is None:
|
|
done = {}
|
|
if done.has_key(top):
|
|
return
|
|
done[top] = 1
|
|
import os, macfs, string
|
|
try:
|
|
names = os.listdir(top)
|
|
except os.error:
|
|
FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
|
|
return
|
|
savedir = os.getcwd()
|
|
os.chdir(top)
|
|
for name in names:
|
|
if name == "CVS":
|
|
continue
|
|
try:
|
|
fss, isdir, isalias = macfs.ResolveAliasFile(name)
|
|
except:
|
|
# maybe a broken alias
|
|
continue
|
|
path = fss.as_pathname()
|
|
if done.has_key(path):
|
|
continue
|
|
name = string.strip(name)
|
|
if name[-3:] == '---':
|
|
menu.addseparator()
|
|
elif isdir:
|
|
submenu = FrameWork.SubMenu(menu, name)
|
|
self.scriptswalk(path, submenu, done)
|
|
else:
|
|
creator, type = fss.GetCreatorType()
|
|
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)
|
|
|
|
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
|
|
|