Commit 79e02231 authored by Just van Rossum's avatar Just van Rossum

removed old IDE stuff -- jvr

parent e1fb04f6
# copyright 1997 Just van Rossum, Letterror. just@knoware.nl
import Splash
import FrameWork
import WFrameWorkPatch
import Win
import W
import os
import macfs
class PythonIDE(WFrameWorkPatch.Application):
def __init__(self):
self.preffilepath = ":Python:PythonIDE preferences"
WFrameWorkPatch.Application.__init__(self, 'Pyth')
import AE, AppleEvents
AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication,
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()
PyConsole.installconsole()
PyConsole.installoutput()
import sys
for path in sys.argv[1:]:
self.opendoc(path)
self.mainloop()
def makeusermenus(self):
m = WFrameWorkPatch.Menu(self.menubar, "File")
newitem = FrameWork.MenuItem(m, "New", "N", 'new')
openitem = FrameWork.MenuItem(m, "Open", "O", 'open')
FrameWork.Separator(m)
closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
saveasitem = FrameWork.MenuItem(m, "Save as", None, 'save_as')
FrameWork.Separator(m)
quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit')
m = WFrameWorkPatch.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", "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 = WFrameWorkPatch.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", "M", self.domenu_modulebrowser)
FrameWork.Separator(m)
mm = FrameWork.SubMenu(m, "Preferences")
FrameWork.MenuItem(mm, "Set Scripts folder", None, self.do_setscriptsfolder)
self.openwindowsmenu = WFrameWorkPatch.Menu(self.menubar, 'Windows')
self.makeopenwindowsmenu()
self._menustocheck = [closeitem, saveitem, saveasitem,
undoitem, cutitem, copyitem, pasteitem,
selallitem, sellineitem,
finditem, findagainitem, enterselitem, replaceitem, replacefinditem,
shiftleftitem, shiftrightitem,
runitem, runselitem]
prefs = self.getprefs()
if prefs.scriptsfolder:
fss, fss_changed = macfs.RawAlias(prefs.scriptsfolder).Resolve()
self.scriptsfolder = fss.NewAlias()
prefs.scriptsfolder = self.scriptsfolder.data
self.scriptsfoldermodtime = fss.GetDates()[1]
else:
path = os.path.join(os.getcwd(), 'Scripts')
if not os.path.exists(path):
os.mkdir(path)
fss = macfs.FSSpec(path)
self.scriptsfolder = fss.NewAlias()
self.scriptsfoldermodtime = fss.GetDates()[1]
self._scripts = {}
self.scriptsmenu = None
self.makescriptsmenu()
def quitevent(self, theAppleEvent, theReply):
import AE
AE.AEInteractWithUser(50000000)
self._quit()
def suspendresume(self, onoff):
if onoff:
fss, fss_changed = self.scriptsfolder.Resolve()
modtime = fss.GetDates()[1]
if self.scriptsfoldermodtime <> modtime or fss_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:
fss, a = doc.Resolve()
path = fss.as_pathname()
self.opendoc(path)
def opendoc(self, path):
fcreator, ftype = macfs.FSSpec(path).GetCreatorType()
if ftype == 'TEXT':
self.openscript(path)
else:
W.Message("Cant open file of type '%s'." % ftype)
def getabouttext(self):
return "About Python IDE"
def do_about(self, id, item, window, event):
Splash.about()
def do_setscriptsfolder(self, *args):
fss, ok = macfs.GetDirectory("Select Scripts Folder")
if ok:
prefs = self.getprefs()
alis = fss.NewAlias()
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):
fss, ok = macfs.StandardGetFile("TEXT")
if ok:
self.openscript(fss.as_pathname())
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()
fss, fss_changed = self.scriptsfolder.Resolve()
self.scriptswalk(fss.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:
item = FrameWork.MenuItem(self.openwindowsmenu, title, 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 _quit(self):
import PyConsole, PyEdit
PyConsole.console.writeprefs()
PyEdit.searchengine.writeprefs()
for window in self._windows.values():
if window.close() > 0:
return
self.quitting = 1
PythonIDE()
(This file must be converted with BinHex 4.0) :$&GTC'GPG(-ZFR0bB`"bFh*M8P0&4!%!N!F5HcQ*!*!%!3!!!"%3!!!3%!!!!@X *!!!!E'PZC@CTC@aNF`N!!!"6Bh*[E'aLBA*c"`!!!!aAD@4RCA4c,R*cFQ-ZFQj MCA0jEfaPFQ9iG'9ZG(0c!!"bFh*M8P0&4!%!N!5"!*!5XK52b3#3"K*lEhKc#!! !!'PZCQpdCAKdF`B!!!"#GA4dEfjc!`!!!(*eER-*!!!!FR9ZBR9dG'pZF``!!!" bG@jcC@aPBh4TEfjc$!!!!(*eER0PE'*eG(4[ER-%!!!!BQPZC(-%!!!!F(9cD(- 0!!!!E@9ZG9pREh4[E'PZCA-*!!!!FfKTCR4XC3!!!-3!a!#3"3X!#`!4![m-!2r q!!!!5!!!!%J!N!F,!!X!N!8"!!S!N!8,!!X!N!#!"!#3"3X!#`#3#8J!!!")!*! &!J!"!!)!N!e(IP3!!!!#!!$rN!B!!Cb3"2rr!!)!N!X,!!X!N!8,!!X!!!#!!!! !S!!!!*J!!!#'!!!!NB!!!)4J!!#4J!!!KJ!!!*J!!!#J!!!!J!!!!2m!!!$%!-3 !N!8,!!X!%3,r$!$rrJ!!!%J!!!")!*!(#`!,!*!&!3!+!*!&#`!,!*!!J!3!N!8 ,!!X!N!P)!!!!5!#3"3)!!3!#!*!04hq$!!!!!J!!rj!'!!'FN!6rr`!#!*!,#`! ,!*!&#`!,!*!1UUUS!#4%B!!*%B!!!NB!!!#B!!!!)!#3#rm!!!",!%X!N!8,!!X 4!3%!#J#3"3X!#j!!!!)!N!8,!!X!N!8,!!X!N!8,!!X!!!J!$!!1!!m!$i!2`!q !$`!1!!`!#!$r!!!!5`",!*!&#`!,%3%"!!S!N!8,!!Z3!!!#!*!&#`!,!*!&#`! ,!*!&#`!,!*!)rq"r`$q!(`!1!!3!N!Ar!!!!53"*!*!&#J!+%3%"!!S!N!8+!!U 3!!!#!*!&#J!+!*!&#J!+!*!&#J!+!!!3!"J!(!!H!"m!(`!H!"`!'!!3!2m!!!" *!%N!N!8+!!S4!3%!#J#3"3S!#T!!!!)!N!8+!!S!N!8+!!S!N!8+!!S!N!Mr`(q !2`!H!!`!N!Ar!!!#bQ!1!!"-4%9'!)!!N!C"q[rZ6R&1F@!!!!*19J!!,`XQEJ! )-#i!'QF1DejA3'G5DPK53'SXB!S[#dkk!'*BMf"),`Xr,J!-2bi!$LmZ!"![,J! 8(bi!'%kk!&T2l`!5B#J[#cmZ!!`r,J!1,bi!%#mZ!"3I,J!B6VS"d%r[!"*J##m ,6VS#,&L2*Pp1AL"I6qm!&%l3K'eKD@i!!!"19J!!6Pj1GBT0H8a%48C*EQPd!!! !6PEr[NMR(c!q,J!5*Qi!#L4Z!"C#E[r-I!"#E[r+5'lrr+Kd)&)[+!!)U(0#TkM B+Km["DKk,`ZSHdKZrqUSQ+LH,`ZSSdKZrpDS05JZrpC`%1#N)#lrfR)3iU!Y32r 1)LlrhR33j+%Y3Ir5d)63J5e!rmBJ5U!T5Qi!&'F!!,Jf"f!5)&)JD!"3)&!--!! 0-!"R$&*$-#i!&0"(X%0Zj$!$N!"(28$rc$`Z!"6F4ja$8dCb!G*$28(rbR3%e'X !!Mm#0"284$m#U*-J8L"S!&![%$m(2blrc+L&5NC[*(!%d'X!!Mm!-"2340"ZrmJ r!+L6)&)JD!"3,a!r,[r+2`DSK8KZrlj)HJ"mU'C)E[qqU*dr+`!#-#lrb0"!d&0 53$m!U*-r+`!'-#lrb0"!d&053$m!U*%J5U!U5Li!#'FD,`Sr,J!82`F[,J!1,`X I,J!)6VS!3Nr[!")[,[rmU(-["DKj,`@Sf8KZrqUSQ8cI$2K1ANjeLNej6%4&4N4 bBAF!!")3-C!3!%j@rqS[#dKZrrbSG#"Z!"BJ8#mS!!LSFd+RU0JQAbm,U(S[,J! +U(Y)E[rUU*LSRMmm!$+SR#mZ!!USSLmZrrbSFbm,U(N[#kMC5'lrkULC*Pp1ANj eMdej6%4&4NKTCfKXD@GSG!!!6PB!!%jH6R@,6AP-4%9'3fa[Ff8!N!9%!B!DF#C )*NS564**D!QB!BJ#3!)J!L!%%!3)#!3)"!J"J"[`2rJrqKrr(rp[rj!%rRrq2ri rr"rm$rJ(q!Ii!!N!#!!!!%3!N!30J"*`%N`55LJ++!*)!N!#)!)J""!%#!J%#!3 )!*!%$B!Im"rm(rirrMrqIrjrrMrq2r`Ir!ri"rJ(q!!*!!J!!!"%!!!"J!'!!B! "J"')-BarrM'-%BJ"J!'!!B!"J!#3"!2!!m!$`!2!'pJlh(rqrrprrM[F'pJ$`!2 !!m!$`!!!!!F!"`!!!2)!N!5!"!#3"4!!%!#3#8J!!!")!*!&!J!"!!)!N"%#!*! &%!!3!*!&!J#3"4!!%!#3#!)!!`!$J!2!!q!$m!2J!m!$J!-!!J#3#`)!!`!#J!* !!L!#%!)J!N!#J!-!!J#3$J)!!2q3"J!"QC!%rrm!!`#3$``!!!!2!!!!$F!!!!a `!!!0(!!!$%F!!!dF!!!-F!!!$F!!!!m!!!!-!*!4mJ#3")!%!*!&%!!3!*!*5!! !!%J!N!8#!!%!!J#3%3)!N!83!"!!N!8#!*!&%!!3!*!12rJIm!rJ"m!$J!%!N"8 rq"!3##!%3!+!!3#3%J)!!2q3"J!"QC!%rrm!!`#3'Jrrrm!$4%F!!0%F!!!dF!! !$F!!!!-!N"R+!*!%J!)!N!83!"!!N!P)!!!!5!#3"3%!!3!"!*!4!J#3"4!!%!# 3"3)!N!83!"!!N!J#!!-!!i!$`!2J!r!$i!2!!i!$!!)!N!X#!!-!!i!$`!2J!r! $i!2!!i!$!!)!N!i"!!$rN!B!!3#3#J)!!`!$J!2!!q!$m!2J!m!$J!-!!J#3#XS !N!5!!J#3"4!!%!#3#8J!!!")!*!&!3!"!!%!N"%#!*!&%!!3!*!&!J#3"4!!%!# 3$Mri(r!2i!I!!i!"!*!92rJIm!rJ"m!$J!%!N")"!!$rN!B!!3#3%$ri(r!2i!I !!i!"!*!0"FjJ#J!!6%4&4J(A!!"1qJ9'6R919[r'51FI-#4Z!!Jk,J!-1#i!$LC Z!"!-4!!"E!K#8h!"B!!"L%KZrrbSG#"Zrr`@+!"'98m[#N*R2`@SKM!I2!"+4QF %[%4Z#$D&F!"J!!&FF!!3!`"!!#!r!+L)98m[#N*R2`@SKM!I2!#m4'i)0S9`!@! !!6B-4J!"E!K#8h!"B!!"+$e'rmC)E[r'5'lraMmm)!kTkdKZrmC)E[r'2c`3%+R V286rd%KZrp")E[r32c`J$URV5'lrd%KZrp!r2"!3UHXp4IrD5'lrfNKZrpSr2#! 1UHY)E[rD5'lrfMmm%"#TkdKZrpT)E[rN2c`3$URV5'lrd%KZrq3r2"!%UHY)E[r '5'lrj$mm%!DTkdKZrq4)E[rZ2c`3%+RV5'lrlNKZrr)r2"!1UHY)E[rb2c`!&UR V5'lrmNKZrr)r2#J3UHXf,[rd98p"qJ"f5&#SM$!I2J"+3fi%GJ"J5P92,`T#Ccm $U)B`(p"(2!"96bm+3QF`!e*!2`#SKM!Id%Fk!,a%EJbi4@i)Z%9Q'P*$B"Dm4'm #8d0+3fi%GJ"J#,T%E,*53f#Z0S0`!8cI$2K1ANjeLh4bG@jMFh4bD@jR!!)"b8j @rrj)ja``*Qi!#$BZ!!`NEJ!11#S!"TKU!!)JEJ!8)&!JD!!)'LJ!4M!U!!*83$m !-",3EJ!52`#SNdKZrri`"&G!2`!r!bm,6VVpm%S!6qm!$'FJ,`Y#CcmZrrkSKEC Zrrj["MmmrmQSJh!!%!8r!+L)B!J[#d*R2`1SK8cI$$K1ANjeM%4bBAG8CAKd3f9 XE!!!!%j@rkj)jam`*Qi!$$JZ!"BU,J!B5'lraUKd)%8J8#mS!!LSFeP2U0JJAbe )rqi[,[rZU(S[#kKl5'lrY+LBU*j+,J!)CJ!#(Lm,U+0)E[rDU$8J,[rDFK$LS#e !rr)Q,[rHiU-X,[rLiUBZ!0k$hSB-4!!'E3!"EL"&)&!YD!"3rp3JE[r8S#NNE[r 8*&,8lJ!829,rdMeU!!,rXMeU!!6rf&b+A83Y5[qZ2!3Z#N*ZrrC+E[r5CeTC6cm Zrp+U(L"I*JK+JfG+)%-J8#eS!!Erq#eS!!Vrr%KZrrJr+`!#2a1SU%KZrrK#Cc! Zrrb3!'lrq#"&)&!b+!!3NN!`!H")lNM33H*!2`#SU%KZrrJ[!kSIGJ"J(J`b!!N `!'B82!053b"+d--Z#$!%N!"$28$rpQ!'8N1f4'hH5NCY!!#J)%8J8(!3d'J!!Y" Zrl)h3!!#)%8J8$!S!!,3E[rB0d!!"L"&)&!`+`!'X'J!"Qm+)%8J8$GS!!B!"M! V!!+`D`!'E"B["6mZrr3[#cm',blrVNkkrGK2l`!3)%8J8$!S!!,3E[rB0d!!!L" &)&!hD!!'!!B`+`!#X'X!"Q`@,`8r,[rd,`Xr,[rf,`G1Z[fH6qm!%#"&)&!hD!! '!!BJE[r8S#TJ(NT%CaS["6mZrr3[#cmm!!0"qJ$+5&"1Z[eZ6qm!%#e6rrJYD`! %rr`J45"3-#J!!Y"ZrpK63$e!rrT53$e!rriJ45"3##J!!!!4C`J),J!!rrPR$NK ZrmT"qJ#'5&#SCQ!-5'lrbN(k!)T)8+KQ5'lrbULG3QHSR%KZrrLSSULH5Li!#QB '5Li!#'FL)%8J8(!3d'J!!MG!!!)J45"30fJ!"J!'2c`!-ULF,`ZSSLmZrmDSFbm ZrqkSH5mZrqkSf8KZrl5SQ8cI$2K1ANjeLNej6%4&4N4bBAF!!#Jr2cm!%'CQ-$" QCM!`CQB`-'CQ-$!!%$!`CQB`-'CQ-$"QCM!`CQB!6PB!!%MR($!D,J!B*Qi!&$J Z!!if,J!-*'i!#$!Z!"TR3P0!C`T63'FJ8d"R0Q!d,`Sr!cm%,bi!%#m,(`9#*dk kr0C2l`!8B"S[#Mm$2`3[,J!3,`XI"4mm!!&1Z[bk6qm!&%cI$$K1AL"I6qm!&%l 3K'eKD@i!N!C%!!!"!!1!"m!"!!%!!3"rr(rm!3!"!!%!"m!$J!%!!!!"!!1!"m! 2i!rJ!i$rr[rqrrlrrJ1!$q!2i!I!!i!"!!!(!!F!!!%!!!!4%!!!%"!!!!&V"cG ,$#RH!!!!(!$q!!035808!!8!)Na%48B!!3"U3e958`!$!)*MD@0Z!!-!XJ(8!!` !N!J"e3!B!!!!b!#3"!(@!#)!!!'3!!#3"!(A!$-!!!(I!*!%!GJ!3J!!!Li!N!3 "f3"0!!!#H`#3"!(8!!!J!!,)!*!%!GF!B3!!#IB!N!3"e!"A)!!&PJ#3"!(9!&` J!!AH!*!%!GErr`!!"LB!N!3"errr!!!2b!#3"!(8rrm!!!CZ!*!%!GArr`!!"f3 !N!3"e[rr!!!)@J#3"!(Arrm!!!NS!*!%#e4hEdaTEQ9-4%9'#f0XEh0PC'&bFQp h#@p`C@jKFR*[Ga"ME'pcC@4KFR*[Gh0[E'PN$Qp`C@jKFR*[Gh0[E'PN#Q&bFQp hFQPRD(3*BA*bEhGNEhGZ"%KKEQ3%4QPcG!Y#FQphFf9b6%4&4VTL:
\ No newline at end of file
import Dlg
import Res
splash = Dlg.GetNewDialog(468, -1)
splash.DrawDialog()
import Qd, TE, Fm, sys
_real__import__ = None
def install_importhook():
global _real__import__
import __builtin__
if _real__import__ is None:
_real__import__ = __builtin__.__import__
__builtin__.__import__ = my__import__
def uninstall_importhook():
global _real__import__
if _real__import__ is not None:
import __builtin__
__builtin__.__import__ = _real__import__
_real__import__ = None
_progress = 0
def importing(module):
global _progress
Qd.SetPort(splash)
fontID = Fm.GetFNum("Python-Sans")
if not fontID:
fontID = geneva
Qd.TextFont(fontID)
Qd.TextSize(9)
rect = (35, 260, 365, 276)
if module:
TE.TETextBox('Importing: ' + module, rect, 0)
if not _progress:
Qd.FrameRect((35, 276, 365, 284))
pos = min(36 + 330 * _progress / 44, 364)
Qd.PaintRect((36, 277, pos, 283))
_progress = _progress + 1
else:
Qd.EraseRect(rect)
Qd.PaintRect((36, 277, pos, 283))
def my__import__(name, globals=None, locals=None, fromlist=None):
try:
return sys.modules[name]
except KeyError:
try:
importing(name)
except:
try:
rv = _real__import__(name)
finally:
uninstall_importhook()
return rv
return _real__import__(name)
install_importhook()
kHighLevelEvent = 23
import Win
from Fonts import *
from QuickDraw import *
from TextEdit import *
import string
import sys
import random
_keepsplashscreenopen = 0
abouttext1 = """The Python Integrated Developement Environment for the Macintosh
Version: %s
Copyright 1997 Just van Rossum, Letterror. <just@knoware.nl>
Python %s
%s
Written by Guido van Rossum with Jack Jansen (and others)
See: <http://www.python.org/> for information and documentation."""
flauwekul = [ 'Goodday, Bruce.',
'Whats new?',
'Nudge, nudge, say no more!',
'No, no sir, its not dead. Its resting.',
'Albatros!',
'Its . . .',
'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 nl2return(text):
return string.join(string.split(text, '\n'), '\r')
def UpdateSplash(drawdialog = 0, what = 0):
if drawdialog:
splash.DrawDialog()
drawtext(what)
Win.ValidRect(splash.GetWindowPort().portRect)
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, 125, 390, 260)
if not what:
import __main__
abouttxt = nl2return(abouttext1 \
% (__main__.__version__, sys.version, sys.copyright))
else:
abouttxt = nl2return(random.choice(flauwekul))
TE.TETextBox(abouttxt, rect, teJustCenter)
UpdateSplash(1)
def wait():
import Evt
from Events import *
global splash
try:
splash
except NameError:
return
Qd.InitCursor()
time = Evt.TickCount()
whattext = 0
while _keepsplashscreenopen:
ok, event = Evt.EventAvail(highLevelEventMask)
if ok:
# got apple event, back to mainloop
break
ok, event = Evt.EventAvail(mDownMask | keyDownMask | updateMask)
if ok:
ok, event = Evt.WaitNextEvent(mDownMask | keyDownMask | updateMask, 30)
if ok:
(what, message, when, where, modifiers) = event
if what == 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
#Res.CloseResFile(splashresfile)
def about():
global splash, splashresfile, _keepsplashscreenopen
_keepsplashscreenopen = 1
splash = Dlg.GetNewDialog(468, -1)
splash.DrawDialog()
wait()
"""usage:
newsettings = print FontDialog(('Chicago', 0, 12, (0, 0, 0))) # font name or id, style flags, size, color (color is ignored)
if newsettings:
font, style, size, color = newsettings # 'font' is always the font name, not the id number
# do something
"""
import W
import PyEdit
import TextEdit
import string
import types
_stylenames = ["Plain", "Bold", "Italic", "Underline", "Outline", "Shadow", "Condensed", "Extended"]
class _FontDialog:
def __init__(self, fontsettings):
leftmargin = 46
self.w = W.ModalDialog((440, 180), 'Font settings')
self.w.fonttitle = W.TextBox((10, 12, 30, 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, 30, 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, 30, 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)
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)
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 set(self, fontsettings):
font, style, size, color = fontsettings
if type(font) <> types.StringType:
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
return (font, style, size, (0, 0, 0))
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(`style`)
self.w.sample.setfontsettings(self.get())
def checksize(self):
size = self.w.sizeedit.get()
if not size:
return
try:
size = string.atoi(size)
except (ValueError, OverflowError):
good = 0
else:
good = 1 <= size <= 500
if good:
if self.lastsize <> size:
self.lastsize = size
self.doit()
else:
# beep!
self.w.sizeedit.set(`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 cancel(self):
self.w.close()
def done(self):
self._rv = self.get()
self.w.close()
def setfont(self, fontname):
self.w.fontname.set(fontname)
self.doit()
def FontDialog(fontsettings):
fd = _FontDialog(fontsettings)
return fd._rv
def test():
print FontDialog(('Zapata-Light', 0, 25, (0, 0, 0)))
import macfs
import marshal
import os
import macostools
import types
kOnSystemDisk = 0x8000
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:
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'))
fss = macfs.FSSpec(self.__path)
fss.SetCreatorType(self.__creator, 'pref')
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'):
if _prefscache.has_key(prefname):
return _prefscache[prefname]
# Find the preferences folder and our prefs file, create if needed.
vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0)
prefsfolder_fss = macfs.FSSpec((vrefnum, dirid, ''))
prefsfolder = prefsfolder_fss.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
import W
import sys
__version__ = "0.2"
__author__ = "jvr"
class _modulebrowser:
def __init__(self):
self.editmodules = []
self.modules = []
self.window = W.Window((194, 1000), "Module Browser", minsize = (194, 160), maxsize = (340, 20000))
self.window.openbutton = W.Button((10, 8, 80, 16), "Open", self.openbuttonhit)
self.window.browsebutton = W.Button((100, 8, 80, 16), "Browse", self.browsebuttonhit)
self.window.reloadbutton = W.Button((10, 32, 80, 16), "Reload", self.reloadbuttonhit)
self.window.openotherbutton = W.Button((100, 32, 80, 16), "Open other", 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("Cant find file for module %s."
% modname)
else:
self.openscript(path, modname)
def openscript(self, path, modname):
if path[-3:] == '.py':
W.getapplication().openscript(path)
else:
W.Message("Cant 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 cant 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:
m = sys.modules[self.window.list[i]]
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
modules = sys.modules.keys()
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':
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()
import W
import Evt
import sys
import StringIO
import string
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 = []
self.w.button_calls = W.RadioButton((54, 4, 45, 12), 'calls', self.buttons, self.setsort)
self.w.button_time = W.RadioButton((104, 4, 40, 12), 'time', self.buttons, self.setsort)
self.w.button_cumulative = W.RadioButton((154, 4, 75, 12), 'cumulative', self.buttons, self.setsort)
self.w.button_stdname = W.RadioButton((234, 4, 60, 12), 'stdname', self.buttons, self.setsort)
self.w.button_calls.set(1)
self.w.button_file = W.RadioButton((304, 4, 40, 12), 'file', self.buttons, self.setsort)
self.w.button_line = W.RadioButton((354, 4, 50, 12), 'line', self.buttons, self.setsort)
self.w.button_module = W.RadioButton((404, 4, 55, 12), 'module', self.buttons, self.setsort)
self.w.button_name = W.RadioButton((464, 4, 50, 12), 'name', self.buttons, self.setsort)
## self.w.button_nfl = W.RadioButton((4, 4, 12, 12), 'nfl', self.buttons, self.setsort)
## self.w.button_pcalls = W.RadioButton((4, 4, 12, 12), 'pcalls', self.buttons, self.setsort)
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')
apply(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:
import macfs
fss, ok = macfs.PromptGetFile('Profiler data')
if not ok: sys.exit(0)
stats = pstats.Stats(fss.as_pathname())
browser = ProfileBrowser(stats)
if __name__ == '__main__':
main()
import W, SpecialKeys
import struct
import string
import types
import regex
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 = regex.compile('[\000-\037\177-\377]')
def double_repr(key, value, truncvalue = 0,
type = type, StringType = types.StringType,
has_ctlchars = has_ctlcharsRE.search, _repr = repr, str = str):
if type(key) == StringType and has_ctlchars(key) < 0:
key = str(key)
else:
key = _repr(key)
if type(value) == StringType and has_ctlchars(value) < 0:
value = str(value)
elif 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 = ' exception in repr()'
if truncvalue:
return key + '\t' + value[:255]
return key + '\t' + value
class BrowserWidget(W.List):
LDEF_ID = 471
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] <> 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 (SpecialKeys.leftarrowkey, SpecialKeys.rightarrowkey):
sel = self.getselection()
sel.reverse()
self.setdrawingmode(0)
for index in sel:
self.fold(index, char == SpecialKeys.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)):
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():
(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.qd.black)
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):
import macfs
fss = macfs.FSSpec(value)
if fss.GetCreatorType()[1] == 'TEXT':
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:
import Scrap
Scrap.ZeroScrap()
Scrap.PutScrap('TEXT', text)
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.Button((-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 = (
types.NoneType,
types.IntType,
types.LongType,
types.FloatType,
types.ComplexType,
types.StringType
)
INDEXING_TYPES = (
types.TupleType,
types.ListType,
types.DictionaryType
)
def unpack_object(object, indent = 0):
tp = type(object)
if tp in SIMPLE_TYPES and tp is not types.NoneType:
raise TypeError, 'cant browse simple type: %s' % tp.__name__
elif tp == types.DictionaryType:
return unpack_dict(object, indent)
elif tp in (types.TupleType, types.ListType):
return unpack_sequence(object, indent)
elif tp == types.InstanceType:
return unpack_instance(object, indent)
elif tp == types.ClassType:
return unpack_class(object, indent)
elif tp == types.ModuleType:
return unpack_dict(object.__dict__, indent)
else:
return unpack_other(object, indent)
def unpack_sequence(seq, indent = 0):
items = map(None, range(len(seq)), seq)
items = map(lambda (k, v), type = type, simp = SIMPLE_TYPES, indent = indent:
(k, v, not type(v) in simp, indent), items)
return items
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 = []
if hasattr(object, '__members__'):
attrs = attrs + object.__members__
if hasattr(object, '__methods__'):
attrs = attrs + object.__methods__
items = []
for attr in attrs:
items.append((attr, getattr(object, attr)))
return pack_items(items, indent)
def pack_items(items, indent = 0):
items = map(lambda (k, v), type = type, simp = SIMPLE_TYPES, indent = indent:
(k, v, not type(v) in simp, indent),
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 TypeError:
items = items[:]
items.sort()
return items
else:
tupledlist.sort()
return map(lambda (low, tuple): tuple, tupledlist)
import W
import Fm
from WASTEconst import *
from SpecialKeys import *
from types import *
import Events
import string
import sys,os
import traceback
import MacOS
import MacPrefs
import PyInteractive
if not hasattr(sys, 'ps1'):
sys.ps1 = '>>> '
if not hasattr(sys, 'ps2'):
sys.ps2 = '... '
class ConsoleTextWidget(W.EditText):
def __init__(self, *args, **kwargs):
apply(W.EditText.__init__, (self,) + args, kwargs)
self._inputstart = 0
self._buf = ''
self.pyinteractive = PyInteractive.PyInteractive()
import __main__
self._namespace = __main__.__dict__
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"
self._namespace = dict
def open(self):
W.EditText.open(self)
self.write('Python ' + sys.version + '\n' + sys.copyright + '\n')
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 arrowkeys:
if char not in navigationkeys:
self.checkselection()
if char == enterkey:
char = returnkey
selstart, selend = self.getselection()
if char == backspacekey:
if selstart <= (self._inputstart - (selstart <> selend)):
return
self.ted.WEKey(ord(char), modifiers)
if char not in navigationkeys:
self.changed = 1
if char not in scrollkeys:
self.selchanged = 1
self.updatescrollbars()
if char == returnkey:
text = self.get()[self._inputstart:selstart]
saveyield = MacOS.EnableAppswitch(0)
self.pyinteractive.executeline(text, self, self._namespace)
MacOS.EnableAppswitch(saveyield)
selstart, selend = self.getselection()
self._inputstart = selstart
def domenu_save_as(self, *args):
import macfs
fss, ok = macfs.StandardPutFile('Save console text as:', 'console.txt')
if not ok:
return
f = open(fss.as_pathname(), 'wb')
f.write(self.get())
f.close()
fss.SetCreatorType(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()
self.ted.WEInsert(stuff, None, None)
selstart, selend = self.getselection()
self._inputstart = selstart
self._buf = ""
self.ted.WEClearUndo()
self.updatescrollbars()
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)), 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)
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([("Font settings", self.dofontsettings),
["Namespace"] + namespacelist, ("Clear buffer", self.clearbuffer), ("Browse namespace", 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(2)
menu = self.namespacemenu.menu.bar.menus[submenuid]
menu.menu.CheckItem(i + 1, 1)
def browsenamespace(self):
import PyBrowser, W
W.SetCursor('watch')
PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
def clearbuffer(self):
import Res
self.consoletext.ted.WEUseText(Res.Resource(''))
self.consoletext.write(sys.ps1)
self.consoletext.flush()
def getnamespacelist(self):
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
fontsettings = FontSettings.FontDialog(self.consoletext.getfontsettings())
if fontsettings:
self.consoletext.setfontsettings(fontsettings)
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.save()
class OutputTextWidget(W.EditText):
def _getflags(self):
import WASTEconst
return WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled | \
WASTEconst.weDoUndo
class PyOutput:
def __init__(self):
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
def write(self, text):
self._buf = self._buf + text
if '\n' in self._buf:
self.flush()
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.WEInsert(stuff, None, None)
self._buf = ""
self.w.outputtext.ted.WEClearUndo()
self.w.outputtext.updatescrollbars()
def show(self):
if self.closed:
if not self.w:
self.setupwidgets()
self.w.open()
self.closed = 0
else:
self.w.show(1)
self.closed = 0
self.w.select()
def setupwidgets(self):
self.w = W.Window((450, 200), "Output", minsize = (200, 100), tabbable = 0)
self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5))
self.w._bary = W.Scrollbar((-15, -1, 16, -14), self.w.outputtext.vscroll, max = 32767)
self.w.bind("<close>", self.close)
self.w.bind("<activate>", self.activate)
def activate(self, onoff):
if onoff:
self.closed = 0
def close(self):
self.w.show(0)
self.closed = 1
return -1
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))
console = PyConsole(prefs.console.windowbounds, prefs.console.show, prefs.console.fontsettings, 1)
def installoutput():
global output
output = PyOutput()
import sys
import bdb
import types
import os
import W
import WASTEconst
import PyBrowser
import Qd
import Evt
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()
prefs = W.getapplication().getprefs()
if prefs.debugger:
self.breaks = prefs.debugger.breaks
self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings
self.tracemagic = prefs.debugger.tracemagic
for key in self.breaks.keys():
if key[:1] == '<' and key[-1:] == '>':
del self.breaks[key]
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
self.editors = {}
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
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'
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 self.w.parent:
self.exit_mainloop()
self.resetwidgets()
def clear_tracefuncs(self):
try:
raise 'spam'
except:
pass
frame = sys.exc_traceback.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, 52, 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, 20, 0, 16), self.reason)
bottom.srctitle = W.TextBox((12, 36, 0, 14))
bottom.buttons = buttons = W.Group((12, 0, 0, 16))
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, 50, 16), "Step", self.do_step)
buttons.stepinbutton = W.Button((239, 0, 50, 16), "Step in", self.do_stepin)
buttons.stepoutbutton = W.Button((297, 0, 50, 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', 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'
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, 'rb')
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('cant find file')
else:
f.close()
if suff == '.py':
f = open(filename, 'rb')
data = f.read()
f.close()
self.w.panes.bottom.src.source.set(data, filename)
else:
self.w.panes.bottom.src.source.set('cant find file')
else:
self.w.panes.bottom.src.source.set('cant find file')
else:
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:
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:', `event`
return self.trace_dispatch
finally:
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_type, sys.exc_value)
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
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):
apply(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
import Lists
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', 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):
apply(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:
frame = sys.exc_traceback.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
frame = sys.exc_traceback.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():
global _debugger
if _debugger is None:
_debugger = Debugger()
return _debugger
"""a simple python editor"""
import W
import Wtraceback
from SpecialKeys import *
import macfs
import MacOS
import Win
import Res
import Evt
import os
import imp
import sys
import string
import marshal
import regex
_scriptuntitledcounter = 1
_wordchars = string.letters + string.digits + "_"
class Editor(W.Window):
def __init__(self, path = "", title = ""):
global _scriptuntitledcounter
if not path:
if title:
self.title = title
else:
self.title = "Untitled Script " + `_scriptuntitledcounter`
_scriptuntitledcounter = _scriptuntitledcounter + 1
text = ""
self._creator = W._signature
elif os.path.exists(path):
self.title = os.path.basename(path)
f = open(path, "rb")
text = f.read()
f.close()
fss = macfs.FSSpec(path)
self._creator, filetype = fss.GetCreatorType()
else:
raise IOError, "file '%s' does not exist" % path
self.path = path
self.settings = {}
if self.path:
self.readwindowsettings()
if self.settings.has_key("windowbounds"):
bounds = self.settings["windowbounds"]
else:
bounds = (500, 250)
if self.settings.has_key("fontsettings"):
self.fontsettings = self.settings["fontsettings"]
else:
self.fontsettings = ("Python-Sans", 0, 9, (0, 0, 0))
W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
self.setupwidgets(text)
if self.settings.has_key("selection"):
selstart, selend = self.settings["selection"]
self.setselection(selstart, selend)
self.open()
self.setinfotext()
self.globals = {}
self._buf = "" # for write method
self.debugging = 0
self.profiling = 0
if self.settings.has_key("run_as_main"):
self.run_as_main = self.settings["run_as_main"]
else:
self.run_as_main = 0
def readwindowsettings(self):
try:
resref = Res.OpenResFile(self.path)
except Res.Error:
return
try:
Res.UseResFile(resref)
data = Res.Get1Resource('PyWS', 128)
self.settings = marshal.loads(data.data)
except:
pass
Res.CloseResFile(resref)
def writewindowsettings(self):
try:
resref = Res.OpenResFile(self.path)
except Res.Error:
Res.CreateResFile(self.path)
resref = Res.OpenResFile(self.path)
try:
data = Res.Resource(marshal.dumps(self.settings))
Res.UseResFile(resref)
try:
temp = Res.Get1Resource('PyWS', 128)
temp.RemoveResource()
except Res.Error:
pass
data.AddResource('PyWS', 128, "window settings")
finally:
Res.UpdateResFile(resref)
Res.CloseResFile(resref)
def getsettings(self):
self.settings = {}
self.settings["windowbounds"] = self.getbounds()
self.settings["selection"] = self.getselection()
self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
self.settings["run_as_main"] = self.run_as_main
def get(self):
return self.editgroup.editor.get()
def getselection(self):
return self.editgroup.editor.ted.WEGetSelection()
def setselection(self, selstart, selend):
self.editgroup.editor.setselection(selstart, selend)
def getfilename(self):
if self.path:
return self.path
return '<%s>' % self.title
def setupwidgets(self, text):
topbarheight = 24
popfieldwidth = 80
self.lastlineno = None
# make an editor
self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
editor = W.PyEditor((0, 0, -15,-15), text, fontsettings = self.fontsettings,
file = self.getfilename())
# make the widgets
self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 2))
self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
self.editgroup.editor = editor # add editor *after* scrollbars
self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
self.infotext = W.TextBox((175, 6, -4, 14))
self.runbutton = W.Button((5, 4, 80, 16), "Run all", self.run)
self.runselbutton = W.Button((90, 4, 80, 16), "Run selection", self.runselection)
# bind some keys
editor.bind("cmdr", self.runbutton.push)
editor.bind("enter", self.runselbutton.push)
editor.bind("cmdj", self.domenu_gotoline)
editor.bind("cmdd", self.domenu_toggledebugger)
editor.bind("<idle>", self.updateselection)
editor.bind("cmde", searchengine.setfindstring)
editor.bind("cmdf", searchengine.show)
editor.bind("cmdg", searchengine.findnext)
editor.bind("cmdshiftr", searchengine.replace)
editor.bind("cmdt", searchengine.replacefind)
self.linefield.bind("return", self.dolinefield)
self.linefield.bind("enter", self.dolinefield)
self.linefield.bind("tab", self.dolinefield)
# intercept clicks
editor.bind("<click>", self.clickeditor)
self.linefield.bind("<click>", self.clicklinefield)
def makeoptionsmenu(self):
menuitems = [('Font settings', self.domenu_fontsettings),
('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
('Modularize', self.domenu_modularize),
('Browse namespace', self.domenu_browsenamespace),
'-']
if self.editgroup.editor._debugger:
menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
('Clear breakpoints', self.domenu_clearbreakpoints),
('Edit breakpoints', self.domenu_editbreakpoints)]
else:
menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
if self.profiling:
menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
else:
menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
self.editgroup.optionsmenu.set(menuitems)
def domenu_toggle_run_as_main(self):
self.run_as_main = not self.run_as_main
self.editgroup.editor.selchanged = 1
def showbreakpoints(self, onoff):
self.editgroup.editor.showbreakpoints(onoff)
self.debugging = onoff
def domenu_clearbreakpoints(self, *args):
self.editgroup.editor.clearbreakpoints()
def domenu_editbreakpoints(self, *args):
self.editgroup.editor.editbreakpoints()
def domenu_toggledebugger(self, *args):
if not self.debugging:
W.SetCursor('watch')
self.debugging = not self.debugging
self.editgroup.editor.togglebreakpoints()
def domenu_toggleprofiler(self, *args):
self.profiling = not self.profiling
def domenu_browsenamespace(self, *args):
import PyBrowser, W
W.SetCursor('watch')
globals, file = self.getenvironment()
modname = _filename_as_modname(self.title)
if not modname:
modname = self.title
PyBrowser.Browser(globals, "Object browser: " + modname)
def domenu_modularize(self, *args):
modname = _filename_as_modname(self.title)
if not modname:
raise W.AlertError, 'Cant modularize %s' % self.title
self.run()
if self.path:
file = self.path
else:
file = self.title
if self.globals and not sys.modules.has_key(modname):
module = imp.new_module(modname)
for attr in self.globals.keys():
setattr(module,attr,self.globals[attr])
sys.modules[modname] = module
self.globals = {}
def domenu_fontsettings(self, *args):
import FontSettings
fontsettings = FontSettings.FontDialog(self.editgroup.editor.getfontsettings())
if fontsettings:
self.editgroup.editor.setfontsettings(fontsettings)
def clicklinefield(self):
if self._currentwidget <> self.linefield:
self.linefield.select(1)
self.linefield.selectall()
return 1
def clickeditor(self):
if self._currentwidget <> self.editgroup.editor:
self.dolinefield()
return 1
def updateselection(self, force = 0):
sel = min(self.editgroup.editor.getselection())
lineno = self.editgroup.editor.offsettoline(sel)
if lineno <> self.lastlineno or force:
self.lastlineno = lineno
self.linefield.set(str(lineno + 1))
self.linefield.selview()
def dolinefield(self):
try:
lineno = string.atoi(self.linefield.get()) - 1
if lineno <> self.lastlineno:
self.editgroup.editor.selectline(lineno)
self.updateselection(1)
except:
self.updateselection(1)
self.editgroup.editor.select(1)
def setinfotext(self):
if not hasattr(self, 'infotext'):
return
if self.path:
self.infotext.set(self.path)
else:
self.infotext.set("")
def close(self):
if self.editgroup.editor.changed:
import EasyDialogs
import Qd
Qd.InitCursor() # XXX should be done by dialog
save = EasyDialogs.AskYesNoCancel('Save window %s before closing?' % self.title, 1)
if save > 0:
if self.domenu_save():
return 1
elif save < 0:
return 1
self.globals = None # XXX doesn't help... all globals leak :-(
W.Window.close(self)
def domenu_close(self, *args):
return self.close()
def domenu_save(self, *args):
if not self.path:
# Will call us recursively
return self.domenu_save_as()
data = self.editgroup.editor.get()
fp = open(self.path, 'wb') # open file in binary mode, data has '\r' line-endings
fp.write(data)
fp.close()
fss = macfs.FSSpec(self.path)
fss.SetCreatorType(self._creator, 'TEXT')
self.getsettings()
self.writewindowsettings()
self.editgroup.editor.changed = 0
self.editgroup.editor.selchanged = 0
import linecache
if linecache.cache.has_key(self.path):
del linecache.cache[self.path]
import macostools
macostools.touched(self.path)
def can_save(self, menuitem):
return self.editgroup.editor.changed or self.editgroup.editor.selchanged
def domenu_save_as(self, *args):
fss, ok = macfs.StandardPutFile('Save as:', self.title)
if not ok:
return 1
self.showbreakpoints(0)
self.path = fss.as_pathname()
self.setinfotext()
self.title = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.title)
self.domenu_save()
self.editgroup.editor.setfile(self.getfilename())
app = W.getapplication()
app.makeopenwindowsmenu()
if hasattr(app, 'makescriptsmenu'):
app = W.getapplication()
fss, fss_changed = app.scriptsfolder.Resolve()
path = fss.as_pathname()
if path == self.path[:len(path)]:
W.getapplication().makescriptsmenu()
def domenu_gotoline(self, *args):
self.linefield.selectall()
self.linefield.select(1)
self.linefield.selectall()
def domenu_selectline(self, *args):
self.editgroup.editor.expandselection()
def domenu_shiftleft(self, *args):
self.editgroup.editor.shiftleft()
def domenu_shiftright(self, *args):
self.editgroup.editor.shiftright()
def domenu_find(self, *args):
searchengine.show()
def domenu_entersearchstring(self, *args):
searchengine.setfindstring()
def domenu_replace(self, *args):
searchengine.replace()
def domenu_findnext(self, *args):
searchengine.findnext()
def domenu_replacefind(self, *args):
searchengine.replacefind()
def domenu_run(self, *args):
self.runbutton.push()
def domenu_runselection(self, *args):
self.runselbutton.push()
def run(self):
pytext = self.editgroup.editor.get()
globals, file = self.getenvironment()
if self.path:
cwd = os.getcwd()
os.chdir(os.path.dirname(self.path) + ':')
else:
cwd = None
execstring(pytext, globals, globals, file, self.debugging, self.run_as_main, self.profiling)
if cwd:
os.chdir(cwd)
def runselection(self):
self._runselection()
def _runselection(self):
globals, file = self.getenvironment()
locals = globals
# select whole lines
self.editgroup.editor.expandselection()
# get lineno of first selected line
selstart, selend = self.editgroup.editor.getselection()
selstart, selend = min(selstart, selend), max(selstart, selend)
selfirstline = self.editgroup.editor.offsettoline(selstart)
alltext = self.editgroup.editor.get()
pytext = alltext[selstart:selend]
lines = string.split(pytext, '\r')
indent = getminindent(lines)
if indent == 1:
classname = ''
alllines = string.split(alltext, '\r')
identifieRE_match = _identifieRE.match
for i in range(selfirstline - 1, -1, -1):
line = alllines[i]
if line[:6] == 'class ':
classname = string.split(string.strip(line[6:]))[0]
classend = identifieRE_match(classname)
if classend < 1:
raise W.AlertError, 'Cant find a class.'
classname = classname[:classend]
break
elif line and line[0] not in '\t#':
raise W.AlertError, 'Cant find a class.'
else:
raise W.AlertError, 'Cant find a class.'
if globals.has_key(classname):
locals = globals[classname].__dict__
else:
raise W.AlertError, 'Cant find class %s.' % classname
for i in range(len(lines)):
lines[i] = lines[i][1:]
pytext = string.join(lines, '\r')
elif indent > 0:
raise W.AlertError, 'Cant run indented code.'
# add newlines to fool compile/exec: a traceback will give the right line number
pytext = selfirstline * '\r' + pytext
if self.path:
cwd = os.getcwd()
os.chdir(os.path.dirname(self.path) + ':')
else:
cwd = None
execstring(pytext, globals, locals, file, self.debugging, self.run_as_main, self.profiling)
if cwd:
os.chdir(cwd)
def getenvironment(self):
if self.path:
file = self.path
modname = _filename_as_modname(self.title)
if sys.modules.has_key(modname):
globals = sys.modules[modname].__dict__
self.globals = {}
else:
globals = self.globals
else:
file = '<%s>' % self.title
globals = self.globals
return globals, file
def write(self, stuff):
"""for use as stdout"""
self._buf = self._buf + stuff
if '\n' in self._buf:
self.flush()
def flush(self):
stuff = string.split(self._buf, '\n')
stuff = string.join(stuff, '\r')
end = self.editgroup.editor.ted.WEGetTextLength()
self.editgroup.editor.ted.WESetSelection(end, end)
self.editgroup.editor.ted.WEInsert(stuff, None, None)
self.editgroup.editor.updatescrollbars()
self._buf = ""
# ? optional:
#self.wid.SelectWindow()
def getclasslist(self):
from string import find, strip
editor = self.editgroup.editor
text = editor.get()
list = []
append = list.append
functag = "func"
classtag = "class"
methodtag = "method"
pos = -1
if text[:4] == 'def ':
append((pos + 4, functag))
pos = 4
while 1:
pos = find(text, '\rdef ', pos + 1)
if pos < 0:
break
append((pos + 5, functag))
pos = -1
if text[:6] == 'class ':
append((pos + 6, classtag))
pos = 6
while 1:
pos = find(text, '\rclass ', pos + 1)
if pos < 0:
break
append((pos + 7, classtag))
pos = 0
while 1:
pos = find(text, '\r\tdef ', pos + 1)
if pos < 0:
break
append((pos + 6, methodtag))
list.sort()
classlist = []
methodlistappend = None
offsetToLine = editor.ted.WEOffsetToLine
getLineRange = editor.ted.WEGetLineRange
append = classlist.append
identifieRE_match = _identifieRE.match
for pos, tag in list:
lineno = offsetToLine(pos)
lineStart, lineEnd = getLineRange(lineno)
line = strip(text[pos:lineEnd])
line = line[:identifieRE_match(line)]
if tag is functag:
append(("def " + line, lineno + 1))
methodlistappend = None
elif tag is classtag:
append(["class " + line])
methodlistappend = classlist[-1].append
elif methodlistappend and tag is methodtag:
methodlistappend(("def " + line, lineno + 1))
return classlist
def popselectline(self, lineno):
self.editgroup.editor.selectline(lineno - 1)
def selectline(self, lineno, charoffset = 0):
self.editgroup.editor.selectline(lineno - 1, charoffset)
class Reporter(Editor):
def close(self):
self.globals = None
W.Window.close(self)
def domenu_run(self, *args):
self.run()
def domenu_runselection(self, *args):
self.runselection()
def setupwidgets(self, text):
topbarheight = -1
popfieldwidth = 80
self.lastlineno = None
# make an editor
self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
self.editgroup.editor = W.PyEditor((0, 0, -15,-15), text)
# make the widgets
self.editgroup._barx = W.Scrollbar((popfieldwidth-2, -15, -14, 16), self.editgroup.editor.hscroll, max = 32767)
self.editgroup._bary = W.Scrollbar((-15, -1, 16, -14), self.editgroup.editor.vscroll, max = 32767)
self.hline = W.HorizontalLine((0, -15, 0, 0))
# bind some keys
self.editgroup.editor.bind("cmdr", self.run)
self.editgroup.editor.bind("enter", self.runselection)
self.editgroup.editor.bind("cmde", searchengine.setfindstring)
self.editgroup.editor.bind("cmdf", searchengine.show)
self.editgroup.editor.bind("cmdg", searchengine.findnext)
self.editgroup.editor.bind("cmdshiftr", searchengine.replace)
self.editgroup.editor.bind("cmdt", searchengine.replacefind)
def _escape(where, what) :
return string.join(string.split(where, what), '\\' + what)
def _makewholewordpattern(word):
# first, escape special regex chars
for esc in "\\[].*^+$?":
word = _escape(word, esc)
import regex
notwordcharspat = '[^' + _wordchars + ']'
pattern = '\(' + word + '\)'
if word[0] in _wordchars:
pattern = notwordcharspat + pattern
if word[-1] in _wordchars:
pattern = pattern + notwordcharspat
return regex.compile(pattern)
class SearchEngine:
def __init__(self):
self.visible = 0
self.w = None
self.parms = { "find": "",
"replace": "",
"wrap": 1,
"casesens": 1,
"wholeword": 1
}
import MacPrefs
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
if prefs.searchengine:
self.parms["casesens"] = prefs.searchengine.casesens
self.parms["wrap"] = prefs.searchengine.wrap
self.parms["wholeword"] = prefs.searchengine.wholeword
def show(self):
self.visible = 1
if self.w:
self.w.wid.ShowWindow()
self.w.wid.SelectWindow()
self.w.find.edit.select(1)
self.w.find.edit.selectall()
return
self.w = W.Dialog((420, 150), "Find")
self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
self.w.boxes = W.Group((10, 50, 300, 40))
self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
self.buttons = [ ("Find", "cmdf", self.find),
("Replace", "cmdr", self.replace),
("Replace all", None, self.replaceall),
("Dont find", "cmdd", self.dont),
("Cancel", "cmd.", self.cancel)
]
for i in range(len(self.buttons)):
bounds = -90, 22 + i * 24, 80, 16
title, shortcut, callback = self.buttons[i]
self.w[title] = W.Button(bounds, title, callback)
if shortcut:
self.w.bind(shortcut, self.w[title].push)
self.w.setdefaultbutton(self.w["Dont find"])
self.w.find.edit.bind("<key>", self.key)
self.w.bind("<activate>", self.activate)
self.w.open()
self.setparms()
self.w.find.edit.select(1)
self.w.find.edit.selectall()
self.checkbuttons()
def key(self, char, modifiers):
self.w.find.edit.key(char, modifiers)
self.checkbuttons()
return 1
def activate(self, onoff):
if onoff:
self.checkbuttons()
def checkbuttons(self):
editor = findeditor(self)
if editor:
if self.w.find.get():
for title, cmd, call in self.buttons[:-2]:
self.w[title].enable(1)
self.w.setdefaultbutton(self.w["Find"])
else:
for title, cmd, call in self.buttons[:-2]:
self.w[title].enable(0)
self.w.setdefaultbutton(self.w["Dont find"])
else:
for title, cmd, call in self.buttons[:-2]:
self.w[title].enable(0)
self.w.setdefaultbutton(self.w["Dont find"])
def find(self):
self.getparmsfromwindow()
if self.findnext():
self.hide()
def replace(self):
editor = findeditor(self)
if not editor:
return
if self.visible:
self.getparmsfromwindow()
text = editor.getselectedtext()
find = self.parms["find"]
if not self.parms["casesens"]:
find = string.lower(find)
text = string.lower(text)
if text == find:
self.hide()
editor.insert(self.parms["replace"])
def replaceall(self):
editor = findeditor(self)
if not editor:
return
if self.visible:
self.getparmsfromwindow()
W.SetCursor("watch")
find = self.parms["find"]
if not find:
return
findlen = len(find)
replace = self.parms["replace"]
replacelen = len(replace)
Text = editor.get()
if not self.parms["casesens"]:
find = string.lower(find)
text = string.lower(Text)
else:
text = Text
newtext = ""
pos = 0
counter = 0
while 1:
if self.parms["wholeword"]:
wholewordRE = _makewholewordpattern(find)
wholewordRE.search(text, pos)
if wholewordRE.regs:
pos = wholewordRE.regs[1][0]
else:
pos = -1
else:
pos = string.find(text, find, pos)
if pos < 0:
break
counter = counter + 1
text = text[:pos] + replace + text[pos + findlen:]
Text = Text[:pos] + replace + Text[pos + findlen:]
pos = pos + replacelen
W.SetCursor("arrow")
if counter:
self.hide()
import EasyDialogs
import Res
editor.changed = 1
editor.selchanged = 1
editor.ted.WEUseText(Res.Resource(Text))
editor.ted.WECalText()
editor.SetPort()
Win.InvalRect(editor._bounds)
#editor.ted.WEUpdate(self.w.wid.GetWindowPort().visRgn)
EasyDialogs.Message("Replaced %d occurrences" % counter)
def dont(self):
self.getparmsfromwindow()
self.hide()
def replacefind(self):
self.replace()
self.findnext()
def setfindstring(self):
editor = findeditor(self)
if not editor:
return
find = editor.getselectedtext()
if not find:
return
self.parms["find"] = find
if self.w:
self.w.find.edit.set(self.parms["find"])
self.w.find.edit.selectall()
def findnext(self):
editor = findeditor(self)
if not editor:
return
find = self.parms["find"]
if not find:
return
text = editor.get()
if not self.parms["casesens"]:
find = string.lower(find)
text = string.lower(text)
selstart, selend = editor.getselection()
selstart, selend = min(selstart, selend), max(selstart, selend)
if self.parms["wholeword"]:
wholewordRE = _makewholewordpattern(find)
wholewordRE.search(text, selend)
if wholewordRE.regs:
pos = wholewordRE.regs[1][0]
else:
pos = -1
else:
pos = string.find(text, find, selend)
if pos >= 0:
editor.setselection(pos, pos + len(find))
return 1
elif self.parms["wrap"]:
if self.parms["wholeword"]:
wholewordRE.search(text, 0)
if wholewordRE.regs:
pos = wholewordRE.regs[1][0]
else:
pos = -1
else:
pos = string.find(text, find)
if selstart > pos >= 0:
editor.setselection(pos, pos + len(find))
return 1
def setparms(self):
for key, value in self.parms.items():
try:
self.w[key].set(value)
except KeyError:
self.w.boxes[key].set(value)
def getparmsfromwindow(self):
if not self.w:
return
for key, value in self.parms.items():
try:
value = self.w[key].get()
except KeyError:
value = self.w.boxes[key].get()
self.parms[key] = value
def cancel(self):
self.hide()
self.setparms()
def hide(self):
if self.w:
self.w.wid.HideWindow()
self.visible = 0
def writeprefs(self):
import MacPrefs
self.getparmsfromwindow()
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
prefs.searchengine.casesens = self.parms["casesens"]
prefs.searchengine.wrap = self.parms["wrap"]
prefs.searchengine.wholeword = self.parms["wholeword"]
prefs.save()
class TitledEditText(W.Group):
def __init__(self, possize, title, text = ""):
W.Group.__init__(self, possize)
self.title = W.TextBox((0, 0, 0, 16), title)
self.edit = W.EditText((0, 16, 0, 0), text)
def set(self, value):
self.edit.set(value)
def get(self):
return self.edit.get()
class ClassFinder(W.PopupWidget):
def click(self, point, modifiers):
W.SetCursor("watch")
self.set(self._parentwindow.getclasslist())
W.PopupWidget.click(self, point, modifiers)
def getminindent(lines):
indent = -1
for line in lines:
stripped = string.strip(line)
if not stripped or stripped[0] == '#':
continue
if indent < 0 or line[:indent] <> indent * '\t':
indent = 0
for c in line:
if c <> '\t':
break
indent = indent + 1
return indent
def getoptionkey():
return not not ord(Evt.GetKeys()[7]) & 0x04
def execstring(pytext, globals, locals, filename = "<string>", debugging = 0,
run_as_main = 0, profiling = 0):
if debugging:
import PyDebugger, bdb
BdbQuit = bdb.BdbQuit
else:
BdbQuit = 'BdbQuitDummyException'
pytext = string.split(pytext, '\r')
pytext = string.join(pytext, '\n') + '\n'
W.SetCursor("watch")
modname = os.path.basename(filename)
if modname[-3:] == '.py':
modname = modname[:-3]
if run_as_main:
globals['__name__'] = '__main__'
else:
globals['__name__'] = modname
globals['__file__'] = filename
sys.argv = [filename]
try:
code = compile(pytext, filename, "exec")
except:
tracebackwindow.traceback(1, filename)
return
try:
if debugging:
PyDebugger.startfromhere()
else:
MacOS.EnableAppswitch(0)
try:
if profiling:
import profile, ProfileBrowser
p = profile.Profile(ProfileBrowser.timer)
p.set_cmd(filename)
try:
p.runctx(code, globals, locals)
finally:
import pstats
stats = pstats.Stats(p)
ProfileBrowser.ProfileBrowser(stats)
else:
exec code in globals, locals
finally:
MacOS.EnableAppswitch(-1)
except W.AlertError, detail:
raise W.AlertError, detail
except (KeyboardInterrupt, BdbQuit):
pass
except:
if debugging:
sys.settrace(None)
PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
return
else:
tracebackwindow.traceback(1, filename)
if debugging:
sys.settrace(None)
PyDebugger.stop()
_identifieRE = regex.compile("[A-Za-z_][A-Za-z_0-9]*")
def _filename_as_modname(fname):
if fname[-3:] == '.py':
mname = fname[:-3]
if _identifieRE.match(mname) == len(mname):
return mname
def findeditor(topwindow, fromtop = 0):
wid = Win.FrontWindow()
if not fromtop:
if topwindow.w and wid == topwindow.w.wid:
wid = topwindow.w.wid.GetNextWindow()
if not wid:
return
window = W.getapplication()._windows[wid]
if not W.HasBaseClass(window, Editor):
return
return window.editgroup.editor
searchengine = SearchEngine()
tracebackwindow = Wtraceback.TraceBack()
"""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 lists 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-1997:
# Mitchell S. Chapman,
# Zachary Roadhouse,
# Tim Peters,
# Just van Rossum
__version__ = "0.3.1"
import string, regex
# 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 = [
"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"]
# Build up a regular expression which will match anything
# interesting, including multi-line triple-quoted strings.
commentPat = "#.*"
pat = "q[^\q\n]*\(\\\\[\000-\377][^\q\n]*\)*q"
quotePat = replace(pat, "q", "'") + "\|" + replace(pat, 'q', '"')
# Way to go, Tim!
pat = """
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 = "\(^\|[^a-zA-Z0-9_.\"']\)"
keyPat = nonKeyPat + "\("
for keyword in keywordsList:
keyPat = keyPat + keyword + "\|"
keyPat = keyPat[:-2] + "\)" + nonKeyPat
matchPat = keyPat + "\|" + commentPat + "\|" + tripleQuotePat + "\|" + quotePat
matchRE = regex.compile(matchPat)
idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*" # Ident w. leading whitespace.
idRE = regex.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
group = matchRE.group
idSearch = idRE.search
idGroup = idRE.group
tags = []
tags_append = tags.append
commentTag = 'comment'
stringTag = 'string'
keywordTag = 'keyword'
identifierTag = 'identifier'
start = 0
end = searchfrom
while 1:
start = search(pytext, end)
if start < 0 or start >= searchto:
break # EXIT LOOP
match = 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"]:
start = idSearch(pytext, end)
if start == end:
match = idGroup(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, `text[start:end]`
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):
self._pybuf = ""
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 = 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 = compile(self._pybuf + "\n", "<input>", "single")
except SyntaxError, err1:
pass
try:
code2 = 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
spacekey = ' '
returnkey = '\r'
tabkey = '\t'
enterkey = '\003'
backspacekey = '\010'
deletekey = '\177'
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
"""Widgets for the Macintosh. Built on top of FrameWork"""
__version__ = "0.1"
from Wbase import *
from Wcontrols import *
from Wtext import *
from Wlist 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 Message(text):
import EasyDialogs, Qd
Qd.InitCursor()
if text:
EasyDialogs.Message(text)
else:
EasyDialogs.Message('<Alert text not specified>')
import FrameWork
import Win
import Qd
import MacOS
import Events
import traceback
from types import *
import Menu; MenuToolbox = Menu; del Menu
class Application(FrameWork.Application):
def __init__(self, signature = 'Pyth'):
import W
W.setapplication(self, signature)
FrameWork.Application.__init__(self)
self._suspended = 0
self.quitting = 0
self.debugger_quitting = 1
self.DebuggerQuit = 'DebuggerQuitDummyException'
def mainloop(self, mask = FrameWork.everyEvent, wait = 0):
import W
self.quitting = 0
saveyield = MacOS.EnableAppswitch(-1)
try:
while not self.quitting:
try:
self.do1event(mask, wait)
except W.AlertError, detail:
MacOS.EnableAppswitch(-1)
W.Message(detail)
except self.DebuggerQuit:
MacOS.EnableAppswitch(-1)
except:
MacOS.EnableAppswitch(-1)
import PyEdit
PyEdit.tracebackwindow.traceback()
finally:
MacOS.EnableAppswitch(1)
def debugger_mainloop(self, mask = FrameWork.everyEvent, wait = 0):
import W
self.debugger_quitting = 0
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:
MacOS.EnableAppswitch(saveyield)
def idle(self, event):
if not self._suspended:
if not self.do_frontWindowMethod("idle", event):
Qd.InitCursor()
def do_frontWindowMethod(self, attr, *args):
wid = Win.FrontWindow()
if wid and self._windows.has_key(wid):
window = self._windows[wid]
if hasattr(window, attr):
handler = getattr(window, attr)
apply(handler, args)
return 1
def appendwindow(self, wid, window):
self._windows[wid] = window
self.makeopenwindowsmenu()
def removewindow(self, wid):
del self._windows[wid]
self.makeopenwindowsmenu()
def do_key(self, event):
(what, message, when, where, modifiers) = event
ch = chr(message & FrameWork.charCodeMask)
rest = message & ~FrameWork.charCodeMask
wid = Win.FrontWindow()
if modifiers & FrameWork.cmdKey:
if wid and self._windows.has_key(wid):
self.checkmenus(self._windows[wid])
else:
self.checkmenus(None)
event = (what, ord(ch) | rest, when, where, modifiers)
result = MenuToolbox.MenuKey(ord(ch))
id = (result>>16) & 0xffff # Hi word
item = result & 0xffff # Lo word
if id:
self.do_rawmenu(id, item, None, event)
return # here! we had a menukey!
#else:
# print "XXX Command-" +`ch`
# See whether the front window wants it
if wid and self._windows.has_key(wid):
window = self._windows[wid]
try:
do_char = window.do_char
except AttributeError:
do_char = self.do_char
do_char(ch, event)
# else it wasn't for us, sigh...
def do_inMenuBar(self, partcode, window, event):
Qd.InitCursor()
(what, message, when, where, modifiers) = event
self.checkopenwindowsmenu()
wid = Win.FrontWindow()
if wid and self._windows.has_key(wid):
self.checkmenus(self._windows[wid])
else:
self.checkmenus(None)
result = MenuToolbox.MenuSelect(where)
id = (result>>16) & 0xffff # Hi word
item = result & 0xffff # Lo word
self.do_rawmenu(id, item, window, event)
def do_updateEvt(self, event):
(what, message, when, where, modifiers) = event
wid = Win.WhichWindow(message)
if wid and self._windows.has_key(wid):
window = self._windows[wid]
window.do_rawupdate(wid, event)
else:
if wid:
wid.HideWindow()
import sys
sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
else:
MacOS.HandleEvent(event)
def suspendresume(self, onoff):
pass
def do_suspendresume(self, event):
# Is this a good idea???
(what, message, when, where, modifiers) = event
self._suspended = not message & 1
self.suspendresume(message & 1)
w = Win.FrontWindow()
if w:
# XXXX Incorrect, should stuff windowptr into message field
nev = (Events.activateEvt, w, when, where, message&1)
self.do_activateEvt(nev)
def checkopenwindowsmenu(self):
if self._openwindowscheckmark:
self.openwindowsmenu.menu.CheckItem(self._openwindowscheckmark, 0)
window = Win.FrontWindow()
if window:
for item, wid in self._openwindows.items():
if wid == window:
#self.pythonwindowsmenuitem.check(1)
self.openwindowsmenu.menu.CheckItem(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 makemenubar(self):
self.menubar = MenuBar(self)
FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
self.makeusermenus()
def scriptswalk(self, top, menu):
import os, macfs, string
try:
names = os.listdir(top)
except os.error:
FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
return
for name in names:
path = os.path.join(top, name)
name = string.strip(name)
if name[-3:] == '---':
menu.addseparator()
elif os.path.isdir(path):
submenu = FrameWork.SubMenu(menu, name)
self.scriptswalk(path, submenu)
else:
fss = macfs.FSSpec(path)
creator, type = fss.GetCreatorType()
if type == 'TEXT':
if name[-3:] == '.py':
name = name[:-3]
item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
self._scripts[(menu.id, item.item)] = path
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 modifiers & FrameWork.optionKey:
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?
MacOS.EnableAppswitch(0)
execfile(path, {'__name__': '__main__', '__file__': path})
except W.AlertError, detail:
MacOS.EnableAppswitch(-1)
raise W.AlertError, detail
except KeyboardInterrupt:
MacOS.EnableAppswitch(-1)
except:
MacOS.EnableAppswitch(-1)
import PyEdit
PyEdit.tracebackwindow.traceback(1)
else:
MacOS.EnableAppswitch(-1)
#os.chdir(cwd)
def openscript(self, filename, lineno = None, charoffset = 0):
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':
import imp
modname = os.path.basename(filename)[:-3]
try:
f, filename, (suff, mode, dummy) = imp.find_module(modname)
except ImportError:
raise W.AlertError, "Cant find file for %s" % modname
else:
f.close()
if suff == '.py':
self.openscript(filename, lineno, charoffset)
return
else:
raise W.AlertError, "Cant find file for %s" % modname
else:
raise W.AlertError, "Cant 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 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)
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 = Win.FrontWindow()
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
import Qd
import Win
import QuickDraw
import Evt
import string
from types import *
from SpecialKeys import *
import sys
WidgetsError = "WidgetsError"
DEBUG = 0
class Widget:
_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.SetPort()
self._visible = onoff
print 'Background'
if self._visible and self._backcolor:
penstate = Qd.GetPenState()
Qd.RGBForeColor(self._backcolor)
Qd.FrameRect(self._bounds)
Qd.RGBForeColor((0, 0, 0))
Qd.SetPenState(penstate)
for w in self._widgets:
w.show(onoff)
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):
#print "yep.", args
if len(args) == 1:
if type(args[0]) == FunctionType or type(args[0]) == MethodType:
self._possize = args[0]
else:
apply(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):
#print "xxx Closing Widget"
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()
Win.InvalRect(oldbounds)
Win.InvalRect(self._bounds)
def _calcbounds(self):
oldbounds = self._bounds
pl, pt, pr, pb = self._parent._bounds
if callable(self._possize):
width = pr - pl
height = pb - pt
self._bounds = Qd.OffsetRect(self._possize(width, height), pl, pt)
else:
l, t, r, b = self._possize
if l < -1:
l = pr + l
else:
l = pl + l
if t < -1:
t = pb + t
else:
t = pt + t
if r > 1:
r = l + r
else:
r = pr + r
if b > 1:
b = t + b
else:
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 = apply(w.forall, (methodname,) + args)
if rv:
return rv
if self._bindings.has_key("<" + methodname + ">"):
callback = self._bindings["<" + methodname + ">"]
rv = apply(callback, args)
if rv:
return rv
if hasattr(self, methodname):
method = getattr(self, methodname)
return apply(method, args)
def forall_butself(self, methodname, *args):
for w in self._widgets:
rv = apply(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 = apply(callback, args)
if rv:
return rv
if hasattr(self, methodname):
method = getattr(self, methodname)
rv = apply(method, args)
if rv:
return rv
for w in self._widgets:
rv = apply(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")
Win.InvalRect(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 " + `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()
Win.InvalRect(widget._bounds)
widget.close()
del self._widgetsdict[key]
self._widgets.remove(widget)
def __setattr__(self, attr, value):
if type(value) == InstanceType and HasBaseClass(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 __del__(self):
if DEBUG:
print "%s instance deleted" % self.__class__.__name__
def _drawbounds(self):
Qd.FrameRect(self._bounds)
class ClickableWidget(Widget):
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):
_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
thickrect = Qd.InsetRect(self._bounds, -3, -3)
state = Qd.GetPenState()
Qd.PenSize(2, 2)
if onoff:
Qd.PenPat(Qd.qd.black)
else:
Qd.PenPat(Qd.qd.white)
Qd.FrameRect(thickrect)
Qd.SetPenState(state)
def adjust(self, oldbounds):
self.SetPort()
if self._selected:
Win.InvalRect(Qd.InsetRect(oldbounds, -3, -3))
Win.InvalRect(Qd.InsetRect(self._bounds, -3, -3))
else:
Win.InvalRect(oldbounds)
Win.InvalRect(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.qd.black, color = (0, 0, 0)):
Widget.__init__(self, possize)
self._framepattern = pattern
self._framecolor = color
def setcolor(self, color):
self._framecolor = color
self.draw()
def setpattern(self, pattern):
self._framepattern = pattern
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)
class Group(Widget): pass
class HorizontalPanes(Widget):
_direction = 1
def __init__(self, possize, panesizes = None, gutter = 8):
ClickableWidget.__init__(self, possize)
self._panesizes = panesizes
self._gutter = gutter
self._enabled = 1
self.setuppanes()
def open(self):
self.installbounds()
ClickableWidget.open(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:
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 % (`panestart`, panestart and halfgutter,
`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.qd.gray)
Qd.PaintRect(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.qd.gray)
Qd.PaintRect(rect)
if self._direction:
rect = l, pos - 1, r, pos
else:
rect = pos - 1, t, pos, b
Qd.PenPat(Qd.qd.gray)
Qd.PaintRect(rect)
lastpos = pos
Qd.PaintRect(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):
_direction = 0
boundstemplate = "lambda width, height: (width * %s + %d, 0, width * %s + %d, height)"
# misc utils
def CallbackCall(callback, mustfit, *args):
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 apply(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 apply(callback, args)
elif not mustfit and minargs == 0:
return callback()
else:
if mustfit:
raise TypeError, "callback accepts wrong number of arguments: " + `len(args)`
else:
raise TypeError, "callback accepts wrong number of arguments: 0 or " + `len(args)`
def HasBaseClass(obj, class_):
try:
raise obj
except class_:
return 1
except:
pass
return 0
_cursors = {
"watch" : Qd.GetCursor(QuickDraw.watchCursor).data,
"arrow" : Qd.qd.arrow,
"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
}
def SetCursor(what):
Qd.SetCursor(_cursors[what])
import Ctl
import Controls
import Win
import Wbase
import Qd
import Evt
class ControlWidget(Wbase.ClickableWidget):
def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1):
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
def open(self):
self._calcbounds()
self._control = Ctl.NewControl(self._parentwindow.wid,
self._bounds,
self._title,
1,
self._value,
self._min,
self._max,
self._procID,
0)
self.SetPort()
Win.ValidRect(self._bounds)
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()
Win.ValidRect(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:
self._control.HiliteControl((not onoff) and 255)
def draw(self, visRgn = None):
if self._visible:
self._control.Draw1Control()
def test(self, point):
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
class Button(ControlWidget):
def __init__(self, possize, title = "Button", callback = None):
procID = Controls.pushButProc | Controls.useWFont
ControlWidget.__init__(self, possize, title, procID, callback, 0, 0, 1)
self._isdefault = 0
def push(self):
if not self._enabled:
return
import time
self._control.HiliteControl(1)
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
if self._isdefault and self._visible:
self.SetPort()
self.drawfatframe(onoff)
def activate(self, onoff):
self._activated = onoff
if self._enabled:
self._control.HiliteControl((not onoff) and 255)
if self._isdefault and self._visible:
self.SetPort()
self.drawfatframe(onoff)
def show(self, onoff):
ControlWidget.show(self, onoff)
if self._isdefault:
self.drawfatframe(onoff and self._enabled)
def draw(self, visRgn = None):
if self._visible:
self._control.Draw1Control()
if self._isdefault and self._activated:
self.drawfatframe(self._enabled)
def drawfatframe(self, onoff):
state = Qd.GetPenState()
if onoff:
Qd.PenPat(Qd.qd.black)
else:
Qd.PenPat(Qd.qd.white)
fatrect = Qd.InsetRect(self._bounds, -4, -4)
Qd.PenSize(3, 3)
Qd.FrameRoundRect(fatrect, 16, 16)
Qd.SetPenState(state)
def _setdefault(self, onoff):
self._isdefault = onoff
if self._control:
self.SetPort()
self.drawfatframe(onoff)
def adjust(self, oldbounds):
if self._isdefault:
old = Qd.InsetRect(oldbounds, -4, -4)
new = Qd.InsetRect(self._bounds, -4, -4)
Qd.EraseRect(old)
Win.InvalRect(old)
Win.InvalRect(new)
ControlWidget.adjust(self, oldbounds)
class CheckBox(ControlWidget):
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())
def set(self, value):
if self._control:
self._control.SetControlValue(value)
else:
self._value = value
def get(self):
if self._control:
return self._control.GetControlValue()
else:
return self._value
class RadioButton(ControlWidget):
def __init__(self, possize, title = "Radiobutton", 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)
def get(self):
if self._control:
return self._control.GetControlValue()
else:
return self._value
class Scrollbar(ControlWidget):
def __init__(self, possize, callback = None, value = 0, min = 0, max = 0):
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):
self._control.SetControlMinimum(min)
def setmax(self, min):
self._control.SetControlMinimum(max)
def getmin(self):
return self._control.GetControlMinimum()
def getmax(self):
return self._control.GetControlMinimum()
# internals
def click(self, point, modifiers):
if not self._enabled:
return
# custom TrackControl. A mousedown in a scrollbar arrow or page area should
# generate _control hits as long as the mouse is a) down, b) still in the same part
part = self._control.TestControl(point)
if Controls.inUpButton <= part <= Controls.inPageDown:
self._control.HiliteControl(part)
self._hit(part)
oldpart = part
while Evt.StillDown():
part = self._control.TestControl(point)
if part == oldpart:
self._control.HiliteControl(part)
self._hit(part)
else:
self._control.HiliteControl(0)
self.SetPort()
point = Evt.GetMouse()
self._control.HiliteControl(0)
elif part == Controls.inThumb:
part = self._control.TrackControl(point)
if part:
self._hit(part)
def _hit(self, part):
if part == Controls.inThumb:
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 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()
Win.InvalRect(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)
Win.ValidRect(self._bounds)
def activate(self, onoff):
self._activated = onoff
if self._visible:
if onoff:
self._control.ShowControl()
else:
self._control.HideControl()
self.draw(None)
Win.ValidRect(self._bounds)
def set(self, value):
if self._control:
self._control.SetControlValue(value)
else:
self._value = value
def get(self):
if self._control:
return self._control.GetControlValue()
else:
return self._value
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)
import W
from types import *
import string
"""
import Wdialogs
testDict1 = {1:1, 2:2, 3:3}
testDict2 = {3:3,4:4, 'testDict1':testDict1, 6:6, 7:7}
testDict3 = {3:3,4:4, 'testDict2':testDict2, 'testDict1':testDict1, 6:6, 7:7}
Wdialogs.EditDictionary(testDict3)
import Wdialogs
a = Wdialogs.Ask('xxx', 'default text', ['font', 'typografie', 'lettertonwerpen', 'huisstijl'])
"""
def Message(text, button = "OK"):
w = W.ModalDialog((300, 100))
w.button = W.Button((-90, -30, 80, 16), button, w.close)
w.message = W.TextBox((10, 10, -10, -40), text)
w.setdefaultbutton(w.button)
w.open()
def Ask(question, defaulttext = "", selections = []):
d = _Ask(question, defaulttext, selections)
return d.rv
class _Ask:
# selections is a list of possible for selections
def __init__(self, question, defaulttext, selections):
self.selections = []
for s in selections:
self.selections.append(string.lower(s))
self.selections.sort()
self.w = W.ModalDialog((300, 120))
self.w.button1 = W.Button((-90, -30, 80, 16), "OK", self.button1hit)
self.w.button2 = W.Button((-180, -30, 80, 16), "Cancel", self.button2hit)
self.w.question = W.TextBox((10, 10, -10, 30), question)
self.w.input = W.EditText((10, 40, -10, 20), defaulttext, self.processInput)
self.rv = None
self.w.setdefaultbutton(self.w.button1)
self.w.bind("cmd.", self.w.button2.push)
self.w.open()
def processInput(self, key, modifiers): # Process user input to match a selection
pos = self.w.input.getselection()
input = string.lower(self.w.input.get()[0:pos[1]])
if len(input):
for t in self.selections:
if input == t[0:pos[0]]:
self.w.input.set(t)
self.w.input.setselection(pos[0], pos[1])
return
self.w.input.set(input)
self.w.input.setselection(pos[1], pos[1])
def button1hit(self):
self.rv = self.w.input.get()
self.w.close()
def button2hit(self):
self.w.close()
class _AskYesNo:
def __init__(self, question, cancelFlag= 0):
if cancelFlag:
size = 190, 80
else: size = 150, 80
self.w = W.ModalDialog(size)
self.w.yes = W.Button((10, -36, 50, 24), 'Yes', self.yes)
if cancelFlag:
self.w.cancel = W.Button((70, -36, -70, 24), "Cancel", self.cancel)
self.w.no = W.Button((-60, -36, -10, 24), 'No', self.no)
self.w.question = W.TextBox((10, 10, -10, 30), question)
self.rv = None
self.w.setdefaultbutton(self.w.yes)
if cancelFlag:
self.w.bind("cmd.", self.w.cancel)
else: self.w.bind("cmd.", self.w.no)
self.w.open()
def yes(self):
self.rv = 1
self.w.close()
def no(self):
self.rv = 0
self.w.close()
def cancel(self):
self.rv = -1
self.w.close()
def AskYesNo(question):
d = _AskYesNo(question, 0)
return d.rv
def AskYesCancelNo(question):
d = _AskYesNo(question, 1)
return d.rv
class CallBackButton(W.Button):
def click(self, point, modifiers):
if not self._enabled:
return
part = self._control.TrackControl(point)
if part:
if self._callback:
self._callback(self.dict)
def push(self):
if not self._enabled:
return
import time
self._control.HiliteControl(1)
time.sleep(0.1)
self._control.HiliteControl(0)
if self._callback:
self._callback(self.dict)
class EditDictionary: # Auto layout editor of dictionary
def __init__(self, dictionary, title = 'Dictionary Editor'):
self.leading = 20
self.d = dictionary
keys = self.d.keys()
windowSize = 400, len(keys) * self.leading + 100
self.w = w = W.ModalDialog(windowSize)
y = 2 * self.leading
theFont = fontsettings = ('Geneva', 0, 10, (0,0,0))
keys.sort()
for key in keys:
if type(key) == StringType:
label = key
else: label = `key`
if type(self.d[key]) == StringType:
value = self.d[key]
else:
value = `self.d[key]` # Just show the value
if type(self.d[key]) == DictType: # Make a button
button = w[label] = CallBackButton((110, y, 50, 18), label, self.pushDict)
button.dict = self.d[key]
else:
w['k_' + label] = W.TextBox((10, y, 200, 18), label, fontsettings = theFont)
w[label] = W.EditText((110, y, -10, 18), value, fontsettings = theFont)
y = y + self.leading
w._name = W.TextBox((10, 4, 100, 10), title)
w._ok = W.Button((-160, -36, 60, 24), "OK", self.ok)
w._cancel = W.Button((-80, -36, 60, 24), "Cancel", self.cancel)
w.setdefaultbutton(self.w._ok)
self.rv = None # Return value
w.open()
def pushDict(self, dict):
EditDictionary(dict)
def popDict(self):
self.w.close()
def ok(self):
self.rv = 1
for key in self.d.keys():
if type(key) == StringType:
label = key
else: label = `key`
if type(self.d[key]) == StringType or self.d[key] == None:
self.d[key] = self.w[label].get()
else:
try:
self.d[key] = eval(self.w[label].get())
except:
pass
self.popDict()
def cancel(self):
self.rv = 0
self.popDict()
"""grid utility for widgets"""
class Grid:
def __init__(self, ncol = None,
minncol = None,
maxncol = None,
colwidth = None,
mincolwidth = None,
maxcolwidth = None,
width = None,
minwidth = None,
maxwidth = None,
vgrid = 8,
gutter = 10,
leftmargin = None,
rightmargin = None,
topmargin = None,
bottommargin = None
):
if leftmargin == None:
leftmargin = gutter
if rightmargin == None:
rightmargin = gutter
if topmargin == None:
topmargin = vgrid
if bottommargin == None:
bottommargin = vgrid
def getbounds(self, width, height, bounds):
xxx
import Wbase
import Scrap
from SpecialKeys import *
import string
import Evt
import Events
import Qd
import Win
class List(Wbase.SelectableWidget):
LDEF_ID = 0
def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1):
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.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):
import List
self._calcbounds()
self.SetPort()
rect = self._bounds
rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
self._list = 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()
if self._selected:
Win.InvalRect(Qd.InsetRect(oldbounds, -3, -3))
Win.InvalRect(Qd.InsetRect(self._bounds, -3, -3))
else:
Win.InvalRect(oldbounds)
Win.InvalRect(self._bounds)
if oldbounds[:2] == self._bounds[:2]:
# list still has the same upper/left coordinates, use LSize
l, t, r, b = self._bounds
width = r - l - 17
height = b - t - 2
self._list.LSize(width, height)
# now *why* deosn't the list manager recalc the cellrect???
l, t, r, b = self._list.LRect((0,0))
cellheight = b - t
self._list.LCellSize((width, cellheight))
else:
# oh well, sice 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 == uparrowkey:
if len(sel) >= 1 and min(sel) > 0:
newselection = [min(sel) - 1]
else:
newselection = [0]
elif char == 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 = ""
self.lasttyping = self.lasttyping + string.lower(char)
self.lasttime = Evt.TickCount()
i = self.findmatch(self.lasttyping)
newselection = [i]
if modifiers & Events.shiftKey:
newselection = newselection + sel
self.setselection(newselection)
self._list.LAutoScroll()
self.click((-1, -1), 0)
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]))
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:
Scrap.ZeroScrap()
Scrap.PutScrap('TEXT', text)
def can_copy(self, *args):
return len(self.getselection()) <> 0
def domenu_selectall(self, *args):
self.selectall()
def selectall(self):
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)
Qd.FrameRect(self._bounds)
if self._selected and self._activated:
self.drawselframe(1)
def adjust(self, oldbounds):
self.SetPort()
if self._selected:
Win.InvalRect(Qd.InsetRect(oldbounds, -3, -3))
Win.InvalRect(Qd.InsetRect(self._bounds, -3, -3))
else:
Win.InvalRect(oldbounds)
Win.InvalRect(self._bounds)
if oldbounds[:2] == self._bounds[:2]:
# list still has the same upper/left coordinates, use LSize
l, t, r, b = self._bounds
width = r - l - 17
height = b - t - 2
self._list.LSize(width, height)
# now *why* deosn't the list manager recalc the cellrect???
l, t, r, b = self._list.LRect((0,0))
cellheight = b - t
self._list.LCellSize((width, cellheight))
else:
# oh well, sice 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 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)
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)
Win.ValidRect(bounds)
else:
if self.drawingmode == 0 and self._list is not None:
self._list.LSetDrawingMode(0)
self.drawingmode = self.drawingmode + 1
class MultiList(List):
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)):
if i in selection:
set_sel(1, (0, i))
else:
set_sel(0, (0, i))
#self._list.LAutoScroll()
import FrameWork
import Qd
import Wbase
from types import *
import WFrameWorkPatch
_arrowright = Qd.GetPicture(472)
_arrowdown = Qd.GetPicture(473)
class PopupWidget(Wbase.ClickableWidget):
def __init__(self, possize, items = [], callback = None):
Wbase.Widget.__init__(self, possize)
self._items = items
self._itemsdict = {}
self._callback = callback
self._enabled = 1
def close(self):
Wbase.Widget.close(self)
self._items = None
self._itemsdict = {}
def draw(self, visRgn = None):
if self._visible:
Qd.FrameRect(self._bounds)
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")
reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
if reply:
id = (reply & 0xffff0000) >> 16
item = reply & 0xffff
self._menu_callback(id, item)
self._emptymenu()
def set(self, items):
self._items = 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 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):
def open(self):
self._calcbounds()
self.menu = WFrameWorkPatch.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 = WFrameWorkPatch.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")
reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
if reply:
id = (reply & 0xffff0000) >> 16
item = reply & 0xffff
self._menu_callback(id, item)
class FontMenu(PopupMenu):
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):
pass
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():
if FontMenu.menu is not None:
return
import W
FontMenu.menu = WFrameWorkPatch.Menu(W.getapplication().menubar, 'Foo', -1)
W.SetCursor('watch')
for i in range(FontMenu.menu.menu.CountMItems(), 0, -1):
FontMenu.menu.menu.DeleteMenuItem(i)
FontMenu.menu.menu.AppendResMenu('FOND')
def _getfontlist():
import Res
fontnames = []
for i in range(1, Res.CountResources('FOND') + 1):
r = Res.GetIndResource('FOND', i)
fontnames.append(r.GetResInfo()[2])
return fontnames
import os
import Qd
import Win
import Qt, QuickTime
import W
import macfs
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()
Win.InvalRect(oldbounds)
Win.InvalRect(self._bounds)
self.calcmoviebox()
def set(self, path_or_fss, start = 0):
self.SetPort()
if self.movie:
#Win.InvalRect(self.movie.GetMovieBox())
Qd.PaintRect(self.movie.GetMovieBox())
if type(path_or_fss) == type(''):
path = path_or_fss
fss = macfs.FSSpec(path)
else:
path = path_or_fss.as_pathname()
fss = path_or_fss
self.movietitle = os.path.basename(path)
movieResRef = Qt.OpenMovieFile(fss, 1)
self.movie, dummy = Qt.NewMovieFromFile(movieResRef, 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()
Win.InvalRect(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)
import Qd
import TE
import Fm
import waste
import WASTEconst
import Res
import Evt
import Events
import Scrap
import string
import Win
import Wbase
import Wcontrols
from SpecialKeys import *
import PyFontify
from types import *
import Fonts
import TextEdit
class TextBox(Wbase.Widget):
def __init__(self, possize, text = "", align = TextEdit.teJustLeft,
fontsettings = ("Monaco", 0, 9, (0, 0, 0)),
backcolor = (0xffff, 0xffff, 0xffff)
):
Wbase.Widget.__init__(self, possize)
self.fontsettings = fontsettings
self.text = text
self.align = align
self.backcolor = backcolor # Settings of editor added by Petr 9/7/97
def draw(self, visRgn = None):
if self._visible:
(font, style, size, color) = self.fontsettings
fontid = GetFNum(font)
savestate = Qd.GetPenState()
Qd.TextFont(fontid)
Qd.TextFace(style)
Qd.TextSize(size)
Qd.RGBForeColor(color)
Qd.RGBBackColor(self.backcolor) # Added by Petr 9/7/97
TE.TETextBox(self.text, self._bounds, self.align)
Qd.RGBBackColor((0xffff, 0xffff, 0xffff)) # Reset color Added by Petr 9/7/97
Qd.SetPenState(savestate)
def get(self):
return self.text
def set(self, text):
self.text = text
if self._parentwindow and self._parentwindow.wid:
self.SetPort()
self.draw()
class ScrollWidget:
# to be overridden
def getscrollbarvalues(self):
return None, None
# internal method
def updatescrollbars(self):
vx, vy = self.getscrollbarvalues()
if self._parent._barx:
if vx <> None:
self._parent._barx.enable(1)
self._parent._barx.set(vx)
else:
self._parent._barx.enable(0)
if self._parent._bary:
if vy <> None:
self._parent._bary.enable(1)
self._parent._bary.set(vy)
else:
self._parent._bary.enable(0)
UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
class EditText(Wbase.SelectableWidget, ScrollWidget):
def __init__(self, possize, text = "",
callback = None, inset = (3, 3),
fontsettings = ("Python-Sans", 0, 9, (0, 0, 0)),
readonly = 0):
Wbase.SelectableWidget.__init__(self, possize)
self.temptext = text
self.ted = None
self.selection = None
self._callback = callback
self.changed = 0
self.selchanged = 0
self._selected = 0
self._enabled = 1
self.wrap = 1
self.readonly = readonly
self.fontsettings = fontsettings
if type(inset) <> TupleType:
self.inset = (inset, inset)
else:
self.inset = inset
def open(self):
if not hasattr(self._parent, "_barx"):
self._parent._barx = None
if not hasattr(self._parent, "_bary"):
self._parent._bary = None
self._calcbounds()
self.SetPort()
viewrect, destrect = self._calctextbounds()
flags = self._getflags()
self.ted = waste.WENew(destrect, viewrect, flags)
self.ted.WEInstallTabHooks()
self.ted.WESetAlignment(WASTEconst.weFlushLeft)
self.setfontsettings(self.fontsettings)
self.ted.WEUseText(Res.Resource(self.temptext))
self.ted.WECalText()
if self.selection:
self.setselection(self.selection[0], self.selection[1])
self.selection = None
else:
self.selview()
self.temptext = None
self.updatescrollbars()
self.bind("pageup", self.scrollpageup)
self.bind("pagedown", self.scrollpagedown)
self.bind("top", self.scrolltop)
self.bind("bottom", self.scrollbottom)
self.selchanged = 0
def close(self):
self._parent._barx = None
self._parent._bary = None
self.ted = None
self.temptext = None
Wbase.SelectableWidget.close(self)
def getfontsettings(self):
import Res
(font, style, size, color) = self.ted.WEGetRunInfo(0)[4]
font = GetFName(font)
return (font, style, size, color)
def setfontsettings(self, (font, style, size, color)):
self.SetPort()
if type(font) <> StringType:
font = GetFName(font)
self.fontsettings = (font, style, size, color)
fontid = GetFNum(font)
readonly = self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, -1)
if readonly:
self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
selstart, selend = self.ted.WEGetSelection()
self.ted.WESetSelection(0, self.ted.WEGetTextLength())
self.ted.WESetStyle(WASTEconst.weDoFace, (0, 0, 0, (0, 0, 0)))
self.ted.WESetStyle(WASTEconst.weDoFace |
WASTEconst.weDoColor |
WASTEconst.weDoFont |
WASTEconst.weDoSize,
(fontid, style, size, color))
self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
self.ted.WECalText()
self.ted.WESetSelection(selstart, selend)
if readonly:
self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
viewrect = self.ted.WEGetViewRect()
Qd.EraseRect(viewrect)
self.ted.WEUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
self.selchanged = 1
self.updatescrollbars()
def adjust(self, oldbounds):
self.SetPort()
if self._selected and self._parentwindow._hasselframes:
Win.InvalRect(Qd.InsetRect(oldbounds, -3, -3))
Win.InvalRect(Qd.InsetRect(self._bounds, -3, -3))
else:
Win.InvalRect(oldbounds)
Win.InvalRect(self._bounds)
viewrect, destrect = self._calctextbounds()
self.ted.WESetViewRect(viewrect)
self.ted.WESetDestRect(destrect)
if self.wrap:
self.ted.WECalText()
if self.ted.WEGetDestRect()[3] < viewrect[1]:
self.selview()
self.updatescrollbars()
# interface -----------------------
# selection stuff
def selview(self):
self.ted.WESelView()
def selectall(self):
self.ted.WESetSelection(0, self.ted.WEGetTextLength())
self.selchanged = 1
self.updatescrollbars()
def selectline(self, lineno, charoffset = 0):
newselstart, newselend = self.ted.WEGetLineRange(lineno)
self.ted.WESetSelection(newselstart + charoffset, newselend)
self.selchanged = 1
self.updatescrollbars()
def getselection(self):
if self.ted:
return self.ted.WEGetSelection()
else:
return self.selection
def setselection(self, selstart, selend):
self.selchanged = 1
if self.ted:
self.ted.WESetSelection(selstart, selend)
self.ted.WESelView()
self.updatescrollbars()
else:
self.selection = selstart, selend
def offsettoline(self, offset):
return self.ted.WEOffsetToLine(offset)
def countlines(self):
return self.ted.WECountLines()
def getselectedtext(self):
selstart, selend = self.ted.WEGetSelection()
return self.ted.WEGetText().data[selstart:selend]
def expandselection(self):
oldselstart, oldselend = self.ted.WEGetSelection()
selstart, selend = min(oldselstart, oldselend), max(oldselstart, oldselend)
if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r':
selend = selend - 1
newselstart, dummy = self.ted.WEFindLine(selstart, 0)
dummy, newselend = self.ted.WEFindLine(selend, 0)
if oldselstart <> newselstart or oldselend <> newselend:
self.ted.WESetSelection(newselstart, newselend)
self.updatescrollbars()
self.selchanged = 1
def insert(self, text):
self.ted.WEInsert(text, None, None)
self.changed = 1
self.selchanged = 1
def shiftleft(self):
self.expandselection()
selstart, selend = self.ted.WEGetSelection()
selstart, selend = min(selstart, selend), max(selstart, selend)
snippet = self.getselectedtext()
lines = string.split(snippet, '\r')
for i in range(len(lines)):
if lines[i][:1] == '\t':
lines[i] = lines[i][1:]
snippet = string.join(lines, '\r')
self.insert(snippet)
self.ted.WESetSelection(selstart, selstart + len(snippet))
def shiftright(self):
self.expandselection()
selstart, selend = self.ted.WEGetSelection()
selstart, selend = min(selstart, selend), max(selstart, selend)
snippet = self.getselectedtext()
lines = string.split(snippet, '\r')
for i in range(len(lines) - 1):
lines[i] = '\t' + lines[i]
snippet = string.join(lines, '\r')
self.insert(snippet)
self.ted.WESetSelection(selstart, selstart + len(snippet))
# text
def set(self, text):
if not self.ted:
self.temptext = text
else:
self.ted.WEUseText(Res.Resource(text))
self.ted.WECalText()
self.SetPort()
viewrect, destrect = self._calctextbounds()
self.ted.WESetViewRect(viewrect)
self.ted.WESetDestRect(destrect)
rgn = Qd.NewRgn()
Qd.RectRgn(rgn, viewrect)
Qd.EraseRect(viewrect)
self.draw(rgn)
#Win.InvalRect(self.ted.WEGetViewRect())
self.updatescrollbars()
def get(self):
if not self._parent:
return self.temptext
else:
return self.ted.WEGetText().data
# events
def key(self, char, event):
(what, message, when, where, modifiers) = event
if self._enabled and not modifiers & Events.cmdKey or char in arrowkeys:
self.ted.WEKey(ord(char), modifiers)
if char not in navigationkeys:
self.changed = 1
if char not in scrollkeys:
self.selchanged = 1
self.updatescrollbars()
if self._callback:
Wbase.CallbackCall(self._callback, 0, char, modifiers)
def click(self, point, modifiers):
if not self._enabled:
return
self.ted.WEClick(point, modifiers, Evt.TickCount())
self.selchanged = 1
self.updatescrollbars()
return 1
def idle(self):
self.SetPort()
self.ted.WEIdle()
def rollover(self, point, onoff):
if onoff:
Wbase.SetCursor("iBeam")
def activate(self, onoff):
self._activated = onoff
if self._selected and self._visible:
if onoff:
self.ted.WEActivate()
else:
self.ted.WEDeactivate()
if self._selected:
self.drawselframe(onoff)
def select(self, onoff, isclick = 0):
if Wbase.SelectableWidget.select(self, onoff):
return
self.SetPort()
if onoff:
self.ted.WEActivate()
if self._parentwindow._tabbable and not isclick:
self.selectall()
else:
self.ted.WEDeactivate()
self.drawselframe(onoff)
def draw(self, visRgn = None):
if self._visible:
if not visRgn:
visRgn = self._parentwindow.wid.GetWindowPort().visRgn
self.ted.WEUpdate(visRgn)
if self._selected and self._activated:
self.drawselframe(1)
Qd.FrameRect(self._bounds)
# scrolling
def scrollpageup(self):
if self._parent._bary and self._parent._bary._enabled:
self.vscroll("++")
def scrollpagedown(self):
if self._parent._bary and self._parent._bary._enabled:
self.vscroll("--")
def scrolltop(self):
if self._parent._bary and self._parent._bary._enabled:
self.vscroll(0)
if self._parent._barx and self._parent._barx._enabled:
self.hscroll(0)
def scrollbottom(self):
if self._parent._bary and self._parent._bary._enabled:
self.vscroll(32767)
# menu handlers
def domenu_copy(self, *args):
selbegin, selend = self.ted.WEGetSelection()
if selbegin == selend:
return
Scrap.ZeroScrap()
self.ted.WECopy()
self.updatescrollbars()
def domenu_cut(self, *args):
selbegin, selend = self.ted.WEGetSelection()
if selbegin == selend:
return
Scrap.ZeroScrap()
self.ted.WECut()
self.updatescrollbars()
self.selview()
self.changed = 1
self.selchanged = 1
if self._callback:
Wbase.CallbackCall(self._callback, 0, "", None)
def domenu_paste(self, *args):
if not self.ted.WECanPaste():
return
self.selview()
self.ted.WEPaste()
self.updatescrollbars()
self.changed = 1
self.selchanged = 1
if self._callback:
Wbase.CallbackCall(self._callback, 0, "", None)
def domenu_clear(self, *args):
self.ted.WEDelete()
self.selview()
self.updatescrollbars()
self.changed = 1
self.selchanged = 1
if self._callback:
Wbase.CallbackCall(self._callback, 0, "", None)
def domenu_undo(self, *args):
which, redo = self.ted.WEGetUndoInfo()
if not which:
return
self.ted.WEUndo()
self.updatescrollbars()
self.changed = 1
self.selchanged = 1
if self._callback:
Wbase.CallbackCall(self._callback, 0, "", None)
def can_undo(self, menuitem):
which, redo = self.ted.WEGetUndoInfo()
which = UNDOLABELS[which]
if which == None:
return None
if redo:
which = "Redo "+which
else:
which = "Undo "+which
menuitem.settext(which)
return 1
def domenu_selectall(self, *args):
self.selectall()
# private
def getscrollbarvalues(self):
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
vx = Wcontrols._scalebarvalue(dr[0], dr[2], vr[0], vr[2])
vy = Wcontrols._scalebarvalue(dr[1], dr[3], vr[1], vr[3])
return vx, vy
def vscroll(self, value):
lineheight = self.ted.WEGetHeight(0, 1)
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
destheight = dr[3] - dr[1]
viewheight = vr[3] - vr[1]
viewoffset = maxdelta = vr[1] - dr[1]
mindelta = vr[3] - dr[3]
if value == "+":
delta = lineheight
elif value == "-":
delta = - lineheight
elif value == "++":
delta = viewheight - lineheight
elif value == "--":
delta = lineheight - viewheight
else: # in thumb
cur = (32767 * viewoffset) / (destheight - viewheight)
delta = (cur-value)*(destheight - viewheight)/32767
if abs(delta - viewoffset) <=2:
# compensate for irritating rounding error
delta = viewoffset
delta = min(maxdelta, delta)
delta = max(mindelta, delta)
self.ted.WEScroll(0, delta)
self.updatescrollbars()
def hscroll(self, value):
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
destwidth = dr[2] - dr[0]
viewwidth = vr[2] - vr[0]
viewoffset = maxdelta = vr[0] - dr[0]
mindelta = vr[2] - dr[2]
if value == "+":
delta = 32
elif value == "-":
delta = - 32
elif value == "++":
delta = 0.5 * (vr[2] - vr[0])
elif value == "--":
delta = 0.5 * (vr[0] - vr[2])
else: # in thumb
cur = (32767 * viewoffset) / (destwidth - viewwidth)
delta = (cur-value)*(destwidth - viewwidth)/32767
if abs(delta - viewoffset) <=2:
# compensate for irritating rounding error
delta = viewoffset
delta = min(maxdelta, delta)
delta = max(mindelta, delta)
self.ted.WEScroll(delta, 0)
self.updatescrollbars()
# some internals
def _getflags(self):
flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled | \
WASTEconst.weDoUndo
if self.readonly:
flags = flags | WASTEconst.weDoReadOnly
return flags
def _getviewrect(self):
return Qd.InsetRect(self._bounds, self.inset[0], self.inset[1])
def _calctextbounds(self):
viewrect = l, t, r, b = self._getviewrect()
if self.ted:
dl, dt, dr, db = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
yshift = t - vt
if (db - dt) < (b - t):
destrect = viewrect
else:
destrect = l, dt + yshift, r, db + yshift
else:
destrect = viewrect
return viewrect, destrect
class TextEditor(EditText):
def __init__(self, possize, text = "", callback = None, wrap = 1, inset = (4, 4),
fontsettings = ("Python-Sans", 0, 9, (0, 0, 0)),
readonly = 0):
EditText.__init__(self, possize, text, callback, inset, fontsettings, readonly)
self.wrap = wrap
def _getflags(self):
flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled | \
WASTEconst.weDoOutlineHilite
if self.readonly:
flags = flags | WASTEconst.weDoReadOnly
else:
flags = flags | WASTEconst.weDoUndo
return flags
def _getviewrect(self):
l, t, r, b = self._bounds
return (l + 5, t + 2, r, b - 2)
def _calctextbounds(self):
if self.wrap:
return EditText._calctextbounds(self)
else:
viewrect = l, t, r, b = self._getviewrect()
if self.ted:
dl, dt, dr, db = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
xshift = l - vl
yshift = t - vt
if (db - dt) < (b - t):
yshift = t - dt
destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
else:
destrect = (l, t, r + 5000, b)
return viewrect, destrect
def draw(self, visRgn = None):
if self._visible:
if not visRgn:
visRgn = self._parentwindow.wid.GetWindowPort().visRgn
self.ted.WEUpdate(visRgn)
if self._selected and self._activated:
self.drawselframe(1)
class PyEditor(TextEditor):
def __init__(self, possize, text = "", callback = None, inset = (4, 4),
fontsettings = ("Python-Sans", 0, 9, (0, 0, 0)),
readonly = 0,
debugger = None,
file = ''):
TextEditor.__init__(self, possize, text, callback, 0, inset, fontsettings, readonly)
self.bind("cmd[", self.shiftleft)
self.bind("cmd]", self.shiftright)
self.file = file # only for debugger reference
self._debugger = debugger
if debugger:
debugger.register_editor(self, self.file)
def setfile(self, file):
self.file = file
def set(self, text, file = ''):
oldfile = self.file
self.file = file
if self._debugger:
self._debugger.unregister_editor(self, oldfile)
self._debugger.register_editor(self, file)
TextEditor.set(self, text)
def close(self):
if self._debugger:
self._debugger.unregister_editor(self, self.file)
self._debugger = None
TextEditor.close(self)
def click(self, point, modifiers):
if not self._enabled:
return
if self._debugger and self.pt_in_breaks(point):
self.breakhit(point, modifiers)
elif self._debugger:
bl, bt, br, bb = self._getbreakrect()
Qd.EraseRect((bl, bt, br-1, bb))
TextEditor.click(self, point, modifiers)
self.drawbreakpoints()
else:
TextEditor.click(self, point, modifiers)
if self.ted.WEGetClickCount() >= 3:
# select block with our indent
lines = string.split(self.get(), '\r')
selstart, selend = self.ted.WEGetSelection()
lineno = self.ted.WEOffsetToLine(selstart)
tabs = 0
line = lines[lineno]
while line[tabs:] and line[tabs] == '\t':
tabs = tabs + 1
tabstag = '\t' * tabs
fromline = 0
toline = len(lines)
if tabs:
for i in range(lineno - 1, -1, -1):
line = lines[i]
if line[:tabs] <> tabstag:
fromline = i + 1
break
for i in range(lineno + 1, toline):
line = lines[i]
if line[:tabs] <> tabstag:
toline = i - 1
break
selstart, dummy = self.ted.WEGetLineRange(fromline)
dummy, selend = self.ted.WEGetLineRange(toline)
self.ted.WESetSelection(selstart, selend)
def breakhit(self, point, modifiers):
if not self.file:
return
offset, edge = self.ted.WEGetOffset(point)
lineno = self.ted.WEOffsetToLine(offset) + 1
if edge < 0:
self._debugger.clear_breaks_above(self.file, lineno)
else:
self._debugger.clear_breaks_above(self.file, self.countlines())
self._debugger.toggle_break(self.file, lineno)
def key(self, char, event):
(what, message, when, where, modifiers) = event
if modifiers & Events.cmdKey and not char in arrowkeys:
return
if char == '\r':
selstart, selend = self.ted.WEGetSelection()
selstart, selend = min(selstart, selend), max(selstart, selend)
lastchar = chr(self.ted.WEGetChar(selstart-1))
if lastchar <> '\r' and selstart:
pos, dummy = self.ted.WEFindLine(selstart, 0)
lineres = Res.Resource('')
self.ted.WECopyRange(pos, selstart, lineres, None, None)
line = lineres.data + '\n'
tabcount = self.extratabs(line)
self.ted.WEKey(ord('\r'), 0)
for i in range(tabcount):
self.ted.WEKey(ord('\t'), 0)
else:
self.ted.WEKey(ord('\r'), 0)
elif char in ')]}':
self.ted.WEKey(ord(char), modifiers)
self.balanceparens(char)
else:
self.ted.WEKey(ord(char), modifiers)
if char not in navigationkeys:
self.changed = 1
self.selchanged = 1
self.updatescrollbars()
def balanceparens(self, char):
if char == ')':
target = '('
elif char == ']':
target = '['
elif char == '}':
target = '{'
recursionlevel = 1
selstart, selend = self.ted.WEGetSelection()
count = min(selstart, selend) - 2
mincount = max(0, count - 2048)
lastquote = None
while count > mincount:
testchar = chr(self.ted.WEGetChar(count))
if testchar in "\"'" and chr(self.ted.WEGetChar(count - 1)) <> '\\':
if lastquote == testchar:
recursionlevel = recursionlevel - 1
lastquote = None
elif not lastquote:
recursionlevel = recursionlevel + 1
lastquote = testchar
elif not lastquote and testchar == char:
recursionlevel = recursionlevel + 1
elif not lastquote and testchar == target:
recursionlevel = recursionlevel - 1
if recursionlevel == 0:
import time
autoscroll = self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, -1)
if autoscroll:
self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
self.ted.WESetSelection(count, count + 1)
time.sleep(0.2)
self.ted.WESetSelection(selstart, selend)
if autoscroll:
self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
break
count = count - 1
def extratabs(self, line):
tabcount = 0
for c in line:
if c <> '\t':
break
tabcount = tabcount + 1
last = 0
cleanline = ''
tags = PyFontify.fontify(line)
# strip comments and strings
for tag, start, end, sublist in tags:
if tag in ('string', 'comment'):
cleanline = cleanline + line[last:start]
last = end
cleanline = cleanline + line[last:]
cleanline = string.strip(cleanline)
if cleanline and cleanline[-1] == ':':
tabcount = tabcount + 1
else:
for open, close in (('(', ')'), ('[', ']'), ('{', '}')):
count = string.count(cleanline, open)
if count and count <> string.count(cleanline, close):
tabcount = tabcount + 2
break
return tabcount
def rollover(self, point, onoff):
if onoff:
if self._debugger and self.pt_in_breaks(point):
Wbase.SetCursor("arrow")
else:
Wbase.SetCursor("iBeam")
def draw(self, visRgn = None):
TextEditor.draw(self, visRgn)
if self._debugger:
self.drawbreakpoints()
def showbreakpoints(self, onoff):
if (not not self._debugger) <> onoff:
if onoff:
import PyDebugger
self._debugger = PyDebugger.getdebugger()
self._debugger.register_editor(self, self.file)
elif self._debugger:
self._debugger.unregister_editor(self, self.file)
self._debugger = None
self.adjust(self._bounds)
def togglebreakpoints(self):
self.showbreakpoints(not self._debugger)
def clearbreakpoints(self):
if self.file:
self._debugger.clear_all_file_breaks(self.file)
def editbreakpoints(self):
if self._debugger:
self._debugger.edit_breaks()
self._debugger.breaksviewer.selectfile(self.file)
def drawbreakpoints(self, eraseall = 0):
breakrect = bl, bt, br, bb = self._getbreakrect()
br = br - 1
self.SetPort()
Qd.PenPat(Qd.qd.gray)
Qd.PaintRect((br, bt, br + 1, bb))
Qd.PenNormal()
self._parentwindow.tempcliprect(breakrect)
Qd.RGBForeColor((0xffff, 0, 0))
try:
lasttop = bt
self_ted = self.ted
Qd_PaintOval = Qd.PaintOval
Qd_EraseRect = Qd.EraseRect
for lineno in self._debugger.get_file_breaks(self.file):
start, end = self_ted.WEGetLineRange(lineno - 1)
if lineno <> self_ted.WEOffsetToLine(start) + 1:
# breakpoints beyond our text: erase rest, and back out
Qd_EraseRect((bl, lasttop, br, bb))
break
(x, y), h = self_ted.WEGetPoint(start, 0)
bottom = y + h
#print y, (lasttop, bottom)
if bottom > lasttop:
Qd_EraseRect((bl, lasttop, br, y + h * eraseall))
lasttop = bottom
redbullet = bl + 2, y + 3, bl + 8, y + 9
Qd_PaintOval(redbullet)
else:
Qd_EraseRect((bl, lasttop, br, bb))
Qd.RGBForeColor((0, 0, 0))
finally:
self._parentwindow.restoreclip()
def updatescrollbars(self):
if self._debugger:
self.drawbreakpoints(1)
TextEditor.updatescrollbars(self)
def pt_in_breaks(self, point):
return Qd.PtInRect(point, self._getbreakrect())
def _getbreakrect(self):
if self._debugger:
l, t, r, b = self._bounds
return (l+1, t+1, l + 12, b-1)
else:
return (0, 0, 0, 0)
def _getviewrect(self):
l, t, r, b = self._bounds
if self._debugger:
return (l + 17, t + 2, r, b - 2)
else:
return (l + 5, t + 2, r, b - 2)
def _calctextbounds(self):
viewrect = l, t, r, b = self._getviewrect()
if self.ted:
dl, dt, dr, db = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
xshift = l - vl
yshift = t - vt
if (db - dt) < (b - t):
yshift = t - dt
destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
else:
destrect = (l, t, r + 5000, b)
return viewrect, destrect
def GetFNum(font):
if font <> 'Chicago':
fontid = Fm.GetFNum(font)
if fontid == 0:
fontid = Fonts.monaco
else:
fontid = 0
return fontid
def GetFName(fontid):
try:
res = Res.GetResource('FOND', fontid)
except Res.Error:
fontname = 'Monaco'
else:
fontname = res.GetResInfo()[2]
return fontname
import traceback
import sys
import W
import os
import types
class TraceList(W.List):
LDEF_ID = 468
def createlist(self):
import List
self._calcbounds()
self.SetPort()
rect = self._bounds
rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
self._list = List.LNew(rect, (0, 0, 1, 0), (0, 28), self.LDEF_ID, self._parentwindow.wid,
0, 1, 0, 1)
self.set(self.items)
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_type, sys.exc_value, sys.exc_traceback
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:
charno = charno - 1
text = value + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "" + line[charno:-1]
else:
text = 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:
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 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 = TraceList((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", self.browselocals)
self.w.browselocalsbutton.enable(0)
self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem", 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 "' + filename + '", line ' + `lineno` + ', in ' + func
else:
tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + 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)
import Qd
import Win
import Evt
import Fm
import FrameWork
import Windows
import Events
import Wbase
import Wlist
import Dlg
import MacOS
import Menu
import struct
from types import *
from SpecialKeys import *
class Window(FrameWork.Window, Wbase.SelectableWidget):
windowkind = Windows.documentProc
def __init__(self, possize, title = "", minsize = None, maxsize = None, tabbable = 1, show = 1):
Wbase.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
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:
self.windowkind = self.windowkind | 4
import W
if not W._application:
raise W.WidgetsError, 'W not properly initialized: unknown Application'
FrameWork.Window.__init__(self, W._application)
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 getbounds(self):
if 0: #self.isvisible():
self.wid.GetWindowContentRgn(scratchRegion)
self._globalbounds = GetRgnBounds(scratchRegion)
return self._globalbounds
def select(self):
self.wid.SelectWindow()
def open(self):
self.wid = Win.NewCWindow(self._globalbounds, self.title, self._show,
self.windowkind, -1, 1, 0)
self.SetPort()
fnum = Fm.GetFNum("Python-Sans")
if fnum == 0:
fnum = Fm.GetFNum("Geneva")
Qd.TextFont(fnum) # XXX font&size from a function?
Qd.TextSize(9) # XXX font&size from a function?
if self._bindings.has_key("<open>"):
callback = self._bindings["<open>"]
callback()
for w in self._widgets:
w.forall_frombottom("open")
self._maketabchain()
if self._tabchain:
self._tabchain[0].select(1)
if self._tabbable:
self.bind('tab', self.nextwidget)
self.bind('shifttab', self.previouswidget)
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>"]
rv = callback()
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 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 y == None:
x, y = x
if self._hasgrowbox:
self.SetPort()
Win.InvalRect(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 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")
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
self._currentwidget.idle()
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 Wbase.HasBaseClass(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()
Win.InvalRect(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):
for w in widgets:
if w._selectable:
self._tabchain.append(w)
if Wbase.HasBaseClass(w, Wlist.List):
self._hasselframes = 1
self._collectselectablewidgets(w._widgets)
def _calcbounds(self):
self._possize = self.wid.GetWindowPort().portRect[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):
(what, message, when, where, modifiers) = event
key = char
if keynames.has_key(key):
key = keynames[char]
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("draw", window.GetWindowPort().visRgn)
if self._drawwidgetbounds:
self.forall("_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):
Win.InvalRect(self.getgrowrect())
self._calcbounds()
# utilities
def tempcliprect(self, tempcliprect):
tempclip = Qd.NewRgn()
Qd.RectRgn(tempclip, tempcliprect)
self.tempclip(tempclip)
def tempclip(self, tempclip):
if hasattr(self, "saveclip"):
raise Wbase.WidgetsError, "already have saveclip"
self.saveclip = Qd.NewRgn()
Qd.GetClip(self.saveclip)
Qd.SectRgn(self.wid.GetWindowPort().visRgn, tempclip, tempclip)
Qd.SetClip(tempclip)
def restoreclip(self):
Qd.SetClip(self.saveclip)
del self.saveclip
def getgrowrect(self):
l, t, r, b = self.wid.GetWindowPort().portRect
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.qd.screenBits.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
if not W._application:
raise W.WidgetsError, 'W not properly initialized: unknown Application'
Dialog.open(self)
self.app = W._application
self.done = 0
Menu.HiliteMenu(0)
self.mainloop()
def close(self):
if not self.wid:
return # we are already closed
self.done = 1
del self.app
Dialog.close(self)
def mainloop(self):
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)
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":
MacOS.HandleEvent(event)
return
if wid == self.wid:
try:
handler = getattr(self, name)
except AttributeError:
handler = self.app.do_unknownpartcode
else:
#MacOS.HandleEvent(event)
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 = Win.FrontWindow()
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(
"Cant find window or widget to insert text into; copy to clipboard instead?",
1) == 1:
import Scrap
Scrap.ZeroScrap()
Scrap.PutScrap('TEXT', 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
union = Qd.UnionRect(bounds, Qd.qd.screenBits.bounds)
if union == Qd.qd.screenBits.bounds:
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.qd.screenBits.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)
# copyright 1997 Just van Rossum, Letterror. just@knoware.nl
# keep this (__main__) as clean as possible, since we are using
# it like the "normal" interpreter.
__version__ = '0.9b1'
def init():
import sys
import MacOS
if sys.version[:5] == '1.5a3':
def MyEnableAppswitch(yield,
table = {-1:0, 0:-1, 1:1},
EnableAppswitch = MacOS.EnableAppswitch):
return table[EnableAppswitch(table[yield])]
MacOS.EnableAppswitch = MyEnableAppswitch
MacOS.EnableAppswitch(-1)
import Qd, QuickDraw
Qd.SetCursor(Qd.GetCursor(QuickDraw.watchCursor).data)
import os
# kludge to keep stdwin's TextEdit.py out the door...
import string
for i in range(len(sys.path)):
path = sys.path[i]
if string.find(path, 'stdwin') > 0:
del sys.path[i]
break
try:
import SpecialKeys # if this succeeds, we should have everything we need inside the applet.
del SpecialKeys
except ImportError:
# personal hack for me
wherearewe = os.getcwd()
import Res, macfs
if os.path.exists(os.path.join(wherearewe, 'IDELib')):
sys.path.append(os.path.join(wherearewe, ':IDELib'))
sys.path.append(os.path.join(wherearewe, ':IDELib:Widgets'))
Res.FSpOpenResFile(macfs.FSSpec(os.path.join(wherearewe, ':IDELib:Resources:Widgets.rsrc')), 1)
Res.FSpOpenResFile(macfs.FSSpec(os.path.join(wherearewe, 'PythonIDE.rsrc')), 1)
else:
oneback = os.path.split(wherearewe)[0]
sys.path.append(os.path.join(oneback, ':Fog:Widgets'))
Res.FSpOpenResFile(macfs.FSSpec(os.path.join(oneback, ':Fog:Resources:Widgets.rsrc')), 1)
Res.FSpOpenResFile(macfs.FSSpec(os.path.join(wherearewe, 'PythonIDE.rsrc')), 1)
init()
del init
##import trace
##trace.set_trace()
import PythonIDEMain
(This file must be converted with BinHex 4.0) :$P"jG'K[ENP%45jbFh*M!(*cFQ058d9%!3#3"b`Nd"S!N!3"!!!!+ci!!#Sq!!! !j[HEcGlIHUcGhQHEhHhhR0lYji[YlIqEhrlr!1rpr`2f$P"jG'K[ENP%45jbFh* MFQ9ZBf9cER0TEfjdC@jdFh-!!(*cFQ058d9%!3!!3!!"!*!5XK52a3#3"L`N!$, Vra0TQplGjTV1hGpj[HhYHmhYhhUqh[Ir"1rrHElHp2m&D*hIpjhIqrm"qFqcr`( `!#[Vra2fQmlGlRQphGjTR0lGk+hHhrLphrAr!QLph[6r"@LXlQLYhk[r!I!2*ZV r$RV-lGhiUqlYpT[GhZqXhr(r!fLYlHrer`4iVGriV`!!+2)SmJ#3"@J"C!!4![m -!2rq!!!!5!!!!%J!N!GS!@3!N!8"!!S!N!9S!@3!Q)&N!*!&D!&N!*!*5!!!!%J !N!8)!!%!#!#3$bJ!!!$r!!$rN!B!!Ik3"J!#rC!'!!2mN!B!"2Z3"J!&qT!'!!E jN!B!"rL3"J!)pj!'!!RfN!B!#[@3"J!,p*!'!!ccN!B!$I+3"J!1mC!'!!r`N!B !%1q3"J!4lT!'!",YN!B!%qb3"J!8kj!'!"AUN!B!&ZQ3"J!Ak*!'!"MRN!B!'HD 3"J!DjC!'!"[NN!B!(113"J!GiT!'!"lKN!B!(q#3"J!Jhj!'!#(HN!B!)Yf3"J! Mh*!'!#6EN!B!*GU3"J!QfC!'!#IBN!B!+0H3"J!TeT!'!#V9N!B!+p53"J!Xdj! '!#h5N!B!,Y'3"J![d*!'!$$2N!B!-Fk3"J!bcC!'!$2-N!B!0-Z3"J!ebT!'!$E *N!B!0mL3"J!iaj!'!$R'N!B!1X@3"J!la*!'!$c$N!B!2F+3"J!q`C!'!$r!N!B !3,q3"J""[T!'!%+pN!B!3lb3"J"%Zj!'!%@kN!B!4VQ3"J"(Z*!'!%LhN!B!5ED 3"J"+YC!'!%ZdN!B!6,13"J"0XT!'!%kaN!B!6l#3"J"3Vj!'!&'ZN!B!8Uf3"J" 6V*!'!&5VN!B!9DU3"J"@UC!'!&HSN!B!@+H3"J"CTT!'!&UPN!B!@k53"J"FSj! '!&fLN!B!AU'3"J"IS*!'!'#IN!B!BCk3"J"LRC!'!'1FN!B!C*Z3"J"PQT!'!'D CN!B!CjL3"J"SPj!'!'Q@N!B!DT@3"J"VP*!'!'b6N!B!EC+3"J"ZNC!'!'q3!*! '!(#2N!B!FBk3"J"bMC!'!(1-N!B!G)Z3"J"eLT!'!(D*N!B!GiL3"J"iKj!'!(Q 'N!B!HS@3"J"lK*!'!(b$N!B!IB+3"J"qJC!'!(q!N!B!J(q3"J#"IT!'!)*pN!B !Jhb3"J#%Hj!'!)9kN!B!KRQ3"J#(H*!'!)KhN!B!LAD3"J#+GC!'!)YdN!B!M(1 3"J#0FT!'!)jaN!B!Mh#3"J#3!'q3"J#4ET!'!**YN!B!Nfb3"J#8Dj!'!*9UN!B !PQQ3"J#AD*!'!*KRN!B!Q@D3"J#DCC!'!*YNN!B!R'13"J#GBT!'!*jKN!B!Rf# 3"J#JAj!'!+&HN!B!SPf3"J#MA*!'!+4EN!B!T9U3"J#Q@C!'!+GBN!B!U&H3"J# T9T!'!+T9N!B!Ue53"J#X8j!'!+e5N!B!VP'3"J#[8*!'!,"2N!B!X8k3"J#b6C! '!,0-N!B!Y%Z3"J#e5T!'!,C*N!B!YdL3"J#i4j!'!,P'N!B!ZN@3"J#l4*!'!,a $N!B![8+3"J#q3C!'!,p!N!B!`$q3"J$"2T!'!-)pN!B!`cb3"J$%1j!'!-8kN!B !aMQ3"J$(1*!'!-JhN!B!b6D3"J$+0C!'!-XdN!B!c$13"J$0-T!'!-iaN!B!cc# 3"J$3,j!'!0%ZN!B!dLf3"J$6,*!'!03VN!B!e5U3"J$@+C!'!0FSN!B!f#H3"J$ C*T!'!0SPN!B!fb53"J$F)j!'!0dLN!B!hL'3"J$I)*!'!1!IN!B!i4k3"J$L(C! '!1-FN!B!j"Z3"J$P'T!'!1BCN!B!jaL3"J$S&j!'!1N@N!B!kK@3"J$V&*!'!1` 6N!B!l4+3"J$Z%C!'!1m3N!B!m!q3"J$a$T!'!2)0N!B!m`b3"J$d#j!'!28+N!B !pJQ3"J$h#*!'!2J(N!B!q3D3"J$k"C!'!2X%N!B!r!13"J$p!T!'!2i"N!B!r`# 3#fJ"C!#3"@J"C!!!!!D"!)%!R3!!"S%!J3#G!!!'J3#"!*d!!!D"!)%!R3!!)S) !!$Vr1[X!rMVl!2ikk3$q1[X!!Kdk1[X!!Kdk1X)!R3!!0i8!!`UGrrrqr`1,!!U ,r2m$L`S+Lrcr!BX+l`!"#S[mr`1,#J"kr2m%R3S!H[$pr`'G#X8!R3!!,BB!!6V Mr[rpr`(9irVrrq2kr`(M(I%!!4h9q[m"ipAkr`(`eIVr!I!kaJ#G!!!AKJ!!eIh rk[m![[%!!,lQr`(M#XF!R3!!&SF!!(,mrqRr!&rc!!"Ij2m!FXF!R3!!&SF!!,l mrqRr!*hc!!#,j2m![XF!R3!!&SF!!2$mrqRr!0Ac!!#qj2m!m-F!R3!!&)F!!2$ mrqRr!12c!!$9irr(!*d!!"D(!!#qr2rTr`#Ym`!!RH6r!,l(!*d!!#U(!!#,r2r jr`,M[Z2dr`4b!"dk1[F!!(,dr`,M[YAdr`5,!"dk1XX!R3!!2)F!!3V`rIrmr`, `FJVq!!%+F[Ir!Z1,m2lr![#,#[S!!3VMprm"HJVp!!&bm2Mr![#,m2hr!Cd+cJ# G!!!XKJ!!F[hrrIm"e4hk!!%kir(r!H-GqJ!!6IRr!I!kqJ!"(GAar`(`1Xm!R3! !*iB!!0Aprrhr!$Vi!!!km2m![[S!!+hjr`"0q!!!1[$r!H-+d!#G!!!QK`!!F[c rr[m!LrB!!*h`r`"Ir!!!ArRr!+hf!!#,m2m!HY!!R3!!*SF!!,lmrrlr!$Vf!!" Im2m!VI`!!*hjr`"bpJ!!1[$r!,l3!*d!!#5(!!$`r2rqr`!+pJ!!1[$r!12m!!$ 9qIm!1[B!!!V[rp!!R3!!()F!qrrqrr8!!!V[rr`!!12jr`!Gp3$[rp!!R3!!*SF !!0Amrrlr!$Vf!!!km2m![[`!!+hjr`"0pJ!!1[$r!123!*d!!*Rh!!%+(IS!!3S GqJ!"#Khk!!%+1[S!!3SkqJ!"#MVk!!%+1[S!!3Skq3!!1[!!!$Vj!!!kq3!$1J! !RIcrr[m!F[B!!(V`r`#,r!!!H[Rr!)[f!!"Im2m$V3!!1[N!!6S+m3!"1JVk!!% k#[S!!6S+qJ!"1JVk!!%G#[S!!4d+qJ!"(3Vk!!%G#[S!!4d+qJ!"(3Vk!2mGj3! "$2S!#afGm2rrm+dk!!UGirlr"Eik!!UGirlr"Eik!!UGirlr"Eik!!UGirlr"Ei k!!U,irlr"Eik!!U,irlr"Ej0!!U,irlr"Ej0!!U,irlr!G90p`!##RVMr[m&[Nd !!(V9r[m&[R)!!(V9r[m#eB[`rIrqr`(M#[J!!3V`mIm"m!Vm!!%+irVr!I!Gq!! "#Z2`r`&k[[lr"H1,#J"0[[lr!Z0k#[F!!8h9r[m&iiX+!%fqr[m&iiX+!$Uqr[m &ijd+!$Uqr[m&ijd+!$Uqr[m&ijd+!$Uqr[m[ijd+!$Uqm2rrijd+!$UYm2rrikd G!$UYm2rrm+dG!$UYm2rrm+dG!$UYm2rrm+dGk!!!S[X!!8h`q[m"Lr$kr`'Gm2V r!Ch`q[m"RI$kr`'GirVr!ChMq[m"VH2kr`'YirVr!+hj!!%kirVr!Dh9q[m"[YA errhr!*hi!!#Ym2m!ArS!!%hjr`#Yq!!!LqMr!H1Yq[m"m$Vj!!#Yq[m"ijhkr`( MRIcrrrm"m*hkr`(`RIVr!I#Gq[m"m*hkr`(`LrVr!I#Gq[m"m*hkr`(`RIRr!&r T!!!jr!!"1[#`r`#,q`!"#YALrrhr!$Vi!!"0m2m![[S!!+hjr`"bq!!!1Ylr!G8 +q`!!HZRrYIm!1ZS!!$Em!!#YV[m!(I`!!(,Krrlr!*hf!!#Ym2m!Ar`!!%hjr`# qpJ!!RGlr!(Vm!!!Gk2qer`$9kJ!!0[d!!!UYr`"br!!!eH(rr[m!6IB!!(,`r`# Gr!!!RIRr!(Vf!!"0h[m!eI`!!(,Srl6r!"hV!!!br3!!1Uhr!,lm!1$rr[m!1[B !!$V`r`$`r!!![[Rr!$Vf!!!GhIrm!!#Yk2qdr`!kk`!!-2d!!$UYr`#qr!$Jrrl r!!Vf!!!Gm2m!m2`!!0Ajr`!kp3$Grr`!!+hSrl6r!&rV!!!fr3!!#Uhr!(Vm!!$ 9iIrqr`!kpJ!!6I$r!,lm!!#GqIm!ArB!!$VHr`$Mr!!!HZMrY2m!1ZX!!([m!!$ Mmrm!irRr!12jr`$MqIm!iqIr!0Acr`C0!!!k!!#Gmrm!ir$r!q2rrhVf!!0krrr Mmrm'HJ!!1J!!F[Rr!)[f!!"bp[m!eIRr!12cr`DY!!!G!!!kmrm!irRr!H2`q[m "ir$Sr`(Mm2(rrr$krrr`mrrr!2m+lJ!!h[`!!&rhrb,`Aad!!!T0eIr`FMS!!!T 0eIr`FMS!!!Sk[[r`FMS!!!Sk[Zhr!ASkrJ!"1Vlhr`,9HYAqr`'qH[Er!ASkrJ! "1Uhfr`+,1J$r!!)kL`Vi!!)GHMVq!!%kLrIr!["I[[lr!Y9kirVr!I!Gq!!"#Z2 jr`'Y1[i!#MTkrrqY1JS!!$Tkp[m(FVl`rrr9LpAhr`fq1JS!!$Tbm2qq1JS!!!X kF[$re8d+!!!GF[$Zr`I963S!!"eIm2Ir%100(3!!(9r`rq00(3!!(8h`prm(Lkh MrrrMV4ha!!#Mq`!!VIRr!Ei+qJ!"FKhk!!&b(IS!!A)GqJ!!F[$r!G8kqJ!!FZI r!H-kqJ!"6I$kr`(`1[i!r3!!#[J!!!Vk!!%km2Rr!2$kr`$`qIm!VIJ!!)[kr`( `6IS!!6T0qJ!"1YAjr`$`q[m!m2Mr!(,k!!%GAr`!r`!"(A,k!!%GeI$r!(Vk!!% +VIRr!Cd+q`!##R)+q`!"#Uhir`$`qrm"m&rb!!"Fr!!"(I$kr`(`#Yd!!)[br`( `(IJ!!(VSr`!kq!!!F[Vr!$Vp!1S!!%hSr`"bq!!!1[Vr!(,[!!!kk2m!Lr)!p3! "#[$br`#Yq!!"#Z2lr`#ql`!"#Z2`r`!km`!!@I`!!,ljr`"Ih!!"#Z2cr`"bpJ! !iqVr!(Vf!!#qr2m!RI`!k3!!VHVr!,lf!!#Gr2m![Zd!!(VUr`(M#[)!p!!!Ar2 r!I!+p`!!1[[r!"hZ!!!km2m!eI-!!&$m!2MrfJ!!RI2r!"hf!!#,k[m!1[B!!(V mr`!kr!$T!!"Ik[m!F[B!!$Vmr`"kl3!!1ZVr!)[a!23!!!Vcr`#qp3$mr`#ql!! !m2$r!"hd!!"5r3!!1[Rr!,lD!!"bp2m!m28!!&rUrr8!!$Vmr`!+r!$T!!!kk[m !1[B!!!Vmr`!kl!$Ur`"Im3$c!!$Mp2m!H[8!!,lpr`#,l!!![[$r!%hd!!"3r3! !1[Rr!,lD!!"0p2m!eI8!!$VUrr8!!$VmrrX!k3!!#ZVr!"he!2cr!$VX!!$Mkrm !1[%!m`!![[6r!(Ve!!#qrIm!HZ`!!*h`r`"bp!!!92d!!"hjr`$MfJ!!H[2rp3! !FZVr!"hf!!"0r2m!1[`!k3!!1ZVr!%hf!!!kr2m!Aqd!!!VUr`"km3$c!!$`p2m !Lr8!!12pr`#Gl!!![[$r!$Vd!!"Ur!!!m2Rr!!VE!!1qrrrMp[m!1[B!!*hUr`" 0pJ!!H[cr!&rm!1N!!(,Ur`"kpJ!'Arrrm2rrLqd!!cVrrr$`r`2MrrqYm3$d!!- GrrrMp[m![[B!"JVrrr$rrpAX!2rrrr$crrm!r`Vh!!#*r!!!H[Rr!)[F!!FGFMS !!!Sk[[Rr!+hh!!%Gm1Vr!0Ah!!%+m2cr!0Am!1S!!3VMk[m"m!Vh!!Gk1JS!!$T k#Zi!"RSk#J!!1RVfr`Hq1JS!!$Tk1[)!p!!(Add+!!!kF[$jr`!kp`$r638G!!! kAcVZ!!GI64d!!"eIm2Ir"jfYirrrikdGqJ!!@rX!!0Ajr`!ke3!!H[Rr!%hi!!# qk2m!H[J!!+hkr`"kr3$U!!#,k2m!RI!!!!V[!!!+qJ!"1YAjr`"bkJ$Y!!%GeIV r!H-+q!!!#ZF!!!Vl!!%+VI(r!I"0q`!!Q[`!!3V`q[m"m!Vi!!!kq`!#1Vjbq`! #1Vjbq`!!(IF!!*hkr`!kq!!!LqMr!$Vi!!"kqIm$L`S!!2i!r`Vi!!%G#[`!!3U Yjrm!FZm!!3SGq`!#HViGq`!!(IJ!!$Vkr`#,p`!!1[X!!R,91[d!r`!#FVikq`! !(IJ!!4h`qrm![Zi!!$Vl!!*0e6Vl!!!Gq!!"#Z2`r`!kr!!!YI`!!*hjr`"Ip`! '(G9k66TbRIlr"G9k66TbRIlr"Y9k66TbRAVh!!%+m2cr!(Vh!!%+iqVr!*hf!!$ MqIm#iiYI!cTILjhf!!DGLemkAi[Mjrm!eHd!riX1FMT0HZ2rrr#GFMT0HVi+p`! !Lrcr!H-+p`!'HTeb1NekeIlr!jeb1Nd"HYAqr`DGFMT0HVi+p`!!F[[r!"hZ!!C IVASk1RUqr[m'VASk1RUq1[F!!$V`r`#qr!!!B2`!q2m!#[B!!,lUr`!kpJ!!VIc r!$Vf!!#Gk[m!1[B!!(Vfrrlr!&rf!!"kiIm!HZd!!%hcr`#,pJ!!1[cr!*hf!!! kp2rhr`#qpJ!!#[cr!,lX!22r!12e!1rr!!Vp!!"Hr3!!1[Rr!12e!!#,k[re!!" kr2re!!"bk[m!(IB!!%hfrrlr!$Vf!!!kiIm!1Zd!!"hcr`"Ip3$mr`"bp3$drrI r!(Ve!!$`rIm!Lq`!!0Adr`#Yp3!![[$r!$Vp!!"Hr3!!1[Rr!,le!!"kkrm!eI8 !!%hpr`$`p3!!1ZVrp3!!1[Err[re!!!kiIm!1Z`!mrm!1[8!r2m!1[8!!12errI r!(Ve!!#qrIm!HZ`!!,ldr`"kp3!!VI$r!(,p!!"Lr3!!(IRr!2$e!!#Gk[re!!" kr2m!#[B!!(VUr`!kpJ!!ArErr[m!1[B!!%hKr`"0l3!!1[2r!(,f!!!+r2m!H[8 !p2rhr`#,p3!!m2hr!*hX!!$Mp2m![[8!!0A`r`!kr3!!B[`!!2$jr`!GpJ!!eHV r!$Vf!!#qr2m!1[B!!+hUr`"0pJ!!LrErr[m!F[B!!(VKr`"kl3!!Ar2r!*hf!!! kr2m!VIB!!$VdrrIr!,lf!!!Gr2m!eHd!!!Vcr`$`p3$[rr`!!*Am!!"kqIm!LrF !'6U,1Kd!1R,MrrqG64d!1R,MrrqG64d!1R+,p`!!1[[r!+hh!"NGLddG!$TIeIr rV8dG!$TIeIrrV8dG!$TILrF!!3V`p[rqr`$9p`!"#Z2Kr`(`#Zi!!0Acr`(`(IF !!,lmr`(`(IF!!+hdrrEr!$Vh!!#,qrm!1Zi!!(Vbr`"0p`!!F[$r!)[m!!#"q`! !eIRr!$Vi!!!+q`!##RSkq`!##RSkq`!!#[F!!0Akr`"0q!!!#[S!!ASkqJ!"HNh k!!!+q!!!VIArrIm!H[J!!)[Ir`#Yl`!!F[(r!,li!!"bq[m![[J!!%hcrrEr!H- +q3!!1[Vr!H-+m!!!1[(r!I!+q3!"(I$ar`(M#[`!!'rm!!%+m2Vr!I!Gh3!!(IX !!4fqq2m!F[X!!4d+h3!!H[ArrIm!ArJ!!(,Ir`"kq!$r#[X!!(V`r`#,q!!!1[V r!*hi!!!kmrrfr`#qq!!"(I$lr`#qp`!!(IX!!8h`mIm"e3Vj!!%+ir(r!I!Gr!! !Fr`!!*hjr`"Ih!!(#Uek1MTILr$fr`E9HNdkAiYbf`!!eIErr[m!VIB!!,lKr`$ 9pJ!'RBYI1Nekir$r!H-+p`!!H[cr!H-+p`!!H[6rprm"m!Vh!!"br2m"m"hh!!C IRA)k1RUqlrm!1[F!!$V`r`$9r!!!82`!q2rD!!#Yk[m!1YX!!(Vfrrlr!%hf!!" biIm!H[B!!$VUr`#,pJ!!1[cr!)[f!!!kp2rhr`#YpJ!!#[cr!,le!1Vr!0Ae!!$ `m2m!(Id!!&$p!!!kqIm!eGS!!(VUrpS!!$Vfrrlr!"hf!!!kiIm!1[B!!!VUr`" 0p3$mr`"Ip3$drrIr!(Ve!!$MrIm!H[8!!0AVr`#Gp3!![[$r!%hp!!"3r3!!1[R r!,lD!!!kkrm!eGS!!$Vfrrlrp!$Kr`!Gp3$Ur`!kp3!!irhr!$Ve!!#qpIrhr`" 0p3!![[hr!(Ve!!#qkrm!H[8!!(V`r`"kr3!!82d!!$Vjr`$MfJ!!HZVrfJ!!6IE rr[m!1[B!!$VKr`!kpJ!!(HVr!&re!2cr!(,e!26rprm!H[8!!12pr`#,p3!!eH[ r!+he!!#qm2m!1[d!!&,m!2Mr!!VE!!#Yk[m!1YX!!(Vfrrlr!&rf!!"kiIm!H[B !!%hUr`#,pJ!!1[cr!*hf!!!kp2rhr`#qpJ!!(Icr!,lf!!!+k[m!ir8!lrm!#[d !!'Em!!"kqIm!HY`!!6V`k[m!VG`!!3VMp[rqr`$9p`!"#Z2`r`DqAcS!1PqqqIm "i`Vh!!#qk[m"m!Vh!!#Yr2m"m"hh!!#Gp2rfr`!kp`!!H[[r!$Vh!!"kkIm!6IF !!(,`r`#Yr!!!C2X!!0Ajr`!kh3!!eHMr!%hG!!#YpIrpr`"kq!!!Lr$r!(Vk!!& bm2Vr!*hi!!"bk2m![[J!!%hkr`#qq!!!6I2rp[m"e3Vj!!!kq[m"i`Vj!!!kk2m "m!Vj!!%Gm2(r!I!+r!!!K[`!!3VMq[m"m"hi!!!Gq`!#(Debq`!#(Debq`!"(El Rr`(`H[X!!JUYH[X!!JUYH[X!r`Vi!!#,pIrpr`"bq!!!H[(r!(Vi!!"bq[m!LrJ !!(,Sr`#Yq!!!6IVr!+hi!!!kmrrfr`#qq!!!1[Vr!0Ai!!%Gm1Rr!H-+q3!"#[$ ar`(`#[`!!*,m!!#,qIm!F[F!'6UqHMSkAi[`rrqqHMSkAi[`rrqqHMSkAi[`j2m BeASk1Pq,m2rreASk1Nekm2rrihT01NekRIF!!3VMp[rqr`#qpJ!!eI2r!0Af!!# qr2m!irB!!,lUr`(`#[F!!*hmr`(`#[F!!)[drrEr!"hh!!"kqrm!1[F!!(,Tr`! kp`!!6I$r!,lm!!"Fr!!!m2Rr!!Vf!!#qY2m!6IB!!(Vfrrlr!&rf!!"kmrm!H[B !!&rmr`"kpJ!!AqVr!*hf!!!kr2m!VIB!!$VdrrIr!,lf!!!Gr2m![[B!!!VUr`$ Mp3$[r`!+r3!!A2d!!"hjr`$Mp3!!Ll6r!"hf!!"0p[rqr`!kpJ!!1[2r!$Vf!!! kr2m!6IB!!$VUr`"bpJ!!#[cr!(Ve!26rprm!Lr8!!2$pr`#,p3!!iq[r!+he!!# qm2m!1[d!!&6p!!!kqIm![[8!!(Udrr8!!$Vfrrlrp3!!(I2r!"he!2cr!$Ve!1V r!$Ve!2cr!$Ve!!$MpIrhr`"kp3!![[hr!(Ve!!#qkrm!H[8!!*h`r`"kr3!!A2d !!"hjr`$Mp3!!Ll6r!"hf!!"Ip[rqr`!kpJ!!1[2r!$Vf!!!kr2m!6IB!!$VUr`" bpJ!!#[cr!(Ve!26rprm!Lr8!!2$pr`#Gp3!!iq[r!,le!!#qm2m!1[d!!&cm!!$ `qIm!#[B!!,kdr`"0pJ!!H[Err[m!ArB!!(Vcr`"kpJ!!F[cr!(Vf!!"Ik[m!RIB !!$Vmr`#YpJ!!1[6rprm![[B!!"hmr`$9pJ!!#ZVr!2$e!1rr!!Vp!!#Cr!!!LrR r!(Vh!!!kbrmBV9mk!$TbirrrV9mk!$Tbirrr[Pmk!$TbLrF!!3VMp[rqr`#qpJ! 2RA)k!$TbeIrreA)k!$TbLrB!!,lmr`(M#[F!!,lUr`(`#[F!!+hmr`(`#[F!rhS ,1JSkAkhrrr"k1JSk#eqGrrr`HMS+(8fG1[F!!(Vlr`!kp`!!FZRr!$Vh!!"0m2m !VI`!!)6m!!%+irRr!"hi!!$9cIm"m%hl!!)+Lh,l!!)+Lh,l!!!+p`!!LrArrIm !F[J!!"hk!2pkqJ!!(IJ!!(,kr`#,q!!!FZMr!+hi!!"0q[m!VIJ!r`Vl!!*0R3V p!2m!!MUG#[X!!!Vi!!!kq[m!eIJ!!4h`kIm"i`Vj!!%+m2(r!I!+r!!!Cr`!!3V MqIm!1[J!!0A0r`"0hJ!!H[6rrIm"m(,k!!!+l`!!(IS!!A,`q[m!LrJ!!(,Sr`# Yq!!!6IRr!BX+q`!!(I)!p!!!#[X!!6VMq[m!eIJ!!4h`kIm"i`Vj!!%+m2(r!I! +r!!!F2`!!)[jr`"bp`!!1Xlr!)[P!!F+Lemk!$TbeI2rqrm'[Pmk!$TILqd!"Te I1J!kAlljr`(M#[F!!,lUr`(`#[F!!+hjr`IMFMS!(8f,(I)!p!!'FRSk#Ke0RIM r!$Vh!!"bkIm!1[F!!%h`r`#Yr!!!5[`!q2m!#[B!!,l2r`!kj!!!HZhrpIm!Aqd !!&rcr`"kpJ!!6HVr!)[f!!!kmrm!RI%!p!!!(I2r!,le!1Vr!12e!!$`m2m!(Id !!%Vp!!!kqIm!ir8!!)[2rq-!!%hYrrAr!$VY!!!kmrm!1[B!!"hUr`"Ip3$cr`" bm3$c!!$`p2m!Lr8!!0AVr`#Yp3!![[$r!%hp!!")r3!!1[Rr!,le!!"bd2m!eH- !!$VYrrArk`$cr`!Gp3$Ur`!kp3!!ir6r!$Va!2-!!,ldr`"kp3!![Z[r!(Ve!!" km2m!H[d!!%Vp!!!kqIm!eI8!!(V2rq-!!%hYrrAr!$VY!!!kmrm!1[B!!!VUr`" Ip3$cr`"bm3$c!!$Mp2m!H[8!!0AVr`#Gp3!![[$r!(,p!!"+r3!!#[Mrp3!![Xr r!$VN!!"klIrer`"Il3!!Ar2r!(Vf!!"0k[m!LrB!!$Vcr`#Gm3$d!!!+mrm![[8 !k[m!eI8!!2$`r`!Gr3!!8r`!!*hjr`"bp`!"(I$2r`#,j3!"#Z2YrrAr!,lY!!# qmrm!eIB!!+hUr`(M#[F!!)[cr`(`#[)!p!!!F[2r!I!Gp`!!FZRr!$Vh!!!km2m ![[`!!&Am!!%+m2Vr!I!Gq!!![Xhr!$VQ!!#,l2rdr`"bl`!!F[(r!(Vi!!"0k2m !LrJ!!$Var`#YmJ$e!!%km2,r!0Ai!!%Gm1Rr!H-+q3!"#[$ar`(`1[`!!)[l!!$ 9qIm"e6Vl!!%+VHrr!2$lr`,`FVllr`,`FVllr`$`q2m"m%hk!!&k6IS!!AT0qJ! !HZ[rp2m"m(,k!2pbqJ!"F[$`r`"kqJ!"6I$Rr`&k#[X!!8h`m2m"L`Vl!!)kL`V p!2m!!MU,#[X!!6VMm2m"V3Vl!!%keHIr!EiGq`!"(GA`r`(M#[`!!+Mm!!"kp[m 'LddG!$Tbm1lr'G9IVH2r[SXG!!"IVH2r[SXG!!"IVH2r[SYbp[mBV8dG!$TIeIr rV8dG!$TIeIrrV8dG!$TIeHVrm[m2[Pmk!$TI[[rr[Pmk!$TI[Zhr"Y9I1J!G6Dh Nr`EMFMS!(8fGlIm0ih)k!"e0RIrrih)k!"d+6Chrrq0b1J!+6B[Yr`E`FMS!#MU ,j2m(m)Xk#JSkLr$Zr`#,r!!!&2`!!2$Er`!kkJ!![XErJIqLrr`!!"Ep!!!Gf[m !FZS!!2$'ri(rS[m!1[d!!"Ep!!!kf[m!LqX!!!V&ri(rS[m!F[d!!"6p!!!kf[m !HZS!aIq"rk,r!%hp!!!8r!$Dr`"IkJ!!imErJIqLr`!kr3!!&r`!!*hFr`(`#ZS !!(V'ri(rSrm![[`!!"Mm!!%Gm0hr!&rT!!%+eFIrJIqMr`!kr!!!2[X!!3V9qrm !m1Ar!$VS!!%+VIVr!2$8r`$`r[rpr`',VIVr!2$#r`$`q[m!m0Irarm!m2[r!2$ Qr`(M#[`!!%hk!!F+FUh`rlk,RHAr!0AQ!!CIRH2reCekdrm$m&qYi`hreDdk!!" 0VH2rikebm-(r"h+GeIrMVA,Merr(rrq,"Elrm,jk[ZAr!*hm!!!Xm`!!m16r!$V K!!#qd[m#HJ!!p3!!Lm$r!+hm!!"be[r'rr`!!"hMr`!+r3!!,23!!"hMr`"ki3$ 4r`+Y!!$e!!#q`2m!m2`!!*h@rmEr!$Vp!!"0irm!1[d!!#Vd!!!kirm!VH)!!$V 4r`,9!!$e!,lrr!!![YEra[m!6Id!!(VMr`"kr3!!+[3!!$VMr`"ki3$4r`+q!!$ e!!$M[rrm!!#Ye[r'r`!kr3!!Aq2r!%hp!!!Um`$Mr`"0i3!!eG,r!RS!!28!!+h !r`#qr!!!HYEra[rm!!!kirm!(Id!!#rc!!#GjIm"m!VK!!"kd[m#1J!!p3!!6F$ r!(,m!!!Ge[r(r`#qq`!!eHAr!0Am!!!`m`!"#[$Qr`"0h`!!eG6r!)[q!23!!+h #r`$9qJ!!HYIrb2m"m"hl!!!kjIm!1[`!!,$b!!%kirVr!B[Mq[m"Lq2kr`"khJ! "1YAkr`'GeIVr!Dh9q[m"VGAkr`'Y[[Vr!Dd+rJ$d!!%+[[Vrrllkr`'qVIVr!Ek Yq[m"[Uhkr`'qVIVr!G@Yq[m"e6Vj!!#,q[m"eChkr`(9RIVr!H1Gq[m"ii[mrrr r!H1,q[m"ii[kr`(MLrVr!I#,q[m"m)[kr`,`Lr$lr`(`6IN!!9r`qrm#m)[`qrm #m*h`qrm"m&rl!!%5m3!C#S[9rrr`V6S!#S[9rrr`V6S!#S[9rrr`[MVE!!&keIl r"Eik!!"keIlr"Ej0!!"keIlr"Ej0!!"keIlr"Ej0!!"b[[lr!Ej0r!$b!!&b[[l r"Ejb!!"b[[lr"Ejb!!"0[[lr"Ejb!!"0[[lr"G9b!!"0[[lr"G9k!!"0[[lr"G9 k!!"0[[lr!G9kpJ!S1Vl`rrr9HJ!!1Vl`rrr9L`!!1Vl`rrr9L`S!1Vl`rrr9L`S !1Vl`rrmieBX+!$UYm2rriiX+!$UYm2rriiX+!$UYm2rrijd+!$UYm2rrijd+!$U Ym2rrijd+!"fYirrrijd+p`!C(DhMrrrMV4d!(DhMrrrMV4d!(DhMrrrMV4hk!!" pl3!!(IN!!"hj!!!Ge3!!1[N!!$Vj!!!kq3!!(IN!!"hj!1m!!"hj!!!Gq3!!1[N !!$Vj!!!kq3!!1[N!!$V`!!!Gq3!!(IN!!"hj!!!Gq3!"(3Vk!!%G#[S!!4d+qJ! "(3Vk!!%G#[S!r`Vk!2m+m3$r#[S!r`Vk!2m+p`!!"S%!J3#G!!!'J3#"!*d!!!D "!)%!R3!!"S%!J3#G!!!!r`!!!"J!9`"f!B-#"J!"!3#3"`(8!!!`#J!!!")!N!F '!"8!EJ&j`!)"m`!!!(X!"`%k$L3S39"36%P$394*6diT$53S8&P85%p1+6T-D@) 4*#K3@94)6diT1P"XG@G*ER-4*#K3@94)6diT1NeKBcT-D@)C*#K3@94)6diT1Ne KBcT-D@)kG'p[E'*[H"XN+&"C9%K26LNk6@&M1NaTBMTcBh*TF(4TEQF!!!!39%9 B9(4dH(3!U$!a1$%!N!8+81!!0U`!!!HK)!!!!!T3i!#F2!!!2R`!N!3+81!!R$` !!!HK)!!!!$3!N@!!!!!&-#ijBM%R-#ijBM%JU6%j16FJ5R9cG#"fB@iJ8QpcFh9 Y)#K-CA4dCA*bEh)T!!!!(3#4B!!!!!P-CA4dCA*bEh)-BRNJ6'9dG'9bFQpb!!! "!!!!+ci!!#Sq!!!!jJ-M*rJTJ!!!!"`!cJ!'8%P$9!!!!$T%6%p(!!!!4N4*9%` !!!"58e45)`!!!&j(9EG*!!!!DP0*@N8!!J"fGQ9bF`!"!*S"m`!-!*!)!G3!"J! !+2B!N!3"e!#3"#N5!*!&JIrr!!!T+!-M*l!S!Irr!!!TT`#3"2q3"!!!+EX$)bC d!!(rr`!!+FN$)bHN!!$rr`!!+GF$)bP`!!(rr`!!+H8$)bHS!!,rr`!!+Kd$)bG B"8&LEh9d"8&LEh9d#h"jG'K[EL"XEfG[NL):
\ No newline at end of file
"Hold the option key to open a script instead of running it."
import W
W.Message(__doc__)
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:] == '.pyc' and os.path.exists(path[:-1]):
print "deleting:", path
os.remove(path)
elif path[-4:] == '.pyc':
print "!!! ------ .pyc file without .py file:", path
fss, ok = macfs.GetDirectory('Select the starting folder:')
if ok:
walk(fss.as_pathname())
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 '
#aetools.keysubst(_arguments, self._argmap_OpenURL)
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise MacOS.Error, aetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
class ToolboxAssi:
def __init__(self):
self.talker = Toolbox('ALTV')
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):
lookup = self.w.edit.get()
try:
self.talker.LookupTopic(lookup)
except MacOS.Error, detail:
if type(detail) == type(()):
if detail[0] == -609:
self.talker.start()
try:
self.talker.LookupTopic(lookup)
return
except MacOS.Error:
pass
W.Message("Requested topic not found.")
ToolboxAssi()
import macfs
fss, ok = macfs.StandardGetFile()
if ok:
import W
W.FrontWindowInsert('"%s"' % fss.as_pathname())
import macfs
fss, ok = macfs.GetDirectory()
if ok:
import W
W.FrontWindowInsert('"%s"' % fss.as_pathname())
__version__ = "$Id$"
import sys
from time import time
class Trace:
def __init__(self):
self.dispatch = {
'call': self.trace_dispatch_call,
'return': self.trace_dispatch_return,
'exception': self.trace_dispatch_exception,
}
self.curframe = None
self.depth = -1
self.stdout = sys.stdout
def run(self, cmd, globals = None, locals = None):
if globals is None:
import __main__
globals = __main__.__dict__
if locals is None:
locals = globals
sys.setprofile(self.trace_dispatch)
try:
exec cmd in globals, locals
finally:
sys.setprofile(None)
def runcall(self, func, *args):
sys.setprofile(self.trace_dispatch)
try:
apply(func, args)
finally:
sys.setprofile(None)
def trace_dispatch(self, frame, event, arg):
curstdout = sys.stdout
sys.stdout = self.stdout
self.dispatch[event](frame, arg)
sys.stdout = curstdout
def trace_dispatch_call(self, frame, arg):
self.depth = self.depth + 1
self.curframe = frame
code = frame.f_code
funcname = code.co_name
if not funcname:
funcname = '<lambda>'
filename = code.co_filename
lineno = frame.f_lineno
if lineno == -1:
code = code.co_code
if ord(code[0]) == 127: # SET_LINENO
lineno = ord(code[1]) | ord(code[2]) << 8
pframe = frame.f_back
if pframe:
plineno = ' (%d)' % pframe.f_lineno
else:
plineno = ''
print '%s> %s:%d %s%s' % (' '*self.depth,filename,lineno,funcname,plineno)
frame.f_locals['__start_time'] = time()
def trace_dispatch_return(self, frame, arg):
try:
t = frame.f_locals['__start_time']
except KeyError:
t = ''
else:
t = ' [%.4f]' % (time() - t)
funcname = frame.f_code.co_name
self.curframe = frame.f_back
if not funcname:
funcname = '<lambda>'
filename = frame.f_code.co_filename
print '%s< %s:%d %s%s' % (' '*self.depth,filename,frame.f_lineno,funcname,t)
self.depth = self.depth - 1
def trace_dispatch_exception(self, frame, arg):
t = ''
if frame is not self.curframe:
try:
t = frame.f_locals['__start_time']
except KeyError:
pass
else:
t = ' [%.4f]' % (time() - t)
self.depth = self.depth - 1
self.curframe = frame
funcname = frame.f_code.co_name
if not funcname:
funcname = '<lambda>'
filename = frame.f_code.co_filename
print '%sE %s:%d %s%s' % (' '*(self.depth+1),filename,frame.f_lineno,funcname,t)
def set_trace(self):
try:
raise 'xyzzy'
except:
frame = sys.exc_traceback.tb_frame
while frame.f_code.co_name != 'set_trace':
frame = frame.f_back
d = 0
while frame:
d = d + 1
frame = frame.f_back
self.depth = d
sys.setprofile(self.trace_dispatch)
def run(cmd, globals = None, locals = None):
Trace().run(cmd, globals, locals)
def runcall(*func_args):
apply(Trace().runcall, funcargs)
def set_trace():
Trace().set_trace()
def unset_trace():
sys.setprofile(None)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment