Hopefully fix make framework install on Mac (see 3174)

Removal of the Mac modules broke many of the Mac scripts (including
BuildApplet.py) so the building of the Python launcher and IDLE.app was
broken. I manually copied built versions of those apps into Mac. Everything else
which used Mac modules had to die.
This commit is contained in:
Benjamin Peterson 2008-07-01 18:23:09 +00:00
parent bbfd71d7ac
commit de9c869fb8
75 changed files with 363 additions and 5710 deletions

View File

@ -1,161 +0,0 @@
"""browsepict - Display all "ICON" resources found"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import Win
from Carbon import Controls
from Carbon import List
from Carbon import Icn
import macresource
#
# Resource definitions
ID_MAIN=512
MAIN_LIST=1
MAIN_SHOW=2
# Where is the picture window?
LEFT=200
TOP=64
MINWIDTH=32
MINHEIGHT=32
MAXWIDTH=320
MAXHEIGHT=320
def main():
macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
ICONbrowse()
class ICONbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
contents = self.findICONresources()
self.main_dialog.open(ID_MAIN, contents)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def showICON(self, resid):
w = ICONwindow(self)
w.open(resid)
#EasyDialogs.Message('Show ICON %r' % (resid,))
def findICONresources(self):
num = Res.CountResources('ICON')
rv = []
for i in range(1, num+1):
Res.SetResLoad(0)
try:
r = Res.GetIndResource('ICON', i)
finally:
Res.SetResLoad(1)
id, type, name = r.GetResInfo()
rv.append((id, name))
return rv
class ICONwindow(FrameWork.Window):
def open(self, (resid, resname)):
if not resname:
resname = '#%r' % (resid,)
self.resid = resid
self.picture = Icn.GetIcon(self.resid)
l, t, r, b = 0, 0, 32, 32
self.pictrect = (l, t, r, b)
width = r-l
height = b-t
if width < MINWIDTH: width = MINWIDTH
elif width > MAXWIDTH: width = MAXWIDTH
if height < MINHEIGHT: height = MINHEIGHT
elif height > MAXHEIGHT: height = MAXHEIGHT
bounds = (LEFT, TOP, LEFT+width, TOP+height)
self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
self.do_postopen()
def do_update(self, *args):
currect = self.fitrect()
Icn.PlotIcon(currect, self.picture)
def fitrect(self):
"""Return self.pictrect scaled to fit in window"""
graf = self.wid.GetWindowPort()
screenrect = graf.GetPortBounds()
picwidth = self.pictrect[2] - self.pictrect[0]
picheight = self.pictrect[3] - self.pictrect[1]
if picwidth > screenrect[2] - screenrect[0]:
factor = float(picwidth) / float(screenrect[2]-screenrect[0])
picwidth = picwidth / factor
picheight = picheight / factor
if picheight > screenrect[3] - screenrect[1]:
factor = float(picheight) / float(screenrect[3]-screenrect[1])
picwidth = picwidth / factor
picheight = picheight / factor
return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
screenrect[1]+int(picheight))
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for ICONbrowse"
def open(self, id, contents):
self.id = id
FrameWork.DialogWindow.open(self, ID_MAIN)
self.dlg.SetDialogDefaultItem(MAIN_SHOW)
self.contents = contents
self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
Controls.kControlListBoxListHandleTag)
self.list = List.as_List(h)
self.setlist()
def setlist(self):
self.list.LDelRow(0, 0)
self.list.LSetDrawingMode(0)
if self.contents:
self.list.LAddRow(len(self.contents), 0)
for i in range(len(self.contents)):
v = repr(self.contents[i][0])
if self.contents[i][1]:
v = v + '"' + self.contents[i][1] + '"'
self.list.LSetCell(v, (0, i))
self.list.LSetDrawingMode(1)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def getselection(self):
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
values = []
for i in items:
values.append(self.contents[i])
return values
def do_show(self, *args):
selection = self.getselection()
for resid in selection:
self.parent.showICON(resid)
def do_close(self):
self.close()
def do_itemhit(self, item, event):
if item == MAIN_SHOW:
self.do_show()
main()

View File

@ -1,140 +0,0 @@
"""browsepict - Display all "PICT" resources found"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import Win
from Carbon import Controls
from Carbon import List
import struct
import macresource
#
# Resource definitions
ID_MAIN=512
MAIN_LIST=1
MAIN_SHOW=2
# Where is the picture window?
LEFT=200
TOP=64
def main():
macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
PICTbrowse()
class PICTbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
contents = self.findPICTresources()
self.main_dialog.open(ID_MAIN, contents)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def showPICT(self, resid):
w = PICTwindow(self)
w.open(resid)
#EasyDialogs.Message('Show PICT %r' % (resid,))
def findPICTresources(self):
num = Res.CountResources('PICT')
rv = []
for i in range(1, num+1):
Res.SetResLoad(0)
try:
r = Res.GetIndResource('PICT', i)
finally:
Res.SetResLoad(1)
id, type, name = r.GetResInfo()
rv.append((id, name))
return rv
class PICTwindow(FrameWork.Window):
def open(self, (resid, resname)):
if not resname:
resname = '#%r' % (resid,)
self.resid = resid
picture = Qd.GetPicture(self.resid)
# Get rect for picture
print(repr(picture.data[:16]))
sz, t, l, b, r = struct.unpack('hhhhh', picture.data[:10])
print('pict:', t, l, b, r)
width = r-l
height = b-t
if width < 64: width = 64
elif width > 480: width = 480
if height < 64: height = 64
elif height > 320: height = 320
bounds = (LEFT, TOP, LEFT+width, TOP+height)
print('bounds:', bounds)
self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
self.wid.SetWindowPic(picture)
self.do_postopen()
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for PICTbrowse"
def open(self, id, contents):
self.id = id
FrameWork.DialogWindow.open(self, ID_MAIN)
self.dlg.SetDialogDefaultItem(MAIN_SHOW)
self.contents = contents
self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
Controls.kControlListBoxListHandleTag)
self.list = List.as_List(h)
self.setlist()
def setlist(self):
self.list.LDelRow(0, 0)
self.list.LSetDrawingMode(0)
if self.contents:
self.list.LAddRow(len(self.contents), 0)
for i in range(len(self.contents)):
v = repr(self.contents[i][0])
if self.contents[i][1]:
v = v + '"' + self.contents[i][1] + '"'
self.list.LSetCell(v, (0, i))
self.list.LSetDrawingMode(1)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def getselection(self):
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
values = []
for i in items:
values.append(self.contents[i])
return values
def do_show(self, *args):
selection = self.getselection()
for resid in selection:
self.parent.showPICT(resid)
def do_close(self):
self.close()
def do_itemhit(self, item, event):
if item == MAIN_SHOW:
self.do_show()
main()

Binary file not shown.

View File

@ -1,162 +0,0 @@
"""browsepict - Display all "PICT" resources found"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import Win
from Carbon import Controls
from Carbon import List
import struct
import macresource
#
# Resource definitions
ID_MAIN=512
MAIN_LIST=1
MAIN_SHOW=2
# Where is the picture window?
LEFT=200
TOP=64
MINWIDTH=64
MINHEIGHT=64
MAXWIDTH=320
MAXHEIGHT=320
def main():
macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
PICTbrowse()
class PICTbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
contents = self.findPICTresources()
self.main_dialog.open(ID_MAIN, contents)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def showPICT(self, resid):
w = PICTwindow(self)
w.open(resid)
#EasyDialogs.Message('Show PICT %r' % (resid,))
def findPICTresources(self):
num = Res.CountResources('PICT')
rv = []
for i in range(1, num+1):
Res.SetResLoad(0)
try:
r = Res.GetIndResource('PICT', i)
finally:
Res.SetResLoad(1)
id, type, name = r.GetResInfo()
rv.append((id, name))
return rv
class PICTwindow(FrameWork.Window):
def open(self, (resid, resname)):
if not resname:
resname = '#%r' % (resid,)
self.resid = resid
self.picture = Qd.GetPicture(self.resid)
# Get rect for picture
sz, t, l, b, r = struct.unpack('hhhhh', self.picture.data[:10])
self.pictrect = (l, t, r, b)
width = r-l
height = b-t
if width < MINWIDTH: width = MINWIDTH
elif width > MAXWIDTH: width = MAXWIDTH
if height < MINHEIGHT: height = MINHEIGHT
elif height > MAXHEIGHT: height = MAXHEIGHT
bounds = (LEFT, TOP, LEFT+width, TOP+height)
self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
self.do_postopen()
def do_update(self, *args):
currect = self.fitrect()
Qd.DrawPicture(self.picture, currect)
def fitrect(self):
"""Return self.pictrect scaled to fit in window"""
graf = self.dlg.GetWindowPort()
screenrect = graf.GetPortBounds()
picwidth = self.pictrect[2] - self.pictrect[0]
picheight = self.pictrect[3] - self.pictrect[1]
if picwidth > screenrect[2] - screenrect[0]:
factor = float(picwidth) / float(screenrect[2]-screenrect[0])
picwidth = picwidth / factor
picheight = picheight / factor
if picheight > screenrect[3] - screenrect[1]:
factor = float(picheight) / float(screenrect[3]-screenrect[1])
picwidth = picwidth / factor
picheight = picheight / factor
return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
screenrect[1]+int(picheight))
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for PICTbrowse"
def open(self, id, contents):
self.id = id
FrameWork.DialogWindow.open(self, ID_MAIN)
self.dlg.SetDialogDefaultItem(MAIN_SHOW)
self.contents = contents
self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
Controls.kControlListBoxListHandleTag)
self.list = List.as_List(h)
self.setlist()
def setlist(self):
self.list.LDelRow(0, 0)
self.list.LSetDrawingMode(0)
if self.contents:
self.list.LAddRow(len(self.contents), 0)
for i in range(len(self.contents)):
v = repr(self.contents[i][0])
if self.contents[i][1]:
v = v + '"' + self.contents[i][1] + '"'
self.list.LSetCell(v, (0, i))
self.list.LSetDrawingMode(1)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def getselection(self):
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
values = []
for i in items:
values.append(self.contents[i])
return values
def do_show(self, *args):
selection = self.getselection()
for resid in selection:
self.parent.showPICT(resid)
def do_close(self):
self.close()
def do_itemhit(self, item, event):
if item == MAIN_SHOW:
self.do_show()
main()

View File

@ -1,161 +0,0 @@
"""browsepict - Display all "cicn" resources found"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import Win
from Carbon import Controls
from Carbon import List
from Carbon import Icn
import macresource
#
# Resource definitions
ID_MAIN=512
MAIN_LIST=1
MAIN_SHOW=2
# Where is the picture window?
LEFT=200
TOP=64
MINWIDTH=32
MINHEIGHT=32
MAXWIDTH=320
MAXHEIGHT=320
def main():
macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
CIconbrowse()
class CIconbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
contents = self.findcicnresources()
self.main_dialog.open(ID_MAIN, contents)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def showCIcon(self, resid):
w = CIconwindow(self)
w.open(resid)
#EasyDialogs.Message('Show cicn %r' % (resid,))
def findcicnresources(self):
num = Res.CountResources('cicn')
rv = []
for i in range(1, num+1):
Res.SetResLoad(0)
try:
r = Res.GetIndResource('cicn', i)
finally:
Res.SetResLoad(1)
id, type, name = r.GetResInfo()
rv.append((id, name))
return rv
class CIconwindow(FrameWork.Window):
def open(self, (resid, resname)):
if not resname:
resname = '#%r' % (resid,)
self.resid = resid
self.picture = Icn.GetCIcon(self.resid)
l, t, r, b = 0, 0, 32, 32
self.pictrect = (l, t, r, b)
width = r-l
height = b-t
if width < MINWIDTH: width = MINWIDTH
elif width > MAXWIDTH: width = MAXWIDTH
if height < MINHEIGHT: height = MINHEIGHT
elif height > MAXHEIGHT: height = MAXHEIGHT
bounds = (LEFT, TOP, LEFT+width, TOP+height)
self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
self.do_postopen()
def do_update(self, *args):
currect = self.fitrect()
Icn.PlotCIcon(currect, self.picture)
def fitrect(self):
"""Return self.pictrect scaled to fit in window"""
graf = self.wid.GetWindowPort()
screenrect = graf.GetPortBounds()
picwidth = self.pictrect[2] - self.pictrect[0]
picheight = self.pictrect[3] - self.pictrect[1]
if picwidth > screenrect[2] - screenrect[0]:
factor = float(picwidth) / float(screenrect[2]-screenrect[0])
picwidth = picwidth / factor
picheight = picheight / factor
if picheight > screenrect[3] - screenrect[1]:
factor = float(picheight) / float(screenrect[3]-screenrect[1])
picwidth = picwidth / factor
picheight = picheight / factor
return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
screenrect[1]+int(picheight))
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for cicnbrowse"
def open(self, id, contents):
self.id = id
FrameWork.DialogWindow.open(self, ID_MAIN)
self.dlg.SetDialogDefaultItem(MAIN_SHOW)
self.contents = contents
self.ctl = self.dlg.GetDialogItemAsControl(MAIN_LIST)
h = self.ctl.GetControlData_Handle(Controls.kControlListBoxPart,
Controls.kControlListBoxListHandleTag)
self.list = List.as_List(h)
self.setlist()
def setlist(self):
self.list.LDelRow(0, 0)
self.list.LSetDrawingMode(0)
if self.contents:
self.list.LAddRow(len(self.contents), 0)
for i in range(len(self.contents)):
v = repr(self.contents[i][0])
if self.contents[i][1]:
v = v + '"' + self.contents[i][1] + '"'
self.list.LSetCell(v, (0, i))
self.list.LSetDrawingMode(1)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def getselection(self):
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
values = []
for i in items:
values.append(self.contents[i])
return values
def do_show(self, *args):
selection = self.getselection()
for resid in selection:
self.parent.showCIcon(resid)
def do_close(self):
self.close()
def do_itemhit(self, item, event):
if item == MAIN_SHOW:
self.do_show()
main()

View File

@ -1,158 +0,0 @@
"""browsepict - Display all "PICT" resources found"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import Win
from Carbon import List
import struct
import macresource
#
# Resource definitions
ID_MAIN=512
MAIN_LIST=1
MAIN_SHOW=2
# Where is the picture window?
LEFT=200
TOP=64
def main():
macresource.need('DLOG', ID_MAIN, "oldPICTbrowse.rsrc")
PICTbrowse()
class PICTbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
contents = self.findPICTresources()
self.main_dialog.open(ID_MAIN, contents)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def showPICT(self, resid):
w = PICTwindow(self)
w.open(resid)
#EasyDialogs.Message('Show PICT %r' % (resid,))
def findPICTresources(self):
num = Res.CountResources('PICT')
rv = []
for i in range(1, num+1):
Res.SetResLoad(0)
try:
r = Res.GetIndResource('PICT', i)
finally:
Res.SetResLoad(1)
id, type, name = r.GetResInfo()
rv.append((id, name))
return rv
class PICTwindow(FrameWork.Window):
def open(self, (resid, resname)):
if not resname:
resname = '#%r' % (resid,)
self.resid = resid
picture = Qd.GetPicture(self.resid)
# Get rect for picture
print(repr(picture.data[:16]))
sz, t, l, b, r = struct.unpack('hhhhh', picture.data[:10])
print('pict:', t, l, b, r)
width = r-l
height = b-t
if width < 64: width = 64
elif width > 480: width = 480
if height < 64: height = 64
elif height > 320: height = 320
bounds = (LEFT, TOP, LEFT+width, TOP+height)
print('bounds:', bounds)
self.wid = Win.NewWindow(bounds, resname, 1, 0, -1, 1, 0)
self.wid.SetWindowPic(picture)
self.do_postopen()
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for PICTbrowse"
def open(self, id, contents):
self.id = id
FrameWork.DialogWindow.open(self, ID_MAIN)
self.dlg.SetDialogDefaultItem(MAIN_SHOW)
tp, h, rect = self.dlg.GetDialogItem(MAIN_LIST)
rect2 = rect[0]+1, rect[1]+1, rect[2]-17, rect[3]-17 # Scroll bar space
self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
0, 1, 1, 1)
self.contents = contents
self.setlist()
def setlist(self):
self.list.LDelRow(0, 0)
self.list.LSetDrawingMode(0)
if self.contents:
self.list.LAddRow(len(self.contents), 0)
for i in range(len(self.contents)):
v = repr(self.contents[i][0])
if self.contents[i][1]:
v = v + '"' + self.contents[i][1] + '"'
self.list.LSetCell(v, (0, i))
self.list.LSetDrawingMode(1)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def do_listhit(self, event):
(what, message, when, where, modifiers) = event
Qd.SetPort(self.wid)
where = Qd.GlobalToLocal(where)
print('LISTHIT', where)
if self.list.LClick(where, modifiers):
self.do_show()
def getselection(self):
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
values = []
for i in items:
values.append(self.contents[i])
return values
def do_show(self, *args):
selection = self.getselection()
for resid in selection:
self.parent.showPICT(resid)
def do_rawupdate(self, window, event):
tp, h, rect = self.dlg.GetDialogItem(MAIN_LIST)
Qd.SetPort(self.wid)
Qd.FrameRect(rect)
self.list.LUpdate(self.wid.GetWindowPort().visRgn)
def do_activate(self, activate, event):
self.list.LActivate(activate)
def do_close(self):
self.close()
def do_itemhit(self, item, event):
if item == MAIN_LIST:
self.do_listhit(event)
if item == MAIN_SHOW:
self.do_show()
main()

View File

@ -1,362 +0,0 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html><head><title>Using the Open Scripting Architecture from Python</title></head>
<body>
<h1>Using the Open Scripting Architecture from Python</h1>
<hr>
<p><b>NOTE:</b> this document describes the OSA support that is shipped with
the core python distribution. Most users are better of with the more
userfriendly <a href="http://freespace.virgin.net/hamish.sanderson/appscript.html">appscript library</a>.
<p>OSA support in Python is still not 100% complete, but
there is already enough in place to allow you to do some nifty things
with other programs from your python program. </p>
<p>
In this example, we will look at a scriptable application, extract its
&#8220;AppleScript Dictionary,&#8221; generate a Python interface package from
the dictionary, and use that package to control the application.
The application we are going to script is Disk Copy, Apple's standard
utility for making copies of floppies, creating files that are mountable
as disk images, etc.
Because we want
to concentrate on the OSA details, we won&#8217;t bother with a real
user-interface for our application. </p>
<p>
<em>When we say &#8220;AppleScript&#8221; in this document we actually mean
&#8220;the Open Scripting Architecture.&#8221; There is nothing
AppleScript-specific in the Python implementation. Most of this document
focuses on the classic Mac OS; <a href="#osx">Mac OS X</a> users have some
additional tools.</em>
</p>
<h2>Python OSA architecture</h2>
<p>Open Scripting suites and inheritance can be modelled rather nicely
with Python packages, so we generate
a package for each application we want to script. Each suite defined in
the application becomes a module in the
package, and the package main module imports everything from all the
submodules and glues together all the classes (in Python terminology&#8212;
events in OSA terminology or verbs in AppleScript terminology). </p>
<p>
A suite in an OSA application can extend the functionality of a standard
suite. This is implemented in Python by importing everything from the
module that implements the standard suites and overriding anything that has
been extended. The standard suites live in the StdSuite package. </p>
<p>
This all sounds complicated, but the good news is that basic
scripting is actually pretty simple. You can do strange and wondrous things
with OSA scripting once you fully understand it. </p>
<h2>Creating the Python interface package</h2>
<p>There is a tool in the standard distribution that can automatically
generate the interface packages. This tool is called
<code>gensuitemodule.py</code>, and lives in <code>Mac:scripts</code>.
It looks through a file
for an &#8216;AETE&#8217; or &#8216;AEUT&#8217; resource,
the internal representation of the
AppleScript dictionary, and parses the resource to generate the suite
modules.
When we start <code>gensuitemodule</code>, it asks us for an input file;
for our example,
we point it to the Disk Copy executable. </p>
<p>
Next, <code>gensuitemodule</code> wants a folder where it will store the
package it is going to generate.
Note that this is the package folder, not the parent folder, so we
navigate to <code>Python:Mac:Demo:applescript</code>, create a folder
<code>Disk_Copy</code>, and select that. </p>
<p>
We next specify the folder from which <code>gensuitemodule</code>
should import the standard suites. Here,
we always select <code>Python:Mac:Lib:lib-scriptpackages:StdSuites</code>. (There is
one exception to this rule: when you are generating <code>StdSuites</code> itself
you select <code>_builtinSuites</code>.)
</p>
<p>
It starts parsing the AETE resource, and for
each AppleEvent suite it finds, <code>gensuitemodule.py</code>
prompts us for the filename of the
resulting python module. Remember to change folders for the first
module&#8212;you don't want to clutter up, say, the
Disk Copy folder
with your python
interfaces. If you want to skip a suite, press <code>cancel</code> and the process
continues with the next suite. </p>
<h3>Summary</h3>
<ol>
<li>Run <code>gensuitemodule</code>.</li>
<li>Select the application (or OSAX) for which you would like a Python interface.</li>
<li>Select the package folder where the interface modules should be
stored.</li>
<li>Specify the folder <code>Python:Mac:Lib:lib-scriptpackages:StdSuites</code>
to import the standard suites (or <code>_builtinSuites</code> if you are
generating <code>StdSuites</code> itself). </li>
<li>Save the generated suites (use <code>cancel</code> to skip a suite).</li>
</ol>
<h3>Notes</h3>
<ul>
<li>The interface package may occasionally need some editing by hand. For example,
<code>gensuitemodule</code> does not handle all Python reserved words, so
if
one of the AppleScript verbs is a Python reserved word, a <code>SyntaxError</code>
may be raised when the package is imported.
Simply rename the class into something acceptable, if this happens;
take a look at how the
<code>print</code> verb is handled (automatically by <code>gensuitemodule</code>)
in the standard suites. But: f you need to edit your package this should be considered a
bug in gensuitemodule, so please report it so it can be fixed in future releases.
</li>
<li>If you want to re-create the StdSuite modules,
you should look in one of two places. With versions of AppleScript older than 1.4.0
(which first shipped with OS 9.0), you will find the
AEUT resources in <code>System Folder:Extensions:Scripting
Additions:Dialects:English Dialect</code>. For newer versions, you will
find them in <code>System Folder:Extensions:Applescript</code>.
</li>
<li>Since MacPython 2.0, this new structure, with packages
per application and submodules per suite, is used. Older MacPythons had a
single level of modules, with uncertain semantics. With the new structure,
it is possible for programs to override standard suites, as programs often do.
</li>
<li><code>Gensuitemodule.py</code> may ask you questions
like &#8220;Where is enum 'xyz ' declared?&#8221;.
This is either due to a misunderstanding on my part or (rather too commonly)
bugs in the AETE resources. Pressing <code>cancel</code> is usually the
right choice: it will cause the specific enum not to be treated as an enum
but as a &#8220;normal&#8221; type. As things like fsspecs and TEXT strings clearly are
not enumerators, this is correct. If someone understands what is really going on
here, please let me know.</li>
</ul>
<h2>The Python interface package contents</h2>
<p>
Let&#8217;s glance at the
<a href="applescript/Disk_Copy">Disk_Copy</a> package just created. You
may want to open Script Editor alongside to see how it
interprets the dictionary.
</p>
<p>
The main package module is in <code>__init__.py</code>.
The only interesting bit is the <code>Disk_Copy</code> class, which
includes the event handling classes from the individual suites. It also
inherits <code>aetools.TalkTo</code>, which is a base class that handles all
details on how to start the program and talk to it, and a class variable
<code>_signature</code> which is the default application this class will talk
to (you can override this in various ways when you instantiate your class, see
<code>aetools.py</code> for details).
</p>
<p>
The <a href="applescript/Disk_Copy/Special_Events.py">Special_Events</a>
module is a nice example of a suite module.
The <code>Special_Events_Events</code> class is the bulk of the code
generated. For each verb, it contains a method. Each method knows what
arguments the verb expects, and it makes use of keyword
arguments to present a palatable
interface to the python programmer.
Notice that each method
calls some routines from <code>aetools</code>, an auxiliary module
living in <code>Mac:Lib</code>.
The other thing to notice is that each method calls
<code>self.send</code>. This comes from the <code>aetools.TalkTo</code>
baseclass. </p>
<p>
After the big class, there are a number of little class declarations. These
declarations are for the (AppleEvent) classes and properties in the suite.
They allow you to create object IDs, which can then be passed to the verbs.
For instance,
when scripting the popular email program Eudora,
you would use <code>mailbox("inbox").message(1).sender</code>
to get the name of the sender of the first message in mailbox
inbox. It is
also possible to specify this as <code>sender(message(1, mailbox("inbox")))</code>,
which is sometimes needed because these classes don&#8217;t always inherit correctly
from baseclasses, so you may have to use a class or property from another
suite. </p>
<p>
Next we get the enumeration dictionaries, which allow you to pass
english names as arguments to verbs, so you don't have to bother with the 4-letter
type code. So, you can say
<code>
diskcopy.create(..., filesystem="Mac OS Standard")
</code>
as it is called in Script Editor, instead of the cryptic lowlevel
<code>
diskcopy.create(..., filesystem="Fhfs")
</code></p>
<p>
Finally, we get the &#8220;table of contents&#8221; of the module, listing all
classes and such
by code, which is used by <code>gensuitemodule</code> itself: if you use this
suite as a base package in a later run this is how it knows what is defined in this
suite, and what the Python names are.
</p>
<h3>Notes</h3>
<ul>
<li>The <code>aetools</code> module contains some other nifty
AppleEvent tools as well. Have a look at it sometime, there is (of
course) no documentation yet.
</li>
<li>There are also some older object specifiers for standard objects in aetools.
You use these in the form <code>aetools.Word(10,
aetools.Document(1))</code>, where the corresponding AppleScript
terminology would be <code>word 10 of the first
document</code>. Examine
<code>aetools</code> and <code>aetools.TalkTo</code>
along with
the comments at the end of your suite module if you need to create
more than the standard object specifiers.
</li>
</ul>
<h2>Using a Python suite module</h2>
<p>
Now that we have created the suite module, we can use it in a Python script.
In older MacPython distributions this used to be a rather
complicated affair, but with the package scheme and with the application signature
known by the package it is very simple: you import the package and instantiate
the class, e.g.
<code>
talker = Disk_Copy.Disk_Copy(start=1)
</code>
You will usually specify the <code>start=1</code>: it will run the application if it is
not already running.
You may want to omit it if you want to talk to the application
only if it is already running, or if the application is something like the Finder.
Another way to ensure that the application is running is to call <code>talker._start()</code>.
</p>
<p>
Looking at the sourcefile <a
href="applescript/makedisk.py">makedisk.py</a>, we see that it starts
with some imports. Naturally, one of these is the Python interface to Disk
Copy.</p>
<p>
The main program itself is a wonder of simplicity: we create the
object (<code>talker</code>) that talks to Disk Copy,
create a disk, and mount it. The bulk of
the work is done by <code>talker</code> and the Python interface package we
just created.</p>
<p>
The exception handling does warrant a few comments, though. Since
AppleScript is basically a connectionless RPC protocol,
nothing happens
when we create the <code>talker</code> object. Hence, if the destination application
is not running, we will not notice until we send our first
command (avoid this as described above). There is another thing to note about errors returned by
AppleScript calls: <code>MacOS.Error</code> is raised for
all of the errors that are known to be <code>OSErr</code>-type errors,
while
server generated errors raise <code>aetools.Error</code>. </p>
<h2>Scripting Additions</h2>
<p>
If you want to use any of the scripting additions (or OSAXen, in
everyday speech) from a Python program, you can use the same method
as for applications, i.e. run <code>gensuitemodule</code> on the
OSAX (commonly found in <code>System Folder:Scripting Additions</code>
or something similar). There is one minor gotcha: the application
signature to use is <code>MACS</code>. You will need to edit the main class
in the <code>__init__.py</code> file of the created package and change the value
of <code>_signature</code> to <code>MACS</code>, or use a subclass to the
same effect.
</p>
<p>
There are two minor points to watch out for when using <code>gensuitemodule</code>
on OSAXen: they appear all to define the class <code>System_Object_Suite</code>,
and a lot of them have the command set in multiple dialects. You have to
watch out for name conflicts and make sure you select a reasonable dialect
(some of the non-English dialects cause <code>gensuitemodule</code> to generate incorrect
Python code). </p>
Despite these difficulties, OSAXen offer a lot of possibilities. Take a
look at some of the OSAXen in the Scripting Additions folder, or
<A HREF="http://www.osaxen.com/index.php">download</A> some from the net.
<h2>Further Reading</h2>
<p>
If you want to look at more involved examples of applescripting, look at the standard
modules <code>findertools</code> and <code>nsremote</code>, or (possibly better, as it
is more involved) <code>fullbuild</code> from the <code>Mac:scripts</code> folder.
</p>
<h2><a name="alternatives">Alternatives</a></h2>
<h3><a name="osx">Mac OS X</a></h3>
<p>
Under Mac OS X, the above still works, but with some new difficulties.
The application package structure can hide the &#8216;AETE&#8217; or
&#8216;AEUT&#8217; resource from <code>gensuitemodule</code>, so that,
for example, it cannot generate an OSA interface to iTunes. Script
Editor gets at the dictionary of such programs using a &#8216;Get
AETE&#8217; AppleEvent, if someone wants to donate code to use the same
method for gensuitemodule: by all means!
</p>
<p>
One alternative is available through the Unix command line version of python.
Apple has provided the <code>osacompile</code> and <code>osascript</code> tools,
which can be used to compile and execute scripts written in OSA languages. See the
man pages for more details.
</p>
</body>
</html>

View File

@ -1,424 +0,0 @@
"""Suite Special Events: Commands for mounting Disk Copy images
Level 1, version 1
Generated from Macintosh HD:Hulpprogramma's:Disk Copy
AETE/AEUT resource version 1/0, language 0, script 0
"""
import aetools
import MacOS
_code = 'ddsk'
class Special_Events_Events:
_argmap_mount = {
'access_mode' : 'Acss',
'checksum_verification' : 'VChk',
'signature_verification' : 'VSig',
'RAM_caching' : 'Cach',
}
def mount(self, _object, _attributes={}, **_arguments):
"""mount: Mounts an Disk Copy image as a disk volume
Required argument: a reference to the disk image to be mounted
Keyword argument access_mode: the access mode for mounted volume (default is "any", i.e. best possible)
Keyword argument checksum_verification: Verify the checksum before mounting?
Keyword argument signature_verification: Verify the DigiSignŽ signature before mounting?
Keyword argument RAM_caching: Cache the disk image in RAM? (if omitted, don't cache)
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to mounted disk
"""
_code = 'ddsk'
_subcode = 'Moun'
aetools.keysubst(_arguments, self._argmap_mount)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'Acss', _Enum_Acss)
aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
aetools.enumsubst(_arguments, 'Cach', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_execute_DiskScript = {
'checksum_verification' : 'VChk',
'signature_verification' : 'VSig',
}
def execute_DiskScript(self, _object, _attributes={}, **_arguments):
"""execute DiskScript: Executes a Disk Copy-specific DiskScript
Required argument: a reference to the DiskScript to execute
Keyword argument checksum_verification: Should checksums be verified when mounting images referenced in the DiskScript?
Keyword argument signature_verification: Should the DigiSignŽ signature of the DiskScript and the images it references be verified?
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'ddsk'
_subcode = 'XEQd'
aetools.keysubst(_arguments, self._argmap_execute_DiskScript)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
def unmount(self, _object, _attributes={}, **_arguments):
"""unmount: Unmount and eject (if necessary) a volume
Required argument: a reference to disk to be unmounted (and ejected)
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'ddsk'
_subcode = 'Umnt'
if _arguments: raise TypeError('No optional args expected')
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_create = {
'saving_as' : 'SvAs',
'logical_blocks' : 'Blks',
'zeroing' : 'Zero',
'leave_image_mounted' : 'Moun',
'filesystem' : 'Fsys',
}
def create(self, _object, _attributes={}, **_arguments):
"""create: Create a new Disk Copy document
Required argument: the name of the volume to create
Keyword argument saving_as: the disk image to be created
Keyword argument logical_blocks: the number of logical blocks
Keyword argument zeroing: Should all blocks on the disk be set to zero?
Keyword argument leave_image_mounted: Should the image be mounted after it is created?
Keyword argument filesystem: file system to use (Mac OS Standard/compatible, Mac OS Enhanced)
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to newly created disk image (or newly mounted disk)
"""
_code = 'ddsk'
_subcode = 'Crea'
aetools.keysubst(_arguments, self._argmap_create)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'SvAs', _Enum_fss_)
aetools.enumsubst(_arguments, 'Blks', _Enum_long)
aetools.enumsubst(_arguments, 'Zero', _Enum_bool)
aetools.enumsubst(_arguments, 'Moun', _Enum_bool)
aetools.enumsubst(_arguments, 'Fsys', _Enum_Fsys)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
def verify_checksum(self, _object, _attributes={}, **_arguments):
"""verify checksum: Verify the checksum of a Disk Copy 4.2 or a Disk Copy 6.0 read-only document
Required argument: the disk image to be verified
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: the result of the checksum verification
"""
_code = 'ddsk'
_subcode = 'Vcrc'
if _arguments: raise TypeError('No optional args expected')
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
def verify_signature(self, _object, _attributes={}, **_arguments):
"""verify signature: Verify the DigiSignŽ signature for a Disk Copy document
Required argument: the disk image to be verified
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: Is the DigiSignŽ signature valid?
"""
_code = 'ddsk'
_subcode = 'Vsig'
if _arguments: raise TypeError('No optional args expected')
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_sign_image = {
'using_signer' : 'Sinr',
}
def sign_image(self, _object, _attributes={}, **_arguments):
"""sign image: Add a DigiSignŽ signature to a Disk Copy document
Required argument: the disk image to be signed
Keyword argument using_signer: a reference to signer file to use
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'ddsk'
_subcode = 'Asig'
aetools.keysubst(_arguments, self._argmap_sign_image)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'Sinr', _Enum_alis)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_create_a_floppy_from = {
'signature_verification' : 'VSig',
'erase_confirmation' : 'Cfrm',
'make_multiple_floppies' : 'Mult',
}
def create_a_floppy_from(self, _object, _attributes={}, **_arguments):
"""create a floppy from: create a floppy disk from a Disk Copy document
Required argument: the disk image to make a floppy from
Keyword argument signature_verification: Should the DigiSignŽ signature be verified before creating a floppy disk?
Keyword argument erase_confirmation: Should the user be asked to confirm the erasure of the previous contents of floppy disks?
Keyword argument make_multiple_floppies: Should the user be prompted to create multiple floppy disks?
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'ddsk'
_subcode = 'Bfpy'
aetools.keysubst(_arguments, self._argmap_create_a_floppy_from)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
aetools.enumsubst(_arguments, 'Cfrm', _Enum_bool)
aetools.enumsubst(_arguments, 'Mult', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_check_image = {
'details' : 'ChDe',
}
def check_image(self, _object, _attributes={}, **_arguments):
"""check image: Check the disk imageÕs internal data structures for any inconsistencies. Works on NDIF, Disk Copy 4.2, DARTŽ, or DiskSet images.
Required argument: the disk image to be verified
Keyword argument details: Should the disk image details be displayed?
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a record containing a boolean (true/false) value if the image passes consistency tests, and the numbers of warnings and errors
"""
_code = 'ddsk'
_subcode = 'Chek'
aetools.keysubst(_arguments, self._argmap_check_image)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'ChDe', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_segment_image = {
'segment_count' : 'SGCT',
'segment_size' : 'SGSZ',
'segment_name' : 'SGNM',
'image_ID' : 'SGID',
}
def segment_image(self, _object, _attributes={}, **_arguments):
"""segment image: Segment a NDIF R/W or R/O image into smaller pieces
Required argument: the disk image to be segmented
Keyword argument segment_count: the number of image segments to create
Keyword argument segment_size: the size of image segments (in blocks) to create
Keyword argument segment_name: the root name for each image segment file
Keyword argument image_ID: string used to generate a unique image ID to group the segments
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a list of references to the image segments created
"""
_code = 'ddsk'
_subcode = 'SGMT'
aetools.keysubst(_arguments, self._argmap_segment_image)
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_create_SMI = {
'source_images' : 'SMI1',
'launching_application' : 'SMI2',
'launching_document' : 'SMI3',
'version_string' : 'SMI4',
'checksum_verification' : 'VChk',
'signature_verification' : 'VSig',
'image_signing' : 'SImg',
}
def create_SMI(self, _object, _attributes={}, **_arguments):
"""create SMI: Creates a self-mounting image (SMI) from a list of NDIF disk images
Required argument: the self-mounting image to create
Keyword argument source_images: a list of references to sources images
Keyword argument launching_application: the path to an application to launch
Keyword argument launching_document: the path to a document to open
Keyword argument version_string: sets the 'vers' 1 resource of the self-mounting image
Keyword argument checksum_verification: Should the checksum of the source images be verified before creating the SMI?
Keyword argument signature_verification: Should the DigiSignŽ signature of the source images be verified before creating the SMI?
Keyword argument image_signing: Should the SMI be given a digital signature when it is created?
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to the self-mounting image created
"""
_code = 'ddsk'
_subcode = 'MSMI'
aetools.keysubst(_arguments, self._argmap_create_SMI)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
aetools.enumsubst(_arguments, 'SImg', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
class Verify_Checksum_reply_record(aetools.ComponentItem):
"""Verify Checksum reply record - """
want = 'Rcrc'
class validity(aetools.NProperty):
"""validity - true if checksum is valid """
which = 'Vlid'
want = 'bool'
class expected_checksum(aetools.NProperty):
"""expected checksum - checksum value stored in the image header (in hexadecimal) """
which = 'crcE'
want = 'TEXT'
class calculated_checksum(aetools.NProperty):
"""calculated checksum - checksum value actually calculated (in hexadecimal) """
which = 'crcA'
want = 'TEXT'
class Check_Image_reply_record(aetools.ComponentItem):
"""Check Image reply record - """
want = 'Rchk'
class consistency(aetools.NProperty):
"""consistency - Does the image pass consistency checks? """
which = 'Rch1'
want = 'bool'
class error_count(aetools.NProperty):
"""error count - the number of errors recorded """
which = 'Rch2'
want = 'long'
class warning_count(aetools.NProperty):
"""warning count - the number of warnings recorded """
which = 'Rch3'
want = 'long'
Verify_Checksum_reply_record._propdict = {
'validity' : validity,
'expected_checksum' : expected_checksum,
'calculated_checksum' : calculated_checksum,
}
Verify_Checksum_reply_record._elemdict = {
}
Check_Image_reply_record._propdict = {
'consistency' : consistency,
'error_count' : error_count,
'warning_count' : warning_count,
}
Check_Image_reply_record._elemdict = {
}
_Enum_Acss = {
'read_and_write' : 'RdWr', # read/write access
'read_only' : 'Rdxx', # read-only access
'any' : 'Anyx', # best possible access
}
_Enum_Fsys = {
'Mac_OS_Standard' : 'Fhfs', # classic HFS file system
'compatible_Mac_OS_Extended' : 'Fhf+', # new HFS+ file system
}
_Enum_alis = None # XXXX enum alis not found!!
_Enum_fss_ = None # XXXX enum fss not found!!
_Enum_long = None # XXXX enum long not found!!
_Enum_bool = None # XXXX enum bool not found!!
#
# Indices of types declared in this module
#
_classdeclarations = {
'Rchk' : Check_Image_reply_record,
'Rcrc' : Verify_Checksum_reply_record,
}
_propdeclarations = {
'crcE' : expected_checksum,
'Rch2' : error_count,
'crcA' : calculated_checksum,
'Rch3' : warning_count,
'Vlid' : validity,
'Rch1' : consistency,
}
_compdeclarations = {
}
_enumdeclarations = {
'Acss' : _Enum_Acss,
'Fsys' : _Enum_Fsys,
}

View File

@ -1,477 +0,0 @@
"""Suite Standard Suite: Common terms for most applications
Level 1, version 1
Generated from Macintosh HD:Hulpprogramma's:Disk Copy
AETE/AEUT resource version 1/0, language 0, script 0
"""
import aetools
import MacOS
_code = 'Core'
class Standard_Suite_Events:
_argmap_save = {
'_in' : 'kfil',
'using_format' : 'SvAs',
'checksum_verification' : 'VChk',
'signature_verification' : 'VSig',
'image_signing' : 'SImg',
'leave_image_mounted' : 'Moun',
'percent_free_space' : 'Slop',
'logical_blocks' : 'Blks',
'zeroing' : 'Zero',
}
def save(self, _object, _attributes={}, **_arguments):
"""save: Save an object
Required argument: the source object
Keyword argument _in: the target object
Keyword argument using_format: the format for the target
Keyword argument checksum_verification: Should the checksum be verified before saving?
Keyword argument signature_verification: Should the DigiSignŽ signature be verified before saving?
Keyword argument image_signing: Should the image be signed?
Keyword argument leave_image_mounted: Should the image be mounted after saving?
Keyword argument percent_free_space: percent free space to reserve (for image folder operation, 0-255%)
Keyword argument logical_blocks: number of logical blocks in the image (for image folder operation)
Keyword argument zeroing: Should all the blocks in the image be set to zeros? (for image folder operation)
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: the result of the save operation
"""
_code = 'core'
_subcode = 'save'
aetools.keysubst(_arguments, self._argmap_save)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'kfil', _Enum_obj_)
aetools.enumsubst(_arguments, 'SvAs', _Enum_SvAs)
aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
aetools.enumsubst(_arguments, 'SImg', _Enum_bool)
aetools.enumsubst(_arguments, 'Moun', _Enum_bool)
aetools.enumsubst(_arguments, 'Slop', _Enum_long)
aetools.enumsubst(_arguments, 'Blks', _Enum_long)
aetools.enumsubst(_arguments, 'Zero', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
def do_script(self, _object, _attributes={}, **_arguments):
"""do script: Execute an attached script located in the folder "Scripts"
Required argument: the script to be executed
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'core'
_subcode = 'dosc'
if _arguments: raise TypeError('No optional args expected')
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
class application(aetools.ComponentItem):
"""application - The Disk Copy application """
want = 'capp'
class version(aetools.NProperty):
"""version - the version of this application """
which = 'vers'
want = 'vers'
class name(aetools.NProperty):
"""name - the name of this application """
which = 'pnam'
want = 'TEXT'
class comment(aetools.NProperty):
"""comment - the comment associated with the application """
which = 'comt'
want = 'TEXT'
class driver_version(aetools.NProperty):
"""driver version - the version of the disk image driver """
which = 'dVer'
want = 'vers'
class nonejectable_mode(aetools.NProperty):
"""nonejectable mode - Should mounted images be non-ejectable? """
which = 'otto'
want = 'bool'
class save_log_file(aetools.NProperty):
"""save log file - Should the log file be saved on disk? """
which = 'PSaL'
want = 'bool'
class use_speech(aetools.NProperty):
"""use speech - Should Disk Copy use spoken feedback? """
which = 'PTlk'
want = 'bool'
class smart_Save_As(aetools.NProperty):
"""smart Save As - Should the Save As... dialog box automatically go to the right folder? """
which = 'PSSP'
want = 'bool'
class checksum_verification(aetools.NProperty):
"""checksum verification - Should image checksums be verified? """
which = 'PVeC'
want = 'bool'
class signature_verification(aetools.NProperty):
"""signature verification - Should digital signatures be verified? """
which = 'PVeS'
want = 'bool'
class exclude_DiskScripts(aetools.NProperty):
"""exclude DiskScripts - Should images referenced in DiskScripts/DiskSets be excluded from verification? """
which = 'PExD'
want = 'bool'
class exclude_remote_images(aetools.NProperty):
"""exclude remote images - Should images that are located on network volumes be excluded from verification? """
which = 'PExR'
want = 'bool'
class image_signing(aetools.NProperty):
"""image signing - Should images be signed with a digital signature? """
which = 'PSiI'
want = 'bool'
class leave_image_mounted(aetools.NProperty):
"""leave image mounted - Should images be mounted after they are created? """
which = 'PMoA'
want = 'bool'
class erase_confirmation(aetools.NProperty):
"""erase confirmation - Should the user be required to confirm commands that erase disks? """
which = 'PCoE'
want = 'bool'
class zeroing(aetools.NProperty):
"""zeroing - Should all blocks of a new image be set to zero? """
which = 'PZeB'
want = 'bool'
class default_create_size(aetools.NProperty):
"""default create size - the default size for a new image, in blocks (512 bytes per block) """
which = 'PDeS'
want = 'long'
class default_create_name(aetools.NProperty):
"""default create name - the default volume name for a new image """
which = 'PDeN'
want = 'TEXT'
class make_multiple_floppies(aetools.NProperty):
"""make multiple floppies - Should the user be prompted to make multiple floppy disk images at a time? """
which = 'PBuM'
want = 'bool'
class auto_image_upon_insert(aetools.NProperty):
"""auto image upon insert - Should a newly-inserted disk automatically be processed into an image? """
which = 'Paim'
want = 'bool'
class eject_after_auto_image(aetools.NProperty):
"""eject after auto image - Should auto-imaged disks be ejected afterwards? """
which = 'Pejc'
want = 'bool'
class auto_copy_upon_floppy_insert(aetools.NProperty):
"""auto copy upon floppy insert - Instead of auto-imaging, should newly-inserted floppy disks be copied? """
which = 'Pcpf'
want = 'bool'
class volume_suffix(aetools.NProperty):
"""volume suffix - the default volume name suffix """
which = 'PDiE'
want = 'TEXT'
class image_suffix(aetools.NProperty):
"""image suffix - the default image name suffix """
which = 'PImE'
want = 'TEXT'
class default_file_system(aetools.NProperty):
"""default file system - the default file system type for new blank images """
which = 'Pfsy'
want = 'Fsys'
class default_image_format(aetools.NProperty):
"""default image format - the default image file format """
which = 'Pdfm'
want = 'SvAs'
class disk(aetools.ComponentItem):
"""disk - A mounted volume """
want = 'Disk'
name = name
comment = comment
class locked(aetools.NProperty):
"""locked - Is the disk locked? """
which = 'islk'
want = 'bool'
class creation_date(aetools.NProperty):
"""creation date - the creation date of disk """
which = 'ascd'
want = 'ldt '
class modification_date(aetools.NProperty):
"""modification date - the modification date of disk """
which = 'asmo'
want = 'ldt '
class crc32_checksum(aetools.NProperty):
"""crc32 checksum - the crc-32 checksum of the disk """
which = 'Xcrc'
want = 'TEXT'
class disk_copy_4_2e_2_checksum(aetools.NProperty):
"""disk copy 4.2 checksum - the Disk Copy 4.2 checksum of the disk """
which = 'Xc42'
want = 'TEXT'
class block_count(aetools.NProperty):
"""block count - the number of blocks on disk """
which = 'Xblk'
want = 'long'
class file_system(aetools.NProperty):
"""file system - the file system used on disk """
which = 'Xfsi'
want = 'TEXT'
class folder(aetools.ComponentItem):
"""folder - A folder or directory on a disk """
want = 'Fold'
name = name
comment = comment
creation_date = creation_date
modification_date = modification_date
class disk_image(aetools.ComponentItem):
"""disk image - A disk image file """
want = 'DImg'
name = name
comment = comment
locked = locked
creation_date = creation_date
modification_date = modification_date
class file_format(aetools.NProperty):
"""file format - the format of the disk image file """
which = 'Ifmt'
want = 'TEXT'
class signed(aetools.NProperty):
"""signed - Does the disk image have a DigiSignŽ signature? """
which = 'Isin'
want = 'bool'
class compressed(aetools.NProperty):
"""compressed - Is the disk image compressed? """
which = 'Icom'
want = 'bool'
class segmented(aetools.NProperty):
"""segmented - Is the disk image segmented? """
which = 'Iseg'
want = 'bool'
class segments(aetools.NProperty):
"""segments - a list of references to other segments that make up a complete image """
which = 'Isg#'
want = 'fss '
class disk_name(aetools.NProperty):
"""disk name - the name of the disk this image represents """
which = 'Idnm'
want = 'TEXT'
crc32_checksum = crc32_checksum
disk_copy_4_2e_2_checksum = disk_copy_4_2e_2_checksum
block_count = block_count
file_system = file_system
class data_fork_size(aetools.NProperty):
"""data fork size - the size (in bytes) of the data fork of the disk image """
which = 'Idfk'
want = 'long'
class resource_fork_size(aetools.NProperty):
"""resource fork size - the size (in bytes) of the resource fork of the disk image """
which = 'Irfk'
want = 'long'
class Save_reply_record(aetools.ComponentItem):
"""Save reply record - Result from the save operation """
want = 'cpyR'
class resulting_target_object(aetools.NProperty):
"""resulting target object - a reference to the target object after it has been saved """
which = 'rcpO'
want = 'obj '
class copy_type(aetools.NProperty):
"""copy type - the way in which the target object was saved """
which = 'rcpT'
want = 'rcpT'
application._propdict = {
'version' : version,
'name' : name,
'comment' : comment,
'driver_version' : driver_version,
'nonejectable_mode' : nonejectable_mode,
'save_log_file' : save_log_file,
'use_speech' : use_speech,
'smart_Save_As' : smart_Save_As,
'checksum_verification' : checksum_verification,
'signature_verification' : signature_verification,
'exclude_DiskScripts' : exclude_DiskScripts,
'exclude_remote_images' : exclude_remote_images,
'image_signing' : image_signing,
'leave_image_mounted' : leave_image_mounted,
'erase_confirmation' : erase_confirmation,
'zeroing' : zeroing,
'default_create_size' : default_create_size,
'default_create_name' : default_create_name,
'make_multiple_floppies' : make_multiple_floppies,
'auto_image_upon_insert' : auto_image_upon_insert,
'eject_after_auto_image' : eject_after_auto_image,
'auto_copy_upon_floppy_insert' : auto_copy_upon_floppy_insert,
'volume_suffix' : volume_suffix,
'image_suffix' : image_suffix,
'default_file_system' : default_file_system,
'default_image_format' : default_image_format,
}
application._elemdict = {
}
disk._propdict = {
'name' : name,
'comment' : comment,
'locked' : locked,
'creation_date' : creation_date,
'modification_date' : modification_date,
'crc32_checksum' : crc32_checksum,
'disk_copy_4_2e_2_checksum' : disk_copy_4_2e_2_checksum,
'block_count' : block_count,
'file_system' : file_system,
}
disk._elemdict = {
}
folder._propdict = {
'name' : name,
'comment' : comment,
'creation_date' : creation_date,
'modification_date' : modification_date,
}
folder._elemdict = {
}
disk_image._propdict = {
'name' : name,
'comment' : comment,
'locked' : locked,
'creation_date' : creation_date,
'modification_date' : modification_date,
'file_format' : file_format,
'signed' : signed,
'compressed' : compressed,
'segmented' : segmented,
'segments' : segments,
'disk_name' : disk_name,
'crc32_checksum' : crc32_checksum,
'disk_copy_4_2e_2_checksum' : disk_copy_4_2e_2_checksum,
'block_count' : block_count,
'file_system' : file_system,
'data_fork_size' : data_fork_size,
'resource_fork_size' : resource_fork_size,
}
disk_image._elemdict = {
}
Save_reply_record._propdict = {
'resulting_target_object' : resulting_target_object,
'copy_type' : copy_type,
}
Save_reply_record._elemdict = {
}
_Enum_UIAc = {
'never_interact' : 'eNvr', # DonÕt allow any interaction at all
'interact_with_self' : 'eInS', # Only allow interaction from internal events
'interact_with_local' : 'eInL', # Allow interaction from any event originating on this machine
'interact_with_all' : 'eInA', # Allow interaction from network events
}
_Enum_SvAs = {
'NDIF_RW' : 'RdWr', # read/write NDIF disk image
'NDIF_RO' : 'Rdxx', # read-only NDIF disk image
'NDIF_Compressed' : 'ROCo', # compressed NDIF disk image
'Disk_Copy_4_2e_2' : 'DC42', # Disk Copy 4.2 disk image
}
_Enum_rcpT = {
'block_disk_copy' : 'cpBl', # block-by-block disk-level copy
'files_and_file_ID_copy' : 'cpID', # all files including desktop databases and file IDÕs
'files_and_desktop_info' : 'cpDT', # all files and most desktop information
'files_only' : 'cpFI', # all files but no desktop information
'disk_image_conversion' : 'cpCV', # disk image format conversion
'disk_image_creation' : 'cpCR', # disk image creation
}
_Enum_long = None # XXXX enum long not found!!
_Enum_bool = None # XXXX enum bool not found!!
_Enum_obj_ = None # XXXX enum obj not found!!
#
# Indices of types declared in this module
#
_classdeclarations = {
'DImg' : disk_image,
'capp' : application,
'Disk' : disk,
'Fold' : folder,
'cpyR' : Save_reply_record,
}
_propdeclarations = {
'Xcrc' : crc32_checksum,
'PDeS' : default_create_size,
'Idnm' : disk_name,
'PSSP' : smart_Save_As,
'Pcpf' : auto_copy_upon_floppy_insert,
'pnam' : name,
'Isin' : signed,
'otto' : nonejectable_mode,
'PExD' : exclude_DiskScripts,
'Iseg' : segmented,
'islk' : locked,
'asmo' : modification_date,
'PTlk' : use_speech,
'Pfsy' : default_file_system,
'PVeC' : checksum_verification,
'Xc42' : disk_copy_4_2e_2_checksum,
'rcpO' : resulting_target_object,
'Paim' : auto_image_upon_insert,
'comt' : comment,
'PCoE' : erase_confirmation,
'dVer' : driver_version,
'PDeN' : default_create_name,
'PBuM' : make_multiple_floppies,
'rcpT' : copy_type,
'PDiE' : volume_suffix,
'Ifmt' : file_format,
'Pdfm' : default_image_format,
'ascd' : creation_date,
'Pejc' : eject_after_auto_image,
'PZeB' : zeroing,
'PExR' : exclude_remote_images,
'PImE' : image_suffix,
'PVeS' : signature_verification,
'PSaL' : save_log_file,
'Xblk' : block_count,
'PMoA' : leave_image_mounted,
'Isg#' : segments,
'Irfk' : resource_fork_size,
'Icom' : compressed,
'Xfsi' : file_system,
'Idfk' : data_fork_size,
'vers' : version,
'PSiI' : image_signing,
}
_compdeclarations = {
}
_enumdeclarations = {
'SvAs' : _Enum_SvAs,
'UIAc' : _Enum_UIAc,
'rcpT' : _Enum_rcpT,
}

View File

@ -1,212 +0,0 @@
"""Suite Utility Events: Commands that allow the user to select Disk Copy files
Level 1, version 1
Generated from Macintosh HD:Hulpprogramma's:Disk Copy
AETE/AEUT resource version 1/0, language 0, script 0
"""
import aetools
import MacOS
_code = 'ddsk'
class Utility_Events_Events:
_argmap_select_disk_image = {
'with_prompt' : 'SELp',
}
def select_disk_image(self, _no_object=None, _attributes={}, **_arguments):
"""select disk image: Prompt the user to select a disk image
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to a disk image
"""
_code = 'UTIL'
_subcode = 'SEL1'
aetools.keysubst(_arguments, self._argmap_select_disk_image)
if _no_object is not None: raise TypeError('No direct arg expected')y
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_select_DiskScript = {
'with_prompt' : 'SELp',
}
def select_DiskScript(self, _no_object=None, _attributes={}, **_arguments):
"""select DiskScript: Prompt the user to select a DiskScript
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to a DiskScript
"""
_code = 'UTIL'
_subcode = 'SEL2'
aetools.keysubst(_arguments, self._argmap_select_DiskScript)
if _no_object is not None: raise TypeError('No direct arg expected')
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_select_disk_image_or_DiskScript = {
'with_prompt' : 'SELp',
}
def select_disk_image_or_DiskScript(self, _no_object=None, _attributes={}, **_arguments):
"""select disk image or DiskScript: Prompt the user to select a disk image or DiskScript
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to disk image or a DiskScript
"""
_code = 'UTIL'
_subcode = 'SEL3'
aetools.keysubst(_arguments, self._argmap_select_disk_image_or_DiskScript)
if _no_object is not None: raise TypeError('No direct arg expected')
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_select_floppy_disk_image = {
'with_prompt' : 'SELp',
}
def select_floppy_disk_image(self, _no_object=None, _attributes={}, **_arguments):
"""select floppy disk image: Prompt the user to select a floppy disk image
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to a floppy disk image
"""
_code = 'UTIL'
_subcode = 'SEL4'
aetools.keysubst(_arguments, self._argmap_select_floppy_disk_image)
if _no_object is not None: raise TypeError('No direct arg expected')
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_select_disk = {
'with_prompt' : 'SELp',
}
def select_disk(self, _no_object=None, _attributes={}, **_arguments):
"""select disk: Prompt the user to select a disk volume
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to the disk
"""
_code = 'UTIL'
_subcode = 'SEL5'
aetools.keysubst(_arguments, self._argmap_select_disk)
if _no_object is not None: raise TypeError('No direct arg expected')
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_select_folder = {
'with_prompt' : 'SELp',
}
def select_folder(self, _no_object=None, _attributes={}, **_arguments):
"""select folder: Prompt the user to select a folder
Keyword argument with_prompt: the prompt string to be displayed
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: a reference to the folder
"""
_code = 'UTIL'
_subcode = 'SEL6'
aetools.keysubst(_arguments, self._argmap_select_folder)
if _no_object is not None: raise TypeError('No direct arg expected')
aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_argmap_log = {
'time_stamp' : 'TSMP',
}
def log(self, _object, _attributes={}, **_arguments):
"""log: Add a string to the log window
Required argument: the string to add to the log window
Keyword argument time_stamp: Should the log entry be time-stamped? (false if not supplied)
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'UTIL'
_subcode = 'LOG '
aetools.keysubst(_arguments, self._argmap_log)
_arguments['----'] = _object
aetools.enumsubst(_arguments, 'TSMP', _Enum_bool)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error(aetools.decodeerror(_arguments))
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_Enum_TEXT = None # XXXX enum TEXT not found!!
_Enum_bool = None # XXXX enum bool not found!!
#
# Indices of types declared in this module
#
_classdeclarations = {
}
_propdeclarations = {
}
_compdeclarations = {
}
_enumdeclarations = {
}

View File

@ -1,35 +0,0 @@
"""
Package generated from Macintosh HD:Hulpprogramma's:Disk Copy
Resource aete resid 0
"""
import aetools
Error = aetools.Error
import Standard_Suite
import Special_Events
import Utility_Events
_code_to_module = {
'Core' : Standard_Suite,
'ddsk' : Special_Events,
'ddsk' : Utility_Events,
}
_code_to_fullname = {
'Core' : ('Disk_Copy.Standard_Suite', 'Standard_Suite'),
'ddsk' : ('Disk_Copy.Special_Events', 'Special_Events'),
'ddsk' : ('Disk_Copy.Utility_Events', 'Utility_Events'),
}
from Standard_Suite import *
from Special_Events import *
from Utility_Events import *
class Disk_Copy(Standard_Suite_Events,
Special_Events_Events,
Utility_Events_Events,
aetools.TalkTo):
_signature = 'ddsk'

View File

@ -1,15 +0,0 @@
import Disk_Copy
import macfs
import sys
talker = Disk_Copy.Disk_Copy(start=1)
talker.activate()
filespec = macfs.FSSpec('my disk image.img')
try:
objref = talker.create('my disk image', saving_as=filespec, leave_image_mounted=1)
except Disk_Copy.Error as arg:
print("ERROR: my disk image:", arg)
else:
print('objref=', objref)
print('Type return to exit-')
sys.stdin.readline()

View File

@ -1,75 +0,0 @@
<HTML><HEAD><TITLE>Using python to create Macintosh applications, part zero</TITLE></HEAD>
<BODY>
<H1>Using python to create Macintosh applications, part zero</H1>
<HR>
This document will show you how to create a simple mac-style
application using Python. We will glance at how to use file dialogs and
messages. <p>
Our example program <a href="example0/checktext.py">checktext.py</a> asks
the user for a text file and checks what style end-of-lines the file has.
This may need a little explanation: ASCII text files are almost identical
on different machines, with one exception:
<ul>
<li> Unix systems terminate lines with the "linefeed" character, <code>0x0a</code>,
<li> Macintoshes terminate lines with the "carriage return" character,
<code>0x0d</code> and
<li> MSDOS and Windows terminate lines with first a carriage return and then a linefeed.
</ul>
Let us have a look at the program. The first interesting statement in the main
program is the call to <code>macfs.PromptGetFile</code>. This is one of the routines
that allow you to ask the user to specify a file. You pass it one required
argument, the prompt string. There are up to four optional MacOS <em>file type</em> arguments
you can pass, as 4-byte strings. Specifying no file
type will allow the user to select any file, specifying one or more types restricts
the user to files of this type. File types are explained in most books on the Mac. <p>
<code>PromptGetFile</code> returns two values: an <em>FSSpec</em> object and a
success indicator. The FSSpec object is the "official" MacOS way of specifying a
file, more on it later. The success indicator tells you whether the user clicked OK
or Cancel. In the event of Cancel we simply exit back to the finder. <p>
<code>PromptGetFile</code> has a number of friends that do similar things:
<ul>
<li> <code>StandardGetFile</code> is identical to <code>PromptGetFile</code> but
without the prompt. It has up to four optional filetype arguments.
<li> <code>StandardPutFile</code> asks the user for an output file. It will
warn the user when she tries to overwrite an existing file. The routine has one
mandatory argument: a prompt string. Pass the empty string if you do not want a prompt.
<li> <code>GetDirectory</code> asks the user for a folder (or directory, in unix terms).
It has one optional argument: a prompt string.
</ul>
All routines return an FSSpec and a success indicator. <p>
There are many things you can do with FSSpec objects (see the
<a href="http://www.python.org/doc/lib/macfs.html">macfs</a> section in the
<a href="http://www.python.org/doc/lib/Top.html">Python Library Reference</a>
for details), but passing them to <code>open</code> is not
one of them. For this, we first have to convert the FSSpec object to a pathname, with
the <code>as_pathname</code> method. This returns a standard MacOS-style pathname with
colon-separated components. This can then be passed to <code>open</code>. Note that
we call open with mode parameter <code>'rb'</code>: we want to read the file in binary
mode. Python, like C and C++, uses unix-style line endings internally and opening a
file in text mode (<code>'r'</code>) would result in conversion of carriage-returns to
linefeeds upon reading. This is something that Mac and DOS programmers are usually aware
of but that never ceases to amaze unix buffs. <p>
After we open the file we attempt to read all data into memory. If this fails we use
<code>EasyDialogs.Message</code> to display a message in a standard dialog box and exit.
The EasyDialogs module has a few more useful simple dialog routines, more on that in
<a href="example1.html">example 1</a>. <p>
The rest of the code is pretty straightforward: we check that the file actually contains
data, count the number of linefeeds and returns and display a message with our guess of the
end-of-line convention used in the file. <p>
The <a href="example0">example0</a> folder has three text files in Mac, Unix and DOS style
for you to try the program on. After that, you can continue with <a href="example1.html">example 1</a>
or go back to the <a href="index.html">index</a> to find another interesting topic. <p>
<HR>
<A HREF="http://www.cwi.nl/~jack">Jack Jansen</A>,
<A HREF="mailto:jack@cwi.nl">jack@cwi.nl</A>, 18-July-1996.
</BODY></HTML>

View File

@ -1,35 +0,0 @@
"""checktext - Check that a text file has macintosh-style newlines"""
import sys
import EasyDialogs
import string
def main():
pathname = EasyDialogs.AskFileForOpen(message='File to check end-of-lines in:')
if not pathname:
sys.exit(0)
fp = open(pathname, 'rb')
try:
data = fp.read()
except MemoryError:
EasyDialogs.Message('Sorry, file is too big.')
sys.exit(0)
if len(data) == 0:
EasyDialogs.Message('File is empty.')
sys.exit(0)
number_cr = string.count(data, '\r')
number_lf = string.count(data, '\n')
if number_cr == number_lf == 0:
EasyDialogs.Message('File contains no lines.')
if number_cr == 0:
EasyDialogs.Message('File has unix-style line endings')
elif number_lf == 0:
EasyDialogs.Message('File has mac-style line endings')
elif number_cr == number_lf:
EasyDialogs.Message('File probably has MSDOS-style line endings')
else:
EasyDialogs.Message('File has no recognizable line endings (binary file?)')
sys.exit(0)
if __name__ == '__main__':
main()

View File

@ -1,193 +0,0 @@
<HTML><HEAD><TITLE>Using python to create Macintosh applications, part one</TITLE></HEAD>
<BODY>
<H1>Using python to create Macintosh applications, part one</H1>
<HR>
This document will show you how to create a simple mac-style
application using Python. We will glance at how to use dialogs and
resources. <p>
The example application we look at will be a simple program with a
dialog that allows you to perform domain name lookups on IP addresses
and hostnames.
The <A HREF="example1/dnslookup-1.py">source code</A> and
<A HREF="example1/dnslookup-1.rsrc">resource file</A>
for this application are available in the <A
HREF="example1">example1</A> folder (which you will have to download
if you are reading this document over the net and if you want to look
at the resources). <p>
We will use the builtin module "socket" that allows a
Python program to perform all sorts of networking functions, and we
will create the user interface around that. You should be able to run
the sample code with the standard Python distribution.<p>
<CITE>
If you are interested in building your own extensions to python you
should check out the companion document <A
HREF="plugins.html">Creating Macintosh Python C extensions</A>,
which tells you how to build your own C extension.
<p>
</CITE>
<H2><A NAME="dialog-resources">Creating dialog resources</A></H2>
Let us start with the creative bit: building the dialogs and creating
an icon for our program. For this you need ResEdit, and a reasonable
working knowledge of how to use it. "Inside Mac" or various books on
macintosh programming will help here. <p>
There is one fine point that deserves to be mentioned here: <A
NAME="resource-numbering">resource numbering</A>. Because often your
resources will be combined with those that the Python interpreter and
various standard modules need you should give your DLOG and DITL
resources numbers above 512. 128 and below are reserved for Apple,
128-228 are for extensions like Tk,
228-255 for the Python interpreter and 256-511 for standard
modules. If you are writing a module that you will be distributing for
inclusion in other people's programs you may want to register a number
in the 256-511 range, contact Guido or myself or whoever you think is
"in charge" of Python for the Macintosh at the moment. Even though the
application we are writing at the moment will keep its resources in a
separate resource file it is still a good idea to make sure that no
conflicts arise: once you have opened your resource file any attempt
by the interpreter to open a dialog will also search your resource
file. <p>
Okay, let's have a look at dnslookup-1.rsrc, our resource file.
The DLOG and accompanying DITL resource both have number 512. Since
ResEdit creates both with default ID=128 you should take care to
change the number on both. The dialog itself is pretty basic: two
buttons (Lookup and Quit), two labels and
two text entry areas, one of which is used for output only. Here's what
the dialog will look like at run time<p>
<div align=center>
<img width=324 height=189 src="example1/dnslookup-1.gif" alt="dialog image">
</div>
<p>
<H2><A NAME="modal-dialog">An application with a modal dialog</A></H2>
Next, we will have to write the actual application. For this example,
we will use a modal dialog. This means that we will put up the dialog
and go into a loop asking the dialog manager for events (buttons
pushed). We handle the actions requested by the user until the Quit
button is pressed, upon which we exit our loop (and the program). This
way of structuring your program is actually rather antisocial, since
you force the user to do whatever you, the application writer, happen
to want. A modal dialog leaves no way of escape whatsoever (except
command-option-escape), and is usually not a good way to structure
anything but the most simple questions. Even then: how often have you
been confronted with a dialog asking a question that you could not
answer because the data you needed was obscured by the dialog itself?
In the next example we will look at an application that does pretty
much the same as this one but in a more user-friendly way. <p>
The code itself is contained in the file <A
HREF="example1/dnslookup-1.py"> dnslookup-1.py</A>. Have
a copy handy before you read on. The file starts off with a
textstring giving a short description. Not many tools do anything with
this as yet, but at some point in the future we <EM>will</EM> have all
sorts of nifty class browser that will display this string, so just
include it. Just put a short description at the start of each module,
class, method and function. After the initial description and some
comments, we import the modules we need. <p>
<A NAME="easydialogs"><CODE>EasyDialogs</CODE></A> is a handy standard
module that provides you with routines that put up common text-only
modal dialogs:
<UL>
<LI> <CODE>Message(str)</CODE>
displays the message "str" and an OK button,
<LI> <CODE>AskString(prompt, default)</CODE>
asks for a string, displays OK and Cancel buttons,
<LI> <CODE>AskYesNoCancel(question, default)</CODE>
displays a question and Yes, No and Cancel buttons.
</UL>
<A NAME="res"><CODE>Res</CODE></A> is a pretty complete interface to
the MacOS Resource Manager, described fully in Inside Mac. There is
currently no documentation of it, but the Apple documentation (or
Think Ref) will help you on your way if you remember two points:
<UL>
<LI> Resources are implemented as Python objects, and each routine
with a resource first argument is implemented as a python method.
<LI> When in doubt about the arguments examine the routines docstring,
as in <CODE>print Res.OpenResFile.__doc__</CODE>
</UL>
Similarly, <A NAME="dlg"><CODE>Dlg</CODE></A> is an interface to the
Dialog manager (with Dialogs being implemented as python objects and
routines with Dialog arguments being methods). The sys module you
know, I hope. The string module is an often used module that enables
you to perform many string related operations. In this case however, we
are only using the "digits" constant from the string module. We could
have simply defined "digits" as "0123456789". The socket module enables
us to perform the domain name lookups. We
use two calls from it:
<UL>
<LI> <CODE>gethostbyaddr()</CODE>
returns the hostname associated with an IP address
<LI> <CODE>gethostbyname()</CODE>
returns the IP address associated with a hostname
</UL>
Next in the source file we get definitions for our dialog resource
number and for the item numbers in our dialog. These should match the
situation in our resource file dnslookup-1.rsrc,
obviously.<p>
On to the main program. We start off with opening our resource file,
which should live in the same folder as the python source. If we
cannot open it we use <CODE>EasyDialogs</CODE> to print a message and
exit. You can try it: just move the resource file somewhere else for a
moment. Then we call do_dialog() to do the real work. <p>
<CODE>Do_dialog()</CODE> uses <CODE>Dlg.GetNewDialog()</CODE> to open
a dialog window initialized from 'DLOG' resource ID_MAIN and putting
it on screen in the frontmost position. Next, we go into a loop,
calling <CODE>Dlg.ModalDialog()</CODE> to wait for the next user
action. <CODE>ModalDialog()</CODE> will return us the item number that
the user has clicked on (or otherwise activated). It will handle a few
slightly more complicated things also, like the user typing into
simple textfields, but it will <EM>not</EM> do things like updating
the physical appearance of radio buttons, etc. See Inside Mac or
another programming guide for how to handle this
yourself. Fortunately, our simple application doesn't have to bother with this,
since buttons and textfields are the only active elements we have. So, we do a
simple switch on item number and call the appropriate routine to implement the
action requested. Upon the user pressing "Quit" we simply leave the loop and,
hence, <CODE>do_dialog()</CODE>. This will cause the python dialog object
<CODE>my_dlg</CODE> to be deleted and the on-screen dialog to disappear. <p>
<A NAME="dialog-warning">Time for a warning</A>: be very careful what
you do as long as a dialog is on-screen. Printing something, for
instance, may suddenly cause the standard output window to appear over
the dialog, and since we took no measures to redraw the dialog it will
become very difficult to get out of the dialog. Also, command-period
may or may not work in this situation. I have also seen crashes in
such a situation, probably due to the multiple event loops involved or
some oversight in the interpreter. You have been warned. <p>
The implementation of the "Lookup" command can use a bit more
explaining: we get the necessary information with <CODE>dnslookup()</CODE>
but now we have to update the on-screen dialog to present this
information to the user. The <CODE>GetDialogItem()</CODE> method of
the dialog returns three bits of information about the given item: its
type, its data handle and its rect (the on-screen <CODE>x,y,w,h</CODE>
coordinates). We are only interested in the data handle here, on which
we call <CODE>SetDialogItemText()</CODE> to set our new text. Note
here that python programmers need not bother with the C-string versus
pascal-string controversy: the python glue module knows what is needed
and converts the python string to the correct type. <p>
And that concludes our first example of the use of resources and
dialogs. Next, you could have a look at the source of EasyDialogs for
some examples of using input fields and filterprocs. Or, go on with
reading the <A HREF="example2.html">second part</A> of this document
to see how to implement a better version of this application.<p>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,55 +0,0 @@
"""Sample program performing domain name lookups and showing off EasyDialogs,
Res and Dlg in the process"""
import EasyDialogs
from Carbon import Res
from Carbon import Dlg
import socket
import string
import macresource
#
# Definitions for our resources
ID_MAIN=512
ITEM_LOOKUP_ENTRY=1
ITEM_RESULT=2
ITEM_LOOKUP_BUTTON=3
ITEM_QUIT_BUTTON=4
def main():
"""Main routine: open resource file, call dialog handler"""
macresource.need("DLOG", ID_MAIN, "dnslookup-1.rsrc")
do_dialog()
def do_dialog():
"""Post dialog and handle user interaction until quit"""
my_dlg = Dlg.GetNewDialog(ID_MAIN, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == ITEM_LOOKUP_BUTTON:
tp, h, rect = my_dlg.GetDialogItem(ITEM_LOOKUP_ENTRY)
txt = Dlg.GetDialogItemText(h)
tp, h, rect = my_dlg.GetDialogItem(ITEM_RESULT)
Dlg.SetDialogItemText(h, dnslookup(txt))
elif n == ITEM_QUIT_BUTTON:
break
def dnslookup(str):
""" Perform DNS lookup on str. If first character of digit is numeric,
assume that str contains an IP address. Otherwise, assume that str
contains a hostname."""
if str == '': str = ' '
if str[0] in string.digits:
try:
value = socket.gethostbyaddr(str)[0]
except:
value = 'Lookup failed'
else:
try:
value = socket.gethostbyname(str)
except:
value = 'Lookup failed'
return value
main()

Binary file not shown.

View File

@ -1,162 +0,0 @@
<HTML><HEAD><TITLE>Using python to create Macintosh applications, part two</TITLE></HEAD>
<BODY>
<H1>Using python to create Macintosh applications, part two</H1>
<HR>
In this document we rewrite the application of the <A
HREF="example1.html">previous example</A> to use modeless dialogs. We
will use an application framework, and we will have a look at creating
applets, standalone applications written in Python. The <A
HREF="example2/dnslookup-2.py">source code</A> and
<A HREF="example2/dnslookup-2.rsrc">resource file</A> are available in the folder
<A HREF="example2">example2</A>. <p>
Again, we start with ResEdit to create our dialogs. Not only do we
want a main dialog this time but also an "About" dialog. This example is less
than complete since we do not provide a <A NAME="bundle">BNDL resource</A>
and related stuff that an application cannot be without. We are able to do this
when building a python applet since BuildApplet will substitute default resources
for BNDL, etc. when none are supplied (<A HREF="#no-bundle">See below</A>.)
"Inside Mac" or various
books on Macintosh programming will help here. Also, you can refer to
the resource files provided in the Python source distribution for some
of the python-specific points of BNDL programming: the
"appletbundle.rsrc" file is what is used for creating applets if you
don't provide your own resource file. <p>
When creating your own BNDL resouorces, keep in mind that the Finder gets
confused if you have more than one application with the same signature. This may be due
to some incorrectness on the side of "BuildApplet", I am not sure. There is one
case when you definitely need a unique signature: when you create an applet that
has its own data files and you want the user to be able to start your
applet by double-clicking one of the datafiles. <p>
Let's have a look at dnslookup-2.rsrc, our resource file. Dialog 512 is the
main window which has one button (Lookup), two labels and
two text entry areas, one of which is used for output only. The "Quit"
button has disappeared, because its function is handled by a menu choice. Here's
what it will look like at run time:<p>
<div align=center>
<img width=324 height=205 src="example2/dnslookup-2.gif" alt="dialog image">
</div>
<p>
<H2>A modeless dialog application using FrameWork</H2>
On to the source code in <A
HREF="example2/dnslookup-2.py">dnslookup-2.py</A>. The
start is similar to our previous example program <A
HREF="example1/dnslookup-1.py">dnslookup-1.py</A>, with
one extra module being imported. To make life more simple we will use
the <CODE>FrameWork</CODE> module, a nifty piece of code that handles
all the gory Mac details of event loop programming, menubar
installation and all the other code that is the same for every Mac
program in the world. Like most standard modules, FrameWork will run
some sample test code when you invoke it as a main program, so try it
now. It will create a menu bar with an Apple menu with the about box
and a "File" menu with some pythonesque choices (which do nothing
interesting, by the way) and a "Quit" command that works. <p>
<BLOCKQUOTE>
If you have not used <code>FrameWork</code> before you may want to
first take a look at the <A HREF="textedit.html">Pathetic EDitor</A>
example, which builds a minimal text editor using FrameWork and TextEdit.
On the other hand: we don't use many features of FrameWork, so you could
also continue with this document.
</BLOCKQUOTE>
After the imports we get the definitions of resource-IDs in our
resource file, slightly changed from the previous version of our
program. The main program is also
similar to our previous version, with one important exception: we
first check to see whether our resource is available before opening
the resource file. Why is this? Because later, when we will have
converted the script to an applet, our resources will be available in
the applet file and we don't need the separate resource file
anymore. <p>
Next comes the definition of our main class,
<CODE>DNSLookup</CODE>, which inherits
<CODE>FrameWork.Application</CODE>. The Application class handles the
menu bar and the main event loop and event dispatching. In the
<CODE>__init__</CODE> routine we first let the base class initialize
itself, then we create our modeless dialog and finally we jump into
the main loop. The main loop continues until we call <CODE>self._quit</CODE>,
which we will do when the user selects "Quit". When we create
the instance of <CODE>MyDialog</CODE> (which inherits
<CODE>DialogWindow</CODE>, which inherits <CODE>Window</CODE>) we pass
a reference to the application object, this reference is used to tell
Application about our new window. This enables the event loop to keep
track of all windows and dispatch things like update events and mouse
clicks. <p>
The <CODE>makeusermenus()</CODE> method (which is called sometime
during the Application <CODE>__init__</CODE> routine) creates a File
menu with a Quit command (shortcut command-Q), which will callback to
our quit() method. <CODE>Quit()</CODE>, in turn, calls <CODE>_quit</CODE> which
causes the mainloop to terminate at a convenient time. <p>
Application provides a standard about box, but we override this by
providing our own <CODE>do_about()</CODE> method which shows an about
box from a resource as a modal dialog. This piece of code should look
familiar to you from the previous example program. That do_about is
called when the user selects About from the Apple menu is, again,
taken care of by the __init__ routine of Application. <p>
The <CODE>MyDialog</CODE> class is the container for our main
window. Initialization is again done by first calling the base class
<CODE>__init__</CODE> function and finally setting the local variable
"parent." <p>
<CODE>Do_itemhit()</CODE> is called when an item is selected in this
dialog by the user. We are passed the item number (and the original
event structure, which we normally ignore). The code is similar to the
main loop of our previous example program: a switch depending on the
item selected. <CODE>Dnslookup()</CODE> is quite similar to our previous
example. <p>
<H2><IMG SRC="html.icons/mkapplet.gif"><A NAME="applets">Creating applets</A></H2>
Now let us try to turn the python script into an applet, a standalone
application. This will <em>not</em> work if you have the "classic 68k"
Python distribution, only if you have the cfm68k or PPC distribution.
<blockquote>
Actually, "standalone" is probably not the correct term here, since an
applet does still depend on a lot of the python environment: the
PythonCore shared library, the Python Preferences file, the python Lib
folder and any other modules that the main module depends on. It is
possible to get rid of all these dependencies and create true standalone
applications in Python, but this is a bit difficult. See <a href="freezing.html">
Standalone Applications in Python</a> for details. For this
document, by standalone we mean here that
the script has the look-and-feel of an application, including the
ability to have its own document types, be droppable, etc.
</blockquote>
The easiest way to create an applet is to take your source file and
drop it onto "BuildApplet", located in the Python home
folder. This will create an applet with the same name as your python
source with the ".py" stripped. Also, if a resource file with the same
name as your source but with ".rsrc" extension is available the
resources from that file will be copied to your applet too. If there
is no resource file for your script a set of default resources will be
used, and the applet will have the default creator 'Pyt0'. The latter
also happens if you do have a resource file but without the BNDL
combo. <A NAME="no-bundle">Actually</A>, as in the present example.
<p>
If you need slightly more control over the BuildApplet process you can
double-click it, and you will get dialogs for source and
destination of the applet. The rest of the process, including locating
the resource file, remains the same. <p>
Note that though our example application completely bypasses the
normal python user interface this is by no means necessary. Any python
script can be turned into an applet, and all the usual features of the
interpreter still work. <p>
That's all for this example, you may now return to the <A HREF="index.html">
table of contents</A> to pick another topic. <p>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,85 +0,0 @@
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Dlg
import socket
import string
import macresource
#
# Definitions for our resources
ID_MAIN=512
ID_ABOUT=513
ITEM_LOOKUP_ENTRY=1
ITEM_RESULT=2
ITEM_LOOKUP_BUTTON=3
def main():
macresource.need("DLOG", ID_MAIN, "dnslookup-2.rsrc")
DNSLookup()
class DNSLookup(FrameWork.Application):
"Application class for DNS Lookup"
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
self.main_dialog.open(ID_MAIN)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def do_about(self, *args):
f = Dlg.GetNewDialog(ID_ABOUT, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == 1:
return
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for DNSLookup"
def __init__(self, parent):
FrameWork.DialogWindow.__init__(self, parent)
self.parent = parent
def do_itemhit(self, item, event):
if item == ITEM_LOOKUP_BUTTON:
self.dolookup()
def dolookup(self):
"""Get text entered in the lookup entry area. Place result of the
call to dnslookup in the result entry area."""
tp, h, rect = self.dlg.GetDialogItem(ITEM_LOOKUP_ENTRY)
txt = Dlg.GetDialogItemText(h)
tp, h, rect = self.dlg.GetDialogItem(ITEM_RESULT)
Dlg.SetDialogItemText(h, self.dnslookup(txt))
def dnslookup(self, str):
""" Perform DNS lookup on str. If first character of digit is numeric,
assume that str contains an IP address. Otherwise, assume that str
contains a hostname."""
if str == '': str = ' '
if str[0] in string.digits:
try:
value = socket.gethostbyaddr(str)[0]
except:
value = 'Lookup failed'
else:
try:
value = socket.gethostbyname(str)
except:
value = 'Lookup failed'
return value
main()

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

View File

@ -1,115 +0,0 @@
"""imgbrowse - Display pictures using img"""
import FrameWork
import EasyDialogs
from Carbon import Res
from Carbon import Qd
from Carbon import QuickDraw
from Carbon import Win
#ifrom Carbon mport List
import struct
import img
import imgformat
import mac_image
# Where is the picture window?
LEFT=200
TOP=64
MINWIDTH=64
MINHEIGHT=64
MAXWIDTH=320
MAXHEIGHT=320
def main():
print('hello world')
imgbrowse()
class imgbrowse(FrameWork.Application):
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
self.lastwin = None
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.openitem = FrameWork.MenuItem(m, "Open...", "O", self.opendoc)
self.infoitem = FrameWork.MenuItem(m, "Info", "I", self.info)
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def opendoc(self, *args):
pathname = EasyDialogs.AskFileForOpen() # Any file type
if not pathname:
return
bar = EasyDialogs.ProgressBar('Reading and converting...')
try:
rdr = img.reader(imgformat.macrgb16, pathname)
except img.error as arg:
EasyDialogs.Message(repr(arg))
return
w, h = rdr.width, rdr.height
bar.set(10)
data = rdr.read()
del bar
pixmap = mac_image.mkpixmap(w, h, imgformat.macrgb16, data)
self.showimg(w, h, pixmap, data)
def showimg(self, w, h, pixmap, data):
win = imgwindow(self)
win.open(w, h, pixmap, data)
self.lastwin = win
def info(self, *args):
if self.lastwin:
self.lastwin.info()
class imgwindow(FrameWork.Window):
def open(self, width, height, pixmap, data):
self.pixmap = pixmap
self.data = data
self.pictrect = (0, 0, width, height)
bounds = (LEFT, TOP, LEFT+width, TOP+height)
self.wid = Win.NewCWindow(bounds, "Picture", 1, 0, -1, 1, 0)
self.do_postopen()
def do_update(self, *args):
pass
currect = self.fitrect()
print('PICT:', self.pictrect)
print('WIND:', currect)
print('ARGS:', (self.pixmap, self.wid.GetWindowPort().GetPortBitMapForCopyBits(), self.pictrect,
currect, QuickDraw.srcCopy, None))
self.info()
Qd.CopyBits(self.pixmap, self.wid.GetWindowPort().GetPortBitMapForCopyBits(), self.pictrect,
currect, QuickDraw.srcCopy, None)
def fitrect(self):
"""Return self.pictrect scaled to fit in window"""
graf = self.wid.GetWindowPort()
screenrect = graf.GetPortBounds()
picwidth = self.pictrect[2] - self.pictrect[0]
picheight = self.pictrect[3] - self.pictrect[1]
if picwidth > screenrect[2] - screenrect[0]:
factor = float(picwidth) / float(screenrect[2]-screenrect[0])
picwidth = picwidth / factor
picheight = picheight / factor
if picheight > screenrect[3] - screenrect[1]:
factor = float(picheight) / float(screenrect[3]-screenrect[1])
picwidth = picwidth / factor
picheight = picheight / factor
return (screenrect[0], screenrect[1], screenrect[0]+int(picwidth),
screenrect[1]+int(picheight))
def info(self):
graf = self.wid.GetWindowPort()
bits = graf.GetPortBitMapForCopyBits()
mac_image.dumppixmap(bits.pixmap_data)
main()

View File

@ -1,55 +0,0 @@
"""mac_image - Helper routines (hacks) for images"""
import imgformat
from Carbon import Qd
import struct
import MacOS
_fmt_to_mac = {
imgformat.macrgb16 : (16, 16, 3, 5),
}
def mkpixmap(w, h, fmt, data):
"""kludge a pixmap together"""
fmtinfo = _fmt_to_mac[fmt]
rv = struct.pack("lHhhhhhhlllhhhhlll",
id(data)+MacOS.string_id_to_buffer, # HACK HACK!!
w*2 + 0x8000,
0, 0, h, w,
0,
0, 0, # XXXX?
72<<16, 72<<16,
fmtinfo[0], fmtinfo[1],
fmtinfo[2], fmtinfo[3],
0, 0, 0)
## print 'Our pixmap, size %d:'%len(rv)
## dumppixmap(rv)
return Qd.RawBitMap(rv)
def dumppixmap(data):
baseAddr, \
rowBytes, \
t, l, b, r, \
pmVersion, \
packType, packSize, \
hRes, vRes, \
pixelType, pixelSize, \
cmpCount, cmpSize, \
planeBytes, pmTable, pmReserved \
= struct.unpack("lhhhhhhhlllhhhhlll", data)
print('Base: 0x%x'%baseAddr)
print('rowBytes: %d (0x%x)'%(rowBytes&0x3fff, rowBytes))
print('rect: %d, %d, %d, %d'%(t, l, b, r))
print('pmVersion: 0x%x'%pmVersion)
print('packing: %d %d'%(packType, packSize))
print('resolution: %f x %f'%(float(hRes)/0x10000, float(vRes)/0x10000))
print('pixeltype: %d, size %d'%(pixelType, pixelSize))
print('components: %d, size %d'%(cmpCount, cmpSize))
print('planeBytes: %d (0x%x)'%(planeBytes, planeBytes))
print('pmTable: 0x%x'%pmTable)
print('pmReserved: 0x%x'%pmReserved)
for i in range(0, len(data), 16):
for j in range(16):
if i + j < len(data):
print('%02.2x'%ord(data[i+j]), end=' ')
print()

View File

@ -1,156 +0,0 @@
<HTML><HEAD><TITLE>Macintosh Python crash course</TITLE></HEAD>
<BODY>
<H1><IMG SRC="html.icons/python.gif">Macintosh Python crash course</H1>
<HR>
<p>This set of documents provides an introduction to various aspects of
Python programming on the Mac. It is assumed that the reader is
already familiar with Python and, to some extent, with MacOS Toolbox
programming. Other readers may find something interesting here too,
your mileage may vary. </p>
<p>As the previous paragraph reveals to the careful observer these examples
are dated, most of them were writting before OSX and haven't been updated
afterwards. They still show how to use the Carbon wrappers but aren't
necessarily the best way to use the Carbon API's in OSX.</p>
Another set of Macintosh-savvy examples, more aimed at beginners, is
maintained by Joseph Strout, at Python Tidbits in <A
HREF="http://www.strout.net/python/">
http://www.strout.net/python/</A>.
<P>
The <a href="http://www.python.org/doc/lib/Top.html">Python Library
Reference</a> contains a section on <a
href="http://www.python.org/doc/lib/Macintosh-Specific-Services.html">Macintosh-specific
modules</a> that you should also read. Documentation is also available
in PostScript and other forms, see the <a
href="http://www.python.org/doc/">documentation</a> section on the
webserver. <p>
<p>The W widget set by Just van Rossum, does not have complete documentation as
of this writing, but Corran Webster has documented most of it on his
<A HREF="http://www.nevada.edu/~cwebster/Python/">Python Page</A>.</p>
There are also some documentation links, as well as other MacPython-related
pages, in the
<A HREF="http://dmoz.org/Computers/Systems/Macintosh/Development/Scripting/Python/">
Open Directory</A>.
<H2>Table of contents</H2>
<blockquote><B>Note:</B>
Some of these documents were actually written a long time ago and have seen
little maintainance, so use with care. </blockquote>
<UL>
<LI>
<A HREF="example0.html">Using python to create Macintosh applications,
part zero</A> whets your appetite by showing you how to ask the user
for a filename, and how to display a message. It explains about end-of-line
confusion while doing so.
<LI>
<A HREF="example1.html">Using python to create Macintosh applications,
part one</A> explains how to create a simple modal-dialog application
in Python. It also takes a glance at using the toolbox modules Res and
Dlg, and EasyDialogs for simple question-dialogs.
<LI>
<A HREF="example2.html">Using python to create Macintosh applications,
part two</A> turns the previous example program into a more complete
mac application, using a modeless dialog, menus, etc. It also explains
how to create applets, standalone applications written in Python.
<LI>
<A HREF="freezing.html">Freezing Python programs</A> extends on this concept,
and shows you how to create applications that can be used on machines without
a full Python installed. This one is probably best skipped on first contact
with MacPython.
<LI>
<A HREF="textedit.html">Using FrameWork and TextEdit</A> shows you
how to use <code>FrameWork</code> application framework and the
<code>TextEdit</code> toolbox to build a text editor.
<LI>
<A HREF="plugins.html">Creating a C extension module on the Macintosh</A>
is meant for the hardcore programmer, and shows how to create an
extension module in C. It also handles using Modulator to create the
boilerplate for your module, and creating dynamically-loadable modules
on PowerPC Macs. It assumes you use CodeWarrior for you development.
<LI>
<A HREF="mpwextensions.html">Creating C extension modules using MPW</A>
is a companion document, written by Corran Webster, which explains how you
can develop Python extensions using Apple's free MPW compiler environment.
<LI>
<A HREF="applescript.html">Using Open Scripting Architecture from Python</A> explains
how to create a Python module interfacing to a scriptable application,
and how to use that module in your python program.
<LI>
<A HREF="cgi.html">Using python to create CGI scripts</A> is a preliminary
introduction to writing CGI scripts in Python and to writing scriptable applications
in Python.
<LI>
<A HREF="building.html">Building Mac Python from source</A> explains
how to build a PPC or 68K interpreter from a source distribution.
<LI>
<A HREF="embed.html">Embedding Python on the Mac</A> is a minimal example of
how to embed Python in other Mac applications.
</UL>
The Python distribution contains a few more examples, all unexplained:
<UL>
<LI>
<I>PICTbrowse</I> is an application that locates PICT
resources and displays them, it demonstrates some quickdraw and the
resource and list managers. In the same folder you will find the very
similar scripts ICONbrowse and cicnbrowse. oldPICTbrowse is the same program
but form the pre-Appearance era, it uses a dialog with a user item and
creates and manages its own List object.
<LI>
<I>Imgbrowse</I> displays image files in
many different formats (gif, tiff, pbm, etc). It shows how to use the
img modules on the mac.
<LI>
<I>Quicktime</I> has the standard <code>MovieInWindow</code> and
<code>VerySimplePlayer</code> examples, re-coded in Python.
<LI>
<I>Resources</I>, <I>Sound</I> and <I>Speech</I> have some examples
on using the respective managers. In the <i>Mac:Lib</i> folder you
will also find modules that do useful things with the Communications
Toolbox, the Finder interface, etc.
<LI>
<I>Printing</I> has an example on using the Printing module to, you guessed
it, print from Python. The code is somewhat self-documenting. Donated
by Just van Rossum, who also donated the Printing module itself.
</UL>
At some point in the (possibly distant) future, I will add chapters on
how to use bgen to create modules completely automatic and how to make
your Python program scriptable, but that will have to wait. <p>
<HR>
Please let me know if you miss critical information in this
document. I am quite sure that I will never find the time to turn it
into a complete MacPython programmers guide (which would probably be a
400-page book instead of 10 lousy html-files), but it should contain
at least the information that is neither in the standard Python
documentation nor in Inside Mac or other Mac programmers
documentation. <p>
<HR>
<A HREF="http://www.cwi.nl/~jack">Jack Jansen</A>,
<A HREF="mailto:jack@cwi.nl">jack@cwi.nl</A>, 22-Apr-00.
</BODY></HTML>

View File

@ -1,374 +0,0 @@
# A minimal text editor using MLTE. Based on wed.py.
#
# To be done:
# - Functionality: find, etc.
from Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Ctl
from Carbon import Qd
from Carbon import Res
from Carbon import Scrap
import os
from Carbon import MacTextEditor
from Carbon import Mlte
UNDOLABELS = [ # Indexed by MLTECanUndo() value
"Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change",
"Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"]
class MlteWindow(Window):
def open(self, path, name, data):
self.path = path
self.name = name
r = windowbounds(400, 400)
w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
self.wid = w
flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \
MacTextEditor.kTXNWantVScrollBarMask
self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType,
MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding)
self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff)
self.changed = 0
self.do_postopen()
self.do_activate(1, None)
def do_idle(self, event):
self.ted.TXNIdle()
self.ted.TXNAdjustCursor(None)
def do_activate(self, onoff, evt):
if onoff:
## self.ted.TXNActivate(self.frameid, 0)
self.ted.TXNFocus(1)
self.parent.active = self
else:
self.ted.TXNFocus(0)
self.parent.active = None
self.parent.updatemenubar()
def do_update(self, wid, event):
self.ted.TXNDraw(None)
def do_postresize(self, width, height, window):
self.ted.TXNResizeFrame(width, height, self.frameid)
def do_contentclick(self, local, modifiers, evt):
self.ted.TXNClick(evt)
self.parent.updatemenubar()
def do_char(self, ch, event):
self.ted.TXNKeyDown(event)
self.parent.updatemenubar()
def close(self):
if self.changed:
save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
if save > 0:
self.menu_save()
elif save < 0:
return
if self.parent.active == self:
self.parent.active = None
self.ted.TXNDeleteObject()
del self.ted
## del self.tedtexthandle
self.do_postclose()
def menu_save(self):
if not self.path:
self.menu_save_as()
return # Will call us recursively
dhandle = self.ted.TXNGetData(0, 0x7fffffff)
data = dhandle.data
fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
fp.write(data)
if data[-1] <> '\r': fp.write('\r')
fp.close()
self.changed = 0
def menu_save_as(self):
path = EasyDialogs.AskFileForSave(message='Save as:')
if not path: return
self.path = path
self.name = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.name)
self.menu_save()
def menu_cut(self):
## self.ted.WESelView()
self.ted.TXNCut()
### Mlte.ConvertToPublicScrap()
## Scrap.ZeroScrap()
## self.ted.WECut()
## self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_copy(self):
## Scrap.ZeroScrap()
self.ted.TXNCopy()
### Mlte.ConvertToPublicScrap()
## self.updatescrollbars()
self.parent.updatemenubar()
def menu_paste(self):
### Mlte.ConvertFromPublicScrap()
self.ted.TXNPaste()
## self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_clear(self):
## self.ted.WESelView()
self.ted.TXNClear()
## self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_undo(self):
self.ted.TXNUndo()
## self.updatescrollbars()
self.parent.updatemenubar()
def menu_redo(self):
self.ted.TXNRedo()
## self.updatescrollbars()
self.parent.updatemenubar()
def have_selection(self):
start, stop = self.ted.TXNGetSelection()
return start < stop
def can_paste(self):
return Mlte.TXNIsScrapPastable()
def can_undo(self):
can, which = self.ted.TXNCanUndo()
if not can:
return None
if which >= len(UNDOLABELS):
# Unspecified undo
return "Undo"
which = UNDOLABELS[which]
return "Undo "+which
def can_redo(self):
can, which = self.ted.TXNCanRedo()
if not can:
return None
if which >= len(UNDOLABELS):
# Unspecified undo
return "Redo"
which = UNDOLABELS[which]
return "Redo "+which
class Mlted(Application):
def __init__(self):
Application.__init__(self)
self.num = 0
self.active = None
self.updatemenubar()
def makeusermenus(self):
self.filemenu = m = Menu(self.menubar, "File")
self.newitem = MenuItem(m, "New window", "N", self.open)
self.openitem = MenuItem(m, "Open...", "O", self.openfile)
self.closeitem = MenuItem(m, "Close", "W", self.closewin)
m.addseparator()
self.saveitem = MenuItem(m, "Save", "S", self.save)
self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
m.addseparator()
self.quititem = MenuItem(m, "Quit", "Q", self.quit)
self.editmenu = m = Menu(self.menubar, "Edit")
self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
self.redoitem = MenuItem(m, "Redo", None, self.redo)
m.addseparator()
self.cutitem = MenuItem(m, "Cut", "X", self.cut)
self.copyitem = MenuItem(m, "Copy", "C", self.copy)
self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
self.clearitem = MenuItem(m, "Clear", "", self.clear)
# Groups of items enabled together:
self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
self.windowgroup_on = -1
self.focusgroup_on = -1
self.pastegroup_on = -1
self.undo_label = "never"
self.redo_label = "never"
def updatemenubar(self):
changed = 0
on = (self.active <> None)
if on <> self.windowgroup_on:
for m in self.windowgroup:
m.enable(on)
self.windowgroup_on = on
changed = 1
if on:
# only if we have an edit menu
on = self.active.have_selection()
if on <> self.focusgroup_on:
for m in self.focusgroup:
m.enable(on)
self.focusgroup_on = on
changed = 1
on = self.active.can_paste()
if on <> self.pastegroup_on:
self.pasteitem.enable(on)
self.pastegroup_on = on
changed = 1
on = self.active.can_undo()
if on <> self.undo_label:
if on:
self.undoitem.enable(1)
self.undoitem.settext(on)
self.undo_label = on
else:
self.undoitem.settext("Nothing to undo")
self.undoitem.enable(0)
changed = 1
on = self.active.can_redo()
if on <> self.redo_label:
if on:
self.redoitem.enable(1)
self.redoitem.settext(on)
self.redo_label = on
else:
self.redoitem.settext("Nothing to redo")
self.redoitem.enable(0)
changed = 1
if changed:
DrawMenuBar()
#
# Apple menu
#
def do_about(self, id, item, window, event):
EasyDialogs.Message("A simple single-font text editor based on MacTextEditor")
#
# File menu
#
def open(self, *args):
self._open(0)
def openfile(self, *args):
self._open(1)
def _open(self, askfile):
if askfile:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
name = os.path.split(path)[-1]
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
data = fp.read()
fp.close()
except IOError as arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
else:
path = None
name = "Untitled %d"%self.num
data = ''
w = MlteWindow(self)
w.open(path, name, data)
self.num = self.num + 1
def closewin(self, *args):
if self.active:
self.active.close()
else:
EasyDialogs.Message("No active window?")
def save(self, *args):
if self.active:
self.active.menu_save()
else:
EasyDialogs.Message("No active window?")
def saveas(self, *args):
if self.active:
self.active.menu_save_as()
else:
EasyDialogs.Message("No active window?")
def quit(self, *args):
for w in self._windows.values():
w.close()
if self._windows:
return
self._quit()
#
# Edit menu
#
def undo(self, *args):
if self.active:
self.active.menu_undo()
else:
EasyDialogs.Message("No active window?")
def redo(self, *args):
if self.active:
self.active.menu_redo()
else:
EasyDialogs.Message("No active window?")
def cut(self, *args):
if self.active:
self.active.menu_cut()
else:
EasyDialogs.Message("No active window?")
def copy(self, *args):
if self.active:
self.active.menu_copy()
else:
EasyDialogs.Message("No active window?")
def paste(self, *args):
if self.active:
self.active.menu_paste()
else:
EasyDialogs.Message("No active window?")
def clear(self, *args):
if self.active:
self.active.menu_clear()
else:
EasyDialogs.Message("No active window?")
#
# Other stuff
#
def idle(self, event):
if self.active:
self.active.do_idle(event)
else:
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def main():
Mlte.TXNInitTextension(0)
try:
App = Mlted()
App.mainloop()
finally:
Mlte.TXNTerminateTextension()
if __name__ == '__main__':
main()

View File

@ -1,70 +0,0 @@
"""MovieInWindow converted to python
Jack Jansen, CWI, December 1995
"""
from Carbon import Qt
from Carbon import QuickTime
from Carbon import Qd
from Carbon import QuickDraw
from Carbon import Evt
from Carbon import Events
from Carbon import Win
from Carbon import Windows
from Carbon import File
import EasyDialogs
import sys
import os
def main():
# skip the toolbox initializations, already done
# XXXX Should use gestalt here to check for quicktime version
Qt.EnterMovies()
# Get the movie file
if len(sys.argv) > 1:
filename = sys.argv[1]
else:
filename = EasyDialogs.AskFileForOpen() # Was: QuickTime.MovieFileType
if not filename:
sys.exit(0)
# Open the window
bounds = (175, 75, 175+160, 75+120)
theWindow = Win.NewCWindow(bounds, os.path.split(filename)[1], 1, 0, -1, 0, 0)
Qd.SetPort(theWindow)
# XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil)
playMovieInWindow(theWindow, filename, theWindow.GetWindowPort().GetPortBounds())
def playMovieInWindow(theWindow, theFile, movieBox):
"""Play a movie in a window"""
# XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil);
# Get the movie
theMovie = loadMovie(theFile)
# Set where we want it
theMovie.SetMovieBox(movieBox)
# Start at the beginning
theMovie.GoToBeginningOfMovie()
# Give a little time to preroll
theMovie.MoviesTask(0)
# Start playing
theMovie.StartMovie()
while not theMovie.IsMovieDone() and not Evt.Button():
theMovie.MoviesTask(0)
def loadMovie(theFile):
"""Load a movie given an fsspec. Return the movie object"""
movieResRef = Qt.OpenMovieFile(theFile, 1)
movie, d1, d2 = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
return movie
if __name__ == '__main__':
main()

View File

@ -1,92 +0,0 @@
"""VerySimplePlayer converted to python
Jack Jansen, CWI, December 1995
"""
from Carbon import Qt
from Carbon import QuickTime
from Carbon import Qd
from Carbon import QuickDraw
from Carbon import Evt
from Carbon import Events
from Carbon import Win
from Carbon import Windows
from Carbon import File
import EasyDialogs
import sys
# XXXX maxbounds = (40, 40, 1000, 1000)
def main():
print('hello world') # XXXX
# skip the toolbox initializations, already done
# XXXX Should use gestalt here to check for quicktime version
Qt.EnterMovies()
# Get the movie file
fss = EasyDialogs.AskFileForOpen(wanted=File.FSSpec) # Was: QuickTime.MovieFileType
if not fss:
sys.exit(0)
# Open the window
bounds = (175, 75, 175+160, 75+120)
theWindow = Win.NewCWindow(bounds, fss.as_tuple()[2], 0, 0, -1, 1, 0)
# XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil)
Qd.SetPort(theWindow)
# Get the movie
theMovie = loadMovie(fss)
# Relocate to (0, 0)
bounds = theMovie.GetMovieBox()
bounds = 0, 0, bounds[2]-bounds[0], bounds[3]-bounds[1]
theMovie.SetMovieBox(bounds)
# Create a controller
theController = theMovie.NewMovieController(bounds, QuickTime.mcTopLeftMovie)
# Get movie size and update window parameters
rv, bounds = theController.MCGetControllerBoundsRect()
theWindow.SizeWindow(bounds[2], bounds[3], 0) # XXXX or [3] [2]?
Qt.AlignWindow(theWindow, 0)
theWindow.ShowWindow()
# XXXX MCDoAction(theController, mcActionSetGrowBoxBounds, &maxBounds)
theController.MCDoAction(QuickTime.mcActionSetKeysEnabled, '1')
# XXXX MCSetActionFilterWithRefCon(theController, movieControllerEventFilter, (long)theWindow)
done = 0
while not done:
gotone, evt = Evt.WaitNextEvent(0xffff, 0)
(what, message, when, where, modifiers) = evt
## print what, message, when, where, modifiers # XXXX
if theController.MCIsPlayerEvent(evt):
continue
if what == Events.mouseDown:
part, whichWindow = Win.FindWindow(where)
if part == Windows.inGoAway:
done = whichWindow.TrackGoAway(where)
elif part == Windows.inDrag:
Qt.DragAlignedWindow(whichWindow, where, (0, 0, 4000, 4000))
elif what == Events.updateEvt:
whichWindow = Win.WhichWindow(message)
if not whichWindow:
# Probably the console window. Print something, hope it helps.
print('update')
else:
Qd.SetPort(whichWindow)
whichWindow.BeginUpdate()
Qd.EraseRect(whichWindow.GetWindowPort().GetPortBounds())
whichWindow.EndUpdate()
def loadMovie(theFile):
"""Load a movie given an fsspec. Return the movie object"""
movieResRef = Qt.OpenMovieFile(theFile, 1)
movie, d1, d2 = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
return movie
if __name__ == '__main__':
main()

View File

@ -1,63 +0,0 @@
from Carbon.Res import *
from Carbon.Resources import *
import MacOS
READ = 1
WRITE = 2
smAllScripts = -3
def raw_input(prompt):
import sys
sys.stdout.write(prompt)
sys.stdout.flush()
return sys.stdin.readline()
def copyres(src, dst):
"""Copy resource from src file to dst file."""
cur = CurResFile()
ctor, type = MacOS.GetCreatorAndType(src)
input = FSpOpenResFile(src, READ)
try:
FSpCreateResFile(dst, ctor, type, smAllScripts)
except:
raw_input("%s already exists... CR to write anyway! " % dst)
output = FSpOpenResFile(dst, WRITE)
UseResFile(input)
ntypes = Count1Types()
for itype in range(1, 1+ntypes):
type = Get1IndType(itype)
nresources = Count1Resources(type)
for ires in range(1, 1+nresources):
res = Get1IndResource(type, ires)
res.LoadResource()
id, type, name = res.GetResInfo()
size = res.SizeResource()
attrs = res.GetResAttrs()
print(id, type, name, size, hex(attrs))
res.DetachResource()
UseResFile(output)
try:
res2 = Get1Resource(type, id)
except (RuntimeError, Res.Error) as msg:
res2 = None
if res2:
print("Duplicate type+id, not copied")
print (res2.size, res2.data)
print(res2.GetResInfo())
if res2.HomeResFile() == output:
'OK'
elif res2.HomeResFile() == input:
'BAD!'
else:
print('Home:', res2.HomeResFile())
else:
res.AddResource(type, id, name)
#res.SetResAttrs(attrs)
res.WriteResource()
UseResFile(input)
UseResFile(cur)
CloseResFile(output)
CloseResFile(input)
copyres('::python.¹.rsrc', '::foo.rsrc')

View File

@ -1,60 +0,0 @@
# List all resources
from Carbon import Res
from Carbon.Resources import *
def list1resources():
ntypes = Res.Count1Types()
for itype in range(1, 1+ntypes):
type = Res.Get1IndType(itype)
print("Type:", repr(type))
nresources = Res.Count1Resources(type)
for i in range(1, 1 + nresources):
Res.SetResLoad(0)
res = Res.Get1IndResource(type, i)
Res.SetResLoad(1)
info(res)
def listresources():
ntypes = Res.CountTypes()
for itype in range(1, 1+ntypes):
type = Res.GetIndType(itype)
print("Type:", repr(type))
nresources = Res.CountResources(type)
for i in range(1, 1 + nresources):
Res.SetResLoad(0)
res = Res.GetIndResource(type, i)
Res.SetResLoad(1)
info(res)
def info(res):
print(res.GetResInfo(), res.SizeResource(), decodeattrs(res.GetResAttrs()))
attrnames = {
resChanged: 'Changed',
resPreload: 'Preload',
resProtected: 'Protected',
resLocked: 'Locked',
resPurgeable: 'Purgeable',
resSysHeap: 'SysHeap',
}
def decodeattrs(attrs):
names = []
for bit in range(16):
mask = 1<<bit
if attrs & mask:
if attrnames.has_key(mask):
names.append(attrnames[mask])
else:
names.append(hex(mask))
return names
def test():
print("=== Local resourcess ===")
list1resources()
print("=== All resources ===")
listresources()
if __name__ == '__main__':
test()

View File

@ -1,202 +0,0 @@
"""Translate text strings to Morse code"""
FRAMERATE = 22050
SAMPWIDTH = 2
BASEFREQ = 441
OCTAVE = 2
DOT = 30
DAH = 80
morsetab = {
'a': '.-',
'b': '-...',
'c': '-.-.',
'd': '-..',
'e': '.',
'f': '..-.',
'g': '--.',
'h': '....',
'i': '..',
'j': '.---',
'k': '-.-',
'l': '.-..',
'm': '--',
'n': '-.',
'o': '---',
'p': '.--.',
'q': '--.-',
'r': '.-.',
's': '...',
't': '-',
'u': '..-',
'v': '...-',
'w': '.--',
'x': '-..-',
'y': '-.--',
'z': '--..',
'0': '-----',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
',': '--..--',
'.': '.-.-.-',
'?': '..--..',
';': '-.-.-.',
':': '---...',
"'": '.----.',
'-': '-....-',
'/': '-..-.',
'(': '-.--.-',
')': '-.--.-', # XXX same as code for '(' ???
'_': '..--.-',
' ': ' '
}
def morsecode(s):
m = ''
for c in s:
c = c.lower()
if c in morsetab:
c = morsetab[c] + ' '
else:
c = '? '
m = m + c
return m
class BaseMorse:
"base class for morse transmissions"
def __init__(self):
"constructor"
self.dots = DOT
self.dahs = DAH
def noise(self, duration):
"beep for given duration"
pass
def pause(self, duration):
"pause for given duration"
pass
def dot(self):
"short beep"
self.noise(self.dots)
def dah(self):
"long beep"
self.noise(self.dahs)
def pdot(self):
"pause as long as a dot"
self.pause(self.dots)
def pdah(self):
"pause as long as a dah"
self.pause(self.dahs)
def sendmorse(self, s):
for c in s:
if c == '.':
self.dot()
elif c == '-':
self.dah()
else:
self.pdah()
self.pdot()
def sendascii(self, s):
self.sendmorse(morsecode(s))
def send(self, s):
self.sendascii(s)
import Audio_mac
class MyAudio(Audio_mac.Play_Audio_mac):
def _callback(self, *args):
if hasattr(self, 'usercallback'):
self.usercallback()
Audio_mac.Play_Audio_mac._callback(self, args)
class MacMorse(BaseMorse):
"Mac specific class to play Morse code"
def __init__(self):
BaseMorse.__init__(self)
self.dev = MyAudio()
self.dev.setoutrate(FRAMERATE)
self.dev.setsampwidth(SAMPWIDTH)
self.dev.setnchannels(1)
self.dev.usercallback = self.usercallback
sinewave = ''
n = int(FRAMERATE / BASEFREQ)
octave = OCTAVE
from math import sin, pi
for i in range(n):
val = int(sin(2 * pi * i * octave / n) * 0x7fff)
sample = chr((val >> 8) & 255) + chr(val & 255)
sinewave = sinewave + sample[:SAMPWIDTH]
self.sinewave = sinewave
self.silence = '\0' * (n*SAMPWIDTH)
self.morsequeue = ''
def __del__(self):
self.close()
def close(self):
self.dev = None
def pause(self, duration):
self.dev.writeframes(self.silence * duration)
def noise(self, duration):
self.dev.writeframes(self.sinewave * duration)
def sendmorse(self, s):
self.morsequeue = self.morsequeue + s
self.dev.usercallback()
self.dev.usercallback()
self.dev.usercallback()
def usercallback(self):
if self.morsequeue:
c, self.morsequeue = self.morsequeue[0], self.morsequeue[1:]
if c == '.':
self.dot()
elif c == '-':
self.dah()
else:
self.pdah()
self.pdot()
def raw_input(prompt):
import sys
sys.stdout.write(prompt)
sys.stdout.flush()
return sys.stdin.readline()
def test():
m = MacMorse()
while 1:
try:
line = raw_input('Morse line: ')
except (EOFError, KeyboardInterrupt):
break
m.send(line)
while m.morsequeue:
pass
if __name__ == '__main__':
test()

View File

@ -1,45 +0,0 @@
from Carbon.Sound import *
from Carbon import Snd
import aifc, audioop
fn = 'f:just samples:2ndbeat.aif'
af = aifc.open(fn, 'r')
print(af.getparams())
print('nframes =', af.getnframes())
print('nchannels =', af.getnchannels())
print('framerate =', af.getframerate())
nframes = min(af.getnframes(), 100000)
frames = af.readframes(nframes)
print('len(frames) =', len(frames))
print(repr(frames[:100]))
frames = audioop.add(frames, '\x80'*len(frames), 1)
print(repr(frames[:100]))
import struct
header1 = struct.pack('llhhllbbl',
0,
af.getnchannels(),
af.getframerate(),0,
0,
0,
0xFF,
60,
nframes)
print(repr(header1))
header2 = struct.pack('llhlll', 0, 0, 0, 0, 0, 0)
header3 = struct.pack('hhlll',
af.getsampwidth()*8,
0,
0,
0,
0)
print(repr(header3))
header = header1 + header2 + header3
buffer = header + frames
chan = Snd.SndNewChannel(5,0x00C0)
Snd.SndDoCommand(chan, (bufferCmd, 0, buffer), 0)

View File

@ -1,150 +0,0 @@
<HTML><HEAD><TITLE>Using FrameWork and TextEdit</TITLE></HEAD>
<BODY>
<H1>Using FrameWork and TextEdit</H1>
<HR>
In this document we use the <CODE>FrameWork</CODE> and <CODE>TextEdit</CODE>
modules to create a simple text editor. The functionality
of the editor is very basic: you can open multiple files, type text and use
cut/copy/paste. The main intention is to explain the use of FrameWork, really. <p>
<H2>FrameWork</H2>
The FrameWork module provides you with a skeleton application. It declares a
number of classes suitable for subclassing in your application, thereby
releaving you of the burden of doing all event handling, etc. yourself. For a
real understanding you will have to browse the source. Here is a short overview
of the classes and what functionality they provide.
<dl>
<dt> <CODE>Application</CODE>
<dd>
This is the toplevel class you will override. It maintains the menu bar and contains
the main event handling code. Normal use is to override the <code>__init__</code> routine
to do your own initializations and override <code>makeusermenus</code> to create your menus
(your menu callback routines may be here too, but this is by no means necessary).
The event handling code can be overridden at various levels, from very low-level (the
<code>dispatch</code> method) to intermedeate level (<code>do_keyDown</code>, for instance)
to high-level (<code>do_key</code>). The application class knows about the <code>Window</code>
objects you create, and will forward events to the appropriate window (So, normally you
would have a <code>do_key</code> method in your window object, not your application object).
<dt> <CODE>MenuBar</CODE>, <CODE>Menu</CODE> and <CODE>MenuItem</CODE>
<dd>
These classes (and a few friends like <CODE>SubMenu</CODE>) handle your menus. You would not
normally override them but use them as-is. The idiom for creating menus is a bit strange,
see the test code at the bottom of FrameWork for sample use. The apple menu is handled for you
by <CODE>MenuBar</CODE> and <CODE>Application</CODE>.
<dt> <CODE>Window</CODE>
<dd>
The basic window. Again, a class that you normally subclass in your application, possibly
multiple times if you have different types of windows. The init call instantiates the data
structure but actually opening the window is delayed until you call <code>open</code>. Your
open method should call <code>do_postopen</code> to let the base class handle linking in to
the application object. Similarly with <code>close</code> and <code>do_postclose</code>. The
rest of the code is mainly event-oriented: you override <code>do_postresize</code>,
<code>do_contentclick</code>, <code>do_update</code>, <code>do_activate</code>
and <code>do_key</code> to "do your thing". When these methods are called the relevant environment
has been setup (like <code>BeginDrawing</code> has been called for updates, etc).
<dt> <CODE>windowbounds</CODE>
<dd>
Not a class but a function: you pass it a width and height and it will return you a rectangle
you can use to create your window. It will take care of staggering windows and it will try
to fit the window on the screen (but the resulting rect will <em>always</em> have the size you
specify).
<dt> <CODE>ControlsWindow</CODE>
<dd>
A subclass of Window which automatically handles drawing and clicking for controls. You override
the same methods as for Window (if you need to: control-related things are done automatically) and
<code>do_controlhit</code>.
<dt> <CODE>ScrolledWindow</CODE>
<dd>
A subclass of ControlsWindow, a window with optional scrollbars. If you override <code>do_activate</code>
or <code>do_postresize</code> you must call the ScrolledWindow methods at the end of your override.
You call <code>scrollbars</code> to enable/disable scrollbars and <code>updatescrollbars</code> to
update them. You provide <code>getscrollbarvalues</code> to return the current x/y values (a helper
method <code>scalebarvalues</code> is available) and <code>scrollbarcallback</code> to update your
display after the user has used the scrollbars.
<dt> <CODE>DialogWindow</CODE>
<dd>
A modeless dialog window initialized from a DLOG resource. See the
<A HREF="example2.html">second Interslip example</A> for its useage.
</dl>
<H2>A sample text editor</H2>
Let us have a look at <A HREF="textedit/ped.py">ped.py</A> (in the Demo:textedit folder), the Pathetic
EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks
as if you can resize the window but it does not work. Still, it serves as an example.
Ped creates two classes, <code>TEWindow</code> and <code>Ped</code>. Let us start with the latter one,
which is a subclass of <code>FrameWork.Application</code> and our main application. The init function
has little to do aside from the standard init: it remembers a window sequence number (for untitled windows),
and sets things up for menu disable to work. Remember, the <code>makeusermenus</code> is called
automatically. <p>
<code>Makeusermenus</code> creates the <code>File</code> and <code>Edit</code> menus. It also initializes
a couple of lists that are used later to correctly enable and disable menu items (and complete menus) depending
on whether a window is open, text is selected, etc. The callback functions for the menu items are
all methods of this class. <p>
<code>Updatemenubar</code> handles greying out (and re-enabling) of menu items depending on whether there
is a current window and its state. <p>
The rest of the methods are all callbacks and simple to understand. They check whether there is an active
window (and complain loudly if there is none: the corresponding menu entry should have been disabled
in that case!) and call the appropriate window method. Only the <code>_open</code> method (the common code
for <code>Open</code> and <code>New</code>) deserves some mention. It instantiates a <code>TEWindow</code>
object and opens it with the title, filename and contents of the file to edit. Note that FrameWork takes
care of remembering the window object. A minor note on opening the file in binary mode: this is because
TextEdit expects MacOS style carriage-return terminated lines, not python/unix/C style newline-terminated
lines. <p>
Oh yes: the <code>quit</code> callback does a little magic too. It closes all windows, and only if this
succeeds it actually quits. This gives the user a chance to cancel the operation if some files are unsaved.
<p>
Lastly, there is the <code>idle</code> method, called by the Application base class when no event
is available. It is forwarded to the active window, so it can blink the text caret. <p>
The <code>TEWindow</code> object handles a single window. Due to this structuring it is absolutely no
problem to have multiple windows open at the same time (although a real application should exercise care when
two windows refer to the same document). TEWindow uses the standard init code inherited from
<code>ScrolledWindow</code>, and sets itself up at the time of the <code>open</code> call. It obtains screen
coordinates, opens the window, creates rectangles for TextEdit to work in (the magical number <code>15</code>
here is the size of a normal scroll bar: unfortunately there is no symbolic constant for it),
creates the TextEdit object and initializes it with our data. Finally, the scroll bars are created (the
initial values will be obtained automatically through <code>getscrollbarvalues</code>) and we activate
ourselves (this is unfortunately not done automatically by the MacOS event handling code). <p>
<code>Do_idle</code> simply calls the TextEdit routine that blinks the cursor. <code>Getscrollbarvalues</code>
returns the current X and Y scrollbar values, scaled to <code>0..32767</code>. For X we return <code>None</code>,
which means "no scrollbar, please", for Y we use the scaler provided by <code>ScrolledWindow</code>. <p>
<code>Scrollbar_callback</code> is called when the user uses the scrollbar. It is passed a string <code>'x'</code>
or <code>'y'</code>, one of <code>'set', '-', '--', '+', '++'</code> and (for <code>set</code>) an absolute
value. Note that the sign of the value passed to <code>TEPinScroll</code> is counter-intuitive. <p>
<code>do_activate</code> (de)activates the scrollbars and calls the relevant TextEdit routine. Moreover, it
tells the application object if we are now the active window, and updates the menubar. The next few methods
are update and menu callbacks, and pretty straightforward. Note that <code>do_close</code> can
return without closing the window (if the document is changed and the users cancels out of the operation).
Also note the "magic" in <code>menu_save_as</code>
that set the correct window title. <p>
Things get moderately interesting again at the cut/copy/paste handling, since the TextEdit scrap is
separate from the desktop scrap. For that reason there are various calls to routines that move the scrap
back and forth. <code>Have_selection</code> is called by the menubar update code to determine whether cut and
copy should be enabled. <p>
Understanding the main program is left as an exercise to the reader. <p>
<hr>
That's all for this example, you could now continue with the <A HREF="waste.html">next example</A>, where we use WASTE, a more-or-less
TextEdit compatible library with more functionality, to rebuild our editor. Or you can
return to the <A HREF="index.html">table of contents</A> to pick another topic. <p>

View File

@ -1,359 +0,0 @@
# A minimal text editor.
#
# To be done:
# - Update viewrect after resize
# - Handle horizontal scrollbar correctly
# - Functionality: find, etc.
from Carbon.Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Qd
from Carbon import TE
from Carbon import Scrap
import os
import macfs
class TEWindow(ScrolledWindow):
def open(self, path, name, data):
self.path = path
self.name = name
r = windowbounds(400, 400)
w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
self.wid = w
x0, y0, x1, y1 = self.wid.GetWindowPort().GetPortBounds()
x0 = x0 + 4
y0 = y0 + 4
x1 = x1 - 20
y1 = y1 - 20
vr = dr = x0, y0, x1, y1
##vr = 4, 0, r[2]-r[0]-15, r[3]-r[1]-15
##dr = (0, 0, vr[2], 0)
Qd.SetPort(w)
Qd.TextFont(4)
Qd.TextSize(9)
self.ted = TE.TENew(dr, vr)
self.ted.TEAutoView(1)
self.ted.TESetText(data)
w.DrawGrowIcon()
self.scrollbars()
self.changed = 0
self.do_postopen()
self.do_activate(1, None)
def do_idle(self):
self.ted.TEIdle()
def getscrollbarvalues(self):
dr = self.ted.destRect
vr = self.ted.viewRect
height = self.ted.nLines * self.ted.lineHeight
vx = self.scalebarvalue(dr[0], dr[2]-dr[0], vr[0], vr[2])
vy = self.scalebarvalue(dr[1], dr[1]+height, vr[1], vr[3])
print(dr, vr, height, vx, vy)
return None, vy
def scrollbar_callback(self, which, what, value):
if which == 'y':
if what == 'set':
height = self.ted.nLines * self.ted.lineHeight
cur = self.getscrollbarvalues()[1]
delta = (cur-value)*height/32767
if what == '-':
delta = self.ted.lineHeight
elif what == '--':
delta = (self.ted.viewRect[3]-self.ted.lineHeight)
if delta <= 0:
delta = self.ted.lineHeight
elif what == '+':
delta = -self.ted.lineHeight
elif what == '++':
delta = -(self.ted.viewRect[3]-self.ted.lineHeight)
if delta >= 0:
delta = -self.ted.lineHeight
self.ted.TEPinScroll(0, delta)
print('SCROLL Y', delta)
else:
pass # No horizontal scrolling
def do_activate(self, onoff, evt):
print("ACTIVATE", onoff)
ScrolledWindow.do_activate(self, onoff, evt)
if onoff:
self.ted.TEActivate()
self.parent.active = self
self.parent.updatemenubar()
else:
self.ted.TEDeactivate()
def do_update(self, wid, event):
Qd.EraseRect(wid.GetWindowPort().GetPortBounds())
self.ted.TEUpdate(wid.GetWindowPort().GetPortBounds())
self.updatescrollbars()
def do_contentclick(self, local, modifiers, evt):
shifted = (modifiers & 0x200)
self.ted.TEClick(local, shifted)
self.updatescrollbars()
self.parent.updatemenubar()
def do_char(self, ch, event):
self.ted.TESelView()
self.ted.TEKey(ord(ch))
self.changed = 1
self.updatescrollbars()
self.parent.updatemenubar()
def close(self):
if self.changed:
save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
if save > 0:
self.menu_save()
elif save < 0:
return
if self.parent.active == self:
self.parent.active = None
self.parent.updatemenubar()
del self.ted
self.do_postclose()
def menu_save(self):
if not self.path:
self.menu_save_as()
return # Will call us recursively
print('Saving to ', self.path)
dhandle = self.ted.TEGetText()
data = dhandle.data
fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
fp.write(data)
if data[-1] <> '\r': fp.write('\r')
fp.close()
self.changed = 0
def menu_save_as(self):
path = EasyDialogs.AskFileForSave(message='Save as:')
if not path: return
self.path = path
self.name = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.name)
self.menu_save()
def menu_cut(self):
self.ted.TESelView()
self.ted.TECut()
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
TE.TEToScrap()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_copy(self):
self.ted.TECopy()
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
TE.TEToScrap()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_paste(self):
TE.TEFromScrap()
self.ted.TESelView()
self.ted.TEPaste()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_clear(self):
self.ted.TESelView()
self.ted.TEDelete()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def have_selection(self):
return (self.ted.selStart < self.ted.selEnd)
class Ped(Application):
def __init__(self):
Application.__init__(self)
self.num = 0
self.active = None
self.updatemenubar()
def makeusermenus(self):
self.filemenu = m = Menu(self.menubar, "File")
self.newitem = MenuItem(m, "New window", "N", self.open)
self.openitem = MenuItem(m, "Open...", "O", self.openfile)
self.closeitem = MenuItem(m, "Close", "W", self.closewin)
m.addseparator()
self.saveitem = MenuItem(m, "Save", "S", self.save)
self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
m.addseparator()
self.quititem = MenuItem(m, "Quit", "Q", self.quit)
self.editmenu = m = Menu(self.menubar, "Edit")
self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
self.cutitem = MenuItem(m, "Cut", "X", self.cut)
self.copyitem = MenuItem(m, "Copy", "C", self.copy)
self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
self.clearitem = MenuItem(m, "Clear", "", self.clear)
# Not yet implemented:
self.undoitem.enable(0)
# Groups of items enabled together:
self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
self.windowgroup_on = -1
self.focusgroup_on = -1
self.pastegroup_on = -1
def updatemenubar(self):
changed = 0
on = (self.active <> None)
if on <> self.windowgroup_on:
for m in self.windowgroup:
m.enable(on)
self.windowgroup_on = on
changed = 1
if on:
# only if we have an edit menu
on = self.active.have_selection()
if on <> self.focusgroup_on:
for m in self.focusgroup:
m.enable(on)
self.focusgroup_on = on
changed = 1
if hasattr(Scrap, 'InfoScrap'):
on = (Scrap.InfoScrap()[0] <> 0)
else:
flavors = Scrap.GetCurrentScrap().GetScrapFlavorInfoList()
for tp, info in flavors:
if tp == 'TEXT':
on = 1
break
else:
on = 0
if on <> self.pastegroup_on:
self.pasteitem.enable(on)
self.pastegroup_on = on
changed = 1
if changed:
DrawMenuBar()
#
# Apple menu
#
def do_about(self, id, item, window, event):
EasyDialogs.Message("A simple single-font text editor")
#
# File menu
#
def open(self, *args):
self._open(0)
def openfile(self, *args):
self._open(1)
def _open(self, askfile):
if askfile:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
name = os.path.split(path)[-1]
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
data = fp.read()
fp.close()
except IOError as arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
else:
path = None
name = "Untitled %d"%self.num
data = ''
w = TEWindow(self)
w.open(path, name, data)
self.num = self.num + 1
def closewin(self, *args):
if self.active:
self.active.close()
else:
EasyDialogs.Message("No active window?")
def save(self, *args):
if self.active:
self.active.menu_save()
else:
EasyDialogs.Message("No active window?")
def saveas(self, *args):
if self.active:
self.active.menu_save_as()
else:
EasyDialogs.Message("No active window?")
def quit(self, *args):
for w in self._windows.values():
w.close()
if self._windows:
return
self._quit()
#
# Edit menu
#
def undo(self, *args):
pass
def cut(self, *args):
if self.active:
self.active.menu_cut()
else:
EasyDialogs.Message("No active window?")
def copy(self, *args):
if self.active:
self.active.menu_copy()
else:
EasyDialogs.Message("No active window?")
def paste(self, *args):
if self.active:
self.active.menu_paste()
else:
EasyDialogs.Message("No active window?")
def clear(self, *args):
if self.active:
self.active.menu_clear()
else:
EasyDialogs.Message("No active window?")
#
# Other stuff
#
def idle(self, *args):
if self.active:
self.active.do_idle()
else:
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def main():
App = Ped()
App.mainloop()
if __name__ == '__main__':
main()

View File

@ -36,7 +36,7 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>IDLE</string> <string>IDLE</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>%VERSION%, © 001-2006 Python Software Foundation</string> <string>2.6.0, © 001-2006 Python Software Foundation</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>IDLE.icns</string> <string>IDLE.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -48,8 +48,10 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>%VERSION%</string> <string>2.6.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>%VERSION%</string> <string>2.6.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1,23 @@
#!/Library/Frameworks/Python.framework/Versions/3.0/Resources/Python.app/Contents/MacOS/Python
import sys, os
execdir = os.path.dirname(sys.argv[0])
executable = os.path.join(execdir, "Python")
resdir = os.path.join(os.path.dirname(execdir), "Resources")
libdir = os.path.join(os.path.dirname(execdir), "Frameworks")
mainprogram = os.path.join(resdir, "idlemain.py")
sys.argv.insert(1, mainprogram)
if 0 or 0:
os.environ["PYTHONPATH"] = resdir
if 0:
os.environ["PYTHONHOME"] = resdir
else:
pypath = os.getenv("PYTHONPATH", "")
if pypath:
pypath = ":" + pypath
os.environ["PYTHONPATH"] = resdir + pypath
os.environ["PYTHONEXECUTABLE"] = executable
os.environ["DYLD_LIBRARY_PATH"] = libdir
os.environ["DYLD_FRAMEWORK_PATH"] = libdir
os.execve(executable, sys.argv, os.environ)

View File

@ -0,0 +1 @@
/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python

View File

@ -0,0 +1 @@
APPL????

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,30 @@
"""
Bootstrap script for IDLE as an application bundle.
"""
import sys, os
from idlelib.PyShell import main
# Change the current directory the user's home directory, that way we'll get
# a more useful default location in the open/save dialogs.
os.chdir(os.path.expanduser('~/Documents'))
# Make sure sys.executable points to the python interpreter inside the
# framework, instead of at the helper executable inside the application
# bundle (the latter works, but doesn't allow access to the window server)
if sys.executable.endswith('-32'):
sys.executable = os.path.join(sys.prefix, 'bin', 'python-32')
else:
sys.executable = os.path.join(sys.prefix, 'bin', 'python')
# Look for the -psn argument that the launcher adds and remove it, it will
# only confuse the IDLE startup code.
for idx, value in enumerate(sys.argv):
if value.startswith('-psn_'):
del sys.argv[idx]
break
#argvemulator.ArgvCollector().mainloop()
if __name__ == '__main__':
main()

View File

@ -1,60 +0,0 @@
prefix=@prefix@
CC=@CC@
LD=@CC@
BASECFLAGS=@BASECFLAGS@
OPT=@OPT@
CFLAGS=$(BASECFLAGS) $(OPT)
LDFLAGS=@LDFLAGS@
srcdir= @srcdir@
VERSION= @VERSION@
UNIVERSALSDK=@UNIVERSALSDK@
builddir= ../..
PYTHONFRAMEWORK=@PYTHONFRAMEWORK@
RUNSHARED= @RUNSHARED@
BUILDEXE= @BUILDEXEEXT@
BUILDPYTHON= $(builddir)/python$(BUILDEXE)
# Deployment target selected during configure, to be checked
# by distutils
MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@
@EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET
BUNDLEBULDER=$(srcdir)/../../Lib/plat-mac/bundlebuilder.py
PYTHONAPPSDIR=/Applications/$(PYTHONFRAMEWORK) $(VERSION)
all: IDLE.app
install: IDLE.app $(srcdir)/config-main.def $(srcdir)/config-extensions.def
test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)"
-test -d "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app"
cp -PR IDLE.app "$(DESTDIR)$(PYTHONAPPSDIR)"
touch "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app"
cp $(srcdir)/config-main.def "$(DESTDIR)$(prefix)/lib/python$(VERSION)/idlelib/config-main.def"
cp $(srcdir)/config-extensions.def "$(DESTDIR)$(prefix)/lib/python$(VERSION)/idlelib/config-extensions.def"
clean:
rm -rf IDLE.app
IDLE.app: \
$(srcdir)/../Icons/IDLE.icns $(srcdir)/idlemain.py \
$(srcdir)/../Icons/PythonSource.icns \
$(srcdir)/../Icons/PythonCompiled.icns Info.plist
rm -fr IDLE.app
$(RUNSHARED) $(BUILDPYTHON) $(BUNDLEBULDER) \
--builddir=. \
--name=IDLE \
--link-exec \
--plist=Info.plist \
--mainprogram=$(srcdir)/idlemain.py \
--iconfile=$(srcdir)/../Icons/IDLE.icns \
--resource=$(srcdir)/../Icons/PythonSource.icns \
--resource=$(srcdir)/../Icons/PythonCompiled.icns \
--python=$(prefix)/Resources/Python.app/Contents/MacOS/Python \
build
Info.plist: $(srcdir)/Info.plist.in
sed 's/%VERSION%/'"`$(RUNSHARED) $(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(srcdir)/Info.plist.in > Info.plist

View File

@ -1,88 +0,0 @@
# config-extensions.def
#
# IDLE reads several config files to determine user preferences. This
# file is the default configuration file for IDLE extensions settings.
#
# Each extension must have at least one section, named after the extension
# module. This section must contain an 'enable' item (=1 to enable the
# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
# items, to apply it only to editor/shell windows, and may also contain any
# other general configuration items for the extension.
#
# Each extension must define at least one section named ExtensionName_bindings
# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
# virtual event bindings for the extension that are not user re-configurable.
# If present, ExtensionName_cfgBindings defines virtual event bindings for the
# extension that may be sensibly re-configured.
#
# If there are no keybindings for a menus' virtual events, include lines like
# <<toggle-code-context>>= (See [CodeContext], below.)
#
# Currently it is necessary to manually modify this file to change extension
# key bindings and default values. To customize, create
# ~/.idlerc/config-extensions.cfg and append the appropriate customized
# section(s). Those sections will override the defaults in this file.
#
# Note: If a keybinding is already in use when the extension is
# loaded, the extension's virtual event's keybinding will be set to ''.
#
# See config-keys.def for notes on specifying keys and extend.txt for
# information on creating IDLE extensions.
[FormatParagraph]
enable=1
[FormatParagraph_cfgBindings]
format-paragraph=<Option-Key-q>
[AutoExpand]
enable=1
[AutoExpand_cfgBindings]
expand-word=<Option-Key-slash>
[ZoomHeight]
enable=1
[ZoomHeight_cfgBindings]
zoom-height=<Option-Key-0>
[ScriptBinding]
enable=1
[ScriptBinding_cfgBindings]
run-module=<Key-F5>
check-module=<Option-Key-x>
[CallTips]
enable=1
[CallTips_cfgBindings]
force-open-calltip=<Control-Key-backslash>
[CallTips_bindings]
try-open-calltip=<KeyRelease-parenleft>
refresh-calltip=<KeyRelease-parenright> <KeyRelease-0>
[ParenMatch]
enable=1
style= expression
flash-delay= 500
bell= 1
[ParenMatch_cfgBindings]
flash-paren=<Control-Key-0>
[ParenMatch_bindings]
paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
[AutoComplete]
enable=1
popupwait=2000
[AutoComplete_cfgBindings]
force-open-completions=<Control-Key-space>
[AutoComplete_bindings]
autocomplete=<Key-Tab>
try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash>
[CodeContext]
enable=1
enable_shell=0
numlines=3
visible=0
bgcolor=LightGray
fgcolor=Black
[CodeContext_bindings]
toggle-code-context=

View File

@ -1,79 +0,0 @@
# IDLE reads several config files to determine user preferences. This
# file is the default config file for general idle settings.
#
# When IDLE starts, it will look in
# the following two sets of files, in order:
#
# default configuration
# ---------------------
# config-main.def the default general config file
# config-extensions.def the default extension config file
# config-highlight.def the default highlighting config file
# config-keys.def the default keybinding config file
#
# user configuration
# -------------------
# ~/.idlerc/config-main.cfg the user general config file
# ~/.idlerc/config-extensions.cfg the user extension config file
# ~/.idlerc/config-highlight.cfg the user highlighting config file
# ~/.idlerc/config-keys.cfg the user keybinding config file
#
# On Windows2000 and Windows XP the .idlerc directory is at
# Documents and Settings\<username>\.idlerc
#
# On Windows98 it is at c:\.idlerc
#
# Any options the user saves through the config dialog will be saved to
# the relevant user config file. Reverting any general setting to the
# default causes that entry to be wiped from the user file and re-read
# from the default file. User highlighting themes or keybinding sets are
# retained unless specifically deleted within the config dialog. Choosing
# one of the default themes or keysets just applies the relevant settings
# from the default file.
#
# Additional help sources are listed in the [HelpFiles] section and must be
# viewable by a web browser (or the Windows Help viewer in the case of .chm
# files). These sources will be listed on the Help menu. The pattern is
# <sequence_number = menu item;/path/to/help/source>
# You can't use a semi-colon in a menu item or path. The path will be platform
# specific because of path separators, drive specs etc.
#
# It is best to use the Configuration GUI to set up additional help sources!
# Example:
#1 = My Extra Help Source;/usr/share/doc/foo/index.html
#2 = Another Help Source;/path/to/another.pdf
[General]
editor-on-startup= 0
autosave= 0
print-command-posix=lpr %s
print-command-win=start /min notepad /p %s
delete-exitfunc= 1
[EditorWindow]
width= 80
height= 40
font= courier
font-size= 10
font-bold= 0
encoding= none
[FormatParagraph]
paragraph=70
[Indent]
use-spaces= 1
num-spaces= 4
[Theme]
default= 1
name= IDLE Classic
[Keys]
default= 1
name= IDLE Classic OSX
[History]
cyclic=1
[HelpFiles]

View File

@ -45,8 +45,8 @@ DOCDIR=$(srcdir)/Resources/app/Resources/English.lproj/Documentation
DOCINDEX=$(DOCDIR)/"Documentation idx" DOCINDEX=$(DOCDIR)/"Documentation idx"
compileall=$(srcdir)/../Lib/compileall.py compileall=$(srcdir)/../Lib/compileall.py
installapps: install_Python install_BuildApplet install_PythonLauncher \ installapps: install_PythonLauncher install_IDLE checkapplepython install_pythonw \
install_IDLE checkapplepython install_pythonw install_versionedtools install_versionedtools
install_pythonw: pythonw install_pythonw: pythonw
$(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)" $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)"
@ -159,73 +159,10 @@ install_Python:
$(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
install_IDLE: install_IDLE:
cd IDLE && make install test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)"
-test -d "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app"
install_BuildApplet: cp -PR IDLE/IDLE.app "$(DESTDIR)$(PYTHONAPPSDIR)"
$(RUNSHARED) $(BUILDPYTHON) $(srcdir)/scripts/BuildApplet.py \ touch "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app"
--destroot "$(DESTDIR)" \
--python $(INSTALLED_PYTHONAPP) \
--output "$(DESTDIR)$(PYTHONAPPSDIR)/Build Applet.app" \
$(srcdir)/scripts/BuildApplet.py
MACLIBDEST=$(LIBDEST)/plat-mac
MACTOOLSDEST=$(prefix)/Mac/Tools
MACTOOLSSRC=$(srcdir)/Mac/Tools
MACTOOLSSUBDIRS=IDE
installmacsubtree:
@for i in $(MACTOOLSDEST); \
do \
if test ! -d $(DESTDIR)$$i; then \
echo "Creating directory $(DESTDIR)$$i"; \
$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
else true; \
fi; \
done
@for d in $(MACTOOLSSUBDIRS); \
do \
a=$(MACTOOLSSRC)/$$d; \
if test ! -d $$a; then continue; else true; fi; \
b=$(DESTDIR)$(MACTOOLSDEST)/$$d; \
if test ! -d $$b; then \
echo "Creating directory $$b"; \
$(INSTALL) -d -m $(DIRMODE) $$b; \
else true; \
fi; \
done
@for d in $(MACTOOLSSUBDIRS); \
do \
a=$(MACTOOLSSRC)/$$d; \
if test ! -d $$a; then continue; else true; fi; \
b=$(DESTDIR)$(MACTOOLSDEST)/$$d; \
for i in $$a/*; \
do \
case $$i in \
*CVS) ;; \
*.svn) ;; \
*.py[co]) ;; \
*.orig) ;; \
*~) ;; \
*.rsrc) \
echo $(CPMAC) $$i $$b ; \
$(CPMAC) $$i $$b ; \
;; \
*) \
if test -d $$i; then continue; fi; \
if test -x $$i; then \
echo $(INSTALL_SCRIPT) $$i $$b; \
$(INSTALL_SCRIPT) $$i $$b; \
else \
echo $(INSTALL_DATA) $$i $$b; \
$(INSTALL_DATA) $$i $$b; \
fi;; \
esac; \
done; \
done
$(RUNSHARED) $(BUILDPYTHON) -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
$(RUNSHARED) $(BUILDPYTHON) -O -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
$(INSTALLED_PYTHONAPP): install_Python $(INSTALLED_PYTHONAPP): install_Python
@ -248,7 +185,6 @@ checkapplepython: $(srcdir)/Tools/fixapplepython23.py
clean: clean:
rm pythonw rm pythonw
cd PythonLauncher && make clean cd PythonLauncher && make clean
cd IDLE && make clean
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
cd .. && CONFIG_FILES=Mac/Makefile CONFIG_HEADERS= $(SHELL) ./config.status cd .. && CONFIG_FILES=Mac/Makefile CONFIG_HEADERS= $(SHELL) ./config.status

View File

@ -24,59 +24,8 @@ BUNDLEBULDER=$(srcdir)/../../Lib/plat-mac/bundlebuilder.py
PYTHONAPPSDIR=/Applications/$(PYTHONFRAMEWORK) $(VERSION) PYTHONAPPSDIR=/Applications/$(PYTHONFRAMEWORK) $(VERSION)
OBJECTS=FileSettings.o MyAppDelegate.o MyDocument.o PreferencesWindowController.o doscript.o main.o OBJECTS=FileSettings.o MyAppDelegate.o MyDocument.o PreferencesWindowController.o doscript.o main.o
all: Python\ Launcher.app install:
install: Python\ Launcher.app
test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)" test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)"
-test -d "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" -test -d "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app"
cp -r "Python Launcher.app" "$(DESTDIR)$(PYTHONAPPSDIR)" cp -r "Python Launcher.app" "$(DESTDIR)$(PYTHONAPPSDIR)"
touch "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" touch "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app"
clean:
rm -f *.o "Python Launcher"
rm -rf "Python Launcher.app"
Python\ Launcher.app: Info.plist \
Python\ Launcher $(srcdir)/../Icons/PythonLauncher.icns \
$(srcdir)/../Icons/PythonSource.icns \
$(srcdir)/../Icons/PythonCompiled.icns \
$(srcdir)/factorySettings.plist
rm -fr "Python Launcher.app"
$(RUNSHARED) $(BUILDPYTHON) $(BUNDLEBULDER) \
--builddir=. \
--name="Python Launcher" \
--executable="Python Launcher" \
--iconfile=$(srcdir)/../Icons/PythonLauncher.icns \
--bundle-id=org.python.PythonLauncher \
--resource=$(srcdir)/../Icons/PythonSource.icns \
--resource=$(srcdir)/../Icons/PythonCompiled.icns \
--resource=$(srcdir)/English.lproj \
--resource=$(srcdir)/factorySettings.plist \
--plist Info.plist \
build
find "Python Launcher.app" -name '.svn' -print0 | xargs -0 rm -r
FileSettings.o: $(srcdir)/FileSettings.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/FileSettings.m
MyAppDelegate.o: $(srcdir)/MyAppDelegate.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/MyAppDelegate.m
MyDocument.o: $(srcdir)/MyDocument.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/MyDocument.m
PreferencesWindowController.o: $(srcdir)/PreferencesWindowController.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/PreferencesWindowController.m
doscript.o: $(srcdir)/doscript.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/doscript.m
main.o: $(srcdir)/main.m
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/main.m
Python\ Launcher: $(OBJECTS)
$(CC) $(LDFLAGS) -o "Python Launcher" $(OBJECTS) -framework AppKit -framework Carbon
Info.plist: $(srcdir)/Info.plist.in
sed 's/%VERSION%/'"`$(RUNSHARED) $(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(srcdir)/Info.plist.in > Info.plist

View File

@ -10,46 +10,56 @@
<key>CFBundleTypeExtensions</key> <key>CFBundleTypeExtensions</key>
<array> <array>
<string>py</string> <string>py</string>
<string>pyw</string>
</array> </array>
<key>CFBundleTypeIconFile</key> <key>CFBundleTypeIconFile</key>
<string>PythonSource.icns</string> <string>PythonSource.icns</string>
<key>CFBundleTypeName</key> <key>CFBundleTypeName</key>
<string>Python Module</string> <string>Python Script</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>TEXT</string>
</array>
<key>CFBundleTypeRole</key> <key>CFBundleTypeRole</key>
<string>Viewer</string> <string>Viewer</string>
<key>NSDocumentClass</key>
<string>MyDocument</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pyc</string>
<string>pyo</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>PythonCompiled.icns</string>
<key>CFBundleTypeName</key>
<string>Python Bytecode Document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>MyDocument</string>
</dict> </dict>
</array> </array>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>BuildApplet</string> <string>Python Launcher</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string> <string>2.6.0, © 001-2006 Python Software Foundation</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>BuildApplet.icns</string> <string>PythonLauncher.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.python.buildapplet</string> <string>org.python.PythonLauncher</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>2.5alpha0, (c) 2004 Python Software Foundation.</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>PythonIDE</string> <string>Python Launcher</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.5alpha0</string> <string>2.6.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>Pide</string> <string>PytL</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.5alpha0</string> <string>2.6.0</string>
<key>CSResourcesFileMapped</key> <key>NSMainNibFile</key>
<true/> <string>MainMenu</string>
<key>LSRequiresCarbon</key> <key>NSPrincipalClass</key>
<true/> <string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
<string>(c) 2004 Python Software Foundation.</string>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1 @@
APPLPytL

View File

@ -0,0 +1,30 @@
{\rtf1\mac\ansicpg10000\cocoartf100
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Engineering:
\f1\b0 \
Jack Jansen\
\
\f0\b Human Interface Design:
\f1\b0 \
Jack Jansen\
\
\f0\b Testing:
\f1\b0 \
Jack Jansen\
Pythonmac-SIG@python.org\
\
\f0\b Documentation:
\f1\b0 \
Missing\
\
\f0\b With special thanks to:
\f1\b0 \
Guido, of course\
}

View File

@ -0,0 +1,12 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {showPreferences = id; };
CLASS = MyAppDelegate;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>99 33 356 240 0 0 800 578 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>82 396 318 44 0 0 800 578 </string>
</dict>
<key>IBFramework Version</key>
<string>263.2</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>5S66</string>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {"do_apply" = id; "do_cancel" = id; "do_reset" = id; "do_run" = id; };
CLASS = MyDocument;
LANGUAGE = ObjC;
OUTLETS = {
commandline = NSTextField;
debug = NSButton;
honourhashbang = NSButton;
inspect = NSButton;
interpreter = NSTextField;
nosite = NSButton;
optimize = NSButton;
others = NSTextField;
scriptargs = NSTextField;
tabs = NSButton;
verbose = NSButton;
"with_terminal" = NSButton;
};
SUPERCLASS = NSDocument;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>398 60 356 240 0 0 1024 746 </string>
<key>IBFramework Version</key>
<string>291.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>6L60</string>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {"do_apply" = id; "do_filetype" = id; "do_reset" = id; };
CLASS = PreferencesWindowController;
LANGUAGE = ObjC;
OUTLETS = {
commandline = NSTextField;
debug = NSButton;
filetype = NSPopUpButton;
honourhashbang = NSButton;
inspect = NSButton;
interpreter = NSTextField;
nosite = NSButton;
optimize = NSButton;
others = NSTextField;
tabs = NSButton;
verbose = NSButton;
"with_terminal" = NSButton;
};
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>565 235 519 534 0 0 1280 1002 </string>
<key>IBFramework Version</key>
<string>364.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>7H63</string>
</dict>
</plist>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Python GUI Script</key>
<dict>
<key>debug</key>
<false/>
<key>inspect</key>
<false/>
<key>interpreter_list</key>
<array>
<string>/usr/local/bin/pythonw</string>
<string>/usr/bin/pythonw</string>
<string>/sw/bin/pythonw</string>
</array>
<key>honourhashbang</key>
<false/>
<key>nosite</key>
<false/>
<key>optimize</key>
<false/>
<key>others</key>
<string></string>
<key>verbose</key>
<false/>
<key>with_terminal</key>
<false/>
</dict>
<key>Python Script</key>
<dict>
<key>debug</key>
<false/>
<key>inspect</key>
<false/>
<key>interpreter_list</key>
<array>
<string>/usr/local/bin/pythonw</string>
<string>/usr/local/bin/python</string>
<string>/usr/bin/pythonw</string>
<string>/usr/bin/python</string>
<string>/sw/bin/pythonw</string>
<string>/sw/bin/python</string>
</array>
<key>honourhashbang</key>
<false/>
<key>nosite</key>
<false/>
<key>optimize</key>
<false/>
<key>others</key>
<string></string>
<key>verbose</key>
<false/>
<key>with_terminal</key>
<true/>
</dict>
<key>Python Bytecode Document</key>
<dict>
<key>debug</key>
<false/>
<key>inspect</key>
<false/>
<key>interpreter_list</key>
<array>
<string>/usr/local/bin/pythonw</string>
<string>/usr/local/bin/python</string>
<string>/usr/bin/pythonw</string>
<string>/usr/bin/python</string>
<string>/sw/bin/pythonw</string>
<string>/sw/bin/python</string>
</array>
<key>honourhashbang</key>
<false/>
<key>nosite</key>
<false/>
<key>optimize</key>
<false/>
<key>others</key>
<string></string>
<key>verbose</key>
<false/>
<key>with_terminal</key>
<true/>
</dict>
</dict>
</plist>

View File

@ -123,11 +123,6 @@ GUI-things. Keep the "alt" key depressed while dragging or double-clicking a
script to set runtime options. These options can be set once and for all script to set runtime options. These options can be set once and for all
through PythonLauncher's preferences dialog. through PythonLauncher's preferences dialog.
"BuildApplet.app" creates an applet from a Python script. Drop the script on it
and out comes a full-featured MacOS application. There is much more to this,
to be supplied later. Some useful (but outdated) info can be found in
Mac/Demo.
The commandline scripts /usr/local/bin/python and pythonw can be used to run The commandline scripts /usr/local/bin/python and pythonw can be used to run
non-GUI and GUI python scripts from the command line, respectively. non-GUI and GUI python scripts from the command line, respectively.

View File

@ -14,7 +14,7 @@ status also when nothing needs to be fixed.
""" """
import sys import sys
import os import os
import gestalt import gestalt as _gestalt
MAKEFILE='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/Makefile' MAKEFILE='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/Makefile'
CHANGES=(( CHANGES=((

Binary file not shown.

View File

@ -1,149 +0,0 @@
"""Create an applet from a Python script.
This puts up a dialog asking for a Python source file ('TEXT').
The output is a file with the same name but its ".py" suffix dropped.
It is created by copying an applet template and then adding a 'PYC '
resource named __main__ containing the compiled, marshalled script.
"""
import sys
sys.stdout = sys.stderr
import os
import MacOS
import EasyDialogs
import buildtools
import getopt
if not sys.executable.startswith(sys.exec_prefix):
# Oh, the joys of using a python script to bootstrap applicatin bundles
# sys.executable points inside the current application bundle. Because this
# path contains blanks (two of them actually) this path isn't usable on
# #! lines. Reset sys.executable to point to the embedded python interpreter
sys.executable = os.path.join(sys.prefix,
'Resources/Python.app/Contents/MacOS/Python')
# Just in case we're not in a framework:
if not os.path.exists(sys.executable):
sys.executable = os.path.join(sys.exec_prefix, 'bin/python')
def main():
try:
buildapplet()
except buildtools.BuildError as detail:
EasyDialogs.Message(detail)
def buildapplet():
buildtools.DEBUG=1
# Find the template
# (there's no point in proceeding if we can't find it)
template = buildtools.findtemplate()
# Ask for source text if not specified in sys.argv[1:]
if not sys.argv[1:]:
filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:',
typeList=('TEXT', 'APPL'))
if not filename:
return
tp, tf = os.path.split(filename)
if tf[-3:] == '.py':
tf = tf[:-3]
else:
tf = tf + '.applet'
dstfilename = EasyDialogs.AskFileForSave(message='Save application as:',
savedFileName=tf)
if not dstfilename: return
cr, tp = MacOS.GetCreatorAndType(filename)
if tp == 'APPL':
buildtools.update(template, filename, dstfilename)
else:
buildtools.process(template, filename, dstfilename, 1)
else:
SHORTOPTS = "o:r:ne:v?PR"
LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=")
try:
options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
except getopt.error:
usage()
if options and len(args) > 1:
sys.stderr.write("Cannot use options when specifying multiple input files")
sys.exit(1)
dstfilename = None
rsrcfilename = None
raw = 0
extras = []
verbose = None
destroot = ''
for opt, arg in options:
if opt in ('-o', '--output'):
dstfilename = arg
elif opt in ('-r', '--resource'):
rsrcfilename = arg
elif opt in ('-n', '--noargv'):
raw = 1
elif opt in ('-e', '--extra'):
if ':' in arg:
arg = arg.split(':')
extras.append(arg)
elif opt in ('-P', '--python'):
# This is a very dirty trick. We set sys.executable
# so that bundlebuilder will use this in the #! line
# for the applet bootstrap.
sys.executable = arg
elif opt in ('-v', '--verbose'):
verbose = Verbose()
elif opt in ('-?', '--help'):
usage()
elif opt in ('-d', '--destroot'):
destroot = arg
# On OS9 always be verbose
if sys.platform == 'mac' and not verbose:
verbose = 'default'
# Loop over all files to be processed
for filename in args:
cr, tp = MacOS.GetCreatorAndType(filename)
if tp == 'APPL':
buildtools.update(template, filename, dstfilename)
else:
buildtools.process(template, filename, dstfilename, 1,
rsrcname=rsrcfilename, others=extras, raw=raw,
progress=verbose, destroot=destroot)
def usage():
print("BuildApplet creates an application from a Python source file")
print("Usage:")
print(" BuildApplet interactive, single file, no options")
print(" BuildApplet src1.py src2.py ... non-interactive multiple file")
print(" BuildApplet [options] src.py non-interactive single file")
print("Options:")
print(" --output o Output file; default based on source filename, short -o")
print(" --resource r Resource file; default based on source filename, short -r")
print(" --noargv Build applet without drag-and-drop sys.argv emulation, short -n, OSX only")
print(" --extra src[:dst] Extra file to put in .app bundle, short -e, OSX only")
print(" --verbose Verbose, short -v")
print(" --help This message, short -?")
sys.exit(1)
class Verbose:
"""This class mimics EasyDialogs.ProgressBar but prints to stderr"""
def __init__(self, *args):
if args and args[0]:
self.label(args[0])
def set(self, *args):
pass
def inc(self, *args):
pass
def label(self, str):
sys.stderr.write(str+'\n')
if __name__ == '__main__':
main()

Binary file not shown.

View File

@ -1,484 +0,0 @@
#!/usr/bin/env python
"""buildpkg.py -- Build OS X packages for Apple's Installer.app.
This is an experimental command-line tool for building packages to be
installed with the Mac OS X Installer.app application.
It is much inspired by Apple's GUI tool called PackageMaker.app, that
seems to be part of the OS X developer tools installed in the folder
/Developer/Applications. But apparently there are other free tools to
do the same thing which are also named PackageMaker like Brian Hill's
one:
http://personalpages.tds.net/~brian_hill/packagemaker.html
Beware of the multi-package features of Installer.app (which are not
yet supported here) that can potentially screw-up your installation
and are discussed in these articles on Stepwise:
http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html
Beside using the PackageMaker class directly, by importing it inside
another module, say, there are additional ways of using this module:
the top-level buildPackage() function provides a shortcut to the same
feature and is also called when using this module from the command-
line.
****************************************************************
NOTE: For now you should be able to run this even on a non-OS X
system and get something similar to a package, but without
the real archive (needs pax) and bom files (needs mkbom)
inside! This is only for providing a chance for testing to
folks without OS X.
****************************************************************
TODO:
- test pre-process and post-process scripts (Python ones?)
- handle multi-volume packages (?)
- integrate into distutils (?)
Dinu C. Gherman,
gherman@europemail.com
November 2001
!! USE AT YOUR OWN RISK !!
"""
__version__ = 0.2
__license__ = "FreeBSD"
import os, sys, glob, fnmatch, shutil, string, copy, getopt
from os.path import basename, dirname, join, islink, isdir, isfile
Error = "buildpkg.Error"
PKG_INFO_FIELDS = """\
Title
Version
Description
DefaultLocation
DeleteWarning
NeedsAuthorization
DisableStop
UseUserMask
Application
Relocatable
Required
InstallOnly
RequiresReboot
RootVolumeOnly
LongFilenames
LibrarySubdirectory
AllowBackRev
OverwritePermissions
InstallFat\
"""
######################################################################
# Helpers
######################################################################
# Convenience class, as suggested by /F.
class GlobDirectoryWalker:
"A forward iterator that traverses files in a directory tree."
def __init__(self, directory, pattern="*"):
self.stack = [directory]
self.pattern = pattern
self.files = []
self.index = 0
def __getitem__(self, index):
while 1:
try:
file = self.files[self.index]
self.index = self.index + 1
except IndexError:
# pop next directory from stack
self.directory = self.stack.pop()
self.files = os.listdir(self.directory)
self.index = 0
else:
# got a filename
fullname = join(self.directory, file)
if isdir(fullname) and not islink(fullname):
self.stack.append(fullname)
if fnmatch.fnmatch(file, self.pattern):
return fullname
######################################################################
# The real thing
######################################################################
class PackageMaker:
"""A class to generate packages for Mac OS X.
This is intended to create OS X packages (with extension .pkg)
containing archives of arbitrary files that the Installer.app
will be able to handle.
As of now, PackageMaker instances need to be created with the
title, version and description of the package to be built.
The package is built after calling the instance method
build(root, **options). It has the same name as the constructor's
title argument plus a '.pkg' extension and is located in the same
parent folder that contains the root folder.
E.g. this will create a package folder /my/space/distutils.pkg/:
pm = PackageMaker("distutils", "1.0.2", "Python distutils.")
pm.build("/my/space/distutils")
"""
packageInfoDefaults = {
'Title': None,
'Version': None,
'Description': '',
'DefaultLocation': '/',
'DeleteWarning': '',
'NeedsAuthorization': 'NO',
'DisableStop': 'NO',
'UseUserMask': 'YES',
'Application': 'NO',
'Relocatable': 'YES',
'Required': 'NO',
'InstallOnly': 'NO',
'RequiresReboot': 'NO',
'RootVolumeOnly' : 'NO',
'InstallFat': 'NO',
'LongFilenames': 'YES',
'LibrarySubdirectory': 'Standard',
'AllowBackRev': 'YES',
'OverwritePermissions': 'NO',
}
def __init__(self, title, version, desc):
"Init. with mandatory title/version/description arguments."
info = {"Title": title, "Version": version, "Description": desc}
self.packageInfo = copy.deepcopy(self.packageInfoDefaults)
self.packageInfo.update(info)
# variables set later
self.packageRootFolder = None
self.packageResourceFolder = None
self.sourceFolder = None
self.resourceFolder = None
def build(self, root, resources=None, **options):
"""Create a package for some given root folder.
With no 'resources' argument set it is assumed to be the same
as the root directory. Option items replace the default ones
in the package info.
"""
# set folder attributes
self.sourceFolder = root
if resources is None:
self.resourceFolder = root
else:
self.resourceFolder = resources
# replace default option settings with user ones if provided
fields = self. packageInfoDefaults.keys()
for k, v in options.items():
if k in fields:
self.packageInfo[k] = v
elif not k in ["OutputDir"]:
raise Error("Unknown package option: %s" % k)
# Check where we should leave the output. Default is current directory
outputdir = options.get("OutputDir", os.getcwd())
packageName = self.packageInfo["Title"]
self.PackageRootFolder = os.path.join(outputdir, packageName + ".pkg")
# do what needs to be done
self._makeFolders()
self._addInfo()
self._addBom()
self._addArchive()
self._addResources()
self._addSizes()
self._addLoc()
def _makeFolders(self):
"Create package folder structure."
# Not sure if the package name should contain the version or not...
# packageName = "%s-%s" % (self.packageInfo["Title"],
# self.packageInfo["Version"]) # ??
contFolder = join(self.PackageRootFolder, "Contents")
self.packageResourceFolder = join(contFolder, "Resources")
os.mkdir(self.PackageRootFolder)
os.mkdir(contFolder)
os.mkdir(self.packageResourceFolder)
def _addInfo(self):
"Write .info file containing installing options."
# Not sure if options in PKG_INFO_FIELDS are complete...
info = ""
for f in string.split(PKG_INFO_FIELDS, "\n"):
if self.packageInfo.has_key(f):
info = info + "%s %%(%s)s\n" % (f, f)
info = info % self.packageInfo
base = self.packageInfo["Title"] + ".info"
path = join(self.packageResourceFolder, base)
f = open(path, "w")
f.write(info)
def _addBom(self):
"Write .bom file containing 'Bill of Materials'."
# Currently ignores if the 'mkbom' tool is not available.
try:
base = self.packageInfo["Title"] + ".bom"
bomPath = join(self.packageResourceFolder, base)
cmd = "mkbom %s %s" % (self.sourceFolder, bomPath)
res = os.system(cmd)
except:
pass
def _addArchive(self):
"Write .pax.gz file, a compressed archive using pax/gzip."
# Currently ignores if the 'pax' tool is not available.
cwd = os.getcwd()
# create archive
os.chdir(self.sourceFolder)
base = basename(self.packageInfo["Title"]) + ".pax"
self.archPath = join(self.packageResourceFolder, base)
cmd = "pax -w -f %s %s" % (self.archPath, ".")
res = os.system(cmd)
# compress archive
cmd = "gzip %s" % self.archPath
res = os.system(cmd)
os.chdir(cwd)
def _addResources(self):
"Add Welcome/ReadMe/License files, .lproj folders and scripts."
# Currently we just copy everything that matches the allowed
# filenames. So, it's left to Installer.app to deal with the
# same file available in multiple formats...
if not self.resourceFolder:
return
# find candidate resource files (txt html rtf rtfd/ or lproj/)
allFiles = []
for pat in string.split("*.txt *.html *.rtf *.rtfd *.lproj", " "):
pattern = join(self.resourceFolder, pat)
allFiles = allFiles + glob.glob(pattern)
# find pre-process and post-process scripts
# naming convention: packageName.{pre,post}_{upgrade,install}
# Alternatively the filenames can be {pre,post}_{upgrade,install}
# in which case we prepend the package name
packageName = self.packageInfo["Title"]
for pat in ("*upgrade", "*install", "*flight"):
pattern = join(self.resourceFolder, packageName + pat)
pattern2 = join(self.resourceFolder, pat)
allFiles = allFiles + glob.glob(pattern)
allFiles = allFiles + glob.glob(pattern2)
# check name patterns
files = []
for f in allFiles:
for s in ("Welcome", "License", "ReadMe"):
if string.find(basename(f), s) == 0:
files.append((f, f))
if f[-6:] == ".lproj":
files.append((f, f))
elif basename(f) in ["pre_upgrade", "pre_install", "post_upgrade", "post_install"]:
files.append((f, packageName+"."+basename(f)))
elif basename(f) in ["preflight", "postflight"]:
files.append((f, f))
elif f[-8:] == "_upgrade":
files.append((f,f))
elif f[-8:] == "_install":
files.append((f,f))
# copy files
for src, dst in files:
src = basename(src)
dst = basename(dst)
f = join(self.resourceFolder, src)
if isfile(f):
shutil.copy(f, os.path.join(self.packageResourceFolder, dst))
elif isdir(f):
# special case for .rtfd and .lproj folders...
d = join(self.packageResourceFolder, dst)
os.mkdir(d)
files = GlobDirectoryWalker(f)
for file in files:
shutil.copy(file, d)
def _addSizes(self):
"Write .sizes file with info about number and size of files."
# Not sure if this is correct, but 'installedSize' and
# 'zippedSize' are now in Bytes. Maybe blocks are needed?
# Well, Installer.app doesn't seem to care anyway, saying
# the installation needs 100+ MB...
numFiles = 0
installedSize = 0
zippedSize = 0
files = GlobDirectoryWalker(self.sourceFolder)
for f in files:
numFiles = numFiles + 1
installedSize = installedSize + os.lstat(f)[6]
try:
zippedSize = os.stat(self.archPath+ ".gz")[6]
except OSError: # ignore error
pass
base = self.packageInfo["Title"] + ".sizes"
f = open(join(self.packageResourceFolder, base), "w")
format = "NumFiles %d\nInstalledSize %d\nCompressedSize %d\n"
f.write(format % (numFiles, installedSize, zippedSize))
def _addLoc(self):
"Write .loc file."
base = self.packageInfo["Title"] + ".loc"
f = open(join(self.packageResourceFolder, base), "w")
f.write('/')
# Shortcut function interface
def buildPackage(*args, **options):
"A Shortcut function for building a package."
o = options
title, version, desc = o["Title"], o["Version"], o["Description"]
pm = PackageMaker(title, version, desc)
pm.build(*args, **options)
######################################################################
# Tests
######################################################################
def test0():
"Vanilla test for the distutils distribution."
pm = PackageMaker("distutils2", "1.0.2", "Python distutils package.")
pm.build("/Users/dinu/Desktop/distutils2")
def test1():
"Test for the reportlab distribution with modified options."
pm = PackageMaker("reportlab", "1.10",
"ReportLab's Open Source PDF toolkit.")
pm.build(root="/Users/dinu/Desktop/reportlab",
DefaultLocation="/Applications/ReportLab",
Relocatable="YES")
def test2():
"Shortcut test for the reportlab distribution with modified options."
buildPackage(
"/Users/dinu/Desktop/reportlab",
Title="reportlab",
Version="1.10",
Description="ReportLab's Open Source PDF toolkit.",
DefaultLocation="/Applications/ReportLab",
Relocatable="YES")
######################################################################
# Command-line interface
######################################################################
def printUsage():
"Print usage message."
format = "Usage: %s <opts1> [<opts2>] <root> [<resources>]"
print(format % basename(sys.argv[0]))
print()
print(" with arguments:")
print(" (mandatory) root: the package root folder")
print(" (optional) resources: the package resources folder")
print()
print(" and options:")
print(" (mandatory) opts1:")
mandatoryKeys = string.split("Title Version Description", " ")
for k in mandatoryKeys:
print(" --%s" % k)
print(" (optional) opts2: (with default values)")
pmDefaults = PackageMaker.packageInfoDefaults
optionalKeys = pmDefaults.keys()
for k in mandatoryKeys:
optionalKeys.remove(k)
optionalKeys.sort()
maxKeyLen = max(map(len, optionalKeys))
for k in optionalKeys:
format = " --%%s:%s %%s"
format = format % (" " * (maxKeyLen-len(k)))
print(format % (k, repr(pmDefaults[k])))
def main():
"Command-line interface."
shortOpts = ""
keys = PackageMaker.packageInfoDefaults.keys()
longOpts = map(lambda k: k+"=", keys)
try:
opts, args = getopt.getopt(sys.argv[1:], shortOpts, longOpts)
except getopt.GetoptError as details:
print(details)
printUsage()
return
optsDict = {}
for k, v in opts:
optsDict[k[2:]] = v
ok = optsDict.keys()
if not (1 <= len(args) <= 2):
print("No argument given!")
elif not ("Title" in ok and \
"Version" in ok and \
"Description" in ok):
print("Missing mandatory option!")
else:
buildPackage(*args, **optsDict)
return
printUsage()
# sample use:
# buildpkg.py --Title=distutils \
# --Version=1.0.2 \
# --Description="Python distutils package." \
# /Users/dinu/Desktop/distutils
if __name__ == "__main__":
main()

View File

@ -1,36 +0,0 @@
#!/usr/local/bin/python
"""Recursively zap all .pyc and .pyo files"""
import os
import sys
# set doit true to actually delete files
# set doit false to just print what would be deleted
doit = 1
def main():
if not sys.argv[1:]:
if os.name == 'mac':
import EasyDialogs
dir = EasyDialogs.AskFolder(message='Directory to zap pyc files in')
if not dir:
sys.exit(0)
zappyc(dir)
else:
print('Usage: zappyc dir ...')
sys.exit(1)
for dir in sys.argv[1:]:
zappyc(dir)
def zappyc(dir):
os.walk(dir, walker, None)
def walker(dummy, top, names):
for name in names:
if name[-4:] in ('.pyc', '.pyo'):
path = os.path.join(top, name)
print('Zapping', path)
if doit:
os.unlink(path)
if __name__ == '__main__':
main()

View File

@ -1026,7 +1026,6 @@ frameworkinstallstructure: $(LDLIBRARY)
# install (which includes python-config) happy. # install (which includes python-config) happy.
frameworkinstallmaclib: frameworkinstallmaclib:
ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a"
cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)"
# This installs the IDE, the Launcher and other apps into /Applications # This installs the IDE, the Launcher and other apps into /Applications
frameworkinstallapps: frameworkinstallapps:

View File

@ -21,6 +21,14 @@ Library
code of every single module of the standard library, including invalid files code of every single module of the standard library, including invalid files
used in the test suite. used in the test suite.
Tools/Demos
-----------
- The Mac/Demos directory has been removed
- All of the Mac scripts have been removed (including BuildApplet.py)
What's new in Python 3.0b1? What's new in Python 3.0b1?
=========================== ===========================

28
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.in Revision: 63697 . # From configure.in Revision: 64085 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 3.0. # Generated by GNU Autoconf 2.61 for python 3.0.
# #
@ -1938,8 +1938,6 @@ if test "${enable_framework+set}" = set; then
ac_config_files="$ac_config_files Mac/PythonLauncher/Makefile" ac_config_files="$ac_config_files Mac/PythonLauncher/Makefile"
ac_config_files="$ac_config_files Mac/IDLE/Makefile"
ac_config_files="$ac_config_files Mac/Resources/framework/Info.plist" ac_config_files="$ac_config_files Mac/Resources/framework/Info.plist"
ac_config_files="$ac_config_files Mac/Resources/app/Info.plist" ac_config_files="$ac_config_files Mac/Resources/app/Info.plist"
@ -2021,7 +2019,7 @@ case $ac_sys_system/$ac_sys_release in
# On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined, # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined,
# even though select is a POSIX function. Reported by J. Ribbens. # even though select is a POSIX function. Reported by J. Ribbens.
# Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish. # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
OpenBSD/2.* | OpenBSD/3.[0123456789] | OpenBSD/4.[0]) OpenBSD/2.* | OpenBSD/3.[0123456789] | OpenBSD/4.[0123])
define_xopen_source=no define_xopen_source=no
# OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is
# also defined. This can be overridden by defining _BSD_SOURCE # also defined. This can be overridden by defining _BSD_SOURCE
@ -2073,6 +2071,11 @@ _ACEOF
Darwin/[789].*) Darwin/[789].*)
define_xopen_source=no define_xopen_source=no
;; ;;
# On QNX 6.3.2, defining _XOPEN_SOURCE prevents netdb.h from
# defining NI_NUMERICHOST.
QNX/6.3.2)
define_xopen_source=no
;;
esac esac
@ -3871,6 +3874,10 @@ then
LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";; LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";;
Monterey64*) Monterey64*)
LINKCC="$LINKCC -L/usr/lib/ia64l64";; LINKCC="$LINKCC -L/usr/lib/ia64l64";;
QNX*)
# qcc must be used because the other compilers do not
# support -N.
LINKCC=qcc;;
esac esac
fi fi
{ echo "$as_me:$LINENO: result: $LINKCC" >&5 { echo "$as_me:$LINENO: result: $LINKCC" >&5
@ -5406,6 +5413,7 @@ done
for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \ for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
@ -5416,7 +5424,7 @@ unistd.h utime.h \
sys/audioio.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \ sys/audioio.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \
sys/lock.h sys/mkdev.h sys/modem.h \ sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
sys/time.h \ sys/termio.h sys/time.h \
sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h bluetooth/bluetooth.h linux/tipc.h
@ -12891,7 +12899,7 @@ then
fi fi
fi fi
;; ;;
Linux*|GNU*) LDSHARED='$(CC) -shared';; Linux*|GNU*|QNX*) LDSHARED='$(CC) -shared';;
BSD/OS*/4*) LDSHARED="gcc -shared";; BSD/OS*/4*) LDSHARED="gcc -shared";;
FreeBSD*) FreeBSD*)
if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ] if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]
@ -13019,6 +13027,13 @@ then
then then
LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)' LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)'
fi;; fi;;
QNX*)
# -Wl,-E causes the symbols to be added to the dynamic
# symbol table so that they can be found when a module
# is loaded. -N 2048K causes the stack size to be set
# to 2048 kilobytes so that the stack doesn't overflow
# when running test_compile.py.
LINKFORSHARED='-Wl,-E -N 2048K';;
esac esac
fi fi
{ echo "$as_me:$LINENO: result: $LINKFORSHARED" >&5 { echo "$as_me:$LINENO: result: $LINKFORSHARED" >&5
@ -24736,7 +24751,6 @@ do
"pyconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS pyconfig.h" ;; "pyconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS pyconfig.h" ;;
"Mac/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/Makefile" ;; "Mac/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/Makefile" ;;
"Mac/PythonLauncher/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/PythonLauncher/Makefile" ;; "Mac/PythonLauncher/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/PythonLauncher/Makefile" ;;
"Mac/IDLE/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/IDLE/Makefile" ;;
"Mac/Resources/framework/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/framework/Info.plist" ;; "Mac/Resources/framework/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/framework/Info.plist" ;;
"Mac/Resources/app/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/app/Info.plist" ;; "Mac/Resources/app/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/app/Info.plist" ;;
"Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;; "Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;;

View File

@ -141,7 +141,6 @@ AC_ARG_ENABLE(framework,
# files: # files:
AC_CONFIG_FILES(Mac/Makefile) AC_CONFIG_FILES(Mac/Makefile)
AC_CONFIG_FILES(Mac/PythonLauncher/Makefile) AC_CONFIG_FILES(Mac/PythonLauncher/Makefile)
AC_CONFIG_FILES(Mac/IDLE/Makefile)
AC_CONFIG_FILES(Mac/Resources/framework/Info.plist) AC_CONFIG_FILES(Mac/Resources/framework/Info.plist)
AC_CONFIG_FILES(Mac/Resources/app/Info.plist) AC_CONFIG_FILES(Mac/Resources/app/Info.plist)
esac esac