Merged revisions 46607-46608 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r46607 | neal.norwitz | 2006-06-03 06:49:00 +0200 (Sat, 03 Jun 2006) | 1 line Remove Mac OS 9 support (http://mail.python.org/pipermail/python-dev/2006-June/065538.html) ........ r46608 | martin.v.loewis | 2006-06-03 09:37:13 +0200 (Sat, 03 Jun 2006) | 2 lines Port to OpenBSD 3.9. Patch from Aldo Cortesi. ........
This commit is contained in:
parent
4d70c3d9dd
commit
1ba5b3b425
|
@ -1 +0,0 @@
|
||||||
A separator ends with '---'
|
|
|
@ -1,4 +0,0 @@
|
||||||
"""Turn the debugger off."""
|
|
||||||
|
|
||||||
import PyDebugger
|
|
||||||
PyDebugger.cont()
|
|
|
@ -1,5 +0,0 @@
|
||||||
"""This script turns the Python debugger on globally, meaning that
|
|
||||||
it will then stop at any breakpoint you might have defined."""
|
|
||||||
|
|
||||||
import PyDebugger
|
|
||||||
PyDebugger.startfrombottom()
|
|
|
@ -1,22 +0,0 @@
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import macfs
|
|
||||||
|
|
||||||
def walk(top):
|
|
||||||
names = os.listdir(top)
|
|
||||||
for name in names:
|
|
||||||
path = os.path.join(top, name)
|
|
||||||
if os.path.isdir(path):
|
|
||||||
walk(path)
|
|
||||||
else:
|
|
||||||
if path[-4:] in ['.pyc', '.pyo'] and os.path.exists(path[:-1]):
|
|
||||||
print "deleting:", path
|
|
||||||
os.remove(path)
|
|
||||||
elif path[-4:] == '.pyc':
|
|
||||||
print "!!! ------ .pyc file without .py file:", path
|
|
||||||
elif path[-4:] == '.pyo':
|
|
||||||
print "!!! ------ .pyo file without .py file:", path
|
|
||||||
|
|
||||||
fss, ok = macfs.GetDirectory('Select the starting folder:')
|
|
||||||
if ok:
|
|
||||||
walk(fss.as_pathname())
|
|
|
@ -1,45 +0,0 @@
|
||||||
import aetools
|
|
||||||
import Standard_Suite
|
|
||||||
import Required_Suite
|
|
||||||
import MacOS
|
|
||||||
import W
|
|
||||||
|
|
||||||
|
|
||||||
class Toolbox(aetools.TalkTo, Standard_Suite.Standard_Suite):
|
|
||||||
|
|
||||||
def LookupTopic(self, _object, _attributes={}, **_arguments):
|
|
||||||
_code = 'DanR'
|
|
||||||
_subcode = 'REF '
|
|
||||||
|
|
||||||
_arguments['----'] = _object
|
|
||||||
|
|
||||||
_reply, _arguments, _attributes = self.send(_code, _subcode,
|
|
||||||
_arguments, _attributes)
|
|
||||||
if _arguments.has_key('errn'):
|
|
||||||
raise MacOS.Error, aetools.decodeerror(_arguments)
|
|
||||||
|
|
||||||
|
|
||||||
class ToolboxAssi:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.talker = None
|
|
||||||
self.w = W.Window((200, 100), "Toolbox Assistant")
|
|
||||||
self.w.button = W.Button((-94, -32, 80, 16), "Lookup", self.lookup)
|
|
||||||
self.w.prompt = W.TextBox((10, 8, -10, 15), "Enter topic:")
|
|
||||||
self.w.edit = W.EditText((10, 24, -10, 20))
|
|
||||||
self.w.setdefaultbutton(self.w.button)
|
|
||||||
self.w.open()
|
|
||||||
|
|
||||||
def lookup(self):
|
|
||||||
if self.talker is None:
|
|
||||||
try:
|
|
||||||
self.talker = Toolbox('ALTV', start = 1)
|
|
||||||
except:
|
|
||||||
raise W.AlertError, "CanÕt find –Toolbox Assistant”"
|
|
||||||
lookup = self.w.edit.get()
|
|
||||||
try:
|
|
||||||
self.talker.LookupTopic(lookup)
|
|
||||||
except MacOS.Error, detail:
|
|
||||||
W.Message("Requested topic not found.\r(%d)" % detail[0])
|
|
||||||
|
|
||||||
t = ToolboxAssi()
|
|
|
@ -1,4 +0,0 @@
|
||||||
"Hold the option key to open a script instead of running it."
|
|
||||||
|
|
||||||
import W
|
|
||||||
W.Message(__doc__)
|
|
|
@ -1,6 +0,0 @@
|
||||||
import macfs
|
|
||||||
|
|
||||||
fss, ok = macfs.StandardGetFile()
|
|
||||||
if ok:
|
|
||||||
import W
|
|
||||||
W.FrontWindowInsert('"%s"' % fss.as_pathname())
|
|
|
@ -1,6 +0,0 @@
|
||||||
import macfs
|
|
||||||
|
|
||||||
fss, ok = macfs.GetDirectory()
|
|
||||||
if ok:
|
|
||||||
import W
|
|
||||||
W.FrontWindowInsert('"%s"' % fss.as_pathname())
|
|
|
@ -1,4 +0,0 @@
|
||||||
import PyDocSearch
|
|
||||||
# set the creator of the browser. 'MSIE' = Exploser, 'MOSS' = Netscape
|
|
||||||
PyDocSearch.SIGNATURE = 'MOSS'
|
|
||||||
pds = PyDocSearch.PyDocSearch()
|
|
|
@ -1,21 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
# this demoscript illustrates how to tie a callback to activating or clicking away of the window.
|
|
||||||
# evb 22 4 99
|
|
||||||
|
|
||||||
class ActivateDemo:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.w = W.Window((200, 200), 'Activate demo')
|
|
||||||
self.w.bind("<activate>", self.my_activate_callback)
|
|
||||||
self.w.open()
|
|
||||||
|
|
||||||
def my_activate_callback(self, onoff):
|
|
||||||
'''the callback gets 1 parameter which indicates whether the window
|
|
||||||
has been activated (1) or clicked to the back (0)'''
|
|
||||||
if onoff == 1:
|
|
||||||
print "I'm in the front now!"
|
|
||||||
else:
|
|
||||||
print "I've been clicked away, Oh No!"
|
|
||||||
|
|
||||||
ad = ActivateDemo()
|
|
|
@ -1,34 +0,0 @@
|
||||||
"""Simple W demo -- shows how to make a window, and bind a function to a "key" event."""
|
|
||||||
|
|
||||||
import W
|
|
||||||
|
|
||||||
# key callback function
|
|
||||||
def tester(char, event):
|
|
||||||
text = "%r\r%d\r%s\r%s" % (char, ord(char), hex(ord(chart)), oct(ord(char)))
|
|
||||||
window.keys.set(text)
|
|
||||||
|
|
||||||
# close callback
|
|
||||||
def close():
|
|
||||||
window.close()
|
|
||||||
|
|
||||||
# new window
|
|
||||||
window = W.Dialog((180, 100), "Type a character")
|
|
||||||
|
|
||||||
# make a frame (a simple rectangle)
|
|
||||||
window.frame = W.Frame((5, 5, -5, -33))
|
|
||||||
|
|
||||||
# some labels, static text
|
|
||||||
window.captions = W.TextBox((10, 9, 43, -36), "char:\rdecimal:\rhex:\roctal:")
|
|
||||||
|
|
||||||
# another static text box
|
|
||||||
window.keys = W.TextBox((60, 9, 40, -36))
|
|
||||||
|
|
||||||
# a button
|
|
||||||
window.button = W.Button((-69, -24, 60, 16), "Done", close)
|
|
||||||
|
|
||||||
# bind the callbacks
|
|
||||||
window.bind("<key>", tester)
|
|
||||||
window.bind("cmdw", window.button.push)
|
|
||||||
|
|
||||||
# open the window
|
|
||||||
window.open()
|
|
|
@ -1,17 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
def listhit(isdbl):
|
|
||||||
if isdbl:
|
|
||||||
print "double-click in list!"
|
|
||||||
else:
|
|
||||||
print "click in list."
|
|
||||||
|
|
||||||
window = W.Window((200, 400), "Window with List", minsize = (150, 200))
|
|
||||||
|
|
||||||
window.list = W.List((-1, 20, 1, -14), [], listhit)
|
|
||||||
|
|
||||||
# or (equivalent):
|
|
||||||
# window.list = W.List((-1, 20, 1, -14), callback = listhit)
|
|
||||||
|
|
||||||
window.list.set(range(13213, 13350))
|
|
||||||
window.open()
|
|
|
@ -1,10 +0,0 @@
|
||||||
import W
|
|
||||||
from Carbon import Windows
|
|
||||||
|
|
||||||
|
|
||||||
w = W.ModalDialog((100, 100))
|
|
||||||
|
|
||||||
w.ed = W.EditText((10, 10, 80, 50))
|
|
||||||
w.ok = W.Button((10, 70, 80, 16), "Ok", w.close)
|
|
||||||
w.setdefaultbutton(w.ok)
|
|
||||||
w.open()
|
|
|
@ -1,14 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
w = W.Window((600, 400), "Ha!", minsize = (240, 200))
|
|
||||||
|
|
||||||
w.panes = W.HorizontalPanes((8, 8, -30, -8), (0.3, 0.3, 0.4))
|
|
||||||
w.panes.blah1 = W.EditText(None, "eehhh...")
|
|
||||||
w.panes.blah2 = W.EditText((8, 8, -8, -8), "xxx nou...")
|
|
||||||
w.panes.panes = W.VerticalPanes(None, (0.3, 0.4, 0.3))
|
|
||||||
w.panes.panes.blah1 = W.EditText(None, "eehhh...")
|
|
||||||
w.panes.panes.blah2 = W.Frame(None)
|
|
||||||
w.panes.panes.blah2.t = W.EditText((0, 0, 0, 0), "nou...")
|
|
||||||
w.panes.panes.blah3 = W.List(None, ["eehhh...", 'abc', 'def'])
|
|
||||||
|
|
||||||
w.open()
|
|
|
@ -1,16 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
w = W.Window((600, 400), "Ha!", minsize = (240, 200))
|
|
||||||
|
|
||||||
w.panes = W.HorizontalPanes((8, 8, -8, -20), (0.6, 0.4))
|
|
||||||
|
|
||||||
w.panes.panes = W.VerticalPanes(None, (0.3, 0.4, 0.3))
|
|
||||||
w.panes.panes.blah1 = W.EditText(None, "eehhh...")
|
|
||||||
w.panes.panes.blah2 = W.EditText(None, "nou...")
|
|
||||||
w.panes.panes.blah3 = W.List(None, ["eehhh...", 'abc', 'def'])
|
|
||||||
|
|
||||||
w.panes.group = W.Group(None)
|
|
||||||
w.panes.group.mytext = W.EditText((0, 24, 0, 0), "eehhh...")
|
|
||||||
w.panes.group.button1 = W.Button((0, 0, 80, 16), "A Button")
|
|
||||||
|
|
||||||
w.open()
|
|
|
@ -1,17 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
# make a non-sizable window
|
|
||||||
#window = W.Window((200, 200), "Fixed Size")
|
|
||||||
|
|
||||||
# make a sizable window
|
|
||||||
window = W.Window((200, 300), "Variable Size!", minsize = (200, 200))
|
|
||||||
|
|
||||||
# make some edit text widgets
|
|
||||||
# a scrollbar
|
|
||||||
window.hbar = W.Scrollbar((-1, -15, -14, 16), max = 100)
|
|
||||||
window.vbar = W.Scrollbar((-15, -1, 16, -14), max = 100)
|
|
||||||
#window.vbar = W.Scrollbar((-15, -1, 1, -14), max = 100)
|
|
||||||
|
|
||||||
|
|
||||||
# open the window
|
|
||||||
window.open()
|
|
|
@ -1,22 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
def twothird(width, height):
|
|
||||||
return (8, 8, width - 8, 2*height/3 - 4)
|
|
||||||
|
|
||||||
def onethird(width, height):
|
|
||||||
return (8, 2*height/3 + 4, width - 8, height - 22)
|
|
||||||
|
|
||||||
def halfbounds1(width, height):
|
|
||||||
return (0, 0, width/2 - 4, height)
|
|
||||||
|
|
||||||
def halfbounds2(width, height):
|
|
||||||
return (width/2 + 4, 0, width, height)
|
|
||||||
|
|
||||||
window = W.Window((400, 400), "Sizable window with two lists", minsize = (200, 200))
|
|
||||||
|
|
||||||
window.listgroup = W.Group(twothird)
|
|
||||||
window.listgroup.list1 = W.List(halfbounds1, range(13213, 13310))
|
|
||||||
window.listgroup.list2 = W.List(halfbounds2, range(800, 830))
|
|
||||||
window.et = W.EditText(onethird, "Wat nu weer?")
|
|
||||||
|
|
||||||
window.open()
|
|
|
@ -1,85 +0,0 @@
|
||||||
import W
|
|
||||||
|
|
||||||
# define some callbacks
|
|
||||||
def callback():
|
|
||||||
window.close()
|
|
||||||
|
|
||||||
def checkcallback(value):
|
|
||||||
print "hit the checkbox", value
|
|
||||||
|
|
||||||
def radiocallback(value):
|
|
||||||
print "hit radiobutton #3", value
|
|
||||||
|
|
||||||
def scrollcallback(value):
|
|
||||||
widget = window.hbar
|
|
||||||
if value == "+":
|
|
||||||
widget.set(widget.get() - 1)
|
|
||||||
elif value == "-":
|
|
||||||
widget.set(widget.get() + 1)
|
|
||||||
elif value == "++":
|
|
||||||
widget.set(widget.get() - 10)
|
|
||||||
elif value == "--":
|
|
||||||
widget.set(widget.get() + 10)
|
|
||||||
else: # in thumb
|
|
||||||
widget.set(value)
|
|
||||||
print "scroll...", widget.get()
|
|
||||||
|
|
||||||
def textcallback():
|
|
||||||
window.et3.set(window.et1.get())
|
|
||||||
|
|
||||||
def cancel():
|
|
||||||
import EasyDialogs
|
|
||||||
EasyDialogs.Message("Cancel!")
|
|
||||||
|
|
||||||
# make a non-sizable window
|
|
||||||
#window = W.Window((200, 300), "Fixed Size")
|
|
||||||
|
|
||||||
# make a sizable window
|
|
||||||
window = W.Window((200, 300), "Variable Size!", minsize = (200, 300))
|
|
||||||
|
|
||||||
# make some edit text widgets
|
|
||||||
window.et1 = W.EditText((10, 10, 110, 110), "Hallo!", textcallback)
|
|
||||||
window.et2 = W.EditText((130, 40, 60, 30), "one!")
|
|
||||||
window.et3 = W.EditText((130, 80, -10, 40), "two?")
|
|
||||||
|
|
||||||
# a button
|
|
||||||
window.button = W.Button((-70, 10, 60, 16), "Close", callback)
|
|
||||||
|
|
||||||
# a checkbox
|
|
||||||
window.ch = W.CheckBox((10, 130, 160, 16), "Check (command \xa4)", checkcallback)
|
|
||||||
|
|
||||||
# set of radio buttons (should become easier/nicer)
|
|
||||||
thebuttons = []
|
|
||||||
window.r1 = W.RadioButton((10, 150, 180, 16), "Radio 1 (cmd 1)", thebuttons)
|
|
||||||
window.r2 = W.RadioButton((10, 170, 180, 16), "Radio 2 (cmd 2)", thebuttons)
|
|
||||||
window.r3 = W.RadioButton((10, 190, 180, 16), "Radio 3 (cmd 3)", thebuttons, radiocallback)
|
|
||||||
window.r1.set(1)
|
|
||||||
|
|
||||||
# a normal button
|
|
||||||
window.cancelbutton = W.Button((10, 220, 60, 16), "Cancel", cancel)
|
|
||||||
|
|
||||||
# a scrollbar
|
|
||||||
window.hbar = W.Scrollbar((-1, -15, -14, 16), scrollcallback, max = 100)
|
|
||||||
|
|
||||||
# some static text
|
|
||||||
window.static = W.TextBox((10, 260, 110, 16), "Schtatic")
|
|
||||||
|
|
||||||
# bind some keystrokes to functions
|
|
||||||
window.bind('cmd\xa4', window.ch.push)
|
|
||||||
window.bind('cmd1', window.r1.push)
|
|
||||||
window.bind('cmd2', window.r2.push)
|
|
||||||
window.bind('cmd3', window.r3.push)
|
|
||||||
window.bind('cmdw', window.button.push)
|
|
||||||
window.bind('cmd.', window.cancelbutton.push)
|
|
||||||
|
|
||||||
window.setdefaultbutton(window.button)
|
|
||||||
# open the window
|
|
||||||
window.open()
|
|
||||||
|
|
||||||
if 0:
|
|
||||||
import time
|
|
||||||
for i in range(20):
|
|
||||||
window.et2.set(repr(i))
|
|
||||||
#window.et2.SetPort()
|
|
||||||
#window.et2.draw()
|
|
||||||
time.sleep(0.1)
|
|
|
@ -1 +0,0 @@
|
||||||
A separator ends with '---'
|
|
|
@ -1,29 +0,0 @@
|
||||||
Set Defines "-d MPW -d HAVE_CONFIG_H"
|
|
||||||
Set Includes "-i :: -i ::Include -i ::Mac"
|
|
||||||
Set SymOptions "-sym off"
|
|
||||||
Set ModelOptions "-model far"
|
|
||||||
Set OtherOptions "-warnings off"
|
|
||||||
Set LinkOptions "{SymOptions} {ModelOptions}"
|
|
||||||
Set COptions "{OtherOptions} {SymOptions} {ModelOptions} {Defines} {Includes}"
|
|
||||||
# For compiling code resources; Restrictions apply
|
|
||||||
Set ResCOptions "{SymOptions} -model near -b {Defines} {Includes} "
|
|
||||||
|
|
||||||
Export ResCOptions
|
|
||||||
Export COptions
|
|
||||||
Export LinkOptions
|
|
||||||
|
|
||||||
# modules with the source in a single sub directory
|
|
||||||
Date
|
|
||||||
Directory {Python}
|
|
||||||
for MODULE in Parser Mac Modules Objects Python
|
|
||||||
Directory :{MODULE}:
|
|
||||||
Echo "### `Directory`: make {1}"
|
|
||||||
make {1} > makefile.out
|
|
||||||
makefile.out
|
|
||||||
Directory ::
|
|
||||||
end
|
|
||||||
|
|
||||||
Echo "### `Directory`: make {1}"
|
|
||||||
make {1} > makefile.out
|
|
||||||
makefile.out
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
"""Build a "big" applet for the IDE, and put it in the Python home
|
|
||||||
directory. It will contain all IDE-specific modules as PYC resources,
|
|
||||||
which reduces the startup time (especially on slower machines)."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import buildtools
|
|
||||||
from Carbon import Res
|
|
||||||
import py_resource
|
|
||||||
|
|
||||||
buildtools.DEBUG=1
|
|
||||||
|
|
||||||
template = buildtools.findtemplate()
|
|
||||||
|
|
||||||
ide_home = os.path.join(sys.exec_prefix, ":Mac:Tools:IDE")
|
|
||||||
|
|
||||||
mainfilename = os.path.join(ide_home, "PythonIDE.py")
|
|
||||||
dstfilename = os.path.join(sys.exec_prefix, "Python IDE")
|
|
||||||
|
|
||||||
buildtools.process(template, mainfilename, dstfilename, 1)
|
|
||||||
|
|
||||||
targetref = Res.FSpOpenResFile(dstfilename, 3)
|
|
||||||
Res.UseResFile(targetref)
|
|
||||||
|
|
||||||
files = os.listdir(ide_home)
|
|
||||||
|
|
||||||
# skip this script and the main program
|
|
||||||
files = filter(lambda x: x[-3:] == '.py' and
|
|
||||||
x not in ("BuildIDE.py", "PythonIDE.py"), files)
|
|
||||||
|
|
||||||
# add the modules as PYC resources
|
|
||||||
for name in files:
|
|
||||||
print "adding", name
|
|
||||||
fullpath = os.path.join(ide_home, name)
|
|
||||||
id, name = py_resource.frompyfile(fullpath, name[:-3], preload=1,
|
|
||||||
ispackage=0)
|
|
||||||
|
|
||||||
# add W resources
|
|
||||||
wresref = Res.FSpOpenResFile(os.path.join(ide_home, "Widgets.rsrc"), 1)
|
|
||||||
buildtools.copyres(wresref, targetref, [], 0)
|
|
|
@ -1,223 +0,0 @@
|
||||||
"""usage:
|
|
||||||
newsettings = FontDialog(('Chicago', 0, 12, (0, 0, 0))) # font name or id, style flags, size, color (color is ignored)
|
|
||||||
if newsettings:
|
|
||||||
fontsettings, tabsettings = newsettings
|
|
||||||
font, style, size, color = fontsettings # 'font' is always the font name, not the id number
|
|
||||||
# do something
|
|
||||||
"""
|
|
||||||
|
|
||||||
import W
|
|
||||||
import PyEdit
|
|
||||||
from Carbon import TextEdit
|
|
||||||
from Carbon import Qd
|
|
||||||
import string
|
|
||||||
import types
|
|
||||||
import sys
|
|
||||||
import MacOS
|
|
||||||
if hasattr(MacOS, "SysBeep"):
|
|
||||||
SysBeep = MacOS.SysBeep
|
|
||||||
else:
|
|
||||||
def SysBeep(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
_stylenames = ["Plain", "Bold", "Italic", "Underline", "Outline", "Shadow", "Condensed", "Extended"]
|
|
||||||
|
|
||||||
|
|
||||||
class _FontDialog:
|
|
||||||
|
|
||||||
#def __del__(self):
|
|
||||||
# print "doei!"
|
|
||||||
|
|
||||||
def __init__(self, fontsettings, tabsettings):
|
|
||||||
leftmargin = 60
|
|
||||||
leftmargin2 = leftmargin - 16
|
|
||||||
self.w = W.ModalDialog((440, 180), 'Font settings')
|
|
||||||
self.w.fonttitle = W.TextBox((10, 12, leftmargin2, 14), "Font:", TextEdit.teJustRight)
|
|
||||||
self.w.pop = W.FontMenu((leftmargin, 10, 16, 16), self.setfont)
|
|
||||||
self.w.fontname = W.TextBox((leftmargin + 20, 12, 150, 14))
|
|
||||||
self.w.sizetitle = W.TextBox((10, 38, leftmargin2, 14), "Size:", TextEdit.teJustRight)
|
|
||||||
self.w.sizeedit = W.EditText((leftmargin, 35, 40, 20), "", self.checksize)
|
|
||||||
styletop = 64
|
|
||||||
self.w.styletitle = W.TextBox((10, styletop + 2, leftmargin2, 14), "Style:", TextEdit.teJustRight)
|
|
||||||
for i in range(len(_stylenames)):
|
|
||||||
top = styletop + (i % 4) * 20
|
|
||||||
left = leftmargin + 80 * (i > 3) - 2
|
|
||||||
if i:
|
|
||||||
self.w[i] = W.CheckBox((left, top, 76, 16), _stylenames[i], self.dostyle)
|
|
||||||
else:
|
|
||||||
self.w[i] = W.CheckBox((left, top, 70, 16), _stylenames[i], self.doplain)
|
|
||||||
|
|
||||||
if tabsettings:
|
|
||||||
self.lasttab, self.tabmode = tabsettings
|
|
||||||
self.w.tabsizetitle = W.TextBox((10, -26, leftmargin2, 14), "Tabsize:", TextEdit.teJustRight)
|
|
||||||
self.w.tabsizeedit = W.EditText((leftmargin, -29, 40, 20), "", self.checktab)
|
|
||||||
self.w.tabsizeedit.set(repr(self.lasttab))
|
|
||||||
radiobuttons = []
|
|
||||||
self.w.tabsizechars = W.RadioButton((leftmargin + 48, -26, 55, 14), "Spaces",
|
|
||||||
radiobuttons, self.toggletabmode)
|
|
||||||
self.w.tabsizepixels = W.RadioButton((leftmargin + 110, -26, 55, 14), "Pixels",
|
|
||||||
radiobuttons, self.toggletabmode)
|
|
||||||
if self.tabmode:
|
|
||||||
self.w.tabsizechars.set(1)
|
|
||||||
else:
|
|
||||||
self.w.tabsizepixels.set(1)
|
|
||||||
else:
|
|
||||||
self.tabmode = None
|
|
||||||
|
|
||||||
self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
|
|
||||||
self.w.donebutton = W.Button((-90, -26, 80, 16), "Done", self.done)
|
|
||||||
|
|
||||||
sampletext = "Sample text."
|
|
||||||
self.w.sample = W.EditText((230, 10, -10, 130), sampletext,
|
|
||||||
fontsettings = fontsettings, tabsettings = tabsettings)
|
|
||||||
|
|
||||||
self.w.setdefaultbutton(self.w.donebutton)
|
|
||||||
self.w.bind('cmd.', self.w.cancelbutton.push)
|
|
||||||
self.w.bind('cmdw', self.w.donebutton.push)
|
|
||||||
self.lastsize = fontsettings[2]
|
|
||||||
self._rv = None
|
|
||||||
self.set(fontsettings)
|
|
||||||
self.w.open()
|
|
||||||
|
|
||||||
def toggletabmode(self, onoff):
|
|
||||||
if self.w.tabsizechars.get():
|
|
||||||
tabmode = 1
|
|
||||||
else:
|
|
||||||
tabmode = 0
|
|
||||||
if self.tabmode <> tabmode:
|
|
||||||
port = self.w.wid.GetWindowPort()
|
|
||||||
(font, style, size, color), (tabsize, dummy) = self.get()
|
|
||||||
savesettings = W.GetPortFontSettings(port)
|
|
||||||
W.SetPortFontSettings(port, (font, style, size))
|
|
||||||
spacewidth = Qd.StringWidth(' ')
|
|
||||||
W.SetPortFontSettings(port, savesettings)
|
|
||||||
if tabmode:
|
|
||||||
# convert pixels to spaces
|
|
||||||
self.lasttab = int(round(float(tabsize) / spacewidth))
|
|
||||||
else:
|
|
||||||
# convert spaces to pixels
|
|
||||||
self.lasttab = spacewidth * tabsize
|
|
||||||
self.w.tabsizeedit.set(repr(self.lasttab))
|
|
||||||
self.tabmode = tabmode
|
|
||||||
self.doit()
|
|
||||||
|
|
||||||
def set(self, fontsettings):
|
|
||||||
font, style, size, color = fontsettings
|
|
||||||
if type(font) <> types.StringType:
|
|
||||||
from Carbon import Res
|
|
||||||
res = Res.GetResource('FOND', font)
|
|
||||||
font = res.GetResInfo()[2]
|
|
||||||
self.w.fontname.set(font)
|
|
||||||
self.w.sizeedit.set(str(size))
|
|
||||||
if style:
|
|
||||||
for i in range(1, len(_stylenames)):
|
|
||||||
self.w[i].set(style & 0x01)
|
|
||||||
style = style >> 1
|
|
||||||
else:
|
|
||||||
self.w[0].set(1)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
font = self.w.fontname.get()
|
|
||||||
style = 0
|
|
||||||
if not self.w[0].get():
|
|
||||||
flag = 0x01
|
|
||||||
for i in range(1, len(_stylenames)):
|
|
||||||
if self.w[i].get():
|
|
||||||
style = style | flag
|
|
||||||
flag = flag << 1
|
|
||||||
size = self.lastsize
|
|
||||||
if self.tabmode is None:
|
|
||||||
return (font, style, size, (0, 0, 0)), (32, 0)
|
|
||||||
else:
|
|
||||||
return (font, style, size, (0, 0, 0)), (self.lasttab, self.tabmode)
|
|
||||||
|
|
||||||
def doit(self):
|
|
||||||
if self.w[0].get():
|
|
||||||
style = 0
|
|
||||||
else:
|
|
||||||
style = 0
|
|
||||||
for i in range(1, len(_stylenames)):
|
|
||||||
if self.w[i].get():
|
|
||||||
style = style | 2 ** (i - 1)
|
|
||||||
#self.w.sample.set(repr(style))
|
|
||||||
fontsettings, tabsettings = self.get()
|
|
||||||
self.w.sample.setfontsettings(fontsettings)
|
|
||||||
self.w.sample.settabsettings(tabsettings)
|
|
||||||
|
|
||||||
def checktab(self):
|
|
||||||
tabsize = self.w.tabsizeedit.get()
|
|
||||||
if not tabsize:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
tabsize = string.atoi(tabsize)
|
|
||||||
except (ValueError, OverflowError):
|
|
||||||
good = 0
|
|
||||||
sys.exc_traceback = None
|
|
||||||
else:
|
|
||||||
good = 1 <= tabsize <= 500
|
|
||||||
if good:
|
|
||||||
if self.lasttab <> tabsize:
|
|
||||||
self.lasttab = tabsize
|
|
||||||
self.doit()
|
|
||||||
else:
|
|
||||||
SysBeep(0)
|
|
||||||
self.w.tabsizeedit.set(repr(self.lasttab))
|
|
||||||
self.w.tabsizeedit.selectall()
|
|
||||||
|
|
||||||
def checksize(self):
|
|
||||||
size = self.w.sizeedit.get()
|
|
||||||
if not size:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
size = string.atoi(size)
|
|
||||||
except (ValueError, OverflowError):
|
|
||||||
good = 0
|
|
||||||
sys.exc_traceback = None
|
|
||||||
else:
|
|
||||||
good = 1 <= size <= 500
|
|
||||||
if good:
|
|
||||||
if self.lastsize <> size:
|
|
||||||
self.lastsize = size
|
|
||||||
self.doit()
|
|
||||||
else:
|
|
||||||
SysBeep(0)
|
|
||||||
self.w.sizeedit.set(repr(self.lastsize))
|
|
||||||
self.w.sizeedit.selectall()
|
|
||||||
|
|
||||||
def doplain(self):
|
|
||||||
for i in range(1, len(_stylenames)):
|
|
||||||
self.w[i].set(0)
|
|
||||||
self.w[0].set(1)
|
|
||||||
self.doit()
|
|
||||||
|
|
||||||
def dostyle(self):
|
|
||||||
for i in range(1, len(_stylenames)):
|
|
||||||
if self.w[i].get():
|
|
||||||
self.w[0].set(0)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.w[0].set(1)
|
|
||||||
self.doit()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.w.close()
|
|
||||||
del self.w
|
|
||||||
|
|
||||||
def cancel(self):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
self._rv = self.get()
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def setfont(self, fontname):
|
|
||||||
self.w.fontname.set(fontname)
|
|
||||||
self.doit()
|
|
||||||
|
|
||||||
|
|
||||||
def FontDialog(fontsettings, tabsettings = (32, 0)):
|
|
||||||
fd = _FontDialog(fontsettings, tabsettings)
|
|
||||||
return fd._rv
|
|
||||||
|
|
||||||
def test():
|
|
||||||
print FontDialog(('Zapata-Light', 0, 25, (0, 0, 0)))
|
|
|
@ -1,108 +0,0 @@
|
||||||
import marshal
|
|
||||||
import types
|
|
||||||
from Carbon import Folder
|
|
||||||
from Carbon import Folders
|
|
||||||
|
|
||||||
class PrefObject:
|
|
||||||
|
|
||||||
def __init__(self, dict = None):
|
|
||||||
if dict == None:
|
|
||||||
self._prefsdict = {}
|
|
||||||
else:
|
|
||||||
self._prefsdict = dict
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._prefsdict)
|
|
||||||
|
|
||||||
def __delattr__(self, attr):
|
|
||||||
if self._prefsdict.has_key(attr):
|
|
||||||
del self._prefsdict[attr]
|
|
||||||
else:
|
|
||||||
raise AttributeError, 'delete non-existing instance attribute'
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
if attr == '__members__':
|
|
||||||
keys = self._prefsdict.keys()
|
|
||||||
keys.sort()
|
|
||||||
return keys
|
|
||||||
try:
|
|
||||||
return self._prefsdict[attr]
|
|
||||||
except KeyError:
|
|
||||||
raise AttributeError, attr
|
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
|
||||||
if attr[0] <> '_':
|
|
||||||
self._prefsdict[attr] = value
|
|
||||||
else:
|
|
||||||
self.__dict__[attr] = value
|
|
||||||
|
|
||||||
def getprefsdict(self):
|
|
||||||
return self._prefsdict
|
|
||||||
|
|
||||||
|
|
||||||
class PrefFile(PrefObject):
|
|
||||||
|
|
||||||
def __init__(self, path, creator = 'Pyth'):
|
|
||||||
# Find the preferences folder and our prefs file, create if needed.
|
|
||||||
self.__path = path
|
|
||||||
self.__creator = creator
|
|
||||||
self._prefsdict = {}
|
|
||||||
try:
|
|
||||||
prefdict = marshal.load(open(self.__path, 'rb'))
|
|
||||||
except (IOError, ValueError):
|
|
||||||
# file not found, or currupt marshal data
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
for key, value in prefdict.items():
|
|
||||||
if type(value) == types.DictType:
|
|
||||||
self._prefsdict[key] = PrefObject(value)
|
|
||||||
else:
|
|
||||||
self._prefsdict[key] = value
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
prefdict = {}
|
|
||||||
for key, value in self._prefsdict.items():
|
|
||||||
if type(value) == types.InstanceType:
|
|
||||||
prefdict[key] = value.getprefsdict()
|
|
||||||
if not prefdict[key]:
|
|
||||||
del prefdict[key]
|
|
||||||
else:
|
|
||||||
prefdict[key] = value
|
|
||||||
marshal.dump(prefdict, open(self.__path, 'wb'))
|
|
||||||
try:
|
|
||||||
MacOS.SetCreatorAndType(self.__path, self.__creator, 'pref')
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
if attr == '__members__':
|
|
||||||
keys = self._prefsdict.keys()
|
|
||||||
keys.sort()
|
|
||||||
return keys
|
|
||||||
try:
|
|
||||||
return self._prefsdict[attr]
|
|
||||||
except KeyError:
|
|
||||||
if attr[0] <> '_':
|
|
||||||
self._prefsdict[attr] = PrefObject()
|
|
||||||
return self._prefsdict[attr]
|
|
||||||
else:
|
|
||||||
raise AttributeError, attr
|
|
||||||
|
|
||||||
|
|
||||||
_prefscache = {}
|
|
||||||
|
|
||||||
def GetPrefs(prefname, creator = 'Pyth'):
|
|
||||||
import macostools, os
|
|
||||||
if _prefscache.has_key(prefname):
|
|
||||||
return _prefscache[prefname]
|
|
||||||
# Find the preferences folder and our prefs file, create if needed.
|
|
||||||
fsr = Folder.FSFindFolder(Folders.kOnSystemDisk, 'pref', 1)
|
|
||||||
prefsfolder = fsr.as_pathname()
|
|
||||||
path = os.path.join(prefsfolder, prefname)
|
|
||||||
head, tail = os.path.split(path)
|
|
||||||
# make sure the folder(s) exist
|
|
||||||
macostools.mkdirs(head)
|
|
||||||
|
|
||||||
preffile = PrefFile(path, creator)
|
|
||||||
_prefscache[prefname] = preffile
|
|
||||||
return preffile
|
|
|
@ -1,177 +0,0 @@
|
||||||
import W
|
|
||||||
import sys
|
|
||||||
from Carbon import Qd
|
|
||||||
|
|
||||||
__version__ = "0.2"
|
|
||||||
__author__ = "jvr"
|
|
||||||
|
|
||||||
class _modulebrowser:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.editmodules = []
|
|
||||||
self.modules = []
|
|
||||||
self.window = W.Window((210, 1000), "Module Browser", minsize = (210, 160), maxsize = (340, 20000))
|
|
||||||
|
|
||||||
self.window.openbutton = W.Button((10, 8, 90, 16), "Open", self.openbuttonhit)
|
|
||||||
self.window.browsebutton = W.Button((110, 8, 90, 16), "Browse\xc9", self.browsebuttonhit)
|
|
||||||
self.window.reloadbutton = W.Button((10, 32, 90, 16), "Reload", self.reloadbuttonhit)
|
|
||||||
self.window.openotherbutton = W.Button((110, 32, 90, 16), "Open other\xc9", self.openother)
|
|
||||||
|
|
||||||
self.window.openbutton.enable(0)
|
|
||||||
self.window.reloadbutton.enable(0)
|
|
||||||
self.window.browsebutton.enable(0)
|
|
||||||
self.window.setdefaultbutton(self.window.browsebutton)
|
|
||||||
|
|
||||||
self.window.bind("cmdr", self.window.reloadbutton.push)
|
|
||||||
self.window.bind("cmdb", self.window.browsebutton.push)
|
|
||||||
|
|
||||||
self.window.bind("<activate>", self.activate)
|
|
||||||
self.window.bind("<close>", self.close)
|
|
||||||
|
|
||||||
self.window.list = W.List((-1, 56, 1, -14), [], self.listhit)
|
|
||||||
|
|
||||||
self.window.open()
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
global _browser
|
|
||||||
_browser = None
|
|
||||||
|
|
||||||
def activate(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
self.makelist()
|
|
||||||
|
|
||||||
def listhit(self, isdbl):
|
|
||||||
self.checkbuttons()
|
|
||||||
if isdbl:
|
|
||||||
if self.window._defaultbutton:
|
|
||||||
self.window._defaultbutton.push()
|
|
||||||
|
|
||||||
def checkbuttons(self):
|
|
||||||
sel = self.window.list.getselection()
|
|
||||||
if sel:
|
|
||||||
for i in sel:
|
|
||||||
if self.editmodules[i]:
|
|
||||||
self.window.openbutton.enable(1)
|
|
||||||
self.window.reloadbutton.enable(1)
|
|
||||||
self.window.setdefaultbutton(self.window.openbutton)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.window.openbutton.enable(0)
|
|
||||||
self.window.reloadbutton.enable(0)
|
|
||||||
self.window.setdefaultbutton(self.window.browsebutton)
|
|
||||||
self.window.browsebutton.enable(1)
|
|
||||||
else:
|
|
||||||
#self.window.setdefaultbutton(self.window.browsebutton)
|
|
||||||
self.window.openbutton.enable(0)
|
|
||||||
self.window.reloadbutton.enable(0)
|
|
||||||
self.window.browsebutton.enable(0)
|
|
||||||
|
|
||||||
def openbuttonhit(self):
|
|
||||||
import imp
|
|
||||||
sel = self.window.list.getselection()
|
|
||||||
W.SetCursor("watch")
|
|
||||||
for i in sel:
|
|
||||||
modname = self.window.list[i]
|
|
||||||
try:
|
|
||||||
self.openscript(sys.modules[modname].__file__, modname)
|
|
||||||
except IOError:
|
|
||||||
try:
|
|
||||||
file, path, description = imp.find_module(modname)
|
|
||||||
except ImportError:
|
|
||||||
W.SetCursor("arrow")
|
|
||||||
W.Message("Can't find file for module '%s'."
|
|
||||||
% modname)
|
|
||||||
else:
|
|
||||||
self.openscript(path, modname)
|
|
||||||
|
|
||||||
def openscript(self, path, modname):
|
|
||||||
import os
|
|
||||||
if path[-3:] == '.py':
|
|
||||||
W.getapplication().openscript(path, modname=modname)
|
|
||||||
elif path[-4:] in ['.pyc', '.pyo']:
|
|
||||||
W.getapplication().openscript(path[:-1], modname=modname)
|
|
||||||
else:
|
|
||||||
W.Message("Can't edit '%s'; it might be a shared library or a .pyc file."
|
|
||||||
% modname)
|
|
||||||
|
|
||||||
def openother(self):
|
|
||||||
import imp
|
|
||||||
import EasyDialogs
|
|
||||||
|
|
||||||
modname = EasyDialogs.AskString("Open module:")
|
|
||||||
if modname:
|
|
||||||
try:
|
|
||||||
file, path, description = imp.find_module(modname)
|
|
||||||
except ImportError:
|
|
||||||
if modname in sys.builtin_module_names:
|
|
||||||
alerttext = "'%s' is a builtin module, which you can't edit." % modname
|
|
||||||
else:
|
|
||||||
alerttext = "No module named '%s'." % modname
|
|
||||||
raise W.AlertError, alerttext
|
|
||||||
self.openscript(path, modname)
|
|
||||||
|
|
||||||
def reloadbuttonhit(self):
|
|
||||||
sel = self.window.list.getselection()
|
|
||||||
W.SetCursor("watch")
|
|
||||||
for i in sel:
|
|
||||||
mname = self.window.list[i]
|
|
||||||
m = sys.modules[mname]
|
|
||||||
# Set the __name__ attribute of the module to its real name.
|
|
||||||
# reload() complains if it's __main__, which is true
|
|
||||||
# when it recently has been run as a script with "Run as __main__"
|
|
||||||
# enabled.
|
|
||||||
m.__name__ = mname
|
|
||||||
reload(m)
|
|
||||||
|
|
||||||
def browsebuttonhit(self):
|
|
||||||
sel = self.window.list.getselection()
|
|
||||||
if not sel:
|
|
||||||
return
|
|
||||||
import PyBrowser
|
|
||||||
for i in sel:
|
|
||||||
PyBrowser.Browser(sys.modules[self.window.list[i]])
|
|
||||||
|
|
||||||
def makelist(self):
|
|
||||||
editmodules, modules = getmoduleslist()
|
|
||||||
if modules == self.modules:
|
|
||||||
return
|
|
||||||
self.editmodules, self.modules = editmodules, modules
|
|
||||||
self.window.list.setdrawingmode(0)
|
|
||||||
sel = self.window.list.getselectedobjects()
|
|
||||||
self.window.list.set(self.modules)
|
|
||||||
self.window.list.setselectedobjects(sel)
|
|
||||||
self.window.list.setdrawingmode(1)
|
|
||||||
|
|
||||||
|
|
||||||
def getmoduleslist():
|
|
||||||
import PyBrowser # for caselesssort function
|
|
||||||
moduleitems = sys.modules.items()
|
|
||||||
moduleitems = filter(lambda (name, module): module is not None, moduleitems)
|
|
||||||
modules = map(lambda (name, module): name, moduleitems)
|
|
||||||
modules = PyBrowser.caselesssort(modules)
|
|
||||||
editmodules = []
|
|
||||||
sysmodules = sys.modules
|
|
||||||
modulesappend = editmodules.append
|
|
||||||
for m in modules:
|
|
||||||
module = sysmodules[m]
|
|
||||||
try:
|
|
||||||
if sysmodules[m].__file__[-3:] == '.py' or \
|
|
||||||
sysmodules[m].__file__[-4:] in ['.pyc', '.pyo']:
|
|
||||||
modulesappend(1)
|
|
||||||
else:
|
|
||||||
modulesappend(0)
|
|
||||||
except AttributeError:
|
|
||||||
modulesappend(0)
|
|
||||||
return editmodules, modules
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_browser = None
|
|
||||||
|
|
||||||
def ModuleBrowser():
|
|
||||||
global _browser
|
|
||||||
if _browser is not None:
|
|
||||||
_browser.window.select()
|
|
||||||
else:
|
|
||||||
_browser = _modulebrowser()
|
|
Binary file not shown.
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>English</string>
|
|
||||||
<key>CFBundleDocumentTypes</key>
|
|
||||||
<array>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>PackageManager</string>
|
|
||||||
<key>CFBundleGetInfoString</key>
|
|
||||||
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>PackageManager.icns</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>org.python.pythonide</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleLongVersionString</key>
|
|
||||||
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>PythonIDE</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>2.5alpha0</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>Pide</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>2.5alpha0</string>
|
|
||||||
<key>CSResourcesFileMapped</key>
|
|
||||||
<true/>
|
|
||||||
<key>LSRequiresCarbon</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>(c) 2004 Python Software Foundation.</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -1,473 +0,0 @@
|
||||||
# Prelude to allow running this as a main program
|
|
||||||
def _init():
|
|
||||||
import macresource
|
|
||||||
import sys, os
|
|
||||||
macresource.need('DITL', 468, "PythonIDE.rsrc")
|
|
||||||
widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
|
|
||||||
widgetresfile = os.path.join(*widgetrespathsegs)
|
|
||||||
if not os.path.exists(widgetresfile):
|
|
||||||
widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
|
|
||||||
widgetresfile = os.path.join(*widgetrespathsegs)
|
|
||||||
refno = macresource.need('CURS', 468, widgetresfile)
|
|
||||||
if os.environ.has_key('PYTHONIDEPATH'):
|
|
||||||
# For development set this environment variable
|
|
||||||
ide_path = os.environ['PYTHONIDEPATH']
|
|
||||||
elif refno:
|
|
||||||
# We're not a fullblown application
|
|
||||||
idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
|
|
||||||
ide_path = os.path.join(*idepathsegs)
|
|
||||||
if not os.path.exists(ide_path):
|
|
||||||
idepathsegs = [os.pardir, "Tools", "IDE"]
|
|
||||||
for p in sys.path:
|
|
||||||
ide_path = os.path.join(*([p]+idepathsegs))
|
|
||||||
if os.path.exists(ide_path):
|
|
||||||
break
|
|
||||||
|
|
||||||
else:
|
|
||||||
# We are a fully frozen application
|
|
||||||
ide_path = sys.argv[0]
|
|
||||||
if ide_path not in sys.path:
|
|
||||||
sys.path.insert(0, ide_path)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
_init()
|
|
||||||
|
|
||||||
import W
|
|
||||||
import Wapplication
|
|
||||||
from Carbon import Evt
|
|
||||||
import EasyDialogs
|
|
||||||
import FrameWork
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import string
|
|
||||||
import os
|
|
||||||
import urllib
|
|
||||||
|
|
||||||
import pimp
|
|
||||||
|
|
||||||
PACKMAN_HOMEPAGE="http://www.python.org/packman"
|
|
||||||
|
|
||||||
ELIPSES = '...'
|
|
||||||
|
|
||||||
USER_INSTALL_DIR = os.path.join(os.environ.get('HOME', ''),
|
|
||||||
'Library',
|
|
||||||
'Python',
|
|
||||||
sys.version[:3],
|
|
||||||
'site-packages')
|
|
||||||
|
|
||||||
class PackageManagerMain(Wapplication.Application):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.preffilepath = os.path.join("Python", "Package Install Manager Prefs")
|
|
||||||
Wapplication.Application.__init__(self, 'Pimp')
|
|
||||||
from Carbon import AE
|
|
||||||
from Carbon import AppleEvents
|
|
||||||
self.defaulturl = ""
|
|
||||||
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication,
|
|
||||||
self.quitevent)
|
|
||||||
if 1:
|
|
||||||
import PyConsole
|
|
||||||
# With -D option (OSX command line only) keep stderr, for debugging the IDE
|
|
||||||
# itself.
|
|
||||||
debug_stderr = None
|
|
||||||
if len(sys.argv) >= 2 and sys.argv[1] == '-D':
|
|
||||||
debug_stderr = sys.stderr
|
|
||||||
del sys.argv[1]
|
|
||||||
PyConsole.installoutput()
|
|
||||||
if debug_stderr:
|
|
||||||
sys.stderr = debug_stderr
|
|
||||||
self.domenu_openstandard()
|
|
||||||
self.mainloop()
|
|
||||||
|
|
||||||
def makeusermenus(self):
|
|
||||||
m = Wapplication.Menu(self.menubar, "File")
|
|
||||||
newitem = FrameWork.MenuItem(m, "Open Standard Database", "N", 'openstandard')
|
|
||||||
newexpitem = FrameWork.MenuItem(m, "Open Experimental Database", None, 'openexperimental')
|
|
||||||
newexpitem.enable(pimp.PIMP_VERSION >= "0.4")
|
|
||||||
openitem = FrameWork.MenuItem(m, "Open"+ELIPSES, "O", 'open')
|
|
||||||
openURLitem = FrameWork.MenuItem(m, "Open URL"+ELIPSES, "D", 'openURL')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
moreinfoitem = FrameWork.MenuItem(m, "More Databases", None, 'opendatabasepage')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
|
|
||||||
## saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
|
|
||||||
## saveasitem = FrameWork.MenuItem(m, "Save as"+ELIPSES, None, 'save_as')
|
|
||||||
## FrameWork.Separator(m)
|
|
||||||
|
|
||||||
m = Wapplication.Menu(self.menubar, "Edit")
|
|
||||||
undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
|
|
||||||
copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
|
|
||||||
pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
|
|
||||||
FrameWork.MenuItem(m, "Clear", None, "clear")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
|
|
||||||
|
|
||||||
m = Wapplication.Menu(self.menubar, "Package")
|
|
||||||
runitem = FrameWork.MenuItem(m, "Install", "I", 'install')
|
|
||||||
homepageitem = FrameWork.MenuItem(m, "Visit Homepage", None, 'homepage')
|
|
||||||
|
|
||||||
self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
|
|
||||||
self.makeopenwindowsmenu()
|
|
||||||
self.makehelpmenu()
|
|
||||||
self._menustocheck = [closeitem,
|
|
||||||
undoitem, cutitem, copyitem, pasteitem,
|
|
||||||
selallitem,
|
|
||||||
runitem, homepageitem]
|
|
||||||
|
|
||||||
def makehelpmenu(self):
|
|
||||||
python_app = os.path.join(sys.prefix, 'Resources/Python.app')
|
|
||||||
help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
|
|
||||||
hashelp = os.path.isdir(help_source)
|
|
||||||
|
|
||||||
self.helpmenu = m = self.gethelpmenu()
|
|
||||||
helpitem1 = FrameWork.MenuItem(m, "PackageManager Help", None, self.domenu_packmanhelp)
|
|
||||||
helpitem1.enable(hashelp)
|
|
||||||
helpitem2 = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_pythonhelp)
|
|
||||||
helpitem2.enable(hashelp)
|
|
||||||
|
|
||||||
def quitevent(self, theAppleEvent, theReply):
|
|
||||||
self._quit()
|
|
||||||
|
|
||||||
def ignoreevent(self, theAppleEvent, theReply):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def opendocsevent(self, theAppleEvent, theReply):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
import aetools
|
|
||||||
parameters, args = aetools.unpackevent(theAppleEvent)
|
|
||||||
docs = parameters['----']
|
|
||||||
if type(docs) <> type([]):
|
|
||||||
docs = [docs]
|
|
||||||
for doc in docs:
|
|
||||||
fsr, a = doc.FSResolveAlias(None)
|
|
||||||
path = fsr.as_pathname()
|
|
||||||
path = urllib.pathname2url(path)
|
|
||||||
self.opendoc(path)
|
|
||||||
|
|
||||||
def opendoc(self, url):
|
|
||||||
if url:
|
|
||||||
self.defaulturl = url
|
|
||||||
PackageBrowser(url)
|
|
||||||
|
|
||||||
def getabouttext(self):
|
|
||||||
return "About Package Manager"+ELIPSES
|
|
||||||
|
|
||||||
def do_about(self, id, item, window, event):
|
|
||||||
EasyDialogs.Message("Package Install Manager for Python\nPackMan engine (pimp) version: %s" %
|
|
||||||
pimp.PIMP_VERSION)
|
|
||||||
|
|
||||||
def domenu_openstandard(self, *args):
|
|
||||||
if pimp.PIMP_VERSION >= "0.4":
|
|
||||||
url = pimp.getDefaultDatabase()
|
|
||||||
else:
|
|
||||||
# 0.3 compatibility
|
|
||||||
url = None
|
|
||||||
self.opendoc(url)
|
|
||||||
|
|
||||||
def domenu_openexperimental(self, *args):
|
|
||||||
database = pimp.getDefaultDatabase(experimental=True)
|
|
||||||
self.opendoc(database)
|
|
||||||
|
|
||||||
def domenu_open(self, *args):
|
|
||||||
filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
|
|
||||||
if filename:
|
|
||||||
filename = urllib.pathname2url(filename)
|
|
||||||
if filename[:5] != 'file:':
|
|
||||||
filename = 'file:' + filename
|
|
||||||
self.opendoc(filename)
|
|
||||||
|
|
||||||
def domenu_openURL(self, *args):
|
|
||||||
ok = EasyDialogs.AskYesNoCancel(
|
|
||||||
"Warning: by opening a non-standard database "
|
|
||||||
"you are trusting the maintainer of it "
|
|
||||||
"to run arbitrary code on your machine.",
|
|
||||||
yes="OK", no="")
|
|
||||||
if ok <= 0: return
|
|
||||||
url = EasyDialogs.AskString("URL of database to open:",
|
|
||||||
default=self.defaulturl, ok="Open")
|
|
||||||
if url:
|
|
||||||
self.opendoc(url)
|
|
||||||
|
|
||||||
def domenu_opendatabasepage(self):
|
|
||||||
import ic
|
|
||||||
|
|
||||||
icr = ic.IC()
|
|
||||||
icr.launchurl(PACKMAN_HOMEPAGE)
|
|
||||||
def makeopenwindowsmenu(self):
|
|
||||||
for i in range(len(self.openwindowsmenu.items)):
|
|
||||||
self.openwindowsmenu.menu.DeleteMenuItem(1)
|
|
||||||
self.openwindowsmenu.items = []
|
|
||||||
windows = []
|
|
||||||
self._openwindows = {}
|
|
||||||
for window in self._windows.keys():
|
|
||||||
title = window.GetWTitle()
|
|
||||||
if not title:
|
|
||||||
title = "<no title>"
|
|
||||||
windows.append((title, window))
|
|
||||||
windows.sort()
|
|
||||||
for title, window in windows:
|
|
||||||
shortcut = None
|
|
||||||
item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
|
|
||||||
self._openwindows[item.item] = window
|
|
||||||
self._openwindowscheckmark = 0
|
|
||||||
self.checkopenwindowsmenu()
|
|
||||||
|
|
||||||
def domenu_openwindows(self, id, item, window, event):
|
|
||||||
w = self._openwindows[item]
|
|
||||||
w.ShowWindow()
|
|
||||||
w.SelectWindow()
|
|
||||||
|
|
||||||
def domenu_quit(self):
|
|
||||||
self._quit()
|
|
||||||
|
|
||||||
def domenu_save(self, *args):
|
|
||||||
print "Save"
|
|
||||||
|
|
||||||
def domenu_pythonhelp(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHGotoPage("MacPython Help", None, None)
|
|
||||||
|
|
||||||
def domenu_packmanhelp(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHGotoPage("MacPython Help", "packman.html", None)
|
|
||||||
|
|
||||||
def _quit(self):
|
|
||||||
## import PyConsole, PyEdit
|
|
||||||
for window in self._windows.values():
|
|
||||||
try:
|
|
||||||
rv = window.close() # ignore any errors while quitting
|
|
||||||
except:
|
|
||||||
rv = 0 # (otherwise, we can get stuck!)
|
|
||||||
if rv and rv > 0:
|
|
||||||
return
|
|
||||||
## try:
|
|
||||||
## PyConsole.console.writeprefs()
|
|
||||||
## PyConsole.output.writeprefs()
|
|
||||||
## PyEdit.searchengine.writeprefs()
|
|
||||||
## except:
|
|
||||||
## # Write to __stderr__ so the msg end up in Console.app and has
|
|
||||||
## # at least _some_ chance of getting read...
|
|
||||||
## # But: this is a workaround for way more serious problems with
|
|
||||||
## # the Python 2.2 Jaguar addon.
|
|
||||||
## sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
|
|
||||||
self.quitting = 1
|
|
||||||
|
|
||||||
class PimpInterface:
|
|
||||||
|
|
||||||
def setuppimp(self, url):
|
|
||||||
self.pimpprefs = pimp.PimpPreferences()
|
|
||||||
self.pimpdb = pimp.PimpDatabase(self.pimpprefs)
|
|
||||||
if not url:
|
|
||||||
url = self.pimpprefs.pimpDatabase
|
|
||||||
try:
|
|
||||||
self.pimpdb.appendURL(url)
|
|
||||||
except IOError, arg:
|
|
||||||
rv = "Cannot open %s: %s\n" % (url, arg)
|
|
||||||
rv += "\nSee MacPython Package Manager help page."
|
|
||||||
return rv
|
|
||||||
except:
|
|
||||||
rv = "Unspecified error while parsing database: %s\n" % url
|
|
||||||
rv += "Usually, this means the database is not correctly formatted.\n"
|
|
||||||
rv += "\nSee MacPython Package Manager help page."
|
|
||||||
return rv
|
|
||||||
# Check whether we can write the installation directory.
|
|
||||||
# If not, set to the per-user directory, possibly
|
|
||||||
# creating it, if needed.
|
|
||||||
installDir = self.pimpprefs.installDir
|
|
||||||
if not os.access(installDir, os.R_OK|os.W_OK|os.X_OK):
|
|
||||||
rv = self.setuserinstall(1)
|
|
||||||
if rv: return rv
|
|
||||||
return self.pimpprefs.check()
|
|
||||||
|
|
||||||
def closepimp(self):
|
|
||||||
self.pimpdb.close()
|
|
||||||
self.pimpprefs = None
|
|
||||||
self.pimpdb = None
|
|
||||||
self.packages = []
|
|
||||||
|
|
||||||
def setuserinstall(self, onoff):
|
|
||||||
rv = ""
|
|
||||||
if onoff:
|
|
||||||
if not os.path.exists(USER_INSTALL_DIR):
|
|
||||||
try:
|
|
||||||
os.makedirs(USER_INSTALL_DIR)
|
|
||||||
except OSError, arg:
|
|
||||||
rv = rv + arg + "\n"
|
|
||||||
if not USER_INSTALL_DIR in sys.path:
|
|
||||||
import site
|
|
||||||
reload(site)
|
|
||||||
self.pimpprefs.setInstallDir(USER_INSTALL_DIR)
|
|
||||||
else:
|
|
||||||
self.pimpprefs.setInstallDir(None)
|
|
||||||
rv = rv + self.pimpprefs.check()
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def getuserinstall(self):
|
|
||||||
return self.pimpprefs.installDir == USER_INSTALL_DIR
|
|
||||||
|
|
||||||
def getbrowserdata(self, show_hidden=1):
|
|
||||||
packages = self.pimpdb.list()
|
|
||||||
if show_hidden:
|
|
||||||
self.packages = packages
|
|
||||||
else:
|
|
||||||
self.packages = []
|
|
||||||
for pkg in packages:
|
|
||||||
name = pkg.fullname()
|
|
||||||
if name[0] == '(' and name[-1] == ')' and not show_hidden:
|
|
||||||
continue
|
|
||||||
self.packages.append(pkg)
|
|
||||||
rv = []
|
|
||||||
for pkg in self.packages:
|
|
||||||
name = pkg.fullname()
|
|
||||||
status, _ = pkg.installed()
|
|
||||||
description = pkg.description()
|
|
||||||
description_line1 = description.split('\n')[0]
|
|
||||||
rv.append((status, name, description_line1))
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def getstatus(self, number):
|
|
||||||
pkg = self.packages[number]
|
|
||||||
return pkg.installed()
|
|
||||||
|
|
||||||
def installpackage(self, sel, output, recursive, force):
|
|
||||||
pkg = self.packages[sel]
|
|
||||||
pimpinstaller = pimp.PimpInstaller(self.pimpdb)
|
|
||||||
list, messages = pimpinstaller.prepareInstall(pkg, force, recursive)
|
|
||||||
if messages:
|
|
||||||
return messages
|
|
||||||
messages = pimpinstaller.install(list, output)
|
|
||||||
return messages
|
|
||||||
|
|
||||||
class PackageBrowser(PimpInterface):
|
|
||||||
|
|
||||||
def __init__(self, url = None):
|
|
||||||
self.ic = None
|
|
||||||
messages = self.setuppimp(url)
|
|
||||||
self.setupwidgets()
|
|
||||||
self.updatestatus()
|
|
||||||
self.showmessages(messages)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.closepimp()
|
|
||||||
|
|
||||||
def setupwidgets(self):
|
|
||||||
DESCRIPTION_HEIGHT = 140
|
|
||||||
INSTALL_POS = -30
|
|
||||||
STATUS_POS = INSTALL_POS - (70 + DESCRIPTION_HEIGHT)
|
|
||||||
self.w = W.Window((580, 600), "Python Install Manager", minsize = (400, 400), tabbable = 0)
|
|
||||||
self.w.titlebar = W.TextBox((4, 8, 60, 18), 'Packages:')
|
|
||||||
self.w.hidden_button = W.CheckBox((-100, 4, 0, 18), 'Show Hidden', self.updatestatus)
|
|
||||||
data = self.getbrowserdata()
|
|
||||||
self.w.packagebrowser = W.MultiList((4, 24, 0, STATUS_POS-2), data, self.listhit, cols=3)
|
|
||||||
|
|
||||||
self.w.installed_l = W.TextBox((4, STATUS_POS, 70, 12), 'Installed:')
|
|
||||||
self.w.installed = W.TextBox((74, STATUS_POS, 0, 12), '')
|
|
||||||
self.w.message_l = W.TextBox((4, STATUS_POS+20, 70, 12), 'Status:')
|
|
||||||
self.w.message = W.TextBox((74, STATUS_POS+20, 0, 12), '')
|
|
||||||
self.w.homepage_button = W.Button((4, STATUS_POS+40, 96, 18), 'View homepage', self.do_homepage)
|
|
||||||
self.w.description_l = W.TextBox((4, STATUS_POS+70, 70, 12), 'Description:')
|
|
||||||
self.w.description = W.EditText((74, STATUS_POS+70, 0, DESCRIPTION_HEIGHT-4))
|
|
||||||
|
|
||||||
self.w.divline = W.HorizontalLine((0, INSTALL_POS-4, 0, 0))
|
|
||||||
self.w.verbose_button = W.CheckBox((84, INSTALL_POS+4, 60, 18), 'Verbose')
|
|
||||||
self.w.recursive_button = W.CheckBox((146, INSTALL_POS+4, 120, 18), 'Install dependencies', self.updatestatus)
|
|
||||||
self.w.recursive_button.set(1)
|
|
||||||
self.w.force_button = W.CheckBox((268, INSTALL_POS+4, 70, 18), 'Overwrite', self.updatestatus)
|
|
||||||
self.w.user_button = W.CheckBox((340, INSTALL_POS+4, 140, 18), 'For Current User Only', self.do_user)
|
|
||||||
self.w.install_button = W.Button((4, INSTALL_POS+4, 56, 18), 'Install:', self.do_install)
|
|
||||||
self.w.open()
|
|
||||||
self.w.description.enable(0)
|
|
||||||
|
|
||||||
def updatestatus(self):
|
|
||||||
topcell = self.w.packagebrowser.gettopcell()
|
|
||||||
sel = self.w.packagebrowser.getselection()
|
|
||||||
data = self.getbrowserdata(self.w.hidden_button.get())
|
|
||||||
self.w.packagebrowser.setitems(data)
|
|
||||||
self.w.user_button.set(self.getuserinstall())
|
|
||||||
if len(sel) != 1:
|
|
||||||
self.w.installed.set('')
|
|
||||||
self.w.message.set('')
|
|
||||||
self.w.install_button.enable(0)
|
|
||||||
self.w.homepage_button.enable(0)
|
|
||||||
self.w.description.set('')
|
|
||||||
self.w.verbose_button.enable(0)
|
|
||||||
self.w.recursive_button.enable(0)
|
|
||||||
self.w.force_button.enable(0)
|
|
||||||
self.w.user_button.enable(0)
|
|
||||||
else:
|
|
||||||
sel = sel[0]
|
|
||||||
if sel >= len(self.packages):
|
|
||||||
sel = 0
|
|
||||||
self.w.packagebrowser.setselection([sel])
|
|
||||||
installed, message = self.getstatus(sel)
|
|
||||||
self.w.installed.set(installed)
|
|
||||||
self.w.message.set(message)
|
|
||||||
self.w.install_button.enable(installed != "yes" or self.w.force_button.get())
|
|
||||||
self.w.homepage_button.enable(not not self.packages[sel].homepage())
|
|
||||||
description = self.packages[sel].description()
|
|
||||||
description = description.splitlines()
|
|
||||||
description = '\r'.join(description)
|
|
||||||
self.w.description.set(description)
|
|
||||||
self.w.verbose_button.enable(1)
|
|
||||||
self.w.recursive_button.enable(1)
|
|
||||||
self.w.force_button.enable(1)
|
|
||||||
self.w.user_button.enable(1)
|
|
||||||
self.w.packagebrowser.settopcell(topcell)
|
|
||||||
|
|
||||||
def listhit(self, *args, **kwargs):
|
|
||||||
self.updatestatus()
|
|
||||||
|
|
||||||
def do_install(self):
|
|
||||||
sel = self.w.packagebrowser.getselection()[0]
|
|
||||||
if self.w.verbose_button.get():
|
|
||||||
output = sys.stdout
|
|
||||||
else:
|
|
||||||
output = None
|
|
||||||
recursive = self.w.recursive_button.get()
|
|
||||||
force = self.w.force_button.get()
|
|
||||||
messages = self.installpackage(sel, output, recursive, force)
|
|
||||||
|
|
||||||
# Re-read .pth files
|
|
||||||
import site
|
|
||||||
reload(site)
|
|
||||||
|
|
||||||
self.updatestatus()
|
|
||||||
self.showmessages(messages)
|
|
||||||
|
|
||||||
def showmessages(self, messages):
|
|
||||||
if messages:
|
|
||||||
# To be on the safe side we always show the hidden packages,
|
|
||||||
# they may be referred to in the error messages.
|
|
||||||
if not self.w.hidden_button.get():
|
|
||||||
self.w.hidden_button.set(1)
|
|
||||||
self.updatestatus()
|
|
||||||
if type(messages) == list:
|
|
||||||
messages = '\n'.join(messages)
|
|
||||||
if self.w.verbose_button.get():
|
|
||||||
sys.stdout.write(messages + '\n')
|
|
||||||
EasyDialogs.Message(messages)
|
|
||||||
|
|
||||||
def do_homepage(self):
|
|
||||||
sel = self.w.packagebrowser.getselection()[0]
|
|
||||||
if not self.ic:
|
|
||||||
import ic
|
|
||||||
|
|
||||||
self.ic = ic.IC()
|
|
||||||
self.ic.launchurl(self.packages[sel].homepage())
|
|
||||||
|
|
||||||
def do_user(self):
|
|
||||||
messages = self.setuserinstall(self.w.user_button.get())
|
|
||||||
self.updatestatus()
|
|
||||||
self.showmessages(messages)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
PackageManagerMain()
|
|
|
@ -1,92 +0,0 @@
|
||||||
import W
|
|
||||||
from Carbon import Evt
|
|
||||||
import EasyDialogs
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import StringIO
|
|
||||||
import string
|
|
||||||
import pstats, fpformat
|
|
||||||
|
|
||||||
# increase precision
|
|
||||||
def f8(x):
|
|
||||||
return string.rjust(fpformat.fix(x, 4), 8)
|
|
||||||
pstats.f8 = f8
|
|
||||||
|
|
||||||
# hacking around a hack
|
|
||||||
if sys.version[:3] > '1.4':
|
|
||||||
timer = Evt.TickCount
|
|
||||||
else:
|
|
||||||
def timer(TickCount = Evt.TickCount):
|
|
||||||
return TickCount() / 60.0
|
|
||||||
|
|
||||||
class ProfileBrowser:
|
|
||||||
|
|
||||||
def __init__(self, stats = None):
|
|
||||||
self.sortkeys = ('calls',)
|
|
||||||
self.setupwidgets()
|
|
||||||
self.setstats(stats)
|
|
||||||
|
|
||||||
def setupwidgets(self):
|
|
||||||
self.w = W.Window((580, 400), "Profile Statistics", minsize = (200, 100), tabbable = 0)
|
|
||||||
self.w.divline = W.HorizontalLine((0, 20, 0, 0))
|
|
||||||
self.w.titlebar = W.TextBox((4, 4, 40, 12), 'Sort by:')
|
|
||||||
self.buttons = []
|
|
||||||
x = 54
|
|
||||||
width1 = 50
|
|
||||||
width2 = 75
|
|
||||||
for name in ["calls", "time", "cumulative", "stdname", "file", "line", "name"]:
|
|
||||||
if len(name) > 6:
|
|
||||||
width = width2
|
|
||||||
else:
|
|
||||||
width = width1
|
|
||||||
self.w["button_" + name] = W.RadioButton((x, 4, width, 12), name, self.buttons, self.setsort)
|
|
||||||
x += width + 10
|
|
||||||
self.w.button_calls.set(1)
|
|
||||||
self.w.text = W.TextEditor((0, 21, -15, -15), inset = (6, 5),
|
|
||||||
readonly = 1, wrap = 0, fontsettings = ('Monaco', 0, 9, (0, 0, 0)))
|
|
||||||
self.w._bary = W.Scrollbar((-15, 20, 16, -14), self.w.text.vscroll, max = 32767)
|
|
||||||
self.w._barx = W.Scrollbar((-1, -15, -14, 16), self.w.text.hscroll, max = 32767)
|
|
||||||
self.w.open()
|
|
||||||
|
|
||||||
def setstats(self, stats):
|
|
||||||
self.stats = stats
|
|
||||||
self.stats.strip_dirs()
|
|
||||||
self.displaystats()
|
|
||||||
|
|
||||||
def setsort(self):
|
|
||||||
# Grmpf. The callback doesn't give us the button:-(
|
|
||||||
for b in self.buttons:
|
|
||||||
if b.get():
|
|
||||||
if b._title == self.sortkeys[0]:
|
|
||||||
return
|
|
||||||
self.sortkeys = (b._title,) + self.sortkeys[:3]
|
|
||||||
break
|
|
||||||
self.displaystats()
|
|
||||||
|
|
||||||
def displaystats(self):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
self.stats.sort_stats(*self.sortkeys)
|
|
||||||
saveout = sys.stdout
|
|
||||||
try:
|
|
||||||
s = sys.stdout = StringIO.StringIO()
|
|
||||||
self.stats.print_stats()
|
|
||||||
finally:
|
|
||||||
sys.stdout = saveout
|
|
||||||
text = string.join(string.split(s.getvalue(), '\n'), '\r')
|
|
||||||
self.w.text.set(text)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
import pstats
|
|
||||||
args = sys.argv[1:]
|
|
||||||
for i in args:
|
|
||||||
stats = pstats.Stats(i)
|
|
||||||
browser = ProfileBrowser(stats)
|
|
||||||
else:
|
|
||||||
filename = EasyDialogs.AskFileForOpen(message='Profiler data')
|
|
||||||
if not filename: sys.exit(0)
|
|
||||||
stats = pstats.Stats(filename)
|
|
||||||
browser = ProfileBrowser(stats)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,616 +0,0 @@
|
||||||
import W
|
|
||||||
import Wkeys
|
|
||||||
import struct
|
|
||||||
import string
|
|
||||||
import types
|
|
||||||
import re
|
|
||||||
from Carbon import Qd, Icn, Fm, QuickDraw
|
|
||||||
from Carbon.QuickDraw import hilitetransfermode
|
|
||||||
|
|
||||||
|
|
||||||
nullid = '\0\0'
|
|
||||||
closedid = struct.pack('h', 468)
|
|
||||||
openid = struct.pack('h', 469)
|
|
||||||
closedsolidid = struct.pack('h', 470)
|
|
||||||
opensolidid = struct.pack('h', 471)
|
|
||||||
|
|
||||||
arrows = (nullid, closedid, openid, closedsolidid, opensolidid)
|
|
||||||
|
|
||||||
has_ctlcharsRE = re.compile(r'[\000-\037\177-\377]')
|
|
||||||
def ctlcharsREsearch(str):
|
|
||||||
if has_ctlcharsRE.search(str) is None:
|
|
||||||
return -1
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def double_repr(key, value, truncvalue = 0,
|
|
||||||
type = type, StringType = types.StringType,
|
|
||||||
has_ctlchars = ctlcharsREsearch, _repr = repr, str = str):
|
|
||||||
if type(key) == StringType and has_ctlchars(key) < 0:
|
|
||||||
key = str(key)
|
|
||||||
else:
|
|
||||||
key = _repr(key)
|
|
||||||
if key == '__builtins__':
|
|
||||||
value = "<" + type(value).__name__ + " '__builtin__'>"
|
|
||||||
elif key == '__return__':
|
|
||||||
# bleh, when returning from a class codeblock we get infinite recursion in repr.
|
|
||||||
# Use safe repr instead.
|
|
||||||
import repr
|
|
||||||
value = repr.repr(value)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
value = _repr(value)
|
|
||||||
'' + value # test to see if it is a string, in case a __repr__ method is buggy
|
|
||||||
except:
|
|
||||||
value = '\xa5\xa5\xa5 exception in repr()'
|
|
||||||
if truncvalue:
|
|
||||||
return key + '\t' + value[:255]
|
|
||||||
return key + '\t' + value
|
|
||||||
|
|
||||||
|
|
||||||
def truncString(s, maxwid):
|
|
||||||
if maxwid < 1:
|
|
||||||
return 1, ""
|
|
||||||
strlen = len(s)
|
|
||||||
strwid = Qd.TextWidth(s, 0, strlen);
|
|
||||||
if strwid <= maxwid:
|
|
||||||
return 0, s
|
|
||||||
|
|
||||||
Qd.TextFace(QuickDraw.condense)
|
|
||||||
strwid = Qd.TextWidth(s, 0, strlen)
|
|
||||||
ellipsis = Qd.StringWidth('\xc9')
|
|
||||||
|
|
||||||
if strwid <= maxwid:
|
|
||||||
Qd.TextFace(0)
|
|
||||||
return 1, s
|
|
||||||
if strwid < 1:
|
|
||||||
Qd.TextFace(0)
|
|
||||||
return 1, ""
|
|
||||||
|
|
||||||
mid = int(strlen * maxwid / strwid)
|
|
||||||
while 1:
|
|
||||||
if mid <= 0:
|
|
||||||
mid = 0
|
|
||||||
break
|
|
||||||
strwid = Qd.TextWidth(s, 0, mid) + ellipsis
|
|
||||||
strwid2 = Qd.TextWidth(s, 0, mid + 1) + ellipsis
|
|
||||||
if strwid <= maxwid and maxwid <= strwid2:
|
|
||||||
if maxwid == strwid2:
|
|
||||||
mid += 1
|
|
||||||
break
|
|
||||||
if strwid > maxwid:
|
|
||||||
mid -= 1
|
|
||||||
if mid <= 0:
|
|
||||||
mid = 0
|
|
||||||
break
|
|
||||||
elif strwid2 < maxwid:
|
|
||||||
mid += 1
|
|
||||||
Qd.TextFace(0)
|
|
||||||
return 1, s[:mid] + '\xc9'
|
|
||||||
|
|
||||||
|
|
||||||
def drawTextCell(text, cellRect, ascent, theList):
|
|
||||||
l, t, r, b = cellRect
|
|
||||||
cellwidth = r - l
|
|
||||||
Qd.MoveTo(int(l + 2), int(t + ascent))
|
|
||||||
condense, text = truncString(text, cellwidth - 3)
|
|
||||||
if condense:
|
|
||||||
Qd.TextFace(QuickDraw.condense)
|
|
||||||
Qd.DrawText(text, 0, len(text))
|
|
||||||
Qd.TextFace(0)
|
|
||||||
|
|
||||||
|
|
||||||
PICTWIDTH = 16
|
|
||||||
|
|
||||||
|
|
||||||
class BrowserWidget(W.CustomList):
|
|
||||||
|
|
||||||
def __init__(self, possize, object = None, col = 100, closechildren = 0):
|
|
||||||
W.List.__init__(self, possize, callback = self.listhit)
|
|
||||||
self.object = (None,)
|
|
||||||
self.indent = 16
|
|
||||||
self.lastmaxindent = 0
|
|
||||||
self.closechildren = closechildren
|
|
||||||
self.children = []
|
|
||||||
self.mincol = 64
|
|
||||||
self.setcolumn(col)
|
|
||||||
self.bind('return', self.openselection)
|
|
||||||
self.bind('enter', self.openselection)
|
|
||||||
if object is not None:
|
|
||||||
self.set(object)
|
|
||||||
|
|
||||||
def set(self, object):
|
|
||||||
if self.object[0] is not object:
|
|
||||||
self.object = object,
|
|
||||||
self[:] = self.unpack(object, 0)
|
|
||||||
elif self._parentwindow is not None and self._parentwindow.wid:
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def unpack(self, object, indent):
|
|
||||||
return unpack_object(object, indent)
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
# for now...
|
|
||||||
W.SetCursor('watch')
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
sel = self.getselectedobjects()
|
|
||||||
fold = self.getunfoldedobjects()
|
|
||||||
topcell = self.gettopcell()
|
|
||||||
self[:] = self.unpack(self.object[0], 0)
|
|
||||||
self.unfoldobjects(fold)
|
|
||||||
self.setselectedobjects(sel)
|
|
||||||
self.settopcell(topcell)
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def setcolumn(self, col):
|
|
||||||
self.col = col
|
|
||||||
self.colstr = struct.pack('h', col)
|
|
||||||
if self._list:
|
|
||||||
sel = self.getselection()
|
|
||||||
self.setitems(self.items)
|
|
||||||
self.setselection(sel)
|
|
||||||
|
|
||||||
def key(self, char, event):
|
|
||||||
if char in (Wkeys.leftarrowkey, Wkeys.rightarrowkey):
|
|
||||||
sel = self.getselection()
|
|
||||||
sel.reverse()
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
for index in sel:
|
|
||||||
self.fold(index, char == Wkeys.rightarrowkey)
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
else:
|
|
||||||
W.List.key(self, char, event)
|
|
||||||
|
|
||||||
def rollover(self, (x, y), onoff):
|
|
||||||
if onoff:
|
|
||||||
if self.incolumn((x, y)):
|
|
||||||
W.SetCursor('hmover')
|
|
||||||
else:
|
|
||||||
W.SetCursor('arrow')
|
|
||||||
|
|
||||||
def inarrow(self, (x, y)):
|
|
||||||
cl, ct, cr, cb = self._list.LRect((0, 0))
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
if (x - cl) < 16:
|
|
||||||
cellheight = cb - ct
|
|
||||||
index = (y - ct) / cellheight
|
|
||||||
if index < len(self.items):
|
|
||||||
return 1, index
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
def incolumn(self, (x, y)):
|
|
||||||
l, t, r, b = self._list.LRect((0, 0))
|
|
||||||
abscol = l + self.col
|
|
||||||
return abs(abscol - x) < 3
|
|
||||||
|
|
||||||
def trackcolumn(self, (x, y)):
|
|
||||||
from Carbon import Qd, QuickDraw, Evt
|
|
||||||
self.SetPort()
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
bounds = l, t, r, b = l + 1, t + 1, r - 16, b - 1
|
|
||||||
abscol = l + self.col
|
|
||||||
mincol = l + self.mincol
|
|
||||||
maxcol = r - 10
|
|
||||||
diff = abscol - x
|
|
||||||
Qd.PenPat('\000\377\000\377\000\377\000\377')
|
|
||||||
Qd.PenMode(QuickDraw.srcXor)
|
|
||||||
rect = abscol - 1, t, abscol, b
|
|
||||||
Qd.PaintRect(rect)
|
|
||||||
lastpoint = (x, y)
|
|
||||||
newcol = -1
|
|
||||||
#W.SetCursor('fist')
|
|
||||||
while Evt.Button():
|
|
||||||
Evt.WaitNextEvent(0, 1, None) # needed for OSX
|
|
||||||
(x, y) = Evt.GetMouse()
|
|
||||||
if (x, y) <> lastpoint:
|
|
||||||
newcol = x + diff
|
|
||||||
newcol = max(newcol, mincol)
|
|
||||||
newcol = min(newcol, maxcol)
|
|
||||||
Qd.PaintRect(rect)
|
|
||||||
rect = newcol - 1, t, newcol, b
|
|
||||||
Qd.PaintRect(rect)
|
|
||||||
lastpoint = (x, y)
|
|
||||||
Qd.PaintRect(rect)
|
|
||||||
Qd.PenPat(Qd.GetQDGlobalsBlack())
|
|
||||||
Qd.PenNormal()
|
|
||||||
if newcol > 0 and newcol <> abscol:
|
|
||||||
self.setcolumn(newcol - l)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if point == (-1, -1): # gross.
|
|
||||||
W.List.click(self, point ,modifiers)
|
|
||||||
return
|
|
||||||
hit, index = self.inarrow(point)
|
|
||||||
if hit:
|
|
||||||
(key, value, arrow, indent) = self.items[index]
|
|
||||||
self.fold(index, arrow == 1)
|
|
||||||
elif self.incolumn(point):
|
|
||||||
self.trackcolumn(point)
|
|
||||||
else:
|
|
||||||
W.List.click(self, point, modifiers)
|
|
||||||
|
|
||||||
# for W.List.key
|
|
||||||
def findmatch(self, tag):
|
|
||||||
lower = string.lower
|
|
||||||
items = self.items
|
|
||||||
taglen = len(tag)
|
|
||||||
match = '\377' * 100
|
|
||||||
match_i = -1
|
|
||||||
for i in range(len(items)):
|
|
||||||
item = lower(str(items[i][0]))
|
|
||||||
if tag <= item < match:
|
|
||||||
match = item
|
|
||||||
match_i = i
|
|
||||||
if match_i >= 0:
|
|
||||||
return match_i
|
|
||||||
else:
|
|
||||||
return len(items) - 1
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self.closechildren:
|
|
||||||
for window in self.children:
|
|
||||||
window.close()
|
|
||||||
self.children = []
|
|
||||||
W.List.close(self)
|
|
||||||
|
|
||||||
def fold(self, index, onoff):
|
|
||||||
(key, value, arrow, indent) = self.items[index]
|
|
||||||
if arrow == 0 or (onoff and arrow == 2) or (not onoff and arrow == 1):
|
|
||||||
return
|
|
||||||
W.SetCursor('watch')
|
|
||||||
topcell = self.gettopcell()
|
|
||||||
if onoff:
|
|
||||||
self[index] = (key, value, 4, indent)
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
self[index+1:index+1] = self.unpack(value, indent + 1)
|
|
||||||
self[index] = (key, value, 2, indent)
|
|
||||||
else:
|
|
||||||
self[index] = (key, value, 3, indent)
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
count = 0
|
|
||||||
for i in range(index + 1, len(self.items)):
|
|
||||||
(dummy, dummy, dummy, subindent) = self.items[i]
|
|
||||||
if subindent <= indent:
|
|
||||||
break
|
|
||||||
count = count + 1
|
|
||||||
self[index+1:index+1+count] = []
|
|
||||||
self[index] = (key, value, 1, indent)
|
|
||||||
maxindent = self.getmaxindent()
|
|
||||||
if maxindent <> self.lastmaxindent:
|
|
||||||
newabsindent = self.col + (maxindent - self.lastmaxindent) * self.indent
|
|
||||||
if newabsindent >= self.mincol:
|
|
||||||
self.setcolumn(newabsindent)
|
|
||||||
self.lastmaxindent = maxindent
|
|
||||||
self.settopcell(topcell)
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def unfoldobjects(self, objects):
|
|
||||||
for obj in objects:
|
|
||||||
try:
|
|
||||||
index = self.items.index(obj)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fold(index, 1)
|
|
||||||
|
|
||||||
def getunfoldedobjects(self):
|
|
||||||
curindent = 0
|
|
||||||
objects = []
|
|
||||||
for index in range(len(self.items)):
|
|
||||||
(key, value, arrow, indent) = self.items[index]
|
|
||||||
if indent > curindent:
|
|
||||||
(k, v, a, i) = self.items[index - 1]
|
|
||||||
objects.append((k, v, 1, i))
|
|
||||||
curindent = indent
|
|
||||||
elif indent < curindent:
|
|
||||||
curindent = indent
|
|
||||||
return objects
|
|
||||||
|
|
||||||
def listhit(self, isdbl):
|
|
||||||
if isdbl:
|
|
||||||
self.openselection()
|
|
||||||
|
|
||||||
def openselection(self):
|
|
||||||
import os
|
|
||||||
sel = self.getselection()
|
|
||||||
for index in sel:
|
|
||||||
(key, value, arrow, indent) = self[index]
|
|
||||||
if arrow:
|
|
||||||
self.children.append(Browser(value))
|
|
||||||
elif type(value) == types.StringType and '\0' not in value:
|
|
||||||
editor = self._parentwindow.parent.getscript(value)
|
|
||||||
if editor:
|
|
||||||
editor.select()
|
|
||||||
return
|
|
||||||
elif os.path.exists(value) and os.path.isfile(value):
|
|
||||||
if MacOS.GetCreatorAndType(value)[1] in ('TEXT', '\0\0\0\0'):
|
|
||||||
W.getapplication().openscript(value)
|
|
||||||
|
|
||||||
def itemrepr(self, (key, value, arrow, indent), str = str, double_repr = double_repr,
|
|
||||||
arrows = arrows, pack = struct.pack):
|
|
||||||
arrow = arrows[arrow]
|
|
||||||
return arrow + pack('h', self.indent * indent) + self.colstr + \
|
|
||||||
double_repr(key, value, 1)
|
|
||||||
|
|
||||||
def getmaxindent(self, max = max):
|
|
||||||
maxindent = 0
|
|
||||||
for item in self.items:
|
|
||||||
maxindent = max(maxindent, item[3])
|
|
||||||
return maxindent
|
|
||||||
|
|
||||||
def domenu_copy(self, *args):
|
|
||||||
sel = self.getselectedobjects()
|
|
||||||
selitems = []
|
|
||||||
for key, value, dummy, dummy in sel:
|
|
||||||
selitems.append(double_repr(key, value))
|
|
||||||
text = string.join(selitems, '\r')
|
|
||||||
if text:
|
|
||||||
from Carbon import Scrap
|
|
||||||
if hasattr(Scrap, 'PutScrap'):
|
|
||||||
Scrap.ZeroScrap()
|
|
||||||
Scrap.PutScrap('TEXT', text)
|
|
||||||
else:
|
|
||||||
Scrap.ClearCurrentScrap()
|
|
||||||
sc = Scrap.GetCurrentScrap()
|
|
||||||
sc.PutScrapFlavor('TEXT', 0, text)
|
|
||||||
|
|
||||||
def listDefDraw(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
self.myDrawCell(0, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList)
|
|
||||||
|
|
||||||
def listDefHighlight(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
self.myDrawCell(1, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList)
|
|
||||||
|
|
||||||
def myDrawCell(self, onlyHilite, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
savedPort = Qd.GetPort()
|
|
||||||
Qd.SetPort(theList.GetListPort())
|
|
||||||
savedClip = Qd.NewRgn()
|
|
||||||
Qd.GetClip(savedClip)
|
|
||||||
Qd.ClipRect(cellRect)
|
|
||||||
savedPenState = Qd.GetPenState()
|
|
||||||
Qd.PenNormal()
|
|
||||||
|
|
||||||
l, t, r, b = cellRect
|
|
||||||
|
|
||||||
if not onlyHilite:
|
|
||||||
Qd.EraseRect(cellRect)
|
|
||||||
|
|
||||||
ascent, descent, leading, size, hm = Fm.FontMetrics()
|
|
||||||
linefeed = ascent + descent + leading
|
|
||||||
|
|
||||||
if dataLen >= 6:
|
|
||||||
data = theList.LGetCell(dataLen, theCell)
|
|
||||||
iconId, indent, tab = struct.unpack("hhh", data[:6])
|
|
||||||
try:
|
|
||||||
key, value = data[6:].split("\t", 1)
|
|
||||||
except ValueError:
|
|
||||||
# bogus data, at least don't crash.
|
|
||||||
indent = 0
|
|
||||||
tab = 0
|
|
||||||
iconId = 0
|
|
||||||
key = ""
|
|
||||||
value = data[6:]
|
|
||||||
|
|
||||||
if iconId:
|
|
||||||
try:
|
|
||||||
theIcon = Icn.GetCIcon(iconId)
|
|
||||||
except Icn.Error:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
rect = (0, 0, 16, 16)
|
|
||||||
rect = Qd.OffsetRect(rect, l, t)
|
|
||||||
rect = Qd.OffsetRect(rect, 0, (theList.cellSize[1] - (rect[3] - rect[1])) / 2)
|
|
||||||
Icn.PlotCIcon(rect, theIcon)
|
|
||||||
|
|
||||||
if len(key) >= 0:
|
|
||||||
cl, ct, cr, cb = cellRect
|
|
||||||
vl, vt, vr, vb = self._viewbounds
|
|
||||||
cl = vl + PICTWIDTH + indent
|
|
||||||
cr = vl + tab
|
|
||||||
if cr > vr:
|
|
||||||
cr = vr
|
|
||||||
if cl < cr:
|
|
||||||
drawTextCell(key, (cl, ct, cr, cb), ascent, theList)
|
|
||||||
cl = vl + tab
|
|
||||||
cr = vr
|
|
||||||
if cl < cr:
|
|
||||||
drawTextCell(value, (cl, ct, cr, cb), ascent, theList)
|
|
||||||
#elif dataLen != 0:
|
|
||||||
# drawTextCell("???", 3, cellRect, ascent, theList)
|
|
||||||
else:
|
|
||||||
return # we have bogus data
|
|
||||||
|
|
||||||
# draw nice dotted line
|
|
||||||
l, t, r, b = cellRect
|
|
||||||
l = self._viewbounds[0] + tab
|
|
||||||
r = l + 1;
|
|
||||||
if not (theList.cellSize[1] & 0x01) or (t & 0x01):
|
|
||||||
myPat = "\xff\x00\xff\x00\xff\x00\xff\x00"
|
|
||||||
else:
|
|
||||||
myPat = "\x00\xff\x00\xff\x00\xff\x00\xff"
|
|
||||||
Qd.PenPat(myPat)
|
|
||||||
Qd.PenMode(QuickDraw.srcCopy)
|
|
||||||
Qd.PaintRect((l, t, r, b))
|
|
||||||
Qd.PenNormal()
|
|
||||||
|
|
||||||
if selected or onlyHilite:
|
|
||||||
l, t, r, b = cellRect
|
|
||||||
l = self._viewbounds[0] + PICTWIDTH
|
|
||||||
r = self._viewbounds[2]
|
|
||||||
Qd.PenMode(hilitetransfermode)
|
|
||||||
Qd.PaintRect((l, t, r, b))
|
|
||||||
|
|
||||||
# restore graphics environment
|
|
||||||
Qd.SetPort(savedPort)
|
|
||||||
Qd.SetClip(savedClip)
|
|
||||||
Qd.DisposeRgn(savedClip)
|
|
||||||
Qd.SetPenState(savedPenState)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Browser:
|
|
||||||
|
|
||||||
def __init__(self, object = None, title = None, closechildren = 0):
|
|
||||||
if hasattr(object, '__name__'):
|
|
||||||
name = object.__name__
|
|
||||||
else:
|
|
||||||
name = ''
|
|
||||||
if title is None:
|
|
||||||
title = 'Object browser'
|
|
||||||
if name:
|
|
||||||
title = title + ': ' + name
|
|
||||||
self.w = w = W.Window((300, 400), title, minsize = (100, 100))
|
|
||||||
w.info = W.TextBox((18, 8, -70, 15))
|
|
||||||
w.updatebutton = W.BevelButton((-64, 4, 50, 16), 'Update', self.update)
|
|
||||||
w.browser = BrowserWidget((-1, 24, 1, -14), None)
|
|
||||||
w.bind('cmdu', w.updatebutton.push)
|
|
||||||
w.open()
|
|
||||||
self.set(object, name)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self.w.wid:
|
|
||||||
self.w.close()
|
|
||||||
|
|
||||||
def set(self, object, name = ''):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
tp = type(object).__name__
|
|
||||||
try:
|
|
||||||
length = len(object)
|
|
||||||
except:
|
|
||||||
length = -1
|
|
||||||
if not name and hasattr(object, '__name__'):
|
|
||||||
name = object.__name__
|
|
||||||
if name:
|
|
||||||
info = name + ': ' + tp
|
|
||||||
else:
|
|
||||||
info = tp
|
|
||||||
if length >= 0:
|
|
||||||
if length == 1:
|
|
||||||
info = info + ' (%d element)' % length
|
|
||||||
else:
|
|
||||||
info = info + ' (%d elements)' % length
|
|
||||||
self.w.info.set(info)
|
|
||||||
self.w.browser.set(object)
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
self.w.browser.update()
|
|
||||||
|
|
||||||
|
|
||||||
SIMPLE_TYPES = (
|
|
||||||
type(None),
|
|
||||||
int,
|
|
||||||
long,
|
|
||||||
float,
|
|
||||||
complex,
|
|
||||||
str,
|
|
||||||
unicode,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_ivars(obj):
|
|
||||||
"""Return a list the names of all (potential) instance variables."""
|
|
||||||
# __mro__ recipe from Guido
|
|
||||||
slots = {}
|
|
||||||
# old-style C objects
|
|
||||||
if hasattr(obj, "__members__"):
|
|
||||||
for name in obj.__members__:
|
|
||||||
slots[name] = None
|
|
||||||
if hasattr(obj, "__methods__"):
|
|
||||||
for name in obj.__methods__:
|
|
||||||
slots[name] = None
|
|
||||||
# generic type
|
|
||||||
if hasattr(obj, "__dict__"):
|
|
||||||
slots.update(obj.__dict__)
|
|
||||||
cls = type(obj)
|
|
||||||
if hasattr(cls, "__mro__"):
|
|
||||||
# new-style class, use descriptors
|
|
||||||
for base in cls.__mro__:
|
|
||||||
for name, value in base.__dict__.items():
|
|
||||||
# XXX using callable() is a heuristic which isn't 100%
|
|
||||||
# foolproof.
|
|
||||||
if hasattr(value, "__get__") and not callable(value):
|
|
||||||
slots[name] = None
|
|
||||||
if "__dict__" in slots:
|
|
||||||
del slots["__dict__"]
|
|
||||||
slots = slots.keys()
|
|
||||||
slots.sort()
|
|
||||||
return slots
|
|
||||||
|
|
||||||
def unpack_object(object, indent = 0):
|
|
||||||
tp = type(object)
|
|
||||||
if isinstance(object, SIMPLE_TYPES) and object is not None:
|
|
||||||
raise TypeError, "can't browse simple type: %s" % tp.__name__
|
|
||||||
elif isinstance(object, dict):
|
|
||||||
return unpack_dict(object, indent)
|
|
||||||
elif isinstance(object, (tuple, list)):
|
|
||||||
return unpack_sequence(object, indent)
|
|
||||||
elif isinstance(object, types.ModuleType):
|
|
||||||
return unpack_dict(object.__dict__, indent)
|
|
||||||
else:
|
|
||||||
return unpack_other(object, indent)
|
|
||||||
|
|
||||||
def unpack_sequence(seq, indent = 0):
|
|
||||||
return [(i, v, not isinstance(v, SIMPLE_TYPES), indent)
|
|
||||||
for i, v in enumerate(seq)]
|
|
||||||
|
|
||||||
def unpack_dict(dict, indent = 0):
|
|
||||||
items = dict.items()
|
|
||||||
return pack_items(items, indent)
|
|
||||||
|
|
||||||
def unpack_instance(inst, indent = 0):
|
|
||||||
if hasattr(inst, '__pybrowse_unpack__'):
|
|
||||||
return unpack_object(inst.__pybrowse_unpack__(), indent)
|
|
||||||
else:
|
|
||||||
items = [('__class__', inst.__class__)] + inst.__dict__.items()
|
|
||||||
return pack_items(items, indent)
|
|
||||||
|
|
||||||
def unpack_class(clss, indent = 0):
|
|
||||||
items = [('__bases__', clss.__bases__), ('__name__', clss.__name__)] + clss.__dict__.items()
|
|
||||||
return pack_items(items, indent)
|
|
||||||
|
|
||||||
def unpack_other(object, indent = 0):
|
|
||||||
attrs = get_ivars(object)
|
|
||||||
items = []
|
|
||||||
for attr in attrs:
|
|
||||||
try:
|
|
||||||
value = getattr(object, attr)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
items.append((attr, value))
|
|
||||||
return pack_items(items, indent)
|
|
||||||
|
|
||||||
def pack_items(items, indent = 0):
|
|
||||||
items = [(k, v, not isinstance(v, SIMPLE_TYPES), indent)
|
|
||||||
for k, v in items]
|
|
||||||
return tuple_caselesssort(items)
|
|
||||||
|
|
||||||
def caselesssort(alist):
|
|
||||||
"""Return a sorted copy of a list. If there are only strings in the list,
|
|
||||||
it will not consider case"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# turn ['FOO', 'aaBc', 'ABcD'] into [('foo', 'FOO'), ('aabc', 'aaBc'), ('abcd', 'ABcD')], if possible
|
|
||||||
tupledlist = map(lambda item, lower = string.lower: (lower(item), item), alist)
|
|
||||||
except TypeError:
|
|
||||||
# at least one element in alist is not a string, proceed the normal way...
|
|
||||||
alist = alist[:]
|
|
||||||
alist.sort()
|
|
||||||
return alist
|
|
||||||
else:
|
|
||||||
tupledlist.sort()
|
|
||||||
# turn [('aabc', 'aaBc'), ('abcd', 'ABcD'), ('foo', 'FOO')] into ['aaBc', 'ABcD', 'FOO']
|
|
||||||
return map(lambda x: x[1], tupledlist)
|
|
||||||
|
|
||||||
def tuple_caselesssort(items):
|
|
||||||
try:
|
|
||||||
tupledlist = map(lambda tuple, lower = string.lower: (lower(tuple[0]), tuple), items)
|
|
||||||
except (AttributeError, TypeError):
|
|
||||||
items = items[:]
|
|
||||||
items.sort()
|
|
||||||
return items
|
|
||||||
else:
|
|
||||||
tupledlist.sort()
|
|
||||||
return map(lambda (low, tuple): tuple, tupledlist)
|
|
|
@ -1,437 +0,0 @@
|
||||||
import W
|
|
||||||
import Wkeys
|
|
||||||
from Carbon import Fm
|
|
||||||
import WASTEconst
|
|
||||||
from types import *
|
|
||||||
from Carbon import Events
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import MacOS
|
|
||||||
import MacPrefs
|
|
||||||
from Carbon import Qd
|
|
||||||
import EasyDialogs
|
|
||||||
import PyInteractive
|
|
||||||
|
|
||||||
if not hasattr(sys, 'ps1'):
|
|
||||||
sys.ps1 = '>>> '
|
|
||||||
if not hasattr(sys, 'ps2'):
|
|
||||||
sys.ps2 = '... '
|
|
||||||
|
|
||||||
def inspect(foo): # JJS 1/25/99
|
|
||||||
"Launch the browser on the given object. This is a general built-in function."
|
|
||||||
import PyBrowser
|
|
||||||
PyBrowser.Browser(foo)
|
|
||||||
|
|
||||||
class ConsoleTextWidget(W.EditText):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
W.EditText.__init__(self, *args, **kwargs)
|
|
||||||
self._inputstart = 0
|
|
||||||
self._buf = ''
|
|
||||||
self.pyinteractive = PyInteractive.PyInteractive()
|
|
||||||
|
|
||||||
import __main__
|
|
||||||
self._namespace = __main__.__dict__
|
|
||||||
self._namespace['inspect'] = inspect # JJS 1/25/99
|
|
||||||
|
|
||||||
def insert(self, text):
|
|
||||||
self.checkselection()
|
|
||||||
self.ted.WEInsert(text, None, None)
|
|
||||||
self.changed = 1
|
|
||||||
self.selchanged = 1
|
|
||||||
|
|
||||||
def set_namespace(self, dict):
|
|
||||||
if type(dict) <> DictionaryType:
|
|
||||||
raise TypeError, "The namespace needs to be a dictionary"
|
|
||||||
if 'inspect' not in dict.keys(): dict['inspect'] = inspect # JJS 1/25/99
|
|
||||||
self._namespace = dict
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
import __main__
|
|
||||||
W.EditText.open(self)
|
|
||||||
self.write('Python %s\n' % sys.version)
|
|
||||||
self.write('Type "copyright", "credits" or "license" for more information.\n')
|
|
||||||
self.write('MacPython IDE %s\n' % __main__.__version__)
|
|
||||||
self.write(sys.ps1)
|
|
||||||
self.flush()
|
|
||||||
|
|
||||||
def key(self, char, event):
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
|
|
||||||
if char not in Wkeys.navigationkeys:
|
|
||||||
self.checkselection()
|
|
||||||
if char == Wkeys.enterkey:
|
|
||||||
char = Wkeys.returnkey
|
|
||||||
selstart, selend = self.getselection()
|
|
||||||
if char == Wkeys.backspacekey:
|
|
||||||
if selstart <= (self._inputstart - (selstart <> selend)):
|
|
||||||
return
|
|
||||||
self.ted.WEKey(ord(char), modifiers)
|
|
||||||
if char not in Wkeys.navigationkeys:
|
|
||||||
self.changed = 1
|
|
||||||
if char not in Wkeys.scrollkeys:
|
|
||||||
self.selchanged = 1
|
|
||||||
self.updatescrollbars()
|
|
||||||
if char == Wkeys.returnkey:
|
|
||||||
text = self.get()[self._inputstart:selstart]
|
|
||||||
text = string.join(string.split(text, "\r"), "\n")
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
saveyield = MacOS.EnableAppswitch(0)
|
|
||||||
self._scriptDone = False
|
|
||||||
if sys.platform == "darwin":
|
|
||||||
# see identical construct in PyEdit.py
|
|
||||||
from threading import Thread
|
|
||||||
t = Thread(target=self._userCancelledMonitor,
|
|
||||||
name="UserCancelledMonitor")
|
|
||||||
t.start()
|
|
||||||
try:
|
|
||||||
self.pyinteractive.executeline(text, self, self._namespace)
|
|
||||||
finally:
|
|
||||||
self._scriptDone = True
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(saveyield)
|
|
||||||
selstart, selend = self.getselection()
|
|
||||||
self._inputstart = selstart
|
|
||||||
|
|
||||||
def _userCancelledMonitor(self):
|
|
||||||
# XXX duplicate code from PyEdit.py
|
|
||||||
import time, os
|
|
||||||
from signal import SIGINT
|
|
||||||
from Carbon import Evt
|
|
||||||
while not self._scriptDone:
|
|
||||||
if Evt.CheckEventQueueForUserCancel():
|
|
||||||
# Send a SIGINT signal to ourselves.
|
|
||||||
# This gets delivered to the main thread,
|
|
||||||
# cancelling the running script.
|
|
||||||
os.kill(os.getpid(), SIGINT)
|
|
||||||
break
|
|
||||||
time.sleep(0.25)
|
|
||||||
|
|
||||||
def domenu_save_as(self, *args):
|
|
||||||
filename = EasyDialogs.AskFileForSave(message='Save console text as:',
|
|
||||||
savedFileName='console.txt')
|
|
||||||
if not filename:
|
|
||||||
return
|
|
||||||
f = open(filename, 'wb')
|
|
||||||
f.write(self.get())
|
|
||||||
f.close()
|
|
||||||
MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
|
|
||||||
|
|
||||||
def write(self, text):
|
|
||||||
self._buf = self._buf + text
|
|
||||||
if '\n' in self._buf:
|
|
||||||
self.flush()
|
|
||||||
|
|
||||||
def flush(self):
|
|
||||||
stuff = string.split(self._buf, '\n')
|
|
||||||
stuff = string.join(stuff, '\r')
|
|
||||||
self.setselection_at_end()
|
|
||||||
try:
|
|
||||||
self.ted.WEInsert(stuff, None, None)
|
|
||||||
finally:
|
|
||||||
self._buf = ""
|
|
||||||
selstart, selend = self.getselection()
|
|
||||||
self._inputstart = selstart
|
|
||||||
self.ted.WEClearUndo()
|
|
||||||
self.updatescrollbars()
|
|
||||||
if self._parentwindow.wid.GetWindowPort().QDIsPortBuffered():
|
|
||||||
self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
|
|
||||||
|
|
||||||
def selection_ok(self):
|
|
||||||
selstart, selend = self.getselection()
|
|
||||||
return not (selstart < self._inputstart or selend < self._inputstart)
|
|
||||||
|
|
||||||
def checkselection(self):
|
|
||||||
if not self.selection_ok():
|
|
||||||
self.setselection_at_end()
|
|
||||||
|
|
||||||
def setselection_at_end(self):
|
|
||||||
end = self.ted.WEGetTextLength()
|
|
||||||
self.setselection(end, end)
|
|
||||||
self.updatescrollbars()
|
|
||||||
|
|
||||||
def domenu_cut(self, *args):
|
|
||||||
if not self.selection_ok():
|
|
||||||
return
|
|
||||||
W.EditText.domenu_cut(self)
|
|
||||||
|
|
||||||
def domenu_paste(self, *args):
|
|
||||||
if not self.selection_ok():
|
|
||||||
self.setselection_at_end()
|
|
||||||
W.EditText.domenu_paste(self)
|
|
||||||
|
|
||||||
def domenu_clear(self, *args):
|
|
||||||
if not self.selection_ok():
|
|
||||||
return
|
|
||||||
W.EditText.domenu_clear(self)
|
|
||||||
|
|
||||||
|
|
||||||
class PyConsole(W.Window):
|
|
||||||
|
|
||||||
def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)),
|
|
||||||
tabsettings = (32, 0), unclosable = 0):
|
|
||||||
W.Window.__init__(self,
|
|
||||||
bounds,
|
|
||||||
"Python Interactive",
|
|
||||||
minsize = (200, 100),
|
|
||||||
tabbable = 0,
|
|
||||||
show = show)
|
|
||||||
|
|
||||||
self._unclosable = unclosable
|
|
||||||
consoletext = ConsoleTextWidget((-1, -1, -14, 1), inset = (6, 5),
|
|
||||||
fontsettings = fontsettings, tabsettings = tabsettings)
|
|
||||||
self._bary = W.Scrollbar((-15, 14, 16, -14), consoletext.vscroll, max = 32767)
|
|
||||||
self.consoletext = consoletext
|
|
||||||
self.namespacemenu = W.PopupMenu((-15, -1, 16, 16), [], self.consoletext.set_namespace)
|
|
||||||
self.namespacemenu.bind('<click>', self.makenamespacemenu)
|
|
||||||
self.open()
|
|
||||||
|
|
||||||
def makenamespacemenu(self, *args):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
namespacelist = self.getnamespacelist()
|
|
||||||
self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings),
|
|
||||||
["Namespace"] + namespacelist, ("Browse namespace\xc9", self.browsenamespace)])
|
|
||||||
currentname = self.consoletext._namespace["__name__"]
|
|
||||||
for i in range(len(namespacelist)):
|
|
||||||
if namespacelist[i][0] == currentname:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
# XXX this functionality should be generally available in Wmenus
|
|
||||||
submenuid = self.namespacemenu.menu.menu.GetItemMark(3)
|
|
||||||
menu = self.namespacemenu.menu.bar.menus[submenuid]
|
|
||||||
menu.menu.CheckMenuItem(i + 1, 1)
|
|
||||||
|
|
||||||
def browsenamespace(self):
|
|
||||||
import PyBrowser, W
|
|
||||||
W.SetCursor('watch')
|
|
||||||
PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
|
|
||||||
|
|
||||||
def clearbuffer(self):
|
|
||||||
from Carbon import Res
|
|
||||||
self.consoletext.ted.WEUseText(Res.Resource(''))
|
|
||||||
self.consoletext.write(sys.ps1)
|
|
||||||
self.consoletext.flush()
|
|
||||||
|
|
||||||
def getnamespacelist(self):
|
|
||||||
import os
|
|
||||||
import __main__
|
|
||||||
editors = filter(lambda x: x.__class__.__name__ == "Editor", self.parent._windows.values())
|
|
||||||
|
|
||||||
namespaces = [ ("__main__",__main__.__dict__) ]
|
|
||||||
for ed in editors:
|
|
||||||
modname = os.path.splitext(ed.title)[0]
|
|
||||||
if sys.modules.has_key(modname):
|
|
||||||
module = sys.modules[modname]
|
|
||||||
namespaces.append((modname, module.__dict__))
|
|
||||||
else:
|
|
||||||
if ed.title[-3:] == '.py':
|
|
||||||
modname = ed.title[:-3]
|
|
||||||
else:
|
|
||||||
modname = ed.title
|
|
||||||
ed.globals["__name__"] = modname
|
|
||||||
namespaces.append((modname, ed.globals))
|
|
||||||
return namespaces
|
|
||||||
|
|
||||||
def dofontsettings(self):
|
|
||||||
import FontSettings
|
|
||||||
settings = FontSettings.FontDialog(self.consoletext.getfontsettings(),
|
|
||||||
self.consoletext.gettabsettings())
|
|
||||||
if settings:
|
|
||||||
fontsettings, tabsettings = settings
|
|
||||||
self.consoletext.setfontsettings(fontsettings)
|
|
||||||
self.consoletext.settabsettings(tabsettings)
|
|
||||||
|
|
||||||
def show(self, onoff = 1):
|
|
||||||
W.Window.show(self, onoff)
|
|
||||||
if onoff:
|
|
||||||
self.select()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self._unclosable:
|
|
||||||
self.show(0)
|
|
||||||
return -1
|
|
||||||
W.Window.close(self)
|
|
||||||
|
|
||||||
def writeprefs(self):
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
prefs.console.show = self.isvisible()
|
|
||||||
prefs.console.windowbounds = self.getbounds()
|
|
||||||
prefs.console.fontsettings = self.consoletext.getfontsettings()
|
|
||||||
prefs.console.tabsettings = self.consoletext.gettabsettings()
|
|
||||||
prefs.save()
|
|
||||||
|
|
||||||
def getselectedtext(self):
|
|
||||||
return self.consoletext.getselectedtext()
|
|
||||||
|
|
||||||
class OutputTextWidget(W.EditText):
|
|
||||||
|
|
||||||
def domenu_save_as(self, *args):
|
|
||||||
title = self._parentwindow.gettitle()
|
|
||||||
filename = EasyDialogs.AskFileForSave(message='Save %s text as:' % title,
|
|
||||||
savedFileName=title + '.txt')
|
|
||||||
if not filename:
|
|
||||||
return
|
|
||||||
f = open(filename, 'wb')
|
|
||||||
f.write(self.get())
|
|
||||||
f.close()
|
|
||||||
MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
|
|
||||||
|
|
||||||
def domenu_cut(self, *args):
|
|
||||||
self.domenu_copy(*args)
|
|
||||||
|
|
||||||
def domenu_clear(self, *args):
|
|
||||||
self.set('')
|
|
||||||
|
|
||||||
|
|
||||||
class PyOutput:
|
|
||||||
|
|
||||||
def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), tabsettings = (32, 0)):
|
|
||||||
self.bounds = bounds
|
|
||||||
self.fontsettings = fontsettings
|
|
||||||
self.tabsettings = tabsettings
|
|
||||||
self.w = None
|
|
||||||
self.closed = 1
|
|
||||||
self._buf = ''
|
|
||||||
# should be able to set this
|
|
||||||
self.savestdout, self.savestderr = sys.stdout, sys.stderr
|
|
||||||
sys.stderr = sys.stdout = self
|
|
||||||
if show:
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
def setupwidgets(self):
|
|
||||||
self.w = W.Window(self.bounds, "Output",
|
|
||||||
minsize = (200, 100),
|
|
||||||
tabbable = 0)
|
|
||||||
self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5),
|
|
||||||
fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1)
|
|
||||||
menuitems = [("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings)]
|
|
||||||
self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems)
|
|
||||||
|
|
||||||
self.w._bary = W.Scrollbar((-15, 14, 16, -14), self.w.outputtext.vscroll, max = 32767)
|
|
||||||
self.w.bind("<close>", self.close)
|
|
||||||
self.w.bind("<activate>", self.activate)
|
|
||||||
|
|
||||||
def write(self, text):
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
oldyield = MacOS.EnableAppswitch(-1)
|
|
||||||
try:
|
|
||||||
self._buf = self._buf + text
|
|
||||||
if '\n' in self._buf:
|
|
||||||
self.flush()
|
|
||||||
finally:
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(oldyield)
|
|
||||||
|
|
||||||
def flush(self):
|
|
||||||
self.show()
|
|
||||||
stuff = string.split(self._buf, '\n')
|
|
||||||
stuff = string.join(stuff, '\r')
|
|
||||||
end = self.w.outputtext.ted.WEGetTextLength()
|
|
||||||
self.w.outputtext.setselection(end, end)
|
|
||||||
self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
|
|
||||||
try:
|
|
||||||
self.w.outputtext.ted.WEInsert(stuff, None, None)
|
|
||||||
finally:
|
|
||||||
self._buf = ""
|
|
||||||
self.w.outputtext.updatescrollbars()
|
|
||||||
self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
|
|
||||||
if self.w.wid.GetWindowPort().QDIsPortBuffered():
|
|
||||||
self.w.wid.GetWindowPort().QDFlushPortBuffer(None)
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
if self.closed:
|
|
||||||
if not self.w:
|
|
||||||
self.setupwidgets()
|
|
||||||
self.w.open()
|
|
||||||
self.w.outputtext.updatescrollbars()
|
|
||||||
self.closed = 0
|
|
||||||
else:
|
|
||||||
self.w.show(1)
|
|
||||||
self.closed = 0
|
|
||||||
self.w.select()
|
|
||||||
|
|
||||||
def writeprefs(self):
|
|
||||||
if self.w is not None:
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
prefs.output.show = self.w.isvisible()
|
|
||||||
prefs.output.windowbounds = self.w.getbounds()
|
|
||||||
prefs.output.fontsettings = self.w.outputtext.getfontsettings()
|
|
||||||
prefs.output.tabsettings = self.w.outputtext.gettabsettings()
|
|
||||||
prefs.save()
|
|
||||||
|
|
||||||
def dofontsettings(self):
|
|
||||||
import FontSettings
|
|
||||||
settings = FontSettings.FontDialog(self.w.outputtext.getfontsettings(),
|
|
||||||
self.w.outputtext.gettabsettings())
|
|
||||||
if settings:
|
|
||||||
fontsettings, tabsettings = settings
|
|
||||||
self.w.outputtext.setfontsettings(fontsettings)
|
|
||||||
self.w.outputtext.settabsettings(tabsettings)
|
|
||||||
|
|
||||||
def clearbuffer(self):
|
|
||||||
from Carbon import Res
|
|
||||||
self.w.outputtext.set('')
|
|
||||||
|
|
||||||
def activate(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
self.closed = 0
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.w.show(0)
|
|
||||||
self.closed = 1
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleStdin:
|
|
||||||
|
|
||||||
def readline(self):
|
|
||||||
import EasyDialogs
|
|
||||||
# A trick to make the input dialog box a bit more palatable
|
|
||||||
if hasattr(sys.stdout, '_buf'):
|
|
||||||
prompt = sys.stdout._buf
|
|
||||||
else:
|
|
||||||
prompt = ""
|
|
||||||
if not prompt:
|
|
||||||
prompt = "Stdin input:"
|
|
||||||
sys.stdout.flush()
|
|
||||||
rv = EasyDialogs.AskString(prompt)
|
|
||||||
if rv is None:
|
|
||||||
return ""
|
|
||||||
rv = rv + "\n" # readline should include line terminator
|
|
||||||
sys.stdout.write(rv) # echo user's reply
|
|
||||||
return rv
|
|
||||||
|
|
||||||
|
|
||||||
def installconsole(defaultshow = 1):
|
|
||||||
global console
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
if not prefs.console or not hasattr(prefs.console, 'show'):
|
|
||||||
prefs.console.show = defaultshow
|
|
||||||
if not hasattr(prefs.console, "windowbounds"):
|
|
||||||
prefs.console.windowbounds = (450, 250)
|
|
||||||
if not hasattr(prefs.console, "fontsettings"):
|
|
||||||
prefs.console.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
|
|
||||||
if not hasattr(prefs.console, "tabsettings"):
|
|
||||||
prefs.console.tabsettings = (32, 0)
|
|
||||||
console = PyConsole(prefs.console.windowbounds, prefs.console.show,
|
|
||||||
prefs.console.fontsettings, prefs.console.tabsettings, 1)
|
|
||||||
|
|
||||||
def installoutput(defaultshow = 0, OutPutWindow = PyOutput):
|
|
||||||
global output
|
|
||||||
|
|
||||||
# quick 'n' dirty std in emulation
|
|
||||||
sys.stdin = SimpleStdin()
|
|
||||||
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
if not prefs.output or not hasattr(prefs.output, 'show'):
|
|
||||||
prefs.output.show = defaultshow
|
|
||||||
if not hasattr(prefs.output, "windowbounds"):
|
|
||||||
prefs.output.windowbounds = (450, 250)
|
|
||||||
if not hasattr(prefs.output, "fontsettings"):
|
|
||||||
prefs.output.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
|
|
||||||
if not hasattr(prefs.output, "tabsettings"):
|
|
||||||
prefs.output.tabsettings = (32, 0)
|
|
||||||
output = OutPutWindow(prefs.output.windowbounds, prefs.output.show,
|
|
||||||
prefs.output.fontsettings, prefs.output.tabsettings)
|
|
|
@ -1,897 +0,0 @@
|
||||||
import sys
|
|
||||||
import bdb
|
|
||||||
import types
|
|
||||||
import os
|
|
||||||
|
|
||||||
import W
|
|
||||||
import WASTEconst
|
|
||||||
import PyBrowser
|
|
||||||
from Carbon import Qd
|
|
||||||
from Carbon import Evt
|
|
||||||
from Carbon import Lists
|
|
||||||
import MacOS
|
|
||||||
_filenames = {}
|
|
||||||
|
|
||||||
SIMPLE_TYPES = (
|
|
||||||
types.NoneType,
|
|
||||||
types.IntType,
|
|
||||||
types.LongType,
|
|
||||||
types.FloatType,
|
|
||||||
types.ComplexType,
|
|
||||||
types.StringType
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Debugger(bdb.Bdb):
|
|
||||||
|
|
||||||
def __init__(self, title = 'Debugger'):
|
|
||||||
bdb.Bdb.__init__(self)
|
|
||||||
self.closed = 1
|
|
||||||
self.title = title
|
|
||||||
self.breaksviewer = None
|
|
||||||
self.reset()
|
|
||||||
self.tracing = 0
|
|
||||||
self.tracingmonitortime = Evt.TickCount()
|
|
||||||
self.editors = {}
|
|
||||||
|
|
||||||
prefs = W.getapplication().getprefs()
|
|
||||||
if prefs.debugger:
|
|
||||||
for file, breaks in prefs.debugger.breaks.items():
|
|
||||||
for b in breaks:
|
|
||||||
self.set_break(file, b)
|
|
||||||
self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings
|
|
||||||
self.tracemagic = prefs.debugger.tracemagic
|
|
||||||
else:
|
|
||||||
self.breaks = {}
|
|
||||||
self.horpanes = (0.4, 0.6)
|
|
||||||
self.verpanes = (0.3, 0.35, 0.35)
|
|
||||||
self.bounds = (600, 400)
|
|
||||||
self.tracemagic = 0
|
|
||||||
self.laststacksel = None
|
|
||||||
|
|
||||||
def canonic(self, filename):
|
|
||||||
# override: the provided canonic() method breaks our
|
|
||||||
# file-less Untitled windows
|
|
||||||
return filename
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self.currentframe = None
|
|
||||||
self.file = None
|
|
||||||
self.laststack = None
|
|
||||||
self.reason = 'Not running'
|
|
||||||
self.continuewithoutdebugger = 0
|
|
||||||
bdb.Bdb.reset(self)
|
|
||||||
self.forget()
|
|
||||||
|
|
||||||
def start(self, bottomframe = None, running = 0):
|
|
||||||
W.getapplication().DebuggerQuit = bdb.BdbQuit
|
|
||||||
from Carbon import Menu
|
|
||||||
Menu.HiliteMenu(0)
|
|
||||||
if self.closed:
|
|
||||||
self.setupwidgets(self.title)
|
|
||||||
self.closed = 0
|
|
||||||
if not self.w.parent.debugger_quitting:
|
|
||||||
self.w.select()
|
|
||||||
raise W.AlertError, 'There is another debugger session busy.'
|
|
||||||
self.reset()
|
|
||||||
self.botframe = bottomframe
|
|
||||||
if running:
|
|
||||||
self.set_continue()
|
|
||||||
self.reason = 'Running\xc9'
|
|
||||||
self.setstate('running')
|
|
||||||
else:
|
|
||||||
self.set_step()
|
|
||||||
self.reason = 'stopped'
|
|
||||||
self.setstate('stopped')
|
|
||||||
sys.settrace(self.trace_dispatch)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.set_quit()
|
|
||||||
if self.w.parent:
|
|
||||||
self.exit_mainloop()
|
|
||||||
self.resetwidgets()
|
|
||||||
|
|
||||||
def set_continue_without_debugger(self):
|
|
||||||
sys.settrace(None)
|
|
||||||
self.set_quit()
|
|
||||||
self.clear_tracefuncs()
|
|
||||||
self.continuewithoutdebugger = 1
|
|
||||||
if hasattr(self, "w") and self.w.parent:
|
|
||||||
self.exit_mainloop()
|
|
||||||
self.resetwidgets()
|
|
||||||
|
|
||||||
def clear_tracefuncs(self):
|
|
||||||
try:
|
|
||||||
raise 'spam'
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
tb = sys.exc_info()[2]
|
|
||||||
frame = tb.tb_frame
|
|
||||||
while frame is not None:
|
|
||||||
del frame.f_trace
|
|
||||||
frame = frame.f_back
|
|
||||||
|
|
||||||
def postmortem(self, exc_type, exc_value, traceback):
|
|
||||||
if self.closed:
|
|
||||||
self.setupwidgets(self.title)
|
|
||||||
self.closed = 0
|
|
||||||
if not self.w.parent.debugger_quitting:
|
|
||||||
raise W.AlertError, 'There is another debugger session busy.'
|
|
||||||
self.reset()
|
|
||||||
if traceback:
|
|
||||||
self.botframe = traceback.tb_frame
|
|
||||||
while traceback.tb_next <> None:
|
|
||||||
traceback = traceback.tb_next
|
|
||||||
frame = traceback.tb_frame
|
|
||||||
else:
|
|
||||||
self.botframe = None
|
|
||||||
frame = None
|
|
||||||
self.w.panes.bottom.buttons.killbutton.enable(1)
|
|
||||||
self.reason = '(dead) ' + self.formatexception(exc_type, exc_value)
|
|
||||||
self.w.select()
|
|
||||||
self.setup(frame, traceback)
|
|
||||||
self.setstate('dead')
|
|
||||||
self.showstack(self.curindex)
|
|
||||||
self.showframe(self.curindex)
|
|
||||||
|
|
||||||
def setupwidgets(self, title):
|
|
||||||
self.w = w = W.Window(self.bounds, title, minsize = (500, 300))
|
|
||||||
|
|
||||||
w.panes = W.HorizontalPanes((8, 4, -8, -8), self.horpanes)
|
|
||||||
|
|
||||||
w.panes.browserpanes = browserpanes = W.VerticalPanes(None, self.verpanes)
|
|
||||||
|
|
||||||
browserpanes.stacklist = W.Group(None)
|
|
||||||
browserpanes.stacklist.title = W.TextBox((4, 0, 0, 12), 'Stack')
|
|
||||||
browserpanes.stacklist.stack = W.List((0, 16, 0, 0), callback = self.do_stack, flags = Lists.lOnlyOne)
|
|
||||||
|
|
||||||
browserpanes.locals = W.Group(None)
|
|
||||||
browserpanes.locals.title = W.TextBox((4, 0, 0, 12), 'Local variables')
|
|
||||||
browserpanes.locals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
|
|
||||||
|
|
||||||
browserpanes.globals = W.Group(None)
|
|
||||||
browserpanes.globals.title = W.TextBox((4, 0, 0, 12), 'Global variables')
|
|
||||||
browserpanes.globals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
|
|
||||||
|
|
||||||
w.panes.bottom = bottom = W.Group(None)
|
|
||||||
bottom.src = src = W.Group((0, 64, 0, 0))
|
|
||||||
source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self)
|
|
||||||
src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), [])
|
|
||||||
src.optionsmenu.bind('<click>', self.makeoptionsmenu)
|
|
||||||
|
|
||||||
src._barx = W.Scrollbar((0, -16, -15, 16), source.hscroll, max = 32767)
|
|
||||||
src._bary = W.Scrollbar((-16, 15, 16, -15), source.vscroll, max = 32767)
|
|
||||||
src.source = source
|
|
||||||
src.frame = W.Frame((0, 0, -15, -15))
|
|
||||||
|
|
||||||
bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6))
|
|
||||||
bottom.state = W.TextBox((12, 24, 0, 16), self.reason)
|
|
||||||
|
|
||||||
bottom.srctitle = W.TextBox((12, 44, 0, 16))
|
|
||||||
bottom.buttons = buttons = W.Group((12, 0, 0, 20))
|
|
||||||
|
|
||||||
buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run)
|
|
||||||
buttons.stopbutton = W.Button((58, 0, 50, 16), "Stop", self.do_stop)
|
|
||||||
buttons.killbutton = W.Button((116, 0, 50, 16), "Kill", self.do_kill)
|
|
||||||
buttons.line = W.VerticalLine((173, 0, 0, 0))
|
|
||||||
buttons.stepbutton = W.Button((181, 0, 60, 16), "Step", self.do_step)
|
|
||||||
buttons.stepinbutton = W.Button((249, 0, 60, 16), "Step in", self.do_stepin)
|
|
||||||
buttons.stepoutbutton = W.Button((317, 0, 60, 16), "Step out", self.do_stepout)
|
|
||||||
|
|
||||||
w.bind('cmdr', buttons.runbutton.push)
|
|
||||||
w.bind('cmd.', buttons.stopbutton.push)
|
|
||||||
w.bind('cmdk', buttons.killbutton.push)
|
|
||||||
w.bind('cmds', buttons.stepbutton.push)
|
|
||||||
w.bind('cmdt', buttons.stepinbutton.push)
|
|
||||||
w.bind('cmdu', buttons.stepoutbutton.push)
|
|
||||||
|
|
||||||
w.bind('<close>', self.close)
|
|
||||||
|
|
||||||
w.open()
|
|
||||||
w.xxx___select(w.panes.bottom.src.source)
|
|
||||||
|
|
||||||
def makeoptionsmenu(self):
|
|
||||||
options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints),
|
|
||||||
('Clear all breakpoints', self.clear_all_breaks),
|
|
||||||
('Edit breakpoints\xc9', self.edit_breaks), '-',
|
|
||||||
(self.tracemagic and
|
|
||||||
'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)]
|
|
||||||
self.w.panes.bottom.src.optionsmenu.set(options)
|
|
||||||
|
|
||||||
def edit_breaks(self):
|
|
||||||
if self.breaksviewer:
|
|
||||||
self.breaksviewer.select()
|
|
||||||
else:
|
|
||||||
self.breaksviewer = BreakpointsViewer(self)
|
|
||||||
|
|
||||||
def togglemagic(self):
|
|
||||||
self.tracemagic = not self.tracemagic
|
|
||||||
|
|
||||||
def setstate(self, state):
|
|
||||||
self.w.panes.bottom.tracingmonitor.reset()
|
|
||||||
self.w.panes.bottom.state.set(self.reason)
|
|
||||||
buttons = self.w.panes.bottom.buttons
|
|
||||||
if state == 'stopped':
|
|
||||||
buttons.runbutton.enable(1)
|
|
||||||
buttons.stopbutton.enable(0)
|
|
||||||
buttons.killbutton.enable(1)
|
|
||||||
buttons.stepbutton.enable(1)
|
|
||||||
buttons.stepinbutton.enable(1)
|
|
||||||
buttons.stepoutbutton.enable(1)
|
|
||||||
elif state == 'running':
|
|
||||||
buttons.runbutton.enable(0)
|
|
||||||
buttons.stopbutton.enable(1)
|
|
||||||
buttons.killbutton.enable(1)
|
|
||||||
buttons.stepbutton.enable(0)
|
|
||||||
buttons.stepinbutton.enable(0)
|
|
||||||
buttons.stepoutbutton.enable(0)
|
|
||||||
elif state == 'idle':
|
|
||||||
buttons.runbutton.enable(0)
|
|
||||||
buttons.stopbutton.enable(0)
|
|
||||||
buttons.killbutton.enable(0)
|
|
||||||
buttons.stepbutton.enable(0)
|
|
||||||
buttons.stepinbutton.enable(0)
|
|
||||||
buttons.stepoutbutton.enable(0)
|
|
||||||
elif state == 'dead':
|
|
||||||
buttons.runbutton.enable(0)
|
|
||||||
buttons.stopbutton.enable(0)
|
|
||||||
buttons.killbutton.enable(1)
|
|
||||||
buttons.stepbutton.enable(0)
|
|
||||||
buttons.stepinbutton.enable(0)
|
|
||||||
buttons.stepoutbutton.enable(0)
|
|
||||||
else:
|
|
||||||
print 'unknown state:', state
|
|
||||||
|
|
||||||
def resetwidgets(self):
|
|
||||||
self.reason = ''
|
|
||||||
self.w.panes.bottom.srctitle.set('')
|
|
||||||
self.w.panes.bottom.src.source.set('')
|
|
||||||
self.w.panes.browserpanes.stacklist.stack.set([])
|
|
||||||
self.w.panes.browserpanes.locals.browser.set({})
|
|
||||||
self.w.panes.browserpanes.globals.browser.set({})
|
|
||||||
self.setstate('idle')
|
|
||||||
|
|
||||||
# W callbacks
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.set_quit()
|
|
||||||
self.exit_mainloop()
|
|
||||||
self.closed = 1
|
|
||||||
|
|
||||||
self.unregister_editor(self.w.panes.bottom.src.source,
|
|
||||||
self.w.panes.bottom.src.source.file)
|
|
||||||
self.horpanes = self.w.panes.getpanesizes()
|
|
||||||
self.verpanes = self.w.panes.browserpanes.getpanesizes()
|
|
||||||
self.bounds = self.w.getbounds()
|
|
||||||
prefs = W.getapplication().getprefs()
|
|
||||||
prefs.debugger.breaks = self.breaks
|
|
||||||
prefs.debugger.windowsettings = self.bounds, self.horpanes, self.verpanes
|
|
||||||
prefs.debugger.tracemagic = self.tracemagic
|
|
||||||
prefs.save()
|
|
||||||
|
|
||||||
# stack list callback
|
|
||||||
|
|
||||||
def do_stack(self, isdbl):
|
|
||||||
sel = self.w.panes.browserpanes.stacklist.stack.getselection()
|
|
||||||
if isdbl:
|
|
||||||
if sel:
|
|
||||||
frame, lineno = self.stack[sel[0] + 1]
|
|
||||||
filename = frame.f_code.co_filename
|
|
||||||
editor = self.w._parentwindow.parent.openscript(filename, lineno)
|
|
||||||
if self.breaks.has_key(filename):
|
|
||||||
editor.showbreakpoints(1)
|
|
||||||
else:
|
|
||||||
if sel and sel <> self.laststacksel:
|
|
||||||
self.showframe(sel[0] + 1)
|
|
||||||
self.laststacksel = sel
|
|
||||||
|
|
||||||
def geteditor(self, filename):
|
|
||||||
if filename[:1] == '<' and filename[-1:] == '>':
|
|
||||||
editor = W.getapplication().getscript(filename[1:-1])
|
|
||||||
else:
|
|
||||||
editor = W.getapplication().getscript(filename)
|
|
||||||
return editor
|
|
||||||
|
|
||||||
# button callbacks
|
|
||||||
|
|
||||||
def do_run(self):
|
|
||||||
self.running()
|
|
||||||
self.set_continue()
|
|
||||||
self.exit_mainloop()
|
|
||||||
|
|
||||||
def do_stop(self):
|
|
||||||
self.set_step()
|
|
||||||
|
|
||||||
def do_kill(self):
|
|
||||||
self.set_quit()
|
|
||||||
self.exit_mainloop()
|
|
||||||
self.resetwidgets()
|
|
||||||
|
|
||||||
def do_step(self):
|
|
||||||
self.running()
|
|
||||||
self.set_next(self.curframe)
|
|
||||||
self.exit_mainloop()
|
|
||||||
|
|
||||||
def do_stepin(self):
|
|
||||||
self.running()
|
|
||||||
self.set_step()
|
|
||||||
self.exit_mainloop()
|
|
||||||
|
|
||||||
def do_stepout(self):
|
|
||||||
self.running()
|
|
||||||
self.set_return(self.curframe)
|
|
||||||
self.exit_mainloop()
|
|
||||||
|
|
||||||
def running(self):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
self.reason = 'Running\xc9'
|
|
||||||
self.setstate('running')
|
|
||||||
#self.w.panes.bottom.src.source.set('')
|
|
||||||
#self.w.panes.browserpanes.stacklist.stack.set([])
|
|
||||||
#self.w.panes.browserpanes.locals.browser.set({})
|
|
||||||
#self.w.panes.browserpanes.globals.browser.set({})
|
|
||||||
|
|
||||||
def exit_mainloop(self):
|
|
||||||
self.w.parent.debugger_quitting = 1
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
def showframe(self, stackindex):
|
|
||||||
(frame, lineno) = self.stack[stackindex]
|
|
||||||
W.SetCursor('watch')
|
|
||||||
filename = frame.f_code.co_filename
|
|
||||||
if filename <> self.file:
|
|
||||||
editor = self.geteditor(filename)
|
|
||||||
if editor:
|
|
||||||
self.w.panes.bottom.src.source.set(editor.get(), filename)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
f = open(filename, 'rU')
|
|
||||||
data = f.read()
|
|
||||||
f.close()
|
|
||||||
except IOError:
|
|
||||||
if filename[-3:] == '.py':
|
|
||||||
import imp
|
|
||||||
modname = os.path.basename(filename)[:-3]
|
|
||||||
try:
|
|
||||||
f, filename, (suff, mode, dummy) = imp.find_module(modname)
|
|
||||||
except ImportError:
|
|
||||||
self.w.panes.bottom.src.source.set("can't find file")
|
|
||||||
else:
|
|
||||||
if f:
|
|
||||||
f.close()
|
|
||||||
if f and suff == '.py':
|
|
||||||
f = open(filename, 'rU')
|
|
||||||
data = f.read()
|
|
||||||
f.close()
|
|
||||||
self.w.panes.bottom.src.source.set(data, filename)
|
|
||||||
else:
|
|
||||||
self.w.panes.bottom.src.source.set("can't find file")
|
|
||||||
else:
|
|
||||||
self.w.panes.bottom.src.source.set("can't find file")
|
|
||||||
else:
|
|
||||||
data = data.replace('\n', '\r')
|
|
||||||
self.w.panes.bottom.src.source.set(data, filename)
|
|
||||||
self.file = filename
|
|
||||||
self.w.panes.bottom.srctitle.set('Source: ' + filename + ((lineno > 0) and (' (line %d)' % lineno) or ' '))
|
|
||||||
self.goto_line(lineno)
|
|
||||||
self.lineno = lineno
|
|
||||||
self.showvars((frame, lineno))
|
|
||||||
|
|
||||||
def showvars(self, (frame, lineno)):
|
|
||||||
if frame.f_locals is not frame.f_globals:
|
|
||||||
locals = frame.f_locals
|
|
||||||
else:
|
|
||||||
locals = {'Same as Globals':''}
|
|
||||||
filteredlocals = {}
|
|
||||||
for key, value in locals.items():
|
|
||||||
# empty key is magic for Python 1.4; '.' is magic for 1.5...
|
|
||||||
if not key or key[0] <> '.':
|
|
||||||
filteredlocals[key] = value
|
|
||||||
self.w.panes.browserpanes.locals.browser.set(filteredlocals)
|
|
||||||
self.w.panes.browserpanes.globals.browser.set(frame.f_globals)
|
|
||||||
|
|
||||||
def showstack(self, stackindex):
|
|
||||||
stack = []
|
|
||||||
for frame, lineno in self.stack[1:]:
|
|
||||||
filename = frame.f_code.co_filename
|
|
||||||
try:
|
|
||||||
filename = _filenames[filename]
|
|
||||||
except KeyError:
|
|
||||||
if filename[:1] + filename[-1:] <> '<>':
|
|
||||||
filename = os.path.basename(filename)
|
|
||||||
_filenames[frame.f_code.co_filename] = filename
|
|
||||||
funcname = frame.f_code.co_name
|
|
||||||
if funcname == '?':
|
|
||||||
funcname = '<toplevel>'
|
|
||||||
stack.append(filename + ': ' + funcname)
|
|
||||||
if stack <> self.laststack:
|
|
||||||
self.w.panes.browserpanes.stacklist.stack.set(stack)
|
|
||||||
self.laststack = stack
|
|
||||||
sel = [stackindex - 1]
|
|
||||||
self.w.panes.browserpanes.stacklist.stack.setselection(sel)
|
|
||||||
self.laststacksel = sel
|
|
||||||
|
|
||||||
def goto_line(self, lineno):
|
|
||||||
if lineno > 0:
|
|
||||||
self.w.panes.bottom.src.source.selectline(lineno - 1)
|
|
||||||
else:
|
|
||||||
self.w.panes.bottom.src.source.setselection(0, 0)
|
|
||||||
|
|
||||||
# bdb entry points
|
|
||||||
|
|
||||||
# def user_call(self, frame, argument_list):
|
|
||||||
# self.reason = 'Calling'
|
|
||||||
# self.interaction(frame, None)
|
|
||||||
|
|
||||||
def user_line(self, frame):
|
|
||||||
# This function is called when we stop or break at this line
|
|
||||||
self.reason = 'Stopped'
|
|
||||||
self.interaction(frame, None)
|
|
||||||
|
|
||||||
def user_return(self, frame, return_value):
|
|
||||||
# This function is called when a return trap is set here
|
|
||||||
fname = frame.f_code.co_name
|
|
||||||
if fname <> '?':
|
|
||||||
self.reason = 'Returning from %s()' % frame.f_code.co_name
|
|
||||||
frame.f_locals['__return__'] = return_value
|
|
||||||
elif frame.f_back is self.botframe:
|
|
||||||
self.reason = 'Done'
|
|
||||||
else:
|
|
||||||
self.reason = 'Returning'
|
|
||||||
self.interaction(frame, None, 1)
|
|
||||||
|
|
||||||
def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
|
|
||||||
# This function is called when we stop or break at this line
|
|
||||||
self.reason = self.formatexception(exc_type, exc_value)
|
|
||||||
self.interaction(frame, exc_traceback)
|
|
||||||
|
|
||||||
def formatexception(self, exc_type, exc_value):
|
|
||||||
if exc_type == SyntaxError:
|
|
||||||
try:
|
|
||||||
value, (filename, lineno, charno, line) = exc_value
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return str(exc_type) + ': ' + str(value)
|
|
||||||
if type(exc_type) == types.ClassType:
|
|
||||||
nice = exc_type.__name__
|
|
||||||
else:
|
|
||||||
nice = str(exc_type)
|
|
||||||
value = str(exc_value)
|
|
||||||
if exc_value and value:
|
|
||||||
nice = nice + ": " + value
|
|
||||||
return nice
|
|
||||||
|
|
||||||
def forget(self):
|
|
||||||
self.stack = []
|
|
||||||
self.curindex = 0
|
|
||||||
self.curframe = None
|
|
||||||
|
|
||||||
def setup(self, f, t, isreturning = 0):
|
|
||||||
self.forget()
|
|
||||||
self.stack, self.curindex = self.get_stack(f, t)
|
|
||||||
self.curframe = self.stack[self.curindex - isreturning][0]
|
|
||||||
|
|
||||||
def interaction(self, frame, traceback, isreturning = 0):
|
|
||||||
saveport = Qd.GetPort()
|
|
||||||
self.w.select()
|
|
||||||
try:
|
|
||||||
self.setup(frame, traceback, isreturning)
|
|
||||||
self.setstate('stopped')
|
|
||||||
stackindex = self.curindex
|
|
||||||
if isreturning:
|
|
||||||
if frame.f_back is not self.botframe:
|
|
||||||
stackindex = stackindex - 1
|
|
||||||
self.showstack(stackindex)
|
|
||||||
self.showframe(stackindex)
|
|
||||||
self.w.parent.debugger_mainloop()
|
|
||||||
self.forget()
|
|
||||||
finally:
|
|
||||||
Qd.SetPort(saveport)
|
|
||||||
|
|
||||||
# bdb customization
|
|
||||||
|
|
||||||
def trace_dispatch(self, frame, event, arg, TickCount = Evt.TickCount):
|
|
||||||
if TickCount() - self.tracingmonitortime > 15:
|
|
||||||
self.tracingmonitortime = TickCount()
|
|
||||||
self.w.panes.bottom.tracingmonitor.toggle()
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(0)
|
|
||||||
if self.quitting:
|
|
||||||
# returning None is not enough, a former BdbQuit exception
|
|
||||||
# might have been eaten by the print statement
|
|
||||||
raise bdb.BdbQuit
|
|
||||||
if event == 'line':
|
|
||||||
return self.dispatch_line(frame)
|
|
||||||
if event == 'call':
|
|
||||||
return self.dispatch_call(frame, arg)
|
|
||||||
if event == 'return':
|
|
||||||
return self.dispatch_return(frame, arg)
|
|
||||||
if event == 'exception':
|
|
||||||
return self.dispatch_exception(frame, arg)
|
|
||||||
print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
|
|
||||||
return self.trace_dispatch
|
|
||||||
finally:
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(-1)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
self.set_step()
|
|
||||||
return self.trace_dispatch
|
|
||||||
except bdb.BdbQuit:
|
|
||||||
if self.continuewithoutdebugger:
|
|
||||||
self.clear_tracefuncs()
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
raise bdb.BdbQuit
|
|
||||||
except:
|
|
||||||
print 'XXX Exception during debugger interaction.', \
|
|
||||||
self.formatexception(sys.exc_info[:2])
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
return self.trace_dispatch
|
|
||||||
|
|
||||||
def dispatch_call(self, frame, arg):
|
|
||||||
if not self.tracemagic and \
|
|
||||||
frame.f_code.co_name[:2] == '__' == frame.f_code.co_name[-2:] and \
|
|
||||||
frame.f_code.co_name <> '__init__':
|
|
||||||
return
|
|
||||||
if self.botframe is None:
|
|
||||||
# First call of dispatch since reset()
|
|
||||||
self.botframe = frame.f_back # xxx !!! added f_back
|
|
||||||
return self.trace_dispatch
|
|
||||||
if not (self.stop_here(frame) or self.break_anywhere(frame)):
|
|
||||||
# No need to trace this function
|
|
||||||
return # None
|
|
||||||
self.user_call(frame, arg)
|
|
||||||
if self.quitting:
|
|
||||||
raise bdb.BdbQuit
|
|
||||||
return self.trace_dispatch
|
|
||||||
|
|
||||||
def set_continue(self):
|
|
||||||
# Don't stop except at breakpoints or when finished
|
|
||||||
self.stopframe = self.botframe
|
|
||||||
self.returnframe = None
|
|
||||||
self.quitting = 0
|
|
||||||
# unlike in bdb/pdb, there's a chance that breakpoints change
|
|
||||||
# *while* a program (this program ;-) is running. It's actually quite likely.
|
|
||||||
# So we don't delete frame.f_trace until the bottom frame if there are no breakpoints.
|
|
||||||
|
|
||||||
def set_break(self, filename, lineno):
|
|
||||||
if not self.breaks.has_key(filename):
|
|
||||||
self.breaks[filename] = []
|
|
||||||
list = self.breaks[filename]
|
|
||||||
if lineno in list:
|
|
||||||
return 'There is already a breakpoint there!'
|
|
||||||
list.append(lineno)
|
|
||||||
list.sort() # I want to keep them neatly sorted; easier for drawing
|
|
||||||
if hasattr(bdb, "Breakpoint"):
|
|
||||||
# 1.5.2b1 specific
|
|
||||||
bp = bdb.Breakpoint(filename, lineno, 0, None)
|
|
||||||
self.update_breaks(filename)
|
|
||||||
|
|
||||||
def clear_break(self, filename, lineno):
|
|
||||||
bdb.Bdb.clear_break(self, filename, lineno)
|
|
||||||
self.update_breaks(filename)
|
|
||||||
|
|
||||||
def clear_all_file_breaks(self, filename):
|
|
||||||
bdb.Bdb.clear_all_file_breaks(self, filename)
|
|
||||||
self.update_breaks(filename)
|
|
||||||
|
|
||||||
def clear_all_breaks(self):
|
|
||||||
bdb.Bdb.clear_all_breaks(self)
|
|
||||||
for editors in self.editors.values():
|
|
||||||
for editor in editors:
|
|
||||||
editor.drawbreakpoints()
|
|
||||||
|
|
||||||
# special
|
|
||||||
|
|
||||||
def toggle_break(self, filename, lineno):
|
|
||||||
if self.get_break(filename, lineno):
|
|
||||||
self.clear_break(filename, lineno)
|
|
||||||
else:
|
|
||||||
self.set_break(filename, lineno)
|
|
||||||
|
|
||||||
def clear_breaks_above(self, filename, above):
|
|
||||||
if not self.breaks.has_key(filename):
|
|
||||||
return 'There are no breakpoints in that file!'
|
|
||||||
for lineno in self.breaks[filename][:]:
|
|
||||||
if lineno > above:
|
|
||||||
self.breaks[filename].remove(lineno)
|
|
||||||
if not self.breaks[filename]:
|
|
||||||
del self.breaks[filename]
|
|
||||||
|
|
||||||
# editor stuff
|
|
||||||
|
|
||||||
def update_breaks(self, filename):
|
|
||||||
if self.breaksviewer:
|
|
||||||
self.breaksviewer.update()
|
|
||||||
if self.editors.has_key(filename):
|
|
||||||
for editor in self.editors[filename]:
|
|
||||||
if editor._debugger: # XXX
|
|
||||||
editor.drawbreakpoints()
|
|
||||||
else:
|
|
||||||
print 'xxx dead editor!'
|
|
||||||
|
|
||||||
def update_allbreaks(self):
|
|
||||||
if self.breaksviewer:
|
|
||||||
self.breaksviewer.update()
|
|
||||||
for filename in self.breaks.keys():
|
|
||||||
if self.editors.has_key(filename):
|
|
||||||
for editor in self.editors[filename]:
|
|
||||||
if editor._debugger: # XXX
|
|
||||||
editor.drawbreakpoints()
|
|
||||||
else:
|
|
||||||
print 'xxx dead editor!'
|
|
||||||
|
|
||||||
def register_editor(self, editor, filename):
|
|
||||||
if not filename:
|
|
||||||
return
|
|
||||||
if not self.editors.has_key(filename):
|
|
||||||
self.editors[filename] = [editor]
|
|
||||||
elif editor not in self.editors[filename]:
|
|
||||||
self.editors[filename].append(editor)
|
|
||||||
|
|
||||||
def unregister_editor(self, editor, filename):
|
|
||||||
if not filename:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self.editors[filename].remove(editor)
|
|
||||||
if not self.editors[filename]:
|
|
||||||
del self.editors[filename]
|
|
||||||
# if this was an untitled window, clear the breaks.
|
|
||||||
if filename[:1] == '<' and filename[-1:] == '>' and \
|
|
||||||
self.breaks.has_key(filename):
|
|
||||||
self.clear_all_file_breaks(filename)
|
|
||||||
except (KeyError, ValueError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SourceViewer(W.PyEditor):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
W.PyEditor.__init__(self, *args, **kwargs)
|
|
||||||
self.bind('<click>', self.clickintercept)
|
|
||||||
|
|
||||||
def clickintercept(self, point, modifiers):
|
|
||||||
if self._parentwindow._currentwidget <> self and not self.pt_in_breaks(point):
|
|
||||||
self._parentwindow.xxx___select(self)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def _getviewrect(self):
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
if self._debugger:
|
|
||||||
return (l + 12, t + 2, r - 1, b - 2)
|
|
||||||
else:
|
|
||||||
return (l + 5, t + 2, r - 1, b - 2)
|
|
||||||
|
|
||||||
def select(self, onoff, isclick = 0):
|
|
||||||
if W.SelectableWidget.select(self, onoff):
|
|
||||||
return
|
|
||||||
self.SetPort()
|
|
||||||
#if onoff:
|
|
||||||
# self.ted.WEActivate()
|
|
||||||
#else:
|
|
||||||
# self.ted.WEDeactivate()
|
|
||||||
self.drawselframe(onoff)
|
|
||||||
|
|
||||||
def drawselframe(self, onoff):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class BreakpointsViewer:
|
|
||||||
|
|
||||||
def __init__(self, debugger):
|
|
||||||
self.debugger = debugger
|
|
||||||
self.w = W.Window((300, 250), 'Breakpoints', minsize = (200, 200))
|
|
||||||
self.w.panes = W.HorizontalPanes((8, 8, -8, -32), (0.3, 0.7))
|
|
||||||
self.w.panes.files = W.List(None, callback = self.filehit) #, flags = Lists.lOnlyOne)
|
|
||||||
self.w.panes.gr = W.Group(None)
|
|
||||||
self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit) #, flags = Lists.lOnlyOne)
|
|
||||||
self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit)
|
|
||||||
self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit)
|
|
||||||
|
|
||||||
self.w.bind('<close>', self.close)
|
|
||||||
self.w.bind('backspace', self.w.panes.gr.deletebutton.push)
|
|
||||||
|
|
||||||
self.setup()
|
|
||||||
self.w.open()
|
|
||||||
self.w.panes.gr.openbutton.enable(0)
|
|
||||||
self.w.panes.gr.deletebutton.enable(0)
|
|
||||||
self.curfile = None
|
|
||||||
|
|
||||||
def deletebuttonhit(self):
|
|
||||||
if self.w._currentwidget == self.w.panes.files:
|
|
||||||
self.del_filename()
|
|
||||||
else:
|
|
||||||
self.del_number()
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def del_number(self):
|
|
||||||
if self.curfile is None:
|
|
||||||
return
|
|
||||||
sel = self.w.panes.gr.breaks.getselectedobjects()
|
|
||||||
for lineno in sel:
|
|
||||||
self.debugger.clear_break(self.curfile, lineno)
|
|
||||||
|
|
||||||
def del_filename(self):
|
|
||||||
sel = self.w.panes.files.getselectedobjects()
|
|
||||||
for filename in sel:
|
|
||||||
self.debugger.clear_all_file_breaks(filename)
|
|
||||||
self.debugger.update_allbreaks()
|
|
||||||
|
|
||||||
def setup(self):
|
|
||||||
files = self.debugger.breaks.keys()
|
|
||||||
files.sort()
|
|
||||||
self.w.panes.files.set(files)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.debugger.breaksviewer = None
|
|
||||||
self.debugger = None
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
sel = self.w.panes.files.getselectedobjects()
|
|
||||||
self.setup()
|
|
||||||
self.w.panes.files.setselectedobjects(sel)
|
|
||||||
sel = self.w.panes.files.getselection()
|
|
||||||
if len(sel) == 0 and self.curfile:
|
|
||||||
self.w.panes.files.setselectedobjects([self.curfile])
|
|
||||||
self.filehit(0)
|
|
||||||
|
|
||||||
def select(self):
|
|
||||||
self.w.select()
|
|
||||||
|
|
||||||
def selectfile(self, file):
|
|
||||||
self.w.panes.files.setselectedobjects([file])
|
|
||||||
self.filehit(0)
|
|
||||||
|
|
||||||
def openbuttonhit(self):
|
|
||||||
self.filehit(1)
|
|
||||||
|
|
||||||
def filehit(self, isdbl):
|
|
||||||
sel = self.w.panes.files.getselectedobjects()
|
|
||||||
if isdbl:
|
|
||||||
for filename in sel:
|
|
||||||
lineno = None
|
|
||||||
if filename == self.curfile:
|
|
||||||
linesel = self.w.panes.gr.breaks.getselectedobjects()
|
|
||||||
if linesel:
|
|
||||||
lineno = linesel[-1]
|
|
||||||
elif self.w.panes.gr.breaks:
|
|
||||||
lineno = self.w.panes.gr.breaks[0]
|
|
||||||
editor = self.w._parentwindow.parent.openscript(filename, lineno)
|
|
||||||
editor.showbreakpoints(1)
|
|
||||||
return
|
|
||||||
if len(sel) == 1:
|
|
||||||
file = sel[0]
|
|
||||||
filebreaks = self.debugger.breaks[file][:]
|
|
||||||
if self.curfile == file:
|
|
||||||
linesel = self.w.panes.gr.breaks.getselectedobjects()
|
|
||||||
self.w.panes.gr.breaks.set(filebreaks)
|
|
||||||
if self.curfile == file:
|
|
||||||
self.w.panes.gr.breaks.setselectedobjects(linesel)
|
|
||||||
self.curfile = file
|
|
||||||
else:
|
|
||||||
if len(sel) <> 0:
|
|
||||||
self.curfile = None
|
|
||||||
self.w.panes.gr.breaks.set([])
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def linehit(self, isdbl):
|
|
||||||
if isdbl:
|
|
||||||
files = self.w.panes.files.getselectedobjects()
|
|
||||||
if len(files) <> 1:
|
|
||||||
return
|
|
||||||
filename = files[0]
|
|
||||||
linenos = self.w.panes.gr.breaks.getselectedobjects()
|
|
||||||
if not linenos:
|
|
||||||
return
|
|
||||||
lineno = linenos[-1]
|
|
||||||
editor = self.w._parentwindow.parent.openscript(filename, lineno)
|
|
||||||
editor.showbreakpoints(1)
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def checkbuttons(self):
|
|
||||||
if self.w.panes.files.getselection():
|
|
||||||
self.w.panes.gr.openbutton.enable(1)
|
|
||||||
self.w._parentwindow.setdefaultbutton(self.w.panes.gr.openbutton)
|
|
||||||
if self.w._currentwidget == self.w.panes.files:
|
|
||||||
if self.w.panes.files.getselection():
|
|
||||||
self.w.panes.gr.deletebutton.enable(1)
|
|
||||||
else:
|
|
||||||
self.w.panes.gr.deletebutton.enable(0)
|
|
||||||
else:
|
|
||||||
if self.w.panes.gr.breaks.getselection():
|
|
||||||
self.w.panes.gr.deletebutton.enable(1)
|
|
||||||
else:
|
|
||||||
self.w.panes.gr.deletebutton.enable(0)
|
|
||||||
else:
|
|
||||||
self.w.panes.gr.openbutton.enable(0)
|
|
||||||
self.w.panes.gr.deletebutton.enable(0)
|
|
||||||
|
|
||||||
|
|
||||||
class TracingMonitor(W.Widget):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
W.Widget.__init__(self, *args, **kwargs)
|
|
||||||
self.state = 0
|
|
||||||
|
|
||||||
def toggle(self):
|
|
||||||
if hasattr(self, "_parentwindow") and self._parentwindow is not None:
|
|
||||||
self.state = self.state % 2 + 1
|
|
||||||
port = Qd.GetPort()
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
Qd.SetPort(port)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
if self._parentwindow:
|
|
||||||
self.state = 0
|
|
||||||
port = Qd.GetPort()
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
Qd.SetPort(port)
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self.state == 2:
|
|
||||||
Qd.PaintOval(self._bounds)
|
|
||||||
else:
|
|
||||||
Qd.EraseOval(self._bounds)
|
|
||||||
|
|
||||||
|
|
||||||
# convenience funcs
|
|
||||||
|
|
||||||
def postmortem(exc_type, exc_value, tb):
|
|
||||||
d = getdebugger()
|
|
||||||
d.postmortem(exc_type, exc_value, tb)
|
|
||||||
|
|
||||||
def start(bottomframe = None):
|
|
||||||
d = getdebugger()
|
|
||||||
d.start(bottomframe)
|
|
||||||
|
|
||||||
def startfromhere():
|
|
||||||
d = getdebugger()
|
|
||||||
try:
|
|
||||||
raise 'spam'
|
|
||||||
except:
|
|
||||||
tb = sys.exc_info()[2]
|
|
||||||
frame = tb.tb_frame.f_back
|
|
||||||
d.start(frame)
|
|
||||||
|
|
||||||
def startfrombottom():
|
|
||||||
d = getdebugger()
|
|
||||||
d.start(_getbottomframe(), 1)
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
d = getdebugger()
|
|
||||||
d.stop()
|
|
||||||
|
|
||||||
def cont():
|
|
||||||
sys.settrace(None)
|
|
||||||
d = getdebugger()
|
|
||||||
d.set_continue_without_debugger()
|
|
||||||
|
|
||||||
def _getbottomframe():
|
|
||||||
try:
|
|
||||||
raise 'spam'
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
tb = sys.exc_info()[2]
|
|
||||||
frame = tb.tb_frame
|
|
||||||
while 1:
|
|
||||||
if frame.f_code.co_name == 'mainloop' or frame.f_back is None:
|
|
||||||
break
|
|
||||||
frame = frame.f_back
|
|
||||||
return frame
|
|
||||||
|
|
||||||
_debugger = None
|
|
||||||
|
|
||||||
def getdebugger():
|
|
||||||
if not __debug__:
|
|
||||||
raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)"
|
|
||||||
global _debugger
|
|
||||||
if _debugger is None:
|
|
||||||
_debugger = Debugger()
|
|
||||||
return _debugger
|
|
|
@ -1,256 +0,0 @@
|
||||||
import re
|
|
||||||
import W
|
|
||||||
import os
|
|
||||||
import MacPrefs
|
|
||||||
import MacOS
|
|
||||||
import string
|
|
||||||
import webbrowser
|
|
||||||
import EasyDialogs
|
|
||||||
|
|
||||||
|
|
||||||
app = W.getapplication()
|
|
||||||
|
|
||||||
_titlepat = re.compile('<title>\([^<]*\)</title>')
|
|
||||||
|
|
||||||
def sucktitle(path):
|
|
||||||
f = open(path)
|
|
||||||
text = f.read(1024) # assume the title is in the first 1024 bytes
|
|
||||||
f.close()
|
|
||||||
lowertext = text.lower()
|
|
||||||
matcher = _titlepat.search(lowertext)
|
|
||||||
if matcher:
|
|
||||||
return matcher.group(1)
|
|
||||||
return path
|
|
||||||
|
|
||||||
def verifydocpath(docpath):
|
|
||||||
try:
|
|
||||||
tut = os.path.join(docpath, "tut")
|
|
||||||
lib = os.path.join(docpath, "lib")
|
|
||||||
ref = os.path.join(docpath, "ref")
|
|
||||||
for path in [tut, lib, ref]:
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return 0
|
|
||||||
except:
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
_resultscounter = 1
|
|
||||||
|
|
||||||
class Results:
|
|
||||||
|
|
||||||
def __init__(self, hits):
|
|
||||||
global _resultscounter
|
|
||||||
hits = map(lambda (path, hits): (sucktitle(path), path, hits), hits)
|
|
||||||
hits.sort()
|
|
||||||
self.hits = hits
|
|
||||||
nicehits = map(
|
|
||||||
lambda (title, path, hits):
|
|
||||||
title + '\r' + string.join(
|
|
||||||
map(lambda (c, p): "%s (%d)" % (p, c), hits), ', '), hits)
|
|
||||||
nicehits.sort()
|
|
||||||
self.w = W.Window((440, 300), "Search results %d" % _resultscounter, minsize = (200, 100))
|
|
||||||
self.w.results = W.TwoLineList((-1, -1, 1, -14), nicehits, self.listhit)
|
|
||||||
self.w.open()
|
|
||||||
self.w.bind('return', self.listhit)
|
|
||||||
self.w.bind('enter', self.listhit)
|
|
||||||
_resultscounter = _resultscounter + 1
|
|
||||||
|
|
||||||
def listhit(self, isdbl = 1):
|
|
||||||
if isdbl:
|
|
||||||
for i in self.w.results.getselection():
|
|
||||||
path = self.hits[i][1]
|
|
||||||
url = "file://" + "/".join(path.split(":"))
|
|
||||||
webbrowser.open(url)
|
|
||||||
|
|
||||||
|
|
||||||
class Status:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.w = W.Dialog((440, 64), "Searching\xc9")
|
|
||||||
self.w.searching = W.TextBox((4, 4, -4, 16), "")
|
|
||||||
self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0")
|
|
||||||
self.w.canceltip = W.TextBox((4, 44, -4, 16), "Type cmd-period (.) to cancel.")
|
|
||||||
self.w.open()
|
|
||||||
|
|
||||||
def set(self, path, hits):
|
|
||||||
self.w.searching.set(path)
|
|
||||||
self.w.hits.set('Hits: %r' % (hits,))
|
|
||||||
app.breathe()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.w.close()
|
|
||||||
|
|
||||||
|
|
||||||
def match(text, patterns, all):
|
|
||||||
hits = []
|
|
||||||
hitsappend = hits.append
|
|
||||||
stringcount = string.count
|
|
||||||
for pat in patterns:
|
|
||||||
c = stringcount(text, pat)
|
|
||||||
if c > 0:
|
|
||||||
hitsappend((c, pat))
|
|
||||||
elif all:
|
|
||||||
hits[:] = []
|
|
||||||
break
|
|
||||||
hits.sort()
|
|
||||||
hits.reverse()
|
|
||||||
return hits
|
|
||||||
|
|
||||||
|
|
||||||
def dosearch(docpath, searchstring, settings):
|
|
||||||
(docpath, kind, case, word, tut, lib, ref, ext, api) = settings
|
|
||||||
books = [(tut, 'tut'), (lib, 'lib'), (ref, 'ref'), (ext, 'ext'), (api, 'api')]
|
|
||||||
if not case:
|
|
||||||
searchstring = string.lower(searchstring)
|
|
||||||
|
|
||||||
if kind == 1:
|
|
||||||
patterns = string.split(searchstring)
|
|
||||||
all = 1
|
|
||||||
elif kind == 2:
|
|
||||||
patterns = string.split(searchstring)
|
|
||||||
all = 0
|
|
||||||
else:
|
|
||||||
patterns = [searchstring]
|
|
||||||
all = 0 # not relevant
|
|
||||||
|
|
||||||
ospathjoin = os.path.join
|
|
||||||
stringlower = string.lower
|
|
||||||
status = Status()
|
|
||||||
statusset = status.set
|
|
||||||
_match = match
|
|
||||||
_open = open
|
|
||||||
hits = {}
|
|
||||||
try:
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(0)
|
|
||||||
try:
|
|
||||||
for do, name in books:
|
|
||||||
if not do:
|
|
||||||
continue
|
|
||||||
bookpath = ospathjoin(docpath, name)
|
|
||||||
if not os.path.exists(bookpath):
|
|
||||||
continue
|
|
||||||
files = os.listdir(bookpath)
|
|
||||||
for file in files:
|
|
||||||
fullpath = ospathjoin(bookpath, file)
|
|
||||||
if fullpath[-5:] <> '.html':
|
|
||||||
continue
|
|
||||||
statusset(fullpath, len(hits))
|
|
||||||
f = _open(fullpath)
|
|
||||||
text = f.read()
|
|
||||||
if not case:
|
|
||||||
text = stringlower(text)
|
|
||||||
f.close()
|
|
||||||
filehits = _match(text, patterns, all)
|
|
||||||
if filehits:
|
|
||||||
hits[fullpath] = filehits
|
|
||||||
finally:
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(-1)
|
|
||||||
status.close()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
pass
|
|
||||||
hits = hits.items()
|
|
||||||
hits.sort()
|
|
||||||
return hits
|
|
||||||
|
|
||||||
|
|
||||||
class PyDocSearch:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
try:
|
|
||||||
(docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine
|
|
||||||
except:
|
|
||||||
(docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine = \
|
|
||||||
("", 0, 0, 0, 1, 1, 0, 0, 0)
|
|
||||||
|
|
||||||
if docpath and not verifydocpath(docpath):
|
|
||||||
docpath = ""
|
|
||||||
|
|
||||||
self.w = W.Window((400, 200), "Search the Python Documentation")
|
|
||||||
self.w.searchtext = W.EditText((10, 10, -100, 20), callback = self.checkbuttons)
|
|
||||||
self.w.searchbutton = W.Button((-90, 12, 80, 16), "Search", self.search)
|
|
||||||
buttons = []
|
|
||||||
|
|
||||||
gutter = 10
|
|
||||||
width = 130
|
|
||||||
bookstart = width + 2 * gutter
|
|
||||||
self.w.phraseradio = W.RadioButton((10, 38, width, 16), "As a phrase", buttons)
|
|
||||||
self.w.allwordsradio = W.RadioButton((10, 58, width, 16), "All words", buttons)
|
|
||||||
self.w.anywordsradio = W.RadioButton((10, 78, width, 16), "Any word", buttons)
|
|
||||||
self.w.casesens = W.CheckBox((10, 98, width, 16), "Case sensitive")
|
|
||||||
self.w.wholewords = W.CheckBox((10, 118, width, 16), "Whole words")
|
|
||||||
self.w.tutorial = W.CheckBox((bookstart, 38, -10, 16), "Tutorial")
|
|
||||||
self.w.library = W.CheckBox((bookstart, 58, -10, 16), "Library reference")
|
|
||||||
self.w.langueref = W.CheckBox((bookstart, 78, -10, 16), "Lanuage reference manual")
|
|
||||||
self.w.extending = W.CheckBox((bookstart, 98, -10, 16), "Extending & embedding")
|
|
||||||
self.w.api = W.CheckBox((bookstart, 118, -10, 16), "C/C++ API")
|
|
||||||
|
|
||||||
self.w.setdocfolderbutton = W.Button((10, -30, 100, 16), "Set doc folder", self.setdocpath)
|
|
||||||
|
|
||||||
if docpath:
|
|
||||||
self.w.setdefaultbutton(self.w.searchbutton)
|
|
||||||
else:
|
|
||||||
self.w.setdefaultbutton(self.w.setdocfolderbutton)
|
|
||||||
|
|
||||||
self.docpath = docpath
|
|
||||||
if not docpath:
|
|
||||||
docpath = "(please select the Python html documentation folder)"
|
|
||||||
self.w.docfolder = W.TextBox((120, -28, -10, 16), docpath)
|
|
||||||
|
|
||||||
[self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio][kind].set(1)
|
|
||||||
|
|
||||||
self.w.casesens.set(case)
|
|
||||||
self.w.wholewords.set(word)
|
|
||||||
self.w.tutorial.set(tut)
|
|
||||||
self.w.library.set(lib)
|
|
||||||
self.w.langueref.set(ref)
|
|
||||||
self.w.extending.set(ext)
|
|
||||||
self.w.api.set(api)
|
|
||||||
|
|
||||||
self.w.open()
|
|
||||||
self.w.wholewords.enable(0)
|
|
||||||
self.w.bind('<close>', self.close)
|
|
||||||
self.w.searchbutton.enable(0)
|
|
||||||
|
|
||||||
def search(self):
|
|
||||||
hits = dosearch(self.docpath, self.w.searchtext.get(), self.getsettings())
|
|
||||||
if hits:
|
|
||||||
Results(hits)
|
|
||||||
elif hasattr(MacOS, 'SysBeep'):
|
|
||||||
MacOS.SysBeep(0)
|
|
||||||
|
|
||||||
def setdocpath(self):
|
|
||||||
docpath = EasyDialogs.AskFolder()
|
|
||||||
if docpath:
|
|
||||||
if not verifydocpath(docpath):
|
|
||||||
W.Message("This does not seem to be a Python documentation folder...")
|
|
||||||
else:
|
|
||||||
self.docpath = docpath
|
|
||||||
self.w.docfolder.set(docpath)
|
|
||||||
self.w.setdefaultbutton(self.w.searchbutton)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
|
||||||
prefs.docsearchengine = self.getsettings()
|
|
||||||
|
|
||||||
def getsettings(self):
|
|
||||||
radiobuttons = [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio]
|
|
||||||
for i in range(3):
|
|
||||||
if radiobuttons[i].get():
|
|
||||||
kind = i
|
|
||||||
break
|
|
||||||
docpath = self.docpath
|
|
||||||
case = self.w.casesens.get()
|
|
||||||
word = self.w.wholewords.get()
|
|
||||||
tut = self.w.tutorial.get()
|
|
||||||
lib = self.w.library.get()
|
|
||||||
ref = self.w.langueref.get()
|
|
||||||
ext = self.w.extending.get()
|
|
||||||
api = self.w.api.get()
|
|
||||||
return (docpath, kind, case, word, tut, lib, ref, ext, api)
|
|
||||||
|
|
||||||
def checkbuttons(self):
|
|
||||||
self.w.searchbutton.enable(not not self.w.searchtext.get())
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,155 +0,0 @@
|
||||||
"""Module to analyze Python source code; for syntax coloring tools.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
tags = fontify(pytext, searchfrom, searchto)
|
|
||||||
|
|
||||||
The 'pytext' argument is a string containing Python source code.
|
|
||||||
The (optional) arguments 'searchfrom' and 'searchto' may contain a slice in pytext.
|
|
||||||
The returned value is a list of tuples, formatted like this:
|
|
||||||
[('keyword', 0, 6, None), ('keyword', 11, 17, None), ('comment', 23, 53, None), etc. ]
|
|
||||||
The tuple contents are always like this:
|
|
||||||
(tag, startindex, endindex, sublist)
|
|
||||||
tag is one of 'keyword', 'string', 'comment' or 'identifier'
|
|
||||||
sublist is not used, hence always None.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Based on FontText.py by Mitchell S. Chapman,
|
|
||||||
# which was modified by Zachary Roadhouse,
|
|
||||||
# then un-Tk'd by Just van Rossum.
|
|
||||||
# Many thanks for regular expression debugging & authoring are due to:
|
|
||||||
# Tim (the-incredib-ly y'rs) Peters and Cristian Tismer
|
|
||||||
# So, who owns the copyright? ;-) How about this:
|
|
||||||
# Copyright 1996-2001:
|
|
||||||
# Mitchell S. Chapman,
|
|
||||||
# Zachary Roadhouse,
|
|
||||||
# Tim Peters,
|
|
||||||
# Just van Rossum
|
|
||||||
|
|
||||||
__version__ = "0.4"
|
|
||||||
|
|
||||||
import string
|
|
||||||
import re
|
|
||||||
|
|
||||||
# First a little helper, since I don't like to repeat things. (Tismer speaking)
|
|
||||||
import string
|
|
||||||
def replace(where, what, with):
|
|
||||||
return string.join(string.split(where, what), with)
|
|
||||||
|
|
||||||
# This list of keywords is taken from ref/node13.html of the
|
|
||||||
# Python 1.3 HTML documentation. ("access" is intentionally omitted.)
|
|
||||||
keywordsList = [
|
|
||||||
"assert", "exec",
|
|
||||||
"del", "from", "lambda", "return",
|
|
||||||
"and", "elif", "global", "not", "try",
|
|
||||||
"break", "else", "if", "or", "while",
|
|
||||||
"class", "except", "import", "pass",
|
|
||||||
"continue", "finally", "in", "print",
|
|
||||||
"def", "for", "is", "raise", "yield"]
|
|
||||||
|
|
||||||
# Build up a regular expression which will match anything
|
|
||||||
# interesting, including multi-line triple-quoted strings.
|
|
||||||
commentPat = r"#[^\n]*"
|
|
||||||
|
|
||||||
pat = r"q[^\\q\n]*(\\[\000-\377][^\\q\n]*)*q"
|
|
||||||
quotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
|
|
||||||
|
|
||||||
# Way to go, Tim!
|
|
||||||
pat = r"""
|
|
||||||
qqq
|
|
||||||
[^\\q]*
|
|
||||||
(
|
|
||||||
( \\[\000-\377]
|
|
||||||
| q
|
|
||||||
( \\[\000-\377]
|
|
||||||
| [^\q]
|
|
||||||
| q
|
|
||||||
( \\[\000-\377]
|
|
||||||
| [^\\q]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
[^\\q]*
|
|
||||||
)*
|
|
||||||
qqq
|
|
||||||
"""
|
|
||||||
pat = string.join(string.split(pat), '') # get rid of whitespace
|
|
||||||
tripleQuotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
|
|
||||||
|
|
||||||
# Build up a regular expression which matches all and only
|
|
||||||
# Python keywords. This will let us skip the uninteresting
|
|
||||||
# identifier references.
|
|
||||||
# nonKeyPat identifies characters which may legally precede
|
|
||||||
# a keyword pattern.
|
|
||||||
nonKeyPat = r"(^|[^a-zA-Z0-9_.\"'])"
|
|
||||||
|
|
||||||
keyPat = nonKeyPat + "(" + "|".join(keywordsList) + ")" + nonKeyPat
|
|
||||||
|
|
||||||
matchPat = commentPat + "|" + keyPat + "|" + tripleQuotePat + "|" + quotePat
|
|
||||||
matchRE = re.compile(matchPat)
|
|
||||||
|
|
||||||
idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*" # Ident w. leading whitespace.
|
|
||||||
idRE = re.compile(idKeyPat)
|
|
||||||
|
|
||||||
|
|
||||||
def fontify(pytext, searchfrom = 0, searchto = None):
|
|
||||||
if searchto is None:
|
|
||||||
searchto = len(pytext)
|
|
||||||
# Cache a few attributes for quicker reference.
|
|
||||||
search = matchRE.search
|
|
||||||
idSearch = idRE.search
|
|
||||||
|
|
||||||
tags = []
|
|
||||||
tags_append = tags.append
|
|
||||||
commentTag = 'comment'
|
|
||||||
stringTag = 'string'
|
|
||||||
keywordTag = 'keyword'
|
|
||||||
identifierTag = 'identifier'
|
|
||||||
|
|
||||||
start = 0
|
|
||||||
end = searchfrom
|
|
||||||
while 1:
|
|
||||||
m = search(pytext, end)
|
|
||||||
if m is None:
|
|
||||||
break # EXIT LOOP
|
|
||||||
start = m.start()
|
|
||||||
if start >= searchto:
|
|
||||||
break # EXIT LOOP
|
|
||||||
match = m.group(0)
|
|
||||||
end = start + len(match)
|
|
||||||
c = match[0]
|
|
||||||
if c not in "#'\"":
|
|
||||||
# Must have matched a keyword.
|
|
||||||
if start <> searchfrom:
|
|
||||||
# there's still a redundant char before and after it, strip!
|
|
||||||
match = match[1:-1]
|
|
||||||
start = start + 1
|
|
||||||
else:
|
|
||||||
# this is the first keyword in the text.
|
|
||||||
# Only a space at the end.
|
|
||||||
match = match[:-1]
|
|
||||||
end = end - 1
|
|
||||||
tags_append((keywordTag, start, end, None))
|
|
||||||
# If this was a defining keyword, look ahead to the
|
|
||||||
# following identifier.
|
|
||||||
if match in ["def", "class"]:
|
|
||||||
m = idSearch(pytext, end)
|
|
||||||
if m is not None:
|
|
||||||
start = m.start()
|
|
||||||
if start == end:
|
|
||||||
match = m.group(0)
|
|
||||||
end = start + len(match)
|
|
||||||
tags_append((identifierTag, start, end, None))
|
|
||||||
elif c == "#":
|
|
||||||
tags_append((commentTag, start, end, None))
|
|
||||||
else:
|
|
||||||
tags_append((stringTag, start, end, None))
|
|
||||||
return tags
|
|
||||||
|
|
||||||
|
|
||||||
def test(path):
|
|
||||||
f = open(path)
|
|
||||||
text = f.read()
|
|
||||||
f.close()
|
|
||||||
tags = fontify(text)
|
|
||||||
for tag, start, end, sublist in tags:
|
|
||||||
print tag, repr(text[start:end])
|
|
|
@ -1,117 +0,0 @@
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
sys.ps1
|
|
||||||
except AttributeError:
|
|
||||||
sys.ps1 = ">>> "
|
|
||||||
try:
|
|
||||||
sys.ps2
|
|
||||||
except AttributeError:
|
|
||||||
sys.ps2 = "... "
|
|
||||||
|
|
||||||
|
|
||||||
def print_exc(limit=None, file=None):
|
|
||||||
if not file:
|
|
||||||
file = sys.stderr
|
|
||||||
# we're going to skip the outermost traceback object, we don't
|
|
||||||
# want people to see the line which excecuted their code.
|
|
||||||
tb = sys.exc_traceback
|
|
||||||
if tb:
|
|
||||||
tb = tb.tb_next
|
|
||||||
try:
|
|
||||||
sys.last_type = sys.exc_type
|
|
||||||
sys.last_value = sys.exc_value
|
|
||||||
sys.last_traceback = tb
|
|
||||||
traceback.print_exception(sys.last_type, sys.last_value,
|
|
||||||
sys.last_traceback, limit, file)
|
|
||||||
except:
|
|
||||||
print '--- hola! ---'
|
|
||||||
traceback.print_exception(sys.exc_type, sys.exc_value,
|
|
||||||
sys.exc_traceback, limit, file)
|
|
||||||
|
|
||||||
|
|
||||||
class PyInteractive:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
import codeop
|
|
||||||
self._pybuf = ""
|
|
||||||
self._compile = codeop.Compile()
|
|
||||||
|
|
||||||
def executeline(self, stuff, out = None, env = None):
|
|
||||||
if env is None:
|
|
||||||
import __main__
|
|
||||||
env = __main__.__dict__
|
|
||||||
if out:
|
|
||||||
saveerr, saveout = sys.stderr, sys.stdout
|
|
||||||
sys.stderr = sys.stdout = out
|
|
||||||
try:
|
|
||||||
if self._pybuf:
|
|
||||||
self._pybuf = self._pybuf + '\n' + stuff
|
|
||||||
else:
|
|
||||||
self._pybuf = stuff
|
|
||||||
|
|
||||||
# Compile three times: as is, with \n, and with \n\n appended.
|
|
||||||
# If it compiles as is, it's complete. If it compiles with
|
|
||||||
# one \n appended, we expect more. If it doesn't compile
|
|
||||||
# either way, we compare the error we get when compiling with
|
|
||||||
# \n or \n\n appended. If the errors are the same, the code
|
|
||||||
# is broken. But if the errors are different, we expect more.
|
|
||||||
# Not intuitive; not even guaranteed to hold in future
|
|
||||||
# releases; but this matches the compiler's behavior in Python
|
|
||||||
# 1.4 and 1.5.
|
|
||||||
err = err1 = err2 = None
|
|
||||||
code = code1 = code2 = None
|
|
||||||
|
|
||||||
# quickly get out of here when the line is 'empty' or is a comment
|
|
||||||
stripped = string.strip(self._pybuf)
|
|
||||||
if not stripped or stripped[0] == '#':
|
|
||||||
self._pybuf = ''
|
|
||||||
sys.stdout.write(sys.ps1)
|
|
||||||
sys.stdout.flush()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
code = self._compile(self._pybuf, "<input>", "single")
|
|
||||||
except SyntaxError, err:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
# OverflowError. More?
|
|
||||||
print_exc()
|
|
||||||
self._pybuf = ""
|
|
||||||
sys.stdout.write(sys.ps1)
|
|
||||||
sys.stdout.flush()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
code1 = self._compile(self._pybuf + "\n", "<input>", "single")
|
|
||||||
except SyntaxError, err1:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
code2 = self._compile(self._pybuf + "\n\n", "<input>", "single")
|
|
||||||
except SyntaxError, err2:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if code:
|
|
||||||
try:
|
|
||||||
exec code in env
|
|
||||||
except:
|
|
||||||
print_exc()
|
|
||||||
self._pybuf = ""
|
|
||||||
elif code1:
|
|
||||||
pass
|
|
||||||
elif err1 == err2 or (not stuff and self._pybuf):
|
|
||||||
print_exc()
|
|
||||||
self._pybuf = ""
|
|
||||||
if self._pybuf:
|
|
||||||
sys.stdout.write(sys.ps2)
|
|
||||||
sys.stdout.flush()
|
|
||||||
else:
|
|
||||||
sys.stdout.write(sys.ps1)
|
|
||||||
sys.stdout.flush()
|
|
||||||
finally:
|
|
||||||
if out:
|
|
||||||
sys.stderr, sys.stdout = saveerr, saveout
|
|
Binary file not shown.
|
@ -1,63 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>English</string>
|
|
||||||
<key>CFBundleDocumentTypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleTypeExtensions</key>
|
|
||||||
<array>
|
|
||||||
<string>py</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleTypeIconFile</key>
|
|
||||||
<string>PythonSource.icns</string>
|
|
||||||
<key>CFBundleTypeName</key>
|
|
||||||
<string>Python Module</string>
|
|
||||||
<key>CFBundleTypeOSTypes</key>
|
|
||||||
<array>
|
|
||||||
<string>TEXT</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleTypeRole</key>
|
|
||||||
<string>Editor</string>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>PythonIDE</string>
|
|
||||||
<key>CFBundleGetInfoString</key>
|
|
||||||
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
|
|
||||||
<key>CFBundleHelpBookFolder</key>
|
|
||||||
<array>
|
|
||||||
<string>PythonDocumentation</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleHelpBookName</key>
|
|
||||||
<string>Python Help</string>
|
|
||||||
<key>CFBundleHelpTOCFile</key>
|
|
||||||
<string>index.html</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>PythonIDE.icns</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>org.python.pythonide</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleLongVersionString</key>
|
|
||||||
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>PythonIDE</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>2.5alpha0</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>Pide</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>2.5alpha0</string>
|
|
||||||
<key>CSResourcesFileMapped</key>
|
|
||||||
<true/>
|
|
||||||
<key>LSRequiresCarbon</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>(c) 2004 Python Software Foundation.</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -1,59 +0,0 @@
|
||||||
# copyright 1996-2001 Just van Rossum, Letterror. just@letterror.com
|
|
||||||
|
|
||||||
# keep this (__main__) as clean as possible, since we are using
|
|
||||||
# it like the "normal" interpreter.
|
|
||||||
|
|
||||||
__version__ = '1.0.2'
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
def init():
|
|
||||||
import MacOS
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(-1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import autoGIL
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
autoGIL.installAutoGIL()
|
|
||||||
|
|
||||||
from Carbon import Qd, QuickDraw
|
|
||||||
Qd.SetCursor(Qd.GetCursor(QuickDraw.watchCursor).data)
|
|
||||||
|
|
||||||
import macresource
|
|
||||||
import sys, os
|
|
||||||
macresource.need('DITL', 468, "PythonIDE.rsrc")
|
|
||||||
widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
|
|
||||||
widgetresfile = os.path.join(*widgetrespathsegs)
|
|
||||||
if not os.path.exists(widgetresfile):
|
|
||||||
widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
|
|
||||||
widgetresfile = os.path.join(*widgetrespathsegs)
|
|
||||||
refno = macresource.need('CURS', 468, widgetresfile)
|
|
||||||
if os.environ.has_key('PYTHONIDEPATH'):
|
|
||||||
# For development set this environment variable
|
|
||||||
ide_path = os.environ['PYTHONIDEPATH']
|
|
||||||
elif refno:
|
|
||||||
# We're not a fullblown application
|
|
||||||
idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
|
|
||||||
ide_path = os.path.join(*idepathsegs)
|
|
||||||
if not os.path.exists(ide_path):
|
|
||||||
idepathsegs = [os.pardir, "Tools", "IDE"]
|
|
||||||
for p in sys.path:
|
|
||||||
ide_path = os.path.join(*([p]+idepathsegs))
|
|
||||||
if os.path.exists(ide_path):
|
|
||||||
break
|
|
||||||
|
|
||||||
else:
|
|
||||||
# We are a fully frozen application
|
|
||||||
ide_path = sys.argv[0]
|
|
||||||
if ide_path not in sys.path:
|
|
||||||
sys.path.insert(1, ide_path)
|
|
||||||
|
|
||||||
|
|
||||||
init()
|
|
||||||
del init
|
|
||||||
|
|
||||||
import PythonIDEMain as _PythonIDEMain
|
|
||||||
_PythonIDEMain.PythonIDE()
|
|
Binary file not shown.
|
@ -1,488 +0,0 @@
|
||||||
# copyright 1997-2001 Just van Rossum, Letterror. just@letterror.com
|
|
||||||
|
|
||||||
import Splash
|
|
||||||
|
|
||||||
import FrameWork
|
|
||||||
import Wapplication
|
|
||||||
import W
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import MacOS
|
|
||||||
import EasyDialogs
|
|
||||||
from Carbon import File
|
|
||||||
from Carbon import Files
|
|
||||||
|
|
||||||
if MacOS.runtimemodel == 'macho':
|
|
||||||
ELLIPSIS = '...'
|
|
||||||
else:
|
|
||||||
ELLIPSIS = '\xc9'
|
|
||||||
|
|
||||||
def runningOnOSX():
|
|
||||||
from gestalt import gestalt
|
|
||||||
gestaltMenuMgrAquaLayoutBit = 1 # menus have the Aqua 1.0 layout
|
|
||||||
gestaltMenuMgrAquaLayoutMask = (1L << gestaltMenuMgrAquaLayoutBit)
|
|
||||||
value = gestalt("menu") & gestaltMenuMgrAquaLayoutMask
|
|
||||||
return not not value
|
|
||||||
|
|
||||||
def getmodtime(file):
|
|
||||||
file = File.FSRef(file)
|
|
||||||
catinfo, d1, d2, d3 = file.FSGetCatalogInfo(Files.kFSCatInfoContentMod)
|
|
||||||
return catinfo.contentModDate
|
|
||||||
|
|
||||||
class PythonIDE(Wapplication.Application):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if sys.platform == "darwin":
|
|
||||||
if len(sys.argv) > 1 and sys.argv[1].startswith("-psn"):
|
|
||||||
home = os.getenv("HOME")
|
|
||||||
if home:
|
|
||||||
os.chdir(home)
|
|
||||||
self.preffilepath = os.path.join("Python", "PythonIDE preferences")
|
|
||||||
Wapplication.Application.__init__(self, 'Pide')
|
|
||||||
from Carbon import AE
|
|
||||||
from Carbon import AppleEvents
|
|
||||||
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments,
|
|
||||||
self.ignoreevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenDocuments,
|
|
||||||
self.opendocsevent)
|
|
||||||
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication,
|
|
||||||
self.quitevent)
|
|
||||||
import PyConsole, PyEdit
|
|
||||||
Splash.wait()
|
|
||||||
# With -D option (OSX command line only) keep stderr, for debugging the IDE
|
|
||||||
# itself.
|
|
||||||
debug_stderr = None
|
|
||||||
if len(sys.argv) >= 2 and sys.argv[1] == '-D':
|
|
||||||
debug_stderr = sys.stderr
|
|
||||||
del sys.argv[1]
|
|
||||||
PyConsole.installoutput()
|
|
||||||
PyConsole.installconsole()
|
|
||||||
if debug_stderr:
|
|
||||||
sys.stderr = debug_stderr
|
|
||||||
for path in sys.argv[1:]:
|
|
||||||
if path.startswith("-p"):
|
|
||||||
# process number added by the OS
|
|
||||||
continue
|
|
||||||
self.opendoc(path)
|
|
||||||
self.mainloop()
|
|
||||||
|
|
||||||
def makeusermenus(self):
|
|
||||||
m = Wapplication.Menu(self.menubar, "File")
|
|
||||||
newitem = FrameWork.MenuItem(m, "New", "N", 'new')
|
|
||||||
openitem = FrameWork.MenuItem(m, "Open"+ELLIPSIS, "O", 'open')
|
|
||||||
openbynameitem = FrameWork.MenuItem(m, "Open File by Name"+ELLIPSIS, "D", 'openbyname')
|
|
||||||
self.openrecentmenu = FrameWork.SubMenu(m, "Open Recent")
|
|
||||||
self.makeopenrecentmenu()
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
|
|
||||||
saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
|
|
||||||
saveasitem = FrameWork.MenuItem(m, "Save as"+ELLIPSIS, None, 'save_as')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
saveasappletitem = FrameWork.MenuItem(m, "Save as Applet"+ELLIPSIS, None, 'save_as_applet')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
instmgritem = FrameWork.MenuItem(m, "Package Manager", None, 'openpackagemanager')
|
|
||||||
gensuiteitem = FrameWork.MenuItem(m, "Generate OSA Suite...", None, 'gensuite')
|
|
||||||
if not runningOnOSX():
|
|
||||||
# On OSX there's a special "magic" quit menu, so we shouldn't add
|
|
||||||
# it to the File menu.
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit')
|
|
||||||
|
|
||||||
m = Wapplication.Menu(self.menubar, "Edit")
|
|
||||||
undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
|
|
||||||
copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
|
|
||||||
pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
|
|
||||||
FrameWork.MenuItem(m, "Clear", None, "clear")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
|
|
||||||
sellineitem = FrameWork.MenuItem(m, "Select line", "L", "selectline")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
finditem = FrameWork.MenuItem(m, "Find"+ELLIPSIS, "F", "find")
|
|
||||||
findagainitem = FrameWork.MenuItem(m, "Find again", 'G', "findnext")
|
|
||||||
enterselitem = FrameWork.MenuItem(m, "Enter search string", "E", "entersearchstring")
|
|
||||||
replaceitem = FrameWork.MenuItem(m, "Replace", None, "replace")
|
|
||||||
replacefinditem = FrameWork.MenuItem(m, "Replace & find again", 'T', "replacefind")
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
shiftleftitem = FrameWork.MenuItem(m, "Shift left", "[", "shiftleft")
|
|
||||||
shiftrightitem = FrameWork.MenuItem(m, "Shift right", "]", "shiftright")
|
|
||||||
|
|
||||||
m = Wapplication.Menu(self.menubar, "Python")
|
|
||||||
runitem = FrameWork.MenuItem(m, "Run window", "R", 'run')
|
|
||||||
runselitem = FrameWork.MenuItem(m, "Run selection", None, 'runselection')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
moditem = FrameWork.MenuItem(m, "Module browser"+ELLIPSIS, "M", self.domenu_modulebrowser)
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
mm = FrameWork.SubMenu(m, "Preferences")
|
|
||||||
FrameWork.MenuItem(mm, "Set Scripts folder"+ELLIPSIS, None, self.do_setscriptsfolder)
|
|
||||||
FrameWork.MenuItem(mm, "Editor default settings"+ELLIPSIS, None, self.do_editorprefs)
|
|
||||||
FrameWork.MenuItem(mm, "Set default window font"+ELLIPSIS, None, self.do_setwindowfont)
|
|
||||||
|
|
||||||
self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
|
|
||||||
self.makeopenwindowsmenu()
|
|
||||||
self._menustocheck = [closeitem, saveitem, saveasitem, saveasappletitem,
|
|
||||||
undoitem, cutitem, copyitem, pasteitem,
|
|
||||||
selallitem, sellineitem,
|
|
||||||
finditem, findagainitem, enterselitem, replaceitem, replacefinditem,
|
|
||||||
shiftleftitem, shiftrightitem,
|
|
||||||
runitem, runselitem]
|
|
||||||
|
|
||||||
prefs = self.getprefs()
|
|
||||||
try:
|
|
||||||
fsr, d = File.Alias(rawdata=prefs.scriptsfolder).FSResolveAlias(None)
|
|
||||||
self.scriptsfolder = fsr.FSNewAliasMinimal()
|
|
||||||
except:
|
|
||||||
path = os.path.join(os.getcwd(), "Mac", "IDE scripts")
|
|
||||||
if not os.path.exists(path):
|
|
||||||
if sys.platform == "darwin":
|
|
||||||
path = os.path.join(os.getenv("HOME"), "Library", "Python", "IDE-Scripts")
|
|
||||||
else:
|
|
||||||
path = os.path.join(os.getcwd(), "Scripts")
|
|
||||||
if not os.path.exists(path):
|
|
||||||
os.makedirs(path)
|
|
||||||
f = open(os.path.join(path, "Place your scripts here"+ELLIPSIS), "w")
|
|
||||||
f.close()
|
|
||||||
fsr = File.FSRef(path)
|
|
||||||
self.scriptsfolder = fsr.FSNewAliasMinimal()
|
|
||||||
self.scriptsfoldermodtime = getmodtime(fsr)
|
|
||||||
else:
|
|
||||||
self.scriptsfoldermodtime = getmodtime(fsr)
|
|
||||||
prefs.scriptsfolder = self.scriptsfolder.data
|
|
||||||
self._scripts = {}
|
|
||||||
self.scriptsmenu = None
|
|
||||||
self.makescriptsmenu()
|
|
||||||
self.makehelpmenu()
|
|
||||||
|
|
||||||
def quitevent(self, theAppleEvent, theReply):
|
|
||||||
self._quit()
|
|
||||||
|
|
||||||
def suspendresume(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
fsr, changed = self.scriptsfolder.FSResolveAlias(None)
|
|
||||||
modtime = getmodtime(fsr)
|
|
||||||
if self.scriptsfoldermodtime <> modtime or changed:
|
|
||||||
self.scriptsfoldermodtime = modtime
|
|
||||||
W.SetCursor('watch')
|
|
||||||
self.makescriptsmenu()
|
|
||||||
|
|
||||||
def ignoreevent(self, theAppleEvent, theReply):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def opendocsevent(self, theAppleEvent, theReply):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
import aetools
|
|
||||||
parameters, args = aetools.unpackevent(theAppleEvent)
|
|
||||||
docs = parameters['----']
|
|
||||||
if type(docs) <> type([]):
|
|
||||||
docs = [docs]
|
|
||||||
for doc in docs:
|
|
||||||
fsr, a = doc.FSResolveAlias(None)
|
|
||||||
path = fsr.as_pathname()
|
|
||||||
self.opendoc(path)
|
|
||||||
|
|
||||||
def opendoc(self, path):
|
|
||||||
fcreator, ftype = MacOS.GetCreatorAndType(path)
|
|
||||||
if ftype == 'TEXT':
|
|
||||||
self.openscript(path)
|
|
||||||
elif ftype == '\0\0\0\0' and path[-3:] == '.py':
|
|
||||||
self.openscript(path)
|
|
||||||
else:
|
|
||||||
W.Message("Can't open file of type '%s'." % ftype)
|
|
||||||
|
|
||||||
def getabouttext(self):
|
|
||||||
return "About Python IDE"+ELLIPSIS
|
|
||||||
|
|
||||||
def do_about(self, id, item, window, event):
|
|
||||||
Splash.about()
|
|
||||||
|
|
||||||
def do_setscriptsfolder(self, *args):
|
|
||||||
fsr = EasyDialogs.AskFolder(message="Select Scripts Folder",
|
|
||||||
wanted=File.FSRef)
|
|
||||||
if fsr:
|
|
||||||
prefs = self.getprefs()
|
|
||||||
alis = fsr.FSNewAliasMinimal()
|
|
||||||
prefs.scriptsfolder = alis.data
|
|
||||||
self.scriptsfolder = alis
|
|
||||||
self.makescriptsmenu()
|
|
||||||
prefs.save()
|
|
||||||
|
|
||||||
def domenu_modulebrowser(self, *args):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
import ModuleBrowser
|
|
||||||
ModuleBrowser.ModuleBrowser()
|
|
||||||
|
|
||||||
def domenu_open(self, *args):
|
|
||||||
filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
|
|
||||||
if filename:
|
|
||||||
self.openscript(filename)
|
|
||||||
|
|
||||||
def domenu_openbyname(self, *args):
|
|
||||||
# Open a file by name. If the clipboard contains a filename
|
|
||||||
# use that as the default.
|
|
||||||
from Carbon import Scrap
|
|
||||||
try:
|
|
||||||
sc = Scrap.GetCurrentScrap()
|
|
||||||
dft = sc.GetScrapFlavorData("TEXT")
|
|
||||||
except Scrap.Error:
|
|
||||||
dft = ""
|
|
||||||
else:
|
|
||||||
if not os.path.exists(dft):
|
|
||||||
dft = ""
|
|
||||||
filename = EasyDialogs.AskString("Open File Named:", default=dft, ok="Open")
|
|
||||||
if filename:
|
|
||||||
self.openscript(filename)
|
|
||||||
|
|
||||||
def domenu_new(self, *args):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
import PyEdit
|
|
||||||
return PyEdit.Editor()
|
|
||||||
|
|
||||||
def makescriptsmenu(self):
|
|
||||||
W.SetCursor('watch')
|
|
||||||
if self._scripts:
|
|
||||||
for id, item in self._scripts.keys():
|
|
||||||
if self.menubar.menus.has_key(id):
|
|
||||||
m = self.menubar.menus[id]
|
|
||||||
m.delete()
|
|
||||||
self._scripts = {}
|
|
||||||
if self.scriptsmenu:
|
|
||||||
if hasattr(self.scriptsmenu, 'id') and self.menubar.menus.has_key(self.scriptsmenu.id):
|
|
||||||
self.scriptsmenu.delete()
|
|
||||||
self.scriptsmenu = FrameWork.Menu(self.menubar, "Scripts")
|
|
||||||
#FrameWork.MenuItem(self.scriptsmenu, "New script", None, self.domenu_new)
|
|
||||||
#self.scriptsmenu.addseparator()
|
|
||||||
fsr, d1 = self.scriptsfolder.FSResolveAlias(None)
|
|
||||||
self.scriptswalk(fsr.as_pathname(), self.scriptsmenu)
|
|
||||||
|
|
||||||
def makeopenwindowsmenu(self):
|
|
||||||
for i in range(len(self.openwindowsmenu.items)):
|
|
||||||
self.openwindowsmenu.menu.DeleteMenuItem(1)
|
|
||||||
self.openwindowsmenu.items = []
|
|
||||||
windows = []
|
|
||||||
self._openwindows = {}
|
|
||||||
for window in self._windows.keys():
|
|
||||||
title = window.GetWTitle()
|
|
||||||
if not title:
|
|
||||||
title = "<no title>"
|
|
||||||
windows.append((title, window))
|
|
||||||
windows.sort()
|
|
||||||
for title, window in windows:
|
|
||||||
if title == "Python Interactive": # ugly but useful hack by Joe Strout
|
|
||||||
shortcut = '0'
|
|
||||||
else:
|
|
||||||
shortcut = None
|
|
||||||
item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
|
|
||||||
self._openwindows[item.item] = window
|
|
||||||
self._openwindowscheckmark = 0
|
|
||||||
self.checkopenwindowsmenu()
|
|
||||||
|
|
||||||
def makeopenrecentmenu(self):
|
|
||||||
for i in range(len(self.openrecentmenu.items)):
|
|
||||||
self.openrecentmenu.menu.DeleteMenuItem(1)
|
|
||||||
self.openrecentmenu.items = []
|
|
||||||
prefs = self.getprefs()
|
|
||||||
filelist = prefs.recentfiles
|
|
||||||
if not filelist:
|
|
||||||
self.openrecentmenu.enable(0)
|
|
||||||
return
|
|
||||||
self.openrecentmenu.enable(1)
|
|
||||||
for filename in filelist:
|
|
||||||
item = FrameWork.MenuItem(self.openrecentmenu, filename, None, callback = self.domenu_openrecent)
|
|
||||||
|
|
||||||
def addrecentfile(self, file):
|
|
||||||
prefs = self.getprefs()
|
|
||||||
filelist = prefs.recentfiles
|
|
||||||
if not filelist:
|
|
||||||
filelist = []
|
|
||||||
|
|
||||||
if file in filelist:
|
|
||||||
if file == filelist[0]:
|
|
||||||
return
|
|
||||||
filelist.remove(file)
|
|
||||||
filelist.insert(0, file)
|
|
||||||
filelist = filelist[:10]
|
|
||||||
prefs.recentfiles = filelist
|
|
||||||
prefs.save()
|
|
||||||
self.makeopenrecentmenu()
|
|
||||||
|
|
||||||
def domenu_openwindows(self, id, item, window, event):
|
|
||||||
w = self._openwindows[item]
|
|
||||||
w.ShowWindow()
|
|
||||||
w.SelectWindow()
|
|
||||||
|
|
||||||
def domenu_openrecent(self, id, item, window, event):
|
|
||||||
prefs = self.getprefs()
|
|
||||||
filelist = prefs.recentfiles
|
|
||||||
if not filelist:
|
|
||||||
filelist = []
|
|
||||||
item = item - 1
|
|
||||||
filename = filelist[item]
|
|
||||||
self.openscript(filename)
|
|
||||||
|
|
||||||
def domenu_quit(self):
|
|
||||||
self._quit()
|
|
||||||
|
|
||||||
def domenu_save(self, *args):
|
|
||||||
print "Save"
|
|
||||||
|
|
||||||
def _quit(self):
|
|
||||||
import PyConsole, PyEdit
|
|
||||||
for window in self._windows.values():
|
|
||||||
try:
|
|
||||||
rv = window.close() # ignore any errors while quitting
|
|
||||||
except:
|
|
||||||
rv = 0 # (otherwise, we can get stuck!)
|
|
||||||
if rv and rv > 0:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
PyConsole.console.writeprefs()
|
|
||||||
PyConsole.output.writeprefs()
|
|
||||||
PyEdit.searchengine.writeprefs()
|
|
||||||
except:
|
|
||||||
# Write to __stderr__ so the msg end up in Console.app and has
|
|
||||||
# at least _some_ chance of getting read...
|
|
||||||
# But: this is a workaround for way more serious problems with
|
|
||||||
# the Python 2.2 Jaguar addon.
|
|
||||||
sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
|
|
||||||
self.quitting = 1
|
|
||||||
|
|
||||||
def domenu_openpackagemanager(self):
|
|
||||||
import PackageManager
|
|
||||||
PackageManager.PackageBrowser()
|
|
||||||
|
|
||||||
def domenu_gensuite(self):
|
|
||||||
import gensuitemodule
|
|
||||||
gensuitemodule.main_interactive()
|
|
||||||
|
|
||||||
def makehelpmenu(self):
|
|
||||||
hashelp, hasdocs = self.installdocumentation()
|
|
||||||
self.helpmenu = m = self.gethelpmenu()
|
|
||||||
helpitem = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_localhelp)
|
|
||||||
helpitem.enable(hashelp)
|
|
||||||
docitem = FrameWork.MenuItem(m, "Python Documentation", None, self.domenu_localdocs)
|
|
||||||
docitem.enable(hasdocs)
|
|
||||||
finditem = FrameWork.MenuItem(m, "Lookup in Python Documentation", None, 'lookuppython')
|
|
||||||
finditem.enable(hasdocs)
|
|
||||||
if runningOnOSX():
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
doc2item = FrameWork.MenuItem(m, "Apple Developer Documentation", None, self.domenu_appledocs)
|
|
||||||
find2item = FrameWork.MenuItem(m, "Lookup in Carbon Documentation", None, 'lookupcarbon')
|
|
||||||
FrameWork.Separator(m)
|
|
||||||
webitem = FrameWork.MenuItem(m, "Python Documentation on the Web", None, self.domenu_webdocs)
|
|
||||||
web2item = FrameWork.MenuItem(m, "Python on the Web", None, self.domenu_webpython)
|
|
||||||
web3item = FrameWork.MenuItem(m, "MacPython on the Web", None, self.domenu_webmacpython)
|
|
||||||
|
|
||||||
def domenu_localdocs(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHGotoPage("Python Documentation", None, None)
|
|
||||||
|
|
||||||
def domenu_localhelp(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHGotoPage("MacPython Help", None, None)
|
|
||||||
|
|
||||||
def domenu_appledocs(self, *args):
|
|
||||||
from Carbon import AH, AppleHelp
|
|
||||||
try:
|
|
||||||
AH.AHGotoMainTOC(AppleHelp.kAHTOCTypeDeveloper)
|
|
||||||
except AH.Error, arg:
|
|
||||||
if arg[0] == -50:
|
|
||||||
W.Message("Developer documentation not installed")
|
|
||||||
else:
|
|
||||||
W.Message("AppleHelp Error: %r" % (arg,))
|
|
||||||
|
|
||||||
def domenu_lookuppython(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
searchstring = self._getsearchstring()
|
|
||||||
if not searchstring:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
AH.AHSearch("Python Documentation", searchstring)
|
|
||||||
except AH.Error, arg:
|
|
||||||
W.Message("AppleHelp Error: %r" % (arg,))
|
|
||||||
|
|
||||||
def domenu_lookupcarbon(self, *args):
|
|
||||||
from Carbon import AH
|
|
||||||
searchstring = self._getsearchstring()
|
|
||||||
if not searchstring:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
AH.AHSearch("Carbon", searchstring)
|
|
||||||
except AH.Error, arg:
|
|
||||||
W.Message("AppleHelp Error: %r" % (arg,))
|
|
||||||
|
|
||||||
def _getsearchstring(self):
|
|
||||||
# First we get the frontmost window
|
|
||||||
front = self.getfrontwindow()
|
|
||||||
if front and hasattr(front, 'getselectedtext'):
|
|
||||||
text = front.getselectedtext()
|
|
||||||
if text:
|
|
||||||
return text
|
|
||||||
# This is a cop-out. We should have disabled the menus
|
|
||||||
# if there is no selection, but the can_ methods only seem
|
|
||||||
# to work for Windows. Or not for the Help menu, maybe?
|
|
||||||
text = EasyDialogs.AskString("Search documentation for", ok="Search")
|
|
||||||
return text
|
|
||||||
|
|
||||||
def domenu_webdocs(self, *args):
|
|
||||||
import webbrowser
|
|
||||||
major, minor, micro, state, nano = sys.version_info
|
|
||||||
if state in ('alpha', 'beta'):
|
|
||||||
docversion = 'dev/doc/devel'
|
|
||||||
elif micro == 0:
|
|
||||||
docversion = 'doc/%d.%d' % (major, minor)
|
|
||||||
else:
|
|
||||||
docversion = 'doc/%d.%d.%d' % (major, minor, micro)
|
|
||||||
webbrowser.open("http://www.python.org/%s" % docversion)
|
|
||||||
|
|
||||||
def domenu_webpython(self, *args):
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open("http://www.python.org/")
|
|
||||||
|
|
||||||
def domenu_webmacpython(self, *args):
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open("http://www.cwi.nl/~jack/macpython.html")
|
|
||||||
|
|
||||||
def installdocumentation(self):
|
|
||||||
# This is rather much of a hack. Someone has to tell the Help Viewer
|
|
||||||
# about the Python documentation, so why not us. The documentation
|
|
||||||
# is located in the framework, but there's a symlink in Python.app.
|
|
||||||
# And as AHRegisterHelpBook wants a bundle (with the right bits in
|
|
||||||
# the plist file) we refer it to Python.app
|
|
||||||
#
|
|
||||||
# To make matters worse we have to look in two places: first in the IDE
|
|
||||||
# itself, then in the Python application inside the framework.
|
|
||||||
has_help = False
|
|
||||||
has_doc = False
|
|
||||||
ide_path_components = sys.argv[0].split("/")
|
|
||||||
if ide_path_components[-3:] == ["Contents", "Resources", "PythonIDE.py"]:
|
|
||||||
ide_app = "/".join(ide_path_components[:-3])
|
|
||||||
help_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/Documentation')
|
|
||||||
doc_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/PythonDocumentation')
|
|
||||||
has_help = os.path.isdir(help_source)
|
|
||||||
has_doc = os.path.isdir(doc_source)
|
|
||||||
if has_help or has_doc:
|
|
||||||
try:
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHRegisterHelpBook(ide_app)
|
|
||||||
except (ImportError, MacOS.Error), arg:
|
|
||||||
pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
|
|
||||||
python_app = os.path.join(sys.prefix, 'Resources/Python.app')
|
|
||||||
if not has_help:
|
|
||||||
help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
|
|
||||||
has_help = os.path.isdir(help_source)
|
|
||||||
if not has_doc:
|
|
||||||
doc_source = os.path.join(python_app, 'Contents/Resources/English.lproj/PythonDocumentation')
|
|
||||||
has_doc = os.path.isdir(doc_source)
|
|
||||||
if has_help or has_doc:
|
|
||||||
try:
|
|
||||||
from Carbon import AH
|
|
||||||
AH.AHRegisterHelpBook(python_app)
|
|
||||||
except (ImportError, MacOS.Error), arg:
|
|
||||||
pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
|
|
||||||
return has_help, has_doc
|
|
|
@ -1,112 +0,0 @@
|
||||||
from Carbon import Dlg
|
|
||||||
from Carbon import Res
|
|
||||||
|
|
||||||
splash = Dlg.GetNewDialog(468, -1)
|
|
||||||
splash.DrawDialog()
|
|
||||||
|
|
||||||
from Carbon import Qd, TE, Fm
|
|
||||||
|
|
||||||
from Carbon import Win
|
|
||||||
from Carbon.Fonts import *
|
|
||||||
from Carbon.QuickDraw import *
|
|
||||||
from Carbon.TextEdit import teJustCenter
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
|
|
||||||
_about_width = 440
|
|
||||||
_about_height = 340
|
|
||||||
|
|
||||||
_keepsplashscreenopen = 0
|
|
||||||
|
|
||||||
abouttext1 = """The Python Integrated Development Environment for the Macintosh\xaa
|
|
||||||
Version: %s
|
|
||||||
Copyright 1997-2001 Just van Rossum, Letterror. <just@letterror.com>
|
|
||||||
Python %s
|
|
||||||
%s
|
|
||||||
See: <http://www.python.org/> for information and documentation."""
|
|
||||||
|
|
||||||
flauwekul = [ "Goodday, Bruce.",
|
|
||||||
"What's new?",
|
|
||||||
"Nudge, nudge, say no more!",
|
|
||||||
"No, no sir, it's not dead. It's resting.",
|
|
||||||
"Albatros!",
|
|
||||||
"It's . . .",
|
|
||||||
"Is your name not Bruce, then?",
|
|
||||||
"""But Mr F.G. Superman has a secret identity . . .
|
|
||||||
when trouble strikes at any time . . .
|
|
||||||
at any place . . . he is ready to become . . .
|
|
||||||
Bicycle Repair Man!"""
|
|
||||||
]
|
|
||||||
|
|
||||||
def skipdoublereturns(text):
|
|
||||||
return string.replace(text, '\n\n', '\n')
|
|
||||||
|
|
||||||
def nl2return(text):
|
|
||||||
return string.replace(text, '\n', '\r')
|
|
||||||
|
|
||||||
def UpdateSplash(drawdialog = 0, what = 0):
|
|
||||||
if drawdialog:
|
|
||||||
splash.DrawDialog()
|
|
||||||
drawtext(what)
|
|
||||||
splash.GetDialogWindow().ValidWindowRect(splash.GetDialogPort().GetPortBounds())
|
|
||||||
splash.GetDialogWindow().GetWindowPort().QDFlushPortBuffer(None)
|
|
||||||
|
|
||||||
def drawtext(what = 0):
|
|
||||||
Qd.SetPort(splash)
|
|
||||||
fontID = Fm.GetFNum("Python-Sans")
|
|
||||||
if not fontID:
|
|
||||||
fontID = geneva
|
|
||||||
Qd.TextFont(fontID)
|
|
||||||
Qd.TextSize(9)
|
|
||||||
rect = (10, 115, _about_width - 10, _about_height - 30)
|
|
||||||
if not what:
|
|
||||||
import __main__
|
|
||||||
abouttxt = nl2return(abouttext1 % (
|
|
||||||
__main__.__version__, sys.version, skipdoublereturns(sys.copyright)))
|
|
||||||
else:
|
|
||||||
import random
|
|
||||||
abouttxt = nl2return(random.choice(flauwekul))
|
|
||||||
TE.TETextBox(abouttxt, rect, teJustCenter)
|
|
||||||
|
|
||||||
UpdateSplash(1)
|
|
||||||
|
|
||||||
def wait():
|
|
||||||
from Carbon import Evt
|
|
||||||
from Carbon import Events
|
|
||||||
global splash
|
|
||||||
try:
|
|
||||||
splash
|
|
||||||
except NameError:
|
|
||||||
return
|
|
||||||
Qd.InitCursor()
|
|
||||||
time = Evt.TickCount()
|
|
||||||
whattext = 0
|
|
||||||
drawtext(whattext)
|
|
||||||
while _keepsplashscreenopen:
|
|
||||||
ok, event = Evt.EventAvail(Events.highLevelEventMask)
|
|
||||||
if ok:
|
|
||||||
# got apple event, back to mainloop
|
|
||||||
break
|
|
||||||
ok, event = Evt.EventAvail(Events.mDownMask | Events.keyDownMask | Events.updateMask)
|
|
||||||
if ok:
|
|
||||||
ok, event = Evt.WaitNextEvent(Events.mDownMask | Events.keyDownMask | Events.updateMask, 30)
|
|
||||||
if ok:
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
if what == Events.updateEvt:
|
|
||||||
if Win.WhichWindow(message) == splash:
|
|
||||||
UpdateSplash(1, whattext)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
if Evt.TickCount() - time > 360:
|
|
||||||
whattext = not whattext
|
|
||||||
drawtext(whattext)
|
|
||||||
time = Evt.TickCount()
|
|
||||||
del splash
|
|
||||||
|
|
||||||
|
|
||||||
def about():
|
|
||||||
global splash, splashresfile, _keepsplashscreenopen
|
|
||||||
_keepsplashscreenopen = 1
|
|
||||||
splash = Dlg.GetNewDialog(468, -1)
|
|
||||||
splash.DrawDialog()
|
|
||||||
wait()
|
|
|
@ -1,40 +0,0 @@
|
||||||
"""Widgets for the Macintosh. Built on top of FrameWork"""
|
|
||||||
|
|
||||||
__version__ = "0.3"
|
|
||||||
|
|
||||||
from Wbase import *
|
|
||||||
from Wcontrols import *
|
|
||||||
from Wtext import *
|
|
||||||
from Wlists import *
|
|
||||||
from Wwindows import *
|
|
||||||
from Wmenus import *
|
|
||||||
|
|
||||||
_application = None
|
|
||||||
_signature = None
|
|
||||||
|
|
||||||
AlertError = 'AlertError'
|
|
||||||
|
|
||||||
def setapplication(app, sig):
|
|
||||||
global _application, _signature
|
|
||||||
_application = app
|
|
||||||
_signature = sig
|
|
||||||
|
|
||||||
def getapplication():
|
|
||||||
if _application is None:
|
|
||||||
raise WidgetsError, 'W not properly initialized: unknown Application'
|
|
||||||
return _application
|
|
||||||
|
|
||||||
def getdefaultfont():
|
|
||||||
prefs = getapplication().getprefs()
|
|
||||||
if not prefs.defaultfont:
|
|
||||||
prefs.defaultfont = ("Geneva", 0, 10, (0, 0, 0))
|
|
||||||
return prefs.defaultfont
|
|
||||||
|
|
||||||
def Message(text):
|
|
||||||
import EasyDialogs, string
|
|
||||||
from Carbon import Qd
|
|
||||||
Qd.InitCursor()
|
|
||||||
text = string.replace(text, "\n", "\r")
|
|
||||||
if not text:
|
|
||||||
text = '<Alert text not specified>'
|
|
||||||
EasyDialogs.Message(text)
|
|
|
@ -1,481 +0,0 @@
|
||||||
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
|
|
|
@ -1,798 +0,0 @@
|
||||||
from Carbon import App, Evt, Qd, QuickDraw, Win
|
|
||||||
import string
|
|
||||||
from types import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
class WidgetsError(Exception): pass
|
|
||||||
|
|
||||||
DEBUG = 0
|
|
||||||
|
|
||||||
|
|
||||||
def _intRect((l, t, r, b)):
|
|
||||||
return (int(l), int(t), int(r), int(b))
|
|
||||||
|
|
||||||
|
|
||||||
class Widget:
|
|
||||||
|
|
||||||
"""Base class for all widgets."""
|
|
||||||
|
|
||||||
_selectable = 0
|
|
||||||
|
|
||||||
def __init__(self, possize):
|
|
||||||
self._widgets = []
|
|
||||||
self._widgetsdict = {}
|
|
||||||
self._possize = possize
|
|
||||||
self._bounds = None
|
|
||||||
self._visible = 1
|
|
||||||
self._enabled = 0
|
|
||||||
self._selected = 0
|
|
||||||
self._activated = 0
|
|
||||||
self._callback = None
|
|
||||||
self._parent = None
|
|
||||||
self._parentwindow = None
|
|
||||||
self._bindings = {}
|
|
||||||
self._backcolor = None
|
|
||||||
|
|
||||||
def show(self, onoff):
|
|
||||||
self._visible = onoff
|
|
||||||
for w in self._widgets:
|
|
||||||
w.show(onoff)
|
|
||||||
if self._parentwindow is not None and self._parentwindow.wid is not None:
|
|
||||||
self.SetPort()
|
|
||||||
if onoff:
|
|
||||||
self.draw()
|
|
||||||
else:
|
|
||||||
Qd.EraseRect(self._bounds)
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
# draw your stuff here
|
|
||||||
pass
|
|
||||||
|
|
||||||
def getpossize(self):
|
|
||||||
return self._possize
|
|
||||||
|
|
||||||
def getbounds(self):
|
|
||||||
return self._bounds
|
|
||||||
|
|
||||||
def move(self, x, y = None):
|
|
||||||
"""absolute move"""
|
|
||||||
if y == None:
|
|
||||||
x, y = x
|
|
||||||
if type(self._possize) <> TupleType:
|
|
||||||
raise WidgetsError, "can't move widget with bounds function"
|
|
||||||
l, t, r, b = self._possize
|
|
||||||
self.resize(x, y, r, b)
|
|
||||||
|
|
||||||
def rmove(self, x, y = None):
|
|
||||||
"""relative move"""
|
|
||||||
if y == None:
|
|
||||||
x, y = x
|
|
||||||
if type(self._possize) <> TupleType:
|
|
||||||
raise WidgetsError, "can't move widget with bounds function"
|
|
||||||
l, t, r, b = self._possize
|
|
||||||
self.resize(l + x, t + y, r, b)
|
|
||||||
|
|
||||||
def resize(self, *args):
|
|
||||||
if len(args) == 1:
|
|
||||||
if type(args[0]) == FunctionType or type(args[0]) == MethodType:
|
|
||||||
self._possize = args[0]
|
|
||||||
else:
|
|
||||||
self.resize(*args[0])
|
|
||||||
elif len(args) == 2:
|
|
||||||
self._possize = (0, 0) + args
|
|
||||||
elif len(args) == 4:
|
|
||||||
self._possize = args
|
|
||||||
else:
|
|
||||||
raise TypeError, "wrong number of arguments"
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
del self._callback
|
|
||||||
del self._possize
|
|
||||||
del self._bindings
|
|
||||||
del self._parent
|
|
||||||
del self._parentwindow
|
|
||||||
|
|
||||||
def bind(self, key, callback):
|
|
||||||
"""bind a key or an 'event' to a callback"""
|
|
||||||
if callback:
|
|
||||||
self._bindings[key] = callback
|
|
||||||
elif self._bindings.has_key(key):
|
|
||||||
del self._bindings[key]
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(oldbounds)
|
|
||||||
self.GetWindow().InvalWindowRect(self._bounds)
|
|
||||||
|
|
||||||
def _calcbounds(self):
|
|
||||||
# calculate absolute bounds relative to the window origin from our
|
|
||||||
# abstract _possize attribute, which is either a 4-tuple or a callable object
|
|
||||||
oldbounds = self._bounds
|
|
||||||
pl, pt, pr, pb = self._parent._bounds
|
|
||||||
if callable(self._possize):
|
|
||||||
# _possize is callable, let it figure it out by itself: it should return
|
|
||||||
# the bounds relative to our parent widget.
|
|
||||||
width = pr - pl
|
|
||||||
height = pb - pt
|
|
||||||
self._bounds = Qd.OffsetRect(_intRect(self._possize(width, height)), pl, pt)
|
|
||||||
else:
|
|
||||||
# _possize must be a 4-tuple. This is where the algorithm by Peter Kriens and
|
|
||||||
# Petr van Blokland kicks in. (*** Parts of this algorithm are applied for
|
|
||||||
# patents by Ericsson, Sweden ***)
|
|
||||||
l, t, r, b = self._possize
|
|
||||||
# depending on the values of l(eft), t(op), r(right) and b(ottom),
|
|
||||||
# they mean different things:
|
|
||||||
if l < -1:
|
|
||||||
# l is less than -1, this mean it measures from the *right* of its parent
|
|
||||||
l = pr + l
|
|
||||||
else:
|
|
||||||
# l is -1 or greater, this mean it measures from the *left* of its parent
|
|
||||||
l = pl + l
|
|
||||||
if t < -1:
|
|
||||||
# t is less than -1, this mean it measures from the *bottom* of its parent
|
|
||||||
t = pb + t
|
|
||||||
else:
|
|
||||||
# t is -1 or greater, this mean it measures from the *top* of its parent
|
|
||||||
t = pt + t
|
|
||||||
if r > 1:
|
|
||||||
# r is greater than 1, this means r is the *width* of the widget
|
|
||||||
r = l + r
|
|
||||||
else:
|
|
||||||
# r is less than 1, this means it measures from the *right* of its parent
|
|
||||||
r = pr + r
|
|
||||||
if b > 1:
|
|
||||||
# b is greater than 1, this means b is the *height* of the widget
|
|
||||||
b = t + b
|
|
||||||
else:
|
|
||||||
# b is less than 1, this means it measures from the *bottom* of its parent
|
|
||||||
b = pb + b
|
|
||||||
self._bounds = (l, t, r, b)
|
|
||||||
if oldbounds and oldbounds <> self._bounds:
|
|
||||||
self.adjust(oldbounds)
|
|
||||||
for w in self._widgets:
|
|
||||||
w._calcbounds()
|
|
||||||
|
|
||||||
def test(self, point):
|
|
||||||
if Qd.PtInRect(point, self._bounds):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def findwidget(self, point, onlyenabled = 1):
|
|
||||||
if self.test(point):
|
|
||||||
for w in self._widgets:
|
|
||||||
widget = w.findwidget(point)
|
|
||||||
if widget is not None:
|
|
||||||
return widget
|
|
||||||
if self._enabled or not onlyenabled:
|
|
||||||
return self
|
|
||||||
|
|
||||||
def forall(self, methodname, *args):
|
|
||||||
for w in self._widgets:
|
|
||||||
rv = w.forall(methodname, *args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
if self._bindings.has_key("<" + methodname + ">"):
|
|
||||||
callback = self._bindings["<" + methodname + ">"]
|
|
||||||
rv = callback(*args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
if hasattr(self, methodname):
|
|
||||||
method = getattr(self, methodname)
|
|
||||||
return method(*args)
|
|
||||||
|
|
||||||
def forall_butself(self, methodname, *args):
|
|
||||||
for w in self._widgets:
|
|
||||||
rv = w.forall(methodname, *args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def forall_frombottom(self, methodname, *args):
|
|
||||||
if self._bindings.has_key("<" + methodname + ">"):
|
|
||||||
callback = self._bindings["<" + methodname + ">"]
|
|
||||||
rv = callback(*args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
if hasattr(self, methodname):
|
|
||||||
method = getattr(self, methodname)
|
|
||||||
rv = method(*args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
for w in self._widgets:
|
|
||||||
rv = w.forall_frombottom(methodname, *args)
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def _addwidget(self, key, widget):
|
|
||||||
if widget in self._widgets:
|
|
||||||
raise ValueError, "duplicate widget"
|
|
||||||
if self._widgetsdict.has_key(key):
|
|
||||||
self._removewidget(key)
|
|
||||||
self._widgets.append(widget)
|
|
||||||
self._widgetsdict[key] = widget
|
|
||||||
widget._parent = self
|
|
||||||
self._setparentwindow(widget)
|
|
||||||
if self._parentwindow and self._parentwindow.wid:
|
|
||||||
widget.forall_frombottom("open")
|
|
||||||
self.GetWindow().InvalWindowRect(widget._bounds)
|
|
||||||
|
|
||||||
def _setparentwindow(self, widget):
|
|
||||||
widget._parentwindow = self._parentwindow
|
|
||||||
for w in widget._widgets:
|
|
||||||
self._setparentwindow(w)
|
|
||||||
|
|
||||||
def _removewidget(self, key):
|
|
||||||
if not self._widgetsdict.has_key(key):
|
|
||||||
raise KeyError, "no widget with key %r" % (key,)
|
|
||||||
widget = self._widgetsdict[key]
|
|
||||||
for k in widget._widgetsdict.keys():
|
|
||||||
widget._removewidget(k)
|
|
||||||
if self._parentwindow._currentwidget == widget:
|
|
||||||
widget.select(0)
|
|
||||||
self._parentwindow._currentwidget = None
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(widget._bounds)
|
|
||||||
widget.close()
|
|
||||||
del self._widgetsdict[key]
|
|
||||||
self._widgets.remove(widget)
|
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
|
||||||
if type(value) == InstanceType and isinstance(value, Widget) and \
|
|
||||||
attr not in ("_currentwidget", "_lastrollover",
|
|
||||||
"_parent", "_parentwindow", "_defaultbutton"):
|
|
||||||
if hasattr(self, attr):
|
|
||||||
raise ValueError, "Can't replace existing attribute: " + attr
|
|
||||||
self._addwidget(attr, value)
|
|
||||||
self.__dict__[attr] = value
|
|
||||||
|
|
||||||
def __delattr__(self, attr):
|
|
||||||
if attr == "_widgetsdict":
|
|
||||||
raise AttributeError, "cannot delete attribute _widgetsdict"
|
|
||||||
if self._widgetsdict.has_key(attr):
|
|
||||||
self._removewidget(attr)
|
|
||||||
if self.__dict__.has_key(attr):
|
|
||||||
del self.__dict__[attr]
|
|
||||||
elif self.__dict__.has_key(attr):
|
|
||||||
del self.__dict__[attr]
|
|
||||||
else:
|
|
||||||
raise AttributeError, attr
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
self._addwidget(key, value)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
if not self._widgetsdict.has_key(key):
|
|
||||||
raise KeyError, key
|
|
||||||
return self._widgetsdict[key]
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
self._removewidget(key)
|
|
||||||
|
|
||||||
def SetPort(self):
|
|
||||||
self._parentwindow.SetPort()
|
|
||||||
|
|
||||||
|
|
||||||
def GetWindow(self):
|
|
||||||
return self._parentwindow.GetWindow()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if DEBUG:
|
|
||||||
print "%s instance deleted" % self.__class__.__name__
|
|
||||||
|
|
||||||
def _drawbounds(self):
|
|
||||||
Qd.FrameRect(self._bounds)
|
|
||||||
|
|
||||||
|
|
||||||
class ClickableWidget(Widget):
|
|
||||||
|
|
||||||
"""Base class for clickable widgets. (note: self._enabled must be true to receive click events.)"""
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def enable(self, onoff):
|
|
||||||
self._enabled = onoff
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def callback(self):
|
|
||||||
if self._callback:
|
|
||||||
return CallbackCall(self._callback, 1)
|
|
||||||
|
|
||||||
|
|
||||||
class SelectableWidget(ClickableWidget):
|
|
||||||
|
|
||||||
"""Base class for selectable widgets."""
|
|
||||||
|
|
||||||
_selectable = 1
|
|
||||||
|
|
||||||
def select(self, onoff, isclick = 0):
|
|
||||||
if onoff == self._selected:
|
|
||||||
return 1
|
|
||||||
if self._bindings.has_key("<select>"):
|
|
||||||
callback = self._bindings["<select>"]
|
|
||||||
if callback(onoff):
|
|
||||||
return 1
|
|
||||||
self._selected = onoff
|
|
||||||
if onoff:
|
|
||||||
if self._parentwindow._currentwidget is not None:
|
|
||||||
self._parentwindow._currentwidget.select(0)
|
|
||||||
self._parentwindow._currentwidget = self
|
|
||||||
else:
|
|
||||||
self._parentwindow._currentwidget = None
|
|
||||||
|
|
||||||
def key(self, char, event):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def drawselframe(self, onoff):
|
|
||||||
if not self._parentwindow._hasselframes:
|
|
||||||
return
|
|
||||||
App.DrawThemeFocusRect(self._bounds, onoff)
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
if self._selected:
|
|
||||||
self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
|
|
||||||
self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
|
|
||||||
else:
|
|
||||||
self.GetWindow().InvalWindowRect(oldbounds)
|
|
||||||
self.GetWindow().InvalWindowRect(self._bounds)
|
|
||||||
|
|
||||||
|
|
||||||
class _Line(Widget):
|
|
||||||
|
|
||||||
def __init__(self, possize, thickness = 1):
|
|
||||||
Widget.__init__(self, possize)
|
|
||||||
self._thickness = thickness
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self._calcbounds()
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
Qd.PaintRect(self._bounds)
|
|
||||||
|
|
||||||
def _drawbounds(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class HorizontalLine(_Line):
|
|
||||||
|
|
||||||
def _calcbounds(self):
|
|
||||||
Widget._calcbounds(self)
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
self._bounds = l, t, r, t + self._thickness
|
|
||||||
|
|
||||||
class VerticalLine(_Line):
|
|
||||||
|
|
||||||
def _calcbounds(self):
|
|
||||||
Widget._calcbounds(self)
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
self._bounds = l, t, l + self._thickness, b
|
|
||||||
|
|
||||||
|
|
||||||
class Frame(Widget):
|
|
||||||
|
|
||||||
def __init__(self, possize, pattern = Qd.GetQDGlobalsBlack(), color = (0, 0, 0)):
|
|
||||||
Widget.__init__(self, possize)
|
|
||||||
self._framepattern = pattern
|
|
||||||
self._framecolor = color
|
|
||||||
|
|
||||||
def setcolor(self, color):
|
|
||||||
self._framecolor = color
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def setpattern(self, pattern):
|
|
||||||
self._framepattern = pattern
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
penstate = Qd.GetPenState()
|
|
||||||
Qd.PenPat(self._framepattern)
|
|
||||||
Qd.RGBForeColor(self._framecolor)
|
|
||||||
Qd.FrameRect(self._bounds)
|
|
||||||
Qd.RGBForeColor((0, 0, 0))
|
|
||||||
Qd.SetPenState(penstate)
|
|
||||||
|
|
||||||
def _darkencolor((r, g, b)):
|
|
||||||
return int(0.75 * r), int(0.75 * g), int(0.75 * b)
|
|
||||||
|
|
||||||
class BevelBox(Widget):
|
|
||||||
|
|
||||||
"""'Platinum' beveled rectangle."""
|
|
||||||
|
|
||||||
def __init__(self, possize, color = (0xe000, 0xe000, 0xe000)):
|
|
||||||
Widget.__init__(self, possize)
|
|
||||||
self._color = color
|
|
||||||
self._darkercolor = _darkencolor(color)
|
|
||||||
|
|
||||||
def setcolor(self, color):
|
|
||||||
self._color = color
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
|
|
||||||
Qd.RGBForeColor(self._color)
|
|
||||||
Qd.PaintRect((l, t, r, b))
|
|
||||||
Qd.RGBForeColor(self._darkercolor)
|
|
||||||
Qd.MoveTo(l, b)
|
|
||||||
Qd.LineTo(r, b)
|
|
||||||
Qd.LineTo(r, t)
|
|
||||||
Qd.RGBForeColor((0, 0, 0))
|
|
||||||
|
|
||||||
|
|
||||||
class Group(Widget):
|
|
||||||
|
|
||||||
"""A container for subwidgets"""
|
|
||||||
|
|
||||||
|
|
||||||
class HorizontalPanes(Widget):
|
|
||||||
|
|
||||||
"""Panes, a.k.a. frames. Works a bit like a group. Devides the widget area into "panes",
|
|
||||||
which can be resized by the user by clicking and dragging between the subwidgets."""
|
|
||||||
|
|
||||||
_direction = 1
|
|
||||||
|
|
||||||
def __init__(self, possize, panesizes = None, gutter = 8):
|
|
||||||
"""panesizes should be a tuple of numbers. The length of the tuple is the number of panes,
|
|
||||||
the items in the tuple are the relative sizes of these panes; these numbers should add up
|
|
||||||
to 1 (the total size of all panes)."""
|
|
||||||
Widget.__init__(self, possize)
|
|
||||||
self._panesizes = panesizes
|
|
||||||
self._gutter = gutter
|
|
||||||
self._enabled = 1
|
|
||||||
self.setuppanes()
|
|
||||||
|
|
||||||
#def open(self):
|
|
||||||
# self.installbounds()
|
|
||||||
# ClickableWidget.open(self)
|
|
||||||
|
|
||||||
def _calcbounds(self):
|
|
||||||
# hmmm. It should not neccesary be override _calcbounds :-(
|
|
||||||
self.installbounds()
|
|
||||||
Widget._calcbounds(self)
|
|
||||||
|
|
||||||
def setuppanes(self):
|
|
||||||
panesizes = self._panesizes
|
|
||||||
total = 0
|
|
||||||
if panesizes is not None:
|
|
||||||
#if len(self._widgets) <> len(panesizes):
|
|
||||||
# raise TypeError, 'number of widgets does not match number of panes'
|
|
||||||
for panesize in panesizes:
|
|
||||||
if not 0 < panesize < 1:
|
|
||||||
raise TypeError, 'pane sizes must be between 0 and 1, not including.'
|
|
||||||
total = total + panesize
|
|
||||||
if round(total, 4) <> 1.0:
|
|
||||||
raise TypeError, 'pane sizes must add up to 1'
|
|
||||||
else:
|
|
||||||
# XXX does not work!
|
|
||||||
step = 1.0 / len(self._widgets)
|
|
||||||
panesizes = []
|
|
||||||
for i in range(len(self._widgets)):
|
|
||||||
panesizes.append(step)
|
|
||||||
current = 0
|
|
||||||
self._panesizes = []
|
|
||||||
self._gutters = []
|
|
||||||
for panesize in panesizes:
|
|
||||||
if current:
|
|
||||||
self._gutters.append(current)
|
|
||||||
self._panesizes.append((current, current + panesize))
|
|
||||||
current = current + panesize
|
|
||||||
self.makepanebounds()
|
|
||||||
|
|
||||||
def getpanesizes(self):
|
|
||||||
return map(lambda (fr, to): to-fr, self._panesizes)
|
|
||||||
|
|
||||||
boundstemplate = "lambda width, height: (0, height * %s + %d, width, height * %s + %d)"
|
|
||||||
|
|
||||||
def makepanebounds(self):
|
|
||||||
halfgutter = self._gutter / 2
|
|
||||||
self._panebounds = []
|
|
||||||
for i in range(len(self._panesizes)):
|
|
||||||
panestart, paneend = self._panesizes[i]
|
|
||||||
boundsstring = self.boundstemplate % (repr(panestart), panestart and halfgutter,
|
|
||||||
repr(paneend), (paneend <> 1.0) and -halfgutter)
|
|
||||||
self._panebounds.append(eval(boundsstring))
|
|
||||||
|
|
||||||
def installbounds(self):
|
|
||||||
#self.setuppanes()
|
|
||||||
for i in range(len(self._widgets)):
|
|
||||||
w = self._widgets[i]
|
|
||||||
w._possize = self._panebounds[i]
|
|
||||||
#if hasattr(w, "setuppanes"):
|
|
||||||
# w.setuppanes()
|
|
||||||
if hasattr(w, "installbounds"):
|
|
||||||
w.installbounds()
|
|
||||||
|
|
||||||
def rollover(self, point, onoff):
|
|
||||||
if onoff:
|
|
||||||
orgmouse = point[self._direction]
|
|
||||||
halfgutter = self._gutter / 2
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
if self._direction:
|
|
||||||
begin, end = t, b
|
|
||||||
else:
|
|
||||||
begin, end = l, r
|
|
||||||
|
|
||||||
i = self.findgutter(orgmouse, begin, end)
|
|
||||||
if i is None:
|
|
||||||
SetCursor("arrow")
|
|
||||||
else:
|
|
||||||
SetCursor(self._direction and 'vmover' or 'hmover')
|
|
||||||
|
|
||||||
def findgutter(self, orgmouse, begin, end):
|
|
||||||
tolerance = max(4, self._gutter) / 2
|
|
||||||
for i in range(len(self._gutters)):
|
|
||||||
pos = begin + (end - begin) * self._gutters[i]
|
|
||||||
if abs(orgmouse - pos) <= tolerance:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
return i
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
# what a mess...
|
|
||||||
orgmouse = point[self._direction]
|
|
||||||
halfgutter = self._gutter / 2
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
if self._direction:
|
|
||||||
begin, end = t, b
|
|
||||||
else:
|
|
||||||
begin, end = l, r
|
|
||||||
|
|
||||||
i = self.findgutter(orgmouse, begin, end)
|
|
||||||
if i is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
pos = orgpos = begin + (end - begin) * self._gutters[i] # init pos too, for fast click on border, bug done by Petr
|
|
||||||
|
|
||||||
minpos = self._panesizes[i][0]
|
|
||||||
maxpos = self._panesizes[i+1][1]
|
|
||||||
minpos = begin + (end - begin) * minpos + 64
|
|
||||||
maxpos = begin + (end - begin) * maxpos - 64
|
|
||||||
if minpos > orgpos and maxpos < orgpos:
|
|
||||||
return
|
|
||||||
|
|
||||||
#SetCursor("fist")
|
|
||||||
self.SetPort()
|
|
||||||
if self._direction:
|
|
||||||
rect = l, orgpos - 1, r, orgpos
|
|
||||||
else:
|
|
||||||
rect = orgpos - 1, t, orgpos, b
|
|
||||||
|
|
||||||
# track mouse --- XXX move to separate method?
|
|
||||||
Qd.PenMode(QuickDraw.srcXor)
|
|
||||||
Qd.PenPat(Qd.GetQDGlobalsGray())
|
|
||||||
Qd.PaintRect(_intRect(rect))
|
|
||||||
lastpos = None
|
|
||||||
while Evt.Button():
|
|
||||||
pos = orgpos - orgmouse + Evt.GetMouse()[self._direction]
|
|
||||||
pos = max(pos, minpos)
|
|
||||||
pos = min(pos, maxpos)
|
|
||||||
if pos == lastpos:
|
|
||||||
continue
|
|
||||||
Qd.PenPat(Qd.GetQDGlobalsGray())
|
|
||||||
Qd.PaintRect(_intRect(rect))
|
|
||||||
if self._direction:
|
|
||||||
rect = l, pos - 1, r, pos
|
|
||||||
else:
|
|
||||||
rect = pos - 1, t, pos, b
|
|
||||||
Qd.PenPat(Qd.GetQDGlobalsGray())
|
|
||||||
Qd.PaintRect(_intRect(rect))
|
|
||||||
lastpos = pos
|
|
||||||
self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
|
|
||||||
Evt.WaitNextEvent(0, 3)
|
|
||||||
Qd.PaintRect(_intRect(rect))
|
|
||||||
Qd.PenNormal()
|
|
||||||
SetCursor("watch")
|
|
||||||
|
|
||||||
newpos = (pos - begin) / float(end - begin)
|
|
||||||
self._gutters[i] = newpos
|
|
||||||
self._panesizes[i] = self._panesizes[i][0], newpos
|
|
||||||
self._panesizes[i+1] = newpos, self._panesizes[i+1][1]
|
|
||||||
self.makepanebounds()
|
|
||||||
self.installbounds()
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
|
|
||||||
class VerticalPanes(HorizontalPanes):
|
|
||||||
"""see HorizontalPanes"""
|
|
||||||
_direction = 0
|
|
||||||
boundstemplate = "lambda width, height: (width * %s + %d, 0, width * %s + %d, height)"
|
|
||||||
|
|
||||||
|
|
||||||
class ColorPicker(ClickableWidget):
|
|
||||||
|
|
||||||
"""Color picker widget. Allows the user to choose a color."""
|
|
||||||
|
|
||||||
def __init__(self, possize, color = (0, 0, 0), callback = None):
|
|
||||||
ClickableWidget.__init__(self, possize)
|
|
||||||
self._color = color
|
|
||||||
self._callback = callback
|
|
||||||
self._enabled = 1
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
import ColorPicker
|
|
||||||
newcolor, ok = ColorPicker.GetColor("", self._color)
|
|
||||||
if ok:
|
|
||||||
self._color = newcolor
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
if self._callback:
|
|
||||||
return CallbackCall(self._callback, 0, self._color)
|
|
||||||
|
|
||||||
def set(self, color):
|
|
||||||
self._color = color
|
|
||||||
self.SetPort()
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return self._color
|
|
||||||
|
|
||||||
def draw(self, visRgn=None):
|
|
||||||
if self._visible:
|
|
||||||
if not visRgn:
|
|
||||||
visRgn = self._parentwindow.wid.GetWindowPort().visRgn
|
|
||||||
Qd.PenPat(Qd.GetQDGlobalsGray())
|
|
||||||
rect = self._bounds
|
|
||||||
Qd.FrameRect(rect)
|
|
||||||
rect = Qd.InsetRect(rect, 3, 3)
|
|
||||||
Qd.PenNormal()
|
|
||||||
Qd.RGBForeColor(self._color)
|
|
||||||
Qd.PaintRect(rect)
|
|
||||||
Qd.RGBForeColor((0, 0, 0))
|
|
||||||
|
|
||||||
|
|
||||||
# misc utils
|
|
||||||
|
|
||||||
def CallbackCall(callback, mustfit, *args):
|
|
||||||
"""internal helper routine for W"""
|
|
||||||
# XXX this function should die.
|
|
||||||
if type(callback) == FunctionType:
|
|
||||||
func = callback
|
|
||||||
maxargs = func.func_code.co_argcount
|
|
||||||
elif type(callback) == MethodType:
|
|
||||||
func = callback.im_func
|
|
||||||
maxargs = func.func_code.co_argcount - 1
|
|
||||||
else:
|
|
||||||
if callable(callback):
|
|
||||||
return callback(*args)
|
|
||||||
else:
|
|
||||||
raise TypeError, "uncallable callback object"
|
|
||||||
|
|
||||||
if func.func_defaults:
|
|
||||||
minargs = maxargs - len(func.func_defaults)
|
|
||||||
else:
|
|
||||||
minargs = maxargs
|
|
||||||
if minargs <= len(args) <= maxargs:
|
|
||||||
return callback(*args)
|
|
||||||
elif not mustfit and minargs == 0:
|
|
||||||
return callback()
|
|
||||||
else:
|
|
||||||
if mustfit:
|
|
||||||
raise TypeError, "callback accepts wrong number of arguments: %r" % len(args)
|
|
||||||
else:
|
|
||||||
raise TypeError, "callback accepts wrong number of arguments: 0 or %r" % len(args)
|
|
||||||
|
|
||||||
|
|
||||||
def HasBaseClass(obj, class_):
|
|
||||||
try:
|
|
||||||
raise obj
|
|
||||||
except class_:
|
|
||||||
return 1
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# To remove the dependence of Widgets.rsrc we hardcode the cursor
|
|
||||||
# data below.
|
|
||||||
#_cursors = {
|
|
||||||
# "watch" : Qd.GetCursor(QuickDraw.watchCursor).data,
|
|
||||||
# "arrow" : Qd.GetQDGlobalsArrow(),
|
|
||||||
# "iBeam" : Qd.GetCursor(QuickDraw.iBeamCursor).data,
|
|
||||||
# "cross" : Qd.GetCursor(QuickDraw.crossCursor).data,
|
|
||||||
# "plus" : Qd.GetCursor(QuickDraw.plusCursor).data,
|
|
||||||
# "hand" : Qd.GetCursor(468).data,
|
|
||||||
# "fist" : Qd.GetCursor(469).data,
|
|
||||||
# "hmover" : Qd.GetCursor(470).data,
|
|
||||||
# "vmover" : Qd.GetCursor(471).data,
|
|
||||||
# "zoomin" : Qd.GetCursor(472).data,
|
|
||||||
# "zoomout" : Qd.GetCursor(473).data,
|
|
||||||
# "zoom" : Qd.GetCursor(474).data,
|
|
||||||
#}
|
|
||||||
|
|
||||||
_cursors = {
|
|
||||||
'arrow':
|
|
||||||
'\x00\x00\x40\x00\x60\x00\x70\x00\x78\x00\x7c\x00\x7e\x00\x7f\x00'
|
|
||||||
'\x7f\x80\x7c\x00\x6c\x00\x46\x00\x06\x00\x03\x00\x03\x00\x00\x00'
|
|
||||||
'\xc0\x00\xe0\x00\xf0\x00\xf8\x00\xfc\x00\xfe\x00\xff\x00\xff\x80'
|
|
||||||
'\xff\xc0\xff\xe0\xfe\x00\xef\x00\xcf\x00\x87\x80\x07\x80\x03\x80'
|
|
||||||
'\x00\x01\x00\x01',
|
|
||||||
'cross':
|
|
||||||
'\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\xff\xe0\x04\x00\x04\x00'
|
|
||||||
'\x04\x00\x04\x00\x04\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
||||||
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
||||||
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
||||||
'\x00\x05\x00\x05',
|
|
||||||
'fist':
|
|
||||||
'\x00\x00\x00\x00\x0d\x80\x12\x70\x12\x4c\x12\x4a\x28\x0a\x28\x02'
|
|
||||||
'\x48\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
|
|
||||||
'\x00\x00\x00\x00\x0d\x80\x1f\xf0\x1f\xfc\x1f\xfe\x3f\xfe\x3f\xfe'
|
|
||||||
'\x7f\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
|
|
||||||
'\x00\x09\x00\x08',
|
|
||||||
'hand':
|
|
||||||
'\x01\x80\x1a\x70\x26\x48\x26\x4a\x12\x4d\x12\x49\x68\x09\x98\x01'
|
|
||||||
'\x88\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
|
|
||||||
'\x01\x80\x1b\xf0\x3f\xf8\x3f\xfa\x1f\xff\x1f\xff\x6f\xff\xff\xff'
|
|
||||||
'\xff\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
|
|
||||||
'\x00\x09\x00\x08',
|
|
||||||
'hmover':
|
|
||||||
'\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x11\x88\x31\x8c\x7f\xfe'
|
|
||||||
'\x31\x8c\x11\x88\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00'
|
|
||||||
'\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x1b\xd8\x3b\xdc\x7f\xfe\xff\xff'
|
|
||||||
'\x7f\xfe\x3b\xdc\x1b\xd8\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x00\x00'
|
|
||||||
'\x00\x07\x00\x07',
|
|
||||||
'iBeam':
|
|
||||||
'\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
|
|
||||||
'\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
|
|
||||||
'\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
|
|
||||||
'\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
|
|
||||||
'\x00\x04\x00\x07',
|
|
||||||
'plus':
|
|
||||||
'\x00\x00\x07\xc0\x04\x60\x04\x60\x04\x60\x7c\x7c\x43\x86\x42\x86'
|
|
||||||
'\x43\x86\x7c\x7e\x3c\x7e\x04\x60\x04\x60\x07\xe0\x03\xe0\x00\x00'
|
|
||||||
'\x0f\xc0\x0f\xe0\x0f\xf0\x0f\xf0\xff\xff\xff\xfe\xfc\x7f\xfc\x7f'
|
|
||||||
'\xfc\x7f\xff\xff\x7f\xff\x7f\xff\x0f\xf0\x0f\xf0\x07\xf0\x03\xe0'
|
|
||||||
'\x00\x08\x00\x08',
|
|
||||||
'vmover':
|
|
||||||
'\x00\x00\x01\x00\x03\x80\x07\xc0\x01\x00\x01\x00\x01\x00\x7f\xfc'
|
|
||||||
'\x7f\xfc\x01\x00\x01\x00\x01\x00\x07\xc0\x03\x80\x01\x00\x00\x00'
|
|
||||||
'\x01\x00\x03\x80\x07\xc0\x0f\xe0\x0f\xe0\x03\x80\xff\xfe\xff\xfe'
|
|
||||||
'\xff\xfe\xff\xfe\x03\x80\x0f\xe0\x0f\xe0\x07\xc0\x03\x80\x01\x00'
|
|
||||||
'\x00\x07\x00\x07',
|
|
||||||
'watch':
|
|
||||||
'\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x40\x80\x84\x40\x84\x40\x84\x60'
|
|
||||||
'\x9c\x60\x80\x40\x80\x40\x40\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
|
|
||||||
'\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x7f\x80\xff\xc0\xff\xc0\xff\xc0'
|
|
||||||
'\xff\xc0\xff\xc0\xff\xc0\x7f\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
|
|
||||||
'\x00\x08\x00\x08',
|
|
||||||
'zoom':
|
|
||||||
'\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x80\x10\x80\x10\x80\x10'
|
|
||||||
'\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
|
|
||||||
'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x00\x06\x00\x06',
|
|
||||||
'zoomin':
|
|
||||||
'\x0f\x00\x30\xc0\x40\x20\x46\x20\x86\x10\x9f\x90\x9f\x90\x86\x10'
|
|
||||||
'\x46\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
|
|
||||||
'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x00\x06\x00\x06',
|
|
||||||
'zoomout':
|
|
||||||
'\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x9f\x90\x9f\x90\x80\x10'
|
|
||||||
'\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
|
|
||||||
'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
|
|
||||||
'\x00\x06\x00\x06',
|
|
||||||
}
|
|
||||||
|
|
||||||
def SetCursor(what):
|
|
||||||
"""Set the cursorshape to any of these: 'arrow', 'cross', 'fist', 'hand', 'hmover', 'iBeam',
|
|
||||||
'plus', 'vmover', 'watch', 'zoom', 'zoomin', 'zoomout'."""
|
|
||||||
Qd.SetCursor(_cursors[what])
|
|
|
@ -1,432 +0,0 @@
|
||||||
from Carbon import Ctl, Controls
|
|
||||||
from Carbon import Evt, Qd, Win
|
|
||||||
import Wbase
|
|
||||||
|
|
||||||
|
|
||||||
class ControlWidget(Wbase.ClickableWidget):
|
|
||||||
|
|
||||||
"""Baseclass for all native controls."""
|
|
||||||
|
|
||||||
def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1, viewsize = 0):
|
|
||||||
Wbase.ClickableWidget.__init__(self, possize)
|
|
||||||
self._control = None
|
|
||||||
self._title = title
|
|
||||||
self._callback = callback
|
|
||||||
self._procID = procID
|
|
||||||
self._value = value
|
|
||||||
self._min = min
|
|
||||||
self._max = max
|
|
||||||
self._enabled = 1
|
|
||||||
self._viewsize = viewsize
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
# NewControl doesn't accept 32-bit value, min, or max, so for consistency
|
|
||||||
# with the new 32-bit set/get methods, out-of-range values are initially
|
|
||||||
# set as zero, followed by a 32-bit set of the actual value.
|
|
||||||
# Values not representable in 16 bits will fail on MacOS 8.1, however
|
|
||||||
# the vast majority of control usage should still be compatible.
|
|
||||||
_value, _min, _max = self._value, self._min, self._max
|
|
||||||
if -32768 <= _value <= 32767:
|
|
||||||
bigvalue = None
|
|
||||||
else:
|
|
||||||
bigvalue = _value
|
|
||||||
_value = 0
|
|
||||||
if -32768 <= _min <= 32767:
|
|
||||||
bigmin = None
|
|
||||||
else:
|
|
||||||
bigmin = _min
|
|
||||||
_min = 0
|
|
||||||
if -32768 <= _max <= 32767:
|
|
||||||
bigmax = None
|
|
||||||
else:
|
|
||||||
bigmax = _max
|
|
||||||
_max = 0
|
|
||||||
self._control = Ctl.NewControl(self._parentwindow.wid,
|
|
||||||
self._bounds,
|
|
||||||
self._title,
|
|
||||||
1,
|
|
||||||
_value,
|
|
||||||
_min,
|
|
||||||
_max,
|
|
||||||
self._procID,
|
|
||||||
0)
|
|
||||||
if bigvalue:
|
|
||||||
self._control.SetControl32BitValue(bigvalue)
|
|
||||||
if bigmin:
|
|
||||||
self._control.SetControl32BitMinimum(bigmin)
|
|
||||||
if bigmax:
|
|
||||||
self._control.SetControl32BitMaximum(bigmax)
|
|
||||||
if self._viewsize:
|
|
||||||
try:
|
|
||||||
self._control.SetControlViewSize(self._viewsize)
|
|
||||||
# Not available in MacOS 8.1, but that's OK since it only affects
|
|
||||||
# proportional scrollbars which weren't available in 8.1 either.
|
|
||||||
except NotImplementedError:
|
|
||||||
pass
|
|
||||||
self.enable(self._enabled)
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
self._control.HideControl()
|
|
||||||
self._control.MoveControl(self._bounds[0], self._bounds[1])
|
|
||||||
self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
|
|
||||||
if self._visible:
|
|
||||||
Qd.EraseRect(self._bounds)
|
|
||||||
self._control.ShowControl()
|
|
||||||
self.GetWindow().ValidWindowRect(self._bounds)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self._control.HideControl()
|
|
||||||
self._control = None
|
|
||||||
Wbase.ClickableWidget.close(self)
|
|
||||||
|
|
||||||
def enable(self, onoff):
|
|
||||||
if self._control and self._enabled <> onoff:
|
|
||||||
self._control.HiliteControl((not onoff) and 255)
|
|
||||||
self._enabled = onoff
|
|
||||||
|
|
||||||
def show(self, onoff):
|
|
||||||
self._visible = onoff
|
|
||||||
for w in self._widgets:
|
|
||||||
w.show(onoff)
|
|
||||||
if onoff:
|
|
||||||
self._control.ShowControl()
|
|
||||||
else:
|
|
||||||
self._control.HideControl()
|
|
||||||
|
|
||||||
def activate(self, onoff):
|
|
||||||
self._activated = onoff
|
|
||||||
if self._enabled:
|
|
||||||
if onoff:
|
|
||||||
self._control.ActivateControl()
|
|
||||||
else:
|
|
||||||
self._control.DeactivateControl()
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
self._control.Draw1Control()
|
|
||||||
|
|
||||||
def test(self, point):
|
|
||||||
if Qd.PtInRect(point, self._bounds) and self._enabled:
|
|
||||||
return 1
|
|
||||||
#ctltype, control = Ctl.FindControl(point, self._parentwindow.wid)
|
|
||||||
#if self._enabled and control == self._control:
|
|
||||||
# return 1
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
part = self._control.TrackControl(point)
|
|
||||||
if part:
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0)
|
|
||||||
|
|
||||||
def settitle(self, title):
|
|
||||||
if self._control:
|
|
||||||
self._control.SetControlTitle(title)
|
|
||||||
self._title = title
|
|
||||||
|
|
||||||
def gettitle(self):
|
|
||||||
return self._title
|
|
||||||
|
|
||||||
def set(self, value):
|
|
||||||
if self._control:
|
|
||||||
if -32768 <= value <= 32767:
|
|
||||||
# No 32-bit control support in MacOS 8.1, so use
|
|
||||||
# the 16-bit interface when possible.
|
|
||||||
self._control.SetControlValue(value)
|
|
||||||
else:
|
|
||||||
self._control.SetControl32BitValue(value)
|
|
||||||
else:
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
if self._control:
|
|
||||||
try:
|
|
||||||
return self._control.GetControl32BitValue()
|
|
||||||
# No 32-bit control support in MacOS 8.1, so fall
|
|
||||||
# back to the 16-bit interface when needed.
|
|
||||||
except NotImplementedError:
|
|
||||||
return self._control.GetControlValue()
|
|
||||||
else:
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
|
|
||||||
class Button(ControlWidget):
|
|
||||||
|
|
||||||
"""Standard push button."""
|
|
||||||
|
|
||||||
procID = Controls.pushButProc | Controls.useWFont
|
|
||||||
|
|
||||||
def __init__(self, possize, title = "Button", callback = None):
|
|
||||||
ControlWidget.__init__(self, possize, title, self.procID, callback, 0, 0, 1)
|
|
||||||
self._isdefault = 0
|
|
||||||
|
|
||||||
def push(self):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
# emulate the pushing of the button
|
|
||||||
import time
|
|
||||||
self._control.HiliteControl(Controls.kControlButtonPart)
|
|
||||||
self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None) # needed under OSX
|
|
||||||
time.sleep(0.1)
|
|
||||||
self._control.HiliteControl(0)
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0)
|
|
||||||
|
|
||||||
def enable(self, onoff):
|
|
||||||
if self._control and self._enabled <> onoff:
|
|
||||||
self._control.HiliteControl((not onoff) and 255)
|
|
||||||
self._enabled = onoff
|
|
||||||
|
|
||||||
def show(self, onoff):
|
|
||||||
ControlWidget.show(self, onoff)
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
self._control.Draw1Control()
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
ControlWidget.open(self)
|
|
||||||
if self._isdefault:
|
|
||||||
self._setdefault(self._isdefault)
|
|
||||||
|
|
||||||
def _setdefault(self, onoff):
|
|
||||||
c = self._control
|
|
||||||
if c is not None:
|
|
||||||
if onoff:
|
|
||||||
data = "\xFF"
|
|
||||||
else:
|
|
||||||
data = "\0"
|
|
||||||
# hide before changing state, otherwise the button isn't always
|
|
||||||
# redrawn correctly, although it's quite different under Aqua
|
|
||||||
# and Classic...
|
|
||||||
c.HideControl()
|
|
||||||
c.SetControlData(Controls.kControlNoPart,
|
|
||||||
Controls.kControlPushButtonDefaultTag, data)
|
|
||||||
c.ShowControl()
|
|
||||||
self._isdefault = onoff
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
if self._isdefault:
|
|
||||||
old = Qd.InsetRect(oldbounds, -4, -4)
|
|
||||||
new = Qd.InsetRect(self._bounds, -4, -4)
|
|
||||||
Qd.EraseRect(old)
|
|
||||||
self.GetWindow().InvalWindowRect(old)
|
|
||||||
self.GetWindow().InvalWindowRect(new)
|
|
||||||
ControlWidget.adjust(self, oldbounds)
|
|
||||||
|
|
||||||
|
|
||||||
class BevelButton(Button):
|
|
||||||
procID = Controls.kControlBevelButtonNormalBevelProc | Controls.useWFont
|
|
||||||
|
|
||||||
|
|
||||||
class CheckBox(ControlWidget):
|
|
||||||
|
|
||||||
"""Standard checkbox."""
|
|
||||||
|
|
||||||
def __init__(self, possize, title = "Checkbox", callback = None, value = 0):
|
|
||||||
procID = Controls.checkBoxProc | Controls.useWFont
|
|
||||||
ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
part = self._control.TrackControl(point)
|
|
||||||
if part:
|
|
||||||
self.toggle()
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, self.get())
|
|
||||||
|
|
||||||
def push(self):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
self.toggle()
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, self.get())
|
|
||||||
|
|
||||||
def toggle(self):
|
|
||||||
self.set(not self.get())
|
|
||||||
|
|
||||||
|
|
||||||
class RadioButton(ControlWidget):
|
|
||||||
|
|
||||||
"""Standard radiobutton."""
|
|
||||||
|
|
||||||
# XXX We need a radiogroup widget; this is too kludgy.
|
|
||||||
|
|
||||||
def __init__(self, possize, title, thebuttons, callback = None, value = 0):
|
|
||||||
procID = Controls.radioButProc | Controls.useWFont
|
|
||||||
ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
|
|
||||||
self.thebuttons = thebuttons
|
|
||||||
thebuttons.append(self)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.thebuttons = None
|
|
||||||
ControlWidget.close(self)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
part = self._control.TrackControl(point)
|
|
||||||
if part:
|
|
||||||
self.set(1)
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, 1)
|
|
||||||
|
|
||||||
def push(self):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
self.set(1)
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, 1)
|
|
||||||
|
|
||||||
def set(self, value):
|
|
||||||
for button in self.thebuttons:
|
|
||||||
if button._control:
|
|
||||||
button._control.SetControlValue(button == self)
|
|
||||||
else:
|
|
||||||
button._value = (button == self)
|
|
||||||
|
|
||||||
|
|
||||||
class Scrollbar(ControlWidget):
|
|
||||||
|
|
||||||
"""Standard scrollbar."""
|
|
||||||
|
|
||||||
def __init__(self, possize, callback=None, value=0, min=0, max=0, livefeedback=1):
|
|
||||||
if livefeedback:
|
|
||||||
procID = Controls.kControlScrollBarLiveProc
|
|
||||||
else:
|
|
||||||
procID = Controls.scrollBarProc
|
|
||||||
ControlWidget.__init__(self, possize, "", procID, callback, value, min, max)
|
|
||||||
|
|
||||||
# interface
|
|
||||||
# def set(self, value):
|
|
||||||
# if self._callback:
|
|
||||||
# Wbase.CallbackCall(self._callback, 1, value)
|
|
||||||
|
|
||||||
def up(self):
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 1, '+')
|
|
||||||
|
|
||||||
def down(self):
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 1, '-')
|
|
||||||
|
|
||||||
def pageup(self):
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 1, '++')
|
|
||||||
|
|
||||||
def pagedown(self):
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 1, '--')
|
|
||||||
|
|
||||||
def setmin(self, min):
|
|
||||||
if self._control is not None:
|
|
||||||
if -32768 <= min <= 32767:
|
|
||||||
# No 32-bit control support in MacOS 8.1, so use
|
|
||||||
# the 16-bit interface when possible.
|
|
||||||
self._control.SetControlMinimum(min)
|
|
||||||
else:
|
|
||||||
self._control.SetControl32BitMinimum(min)
|
|
||||||
else:
|
|
||||||
self._min = min
|
|
||||||
|
|
||||||
def setmax(self, max):
|
|
||||||
if self._control is not None:
|
|
||||||
if -32768 <= max <= 32767:
|
|
||||||
# No 32-bit control support in MacOS 8.1, so use
|
|
||||||
# the 16-bit interface when possible.
|
|
||||||
self._control.SetControlMaximum(max)
|
|
||||||
else:
|
|
||||||
self._control.SetControl32BitMaximum(max)
|
|
||||||
else:
|
|
||||||
self._max = max
|
|
||||||
|
|
||||||
def setviewsize(self, viewsize):
|
|
||||||
if self._control is not None:
|
|
||||||
try:
|
|
||||||
self._control.SetControlViewSize(viewsize)
|
|
||||||
# Not available in MacOS 8.1, but that's OK since it only affects
|
|
||||||
# proportional scrollbars which weren't available in 8.1 either.
|
|
||||||
except NotImplementedError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self._viewsize = viewsize
|
|
||||||
|
|
||||||
def getmin(self):
|
|
||||||
try:
|
|
||||||
return self._control.GetControl32BitMinimum()
|
|
||||||
# No 32-bit control support in MacOS 8.1, so fall
|
|
||||||
# back to the 16-bit interface when needed.
|
|
||||||
except NotImplementedError:
|
|
||||||
return self._control.GetControlMinimum()
|
|
||||||
|
|
||||||
def getmax(self):
|
|
||||||
try:
|
|
||||||
return self._control.GetControl32BitMaximum()
|
|
||||||
# No 32-bit control support in MacOS 8.1, so fall
|
|
||||||
# back to the 16-bit interface when needed.
|
|
||||||
except NotImplementedError:
|
|
||||||
return self._control.GetControlMaximum()
|
|
||||||
|
|
||||||
# internals
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
def hitter(ctl, part, self=self):
|
|
||||||
if part:
|
|
||||||
self._hit(part)
|
|
||||||
part = self._control.TrackControl(point, hitter)
|
|
||||||
|
|
||||||
def _hit(self, part):
|
|
||||||
value = None
|
|
||||||
if part == Controls.inThumb:
|
|
||||||
try:
|
|
||||||
value = self._control.GetControl32BitValue()
|
|
||||||
# No 32-bit control support in MacOS 8.1, so fall
|
|
||||||
# back to the 16-bit interface when needed.
|
|
||||||
except NotImplementedError:
|
|
||||||
value = self._control.GetControlValue()
|
|
||||||
elif part == Controls.inUpButton:
|
|
||||||
value = "+"
|
|
||||||
elif part == Controls.inDownButton:
|
|
||||||
value = "-"
|
|
||||||
elif part == Controls.inPageUp:
|
|
||||||
value = "++"
|
|
||||||
elif part == Controls.inPageDown:
|
|
||||||
value = "--"
|
|
||||||
if value is not None and self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 1, value)
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
self._control.Draw1Control()
|
|
||||||
#Qd.FrameRect(self._bounds)
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(oldbounds)
|
|
||||||
self._control.HideControl()
|
|
||||||
self._control.MoveControl(self._bounds[0], self._bounds[1])
|
|
||||||
self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
|
|
||||||
if self._visible:
|
|
||||||
Qd.EraseRect(self._bounds)
|
|
||||||
if self._activated:
|
|
||||||
self._control.ShowControl()
|
|
||||||
else:
|
|
||||||
Qd.FrameRect(self._bounds)
|
|
||||||
self.GetWindow().ValidWindowRect(self._bounds)
|
|
||||||
|
|
||||||
|
|
||||||
def _scalebarvalue(absmin, absmax, curmin, curmax):
|
|
||||||
if curmin <= absmin and curmax >= absmax:
|
|
||||||
return None
|
|
||||||
if curmin <= absmin:
|
|
||||||
return 0
|
|
||||||
if curmax >= absmax:
|
|
||||||
return 32767
|
|
||||||
perc = float(curmin-absmin) / float((absmax - absmin) - (curmax - curmin))
|
|
||||||
return int(perc*32767)
|
|
Binary file not shown.
|
@ -1,45 +0,0 @@
|
||||||
spacekey = ' '
|
|
||||||
returnkey = '\r'
|
|
||||||
tabkey = '\t'
|
|
||||||
enterkey = '\003'
|
|
||||||
backspacekey = '\010'
|
|
||||||
deletekey = '\177'
|
|
||||||
clearkey = '\033'
|
|
||||||
helpkey = '\005'
|
|
||||||
|
|
||||||
leftarrowkey = '\034'
|
|
||||||
rightarrowkey = '\035'
|
|
||||||
uparrowkey = '\036'
|
|
||||||
downarrowkey = '\037'
|
|
||||||
arrowkeys = [leftarrowkey, rightarrowkey, uparrowkey, downarrowkey]
|
|
||||||
|
|
||||||
topkey = '\001'
|
|
||||||
bottomkey = '\004'
|
|
||||||
pageupkey = '\013'
|
|
||||||
pagedownkey = '\014'
|
|
||||||
scrollkeys = [topkey, bottomkey, pageupkey, pagedownkey]
|
|
||||||
|
|
||||||
navigationkeys = arrowkeys + scrollkeys
|
|
||||||
|
|
||||||
keycodes = {
|
|
||||||
"space" : ' ',
|
|
||||||
"return" : '\r',
|
|
||||||
"tab" : '\t',
|
|
||||||
"enter" : '\003',
|
|
||||||
"backspace" : '\010',
|
|
||||||
"delete" : '\177',
|
|
||||||
"help" : '\005',
|
|
||||||
"leftarrow" : '\034',
|
|
||||||
"rightarrow" : '\035',
|
|
||||||
"uparrow" : '\036',
|
|
||||||
"downarrow" : '\037',
|
|
||||||
"top" : '\001',
|
|
||||||
"bottom" : '\004',
|
|
||||||
"pageup" : '\013',
|
|
||||||
"pagedown" : '\014'
|
|
||||||
}
|
|
||||||
|
|
||||||
keynames = {}
|
|
||||||
for k, v in keycodes.items():
|
|
||||||
keynames[v] = k
|
|
||||||
del k, v
|
|
|
@ -1,581 +0,0 @@
|
||||||
import Wbase
|
|
||||||
import Wkeys
|
|
||||||
import string
|
|
||||||
from Carbon import Evt, Events, Fm, Lists, Qd, Scrap, Win
|
|
||||||
from Carbon.List import LNew, CreateCustomList
|
|
||||||
from Carbon.Lists import kListDefUserProcType, lInitMsg, lDrawMsg, lHiliteMsg, lCloseMsg
|
|
||||||
from Carbon.QuickDraw import hilitetransfermode
|
|
||||||
from Carbon import App
|
|
||||||
from Carbon.Appearance import kThemeStateActive, kThemeStateInactive, kThemeStatePressed
|
|
||||||
|
|
||||||
|
|
||||||
class List(Wbase.SelectableWidget):
|
|
||||||
|
|
||||||
"""Standard list widget."""
|
|
||||||
|
|
||||||
LDEF_ID = 0
|
|
||||||
|
|
||||||
def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1, typingcasesens=0):
|
|
||||||
if items is None:
|
|
||||||
items = []
|
|
||||||
self.items = items
|
|
||||||
Wbase.SelectableWidget.__init__(self, possize)
|
|
||||||
self._selected = 0
|
|
||||||
self._enabled = 1
|
|
||||||
self._list = None
|
|
||||||
self._cols = cols
|
|
||||||
self._callback = callback
|
|
||||||
self._flags = flags
|
|
||||||
self.typingcasesens = typingcasesens
|
|
||||||
self.lasttyping = ""
|
|
||||||
self.lasttime = Evt.TickCount()
|
|
||||||
self.timelimit = 30
|
|
||||||
self.setitems(items)
|
|
||||||
self.drawingmode = 0
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
self.createlist()
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def createlist(self):
|
|
||||||
self._calcbounds()
|
|
||||||
self.SetPort()
|
|
||||||
rect = self._bounds
|
|
||||||
rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
|
|
||||||
self._viewbounds = rect
|
|
||||||
self._list = LNew(rect, (0, 0, self._cols, 0), (0, 0), self.LDEF_ID, self._parentwindow.wid,
|
|
||||||
0, 1, 0, 1)
|
|
||||||
if self.drawingmode:
|
|
||||||
self._list.LSetDrawingMode(0)
|
|
||||||
self._list.selFlags = self._flags
|
|
||||||
self.setitems(self.items)
|
|
||||||
if hasattr(self, "_sel"):
|
|
||||||
self.setselection(self._sel)
|
|
||||||
del self._sel
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
# Appearance frames are drawn outside the specified bounds,
|
|
||||||
# so we always need to outset the invalidated area.
|
|
||||||
self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
|
|
||||||
self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
|
|
||||||
|
|
||||||
if oldbounds[:2] == self._bounds[:2]:
|
|
||||||
# set visRgn to empty, to prevent nasty drawing side effect of LSize()
|
|
||||||
Qd.RectRgn(self._parentwindow.wid.GetWindowPort().visRgn, (0, 0, 0, 0))
|
|
||||||
# list still has the same upper/left coordinates, use LSize
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
width = r - l - 17
|
|
||||||
height = b - t - 2
|
|
||||||
vl, vt, vr, vb = self._viewbounds
|
|
||||||
self._viewbounds = vl, vt, vl + width, vt + height
|
|
||||||
self._list.LSize(width, height)
|
|
||||||
# now *why* doesn't the list manager recalc the cellrect???
|
|
||||||
l, t, r, b = self._list.LRect((0,0))
|
|
||||||
cellheight = b - t
|
|
||||||
self._list.LCellSize((width/self._cols, cellheight))
|
|
||||||
# reset visRgn
|
|
||||||
self._parentwindow.wid.CalcVis()
|
|
||||||
else:
|
|
||||||
# oh well, since the list manager doesn't have a LMove call,
|
|
||||||
# we have to make the list all over again...
|
|
||||||
sel = self.getselection()
|
|
||||||
topcell = self.gettopcell()
|
|
||||||
self._list = None
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
self.createlist()
|
|
||||||
self.setselection(sel)
|
|
||||||
self.settopcell(topcell)
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self._list = None
|
|
||||||
self._callback = None
|
|
||||||
self.items = []
|
|
||||||
Wbase.SelectableWidget.close(self)
|
|
||||||
|
|
||||||
def set(self, items):
|
|
||||||
self.setitems(items)
|
|
||||||
|
|
||||||
def setitems(self, items):
|
|
||||||
self.items = items
|
|
||||||
the_list = self._list
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
return
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
topcell = self.gettopcell()
|
|
||||||
the_list.LDelRow(0, 1)
|
|
||||||
the_list.LAddRow(len(self.items), 0)
|
|
||||||
self_itemrepr = self.itemrepr
|
|
||||||
set_cell = the_list.LSetCell
|
|
||||||
for i in range(len(items)):
|
|
||||||
set_cell(self_itemrepr(items[i]), (0, i))
|
|
||||||
self.settopcell(topcell)
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
isdoubleclick = self._list.LClick(point, modifiers)
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, isdoubleclick)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def key(self, char, event):
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
sel = self.getselection()
|
|
||||||
newselection = []
|
|
||||||
if char == Wkeys.uparrowkey:
|
|
||||||
if len(sel) >= 1 and min(sel) > 0:
|
|
||||||
newselection = [min(sel) - 1]
|
|
||||||
else:
|
|
||||||
newselection = [0]
|
|
||||||
elif char == Wkeys.downarrowkey:
|
|
||||||
if len(sel) >= 1 and max(sel) < (len(self.items) - 1):
|
|
||||||
newselection = [max(sel) + 1]
|
|
||||||
else:
|
|
||||||
newselection = [len(self.items) - 1]
|
|
||||||
else:
|
|
||||||
modifiers = 0
|
|
||||||
if (self.lasttime + self.timelimit) < Evt.TickCount():
|
|
||||||
self.lasttyping = ""
|
|
||||||
if self.typingcasesens:
|
|
||||||
self.lasttyping = self.lasttyping + char
|
|
||||||
else:
|
|
||||||
self.lasttyping = self.lasttyping + string.lower(char)
|
|
||||||
self.lasttime = Evt.TickCount()
|
|
||||||
i = self.findmatch(self.lasttyping)
|
|
||||||
newselection = [i]
|
|
||||||
if modifiers & Events.shiftKey and not self._list.selFlags & Lists.lOnlyOne:
|
|
||||||
newselection = newselection + sel
|
|
||||||
self.setselection(newselection)
|
|
||||||
self._list.LAutoScroll()
|
|
||||||
self.click((-1, -1), 0)
|
|
||||||
|
|
||||||
def findmatch(self, tag):
|
|
||||||
lower = string.lower
|
|
||||||
items = self.items
|
|
||||||
typingcasesens = self.typingcasesens
|
|
||||||
taglen = len(tag)
|
|
||||||
match = '\377' * 100
|
|
||||||
match_i = -1
|
|
||||||
for i in range(len(items)):
|
|
||||||
item = str(items[i])
|
|
||||||
if not typingcasesens:
|
|
||||||
item = lower(item)
|
|
||||||
if tag <= item < match:
|
|
||||||
match = item
|
|
||||||
match_i = i
|
|
||||||
if match_i >= 0:
|
|
||||||
return match_i
|
|
||||||
else:
|
|
||||||
return len(items) - 1
|
|
||||||
|
|
||||||
def domenu_copy(self, *args):
|
|
||||||
sel = self.getselection()
|
|
||||||
selitems = []
|
|
||||||
for i in sel:
|
|
||||||
selitems.append(str(self.items[i]))
|
|
||||||
text = string.join(selitems, '\r')
|
|
||||||
if text:
|
|
||||||
if hasattr(Scrap, 'PutScrap'):
|
|
||||||
Scrap.ZeroScrap()
|
|
||||||
Scrap.PutScrap('TEXT', text)
|
|
||||||
else:
|
|
||||||
Scrap.ClearCurrentScrap()
|
|
||||||
sc = Scrap.GetCurrentScrap()
|
|
||||||
sc.PutScrapFlavor('TEXT', 0, text)
|
|
||||||
|
|
||||||
def can_copy(self, *args):
|
|
||||||
return len(self.getselection()) <> 0
|
|
||||||
|
|
||||||
def domenu_selectall(self, *args):
|
|
||||||
self.selectall()
|
|
||||||
|
|
||||||
def can_selectall(self, *args):
|
|
||||||
return not self._list.selFlags & Lists.lOnlyOne
|
|
||||||
|
|
||||||
def selectall(self):
|
|
||||||
if not self._list.selFlags & Lists.lOnlyOne:
|
|
||||||
self.setselection(range(len(self.items)))
|
|
||||||
self._list.LAutoScroll()
|
|
||||||
self.click((-1, -1), 0)
|
|
||||||
|
|
||||||
def getselection(self):
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
if hasattr(self, "_sel"):
|
|
||||||
return self._sel
|
|
||||||
return []
|
|
||||||
items = []
|
|
||||||
point = (0,0)
|
|
||||||
while 1:
|
|
||||||
ok, point = self._list.LGetSelect(1, point)
|
|
||||||
if not ok:
|
|
||||||
break
|
|
||||||
items.append(point[1])
|
|
||||||
point = point[0], point[1]+1
|
|
||||||
return items
|
|
||||||
|
|
||||||
def setselection(self, selection):
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
self._sel = selection
|
|
||||||
return
|
|
||||||
set_sel = self._list.LSetSelect
|
|
||||||
for i in range(len(self.items)):
|
|
||||||
if i in selection:
|
|
||||||
set_sel(1, (0, i))
|
|
||||||
else:
|
|
||||||
set_sel(0, (0, i))
|
|
||||||
self._list.LAutoScroll()
|
|
||||||
|
|
||||||
def getselectedobjects(self):
|
|
||||||
sel = self.getselection()
|
|
||||||
objects = []
|
|
||||||
for i in sel:
|
|
||||||
objects.append(self.items[i])
|
|
||||||
return objects
|
|
||||||
|
|
||||||
def setselectedobjects(self, objects):
|
|
||||||
sel = []
|
|
||||||
for o in objects:
|
|
||||||
try:
|
|
||||||
sel.append(self.items.index(o))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.setselection(sel)
|
|
||||||
|
|
||||||
def gettopcell(self):
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
t = t + 1
|
|
||||||
cl, ct, cr, cb = self._list.LRect((0, 0))
|
|
||||||
cellheight = cb - ct
|
|
||||||
return (t - ct) / cellheight
|
|
||||||
|
|
||||||
def settopcell(self, topcell):
|
|
||||||
top = self.gettopcell()
|
|
||||||
diff = topcell - top
|
|
||||||
self._list.LScroll(0, diff)
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
if not visRgn:
|
|
||||||
visRgn = self._parentwindow.wid.GetWindowPort().visRgn
|
|
||||||
self._list.LUpdate(visRgn)
|
|
||||||
state = [kThemeStateActive, kThemeStateInactive][not self._activated]
|
|
||||||
App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
|
|
||||||
if self._selected and self._activated:
|
|
||||||
self.drawselframe(1)
|
|
||||||
|
|
||||||
def select(self, onoff, isclick = 0):
|
|
||||||
if Wbase.SelectableWidget.select(self, onoff):
|
|
||||||
return
|
|
||||||
self.SetPort()
|
|
||||||
self.drawselframe(onoff)
|
|
||||||
|
|
||||||
def activate(self, onoff):
|
|
||||||
self._activated = onoff
|
|
||||||
if self._visible:
|
|
||||||
self._list.LActivate(onoff)
|
|
||||||
#state = [kThemeStateActive, kThemeStateInactive][not onoff]
|
|
||||||
#App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
|
|
||||||
if self._selected:
|
|
||||||
self.drawselframe(onoff)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return self.items
|
|
||||||
|
|
||||||
def itemrepr(self, item):
|
|
||||||
return str(item)[:255]
|
|
||||||
|
|
||||||
def __getitem__(self, index):
|
|
||||||
return self.items[index]
|
|
||||||
|
|
||||||
def __setitem__(self, index, item):
|
|
||||||
if self._parent and self._list:
|
|
||||||
self._list.LSetCell(self.itemrepr(item), (0, index))
|
|
||||||
self.items[index] = item
|
|
||||||
|
|
||||||
def __delitem__(self, index):
|
|
||||||
if self._parent and self._list:
|
|
||||||
self._list.LDelRow(1, index)
|
|
||||||
del self.items[index]
|
|
||||||
|
|
||||||
def __getslice__(self, a, b):
|
|
||||||
return self.items[a:b]
|
|
||||||
|
|
||||||
def __delslice__(self, a, b):
|
|
||||||
if b-a:
|
|
||||||
if self._parent and self._list:
|
|
||||||
self._list.LDelRow(b-a, a)
|
|
||||||
del self.items[a:b]
|
|
||||||
|
|
||||||
def __setslice__(self, a, b, items):
|
|
||||||
if self._parent and self._list:
|
|
||||||
l = len(items)
|
|
||||||
the_list = self._list
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
if b-a:
|
|
||||||
if b > len(self.items):
|
|
||||||
# fix for new 1.5 "feature" where b is sys.maxint instead of len(self)...
|
|
||||||
# LDelRow doesn't like maxint.
|
|
||||||
b = len(self.items)
|
|
||||||
the_list.LDelRow(b-a, a)
|
|
||||||
the_list.LAddRow(l, a)
|
|
||||||
self_itemrepr = self.itemrepr
|
|
||||||
set_cell = the_list.LSetCell
|
|
||||||
for i in range(len(items)):
|
|
||||||
set_cell(self_itemrepr(items[i]), (0, i + a))
|
|
||||||
self.items[a:b] = items
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
else:
|
|
||||||
self.items[a:b] = items
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self.items)
|
|
||||||
|
|
||||||
def append(self, item):
|
|
||||||
if self._parent and self._list:
|
|
||||||
index = len(self.items)
|
|
||||||
self._list.LAddRow(1, index)
|
|
||||||
self._list.LSetCell(self.itemrepr(item), (0, index))
|
|
||||||
self.items.append(item)
|
|
||||||
|
|
||||||
def remove(self, item):
|
|
||||||
index = self.items.index(item)
|
|
||||||
self.__delitem__(index)
|
|
||||||
|
|
||||||
def index(self, item):
|
|
||||||
return self.items.index(item)
|
|
||||||
|
|
||||||
def insert(self, index, item):
|
|
||||||
if index < 0:
|
|
||||||
index = 0
|
|
||||||
if self._parent and self._list:
|
|
||||||
self._list.LAddRow(1, index)
|
|
||||||
self._list.LSetCell(self.itemrepr(item), (0, index))
|
|
||||||
self.items.insert(index, item)
|
|
||||||
|
|
||||||
def setdrawingmode(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
self.drawingmode = self.drawingmode - 1
|
|
||||||
if self.drawingmode == 0 and self._list is not None:
|
|
||||||
self._list.LSetDrawingMode(1)
|
|
||||||
if self._visible:
|
|
||||||
bounds = l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
|
|
||||||
cl, ct, cr, cb = self._list.LRect((0, len(self.items)-1))
|
|
||||||
if cb < b:
|
|
||||||
self.SetPort()
|
|
||||||
Qd.EraseRect((l, cb, cr, b))
|
|
||||||
self._list.LUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
|
|
||||||
self.GetWindow().ValidWindowRect(bounds)
|
|
||||||
else:
|
|
||||||
if self.drawingmode == 0 and self._list is not None:
|
|
||||||
self._list.LSetDrawingMode(0)
|
|
||||||
self.drawingmode = self.drawingmode + 1
|
|
||||||
|
|
||||||
|
|
||||||
class CustomList(List):
|
|
||||||
|
|
||||||
"""Base class for writing custom list definitions."""
|
|
||||||
|
|
||||||
_cellHeight = 0
|
|
||||||
|
|
||||||
def createlist(self):
|
|
||||||
self._calcbounds()
|
|
||||||
self.SetPort()
|
|
||||||
rect = self._bounds
|
|
||||||
rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
|
|
||||||
self._viewbounds = rect
|
|
||||||
self._list = CreateCustomList(
|
|
||||||
rect,
|
|
||||||
(0, 0, 1, 0),
|
|
||||||
(0, self._cellHeight),
|
|
||||||
(kListDefUserProcType, self.listDefinitionFunc),
|
|
||||||
self._parentwindow.wid,
|
|
||||||
0, 1, 0, 1)
|
|
||||||
if self.drawingmode:
|
|
||||||
self._list.LSetDrawingMode(0)
|
|
||||||
self._list.selFlags = self._flags
|
|
||||||
self.setitems(self.items)
|
|
||||||
if hasattr(self, "_sel"):
|
|
||||||
self.setselection(self._sel)
|
|
||||||
del self._sel
|
|
||||||
|
|
||||||
def listDefinitionFunc(self, message, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
"""The LDEF message dispatcher routine, no need to override."""
|
|
||||||
if message == lInitMsg:
|
|
||||||
self.listDefInit(theList)
|
|
||||||
elif message == lDrawMsg:
|
|
||||||
self.listDefDraw(selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList)
|
|
||||||
elif message == lHiliteMsg:
|
|
||||||
self.listDefHighlight(selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList)
|
|
||||||
elif message == lCloseMsg:
|
|
||||||
self.listDefClose(theList)
|
|
||||||
|
|
||||||
def listDefInit(self, theList):
|
|
||||||
pass
|
|
||||||
def listDefClose(self, theList):
|
|
||||||
pass
|
|
||||||
def listDefDraw(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
pass
|
|
||||||
def listDefHighlight(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TwoLineList(CustomList):
|
|
||||||
|
|
||||||
_cellHeight = 28
|
|
||||||
|
|
||||||
def listDefDraw(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
savedPort = Qd.GetPort()
|
|
||||||
Qd.SetPort(theList.GetListPort())
|
|
||||||
savedClip = Qd.NewRgn()
|
|
||||||
Qd.GetClip(savedClip)
|
|
||||||
Qd.ClipRect(cellRect)
|
|
||||||
savedPenState = Qd.GetPenState()
|
|
||||||
Qd.PenNormal()
|
|
||||||
Qd.EraseRect(cellRect)
|
|
||||||
|
|
||||||
#draw the cell if it contains data
|
|
||||||
ascent, descent, leading, size, hm = Fm.FontMetrics()
|
|
||||||
linefeed = ascent + descent + leading
|
|
||||||
|
|
||||||
if dataLen:
|
|
||||||
left, top, right, bottom = cellRect
|
|
||||||
data = theList.LGetCell(dataLen, theCell)
|
|
||||||
lines = data.split("\r")
|
|
||||||
line1 = lines[0]
|
|
||||||
if len(lines) > 1:
|
|
||||||
line2 = lines[1]
|
|
||||||
else:
|
|
||||||
line2 = ""
|
|
||||||
Qd.MoveTo(int(left + 4), int(top + ascent))
|
|
||||||
Qd.DrawText(line1, 0, len(line1))
|
|
||||||
if line2:
|
|
||||||
Qd.MoveTo(int(left + 4), int(top + ascent + linefeed))
|
|
||||||
Qd.DrawText(line2, 0, len(line2))
|
|
||||||
Qd.PenPat("\x11\x11\x11\x11\x11\x11\x11\x11")
|
|
||||||
bottom = top + theList.cellSize[1]
|
|
||||||
Qd.MoveTo(left, bottom - 1)
|
|
||||||
Qd.LineTo(right, bottom - 1)
|
|
||||||
if selected:
|
|
||||||
self.listDefHighlight(selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList)
|
|
||||||
#restore graphics environment
|
|
||||||
Qd.SetPort(savedPort)
|
|
||||||
Qd.SetClip(savedClip)
|
|
||||||
Qd.DisposeRgn(savedClip)
|
|
||||||
Qd.SetPenState(savedPenState)
|
|
||||||
|
|
||||||
def listDefHighlight(self, selected, cellRect, theCell,
|
|
||||||
dataOffset, dataLen, theList):
|
|
||||||
savedPort = Qd.GetPort()
|
|
||||||
Qd.SetPort(theList.GetListPort())
|
|
||||||
savedClip = Qd.NewRgn()
|
|
||||||
Qd.GetClip(savedClip)
|
|
||||||
Qd.ClipRect(cellRect)
|
|
||||||
savedPenState = Qd.GetPenState()
|
|
||||||
Qd.PenNormal()
|
|
||||||
Qd.PenMode(hilitetransfermode)
|
|
||||||
Qd.PaintRect(cellRect)
|
|
||||||
|
|
||||||
#restore graphics environment
|
|
||||||
Qd.SetPort(savedPort)
|
|
||||||
Qd.SetClip(savedClip)
|
|
||||||
Qd.DisposeRgn(savedClip)
|
|
||||||
Qd.SetPenState(savedPenState)
|
|
||||||
|
|
||||||
|
|
||||||
class ResultsWindow:
|
|
||||||
|
|
||||||
"""Simple results window. The user cannot make this window go away completely:
|
|
||||||
closing it will just hide it. It will remain in the windows list. The owner of this window
|
|
||||||
should call the done() method to indicate it's done with it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, possize=None, title="Results", callback=None):
|
|
||||||
import W
|
|
||||||
if possize is None:
|
|
||||||
possize = (500, 200)
|
|
||||||
self.w = W.Window(possize, title, minsize=(200, 100))
|
|
||||||
self.w.results = W.TwoLineList((-1, -1, 1, -14), callback=None)
|
|
||||||
self.w.bind("<close>", self.hide)
|
|
||||||
self.w.open()
|
|
||||||
self._done = 0
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
self._done = 1
|
|
||||||
if not self.w.isvisible():
|
|
||||||
self.w.close()
|
|
||||||
|
|
||||||
def hide(self):
|
|
||||||
if not self._done:
|
|
||||||
self.w.show(0)
|
|
||||||
return -1
|
|
||||||
|
|
||||||
def append(self, msg):
|
|
||||||
if not self.w.isvisible():
|
|
||||||
self.w.show(1)
|
|
||||||
self.w.select()
|
|
||||||
msg = string.replace(msg, '\n', '\r')
|
|
||||||
self.w.results.append(msg)
|
|
||||||
self.w.results.setselection([len(self.w.results)-1])
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
return getattr(self.w.results, attr)
|
|
||||||
|
|
||||||
|
|
||||||
class MultiList(List):
|
|
||||||
|
|
||||||
"""XXX Experimantal!!!"""
|
|
||||||
|
|
||||||
def setitems(self, items):
|
|
||||||
self.items = items
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
return
|
|
||||||
self._list.LDelRow(0, 1)
|
|
||||||
self.setdrawingmode(0)
|
|
||||||
self._list.LAddRow(len(self.items), 0)
|
|
||||||
self_itemrepr = self.itemrepr
|
|
||||||
set_cell = self._list.LSetCell
|
|
||||||
for i in range(len(items)):
|
|
||||||
row = items[i]
|
|
||||||
for j in range(len(row)):
|
|
||||||
item = row[j]
|
|
||||||
set_cell(self_itemrepr(item), (j, i))
|
|
||||||
self.setdrawingmode(1)
|
|
||||||
|
|
||||||
def getselection(self):
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
if hasattr(self, "_sel"):
|
|
||||||
return self._sel
|
|
||||||
return []
|
|
||||||
items = []
|
|
||||||
point = (0,0)
|
|
||||||
while 1:
|
|
||||||
ok, point = self._list.LGetSelect(1, point)
|
|
||||||
if not ok:
|
|
||||||
break
|
|
||||||
items.append(point[1])
|
|
||||||
point = point[0], point[1]+1
|
|
||||||
return items
|
|
||||||
|
|
||||||
def setselection(self, selection):
|
|
||||||
if not self._parent or not self._list:
|
|
||||||
self._sel = selection
|
|
||||||
return
|
|
||||||
set_sel = self._list.LSetSelect
|
|
||||||
for i in range(len(self.items)):
|
|
||||||
for j in range(len(self.items[i])):
|
|
||||||
if i in selection:
|
|
||||||
set_sel(1, (j, i))
|
|
||||||
else:
|
|
||||||
set_sel(0, (j, i))
|
|
||||||
#self._list.LAutoScroll()
|
|
|
@ -1,259 +0,0 @@
|
||||||
import FrameWork
|
|
||||||
import Wbase, Wcontrols
|
|
||||||
from Carbon import Ctl, Controls, Qd, Res
|
|
||||||
from types import *
|
|
||||||
import Wapplication
|
|
||||||
|
|
||||||
#_arrowright = Qd.GetPicture(472)
|
|
||||||
#_arrowdown = Qd.GetPicture(473)
|
|
||||||
|
|
||||||
_arrowright = Res.Resource(
|
|
||||||
'\x00I\x00\x00\x00\x00\x00\n\x00\n\x11\x01\x01\x00\n\x00\x00\x00'
|
|
||||||
'\x00\x00\n\x00\n\x90\x00\x02\x00\x00\x00\x00\x00\n\x00\n\x00\x00'
|
|
||||||
'\x00\x00\x00\n\x00\n\x00\x00\x00\x00\x00\n\x00\n\x00\x00\x10\x00'
|
|
||||||
'\x18\x00\x1c\x00\x1e\x00\x1f\x00\x1f\x00\x1e\x00\x1c\x00\x18\x00'
|
|
||||||
'\x10\x00\xff')
|
|
||||||
|
|
||||||
|
|
||||||
class PopupControl(Wcontrols.ControlWidget):
|
|
||||||
|
|
||||||
def __init__(self, possize, items=None, callback=None):
|
|
||||||
if items is None:
|
|
||||||
items = []
|
|
||||||
procID = Controls.popupMenuProc|Controls.popupFixedWidth|Controls.useWFont
|
|
||||||
Wcontrols.ControlWidget.__init__(self, possize, "", procID, callback, 0, 0, 0)
|
|
||||||
self._items = items[:]
|
|
||||||
|
|
||||||
def set(self, value):
|
|
||||||
self._control.SetControlValue(value+1)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return self._control.GetControlValue() - 1
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self.menu = menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
|
|
||||||
|
|
||||||
for i in range(len(self._items)):
|
|
||||||
item = self._items[i]
|
|
||||||
if type(item) == StringType:
|
|
||||||
menuitemtext = object = item
|
|
||||||
elif type(item) == TupleType and len(item) == 2:
|
|
||||||
menuitemtext, object = item
|
|
||||||
self._items[i] = object
|
|
||||||
else:
|
|
||||||
raise Wbase.WidgetsError, "illegal itemlist for popup menu"
|
|
||||||
menuitem = FrameWork.MenuItem(menu, menuitemtext, None, None)
|
|
||||||
|
|
||||||
self._calcbounds()
|
|
||||||
self._control = Ctl.NewControl(self._parentwindow.wid,
|
|
||||||
self._bounds,
|
|
||||||
self._title,
|
|
||||||
1,
|
|
||||||
self._value,
|
|
||||||
self.menu.id,
|
|
||||||
self._max,
|
|
||||||
self._procID,
|
|
||||||
0)
|
|
||||||
self.SetPort()
|
|
||||||
self.enable(self._enabled)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.menu.delete()
|
|
||||||
return Wcontrols.ControlWidget.close(self)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
part = self._control.TrackControl(point, -1)
|
|
||||||
if part:
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, self._items[self.get()])
|
|
||||||
|
|
||||||
|
|
||||||
class PopupWidget(Wbase.ClickableWidget):
|
|
||||||
|
|
||||||
"""Simple title-less popup widget. Should be 16x16 pixels.
|
|
||||||
Builds the menu items on the fly, good for dynamic popup menus."""
|
|
||||||
|
|
||||||
def __init__(self, possize, items=None, callback=None):
|
|
||||||
Wbase.ClickableWidget.__init__(self, possize)
|
|
||||||
if items is None:
|
|
||||||
items = []
|
|
||||||
self._items = items
|
|
||||||
self._itemsdict = {}
|
|
||||||
self._callback = callback
|
|
||||||
self._enabled = 1
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
Wbase.ClickableWidget.close(self)
|
|
||||||
self._items = None
|
|
||||||
self._itemsdict = {}
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
Qd.FrameRect(self._bounds)
|
|
||||||
Qd.EraseRect(Qd.InsetRect(self._bounds, 1, 1))
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
l = l + 2
|
|
||||||
t = t + 3
|
|
||||||
pictframe = (l, t, l + 10, t + 10)
|
|
||||||
Qd.DrawPicture(_arrowright, pictframe)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
self.menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
|
|
||||||
self._additems(self._items, self.menu)
|
|
||||||
self.SetPort()
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
l, t = Qd.LocalToGlobal((l+1, t+1))
|
|
||||||
Wbase.SetCursor("arrow")
|
|
||||||
self.menu.menu.EnableMenuItem(0)
|
|
||||||
reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
|
|
||||||
if reply:
|
|
||||||
id = reply >> 16
|
|
||||||
item = reply & 0xffff
|
|
||||||
self._menu_callback(id, item)
|
|
||||||
self._emptymenu()
|
|
||||||
|
|
||||||
def set(self, items):
|
|
||||||
self._items = items
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return self._items
|
|
||||||
|
|
||||||
def _additems(self, items, menu):
|
|
||||||
from FrameWork import SubMenu, MenuItem
|
|
||||||
menu_id = menu.id
|
|
||||||
for item in items:
|
|
||||||
if item == "-":
|
|
||||||
menu.addseparator()
|
|
||||||
continue
|
|
||||||
elif type(item) == ListType:
|
|
||||||
submenu = SubMenu(menu, item[0])
|
|
||||||
self._additems(item[1:], submenu)
|
|
||||||
continue
|
|
||||||
elif type(item) == StringType:
|
|
||||||
menuitemtext = object = item
|
|
||||||
elif type(item) == TupleType and len(item) == 2:
|
|
||||||
menuitemtext, object = item
|
|
||||||
else:
|
|
||||||
raise Wbase.WidgetsError, "illegal itemlist for popup menu"
|
|
||||||
|
|
||||||
if menuitemtext[:1] == '\0':
|
|
||||||
check = ord(menuitemtext[1])
|
|
||||||
menuitemtext = menuitemtext[2:]
|
|
||||||
else:
|
|
||||||
check = 0
|
|
||||||
menuitem = MenuItem(menu, menuitemtext, None, None)
|
|
||||||
if check:
|
|
||||||
menuitem.check(1)
|
|
||||||
self._itemsdict[(menu_id, menuitem.item)] = object
|
|
||||||
|
|
||||||
def _emptymenu(self):
|
|
||||||
menus = self._parentwindow.parent.menubar.menus
|
|
||||||
for id, item in self._itemsdict.keys():
|
|
||||||
if menus.has_key(id):
|
|
||||||
self.menu = menus[id]
|
|
||||||
self.menu.delete()
|
|
||||||
self._itemsdict = {}
|
|
||||||
|
|
||||||
def _menu_callback(self, id, item):
|
|
||||||
thing = self._itemsdict[(id, item)]
|
|
||||||
if callable(thing):
|
|
||||||
thing()
|
|
||||||
elif self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, thing)
|
|
||||||
|
|
||||||
|
|
||||||
class PopupMenu(PopupWidget):
|
|
||||||
|
|
||||||
"""Simple title-less popup widget. Should be 16x16 pixels.
|
|
||||||
Prebuilds the menu items, good for static (non changing) popup menus."""
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self._calcbounds()
|
|
||||||
self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
|
|
||||||
self._additems(self._items, self.menu)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self._emptymenu()
|
|
||||||
Wbase.Widget.close(self)
|
|
||||||
self._items = None
|
|
||||||
self._itemsdict = {}
|
|
||||||
self.menu = None
|
|
||||||
|
|
||||||
def set(self, items):
|
|
||||||
if self._itemsdict:
|
|
||||||
self._emptymenu()
|
|
||||||
self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
|
|
||||||
self._items = items
|
|
||||||
self._additems(self._items, self.menu)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
self.SetPort()
|
|
||||||
l, t, r, b = self._bounds
|
|
||||||
l, t = Qd.LocalToGlobal((l+1, t+1))
|
|
||||||
Wbase.SetCursor("arrow")
|
|
||||||
self.menu.menu.EnableMenuItem(0)
|
|
||||||
reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
|
|
||||||
if reply:
|
|
||||||
id = reply >> 16
|
|
||||||
item = reply & 0xffff
|
|
||||||
self._menu_callback(id, item)
|
|
||||||
|
|
||||||
|
|
||||||
class FontMenu(PopupMenu):
|
|
||||||
|
|
||||||
"""A font popup menu."""
|
|
||||||
|
|
||||||
menu = None
|
|
||||||
|
|
||||||
def __init__(self, possize, callback):
|
|
||||||
PopupMenu.__init__(self, possize)
|
|
||||||
_makefontmenu()
|
|
||||||
self._callback = callback
|
|
||||||
self._enabled = 1
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
del self._callback
|
|
||||||
|
|
||||||
def set(self):
|
|
||||||
raise Wbase.WidgetsError, "can't change font menu widget"
|
|
||||||
|
|
||||||
def _menu_callback(self, id, item):
|
|
||||||
fontname = self.menu.menu.GetMenuItemText(item)
|
|
||||||
if self._callback:
|
|
||||||
Wbase.CallbackCall(self._callback, 0, fontname)
|
|
||||||
|
|
||||||
def click(self, point, modifiers):
|
|
||||||
if not self._enabled:
|
|
||||||
return
|
|
||||||
_makefontmenu()
|
|
||||||
return PopupMenu.click(self, point, modifiers)
|
|
||||||
|
|
||||||
|
|
||||||
def _makefontmenu():
|
|
||||||
"""helper for font menu"""
|
|
||||||
if FontMenu.menu is not None:
|
|
||||||
return
|
|
||||||
import W
|
|
||||||
FontMenu.menu = Wapplication.Menu(W.getapplication().menubar, 'Foo', -1)
|
|
||||||
W.SetCursor('watch')
|
|
||||||
for i in range(FontMenu.menu.menu.CountMenuItems(), 0, -1):
|
|
||||||
FontMenu.menu.menu.DeleteMenuItem(i)
|
|
||||||
FontMenu.menu.menu.AppendResMenu('FOND')
|
|
||||||
|
|
||||||
|
|
||||||
def _getfontlist():
|
|
||||||
from Carbon import Res
|
|
||||||
fontnames = []
|
|
||||||
for i in range(1, Res.CountResources('FOND') + 1):
|
|
||||||
r = Res.GetIndResource('FOND', i)
|
|
||||||
fontnames.append(r.GetResInfo()[2])
|
|
||||||
return fontnames
|
|
|
@ -1,22 +0,0 @@
|
||||||
"""Minimal W application."""
|
|
||||||
|
|
||||||
import Wapplication
|
|
||||||
import macresource
|
|
||||||
import os
|
|
||||||
|
|
||||||
class TestApp(Wapplication.Application):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
from Carbon import Res
|
|
||||||
# macresource.open_pathname("Widgets.rsrc")
|
|
||||||
self._menustocheck = []
|
|
||||||
self.preffilepath = os.path.join("Python", "PythonIDE preferences")
|
|
||||||
Wapplication.Application.__init__(self, 'Pyth')
|
|
||||||
# open a new text editor
|
|
||||||
import PyEdit
|
|
||||||
PyEdit.Editor()
|
|
||||||
# start the mainloop
|
|
||||||
self.mainloop()
|
|
||||||
|
|
||||||
|
|
||||||
TestApp()
|
|
|
@ -1,113 +0,0 @@
|
||||||
import os
|
|
||||||
from Carbon import Qd
|
|
||||||
from Carbon import Win
|
|
||||||
from Carbon import Qt, QuickTime
|
|
||||||
import W
|
|
||||||
from Carbon import File
|
|
||||||
from Carbon import Evt, Events
|
|
||||||
|
|
||||||
_moviesinitialized = 0
|
|
||||||
|
|
||||||
def EnterMovies():
|
|
||||||
global _moviesinitialized
|
|
||||||
if not _moviesinitialized:
|
|
||||||
Qt.EnterMovies()
|
|
||||||
_moviesinitialized = 1
|
|
||||||
|
|
||||||
class Movie(W.Widget):
|
|
||||||
|
|
||||||
def __init__(self, possize):
|
|
||||||
EnterMovies()
|
|
||||||
self.movie = None
|
|
||||||
self.running = 0
|
|
||||||
W.Widget.__init__(self, possize)
|
|
||||||
|
|
||||||
def adjust(self, oldbounds):
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(oldbounds)
|
|
||||||
self.GetWindow().InvalWindowRect(self._bounds)
|
|
||||||
self.calcmoviebox()
|
|
||||||
|
|
||||||
def set(self, path_or_fss, start = 0):
|
|
||||||
self.SetPort()
|
|
||||||
if self.movie:
|
|
||||||
#self.GetWindow().InvalWindowRect(self.movie.GetMovieBox())
|
|
||||||
Qd.PaintRect(self.movie.GetMovieBox())
|
|
||||||
path = File.pathname(path)
|
|
||||||
self.movietitle = os.path.basename(path)
|
|
||||||
movieResRef = Qt.OpenMovieFile(path_or_fss, 1)
|
|
||||||
self.movie, dummy, dummy = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
|
|
||||||
self.moviebox = self.movie.GetMovieBox()
|
|
||||||
self.calcmoviebox()
|
|
||||||
Qd.ObscureCursor() # XXX does this work at all?
|
|
||||||
self.movie.GoToBeginningOfMovie()
|
|
||||||
if start:
|
|
||||||
self.movie.StartMovie()
|
|
||||||
self.running = 1
|
|
||||||
else:
|
|
||||||
self.running = 0
|
|
||||||
self.movie.MoviesTask(0)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return self.movie
|
|
||||||
|
|
||||||
def getmovietitle(self):
|
|
||||||
return self.movietitle
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
if self.movie:
|
|
||||||
Qd.ObscureCursor()
|
|
||||||
self.movie.StartMovie()
|
|
||||||
self.running = 1
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if self.movie:
|
|
||||||
self.movie.StopMovie()
|
|
||||||
self.running = 0
|
|
||||||
|
|
||||||
def rewind(self):
|
|
||||||
if self.movie:
|
|
||||||
self.movie.GoToBeginningOfMovie()
|
|
||||||
|
|
||||||
def calcmoviebox(self):
|
|
||||||
if not self.movie:
|
|
||||||
return
|
|
||||||
ml, mt, mr, mb = self.moviebox
|
|
||||||
wl, wt, wr, wb = widgetbox = self._bounds
|
|
||||||
mheight = mb - mt
|
|
||||||
mwidth = mr - ml
|
|
||||||
wheight = wb - wt
|
|
||||||
wwidth = wr - wl
|
|
||||||
if (mheight * 2 < wheight) and (mwidth * 2 < wwidth):
|
|
||||||
scale = 2
|
|
||||||
elif mheight > wheight or mwidth > wwidth:
|
|
||||||
scale = min(float(wheight) / mheight, float(wwidth) / mwidth)
|
|
||||||
else:
|
|
||||||
scale = 1
|
|
||||||
mwidth, mheight = mwidth * scale, mheight * scale
|
|
||||||
ml, mt = wl + (wwidth - mwidth) / 2, wt + (wheight - mheight) / 2
|
|
||||||
mr, mb = ml + mwidth, mt + mheight
|
|
||||||
self.movie.SetMovieBox((ml, mt, mr, mb))
|
|
||||||
|
|
||||||
def idle(self, *args):
|
|
||||||
if self.movie:
|
|
||||||
if not self.movie.IsMovieDone() and self.running:
|
|
||||||
Qd.ObscureCursor()
|
|
||||||
while 1:
|
|
||||||
self.movie.MoviesTask(0)
|
|
||||||
gotone, event = Evt.EventAvail(Events.everyEvent)
|
|
||||||
if gotone or self.movie.IsMovieDone():
|
|
||||||
break
|
|
||||||
elif self.running:
|
|
||||||
box = self.movie.GetMovieBox()
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(box)
|
|
||||||
self.movie = None
|
|
||||||
self.running = 0
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._visible:
|
|
||||||
Qd.PaintRect(self._bounds)
|
|
||||||
if self.movie:
|
|
||||||
self.movie.UpdateMovie()
|
|
||||||
self.movie.MoviesTask(0)
|
|
|
@ -1,395 +0,0 @@
|
||||||
"""Async sockets, build on top of Sam Rushing's excellent async library"""
|
|
||||||
|
|
||||||
import asyncore
|
|
||||||
import socket
|
|
||||||
from socket import AF_INET, SOCK_STREAM
|
|
||||||
import string
|
|
||||||
import cStringIO
|
|
||||||
import mimetools
|
|
||||||
import httplib
|
|
||||||
|
|
||||||
|
|
||||||
__version__ = "0.9"
|
|
||||||
__author__ = "jvr"
|
|
||||||
|
|
||||||
BUFSIZE = 512
|
|
||||||
|
|
||||||
VERBOSE = 1
|
|
||||||
|
|
||||||
class Server(asyncore.dispatcher):
|
|
||||||
|
|
||||||
"""Generic asynchronous server class"""
|
|
||||||
|
|
||||||
def __init__(self, port, handler_class, backlog=1, host=""):
|
|
||||||
"""arguments:
|
|
||||||
- port: the port to listen to
|
|
||||||
- handler_class: class to handle requests
|
|
||||||
- backlog: backlog queue size (optional) (don't fully understand, see socket docs)
|
|
||||||
- host: host name (optional: can be empty to use default host name)
|
|
||||||
"""
|
|
||||||
if VERBOSE:
|
|
||||||
print "Starting", self.__class__.__name__
|
|
||||||
self.handler_class = handler_class
|
|
||||||
asyncore.dispatcher.__init__(self)
|
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.bind((host, port))
|
|
||||||
self.listen(backlog)
|
|
||||||
|
|
||||||
def handle_accept(self):
|
|
||||||
conn, addr = self.accept()
|
|
||||||
if VERBOSE:
|
|
||||||
print 'Incoming Connection from %s:%d' % addr
|
|
||||||
self.handler_class(conn)
|
|
||||||
|
|
||||||
|
|
||||||
class ProxyServer(Server):
|
|
||||||
|
|
||||||
"""Generic proxy server class"""
|
|
||||||
|
|
||||||
def __init__(self, port, handler_class, proxyaddr=None, closepartners=0):
|
|
||||||
"""arguments:
|
|
||||||
- port: the port to listen to
|
|
||||||
- handler_class: proxy class to handle requests
|
|
||||||
- proxyaddr: a tuple containing the address and
|
|
||||||
port of a remote host to connect to (optional)
|
|
||||||
- closepartners: boolean, specifies whether we should close
|
|
||||||
all proxy connections or not (optional). http seems to *not*
|
|
||||||
want this, but telnet does...
|
|
||||||
"""
|
|
||||||
Server.__init__(self, port, handler_class, 1, "")
|
|
||||||
self.proxyaddr = proxyaddr
|
|
||||||
self.closepartners = closepartners
|
|
||||||
|
|
||||||
def handle_accept(self):
|
|
||||||
conn, addr = self.accept()
|
|
||||||
if VERBOSE:
|
|
||||||
print 'Incoming Connection from %s:%d' % addr
|
|
||||||
self.handler_class(conn, self.proxyaddr, closepartner=self.closepartners)
|
|
||||||
|
|
||||||
|
|
||||||
class Connection(asyncore.dispatcher):
|
|
||||||
|
|
||||||
"""Generic connection class"""
|
|
||||||
|
|
||||||
def __init__(self, sock_or_address=None, readfunc=None, terminator=None):
|
|
||||||
"""arguments:
|
|
||||||
- sock_or_address: either a socket, or a tuple containing the name
|
|
||||||
and port number of a remote host
|
|
||||||
- readfunc: callback function (optional). Will be called whenever
|
|
||||||
there is some data available, or when an appropraite terminator
|
|
||||||
is found.
|
|
||||||
- terminator: string which specifies when a read is complete (optional)"""
|
|
||||||
self._out_buffer = ""
|
|
||||||
self._in_buffer = ""
|
|
||||||
self.readfunc = readfunc
|
|
||||||
self.terminator = terminator
|
|
||||||
asyncore.dispatcher.__init__(self)
|
|
||||||
if hasattr(sock_or_address, "fileno"):
|
|
||||||
self.set_socket(sock_or_address)
|
|
||||||
else:
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
sock.setblocking(0)
|
|
||||||
self.set_socket(sock)
|
|
||||||
if sock_or_address:
|
|
||||||
self.connect(sock_or_address)
|
|
||||||
|
|
||||||
# public methods
|
|
||||||
def send(self, data):
|
|
||||||
self._out_buffer = self._out_buffer + data
|
|
||||||
|
|
||||||
def recv(self, bytes=-1):
|
|
||||||
if bytes == -1:
|
|
||||||
bytes = len(self._in_buffer)
|
|
||||||
data = self._in_buffer[:bytes]
|
|
||||||
self._in_buffer = self._in_buffer[bytes:]
|
|
||||||
return data
|
|
||||||
|
|
||||||
def set_terminator(self, terminator):
|
|
||||||
self.terminator = terminator
|
|
||||||
|
|
||||||
# override this if you want to control the incoming data stream
|
|
||||||
def handle_incoming_data(self, data):
|
|
||||||
if self.readfunc:
|
|
||||||
if self.terminator:
|
|
||||||
self._in_buffer = self._in_buffer + data
|
|
||||||
pos = string.find(self._in_buffer, self.terminator)
|
|
||||||
if pos < 0:
|
|
||||||
return
|
|
||||||
data = self._in_buffer[:pos]
|
|
||||||
self._in_buffer = self._in_buffer[pos + len(self.terminator):]
|
|
||||||
self.readfunc(data)
|
|
||||||
else:
|
|
||||||
self.readfunc(self._in_buffer + data)
|
|
||||||
self._in_buffer = ""
|
|
||||||
else:
|
|
||||||
self._in_buffer = self._in_buffer + data
|
|
||||||
|
|
||||||
# internal muck
|
|
||||||
def handle_read(self):
|
|
||||||
data = asyncore.dispatcher.recv(self, BUFSIZE)
|
|
||||||
if data:
|
|
||||||
if VERBOSE > 2:
|
|
||||||
print "incoming -> %x %r" % (id(self), data)
|
|
||||||
self.handle_incoming_data(data)
|
|
||||||
|
|
||||||
def handle_write(self):
|
|
||||||
if self._out_buffer:
|
|
||||||
sent = self.socket.send(self._out_buffer[:BUFSIZE])
|
|
||||||
if VERBOSE > 2:
|
|
||||||
print "outgoing -> %x %r" % (id(self), self._out_buffer[:sent])
|
|
||||||
self._out_buffer = self._out_buffer[sent:]
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self.readfunc and self._in_buffer:
|
|
||||||
self.readfunc(self._in_buffer)
|
|
||||||
self._in_buffer = ""
|
|
||||||
#elif VERBOSE > 1 and self._in_buffer:
|
|
||||||
# print "--- there is unread data: %r", (self._in_buffer,)
|
|
||||||
asyncore.dispatcher.close(self)
|
|
||||||
|
|
||||||
def handle_close(self):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def handle_connect(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionUI:
|
|
||||||
|
|
||||||
"""Glue to let a connection tell things to the UI in a standardized way.
|
|
||||||
|
|
||||||
The protocoll defines four functions, which the connection will call:
|
|
||||||
|
|
||||||
def settotal(int total): gets called when the connection knows the data size
|
|
||||||
def setcurrent(int current): gets called when some new data has arrived
|
|
||||||
def done(): gets called when the transaction is complete
|
|
||||||
def error(type, value, tb): gets called wheneven an error occurred
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, settotal_func, setcurrent_func, done_func, error_func):
|
|
||||||
self.settotal = settotal_func
|
|
||||||
self.setcurrent = setcurrent_func
|
|
||||||
self.done = done_func
|
|
||||||
self.error = error_func
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPError(socket.error): pass
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPClient(Connection, httplib.HTTP):
|
|
||||||
|
|
||||||
"""Asynchronous HTTP connection"""
|
|
||||||
|
|
||||||
def __init__(self, (host, port), datahandler, ui=None):
|
|
||||||
Connection.__init__(self, (host, port))
|
|
||||||
self.datahandler = datahandler
|
|
||||||
self.ui = ui
|
|
||||||
self.buf = ""
|
|
||||||
self.doneheaders = 0
|
|
||||||
self.done = 0
|
|
||||||
self.headers = None
|
|
||||||
self.length = None
|
|
||||||
self.pos = 0
|
|
||||||
|
|
||||||
def getreply(self):
|
|
||||||
raise TypeError, "getreply() is not supported in async HTTP connection"
|
|
||||||
|
|
||||||
def handle_incoming_data(self, data):
|
|
||||||
assert not self.done
|
|
||||||
if not self.doneheaders:
|
|
||||||
self.buf = self.buf + data
|
|
||||||
pos = string.find(self.buf, "\r\n\r\n")
|
|
||||||
if pos >= 0:
|
|
||||||
self.handle_reply(self.buf[:pos+4])
|
|
||||||
length = self.headers.getheader("Content-Length")
|
|
||||||
if length is not None:
|
|
||||||
self.length = int(length)
|
|
||||||
if self.ui is not None:
|
|
||||||
self.ui.settotal(self.length)
|
|
||||||
else:
|
|
||||||
self.length = -1
|
|
||||||
self.doneheaders = 1
|
|
||||||
self.handle_data(self.buf[pos+4:])
|
|
||||||
self.buf = ""
|
|
||||||
else:
|
|
||||||
self.handle_data(data)
|
|
||||||
|
|
||||||
def handle_reply(self, data):
|
|
||||||
f = cStringIO.StringIO(data)
|
|
||||||
ver, code, msg = string.split(f.readline(), None, 2)
|
|
||||||
code = int(code)
|
|
||||||
msg = string.strip(msg)
|
|
||||||
if code <> 200:
|
|
||||||
# Hm, this is what *I* need, but probably not correct...
|
|
||||||
raise HTTPError, (code, msg)
|
|
||||||
self.headers = mimetools.Message(f)
|
|
||||||
|
|
||||||
def handle_data(self, data):
|
|
||||||
self.pos = self.pos + len(data)
|
|
||||||
if self.ui is not None:
|
|
||||||
self.ui.setcurrent(self.pos)
|
|
||||||
self.datahandler(data)
|
|
||||||
if self.pos >= self.length:
|
|
||||||
self.datahandler("")
|
|
||||||
self.done = 1
|
|
||||||
if self.ui is not None:
|
|
||||||
self.ui.done()
|
|
||||||
|
|
||||||
def handle_error(self, type, value, tb):
|
|
||||||
if self.ui is not None:
|
|
||||||
self.ui.error(type, value, tb)
|
|
||||||
else:
|
|
||||||
Connection.handle_error(self, type, value, tb)
|
|
||||||
|
|
||||||
def log(self, message):
|
|
||||||
if VERBOSE:
|
|
||||||
print 'LOG:', message
|
|
||||||
|
|
||||||
|
|
||||||
class PyMessage:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._buf = ""
|
|
||||||
self._len = None
|
|
||||||
self._checksum = None
|
|
||||||
|
|
||||||
def feed(self, data):
|
|
||||||
self._buf = self._buf + data
|
|
||||||
if self._len is None:
|
|
||||||
if len(self._buf) >= 8:
|
|
||||||
import struct
|
|
||||||
self._len, self._checksum = struct.unpack("ll", self._buf[:8])
|
|
||||||
self._buf = self._buf[8:]
|
|
||||||
if self._len is not None:
|
|
||||||
if len(self._buf) >= self._len:
|
|
||||||
import zlib
|
|
||||||
data = self._buf[:self._len]
|
|
||||||
leftover = self._buf[self._len:]
|
|
||||||
self._buf = None
|
|
||||||
assert self._checksum == zlib.adler32(data), "corrupt data"
|
|
||||||
self.data = data
|
|
||||||
return 1, leftover
|
|
||||||
else:
|
|
||||||
return 0, None
|
|
||||||
else:
|
|
||||||
return 0, None
|
|
||||||
|
|
||||||
|
|
||||||
class PyConnection(Connection):
|
|
||||||
|
|
||||||
def __init__(self, sock_or_address):
|
|
||||||
Connection.__init__(self, sock_or_address)
|
|
||||||
self.currentmessage = PyMessage()
|
|
||||||
|
|
||||||
def handle_incoming_data(self, data):
|
|
||||||
while data:
|
|
||||||
done, data = self.currentmessage.feed(data)
|
|
||||||
if done:
|
|
||||||
import cPickle
|
|
||||||
self.handle_object(cPickle.loads(self.currentmessage.data))
|
|
||||||
self.currentmessage = PyMessage()
|
|
||||||
|
|
||||||
def handle_object(self, object):
|
|
||||||
print 'unhandled object:', repr(object)
|
|
||||||
|
|
||||||
def send(self, object):
|
|
||||||
import cPickle, zlib, struct
|
|
||||||
data = cPickle.dumps(object, 1)
|
|
||||||
length = len(data)
|
|
||||||
checksum = zlib.adler32(data)
|
|
||||||
data = struct.pack("ll", length, checksum) + data
|
|
||||||
Connection.send(self, data)
|
|
||||||
|
|
||||||
|
|
||||||
class Echo(Connection):
|
|
||||||
|
|
||||||
"""Simple echoing connection: it sends everything back it receives."""
|
|
||||||
|
|
||||||
def handle_incoming_data(self, data):
|
|
||||||
self.send(data)
|
|
||||||
|
|
||||||
|
|
||||||
class Proxy(Connection):
|
|
||||||
|
|
||||||
"""Generic proxy connection"""
|
|
||||||
|
|
||||||
def __init__(self, sock_or_address=None, proxyaddr=None, closepartner=0):
|
|
||||||
"""arguments:
|
|
||||||
- sock_or_address is either a socket or a tuple containing the
|
|
||||||
name and port number of a remote host
|
|
||||||
- proxyaddr: a tuple containing a name and a port number of a
|
|
||||||
remote host (optional).
|
|
||||||
- closepartner: boolean, specifies whether we should close
|
|
||||||
the proxy connection (optional)"""
|
|
||||||
|
|
||||||
Connection.__init__(self, sock_or_address)
|
|
||||||
self.other = None
|
|
||||||
self.proxyaddr = proxyaddr
|
|
||||||
self.closepartner = closepartner
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self.other:
|
|
||||||
other = self.other
|
|
||||||
self.other = None
|
|
||||||
other.other = None
|
|
||||||
if self.closepartner:
|
|
||||||
other.close()
|
|
||||||
Connection.close(self)
|
|
||||||
|
|
||||||
def handle_incoming_data(self, data):
|
|
||||||
if not self.other:
|
|
||||||
# pass data for possible automatic remote host detection
|
|
||||||
# (see HTTPProxy)
|
|
||||||
data = self.connectproxy(data)
|
|
||||||
self.other.send(data)
|
|
||||||
|
|
||||||
def connectproxy(self, data):
|
|
||||||
other = self.__class__(self.proxyaddr, closepartner=self.closepartner)
|
|
||||||
self.other = other
|
|
||||||
other.other = self
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPProxy(Proxy):
|
|
||||||
|
|
||||||
"""Simple, useless, http proxy. It figures out itself where to connect to."""
|
|
||||||
|
|
||||||
def connectproxy(self, data):
|
|
||||||
if VERBOSE:
|
|
||||||
print "--- proxy request", repr(data)
|
|
||||||
addr, data = de_proxify(data)
|
|
||||||
other = Proxy(addr)
|
|
||||||
self.other = other
|
|
||||||
other.other = self
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
# helper for HTTPProxy
|
|
||||||
def de_proxify(data):
|
|
||||||
import re
|
|
||||||
req_pattern = "GET http://([a-zA-Z0-9-_.]+)(:([0-9]+))?"
|
|
||||||
m = re.match(req_pattern, data)
|
|
||||||
host, dummy, port = m.groups()
|
|
||||||
if not port:
|
|
||||||
port = 80
|
|
||||||
else:
|
|
||||||
port = int(port)
|
|
||||||
# change "GET http://xx.xx.xx/yy" into "GET /yy"
|
|
||||||
data = re.sub(req_pattern, "GET ", data)
|
|
||||||
return (host, port), data
|
|
||||||
|
|
||||||
|
|
||||||
# if we're running "under W", let's register the socket poller to the event loop
|
|
||||||
try:
|
|
||||||
import W
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
W.getapplication().addidlefunc(asyncore.poll)
|
|
||||||
|
|
||||||
|
|
||||||
## testing muck
|
|
||||||
#testserver = Server(10000, Connection)
|
|
||||||
#echoserver = Server(10007, Echo)
|
|
||||||
#httpproxyserver = Server(8088, HTTPProxy, 5)
|
|
||||||
#asyncore.close_all()
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,187 +0,0 @@
|
||||||
import traceback
|
|
||||||
import sys
|
|
||||||
import W
|
|
||||||
import os
|
|
||||||
import types
|
|
||||||
from Carbon import List
|
|
||||||
|
|
||||||
|
|
||||||
class TraceBack:
|
|
||||||
|
|
||||||
def __init__(self, title = "Traceback"):
|
|
||||||
app = W.getapplication() # checks if W is properly initialized
|
|
||||||
self.title = title
|
|
||||||
self.w = None
|
|
||||||
self.closed = 1
|
|
||||||
self.start = 0
|
|
||||||
self.lastwindowtitle = ""
|
|
||||||
self.bounds = (360, 298)
|
|
||||||
|
|
||||||
def traceback(self, start = 0, lastwindowtitle = ""):
|
|
||||||
try:
|
|
||||||
self.lastwindowtitle = lastwindowtitle
|
|
||||||
self.start = start
|
|
||||||
self.type, self.value, self.tb = sys.exc_info()
|
|
||||||
if self.type is not SyntaxError:
|
|
||||||
self.show()
|
|
||||||
if type(self.type) == types.ClassType:
|
|
||||||
errortext = self.type.__name__
|
|
||||||
else:
|
|
||||||
errortext = str(self.type)
|
|
||||||
value = str(self.value)
|
|
||||||
if self.value and value:
|
|
||||||
errortext = errortext + ": " + value
|
|
||||||
self.w.text.set(errortext)
|
|
||||||
self.buildtblist()
|
|
||||||
self.w.list.set(self.textlist)
|
|
||||||
self.w.list.setselection([len(self.textlist) - 1])
|
|
||||||
self.w.wid.SelectWindow()
|
|
||||||
self.closed = 0
|
|
||||||
else:
|
|
||||||
self.syntaxerror()
|
|
||||||
except:
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
def syntaxerror(self):
|
|
||||||
try:
|
|
||||||
value, (filename, lineno, charno, line) = self.value
|
|
||||||
except:
|
|
||||||
filename = ""
|
|
||||||
lineno = None
|
|
||||||
value = self.value
|
|
||||||
if not filename and self.lastwindowtitle:
|
|
||||||
filename = self.lastwindowtitle
|
|
||||||
elif not filename:
|
|
||||||
filename = "<unknown>"
|
|
||||||
if filename and os.path.exists(filename):
|
|
||||||
filename = os.path.split(filename)[1]
|
|
||||||
if lineno and charno is not None:
|
|
||||||
charno = charno - 1
|
|
||||||
text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1]
|
|
||||||
else:
|
|
||||||
text = str(value) + '\rFile: "' + str(filename) + '"'
|
|
||||||
self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
|
|
||||||
self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
|
|
||||||
self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
|
|
||||||
self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
|
|
||||||
self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
|
|
||||||
self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
|
|
||||||
self.syntaxdialog.open()
|
|
||||||
|
|
||||||
def syntaxclose(self):
|
|
||||||
self.syntaxdialog.close()
|
|
||||||
del self.syntaxdialog
|
|
||||||
|
|
||||||
def syntaxedit(self):
|
|
||||||
try:
|
|
||||||
value, (filename, lineno, charno, line) = self.value
|
|
||||||
except:
|
|
||||||
filename = ""
|
|
||||||
lineno = None
|
|
||||||
if not filename and self.lastwindowtitle:
|
|
||||||
filename = self.lastwindowtitle
|
|
||||||
elif not filename:
|
|
||||||
filename = "<unknown>"
|
|
||||||
self.syntaxclose()
|
|
||||||
if lineno:
|
|
||||||
if charno is None:
|
|
||||||
charno = 1
|
|
||||||
W.getapplication().openscript(filename, lineno, charno - 1)
|
|
||||||
else:
|
|
||||||
W.getapplication().openscript(filename)
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
if self.closed:
|
|
||||||
self.setupwidgets()
|
|
||||||
self.w.open()
|
|
||||||
else:
|
|
||||||
self.w.wid.ShowWindow()
|
|
||||||
self.w.wid.SelectWindow()
|
|
||||||
|
|
||||||
def hide(self):
|
|
||||||
if self.closed:
|
|
||||||
return
|
|
||||||
self.w.close()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.bounds = self.w.getbounds()
|
|
||||||
self.closed = 1
|
|
||||||
self.type, self.value, self.tb = None, None, None
|
|
||||||
self.tblist = None
|
|
||||||
|
|
||||||
def activate(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
if self.closed:
|
|
||||||
self.traceback()
|
|
||||||
self.closed = 0
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def setupwidgets(self):
|
|
||||||
self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
|
|
||||||
self.w.text = W.TextBox((10, 10, -10, 30))
|
|
||||||
self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
|
|
||||||
self.w.list = W.TwoLineList((10, 60, -10, -40), callback = self.listhit)
|
|
||||||
|
|
||||||
self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
|
|
||||||
self.w.editbutton.enable(0)
|
|
||||||
|
|
||||||
self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals\xc9", self.browselocals)
|
|
||||||
self.w.browselocalsbutton.enable(0)
|
|
||||||
|
|
||||||
self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem\xc9", self.postmortem)
|
|
||||||
|
|
||||||
self.w.setdefaultbutton(self.w.editbutton)
|
|
||||||
self.w.bind("cmdb", self.w.browselocalsbutton.push)
|
|
||||||
self.w.bind("<close>", self.close)
|
|
||||||
self.w.bind("<activate>", self.activate)
|
|
||||||
|
|
||||||
def buildtblist(self):
|
|
||||||
tb = self.tb
|
|
||||||
for i in range(self.start):
|
|
||||||
if tb.tb_next is None:
|
|
||||||
break
|
|
||||||
tb = tb.tb_next
|
|
||||||
self.tblist = traceback.extract_tb(tb)
|
|
||||||
self.textlist = []
|
|
||||||
for filename, lineno, func, line in self.tblist:
|
|
||||||
tbline = ""
|
|
||||||
if os.path.exists(filename):
|
|
||||||
filename = os.path.split(filename)[1]
|
|
||||||
tbline = 'File "%s", line %r, in %r' % (filename, lineno, func)
|
|
||||||
if line:
|
|
||||||
tbline = tbline + '\r ' + line
|
|
||||||
self.textlist.append(tbline[:255])
|
|
||||||
|
|
||||||
def edit(self):
|
|
||||||
sel = self.w.list.getselection()
|
|
||||||
for i in sel:
|
|
||||||
filename, lineno, func, line = self.tblist[i]
|
|
||||||
W.getapplication().openscript(filename, lineno)
|
|
||||||
|
|
||||||
def browselocals(self):
|
|
||||||
sel = self.w.list.getselection()
|
|
||||||
for i in sel:
|
|
||||||
tb = self.tb
|
|
||||||
for j in range(i + self.start):
|
|
||||||
tb = tb.tb_next
|
|
||||||
self.browse(tb.tb_frame.f_locals)
|
|
||||||
|
|
||||||
def browse(self, object):
|
|
||||||
import PyBrowser
|
|
||||||
PyBrowser.Browser(object)
|
|
||||||
|
|
||||||
def postmortem(self):
|
|
||||||
import PyDebugger
|
|
||||||
PyDebugger.postmortem(self.type, self.value, self.tb)
|
|
||||||
|
|
||||||
def listhit(self, isdbl):
|
|
||||||
if isdbl:
|
|
||||||
self.w.editbutton.push()
|
|
||||||
else:
|
|
||||||
self.checkbuttons()
|
|
||||||
|
|
||||||
def checkbuttons(self):
|
|
||||||
havefile = len(self.w.list.getselection()) > 0
|
|
||||||
self.w.editbutton.enable(havefile)
|
|
||||||
self.w.browselocalsbutton.enable(havefile)
|
|
||||||
self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)
|
|
|
@ -1,636 +0,0 @@
|
||||||
from Carbon import Dlg, Evt, Events, Fm
|
|
||||||
from Carbon import Menu, Qd, Win, Windows
|
|
||||||
import FrameWork
|
|
||||||
import Wbase
|
|
||||||
import MacOS
|
|
||||||
import struct
|
|
||||||
import traceback
|
|
||||||
from types import InstanceType, StringType
|
|
||||||
|
|
||||||
if hasattr(Win, "FrontNonFloatingWindow"):
|
|
||||||
MyFrontWindow = Win.FrontNonFloatingWindow
|
|
||||||
else:
|
|
||||||
MyFrontWindow = Win.FrontWindow
|
|
||||||
|
|
||||||
|
|
||||||
class Window(FrameWork.Window, Wbase.SelectableWidget):
|
|
||||||
|
|
||||||
windowkind = Windows.documentProc
|
|
||||||
|
|
||||||
def __init__(self, possize, title="", minsize=None, maxsize=None,
|
|
||||||
tabbable=1, show=1, fontsettings=None):
|
|
||||||
import W
|
|
||||||
if fontsettings is None:
|
|
||||||
fontsettings = W.getdefaultfont()
|
|
||||||
self._fontsettings = fontsettings
|
|
||||||
W.SelectableWidget.__init__(self, possize)
|
|
||||||
self._globalbounds = l, t, r, b = self.getwindowbounds(possize, minsize)
|
|
||||||
self._bounds = (0, 0, r - l, b - t)
|
|
||||||
self._tabchain = []
|
|
||||||
self._currentwidget = None
|
|
||||||
self.title = title
|
|
||||||
self._parentwindow = self
|
|
||||||
self._tabbable = tabbable
|
|
||||||
self._defaultbutton = None
|
|
||||||
self._drawwidgetbounds = 0
|
|
||||||
self._show = show
|
|
||||||
self._lastrollover = None
|
|
||||||
self.hasclosebox = 1
|
|
||||||
# XXX the following is not really compatible with the
|
|
||||||
# new (system >= 7.5) window procs.
|
|
||||||
if minsize:
|
|
||||||
self._hasgrowbox = 1
|
|
||||||
self.windowkind = self.windowkind | 8
|
|
||||||
l, t = minsize
|
|
||||||
if maxsize:
|
|
||||||
r, b = maxsize[0] + 1, maxsize[1] + 1
|
|
||||||
else:
|
|
||||||
r, b = 32000, 32000
|
|
||||||
self.growlimit = (l, t, r, b)
|
|
||||||
else:
|
|
||||||
self._hasgrowbox = 0
|
|
||||||
if (self.windowkind == 0 or self.windowkind >= 8) and self.windowkind < 1000:
|
|
||||||
self.windowkind = self.windowkind | 4
|
|
||||||
FrameWork.Window.__init__(self, W.getapplication())
|
|
||||||
|
|
||||||
def gettitle(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
def settitle(self, title):
|
|
||||||
self.title = title
|
|
||||||
if self.wid:
|
|
||||||
self.wid.SetWTitle(title)
|
|
||||||
|
|
||||||
def getwindowbounds(self, size, minsize = None):
|
|
||||||
return windowbounds(size, minsize)
|
|
||||||
|
|
||||||
def getcurrentwidget(self):
|
|
||||||
return self._currentwidget
|
|
||||||
|
|
||||||
def show(self, onoff):
|
|
||||||
if onoff:
|
|
||||||
self.wid.ShowWindow()
|
|
||||||
else:
|
|
||||||
self.wid.HideWindow()
|
|
||||||
|
|
||||||
def isvisible(self):
|
|
||||||
return self.wid.IsWindowVisible()
|
|
||||||
|
|
||||||
def select(self):
|
|
||||||
self.wid.SelectWindow()
|
|
||||||
# not sure if this is the best place, I need it when
|
|
||||||
# an editor gets selected, and immediately scrolled
|
|
||||||
# to a certain line, waste scroll assumes everything
|
|
||||||
# to be in tact.
|
|
||||||
self.do_rawupdate(self.wid, "DummyEvent")
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self.wid = Win.NewCWindow(self._globalbounds, self.title, self._show,
|
|
||||||
self.windowkind, -1, self.hasclosebox, 0)
|
|
||||||
self.SetPort()
|
|
||||||
fontname, fontstyle, fontsize, fontcolor = self._fontsettings
|
|
||||||
fnum = Fm.GetFNum(fontname)
|
|
||||||
if fnum == 0:
|
|
||||||
fnum = Fm.GetFNum("Geneva")
|
|
||||||
Qd.TextFont(fnum)
|
|
||||||
Qd.TextFace(fontstyle)
|
|
||||||
Qd.TextSize(fontsize)
|
|
||||||
if self._bindings.has_key("<open>"):
|
|
||||||
callback = self._bindings["<open>"]
|
|
||||||
callback()
|
|
||||||
for w in self._widgets:
|
|
||||||
w.forall_frombottom("open")
|
|
||||||
self._maketabchain()
|
|
||||||
if self._tabbable:
|
|
||||||
self.bind('tab', self.nextwidget)
|
|
||||||
self.bind('shifttab', self.previouswidget)
|
|
||||||
else:
|
|
||||||
self._hasselframes = 0
|
|
||||||
if self._tabchain:
|
|
||||||
self._tabchain[0].select(1)
|
|
||||||
self.do_postopen()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if not self.wid:
|
|
||||||
return # we are already closed
|
|
||||||
if self._bindings.has_key("<close>"):
|
|
||||||
callback = self._bindings["<close>"]
|
|
||||||
try:
|
|
||||||
rv = callback()
|
|
||||||
except:
|
|
||||||
print 'error in <close> callback'
|
|
||||||
traceback.print_exc()
|
|
||||||
else:
|
|
||||||
if rv:
|
|
||||||
return rv
|
|
||||||
#for key in self._widgetsdict.keys():
|
|
||||||
# self._removewidget(key)
|
|
||||||
self.forall_butself("close")
|
|
||||||
Wbase.SelectableWidget.close(self)
|
|
||||||
self._tabchain = []
|
|
||||||
self._currentwidget = None
|
|
||||||
self.wid.HideWindow()
|
|
||||||
self.do_postclose()
|
|
||||||
|
|
||||||
def domenu_close(self, *args):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def getbounds(self):
|
|
||||||
return self._globalbounds
|
|
||||||
|
|
||||||
def setbounds(self, bounds):
|
|
||||||
l, t, r, b = bounds
|
|
||||||
self.move(l, t)
|
|
||||||
self.resize(r-l, b-t)
|
|
||||||
|
|
||||||
def move(self, x, y = None):
|
|
||||||
"""absolute move"""
|
|
||||||
if y == None:
|
|
||||||
x, y = x
|
|
||||||
self.wid.MoveWindow(x, y, 0)
|
|
||||||
|
|
||||||
def resize(self, x, y = None):
|
|
||||||
if not self._hasgrowbox:
|
|
||||||
return # hands off!
|
|
||||||
if y == None:
|
|
||||||
x, y = x
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(self.getgrowrect())
|
|
||||||
self.wid.SizeWindow(x, y, 1)
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
def test(self, point):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def draw(self, visRgn = None):
|
|
||||||
if self._hasgrowbox:
|
|
||||||
self.tempcliprect(self.getgrowrect())
|
|
||||||
self.wid.DrawGrowIcon()
|
|
||||||
self.restoreclip()
|
|
||||||
|
|
||||||
def idle(self, *args):
|
|
||||||
self.SetPort()
|
|
||||||
point = Evt.GetMouse()
|
|
||||||
widget = self.findwidget(point, 0)
|
|
||||||
if self._bindings.has_key("<idle>"):
|
|
||||||
callback = self._bindings["<idle>"]
|
|
||||||
if callback():
|
|
||||||
return
|
|
||||||
if self._currentwidget is not None and hasattr(self._currentwidget, "idle"):
|
|
||||||
if self._currentwidget._bindings.has_key("<idle>"):
|
|
||||||
callback = self._currentwidget._bindings["<idle>"]
|
|
||||||
if callback():
|
|
||||||
return
|
|
||||||
if self._currentwidget.idle():
|
|
||||||
return
|
|
||||||
if widget is not None and hasattr(widget, "rollover"):
|
|
||||||
if 1: #self._lastrollover <> widget:
|
|
||||||
if self._lastrollover:
|
|
||||||
self._lastrollover.rollover(point, 0)
|
|
||||||
self._lastrollover = widget
|
|
||||||
self._lastrollover.rollover(point, 1)
|
|
||||||
else:
|
|
||||||
if self._lastrollover:
|
|
||||||
self._lastrollover.rollover(point, 0)
|
|
||||||
self._lastrollover = None
|
|
||||||
Wbase.SetCursor("arrow")
|
|
||||||
|
|
||||||
def xxx___select(self, widget):
|
|
||||||
if self._currentwidget == widget:
|
|
||||||
return
|
|
||||||
if self._bindings.has_key("<select>"):
|
|
||||||
callback = self._bindings["<select>"]
|
|
||||||
if callback(widget):
|
|
||||||
return
|
|
||||||
if widget is None:
|
|
||||||
if self._currentwidget is not None:
|
|
||||||
self._currentwidget.select(0)
|
|
||||||
elif type(widget) == InstanceType and widget._selectable:
|
|
||||||
widget.select(1)
|
|
||||||
elif widget == -1 or widget == 1:
|
|
||||||
if len(self._tabchain) <= 1:
|
|
||||||
return
|
|
||||||
temp = self._tabchain[(self._tabchain.index(self._currentwidget) + widget) % len(self._tabchain)]
|
|
||||||
temp.select(1)
|
|
||||||
else:
|
|
||||||
raise TypeError, "Widget is not selectable"
|
|
||||||
|
|
||||||
def setdefaultbutton(self, newdefaultbutton = None, *keys):
|
|
||||||
if newdefaultbutton == self._defaultbutton:
|
|
||||||
return
|
|
||||||
if self._defaultbutton:
|
|
||||||
self._defaultbutton._setdefault(0)
|
|
||||||
if not newdefaultbutton:
|
|
||||||
self.bind("return", None)
|
|
||||||
self.bind("enter", None)
|
|
||||||
return
|
|
||||||
import Wcontrols
|
|
||||||
if not isinstance(newdefaultbutton, Wcontrols.Button):
|
|
||||||
raise TypeError, "widget is not a button"
|
|
||||||
self._defaultbutton = newdefaultbutton
|
|
||||||
self._defaultbutton._setdefault(1)
|
|
||||||
if not keys:
|
|
||||||
self.bind("return", self._defaultbutton.push)
|
|
||||||
self.bind("enter", self._defaultbutton.push)
|
|
||||||
else:
|
|
||||||
for key in keys:
|
|
||||||
self.bind(key, self._defaultbutton.push)
|
|
||||||
|
|
||||||
def nextwidget(self):
|
|
||||||
self.xxx___select(1)
|
|
||||||
|
|
||||||
def previouswidget(self):
|
|
||||||
self.xxx___select(-1)
|
|
||||||
|
|
||||||
def drawwidgetbounds(self, onoff):
|
|
||||||
self._drawwidgetbounds = onoff
|
|
||||||
self.SetPort()
|
|
||||||
self.GetWindow().InvalWindowRect(self._bounds)
|
|
||||||
|
|
||||||
def _drawbounds(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _maketabchain(self):
|
|
||||||
# XXX This has to change, it's no good when we are adding or deleting widgets.
|
|
||||||
# XXX Perhaps we shouldn't keep a "tabchain" at all.
|
|
||||||
self._hasselframes = 0
|
|
||||||
self._collectselectablewidgets(self._widgets)
|
|
||||||
if self._hasselframes and len(self._tabchain) > 1:
|
|
||||||
self._hasselframes = 1
|
|
||||||
else:
|
|
||||||
self._hasselframes = 0
|
|
||||||
|
|
||||||
def _collectselectablewidgets(self, widgets):
|
|
||||||
import W
|
|
||||||
for w in widgets:
|
|
||||||
if w._selectable:
|
|
||||||
self._tabchain.append(w)
|
|
||||||
if isinstance(w, W.List):
|
|
||||||
self._hasselframes = 1
|
|
||||||
self._collectselectablewidgets(w._widgets)
|
|
||||||
|
|
||||||
def _calcbounds(self):
|
|
||||||
self._possize = self.wid.GetWindowPort().GetPortBounds()[2:]
|
|
||||||
w, h = self._possize
|
|
||||||
self._bounds = (0, 0, w, h)
|
|
||||||
self.wid.GetWindowContentRgn(scratchRegion)
|
|
||||||
l, t, r, b = GetRgnBounds(scratchRegion)
|
|
||||||
self._globalbounds = l, t, l + w, t + h
|
|
||||||
for w in self._widgets:
|
|
||||||
w._calcbounds()
|
|
||||||
|
|
||||||
# FrameWork override methods
|
|
||||||
def do_inDrag(self, partcode, window, event):
|
|
||||||
where = event[3]
|
|
||||||
self.wid.GetWindowContentRgn(scratchRegion)
|
|
||||||
was_l, was_t, r, b = GetRgnBounds(scratchRegion)
|
|
||||||
window.DragWindow(where, self.draglimit)
|
|
||||||
self.wid.GetWindowContentRgn(scratchRegion)
|
|
||||||
is_l, is_t, r, b = GetRgnBounds(scratchRegion)
|
|
||||||
self._globalbounds = Qd.OffsetRect(self._globalbounds,
|
|
||||||
is_l - was_l, is_t - was_t)
|
|
||||||
|
|
||||||
def do_char(self, char, event):
|
|
||||||
import Wkeys
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
key = char
|
|
||||||
if Wkeys.keynames.has_key(key):
|
|
||||||
key = Wkeys.keynames[key]
|
|
||||||
if modifiers & Events.shiftKey:
|
|
||||||
key = 'shift' + key
|
|
||||||
if modifiers & Events.cmdKey:
|
|
||||||
key = 'cmd' + key
|
|
||||||
if modifiers & Events.controlKey:
|
|
||||||
key = 'control' + key
|
|
||||||
if self._bindings.has_key("<key>"):
|
|
||||||
callback = self._bindings["<key>"]
|
|
||||||
if Wbase.CallbackCall(callback, 0, char, event):
|
|
||||||
return
|
|
||||||
if self._bindings.has_key(key):
|
|
||||||
callback = self._bindings[key]
|
|
||||||
Wbase.CallbackCall(callback, 0, char, event)
|
|
||||||
elif self._currentwidget is not None:
|
|
||||||
if self._currentwidget._bindings.has_key(key):
|
|
||||||
callback = self._currentwidget._bindings[key]
|
|
||||||
Wbase.CallbackCall(callback, 0, char, event)
|
|
||||||
else:
|
|
||||||
if self._currentwidget._bindings.has_key("<key>"):
|
|
||||||
callback = self._currentwidget._bindings["<key>"]
|
|
||||||
if Wbase.CallbackCall(callback, 0, char, event):
|
|
||||||
return
|
|
||||||
self._currentwidget.key(char, event)
|
|
||||||
|
|
||||||
def do_contentclick(self, point, modifiers, event):
|
|
||||||
widget = self.findwidget(point)
|
|
||||||
if widget is not None:
|
|
||||||
if self._bindings.has_key("<click>"):
|
|
||||||
callback = self._bindings["<click>"]
|
|
||||||
if Wbase.CallbackCall(callback, 0, point, modifiers):
|
|
||||||
return
|
|
||||||
if widget._bindings.has_key("<click>"):
|
|
||||||
callback = widget._bindings["<click>"]
|
|
||||||
if Wbase.CallbackCall(callback, 0, point, modifiers):
|
|
||||||
return
|
|
||||||
if widget._selectable:
|
|
||||||
widget.select(1, 1)
|
|
||||||
widget.click(point, modifiers)
|
|
||||||
|
|
||||||
def do_update(self, window, event):
|
|
||||||
Qd.EraseRgn(window.GetWindowPort().visRgn)
|
|
||||||
self.forall_frombottom("draw", window.GetWindowPort().visRgn)
|
|
||||||
if self._drawwidgetbounds:
|
|
||||||
self.forall_frombottom("_drawbounds")
|
|
||||||
|
|
||||||
def do_activate(self, onoff, event):
|
|
||||||
if not onoff:
|
|
||||||
if self._lastrollover:
|
|
||||||
self._lastrollover.rollover((0, 0), 0)
|
|
||||||
self._lastrollover = None
|
|
||||||
self.SetPort()
|
|
||||||
self.forall("activate", onoff)
|
|
||||||
self.draw()
|
|
||||||
|
|
||||||
def do_postresize(self, width, height, window):
|
|
||||||
self.GetWindow().InvalWindowRect(self.getgrowrect())
|
|
||||||
self._calcbounds()
|
|
||||||
|
|
||||||
def do_inGoAway(self, partcode, window, event):
|
|
||||||
where = event[3]
|
|
||||||
closeall = event[4] & Events.optionKey
|
|
||||||
if window.TrackGoAway(where):
|
|
||||||
if not closeall:
|
|
||||||
self.close()
|
|
||||||
else:
|
|
||||||
for window in self.parent._windows.values():
|
|
||||||
rv = window.close()
|
|
||||||
if rv and rv > 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
# utilities
|
|
||||||
def tempcliprect(self, tempcliprect):
|
|
||||||
tempclip = Qd.NewRgn()
|
|
||||||
Qd.RectRgn(tempclip, tempcliprect)
|
|
||||||
self.tempclip(tempclip)
|
|
||||||
Qd.DisposeRgn(tempclip)
|
|
||||||
|
|
||||||
def tempclip(self, tempclip):
|
|
||||||
if not hasattr(self, "saveclip"):
|
|
||||||
self.saveclip = []
|
|
||||||
saveclip = Qd.NewRgn()
|
|
||||||
Qd.GetClip(saveclip)
|
|
||||||
self.saveclip.append(saveclip)
|
|
||||||
Qd.SetClip(tempclip)
|
|
||||||
|
|
||||||
def restoreclip(self):
|
|
||||||
Qd.SetClip(self.saveclip[-1])
|
|
||||||
Qd.DisposeRgn(self.saveclip[-1])
|
|
||||||
del self.saveclip[-1]
|
|
||||||
|
|
||||||
def getgrowrect(self):
|
|
||||||
l, t, r, b = self.wid.GetWindowPort().GetPortBounds()
|
|
||||||
return (r - 15, b - 15, r, b)
|
|
||||||
|
|
||||||
def has_key(self, key):
|
|
||||||
return self._widgetsdict.has_key(key)
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
global _successcount, _failcount, _magiccount
|
|
||||||
if self._widgetsdict.has_key(attr):
|
|
||||||
_successcount = _successcount + 1
|
|
||||||
return self._widgetsdict[attr]
|
|
||||||
if self._currentwidget is None or (attr[:7] <> 'domenu_' and
|
|
||||||
attr[:4] <> 'can_' and attr <> 'insert'):
|
|
||||||
_failcount = _failcount + 1
|
|
||||||
raise AttributeError, attr
|
|
||||||
# special case: if a domenu_xxx, can_xxx or insert method is asked for,
|
|
||||||
# see if the active widget supports it
|
|
||||||
_magiccount = _magiccount + 1
|
|
||||||
return getattr(self._currentwidget, attr)
|
|
||||||
|
|
||||||
_successcount = 0
|
|
||||||
_failcount = 0
|
|
||||||
_magiccount = 0
|
|
||||||
|
|
||||||
class Dialog(Window):
|
|
||||||
|
|
||||||
windowkind = Windows.movableDBoxProc
|
|
||||||
|
|
||||||
# this __init__ seems redundant, but it's not: it has less args
|
|
||||||
def __init__(self, possize, title = ""):
|
|
||||||
Window.__init__(self, possize, title)
|
|
||||||
|
|
||||||
def can_close(self, *args):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def getwindowbounds(self, size, minsize = None):
|
|
||||||
screenbounds = sl, st, sr, sb = Qd.GetQDGlobalsScreenBits().bounds
|
|
||||||
w, h = size
|
|
||||||
l = sl + (sr - sl - w) / 2
|
|
||||||
t = st + (sb - st - h) / 3
|
|
||||||
return l, t, l + w, t + h
|
|
||||||
|
|
||||||
|
|
||||||
class ModalDialog(Dialog):
|
|
||||||
|
|
||||||
def __init__(self, possize, title = ""):
|
|
||||||
Dialog.__init__(self, possize, title)
|
|
||||||
if title:
|
|
||||||
self.windowkind = Windows.movableDBoxProc
|
|
||||||
else:
|
|
||||||
self.windowkind = Windows.dBoxProc
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
import W
|
|
||||||
Dialog.open(self)
|
|
||||||
self.app = W.getapplication()
|
|
||||||
self.done = 0
|
|
||||||
Menu.HiliteMenu(0)
|
|
||||||
app = self.parent
|
|
||||||
app.enablemenubar(0)
|
|
||||||
try:
|
|
||||||
self.mainloop()
|
|
||||||
finally:
|
|
||||||
app.enablemenubar(1)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if not self.wid:
|
|
||||||
return # we are already closed
|
|
||||||
self.done = 1
|
|
||||||
del self.app
|
|
||||||
Dialog.close(self)
|
|
||||||
|
|
||||||
def mainloop(self):
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
saveyield = MacOS.EnableAppswitch(-1)
|
|
||||||
while not self.done:
|
|
||||||
#self.do1event()
|
|
||||||
self.do1event( Events.keyDownMask +
|
|
||||||
Events.autoKeyMask +
|
|
||||||
Events.activMask +
|
|
||||||
Events.updateMask +
|
|
||||||
Events.mDownMask +
|
|
||||||
Events.mUpMask,
|
|
||||||
10)
|
|
||||||
if hasattr(MacOS, 'EnableAppswitch'):
|
|
||||||
MacOS.EnableAppswitch(saveyield)
|
|
||||||
|
|
||||||
def do1event(self, mask = Events.everyEvent, wait = 0):
|
|
||||||
ok, event = self.app.getevent(mask, wait)
|
|
||||||
if Dlg.IsDialogEvent(event):
|
|
||||||
if self.app.do_dialogevent(event):
|
|
||||||
return
|
|
||||||
if ok:
|
|
||||||
self.dispatch(event)
|
|
||||||
else:
|
|
||||||
self.app.idle(event)
|
|
||||||
|
|
||||||
def do_keyDown(self, event):
|
|
||||||
self.do_key(event)
|
|
||||||
|
|
||||||
def do_autoKey(self, event):
|
|
||||||
if not event[-1] & Events.cmdKey:
|
|
||||||
self.do_key(event)
|
|
||||||
|
|
||||||
def do_key(self, event):
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
#w = Win.FrontWindow()
|
|
||||||
#if w <> self.wid:
|
|
||||||
# return
|
|
||||||
c = chr(message & Events.charCodeMask)
|
|
||||||
if modifiers & Events.cmdKey:
|
|
||||||
self.app.checkmenus(self)
|
|
||||||
result = Menu.MenuKey(ord(c))
|
|
||||||
id = (result>>16) & 0xffff # Hi word
|
|
||||||
item = result & 0xffff # Lo word
|
|
||||||
if id:
|
|
||||||
self.app.do_rawmenu(id, item, None, event)
|
|
||||||
return
|
|
||||||
self.do_char(c, event)
|
|
||||||
|
|
||||||
def do_mouseDown(self, event):
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
partcode, wid = Win.FindWindow(where)
|
|
||||||
#
|
|
||||||
# Find the correct name.
|
|
||||||
#
|
|
||||||
if FrameWork.partname.has_key(partcode):
|
|
||||||
name = "do_" + FrameWork.partname[partcode]
|
|
||||||
else:
|
|
||||||
name = "do_%d" % partcode
|
|
||||||
|
|
||||||
if name == "do_inDesk":
|
|
||||||
if hasattr(MacOS, "HandleEvent"):
|
|
||||||
MacOS.HandleEvent(event)
|
|
||||||
else:
|
|
||||||
print 'Unexpected inDesk event:', event
|
|
||||||
return
|
|
||||||
if wid == self.wid:
|
|
||||||
try:
|
|
||||||
handler = getattr(self, name)
|
|
||||||
except AttributeError:
|
|
||||||
handler = self.app.do_unknownpartcode
|
|
||||||
else:
|
|
||||||
#MacOS.HandleEvent(event)
|
|
||||||
if name == 'do_inMenuBar':
|
|
||||||
handler = getattr(self.parent, name)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
handler(partcode, wid, event)
|
|
||||||
|
|
||||||
def dispatch(self, event):
|
|
||||||
(what, message, when, where, modifiers) = event
|
|
||||||
if FrameWork.eventname.has_key(what):
|
|
||||||
name = "do_" + FrameWork.eventname[what]
|
|
||||||
else:
|
|
||||||
name = "do_%d" % what
|
|
||||||
try:
|
|
||||||
handler = getattr(self, name)
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
|
||||||
handler = getattr(self.app, name)
|
|
||||||
except AttributeError:
|
|
||||||
handler = self.app.do_unknownevent
|
|
||||||
handler(event)
|
|
||||||
|
|
||||||
|
|
||||||
def FrontWindowInsert(stuff):
|
|
||||||
if not stuff:
|
|
||||||
return
|
|
||||||
if type(stuff) <> StringType:
|
|
||||||
raise TypeError, 'string expected'
|
|
||||||
import W
|
|
||||||
app = W.getapplication()
|
|
||||||
wid = MyFrontWindow()
|
|
||||||
if wid and app._windows.has_key(wid):
|
|
||||||
window = app._windows[wid]
|
|
||||||
if hasattr(window, "insert"):
|
|
||||||
try:
|
|
||||||
window.insert(stuff)
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
import EasyDialogs
|
|
||||||
if EasyDialogs.AskYesNoCancel(
|
|
||||||
"Can't find window or widget to insert text into; copy to clipboard instead?",
|
|
||||||
1) == 1:
|
|
||||||
from Carbon import Scrap
|
|
||||||
if hasattr(Scrap, 'PutScrap'):
|
|
||||||
Scrap.ZeroScrap()
|
|
||||||
Scrap.PutScrap('TEXT', stuff)
|
|
||||||
else:
|
|
||||||
Scrap.ClearCurrentScrap()
|
|
||||||
sc = Scrap.GetCurrentScrap()
|
|
||||||
sc.PutScrapFlavor('TEXT', 0, stuff)
|
|
||||||
|
|
||||||
|
|
||||||
# not quite based on the same function in FrameWork
|
|
||||||
_windowcounter = 0
|
|
||||||
|
|
||||||
def getnextwindowpos():
|
|
||||||
global _windowcounter
|
|
||||||
rows = 8
|
|
||||||
l = 4 * (rows + 1 - (_windowcounter % rows) + _windowcounter / rows)
|
|
||||||
t = 44 + 20 * (_windowcounter % rows)
|
|
||||||
_windowcounter = _windowcounter + 1
|
|
||||||
return l, t
|
|
||||||
|
|
||||||
def windowbounds(preferredsize, minsize=None):
|
|
||||||
"Return sensible window bounds"
|
|
||||||
|
|
||||||
global _windowcounter
|
|
||||||
if len(preferredsize) == 4:
|
|
||||||
bounds = l, t, r, b = preferredsize
|
|
||||||
desktopRgn = Win.GetGrayRgn()
|
|
||||||
tempRgn = Qd.NewRgn()
|
|
||||||
Qd.RectRgn(tempRgn, bounds)
|
|
||||||
union = Qd.UnionRgn(tempRgn, desktopRgn, tempRgn)
|
|
||||||
equal = Qd.EqualRgn(tempRgn, desktopRgn)
|
|
||||||
Qd.DisposeRgn(tempRgn)
|
|
||||||
if equal:
|
|
||||||
return bounds
|
|
||||||
else:
|
|
||||||
preferredsize = r - l, b - t
|
|
||||||
if not minsize:
|
|
||||||
minsize = preferredsize
|
|
||||||
minwidth, minheight = minsize
|
|
||||||
width, height = preferredsize
|
|
||||||
|
|
||||||
sl, st, sr, sb = screenbounds = Qd.InsetRect(Qd.GetQDGlobalsScreenBits().bounds, 4, 4)
|
|
||||||
l, t = getnextwindowpos()
|
|
||||||
if (l + width) > sr:
|
|
||||||
_windowcounter = 0
|
|
||||||
l, t = getnextwindowpos()
|
|
||||||
r = l + width
|
|
||||||
b = t + height
|
|
||||||
if (t + height) > sb:
|
|
||||||
b = sb
|
|
||||||
if (b - t) < minheight:
|
|
||||||
b = t + minheight
|
|
||||||
return l, t, r, b
|
|
||||||
|
|
||||||
scratchRegion = Qd.NewRgn()
|
|
||||||
|
|
||||||
# util -- move somewhere convenient???
|
|
||||||
def GetRgnBounds(the_Rgn):
|
|
||||||
(t, l, b, r) = struct.unpack("hhhh", the_Rgn.data[2:10])
|
|
||||||
return (l, t, r, b)
|
|
|
@ -1,42 +0,0 @@
|
||||||
import re
|
|
||||||
import os
|
|
||||||
|
|
||||||
# The regular expression for freeze directives. These are comments with the
|
|
||||||
# word macfreeze immedeately followed by a colon, followed by a directive,
|
|
||||||
# followed by argument(s)
|
|
||||||
#
|
|
||||||
# The directives supported are
|
|
||||||
# include - Include a module or file
|
|
||||||
# exclude - Exclude a module
|
|
||||||
# optional - Include a module if it is found, but don't complain if it isn't
|
|
||||||
# path - Add sys.path entries. Relative paths are relative to the source file.
|
|
||||||
#
|
|
||||||
# See the macfreeze.py main program for a real live example.
|
|
||||||
#
|
|
||||||
DIRECTIVE_RE=r'^\s*#\s*macfreeze:\s*(\S*)\s*(.*)\s*$'
|
|
||||||
REPROG=re.compile(DIRECTIVE_RE)
|
|
||||||
|
|
||||||
def findfreezedirectives(program):
|
|
||||||
extra_modules = []
|
|
||||||
exclude_modules = []
|
|
||||||
optional_modules = []
|
|
||||||
extra_path = []
|
|
||||||
progdir, filename = os.path.split(program)
|
|
||||||
fp = open(program)
|
|
||||||
for line in fp.readlines():
|
|
||||||
match = REPROG.match(line)
|
|
||||||
if match:
|
|
||||||
directive = match.group(1)
|
|
||||||
argument = match.group(2)
|
|
||||||
if directive == 'include':
|
|
||||||
extra_modules.append(argument)
|
|
||||||
elif directive == 'exclude':
|
|
||||||
exclude_modules.append(argument)
|
|
||||||
elif directive == 'optional':
|
|
||||||
optional_modules.append(argument)
|
|
||||||
elif directive == 'path':
|
|
||||||
argument = os.path.join(progdir, argument)
|
|
||||||
extra_path.append(argument)
|
|
||||||
else:
|
|
||||||
print '** Unknown directive', line
|
|
||||||
return extra_modules, exclude_modules, optional_modules, extra_path
|
|
|
@ -1,5 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
print 'Hello world'
|
|
||||||
print 'Builtin modules:', sys.builtin_module_names
|
|
||||||
sys.exit(1)
|
|
|
@ -1,75 +0,0 @@
|
||||||
"""macfreeze - Main program and GUI
|
|
||||||
|
|
||||||
macfreeze allows you to turn Python scripts into fully self-contained
|
|
||||||
Mac applications, by including all the Python and C code needed in a single
|
|
||||||
executable. Like unix/windows freeze it can produce a config.c allowing you
|
|
||||||
to build the application with a development environment (CodeWarrior, to be
|
|
||||||
precise), but unlike the standard freeze it is also possible to create frozen
|
|
||||||
applications without a development environment, by glueing all the
|
|
||||||
shared libraries and extension modules needed together in a single
|
|
||||||
executable, using some Code Fragment Manager tricks."""
|
|
||||||
|
|
||||||
import macfs
|
|
||||||
import sys
|
|
||||||
import EasyDialogs
|
|
||||||
import string
|
|
||||||
|
|
||||||
import macfreezegui
|
|
||||||
import macmodulefinder
|
|
||||||
|
|
||||||
#
|
|
||||||
# Here are the macfreeze directives, used when freezing macfreeze itself
|
|
||||||
# (see directives.py for an explanation)
|
|
||||||
#
|
|
||||||
# macfreeze: path ::::Tools:freeze
|
|
||||||
# macfreeze: exclude win32api
|
|
||||||
#
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
gentype, program, output, debug = macfreezegui.dialog()
|
|
||||||
elif len(sys.argv) == 2:
|
|
||||||
gentype, program, output, debug = macfreezegui.dialog(sys.argv[1])
|
|
||||||
else:
|
|
||||||
EasyDialog.Message(
|
|
||||||
"Please pass a single script. Additional modules can be specified with directives")
|
|
||||||
sys.exit(0)
|
|
||||||
mustwait = process(gentype, program, output, debug=debug)
|
|
||||||
if mustwait:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def process(gentype, program, output, modules=None, module_files=None, debug=0, with_ifdef=0):
|
|
||||||
if modules is None:
|
|
||||||
modules = []
|
|
||||||
if module_files is None:
|
|
||||||
module_files = []
|
|
||||||
module_dict, missing = macmodulefinder.process(program, modules, module_files, debug)
|
|
||||||
if missing:
|
|
||||||
missing.sort()
|
|
||||||
print '** Missing modules:', string.join(missing, ' ')
|
|
||||||
sys.exit(1)
|
|
||||||
#
|
|
||||||
# And generate
|
|
||||||
#
|
|
||||||
if gentype == 'info':
|
|
||||||
import macgen_info
|
|
||||||
macgen_info.generate(output, module_dict)
|
|
||||||
return 1 # So the user can inspect it
|
|
||||||
elif gentype == 'source':
|
|
||||||
import macgen_src
|
|
||||||
warnings = macgen_src.generate(output, module_dict, debug, with_ifdef)
|
|
||||||
return warnings
|
|
||||||
elif gentype == 'resource':
|
|
||||||
import macgen_rsrc
|
|
||||||
macgen_rsrc.generate(output, module_dict, debug)
|
|
||||||
warnings = macgen_rsrc.warnings(module_dict)
|
|
||||||
return warnings
|
|
||||||
elif gentype == 'applet':
|
|
||||||
import macgen_bin
|
|
||||||
architecture = 'fat' # user should choose
|
|
||||||
macgen_bin.generate(program, output, module_dict, architecture, debug)
|
|
||||||
else:
|
|
||||||
raise 'unknown gentype', gentype
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
Binary file not shown.
|
@ -1,150 +0,0 @@
|
||||||
"""macfreezegui - The GUI for macfreeze"""
|
|
||||||
from Carbon import Dlg
|
|
||||||
import macfs
|
|
||||||
import EasyDialogs
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import string
|
|
||||||
from Carbon import Res
|
|
||||||
import macresource
|
|
||||||
|
|
||||||
ID_MAINDIALOG=512
|
|
||||||
|
|
||||||
ITEM_SCRIPTNAME=2
|
|
||||||
ITEM_SCRIPTBROWSE=3
|
|
||||||
ITEM_GENSOURCE=4
|
|
||||||
ITEM_GENSOURCE_ITEMS=(7,)
|
|
||||||
ITEM_SOURCEDIRNAME=6
|
|
||||||
ITEM_SOURCEDIRBROWSE=7
|
|
||||||
ITEM_GENRESOURCE=8
|
|
||||||
ITEM_GENRESOURCE_ITEMS=(11,)
|
|
||||||
ITEM_RESOURCENAME=10
|
|
||||||
ITEM_RESOURCEBROWSE=11
|
|
||||||
ITEM_GENAPPLET=12
|
|
||||||
ITEM_GENAPPLET_ITEMS=(15,)
|
|
||||||
ITEM_APPLETNAME=14
|
|
||||||
ITEM_APPLETBROWSE=15
|
|
||||||
ITEM_OK=16
|
|
||||||
ITEM_CANCEL=17
|
|
||||||
ITEM_DEBUG=19
|
|
||||||
ITEM_GENINFO=20
|
|
||||||
|
|
||||||
RADIO_GROUPING={
|
|
||||||
ITEM_GENSOURCE: ITEM_GENSOURCE_ITEMS,
|
|
||||||
ITEM_GENRESOURCE: ITEM_GENRESOURCE_ITEMS,
|
|
||||||
ITEM_GENAPPLET: ITEM_GENAPPLET_ITEMS,
|
|
||||||
ITEM_GENINFO: ()
|
|
||||||
}
|
|
||||||
|
|
||||||
def dialog(script=None):
|
|
||||||
|
|
||||||
# Invent the various names
|
|
||||||
if not script:
|
|
||||||
fss, ok = macfs.PromptGetFile("Script?", "TEXT")
|
|
||||||
if not ok:
|
|
||||||
sys.exit(0)
|
|
||||||
script = fss.as_pathname()
|
|
||||||
basename, ext = os.path.splitext(script)
|
|
||||||
if ext:
|
|
||||||
appletname = basename
|
|
||||||
rsrcname = basename + 'modules.rsrc'
|
|
||||||
else:
|
|
||||||
appletname = script + '.applet'
|
|
||||||
rsrcname = script + 'modules.rsrc'
|
|
||||||
dirname, basebase = os.path.split(basename)
|
|
||||||
dirname = os.path.join(dirname, 'build.'+basebase)
|
|
||||||
|
|
||||||
# Get the dialog, possibly opening the resource file (if needed)
|
|
||||||
macresource.need('DLOG', ID_MAINDIALOG, 'macfreeze.rsrc')
|
|
||||||
d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
|
|
||||||
if d == None:
|
|
||||||
EasyDialogs.Message("Dialog resource not found or faulty")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Fill the dialog
|
|
||||||
d.SetDialogDefaultItem(ITEM_OK)
|
|
||||||
d.SetDialogCancelItem(ITEM_CANCEL)
|
|
||||||
|
|
||||||
_dialogsetfile(d, ITEM_SCRIPTNAME, script)
|
|
||||||
_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
|
|
||||||
_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
|
|
||||||
_dialogsetfile(d, ITEM_APPLETNAME, appletname)
|
|
||||||
|
|
||||||
gentype = ITEM_GENSOURCE
|
|
||||||
_dialogradiogroup(d, ITEM_GENSOURCE)
|
|
||||||
|
|
||||||
# Interact
|
|
||||||
d.GetDialogWindow().SetWTitle("Standalone application creation options")
|
|
||||||
d.GetDialogWindow().ShowWindow()
|
|
||||||
d.DrawDialog()
|
|
||||||
while 1:
|
|
||||||
item = Dlg.ModalDialog(None)
|
|
||||||
if item == ITEM_OK:
|
|
||||||
break
|
|
||||||
elif item == ITEM_CANCEL:
|
|
||||||
sys.exit(0)
|
|
||||||
elif item in RADIO_GROUPING.keys():
|
|
||||||
gentype = item
|
|
||||||
_dialogradiogroup(d, item)
|
|
||||||
elif item == ITEM_SCRIPTBROWSE:
|
|
||||||
fss, ok = macfs.PromptGetFile("Script?")
|
|
||||||
if ok:
|
|
||||||
script = fss.as_pathname()
|
|
||||||
_dialogsetfile(d, ITEM_SCRIPTNAME, script)
|
|
||||||
elif item == ITEM_SOURCEDIRBROWSE:
|
|
||||||
fss, ok = macfs.StandardPutFile("Output folder name", os.path.split(dirname)[1])
|
|
||||||
if ok:
|
|
||||||
dirname = fss.as_pathname()
|
|
||||||
_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
|
|
||||||
elif item == ITEM_RESOURCEBROWSE:
|
|
||||||
fss, ok = macfs.StandardPutFile("Resource output file", os.path.split(rsrcname)[1])
|
|
||||||
if ok:
|
|
||||||
rsrcname = fss.as_pathname()
|
|
||||||
_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
|
|
||||||
elif item == ITEM_APPLETBROWSE:
|
|
||||||
fss, ok = macfs.StandardPutFile("Applet output file", os.path.split(appletname)[1])
|
|
||||||
if ok:
|
|
||||||
appletname = fss.as_pathname()
|
|
||||||
_dialogsetfile(d, ITEM_APPLETNAME, appletname)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
tp, h, rect = d.GetDialogItem(ITEM_DEBUG)
|
|
||||||
debug = Dlg.GetDialogItemText(h)
|
|
||||||
try:
|
|
||||||
debug = string.atoi(string.strip(debug))
|
|
||||||
except ValueError:
|
|
||||||
EasyDialogs.Message("Illegal debug value %r, set to zero."%(debug,))
|
|
||||||
debug = 0
|
|
||||||
if gentype == ITEM_GENSOURCE:
|
|
||||||
return 'source', script, dirname, debug
|
|
||||||
elif gentype == ITEM_GENRESOURCE:
|
|
||||||
return 'resource', script, rsrcname, debug
|
|
||||||
elif gentype == ITEM_GENAPPLET:
|
|
||||||
return 'applet', script, appletname, debug
|
|
||||||
elif gentype == ITEM_GENINFO:
|
|
||||||
return 'info', script, '', debug
|
|
||||||
raise 'Error in gentype', gentype
|
|
||||||
|
|
||||||
def _dialogradiogroup(d, item):
|
|
||||||
for k in RADIO_GROUPING.keys():
|
|
||||||
subitems = RADIO_GROUPING[k]
|
|
||||||
tp, h, rect = d.GetDialogItem(k)
|
|
||||||
if k == item:
|
|
||||||
h.as_Control().SetControlValue(1)
|
|
||||||
for i2 in subitems:
|
|
||||||
d.ShowDialogItem(i2)
|
|
||||||
else:
|
|
||||||
h.as_Control().SetControlValue(0)
|
|
||||||
for i2 in subitems:
|
|
||||||
d.HideDialogItem(i2)
|
|
||||||
|
|
||||||
def _dialogsetfile(d, item, file):
|
|
||||||
if len(file) > 32:
|
|
||||||
file = '\311:' + os.path.split(file)[1]
|
|
||||||
tp, h, rect = d.GetDialogItem(item)
|
|
||||||
Dlg.SetDialogItemText(h, file)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
type, script, file, debug = dialog()
|
|
||||||
print type, script, file, 'debug=%d'%debug
|
|
||||||
sys.exit(1)
|
|
|
@ -1,221 +0,0 @@
|
||||||
"""macgen_bin - Generate application from shared libraries"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import string
|
|
||||||
import types
|
|
||||||
import macfs
|
|
||||||
from MACFS import *
|
|
||||||
import MacOS
|
|
||||||
from Carbon import Res
|
|
||||||
import py_resource
|
|
||||||
import cfmfile
|
|
||||||
import buildtools
|
|
||||||
|
|
||||||
|
|
||||||
def generate(input, output, module_dict=None, architecture='fat', debug=0):
|
|
||||||
# try to remove old file
|
|
||||||
try:
|
|
||||||
os.remove(output)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if module_dict is None:
|
|
||||||
import macmodulefinder
|
|
||||||
print "Searching for modules..."
|
|
||||||
module_dict, missing = macmodulefinder.process(input, [], [], 1)
|
|
||||||
if missing:
|
|
||||||
import EasyDialogs
|
|
||||||
missing.sort()
|
|
||||||
answer = EasyDialogs.AskYesNoCancel("Some modules could not be found; continue anyway?\n(%s)"
|
|
||||||
% string.join(missing, ", "))
|
|
||||||
if answer <> 1:
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
applettemplatepath = buildtools.findtemplate()
|
|
||||||
corepath = findpythoncore()
|
|
||||||
|
|
||||||
dynamicmodules, dynamicfiles, extraresfiles = findfragments(module_dict, architecture)
|
|
||||||
|
|
||||||
print 'Adding "__main__"'
|
|
||||||
buildtools.process(applettemplatepath, input, output, 0)
|
|
||||||
|
|
||||||
outputref = Res.FSpOpenResFile(output, 3)
|
|
||||||
try:
|
|
||||||
Res.UseResFile(outputref)
|
|
||||||
|
|
||||||
print "Adding Python modules"
|
|
||||||
addpythonmodules(module_dict)
|
|
||||||
|
|
||||||
print "Adding PythonCore resources"
|
|
||||||
copyres(corepath, outputref, ['cfrg', 'Popt', 'GU\267I'], 1)
|
|
||||||
|
|
||||||
print "Adding resources from shared libraries"
|
|
||||||
for ppcpath, cfm68kpath in extraresfiles:
|
|
||||||
if os.path.exists(ppcpath):
|
|
||||||
copyres(ppcpath, outputref, ['cfrg'], 1)
|
|
||||||
elif os.path.exists(cfm68kpath):
|
|
||||||
copyres(cfm68kpath, outputref, ['cfrg'], 1)
|
|
||||||
|
|
||||||
print "Fixing sys.path prefs"
|
|
||||||
Res.UseResFile(outputref)
|
|
||||||
try:
|
|
||||||
res = Res.Get1Resource('STR#', 228) # from PythonCore
|
|
||||||
except Res.Error: pass
|
|
||||||
else:
|
|
||||||
res.RemoveResource()
|
|
||||||
# setting pref file name to empty string
|
|
||||||
res = Res.Get1NamedResource('STR ', "PythonPreferenceFileName")
|
|
||||||
res.data = Pstring("")
|
|
||||||
res.ChangedResource()
|
|
||||||
syspathpref = "$(APPLICATION)"
|
|
||||||
res = Res.Resource("\000\001" + Pstring(syspathpref))
|
|
||||||
res.AddResource("STR#", 229, "sys.path preference")
|
|
||||||
|
|
||||||
print "Creating 'PYD ' resources"
|
|
||||||
for modname, (ppcfrag, cfm68kfrag) in dynamicmodules.items():
|
|
||||||
res = Res.Resource(Pstring(ppcfrag) + Pstring(cfm68kfrag))
|
|
||||||
id = 0
|
|
||||||
while id < 128:
|
|
||||||
id = Res.Unique1ID('PYD ')
|
|
||||||
res.AddResource('PYD ', id, modname)
|
|
||||||
finally:
|
|
||||||
Res.CloseResFile(outputref)
|
|
||||||
print "Merging code fragments"
|
|
||||||
cfmfile.mergecfmfiles([applettemplatepath, corepath] + dynamicfiles.keys(),
|
|
||||||
output, architecture)
|
|
||||||
|
|
||||||
print "done!"
|
|
||||||
|
|
||||||
|
|
||||||
def findfragments(module_dict, architecture):
|
|
||||||
dynamicmodules = {}
|
|
||||||
dynamicfiles = {}
|
|
||||||
extraresfiles = []
|
|
||||||
for name, module in module_dict.items():
|
|
||||||
if module.gettype() <> 'dynamic':
|
|
||||||
continue
|
|
||||||
path = resolvealiasfile(module.__file__)
|
|
||||||
dir, filename = os.path.split(path)
|
|
||||||
## ppcfile, cfm68kfile = makefilenames(filename)
|
|
||||||
ppcfile = filename
|
|
||||||
cfm68kfile = "dummy.cfm68k.slb"
|
|
||||||
|
|
||||||
# ppc stuff
|
|
||||||
ppcpath = os.path.join(dir, ppcfile)
|
|
||||||
if architecture <> 'm68k':
|
|
||||||
ppcfrag, dynamicfiles = getfragname(ppcpath, dynamicfiles)
|
|
||||||
else:
|
|
||||||
ppcfrag = "_no_fragment_"
|
|
||||||
|
|
||||||
# 68k stuff
|
|
||||||
cfm68kpath = os.path.join(dir, cfm68kfile)
|
|
||||||
if architecture <> 'pwpc':
|
|
||||||
cfm68kfrag, dynamicfiles = getfragname(cfm68kpath, dynamicfiles)
|
|
||||||
else:
|
|
||||||
cfm68kfrag = "_no_fragment_"
|
|
||||||
|
|
||||||
dynamicmodules[name] = ppcfrag, cfm68kfrag
|
|
||||||
if (ppcpath, cfm68kpath) not in extraresfiles:
|
|
||||||
extraresfiles.append((ppcpath, cfm68kpath))
|
|
||||||
return dynamicmodules, dynamicfiles, extraresfiles
|
|
||||||
|
|
||||||
|
|
||||||
def getfragname(path, dynamicfiles):
|
|
||||||
if not dynamicfiles.has_key(path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
lib = cfmfile.CfrgResource(path)
|
|
||||||
fragname = lib.fragments[0].name
|
|
||||||
else:
|
|
||||||
print "shared lib not found:", path
|
|
||||||
fragname = "_no_fragment_"
|
|
||||||
dynamicfiles[path] = fragname
|
|
||||||
else:
|
|
||||||
fragname = dynamicfiles[path]
|
|
||||||
return fragname, dynamicfiles
|
|
||||||
|
|
||||||
|
|
||||||
def addpythonmodules(module_dict):
|
|
||||||
# XXX should really use macgen_rsrc.generate(), this does the same, but skips __main__
|
|
||||||
items = module_dict.items()
|
|
||||||
items.sort()
|
|
||||||
for name, module in items:
|
|
||||||
mtype = module.gettype()
|
|
||||||
if mtype not in ['module', 'package'] or name == "__main__":
|
|
||||||
continue
|
|
||||||
location = module.__file__
|
|
||||||
|
|
||||||
if location[-4:] == '.pyc':
|
|
||||||
# Attempt corresponding .py
|
|
||||||
location = location[:-1]
|
|
||||||
if location[-3:] != '.py':
|
|
||||||
print '*** skipping', location
|
|
||||||
continue
|
|
||||||
|
|
||||||
print 'Adding module "%s"' % name
|
|
||||||
id, name = py_resource.frompyfile(location, name, preload=0,
|
|
||||||
ispackage=mtype=='package')
|
|
||||||
|
|
||||||
def Pstring(str):
|
|
||||||
if len(str) > 255:
|
|
||||||
raise TypeError, "Str255 must be at most 255 chars long"
|
|
||||||
return chr(len(str)) + str
|
|
||||||
|
|
||||||
##def makefilenames(name):
|
|
||||||
## lname = string.lower(name)
|
|
||||||
## pos = string.find(lname, ".ppc.")
|
|
||||||
## if pos > 0:
|
|
||||||
## return name, name[:pos] + '.CFM68K.' + name[pos+5:]
|
|
||||||
## pos = string.find(lname, ".cfm68k.")
|
|
||||||
## if pos > 0:
|
|
||||||
## return name[:pos] + '.ppc.' + name[pos+8:], name
|
|
||||||
## raise ValueError, "can't make ppc/cfm68k filenames"
|
|
||||||
|
|
||||||
def copyres(input, output, *args, **kwargs):
|
|
||||||
openedin = openedout = 0
|
|
||||||
if type(input) == types.StringType:
|
|
||||||
input = Res.FSpOpenResFile(input, 1)
|
|
||||||
openedin = 1
|
|
||||||
if type(output) == types.StringType:
|
|
||||||
output = Res.FSpOpenResFile(output, 3)
|
|
||||||
openedout = 1
|
|
||||||
try:
|
|
||||||
buildtools.copyres(input, output, *args, **kwargs)
|
|
||||||
finally:
|
|
||||||
if openedin:
|
|
||||||
Res.CloseResFile(input)
|
|
||||||
if openedout:
|
|
||||||
Res.CloseResFile(output)
|
|
||||||
|
|
||||||
def findpythoncore():
|
|
||||||
"""find the PythonCore shared library, possibly asking the user if we can't find it"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kSharedLibrariesFolderType, 0)
|
|
||||||
except macfs.error:
|
|
||||||
extpath = ":"
|
|
||||||
else:
|
|
||||||
extpath = macfs.FSSpec((vRefNum, dirID, "")).as_pathname()
|
|
||||||
version = string.split(sys.version)[0]
|
|
||||||
if MacOS.runtimemodel == 'carbon':
|
|
||||||
corename = "PythonCoreCarbon " + version
|
|
||||||
elif MacOS.runtimemodel == 'ppc':
|
|
||||||
corename = "PythonCore " + version
|
|
||||||
else:
|
|
||||||
raise "Unknown MacOS.runtimemodel", MacOS.runtimemodel
|
|
||||||
corepath = os.path.join(extpath, corename)
|
|
||||||
if not os.path.exists(corepath):
|
|
||||||
corepath = EasyDialogs.AskFileForOpen(message="Please locate PythonCore:",
|
|
||||||
typeList=("shlb",))
|
|
||||||
if not corepath:
|
|
||||||
raise KeyboardInterrupt, "cancelled"
|
|
||||||
return resolvealiasfile(corepath)
|
|
||||||
|
|
||||||
def resolvealiasfile(path):
|
|
||||||
try:
|
|
||||||
fss, dummy1, dummy2 = macfs.ResolveAliasFile(path)
|
|
||||||
except macfs.error:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
path = fss.as_pathname()
|
|
||||||
return path
|
|
|
@ -1,8 +0,0 @@
|
||||||
"""macgen_info - Generate informational output"""
|
|
||||||
|
|
||||||
def generate(output, module_dict):
|
|
||||||
for name in module_dict.keys():
|
|
||||||
print 'Include %-20s\t'%name,
|
|
||||||
module = module_dict[name]
|
|
||||||
print module.gettype(), '\t', repr(module)
|
|
||||||
return 0
|
|
|
@ -1,36 +0,0 @@
|
||||||
"""macgen_info - Generate PYC resource file only"""
|
|
||||||
import EasyDialogs
|
|
||||||
import py_resource
|
|
||||||
from Carbon import Res
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def generate(output, module_dict, debug=0, preload=1):
|
|
||||||
fsid = py_resource.create(output)
|
|
||||||
|
|
||||||
for name, module in module_dict.items():
|
|
||||||
mtype = module.gettype()
|
|
||||||
if mtype not in ['module', 'package']:
|
|
||||||
continue
|
|
||||||
location = module.__file__
|
|
||||||
|
|
||||||
if location[-4:] == '.pyc':
|
|
||||||
# Attempt corresponding .py
|
|
||||||
location = location[:-1]
|
|
||||||
if location[-3:] != '.py':
|
|
||||||
print '*** skipping', location
|
|
||||||
continue
|
|
||||||
|
|
||||||
id, name = py_resource.frompyfile(location, name, preload=preload,
|
|
||||||
ispackage=mtype=='package')
|
|
||||||
if debug > 0:
|
|
||||||
print 'PYC resource %5d\t%s\t%s'%(id, name, location)
|
|
||||||
|
|
||||||
Res.CloseResFile(fsid)
|
|
||||||
|
|
||||||
def warnings(module_dict):
|
|
||||||
problems = 0
|
|
||||||
for name, module in module_dict.items():
|
|
||||||
if module.gettype() not in ('builtin', 'module', 'package'):
|
|
||||||
problems = problems + 1
|
|
||||||
print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
|
|
||||||
return problems
|
|
|
@ -1,113 +0,0 @@
|
||||||
"""macgen_info - Generate CodeWarrior project, config source, resource file"""
|
|
||||||
import EasyDialogs
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import macfs
|
|
||||||
import MacOS
|
|
||||||
import macostools
|
|
||||||
import macgen_rsrc
|
|
||||||
# Note: this depends on being frozen, or on sys.path already being
|
|
||||||
# modified by macmodulefinder.
|
|
||||||
import makeconfig
|
|
||||||
|
|
||||||
TEMPLATEDIR=os.path.join(sys.prefix, ':Mac:mwerks:projects:build.macfreeze')
|
|
||||||
PROJECT_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozen.prj')
|
|
||||||
CONFIG_TEMPLATE=os.path.join(TEMPLATEDIR, ':templatefrozenconfig.c')
|
|
||||||
BUNDLE_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozenbundle.rsrc')
|
|
||||||
|
|
||||||
def generate(output, module_dict, debug=0, with_ifdef=0):
|
|
||||||
problems = 0
|
|
||||||
output_created=0
|
|
||||||
if not os.path.exists(output):
|
|
||||||
print 'Creating project folder', output
|
|
||||||
os.mkdir(output)
|
|
||||||
output_created = 1
|
|
||||||
# Resolve aliases, if needed
|
|
||||||
try:
|
|
||||||
fss, dummy1, dummy2 = macfs.ResolveAliasFile(output)
|
|
||||||
except macfs.error:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
newname = fss.as_pathname()
|
|
||||||
if newname != output:
|
|
||||||
if debug:
|
|
||||||
print 'Alias', output
|
|
||||||
print 'Resolved to', newname
|
|
||||||
output = newname
|
|
||||||
# Construct the filenames
|
|
||||||
dummy, outfile = os.path.split(output)
|
|
||||||
build, ext = os.path.splitext(outfile)
|
|
||||||
if build == 'build' and ext[0] == '.':
|
|
||||||
# This is probably a good name for the project
|
|
||||||
projname = ext[1:]
|
|
||||||
else:
|
|
||||||
projname = 'frozenapplet.prj'
|
|
||||||
config_name = os.path.join(output, ':macfrozenconfig.c')
|
|
||||||
project_name = os.path.join(output, ':' + projname + '.prj')
|
|
||||||
resource_name = os.path.join(output, ':frozenmodules.rsrc')
|
|
||||||
bundle_name = os.path.join(output, ':frozenbundle.rsrc')
|
|
||||||
|
|
||||||
# Fill the output folder, if needed.
|
|
||||||
if output_created:
|
|
||||||
# Create the project, if needed
|
|
||||||
if not os.path.exists(project_name):
|
|
||||||
print 'Creating project', project_name
|
|
||||||
if not os.path.exists(PROJECT_TEMPLATE):
|
|
||||||
print '** No template CodeWarrior project found at', PROJECT_TEMPLATE
|
|
||||||
print ' To generate standalone Python applications from source you need'
|
|
||||||
print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
|
|
||||||
print ' for details.'
|
|
||||||
problems = 1
|
|
||||||
else:
|
|
||||||
macostools.copy(PROJECT_TEMPLATE, project_name)
|
|
||||||
print 'A template CodeWarrior project has been copied to', project_name
|
|
||||||
print 'It is up to you to make the following changes:'
|
|
||||||
print '- Change the output file name'
|
|
||||||
print '- Change the search path, unless the folder is in the python home'
|
|
||||||
print '- Add sourcefiles/libraries for any extension modules used'
|
|
||||||
print '- Remove unused sources, to speed up the build process'
|
|
||||||
print '- Remove unused resource files (like tcl/tk) for a smaller binary'
|
|
||||||
problems = 1
|
|
||||||
macostools.copy(BUNDLE_TEMPLATE, bundle_name)
|
|
||||||
print 'A template bundle file has also been copied to', bundle_name
|
|
||||||
print 'You may want to adapt signature, size resource, etc'
|
|
||||||
|
|
||||||
|
|
||||||
# Create the resource file
|
|
||||||
macgen_rsrc.generate(resource_name, module_dict, debug=debug)
|
|
||||||
|
|
||||||
# Create the config.c file
|
|
||||||
if not os.path.exists(CONFIG_TEMPLATE):
|
|
||||||
print '** No template config.c found at', PROJECT_TEMPLATE
|
|
||||||
print ' To generate standalone Python applications from source you need'
|
|
||||||
print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
|
|
||||||
print ' for details.'
|
|
||||||
problems = 1
|
|
||||||
else:
|
|
||||||
# Find elegible modules (builtins and dynamically loaded modules)
|
|
||||||
c_modules = []
|
|
||||||
for module in module_dict.keys():
|
|
||||||
if module_dict[module].gettype() in ('builtin', 'dynamic'):
|
|
||||||
# if the module is in a package we have no choice but
|
|
||||||
# to put it at the toplevel in the frozen application.
|
|
||||||
if '.' in module:
|
|
||||||
module = module.split('.')[-1]
|
|
||||||
c_modules.append(module)
|
|
||||||
ifp = open(CONFIG_TEMPLATE)
|
|
||||||
ofp = open(config_name, 'w')
|
|
||||||
makeconfig.makeconfig(ifp, ofp, c_modules, with_ifdef)
|
|
||||||
ifp.close()
|
|
||||||
ofp.close()
|
|
||||||
MacOS.SetCreatorAndType(config_name, 'CWIE', 'TEXT')
|
|
||||||
|
|
||||||
if warnings(module_dict):
|
|
||||||
problems = 1
|
|
||||||
return problems
|
|
||||||
|
|
||||||
def warnings(module_dict):
|
|
||||||
problems = 0
|
|
||||||
for name, module in module_dict.items():
|
|
||||||
if module.gettype() not in ('builtin', 'module', 'dynamic', 'package'):
|
|
||||||
problems = problems + 1
|
|
||||||
print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
|
|
||||||
return problems
|
|
|
@ -1,8 +0,0 @@
|
||||||
"""macgenerate - Generate the out for macfreeze"""
|
|
||||||
|
|
||||||
def generate(program, module_dict):
|
|
||||||
for name in module_dict.keys():
|
|
||||||
print 'Include %-20s\t'%name,
|
|
||||||
module = module_dict[name]
|
|
||||||
print module.gettype(), '\t', repr(module)
|
|
||||||
return 0
|
|
|
@ -1,112 +0,0 @@
|
||||||
"""macmodulefinder - Find modules used in a script. Only slightly
|
|
||||||
mac-specific, really."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
import directives
|
|
||||||
|
|
||||||
try:
|
|
||||||
# This will work if we are frozen ourselves
|
|
||||||
import modulefinder
|
|
||||||
except ImportError:
|
|
||||||
# And this will work otherwise
|
|
||||||
_FREEZEDIR=os.path.join(sys.prefix, ':Tools:freeze')
|
|
||||||
sys.path.insert(0, _FREEZEDIR)
|
|
||||||
import modulefinder
|
|
||||||
|
|
||||||
#
|
|
||||||
# Modules that must be included, and modules that need not be included
|
|
||||||
# (but are if they are found)
|
|
||||||
#
|
|
||||||
MAC_INCLUDE_MODULES=['site']
|
|
||||||
MAC_MAYMISS_MODULES=['posix', 'os2', 'nt', 'ntpath', 'dos', 'dospath',
|
|
||||||
'win32api', 'ce', '_winreg',
|
|
||||||
'nturl2path', 'pwd', 'sitecustomize',
|
|
||||||
'org.python.core',
|
|
||||||
'riscos', 'riscosenviron', 'riscospath'
|
|
||||||
]
|
|
||||||
|
|
||||||
# An exception:
|
|
||||||
Missing="macmodulefinder.Missing"
|
|
||||||
|
|
||||||
class Module(modulefinder.Module):
|
|
||||||
|
|
||||||
def gettype(self):
|
|
||||||
"""Return type of module"""
|
|
||||||
if self.__path__:
|
|
||||||
return 'package'
|
|
||||||
if self.__code__:
|
|
||||||
return 'module'
|
|
||||||
if self.__file__:
|
|
||||||
return 'dynamic'
|
|
||||||
return 'builtin'
|
|
||||||
|
|
||||||
class ModuleFinder(modulefinder.ModuleFinder):
|
|
||||||
|
|
||||||
def add_module(self, fqname):
|
|
||||||
if self.modules.has_key(fqname):
|
|
||||||
return self.modules[fqname]
|
|
||||||
self.modules[fqname] = m = Module(fqname)
|
|
||||||
return m
|
|
||||||
|
|
||||||
def process(program, modules=None, module_files=None, debug=0):
|
|
||||||
if modules is None:
|
|
||||||
modules = []
|
|
||||||
if module_files is None:
|
|
||||||
module_files = []
|
|
||||||
missing = []
|
|
||||||
#
|
|
||||||
# Add the standard modules needed for startup
|
|
||||||
#
|
|
||||||
modules = modules + MAC_INCLUDE_MODULES
|
|
||||||
#
|
|
||||||
# search the main source for directives
|
|
||||||
#
|
|
||||||
extra_modules, exclude_modules, optional_modules, extra_path = \
|
|
||||||
directives.findfreezedirectives(program)
|
|
||||||
for m in extra_modules:
|
|
||||||
if os.sep in m:
|
|
||||||
# It is a file
|
|
||||||
module_files.append(m)
|
|
||||||
else:
|
|
||||||
modules.append(m)
|
|
||||||
# collect all modules of the program
|
|
||||||
path = sys.path[:]
|
|
||||||
dir = os.path.dirname(program)
|
|
||||||
path[0] = dir # "current dir"
|
|
||||||
path = extra_path + path
|
|
||||||
#
|
|
||||||
# Create the module finder and let it do its work
|
|
||||||
#
|
|
||||||
modfinder = ModuleFinder(path,
|
|
||||||
excludes=exclude_modules, debug=debug)
|
|
||||||
for m in modules:
|
|
||||||
modfinder.import_hook(m)
|
|
||||||
for m in module_files:
|
|
||||||
modfinder.load_file(m)
|
|
||||||
modfinder.run_script(program)
|
|
||||||
module_dict = modfinder.modules
|
|
||||||
#
|
|
||||||
# Tell the user about missing modules
|
|
||||||
#
|
|
||||||
maymiss = exclude_modules + optional_modules + MAC_MAYMISS_MODULES
|
|
||||||
for m in modfinder.badmodules.keys():
|
|
||||||
if not m in maymiss:
|
|
||||||
if debug > 0:
|
|
||||||
print 'Missing', m
|
|
||||||
missing.append(m)
|
|
||||||
#
|
|
||||||
# Warn the user about unused builtins
|
|
||||||
#
|
|
||||||
for m in sys.builtin_module_names:
|
|
||||||
if m in ('__main__', '__builtin__'):
|
|
||||||
pass
|
|
||||||
elif not module_dict.has_key(m):
|
|
||||||
if debug > 0:
|
|
||||||
print 'Unused', m
|
|
||||||
elif module_dict[m].gettype() != 'builtin':
|
|
||||||
# XXXX Can this happen?
|
|
||||||
if debug > 0:
|
|
||||||
print 'Conflict', m
|
|
||||||
return module_dict, missing
|
|
|
@ -1,301 +0,0 @@
|
||||||
/* DNR.c - DNR library for MPW
|
|
||||||
|
|
||||||
(c) Copyright 1988 by Apple Computer. All rights reserved
|
|
||||||
|
|
||||||
Modifications by Jim Matthews, Dartmouth College, 5/91
|
|
||||||
Again modified for use with python by Jack Jansen, CWI, October 1994.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Traps.h>
|
|
||||||
#include <OSUtils.h>
|
|
||||||
#include <Errors.h>
|
|
||||||
#include <Files.h>
|
|
||||||
#include <Resources.h>
|
|
||||||
#include <Memory.h>
|
|
||||||
#include <Traps.h>
|
|
||||||
#include <GestaltEqu.h>
|
|
||||||
#include <Folders.h>
|
|
||||||
#include <ToolUtils.h>
|
|
||||||
#include <MacTCPCommonTypes.h>
|
|
||||||
#include "AddressXlation.h"
|
|
||||||
|
|
||||||
TrapType GetTrapType(unsigned long theTrap);
|
|
||||||
Boolean TrapAvailable(unsigned long trap);
|
|
||||||
void GetSystemFolder(short *vRefNumP, long *dirIDP);
|
|
||||||
void GetCPanelFolder(short *vRefNumP, long *dirIDP);
|
|
||||||
short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID);
|
|
||||||
short OpenOurRF(void);
|
|
||||||
|
|
||||||
#define OPENRESOLVER 1L
|
|
||||||
#define CLOSERESOLVER 2L
|
|
||||||
#define STRTOADDR 3L
|
|
||||||
#define ADDRTOSTR 4L
|
|
||||||
#define ENUMCACHE 5L
|
|
||||||
#define ADDRTONAME 6L
|
|
||||||
#define HINFO 7L
|
|
||||||
#define MXINFO 8L
|
|
||||||
|
|
||||||
Handle codeHndl = nil;
|
|
||||||
|
|
||||||
OSErrProcPtr dnr = nil;
|
|
||||||
|
|
||||||
TrapType GetTrapType(theTrap)
|
|
||||||
unsigned long theTrap;
|
|
||||||
{
|
|
||||||
if (BitAnd(theTrap, 0x0800) > 0)
|
|
||||||
return(ToolTrap);
|
|
||||||
else
|
|
||||||
return(OSTrap);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boolean TrapAvailable(trap)
|
|
||||||
unsigned long trap;
|
|
||||||
{
|
|
||||||
TrapType trapType = ToolTrap;
|
|
||||||
unsigned long numToolBoxTraps;
|
|
||||||
|
|
||||||
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
|
|
||||||
numToolBoxTraps = 0x200;
|
|
||||||
else
|
|
||||||
numToolBoxTraps = 0x400;
|
|
||||||
|
|
||||||
trapType = GetTrapType(trap);
|
|
||||||
if (trapType == ToolTrap) {
|
|
||||||
trap = BitAnd(trap, 0x07FF);
|
|
||||||
if (trap >= numToolBoxTraps)
|
|
||||||
trap = _Unimplemented;
|
|
||||||
}
|
|
||||||
return(NGetTrapAddress(trap, trapType) != NGetTrapAddress(_Unimplemented, ToolTrap));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetSystemFolder(short *vRefNumP, long *dirIDP)
|
|
||||||
{
|
|
||||||
SysEnvRec info;
|
|
||||||
long wdProcID;
|
|
||||||
|
|
||||||
SysEnvirons(1, &info);
|
|
||||||
if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) {
|
|
||||||
*vRefNumP = 0;
|
|
||||||
*dirIDP = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetCPanelFolder(short *vRefNumP, long *dirIDP)
|
|
||||||
{
|
|
||||||
Boolean hasFolderMgr = false;
|
|
||||||
long feature;
|
|
||||||
|
|
||||||
if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
|
|
||||||
if (!hasFolderMgr) {
|
|
||||||
GetSystemFolder(vRefNumP, dirIDP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) {
|
|
||||||
*vRefNumP = 0;
|
|
||||||
*dirIDP = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SearchFolderForDNRP is called to search a folder for files that might
|
|
||||||
contain the 'dnrp' resource */
|
|
||||||
short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID)
|
|
||||||
{
|
|
||||||
HParamBlockRec fi;
|
|
||||||
Str255 filename;
|
|
||||||
short refnum;
|
|
||||||
|
|
||||||
fi.fileParam.ioCompletion = nil;
|
|
||||||
fi.fileParam.ioNamePtr = filename;
|
|
||||||
fi.fileParam.ioVRefNum = vRefNum;
|
|
||||||
fi.fileParam.ioDirID = dirID;
|
|
||||||
fi.fileParam.ioFDirIndex = 1;
|
|
||||||
|
|
||||||
while (PBHGetFInfo(&fi, false) == noErr) {
|
|
||||||
/* scan system folder for driver resource files of specific type & creator */
|
|
||||||
if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
|
|
||||||
fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) {
|
|
||||||
/* found the MacTCP driver file? */
|
|
||||||
refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
|
|
||||||
if (GetIndResource('dnrp', 1) == NULL)
|
|
||||||
CloseResFile(refnum);
|
|
||||||
else
|
|
||||||
return refnum;
|
|
||||||
}
|
|
||||||
/* check next file in system folder */
|
|
||||||
fi.fileParam.ioFDirIndex++;
|
|
||||||
fi.fileParam.ioDirID = dirID; /* PBHGetFInfo() clobbers ioDirID */
|
|
||||||
}
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OpenOurRF is called to open the MacTCP driver resources */
|
|
||||||
|
|
||||||
short OpenOurRF()
|
|
||||||
{
|
|
||||||
short refnum;
|
|
||||||
short vRefNum;
|
|
||||||
long dirID;
|
|
||||||
|
|
||||||
/* first search Control Panels for MacTCP 1.1 */
|
|
||||||
GetCPanelFolder(&vRefNum, &dirID);
|
|
||||||
refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
|
|
||||||
if (refnum != -1) return(refnum);
|
|
||||||
|
|
||||||
/* next search System Folder for MacTCP 1.0.x */
|
|
||||||
GetSystemFolder(&vRefNum, &dirID);
|
|
||||||
refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
|
|
||||||
if (refnum != -1) return(refnum);
|
|
||||||
|
|
||||||
/* finally, search Control Panels for MacTCP 1.0.x */
|
|
||||||
GetCPanelFolder(&vRefNum, &dirID);
|
|
||||||
refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
|
|
||||||
if (refnum != -1) return(refnum);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSErr OpenResolver(fileName)
|
|
||||||
char *fileName;
|
|
||||||
{
|
|
||||||
short refnum;
|
|
||||||
OSErr rc;
|
|
||||||
|
|
||||||
if (dnr != nil)
|
|
||||||
/* resolver already loaded in */
|
|
||||||
return(noErr);
|
|
||||||
|
|
||||||
/* open the MacTCP driver to get DNR resources. Search for it based on
|
|
||||||
creator & type rather than simply file name */
|
|
||||||
refnum = OpenOurRF();
|
|
||||||
|
|
||||||
/* ignore failures since the resource may have been installed in the
|
|
||||||
System file if running on a Mac 512Ke */
|
|
||||||
|
|
||||||
/* load in the DNR resource package */
|
|
||||||
codeHndl = GetIndResource('dnrp', 1);
|
|
||||||
if (codeHndl == nil) {
|
|
||||||
/* can't open DNR */
|
|
||||||
return(ResError());
|
|
||||||
}
|
|
||||||
|
|
||||||
DetachResource(codeHndl);
|
|
||||||
if (refnum != -1) {
|
|
||||||
CloseWD(refnum);
|
|
||||||
CloseResFile(refnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lock the DNR resource since it cannot be reloated while opened */
|
|
||||||
HLock(codeHndl);
|
|
||||||
dnr = (OSErrProcPtr) *codeHndl;
|
|
||||||
|
|
||||||
/* call open resolver */
|
|
||||||
rc = (*dnr)(OPENRESOLVER, fileName);
|
|
||||||
if (rc != noErr) {
|
|
||||||
/* problem with open resolver, flush it */
|
|
||||||
HUnlock(codeHndl);
|
|
||||||
DisposHandle(codeHndl);
|
|
||||||
dnr = nil;
|
|
||||||
}
|
|
||||||
return(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSErr CloseResolver()
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
/* call close resolver */
|
|
||||||
(void) (*dnr)(CLOSERESOLVER);
|
|
||||||
|
|
||||||
/* release the DNR resource package */
|
|
||||||
HUnlock(codeHndl);
|
|
||||||
DisposHandle(codeHndl);
|
|
||||||
dnr = nil;
|
|
||||||
return(noErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr)
|
|
||||||
char *hostName;
|
|
||||||
struct hostInfo *rtnStruct;
|
|
||||||
ResultProcPtr resultproc;
|
|
||||||
char *userDataPtr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
return((*dnr)(STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr AddrToStr(addr, addrStr)
|
|
||||||
unsigned long addr;
|
|
||||||
char *addrStr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
(*dnr)(ADDRTOSTR, addr, addrStr);
|
|
||||||
return(noErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr EnumCache(resultproc, userDataPtr)
|
|
||||||
EnumResultProcPtr resultproc;
|
|
||||||
char *userDataPtr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
return((*dnr)(ENUMCACHE, resultproc, userDataPtr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr)
|
|
||||||
unsigned long addr;
|
|
||||||
struct hostInfo *rtnStruct;
|
|
||||||
ResultProcPtr resultproc;
|
|
||||||
char *userDataPtr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
return((*dnr)(ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern OSErr HInfo(hostName, returnRecPtr, resultProc, userDataPtr)
|
|
||||||
char *hostName;
|
|
||||||
struct returnRec *returnRecPtr;
|
|
||||||
ResultProc2Ptr resultProc;
|
|
||||||
char *userDataPtr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
return((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern OSErr MXInfo(hostName, returnRecPtr, resultProc, userDataPtr)
|
|
||||||
char *hostName;
|
|
||||||
struct returnRec *returnRecPtr;
|
|
||||||
ResultProc2Ptr resultProc;
|
|
||||||
char *userDataPtr;
|
|
||||||
{
|
|
||||||
if (dnr == nil)
|
|
||||||
/* resolver not loaded error */
|
|
||||||
return(notOpenErr);
|
|
||||||
|
|
||||||
return((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
WASTE Demo Project:
|
|
||||||
Sample WASTE Object Handlers
|
|
||||||
|
|
||||||
Copyright © 1993-1998 Marco Piovanelli
|
|
||||||
All Rights Reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WEObjectHandlers.h"
|
|
||||||
|
|
||||||
#ifndef __ICONS__
|
|
||||||
#include <Icons.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __SOUND__
|
|
||||||
#include <Sound.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PICTURES */
|
|
||||||
|
|
||||||
pascal OSErr HandleNewPicture(Point *defaultObjectSize, WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
PicHandle thePicture;
|
|
||||||
Rect frame;
|
|
||||||
|
|
||||||
/* get handle to object data (in this case, a picture handle) */
|
|
||||||
thePicture = (PicHandle) WEGetObjectDataHandle(objectRef);
|
|
||||||
|
|
||||||
/* figure out the default object size by looking at the picFrame record */
|
|
||||||
frame = (*thePicture)->picFrame;
|
|
||||||
OffsetRect(&frame, -frame.left, -frame.top);
|
|
||||||
defaultObjectSize->v = frame.bottom;
|
|
||||||
defaultObjectSize->h = frame.right;
|
|
||||||
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal OSErr HandleDisposePicture(WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
PicHandle thePicture;
|
|
||||||
|
|
||||||
/* get handle to object data (in this case, a picture handle) */
|
|
||||||
thePicture = (PicHandle) WEGetObjectDataHandle(objectRef);
|
|
||||||
|
|
||||||
/* kill the picture */
|
|
||||||
KillPicture(thePicture);
|
|
||||||
|
|
||||||
return MemError();
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal OSErr HandleDrawPicture(const Rect *destRect, WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
PicHandle thePicture;
|
|
||||||
|
|
||||||
/* get handle to object data (in this case, a picture handle) */
|
|
||||||
thePicture = (PicHandle) WEGetObjectDataHandle(objectRef);
|
|
||||||
|
|
||||||
/* draw the picture */
|
|
||||||
DrawPicture(thePicture, destRect);
|
|
||||||
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* SOUND */
|
|
||||||
|
|
||||||
pascal OSErr HandleNewSound(Point *defaultObjectSize, WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
#pragma unused(objectRef)
|
|
||||||
|
|
||||||
/* sounds are drawn as standard 32x32 icons */
|
|
||||||
defaultObjectSize->v = 32;
|
|
||||||
defaultObjectSize->h = 32;
|
|
||||||
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal OSErr HandleDrawSound(const Rect *destRect, WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
#pragma unused(objectRef)
|
|
||||||
|
|
||||||
/* draw the sound icon */
|
|
||||||
return PlotIconID(destRect, kAlignNone, kTransformNone, kSoundIconID);
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal Boolean HandleClickSound(Point hitPt, EventModifiers modifiers,
|
|
||||||
UInt32 clickTime, WEObjectReference objectRef)
|
|
||||||
{
|
|
||||||
#pragma unused(hitPt, clickTime)
|
|
||||||
|
|
||||||
SndListHandle theSound;
|
|
||||||
|
|
||||||
/* WASTE sets the low bit of modifiers on double (multiple) clicks */
|
|
||||||
if (modifiers & 0x0001)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* get a handle to the object data (in this case, a sound handle) */
|
|
||||||
theSound = (SndListHandle) WEGetObjectDataHandle(objectRef);
|
|
||||||
|
|
||||||
/* play the sound */
|
|
||||||
SndPlay(nil, theSound, false);
|
|
||||||
|
|
||||||
/* return TRUE so WASTE knows we handled the click */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* not a double click: let WASTE handle the mouse-down */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
WASTE Demo Project:
|
|
||||||
Sample WASTE Object Handlers
|
|
||||||
|
|
||||||
Copyright © 1993-1998 Marco Piovanelli
|
|
||||||
All Rights Reserved
|
|
||||||
*/
|
|
||||||
#ifndef WITHOUT_FRAMEWORKS
|
|
||||||
#include <Carbon/Carbon.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _WASTE_
|
|
||||||
#include "WASTE.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// PICTURES
|
|
||||||
|
|
||||||
pascal OSErr HandleNewPicture(Point *defaultObjectSize, WEObjectReference objectRef);
|
|
||||||
pascal OSErr HandleDisposePicture(WEObjectReference objectRef);
|
|
||||||
pascal OSErr HandleDrawPicture(const Rect *destRect, WEObjectReference objectRef);
|
|
||||||
|
|
||||||
// SOUNDS
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kSoundIconID = 550
|
|
||||||
};
|
|
||||||
|
|
||||||
pascal OSErr HandleNewSound(Point *defaultObjectSize, WEObjectReference objectRef);
|
|
||||||
pascal OSErr HandleDrawSound(const Rect *destRect, WEObjectReference objectRef);
|
|
||||||
pascal Boolean HandleClickSound(Point hitPt, EventModifiers modifiers,
|
|
||||||
UInt32 clickTime, WEObjectReference objectRef);
|
|
|
@ -1,281 +0,0 @@
|
||||||
/*
|
|
||||||
* WETabHooks.c
|
|
||||||
*
|
|
||||||
* WASTE TABS PACKAGE
|
|
||||||
* Hooks for adding tab support to WASTE
|
|
||||||
*
|
|
||||||
* Written by:
|
|
||||||
* Mark Alldritt (original code)
|
|
||||||
* Dan Crevier (line breaks)
|
|
||||||
* John Daub (maintenance)
|
|
||||||
* Jonathan Kew (variable-width tabs)
|
|
||||||
* Marco Piovanelli (?)
|
|
||||||
* Bert Seltzer (horizontal scrolling)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WETabs.h"
|
|
||||||
#include "WETabHooks.h"
|
|
||||||
|
|
||||||
#define FIXROUND(f) ((SInt16) (((f) + 0x00008000) >> 16))
|
|
||||||
#define BSL(A, B) (((SInt32) (A)) << (B))
|
|
||||||
|
|
||||||
static const Point kOneToOneScaling = { 1, 1 } ;
|
|
||||||
|
|
||||||
pascal void _WETabDrawText
|
|
||||||
(
|
|
||||||
const char * pText,
|
|
||||||
SInt32 textLength,
|
|
||||||
Fixed slop,
|
|
||||||
JustStyleCode styleRunPosition,
|
|
||||||
WEReference we
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#pragma unused ( slop, styleRunPosition )
|
|
||||||
|
|
||||||
LongRect destRect;
|
|
||||||
SInt32 beginChar = 0;
|
|
||||||
SInt32 ii;
|
|
||||||
SInt16 tabWidth;
|
|
||||||
SInt16 destLeft;
|
|
||||||
Point penPos;
|
|
||||||
SInt16 tabSize = WEGetTabSize(we);
|
|
||||||
|
|
||||||
WEGetDestRect(&destRect, we);
|
|
||||||
destLeft = (SInt16) destRect.left;
|
|
||||||
|
|
||||||
for ( ii = 0; ii < textLength; ii++ )
|
|
||||||
{
|
|
||||||
if (pText[ii] == '\t')
|
|
||||||
{
|
|
||||||
DrawText(pText, beginChar, ii - beginChar);
|
|
||||||
|
|
||||||
/* advance the pen to the next tab stop */
|
|
||||||
GetPen(&penPos);
|
|
||||||
tabWidth = tabSize - (penPos.h - destLeft) % tabSize;
|
|
||||||
MoveTo(penPos.h + tabWidth, penPos.v);
|
|
||||||
beginChar = ii + 1;
|
|
||||||
}
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
DrawText(pText, beginChar, textLength - beginChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal SInt32 _WETabPixelToChar
|
|
||||||
(
|
|
||||||
const char * pText,
|
|
||||||
SInt32 textLength,
|
|
||||||
Fixed slop,
|
|
||||||
Fixed *width,
|
|
||||||
WEEdge *edge,
|
|
||||||
JustStyleCode styleRunPosition,
|
|
||||||
Fixed hPos,
|
|
||||||
WEReference we
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SInt32 beginChar = 0;
|
|
||||||
SInt32 offset = 0;
|
|
||||||
SInt32 ii;
|
|
||||||
Fixed lastWidth;
|
|
||||||
Fixed tabWidth;
|
|
||||||
SInt16 tabSize = WEGetTabSize(we);
|
|
||||||
|
|
||||||
/* loop through every character in the segment looking for tabs */
|
|
||||||
for ( ii = 0; ii < textLength; ii++ )
|
|
||||||
{
|
|
||||||
/* exit now if width has gone negative */
|
|
||||||
/* (i.e., if we have found which glyph was hit) */
|
|
||||||
if (*width <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tab found? */
|
|
||||||
if (pText[ii] == '\t')
|
|
||||||
{
|
|
||||||
/* calculate the width of the sub-segment preceding the tab */
|
|
||||||
lastWidth = *width;
|
|
||||||
offset += PixelToChar((char *)pText + beginChar, ii - beginChar, slop,
|
|
||||||
lastWidth, (Boolean *) edge, width, styleRunPosition,
|
|
||||||
kOneToOneScaling, kOneToOneScaling);
|
|
||||||
beginChar = ii + 1;
|
|
||||||
|
|
||||||
/* hit point past sub-segment? */
|
|
||||||
if (*width >= 0)
|
|
||||||
{
|
|
||||||
/* increment hPos by width of sub-segment preceding the tab */
|
|
||||||
hPos += (lastWidth - *width);
|
|
||||||
|
|
||||||
/* calculate the width of the tab "glyph" (as a Fixed value) */
|
|
||||||
tabWidth = BSL(tabSize - FIXROUND(hPos) % tabSize, 16);
|
|
||||||
|
|
||||||
/* increment hPos by width of tab character */
|
|
||||||
hPos += tabWidth;
|
|
||||||
|
|
||||||
/* hit point within tab glyph? */
|
|
||||||
if (*width < tabWidth)
|
|
||||||
{
|
|
||||||
/* yes: determine which half of tab glyph was hit */
|
|
||||||
if (*width > (tabWidth >> 1))
|
|
||||||
{
|
|
||||||
*edge = kTrailingEdge; /* second (trailing) edge of tab */
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*edge = kLeadingEdge; /* first (leading) edge of tab */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returning -1 (as Fixed) in width means we're finished */
|
|
||||||
*width = 0xFFFF0000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* hit point is past tab: keep looping */
|
|
||||||
offset++;
|
|
||||||
*width -= tabWidth;
|
|
||||||
}
|
|
||||||
} /* if (*width >= 0) */
|
|
||||||
} /* if tab found */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* no more tabs in this segment: process the last sub-segment */
|
|
||||||
if (*width >= 0)
|
|
||||||
{
|
|
||||||
lastWidth = *width;
|
|
||||||
offset += PixelToChar((char *)pText + beginChar, textLength - beginChar, slop,
|
|
||||||
lastWidth, (Boolean *) edge, width, styleRunPosition,
|
|
||||||
kOneToOneScaling, kOneToOneScaling);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* round width to nearest integer value */
|
|
||||||
/* this is supposed to fix an incompatibility with the WorldScript Power Adapter */
|
|
||||||
*width = (*width + 0x00008000) & 0xFFFF0000;
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal SInt16 _WETabCharToPixel
|
|
||||||
(
|
|
||||||
const char * pText,
|
|
||||||
SInt32 textLength,
|
|
||||||
Fixed slop,
|
|
||||||
SInt32 offset,
|
|
||||||
SInt16 direction,
|
|
||||||
JustStyleCode styleRunPosition,
|
|
||||||
SInt16 hPos,
|
|
||||||
WEReference we
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LongRect destRect;
|
|
||||||
SInt32 beginChar = 0;
|
|
||||||
SInt32 ii;
|
|
||||||
SInt16 width;
|
|
||||||
SInt16 destLeft;
|
|
||||||
SInt16 totalWidth = 0;
|
|
||||||
SInt16 tabSize = WEGetTabSize(we);
|
|
||||||
|
|
||||||
WEGetDestRect(&destRect, we);
|
|
||||||
destLeft = (SInt16) destRect.left;
|
|
||||||
|
|
||||||
/* measure text up to offset, if offset is within this segment,
|
|
||||||
otherwise to textLength */
|
|
||||||
if (offset > textLength)
|
|
||||||
{
|
|
||||||
offset = textLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( ii = 0; ii < offset; ii++ )
|
|
||||||
{
|
|
||||||
if (pText[ii] == '\t')
|
|
||||||
{
|
|
||||||
/* calculate the pixel width of the subsegment preceding the tab */
|
|
||||||
width = TextWidth(pText, beginChar, ii - beginChar);
|
|
||||||
totalWidth += width;
|
|
||||||
hPos += width;
|
|
||||||
|
|
||||||
/* calculate tab width */
|
|
||||||
width = tabSize - (hPos - destLeft) % tabSize;
|
|
||||||
totalWidth += width;
|
|
||||||
hPos += width;
|
|
||||||
|
|
||||||
/* go to next subsegment */
|
|
||||||
beginChar = ii + 1;
|
|
||||||
}
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* calculate width of remaining characters */
|
|
||||||
width = CharToPixel((char *)pText + beginChar, textLength - beginChar, slop,
|
|
||||||
offset - beginChar, direction, styleRunPosition,
|
|
||||||
kOneToOneScaling, kOneToOneScaling);
|
|
||||||
totalWidth += width;
|
|
||||||
|
|
||||||
return totalWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal StyledLineBreakCode _WETabLineBreak
|
|
||||||
(
|
|
||||||
const char * pText,
|
|
||||||
SInt32 textLength,
|
|
||||||
SInt32 textStart,
|
|
||||||
SInt32 textEnd,
|
|
||||||
Fixed *textWidth,
|
|
||||||
SInt32 *textOffset,
|
|
||||||
WEReference we
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LongRect destRect;
|
|
||||||
SInt32 beginChar = textStart;
|
|
||||||
SInt32 ii;
|
|
||||||
Fixed tabWidth;
|
|
||||||
SInt16 destWidth;
|
|
||||||
StyledLineBreakCode breakCode = smBreakOverflow;
|
|
||||||
SInt16 tabSize = WEGetTabSize(we);
|
|
||||||
|
|
||||||
WEGetDestRect(&destRect, we);
|
|
||||||
destWidth = (SInt16) (destRect.right - destRect.left);
|
|
||||||
|
|
||||||
for ( ii = textStart; ii < textEnd; ii++ )
|
|
||||||
{
|
|
||||||
if (pText[ii] == 0x0D)
|
|
||||||
{
|
|
||||||
/* found a <return>, so stop looking ahead for tabs */
|
|
||||||
ii++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (pText[ii] == '\t')
|
|
||||||
{
|
|
||||||
/* do previous "segment" */
|
|
||||||
breakCode = StyledLineBreak((char *)pText, textLength, beginChar, ii, 0, textWidth, textOffset);
|
|
||||||
if ((breakCode != smBreakOverflow) || (ii >= textLength))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
beginChar = ii + 1;
|
|
||||||
|
|
||||||
/* calculate tab width (as a Fixed value) */
|
|
||||||
tabWidth = BSL(tabSize - (destWidth - FIXROUND(*textWidth)) % tabSize, 16);
|
|
||||||
|
|
||||||
/* if tabWidth > pixelWidth we break in tab */
|
|
||||||
/* don't move tab to next line */
|
|
||||||
if (tabWidth > *textWidth)
|
|
||||||
{
|
|
||||||
breakCode = smBreakWord;
|
|
||||||
*textOffset = ii + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*textWidth -= tabWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* do last sub-segment */
|
|
||||||
if ((ii - beginChar >= 0) && (breakCode == smBreakOverflow))
|
|
||||||
{
|
|
||||||
breakCode = StyledLineBreak((char *)pText, textLength, beginChar, ii, 0, textWidth, textOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return breakCode;
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* WETabHooks.h
|
|
||||||
*
|
|
||||||
* WASTE TABS PACKAGE
|
|
||||||
* Private (internal) interface
|
|
||||||
*
|
|
||||||
* Copyright (c) 1993-1998 Marco Piovanelli
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef WITHOUT_FRAMEWORKS
|
|
||||||
#include <Carbon/Carbon.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _WASTE_
|
|
||||||
#include "WASTE.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kTabSizeTag = 'tbsz'
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pascal void _WETabDrawText(const char *, SInt32, Fixed, JustStyleCode, WEReference);
|
|
||||||
pascal SInt32 _WETabPixelToChar(const char *, SInt32, Fixed, Fixed *, WEEdge *, JustStyleCode, Fixed, WEReference);
|
|
||||||
pascal SInt16 _WETabCharToPixel(const char *, SInt32, Fixed, SInt32, SInt16, JustStyleCode, SInt16, WEReference);
|
|
||||||
pascal StyledLineBreakCode _WETabLineBreak(const char *, SInt32, SInt32, SInt32, Fixed *, SInt32 *, WEReference);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* WETabs.c
|
|
||||||
*
|
|
||||||
* WASTE TABS PACKAGE
|
|
||||||
* Routines for installing/removing tab hooks; accessors
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "WETabs.h"
|
|
||||||
#include "WETabHooks.h"
|
|
||||||
|
|
||||||
#if !defined(__ERRORS__) && defined(WITHOUT_FRAMEWORKS)
|
|
||||||
#include <Errors.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* static UPP's */
|
|
||||||
static WEDrawTextUPP _weTabDrawTextProc = nil;
|
|
||||||
static WEPixelToCharUPP _weTabPixelToCharProc = nil;
|
|
||||||
static WECharToPixelUPP _weTabCharToPixelProc = nil;
|
|
||||||
static WELineBreakUPP _weTabLineBreakProc = nil;
|
|
||||||
|
|
||||||
pascal OSErr WEInstallTabHooks(WEReference we)
|
|
||||||
{
|
|
||||||
OSErr err;
|
|
||||||
|
|
||||||
/* if first time, create routine descriptors */
|
|
||||||
if (_weTabDrawTextProc == nil)
|
|
||||||
{
|
|
||||||
_weTabDrawTextProc = NewWEDrawTextProc(_WETabDrawText);
|
|
||||||
_weTabPixelToCharProc = NewWEPixelToCharProc(_WETabPixelToChar);
|
|
||||||
_weTabCharToPixelProc = NewWECharToPixelProc(_WETabCharToPixel);
|
|
||||||
_weTabLineBreakProc = NewWELineBreakProc(_WETabLineBreak);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = WESetInfo( weDrawTextHook, &_weTabDrawTextProc, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( wePixelToCharHook, &_weTabPixelToCharProc, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( weCharToPixelHook, &_weTabCharToPixelProc, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( weLineBreakHook, &_weTabLineBreakProc, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal OSErr WERemoveTabHooks(WEReference we)
|
|
||||||
{
|
|
||||||
UniversalProcPtr nullHook = nil;
|
|
||||||
OSErr err;
|
|
||||||
|
|
||||||
if ((err = WESetInfo( weDrawTextHook, &nullHook, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( wePixelToCharHook, &nullHook, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( weCharToPixelHook, &nullHook, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ((err = WESetInfo( weLineBreakHook, &nullHook, we )) != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal Boolean WEIsTabHooks(WEReference we)
|
|
||||||
{
|
|
||||||
WEPixelToCharUPP hook = nil;
|
|
||||||
|
|
||||||
/* return true if our tab hooks are installed */
|
|
||||||
|
|
||||||
return ( _weTabPixelToCharProc != nil ) &&
|
|
||||||
( WEGetInfo( wePixelToCharHook, &hook, we ) == noErr) &&
|
|
||||||
( _weTabPixelToCharProc == hook );
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal SInt16 WEGetTabSize(WEReference we)
|
|
||||||
{
|
|
||||||
SInt32 result;
|
|
||||||
|
|
||||||
if (WEGetUserInfo( kTabSizeTag, &result, we ) != noErr)
|
|
||||||
{
|
|
||||||
result = kDefaultTabSize;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
pascal OSErr WESetTabSize(SInt16 tabSize, WEReference we)
|
|
||||||
{
|
|
||||||
// make sure tabSize is a reasonable size
|
|
||||||
if ((tabSize < kMinTabSize) || (tabSize > kMaxTabSize))
|
|
||||||
{
|
|
||||||
return paramErr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return WESetUserInfo( kTabSizeTag, tabSize, we );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* WETabs.h
|
|
||||||
*
|
|
||||||
* WASTE TABS PACKAGE
|
|
||||||
* Public C/C++ interface
|
|
||||||
*
|
|
||||||
* version 1.3.2 (August 1996)
|
|
||||||
*
|
|
||||||
* Copyright (c) 1993-1998 Marco Piovanelli
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef WITHOUT_FRAMEWORKS
|
|
||||||
#include <Carbon/Carbon.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _WASTE_
|
|
||||||
#include "WASTE.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kMinTabSize = 1, // must be greater than zero
|
|
||||||
kDefaultTabSize = 32,
|
|
||||||
kMaxTabSize = 1024 // arbitrary value
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pascal OSErr WEInstallTabHooks(WEReference we);
|
|
||||||
pascal OSErr WERemoveTabHooks(WEReference we);
|
|
||||||
pascal Boolean WEIsTabHooks(WEReference we);
|
|
||||||
pascal SInt16 WEGetTabSize(WEReference we);
|
|
||||||
pascal OSErr WESetTabSize(SInt16 tabWidth, WEReference we);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,11 +0,0 @@
|
||||||
These files were in the Waste 1.3 distribution, but they are missing from the
|
|
||||||
Waste 2.0 distribution. At least: from the 2.0 distribution as included with
|
|
||||||
MetroWerks CodeWarrior. As the Python Waste module needs them I have included them
|
|
||||||
here. There were a few minor changes (in function signatures) to accomodate
|
|
||||||
slight changes in the Waste 2.0 headers.
|
|
||||||
|
|
||||||
All the copyright notices in the files and in Waste 1.3 seem to indicate that it
|
|
||||||
is fine to redistribute these files. If I am mistaken in this please let me know
|
|
||||||
and I will rectify the situation immedeately.
|
|
||||||
|
|
||||||
Jack Jansen, jack@cwi.nl, 31-Jan-01.
|
|
18
configure.in
18
configure.in
|
@ -177,7 +177,7 @@ case $ac_sys_system/$ac_sys_release in
|
||||||
# On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined,
|
# On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined,
|
||||||
# even though select is a POSIX function. Reported by J. Ribbens.
|
# even though select is a POSIX function. Reported by J. Ribbens.
|
||||||
# Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
|
# Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
|
||||||
OpenBSD/2.* | OpenBSD/3.@<:@012345678@:>@)
|
OpenBSD/2.* | OpenBSD/3.@<:@0123456789@:>@)
|
||||||
define_xopen_source=no;;
|
define_xopen_source=no;;
|
||||||
# On Solaris 2.6, sys/wait.h is inconsistent in the usage
|
# On Solaris 2.6, sys/wait.h is inconsistent in the usage
|
||||||
# of union __?sigval. Reported by Stuart Bishop.
|
# of union __?sigval. Reported by Stuart Bishop.
|
||||||
|
@ -1474,13 +1474,27 @@ then
|
||||||
;;
|
;;
|
||||||
Linux*|GNU*) LDSHARED='$(CC) -shared';;
|
Linux*|GNU*) LDSHARED='$(CC) -shared';;
|
||||||
BSD/OS*/4*) LDSHARED="gcc -shared";;
|
BSD/OS*/4*) LDSHARED="gcc -shared";;
|
||||||
OpenBSD*|FreeBSD*)
|
FreeBSD*)
|
||||||
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
|
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
|
||||||
then
|
then
|
||||||
LDSHARED="$CC -shared ${LDFLAGS}"
|
LDSHARED="$CC -shared ${LDFLAGS}"
|
||||||
else
|
else
|
||||||
LDSHARED="ld -Bshareable ${LDFLAGS}"
|
LDSHARED="ld -Bshareable ${LDFLAGS}"
|
||||||
fi;;
|
fi;;
|
||||||
|
OpenBSD*)
|
||||||
|
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
|
||||||
|
then
|
||||||
|
LDSHARED='$(CC) -shared $(CCSHARED) ${LDFLAGS}'
|
||||||
|
else
|
||||||
|
case `uname -r` in
|
||||||
|
[[01]].* | 2.[[0-7]] | 2.[[0-7]].*)
|
||||||
|
LDSHARED="ld -Bshareable ${LDFLAGS}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
LDSHARED='$(CC) -shared $(CCSHARED) ${LDFLAGS}'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi;;
|
||||||
NetBSD*|DragonFly*) LDSHARED="cc -shared ${LDFLAGS}";;
|
NetBSD*|DragonFly*) LDSHARED="cc -shared ${LDFLAGS}";;
|
||||||
OpenUNIX*|UnixWare*)
|
OpenUNIX*|UnixWare*)
|
||||||
if test "$GCC" = "yes"
|
if test "$GCC" = "yes"
|
||||||
|
|
Loading…
Reference in New Issue