Whitespace normalization, via reindent.py.
diff --git a/Mac/Demo/PICTbrowse/ICONbrowse.py b/Mac/Demo/PICTbrowse/ICONbrowse.py
index 1194b7e..701ef7f 100644
--- a/Mac/Demo/PICTbrowse/ICONbrowse.py
+++ b/Mac/Demo/PICTbrowse/ICONbrowse.py
@@ -27,137 +27,137 @@
 MAXHEIGHT=320
 
 def main():
-	macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
-	ICONbrowse()
+    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
-		
+    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))
-		
+    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"
+    "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 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()
+    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()
diff --git a/Mac/Demo/PICTbrowse/PICTbrowse.py b/Mac/Demo/PICTbrowse/PICTbrowse.py
index eace869..0adfc83 100644
--- a/Mac/Demo/PICTbrowse/PICTbrowse.py
+++ b/Mac/Demo/PICTbrowse/PICTbrowse.py
@@ -22,120 +22,120 @@
 TOP=64
 
 def main():
-	macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
-	PICTbrowse()
+    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
-		
+    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()
-		
+    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"
+    "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 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()
+    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()
diff --git a/Mac/Demo/PICTbrowse/PICTbrowse2.py b/Mac/Demo/PICTbrowse/PICTbrowse2.py
index 875c99b..84cf8b8 100644
--- a/Mac/Demo/PICTbrowse/PICTbrowse2.py
+++ b/Mac/Demo/PICTbrowse/PICTbrowse2.py
@@ -26,138 +26,138 @@
 MAXHEIGHT=320
 
 def main():
-	macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
-	PICTbrowse()
+    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
-		
+    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))
-		
+    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"
+    "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 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()
+    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()
diff --git a/Mac/Demo/PICTbrowse/cicnbrowse.py b/Mac/Demo/PICTbrowse/cicnbrowse.py
index e3d7972..d95e7c8 100644
--- a/Mac/Demo/PICTbrowse/cicnbrowse.py
+++ b/Mac/Demo/PICTbrowse/cicnbrowse.py
@@ -27,137 +27,137 @@
 MAXHEIGHT=320
 
 def main():
-	macresource.need('DLOG', ID_MAIN, "PICTbrowse.rsrc")
-	CIconbrowse()
+    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
-		
+    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))
-		
+    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"
+    "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 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()
+    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()
diff --git a/Mac/Demo/PICTbrowse/oldPICTbrowse.py b/Mac/Demo/PICTbrowse/oldPICTbrowse.py
index 5f5893c..8600bb2 100644
--- a/Mac/Demo/PICTbrowse/oldPICTbrowse.py
+++ b/Mac/Demo/PICTbrowse/oldPICTbrowse.py
@@ -21,139 +21,139 @@
 TOP=64
 
 def main():
-	macresource.need('DLOG', ID_MAIN, "oldPICTbrowse.rsrc")
-	PICTbrowse()
+    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
-		
+    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()
-		
+    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"
+    "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 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()
+    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()
diff --git a/Mac/Demo/applescript/Disk_Copy/Special_Events.py b/Mac/Demo/applescript/Disk_Copy/Special_Events.py
index a98eb8a..a2b0910 100644
--- a/Mac/Demo/applescript/Disk_Copy/Special_Events.py
+++ b/Mac/Demo/applescript/Disk_Copy/Special_Events.py
@@ -12,385 +12,385 @@
 
 class Special_Events_Events:
 
-	_argmap_mount = {
-		'access_mode' : 'Acss',
-		'checksum_verification' : 'VChk',
-		'signature_verification' : 'VSig',
-		'RAM_caching' : 'Cach',
-	}
+    _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'
+    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.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)
+        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['----']
+        _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',
-	}
+    _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'
+    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.keysubst(_arguments, self._argmap_execute_DiskScript)
+        _arguments['----'] = _object
 
-		aetools.enumsubst(_arguments, 'VChk', _Enum_bool)
-		aetools.enumsubst(_arguments, 'VSig', _Enum_bool)
+        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['----']
+        _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'
+    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
+        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['----']
+        _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',
-	}
+    _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'
+    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.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)
+        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['----']
+        _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'
+    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
+        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['----']
+        _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'
+    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
+        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['----']
+        _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',
-	}
+    _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'
+    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.keysubst(_arguments, self._argmap_sign_image)
+        _arguments['----'] = _object
 
-		aetools.enumsubst(_arguments, 'Sinr', _Enum_alis)
+        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['----']
+        _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',
-	}
+    _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'
+    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.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)
+        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['----']
+        _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',
-	}
+    _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'
+    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.keysubst(_arguments, self._argmap_check_image)
+        _arguments['----'] = _object
 
-		aetools.enumsubst(_arguments, 'ChDe', _Enum_bool)
+        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['----']
+        _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',
-	}
+    _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'
+    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
+        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['----']
+        _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',
-	}
+    _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'
+    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.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)
+        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['----']
+        _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'
+    """Verify Checksum reply record -  """
+    want = 'Rcrc'
 class validity(aetools.NProperty):
-	"""validity - true if checksum is valid """
-	which = 'Vlid'
-	want = 'bool'
+    """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'
+    """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'
+    """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'
+    """Check Image reply record -  """
+    want = 'Rchk'
 class consistency(aetools.NProperty):
-	"""consistency - Does the image pass consistency checks? """
-	which = 'Rch1'
-	want = 'bool'
+    """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'
+    """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'
+    """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,
+        '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,
+        '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
+        '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
+        '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!!
@@ -402,23 +402,23 @@
 # Indices of types declared in this module
 #
 _classdeclarations = {
-	'Rchk' : Check_Image_reply_record,
-	'Rcrc' : Verify_Checksum_reply_record,
+        '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,
+        'crcE' : expected_checksum,
+        'Rch2' : error_count,
+        'crcA' : calculated_checksum,
+        'Rch3' : warning_count,
+        'Vlid' : validity,
+        'Rch1' : consistency,
 }
 
 _compdeclarations = {
 }
 
 _enumdeclarations = {
-	'Acss' : _Enum_Acss,
-	'Fsys' : _Enum_Fsys,
+        'Acss' : _Enum_Acss,
+        'Fsys' : _Enum_Fsys,
 }
diff --git a/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py b/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py
index 931246e..455e78d 100644
--- a/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py
+++ b/Mac/Demo/applescript/Disk_Copy/Standard_Suite.py
@@ -12,225 +12,225 @@
 
 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',
-	}
+    _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'
+    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.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)
+        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['----']
+        _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'
+    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
+        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['----']
+        _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'
+    """application - The Disk Copy application """
+    want = 'capp'
 class version(aetools.NProperty):
-	"""version - the version of this application """
-	which = 'vers'
-	want = 'vers'
+    """version - the version of this application """
+    which = 'vers'
+    want = 'vers'
 class name(aetools.NProperty):
-	"""name - the name of this application """
-	which = 'pnam'
-	want = 'TEXT'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """default image format - the default image file format """
+    which = 'Pdfm'
+    want = 'SvAs'
 
 class disk(aetools.ComponentItem):
-	"""disk - A mounted volume """
-	want = 'Disk'
+    """disk - A mounted volume """
+    want = 'Disk'
 
 name = name
 
 comment = comment
 class locked(aetools.NProperty):
-	"""locked - Is the disk locked? """
-	which = 'islk'
-	want = 'bool'
+    """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 '
+    """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 '
+    """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'
+    """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'
+    """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'
+    """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'
+    """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'
+    """folder - A folder or directory on a disk """
+    want = 'Fold'
 
 name = name
 
@@ -241,8 +241,8 @@
 modification_date = modification_date
 
 class disk_image(aetools.ComponentItem):
-	"""disk image - A disk image file """
-	want = 'DImg'
+    """disk image - A disk image file """
+    want = 'DImg'
 
 name = name
 
@@ -254,29 +254,29 @@
 
 modification_date = modification_date
 class file_format(aetools.NProperty):
-	"""file format - the format of the disk image file """
-	which = 'Ifmt'
-	want = 'TEXT'
+    """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'
+    """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'
+    """compressed - Is the disk image compressed? """
+    which = 'Icom'
+    want = 'bool'
 class segmented(aetools.NProperty):
-	"""segmented - Is the disk image segmented? """
-	which = 'Iseg'
-	want = 'bool'
+    """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 '
+    """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'
+    """disk name - the name of the disk this image represents """
+    which = 'Idnm'
+    want = 'TEXT'
 
 crc32_checksum = crc32_checksum
 
@@ -286,124 +286,124 @@
 
 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'
+    """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'
+    """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'
+    """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 '
+    """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'
+    """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,
+        '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,
+        '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,
+        '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,
+        '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,
+        '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
+        '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
+        '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
+        '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!!
@@ -414,64 +414,64 @@
 # Indices of types declared in this module
 #
 _classdeclarations = {
-	'DImg' : disk_image,
-	'capp' : application,
-	'Disk' : disk,
-	'Fold' : folder,
-	'cpyR' : Save_reply_record,
+        '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,
+        '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,
+        'SvAs' : _Enum_SvAs,
+        'UIAc' : _Enum_UIAc,
+        'rcpT' : _Enum_rcpT,
 }
diff --git a/Mac/Demo/applescript/Disk_Copy/Utility_Events.py b/Mac/Demo/applescript/Disk_Copy/Utility_Events.py
index edac8f4..172b408 100644
--- a/Mac/Demo/applescript/Disk_Copy/Utility_Events.py
+++ b/Mac/Demo/applescript/Disk_Copy/Utility_Events.py
@@ -12,187 +12,187 @@
 
 class Utility_Events_Events:
 
-	_argmap_select_disk_image = {
-		'with_prompt' : 'SELp',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_disk_image)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_DiskScript)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_disk_image_or_DiskScript)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_floppy_disk_image)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_disk)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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'
+    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 != None: raise TypeError, 'No direct arg expected'
+        aetools.keysubst(_arguments, self._argmap_select_folder)
+        if _no_object != None: raise TypeError, 'No direct arg expected'
 
-		aetools.enumsubst(_arguments, 'SELp', _Enum_TEXT)
+        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['----']
+        _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',
-	}
+    _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 '
+    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.keysubst(_arguments, self._argmap_log)
+        _arguments['----'] = _object
 
-		aetools.enumsubst(_arguments, 'TSMP', _Enum_bool)
+        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['----']
+        _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!!
diff --git a/Mac/Demo/applescript/Disk_Copy/__init__.py b/Mac/Demo/applescript/Disk_Copy/__init__.py
index b814056..ac50561 100644
--- a/Mac/Demo/applescript/Disk_Copy/__init__.py
+++ b/Mac/Demo/applescript/Disk_Copy/__init__.py
@@ -1,6 +1,6 @@
 """
 Package generated from Macintosh HD:Hulpprogramma's:Disk Copy
-Resource aete resid 0 
+Resource aete resid 0
 """
 import aetools
 Error = aetools.Error
@@ -10,17 +10,17 @@
 
 
 _code_to_module = {
-	'Core' : Standard_Suite,
-	'ddsk' : Special_Events,
-	'ddsk' : Utility_Events,
+        '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'),
+        '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 *
@@ -29,8 +29,7 @@
 
 
 class Disk_Copy(Standard_Suite_Events,
-		Special_Events_Events,
-		Utility_Events_Events,
-		aetools.TalkTo):
-	_signature = 'ddsk'
-
+                Special_Events_Events,
+                Utility_Events_Events,
+                aetools.TalkTo):
+    _signature = 'ddsk'
diff --git a/Mac/Demo/applescript/makedisk.py b/Mac/Demo/applescript/makedisk.py
index 3016964..91210ee 100644
--- a/Mac/Demo/applescript/makedisk.py
+++ b/Mac/Demo/applescript/makedisk.py
@@ -6,10 +6,10 @@
 talker.activate()
 filespec = macfs.FSSpec('my disk image.img')
 try:
-	objref = talker.create('my disk image', saving_as=filespec, leave_image_mounted=1)
+    objref = talker.create('my disk image', saving_as=filespec, leave_image_mounted=1)
 except Disk_Copy.Error, arg:
-	print "ERROR: my disk image:", arg
+    print "ERROR: my disk image:", arg
 else:
-	print 'objref=', objref
+    print 'objref=', objref
 print 'Type return to exit-'
 sys.stdin.readline()
diff --git a/Mac/Demo/calldll/testcalldll.py b/Mac/Demo/calldll/testcalldll.py
index d4a4853..e0f6964 100644
--- a/Mac/Demo/calldll/testcalldll.py
+++ b/Mac/Demo/calldll/testcalldll.py
@@ -8,16 +8,16 @@
 
 lib = calldll.getdiskfragment(fss, 'calldll.ppc.slb')
 
-cdll_b_bbbbbbbb = calldll.newcall(lib.cdll_b_bbbbbbbb, 'Byte', 'InByte', 'InByte', 
-				'InByte', 'InByte','InByte', 'InByte','InByte', 'InByte')
-cdll_h_hhhhhhhh = calldll.newcall(lib.cdll_h_hhhhhhhh, 'Short', 'InShort', 'InShort', 
-				'InShort', 'InShort','InShort', 'InShort','InShort', 'InShort')
-cdll_l_llllllll = calldll.newcall(lib.cdll_l_llllllll, 'Long', 'InLong', 'InLong', 
-				'InLong', 'InLong','InLong', 'InLong','InLong', 'InLong')
-				
+cdll_b_bbbbbbbb = calldll.newcall(lib.cdll_b_bbbbbbbb, 'Byte', 'InByte', 'InByte',
+                                'InByte', 'InByte','InByte', 'InByte','InByte', 'InByte')
+cdll_h_hhhhhhhh = calldll.newcall(lib.cdll_h_hhhhhhhh, 'Short', 'InShort', 'InShort',
+                                'InShort', 'InShort','InShort', 'InShort','InShort', 'InShort')
+cdll_l_llllllll = calldll.newcall(lib.cdll_l_llllllll, 'Long', 'InLong', 'InLong',
+                                'InLong', 'InLong','InLong', 'InLong','InLong', 'InLong')
+
 cdll_N_ssssssss = calldll.newcall(lib.cdll_N_ssssssss, 'None', 'InString', 'InString',
-				'InString', 'InString', 'InString', 'InString', 'InString', 'InString')
-				
+                                'InString', 'InString', 'InString', 'InString', 'InString', 'InString')
+
 cdll_o_l = calldll.newcall(lib.cdll_o_l, 'OSErr', 'InLong')
 
 cdll_N_pp = calldll.newcall(lib.cdll_N_pp, 'None', 'InPstring', 'OutPstring')
@@ -30,103 +30,103 @@
 print 'Test cdll_b_bbbbbbbb'
 rv = cdll_b_bbbbbbbb(1, 2, 3, 4, 5, 6, 7, 8)
 if rv == 36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_b_bbbbbbbb negative'
 rv = cdll_b_bbbbbbbb(-1, -2, -3, -4, -5, -6, -7, -8)
 if rv == -36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
+    print 'Failed, returned', rv
 
 print 'Test cdll_h_hhhhhhhh'
 rv = cdll_h_hhhhhhhh(1, 2, 3, 4, 5, 6, 7, 8)
 if rv == 36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_h_hhhhhhhh negative'
 rv = cdll_h_hhhhhhhh(-1, -2, -3, -4, -5, -6, -7, -8)
 if rv == -36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
+    print 'Failed, returned', rv
 
 print 'Test cdll_l_llllllll'
 rv = cdll_l_llllllll(1, 2, 3, 4, 5, 6, 7, 8)
 if rv == 36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_l_llllllll negative'
 rv = cdll_l_llllllll(-1, -2, -3, -4, -5, -6, -7, -8)
 if rv == -36:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_N_ssssssss'
 print 'Should print one two three four five six seven eight'
 rv = cdll_N_ssssssss('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight')
 if rv == None:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_o_l(0)'
 rv = cdll_o_l(0)
 if rv == None:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Error, returned', rv
-	
+    print 'Error, returned', rv
+
 print 'Test cdll_o_l(-100)'
 try:
-	rv = cdll_o_l(-100)
-	print 'Error, did not raise exception, returned', rv
+    rv = cdll_o_l(-100)
+    print 'Error, did not raise exception, returned', rv
 except MacOS.Error, arg:
-	if arg[0] == -100:
-		print 'ok.'
-	else:
-		print 'Error, returned incorrect exception arg:', arg[0]
-	
+    if arg[0] == -100:
+        print 'ok.'
+    else:
+        print 'Error, returned incorrect exception arg:', arg[0]
+
 print 'Test cdll_N_pp'
 rv = cdll_N_pp('pascal string')
 if rv == 'Was: pascal string':
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', repr(rv)
-	
+    print 'Failed, returned', repr(rv)
+
 print 'Test cdll_N_bb'
 rv = cdll_N_bb(-100)
 if rv == -100:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_N_hh'
 rv = cdll_N_hh(-100)
 if rv == -100:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
-	
+    print 'Failed, returned', rv
+
 print 'Test cdll_N_ll'
 rv = cdll_N_ll(-100)
 if rv == -100:
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, returned', rv
+    print 'Failed, returned', rv
 
 print 'Test cdll_N_sH'
 h = Res.Resource('xyz')
 rv = cdll_N_sH('new data', h)
 if rv == None and h.data == 'new data':
-	print 'ok.'
+    print 'ok.'
 else:
-	print 'Failed, rv is', rv, 'and handle data is', repr(rv.data)
+    print 'Failed, rv is', rv, 'and handle data is', repr(rv.data)
 sys.exit(1)
diff --git a/Mac/Demo/example0/checktext.py b/Mac/Demo/example0/checktext.py
index a5943a6..25f71e4 100644
--- a/Mac/Demo/example0/checktext.py
+++ b/Mac/Demo/example0/checktext.py
@@ -5,33 +5,31 @@
 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)
-	
+    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()
-	
-	
+    main()
diff --git a/Mac/Demo/example1/dnslookup-1.py b/Mac/Demo/example1/dnslookup-1.py
index 2aa7c88..2fb8dc4 100644
--- a/Mac/Demo/example1/dnslookup-1.py
+++ b/Mac/Demo/example1/dnslookup-1.py
@@ -32,7 +32,7 @@
             txt = Dlg.GetDialogItemText(h)
 
             tp, h, rect = my_dlg.GetDialogItem(ITEM_RESULT)
-            Dlg.SetDialogItemText(h, dnslookup(txt))        
+            Dlg.SetDialogItemText(h, dnslookup(txt))
         elif n == ITEM_QUIT_BUTTON:
             break
 
@@ -54,4 +54,3 @@
     return value
 
 main()
-
diff --git a/Mac/Demo/example2/dnslookup-2.py b/Mac/Demo/example2/dnslookup-2.py
index 9747c4a..92cd181 100644
--- a/Mac/Demo/example2/dnslookup-2.py
+++ b/Mac/Demo/example2/dnslookup-2.py
@@ -18,10 +18,10 @@
 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)
@@ -31,27 +31,27 @@
         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()
@@ -64,7 +64,7 @@
 
         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
diff --git a/Mac/Demo/imgbrowse/imgbrowse.py b/Mac/Demo/imgbrowse/imgbrowse.py
index 262c650..28dffd3 100644
--- a/Mac/Demo/imgbrowse/imgbrowse.py
+++ b/Mac/Demo/imgbrowse/imgbrowse.py
@@ -25,93 +25,93 @@
 
 
 def main():
-	print 'hello world'
-	imgbrowse()
+    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, 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 __init__(self):
+        # First init menus, etc.
+        FrameWork.Application.__init__(self)
+        self.lastwin = None
+        # Finally, go into the event loop
+        self.mainloop()
 
-	def info(self, *args):
-		if self.lastwin:
-			self.lastwin.info()		
-		
+    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, 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)
+    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()
diff --git a/Mac/Demo/imgbrowse/mac_image.py b/Mac/Demo/imgbrowse/mac_image.py
index 094c58e..9c9eeb7 100644
--- a/Mac/Demo/imgbrowse/mac_image.py
+++ b/Mac/Demo/imgbrowse/mac_image.py
@@ -6,51 +6,51 @@
 import MacOS
 
 _fmt_to_mac = {
-	imgformat.macrgb16 : (16, 16, 3, 5),
+        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)
+    """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]),
-		print
+    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]),
+        print
diff --git a/Mac/Demo/mlte/mlted.py b/Mac/Demo/mlte/mlted.py
index 381345a..323ea62 100644
--- a/Mac/Demo/mlte/mlted.py
+++ b/Mac/Demo/mlte/mlted.py
@@ -15,361 +15,360 @@
 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"]
-	
+        "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 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_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_idle(self, event):
+        self.ted.TXNIdle()
+        self.ted.TXNAdjustCursor(None)
 
-	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
+    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()
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
 
-	#
-	# Apple menu
-	#
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("A simple single-font text editor based on MacTextEditor")
-			
-	#
-	# File menu
-	#
+    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)
 
-	def open(self, *args):
-		self._open(0)
-		
-	def openfile(self, *args):
-		self._open(1)
+        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)
 
-	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, 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?")
+        # 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 clear(self, *args):
-		if self.active:
-			self.active.menu_clear()
-		else:
-			EasyDialogs.Message("No active window?")
-		
-	#
-	# Other stuff
-	#	
+    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()
 
-	def idle(self, event):
-		if self.active:
-			self.active.do_idle(event)
-		else:
-			Qd.SetCursor(Qd.GetQDGlobalsArrow())
+    #
+    # 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, 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()
-	
+    Mlte.TXNInitTextension(0)
+    try:
+        App = Mlted()
+        App.mainloop()
+    finally:
+        Mlte.TXNTerminateTextension()
+
 if __name__ == '__main__':
-	main()
-	
+    main()
diff --git a/Mac/Demo/quicktime/MovieInWindow.py b/Mac/Demo/quicktime/MovieInWindow.py
index ec4beae..00f596e 100644
--- a/Mac/Demo/quicktime/MovieInWindow.py
+++ b/Mac/Demo/quicktime/MovieInWindow.py
@@ -18,54 +18,53 @@
 
 
 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())
-	
+    # 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)
-			
+    """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
-	
+    """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()
-	
+    main()
diff --git a/Mac/Demo/quicktime/VerySimplePlayer.py b/Mac/Demo/quicktime/VerySimplePlayer.py
index de64e3f..2930eac 100644
--- a/Mac/Demo/quicktime/VerySimplePlayer.py
+++ b/Mac/Demo/quicktime/VerySimplePlayer.py
@@ -18,76 +18,75 @@
 # 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()
-			
+    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
-	
+    """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()
-	
+    main()
diff --git a/Mac/Demo/resources/copyres.py b/Mac/Demo/resources/copyres.py
index ae627ef..528ff16 100644
--- a/Mac/Demo/resources/copyres.py
+++ b/Mac/Demo/resources/copyres.py
@@ -7,51 +7,51 @@
 smAllScripts = -3
 
 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), 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)
+    """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), 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')
diff --git a/Mac/Demo/resources/listres.py b/Mac/Demo/resources/listres.py
index eacf2b7..6ce5779 100644
--- a/Mac/Demo/resources/listres.py
+++ b/Mac/Demo/resources/listres.py
@@ -4,57 +4,57 @@
 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)
+    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)
+    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())
+    print res.GetResInfo(), res.SizeResource(), decodeattrs(res.GetResAttrs())
 
 attrnames = {
-	resChanged:	'Changed',
-	resPreload:	'Preload',
-	resProtected:	'Protected',
-	resLocked:	'Locked',
-	resPurgeable:	'Purgeable',
-	resSysHeap:	'SysHeap',
+        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
+    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()
+    print "=== Local resourcess ==="
+    list1resources()
+    print "=== All resources ==="
+    listresources()
 
 if __name__ == '__main__':
-	test()
+    test()
diff --git a/Mac/Demo/sound/morse.py b/Mac/Demo/sound/morse.py
index bf5fa5f..b26d554 100644
--- a/Mac/Demo/sound/morse.py
+++ b/Mac/Demo/sound/morse.py
@@ -2,61 +2,61 @@
 
 DOT = 30
 DAH = 80
-OCTAVE = 2				# 1 == 441 Hz, 2 == 882 Hz, ...
+OCTAVE = 2                              # 1 == 441 Hz, 2 == 882 Hz, ...
 SAMPWIDTH = 2
 FRAMERATE = 44100
 BASEFREQ = 441
 QSIZE = 20000
 
 morsetab = {
-	'A': '.-',		'a': '.-',
-	'B': '-...',		'b': '-...',
-	'C': '-.-.',		'c': '-.-.',
-	'D': '-..',		'd': '-..',
-	'E': '.',		'e': '.',
-	'F': '..-.',		'f': '..-.',
-	'G': '--.',		'g': '--.',
-	'H': '....',		'h': '....',
-	'I': '..',		'i': '..',
-	'J': '.---',		'j': '.---',
-	'K': '-.-',		'k': '-.-',
-	'L': '.-..',		'l': '.-..',
-	'M': '--',		'm': '--',
-	'N': '-.',		'n': '-.',
-	'O': '---',		'o': '---',
-	'P': '.--.',		'p': '.--.',
-	'Q': '--.-',		'q': '--.-',
-	'R': '.-.',		'r': '.-.',
-	'S': '...',		's': '...',
-	'T': '-',		't': '-',
-	'U': '..-',		'u': '..-',
-	'V': '...-',		'v': '...-',
-	'W': '.--',		'w': '.--',
-	'X': '-..-',		'x': '-..-',
-	'Y': '-.--',		'y': '-.--',
-	'Z': '--..',		'z': '--..',
-	'0': '-----',
-	'1': '.----',
-	'2': '..---',
-	'3': '...--',
-	'4': '....-',
-	'5': '.....',
-	'6': '-....',
-	'7': '--...',
-	'8': '---..',
-	'9': '----.',
-	',': '--..--',
-	'.': '.-.-.-',
-	'?': '..--..',
-	';': '-.-.-.',
-	':': '---...',
-	"'": '.----.',
-	'-': '-....-',
-	'/': '-..-.',
-	'(': '-.--.-',
-	')': '-.--.-',
-	'_': '..--.-',
-	' ': ' '
+        'A': '.-',              'a': '.-',
+        'B': '-...',            'b': '-...',
+        'C': '-.-.',            'c': '-.-.',
+        'D': '-..',             'd': '-..',
+        'E': '.',               'e': '.',
+        'F': '..-.',            'f': '..-.',
+        'G': '--.',             'g': '--.',
+        'H': '....',            'h': '....',
+        'I': '..',              'i': '..',
+        'J': '.---',            'j': '.---',
+        'K': '-.-',             'k': '-.-',
+        'L': '.-..',            'l': '.-..',
+        'M': '--',              'm': '--',
+        'N': '-.',              'n': '-.',
+        'O': '---',             'o': '---',
+        'P': '.--.',            'p': '.--.',
+        'Q': '--.-',            'q': '--.-',
+        'R': '.-.',             'r': '.-.',
+        'S': '...',             's': '...',
+        'T': '-',               't': '-',
+        'U': '..-',             'u': '..-',
+        'V': '...-',            'v': '...-',
+        'W': '.--',             'w': '.--',
+        'X': '-..-',            'x': '-..-',
+        'Y': '-.--',            'y': '-.--',
+        'Z': '--..',            'z': '--..',
+        '0': '-----',
+        '1': '.----',
+        '2': '..---',
+        '3': '...--',
+        '4': '....-',
+        '5': '.....',
+        '6': '-....',
+        '7': '--...',
+        '8': '---..',
+        '9': '----.',
+        ',': '--..--',
+        '.': '.-.-.-',
+        '?': '..--..',
+        ';': '-.-.-.',
+        ':': '---...',
+        "'": '.----.',
+        '-': '-....-',
+        '/': '-..-.',
+        '(': '-.--.-',
+        ')': '-.--.-',
+        '_': '..--.-',
+        ' ': ' '
 }
 
 # If we play at 44.1 kHz (which we do), then if we produce one sine
@@ -64,117 +64,117 @@
 # sine waves in these 100 samples, we get a tone of 882 Hz.  882 Hz
 # appears to be a nice one for playing morse code.
 def mkwave(octave):
-	global sinewave, nowave
-	sinewave = ''
-	n = int(FRAMERATE / BASEFREQ)
-	for i in range(n):
-		val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
-		sample = chr((val >> 8) & 255) + chr(val & 255)
-		sinewave = sinewave + sample[:SAMPWIDTH]
-	nowave = '\0' * (n*SAMPWIDTH)
+    global sinewave, nowave
+    sinewave = ''
+    n = int(FRAMERATE / BASEFREQ)
+    for i in range(n):
+        val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
+        sample = chr((val >> 8) & 255) + chr(val & 255)
+        sinewave = sinewave + sample[:SAMPWIDTH]
+    nowave = '\0' * (n*SAMPWIDTH)
 
 mkwave(OCTAVE)
 
 class BufferedAudioDev:
-	def __init__(self, *args):
-		import audiodev
-		self._base = apply(audiodev.AudioDev, args)
-		self._buffer = []
-		self._filled = 0
-		self._addmethods(self._base, self._base.__class__)
-	def _addmethods(self, inst, cls):
-		for name in cls.__dict__.keys():
-			if not hasattr(self, name):
-				try:
-					setattr(self, name, getattr(inst, name))
-				except:
-					pass
-		for basecls in cls.__bases__:
-			self._addmethods(self, inst, basecls)
-	def writeframesraw(self, frames):
-		self._buffer.append(frames)
-		self._filled = self._filled + len(frames)
-		if self._filled >= QSIZE:
-			self.flush()
-	def wait(self):
-		self.flush()
-		self._base.wait()
-	def flush(self):
-		print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
-		if self._buffer:
-			import string
-			self._base.writeframes(string.joinfields(self._buffer, ''))
-			self._buffer = []
-			self._filled = 0
+    def __init__(self, *args):
+        import audiodev
+        self._base = apply(audiodev.AudioDev, args)
+        self._buffer = []
+        self._filled = 0
+        self._addmethods(self._base, self._base.__class__)
+    def _addmethods(self, inst, cls):
+        for name in cls.__dict__.keys():
+            if not hasattr(self, name):
+                try:
+                    setattr(self, name, getattr(inst, name))
+                except:
+                    pass
+        for basecls in cls.__bases__:
+            self._addmethods(self, inst, basecls)
+    def writeframesraw(self, frames):
+        self._buffer.append(frames)
+        self._filled = self._filled + len(frames)
+        if self._filled >= QSIZE:
+            self.flush()
+    def wait(self):
+        self.flush()
+        self._base.wait()
+    def flush(self):
+        print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
+        if self._buffer:
+            import string
+            self._base.writeframes(string.joinfields(self._buffer, ''))
+            self._buffer = []
+            self._filled = 0
 
 def main(args = sys.argv[1:]):
-	import getopt, string
-	try:
-		opts, args = getopt.getopt(args, 'o:p:')
-	except getopt.error:
-		sys.stderr.write('Usage ' + sys.argv[0] +
-				 ' [ -o outfile ] [ args ] ...\n')
-		sys.exit(1)
-	dev = None
-	for o, a in opts:
-		if o == '-o':
-			import aifc
-			dev = aifc.open(a, 'w')
-			dev.setframerate(FRAMERATE)
-			dev.setsampwidth(SAMPWIDTH)
-			dev.setnchannels(1)
-		if o == '-p':
-			mkwave(string.atoi(a))
-	if not dev:
-		dev = BufferedAudioDev()
-		dev.setoutrate(FRAMERATE)
-		dev.setsampwidth(SAMPWIDTH)
-		dev.setnchannels(1)
-		dev.close = dev.stop
-	if args:
-		line = string.join(args)
-	else:
-		line = sys.stdin.readline()
-	while line:
-		print line
-		mline = morse(line)
-		print mline
-		play(mline, dev)
-		if hasattr(dev, 'wait'):
-			dev.wait()
-		if not args:
-			line = sys.stdin.readline()
-		else:
-			line = ''
-	dev.close()
+    import getopt, string
+    try:
+        opts, args = getopt.getopt(args, 'o:p:')
+    except getopt.error:
+        sys.stderr.write('Usage ' + sys.argv[0] +
+                         ' [ -o outfile ] [ args ] ...\n')
+        sys.exit(1)
+    dev = None
+    for o, a in opts:
+        if o == '-o':
+            import aifc
+            dev = aifc.open(a, 'w')
+            dev.setframerate(FRAMERATE)
+            dev.setsampwidth(SAMPWIDTH)
+            dev.setnchannels(1)
+        if o == '-p':
+            mkwave(string.atoi(a))
+    if not dev:
+        dev = BufferedAudioDev()
+        dev.setoutrate(FRAMERATE)
+        dev.setsampwidth(SAMPWIDTH)
+        dev.setnchannels(1)
+        dev.close = dev.stop
+    if args:
+        line = string.join(args)
+    else:
+        line = sys.stdin.readline()
+    while line:
+        print line
+        mline = morse(line)
+        print mline
+        play(mline, dev)
+        if hasattr(dev, 'wait'):
+            dev.wait()
+        if not args:
+            line = sys.stdin.readline()
+        else:
+            line = ''
+    dev.close()
 
 # Convert a string to morse code with \001 between the characters in
 # the string.
 def morse(line):
-	res = ''
-	for c in line:
-		try:
-			res = res + morsetab[c] + '\001'
-		except KeyError:
-			pass
-	return res
+    res = ''
+    for c in line:
+        try:
+            res = res + morsetab[c] + '\001'
+        except KeyError:
+            pass
+    return res
 
 # Play a line of morse code.
 def play(line, dev):
-	for c in line:
-		if c == '.':
-			sine(dev, DOT)
-		elif c == '-':
-			sine(dev, DAH)
-		else:
-			pause(dev, DAH)
-		pause(dev, DOT)
+    for c in line:
+        if c == '.':
+            sine(dev, DOT)
+        elif c == '-':
+            sine(dev, DAH)
+        else:
+            pause(dev, DAH)
+        pause(dev, DOT)
 
 def sine(dev, length):
-	dev.writeframesraw(sinewave*length)
+    dev.writeframesraw(sinewave*length)
 
 def pause(dev, length):
-	dev.writeframesraw(nowave*length)
+    dev.writeframesraw(nowave*length)
 
 if __name__ == '__main__' or sys.argv[0] == __name__:
-	main()
+    main()
diff --git a/Mac/Demo/sound/morselib.py b/Mac/Demo/sound/morselib.py
index 6f8eed6..98e2590 100644
--- a/Mac/Demo/sound/morselib.py
+++ b/Mac/Demo/sound/morselib.py
@@ -10,179 +10,179 @@
 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 '(' ???
-	'_': '..--.-',
-	' ': ' '
+        '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):
-	from string import lower
-	m = ''
-	for c in s:
-		c = lower(c)
-		if morsetab.has_key(c):
-			c = morsetab[c] + ' '
-		else:
-			c = '? '
-		m = m + c
-	return m
+    from string import lower
+    m = ''
+    for c in s:
+        c = lower(c)
+        if morsetab.has_key(c):
+            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)
+    "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()
-		apply(Audio_mac.Play_Audio_mac._callback, (self,) + args)
+    def _callback(self, *args):
+        if hasattr(self, 'usercallback'): self.usercallback()
+        apply(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()
+    "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 test():
-	m = MacMorse()
-	while 1:
-		try:
-			line = raw_input('Morse line: ')
-		except (EOFError, KeyboardInterrupt):
-			break
-		m.send(line)
-		while m.morsequeue: pass
+    m = MacMorse()
+    while 1:
+        try:
+            line = raw_input('Morse line: ')
+        except (EOFError, KeyboardInterrupt):
+            break
+        m.send(line)
+        while m.morsequeue: pass
 
 test()
diff --git a/Mac/Demo/textedit/ped.py b/Mac/Demo/textedit/ped.py
index eee848b..3e91b32 100644
--- a/Mac/Demo/textedit/ped.py
+++ b/Mac/Demo/textedit/ped.py
@@ -15,346 +15,345 @@
 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 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_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_idle(self):
+        self.ted.TEIdle()
 
-	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)
+    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()
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
 
-	#
-	# Apple menu
-	#
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("A simple single-font text editor")
-			
-	#
-	# File menu
-	#
+    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)
 
-	def open(self, *args):
-		self._open(0)
-		
-	def openfile(self, *args):
-		self._open(1)
+        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)
 
-	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, 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?")
+        # Not yet implemented:
+        self.undoitem.enable(0)
 
-	def clear(self, *args):
-		if self.active:
-			self.active.menu_clear()
-		else:
-			EasyDialogs.Message("No active window?")
-		
-	#
-	# Other stuff
-	#	
+        # 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 idle(self, *args):
-		if self.active:
-			self.active.do_idle()
-		else:
-			Qd.SetCursor(Qd.GetQDGlobalsArrow())
+    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, 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()
-	
+    App = Ped()
+    App.mainloop()
+
 if __name__ == '__main__':
-	main()
-	
+    main()
diff --git a/Mac/Demo/waste/htmled.py b/Mac/Demo/waste/htmled.py
index 8710766..d8cea1b 100644
--- a/Mac/Demo/waste/htmled.py
+++ b/Mac/Demo/waste/htmled.py
@@ -23,809 +23,808 @@
 LEFTMARGIN=0
 
 UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
-	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
-	
+        None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
+
 # Style and size menu. Note that style order is important (tied to bit values)
 STYLES = [
-	("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
-	("Shadow", ""), ("Condensed", ""), ("Extended", "")
-	]
+        ("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
+        ("Shadow", ""), ("Condensed", ""), ("Extended", "")
+        ]
 SIZES = [ 9, 10, 12, 14, 18, 24]
 
 # Sizes for HTML tag types
 HTML_SIZE={
-	'h1': 18,
-	'h2': 14
+        'h1': 18,
+        'h2': 14
 }
-	
+
 BIGREGION=Qd.NewRgn()
 Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
 
 class WasteWindow(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
-		vr = LEFTMARGIN, 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)
-		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
-			WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
-		self.ted = waste.WENew(dr, vr, flags)
-		self.ted.WEInstallTabHooks()
-		style, soup = self.getstylesoup(self.path)
-		self.ted.WEInsert(data, style, soup)
-		self.ted.WESetSelection(0,0)
-		self.ted.WECalText()
-		self.ted.WEResetModCount()
-		w.DrawGrowIcon()
-		self.scrollbars()
-		self.do_postopen()
-		self.do_activate(1, None)
-		
-	def getstylesoup(self, pathname):
-		if not pathname:
-			return None, None
-		oldrf = Res.CurResFile()
-		try:
-			rf = Res.FSpOpenResFile(self.path, 1)
-		except Res.Error:
-			return None, None
-		try:
-			hstyle = Res.Get1Resource('styl', 128)
-			hstyle.DetachResource()
-		except Res.Error:
-			hstyle = None
-		try:
-			hsoup = Res.Get1Resource('SOUP', 128)
-			hsoup.DetachResource()
-		except Res.Error:
-			hsoup = None
-		Res.CloseResFile(rf)
-		Res.UseResFile(oldrf)
-		return hstyle, hsoup
-				
-	def do_idle(self, event):
-		(what, message, when, where, modifiers) = event
-		Qd.SetPort(self.wid)
-		self.ted.WEIdle()	
-		if self.ted.WEAdjustCursor(where, BIGREGION):
-			return
-		Qd.SetCursor(Qd.GetQDGlobalsArrow())
-		
-	def getscrollbarvalues(self):
-		dr = self.ted.WEGetDestRect()
-		vr = self.ted.WEGetViewRect()
-		vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
-		vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
-		return vx, vy
-		
-	def scrollbar_callback(self, which, what, value):
-		if which == 'y':
-			#
-			# "line" size is minimum of top and bottom line size
-			#
-			topline_off,dummy = self.ted.WEGetOffset((1,1))
-			topline_num = self.ted.WEOffsetToLine(topline_off)
-			toplineheight = self.ted.WEGetHeight(topline_num, topline_num+1)
+    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
+        vr = LEFTMARGIN, 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)
+        flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
+                WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
+        self.ted = waste.WENew(dr, vr, flags)
+        self.ted.WEInstallTabHooks()
+        style, soup = self.getstylesoup(self.path)
+        self.ted.WEInsert(data, style, soup)
+        self.ted.WESetSelection(0,0)
+        self.ted.WECalText()
+        self.ted.WEResetModCount()
+        w.DrawGrowIcon()
+        self.scrollbars()
+        self.do_postopen()
+        self.do_activate(1, None)
 
-			botlinepos = self.ted.WEGetViewRect()[3]			
-			botline_off, dummy = self.ted.WEGetOffset((1, botlinepos-1))
-			botline_num = self.ted.WEOffsetToLine(botline_off)
-			botlineheight = self.ted.WEGetHeight(botline_num, botline_num+1)
-			
-			if botlineheight == 0:
-				botlineheight = self.ted.WEGetHeight(botline_num-1, botline_num)
-			if botlineheight < toplineheight:
-				lineheight = botlineheight
-			else:
-				lineheight = toplineheight
-			if lineheight <= 0:
-				lineheight = 1
-			#
-			# Now do the command.
-			#
-			if what == 'set':
-				height = self.ted.WEGetHeight(0, 0x3fffffff)
-				cur = self.getscrollbarvalues()[1]
-				delta = (cur-value)*height/32767
-			if what == '-':
-				delta = lineheight
-			elif what == '--':
-				delta = (self.ted.WEGetViewRect()[3]-lineheight)
-				if delta <= 0:
-					delta = lineheight
-			elif what == '+':
-				delta = -lineheight
-			elif what == '++':
-				delta = -(self.ted.WEGetViewRect()[3]-lineheight)
-				if delta >= 0:
-					delta = -lineheight
-			self.ted.WEScroll(0, delta)
-		else:
-			if what == 'set':
-				return # XXXX
-			vr = self.ted.WEGetViewRect()
-			winwidth = vr[2]-vr[0]
-			if what == '-':
-				delta = winwidth/10
-			elif what == '--':
-				delta = winwidth/2
-			elif what == '+':
-				delta = -winwidth/10
-			elif what == '++':
-				delta = -winwidth/2
-			self.ted.WEScroll(delta, 0)
-		# Pin the scroll
-		l, t, r, b = self.ted.WEGetDestRect()
-		vl, vt, vr, vb = self.ted.WEGetViewRect()
-		if t > 0 or l > 0:
-			dx = dy = 0
-			if t > 0: dy = -t
-			if l > 0: dx = -l
-			self.ted.WEScroll(dx, dy)
-		elif b < vb:
-			self.ted.WEScroll(0, vb-b)
+    def getstylesoup(self, pathname):
+        if not pathname:
+            return None, None
+        oldrf = Res.CurResFile()
+        try:
+            rf = Res.FSpOpenResFile(self.path, 1)
+        except Res.Error:
+            return None, None
+        try:
+            hstyle = Res.Get1Resource('styl', 128)
+            hstyle.DetachResource()
+        except Res.Error:
+            hstyle = None
+        try:
+            hsoup = Res.Get1Resource('SOUP', 128)
+            hsoup.DetachResource()
+        except Res.Error:
+            hsoup = None
+        Res.CloseResFile(rf)
+        Res.UseResFile(oldrf)
+        return hstyle, hsoup
 
-		
-	def do_activate(self, onoff, evt):
-		Qd.SetPort(self.wid)
-		ScrolledWindow.do_activate(self, onoff, evt)
-		if onoff:
-			self.ted.WEActivate()
-			self.parent.active = self
-			self.parent.updatemenubar()
-		else:
-			self.ted.WEDeactivate()
+    def do_idle(self, event):
+        (what, message, when, where, modifiers) = event
+        Qd.SetPort(self.wid)
+        self.ted.WEIdle()
+        if self.ted.WEAdjustCursor(where, BIGREGION):
+            return
+        Qd.SetCursor(Qd.GetQDGlobalsArrow())
 
-	def do_update(self, wid, event):
-		region = wid.GetWindowPort().visRgn
-		if Qd.EmptyRgn(region):
-			return
-		Qd.EraseRgn(region)
-		self.ted.WEUpdate(region)
-		self.updatescrollbars()
-		
-	def do_postresize(self, width, height, window):
-		l, t, r, b = self.ted.WEGetViewRect()
-		vr = (l, t, l+width-15, t+height-15)
-		self.ted.WESetViewRect(vr)
-		self.wid.InvalWindowRect(vr)
-		ScrolledWindow.do_postresize(self, width, height, window)
-		
-	def do_contentclick(self, local, modifiers, evt):
-		(what, message, when, where, modifiers) = evt
-		self.ted.WEClick(local, modifiers, when)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
+    def getscrollbarvalues(self):
+        dr = self.ted.WEGetDestRect()
+        vr = self.ted.WEGetViewRect()
+        vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
+        vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
+        return vx, vy
 
-	def do_char(self, ch, event):
-		self.ted.WESelView()
-		(what, message, when, where, modifiers) = event
-		self.ted.WEKey(ord(ch), modifiers)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def close(self):
-		if self.ted.WEGetModCount():
-			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
-		#
-		# First save data
-		#
-		dhandle = self.ted.WEGetText()
-		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()
-		#
-		# Now save style and soup
-		#
-		oldresfile = Res.CurResFile()
-		try:
-			rf = Res.FSpOpenResFile(self.path, 3)
-		except Res.Error:
-			Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
-			rf = Res.FSpOpenResFile(self.path, 3)
-		styles = Res.Resource('')
-		soup = Res.Resource('')
-		self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
-		styles.AddResource('styl', 128, '')
-		soup.AddResource('SOUP', 128, '')
-		Res.CloseResFile(rf)
-		Res.UseResFile(oldresfile)
-		
-		self.ted.WEResetModCount()
-		
-	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_insert(self, fp):
-		self.ted.WESelView()
-		data = fp.read()
-		self.ted.WEInsert(data, None, None)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_insert_html(self, fp):
-		import htmllib
-		import formatter
-		f = formatter.AbstractFormatter(self)
-		
-		# Remember where we are, and don't update
-		Qd.SetCursor(WATCH)
-		start, dummy = self.ted.WEGetSelection()
-		self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
+    def scrollbar_callback(self, which, what, value):
+        if which == 'y':
+            #
+            # "line" size is minimum of top and bottom line size
+            #
+            topline_off,dummy = self.ted.WEGetOffset((1,1))
+            topline_num = self.ted.WEOffsetToLine(topline_off)
+            toplineheight = self.ted.WEGetHeight(topline_num, topline_num+1)
 
-		self.html_init()
-		p = MyHTMLParser(f)
-		p.feed(fp.read())
-		
-		# Restore updating, recalc, set focus
-		dummy, end = self.ted.WEGetSelection()
-		self.ted.WECalText()
-		self.ted.WESetSelection(start, end)
-		self.ted.WESelView()
-		self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
-		self.wid.InvalWindowRect(self.ted.WEGetViewRect())
+            botlinepos = self.ted.WEGetViewRect()[3]
+            botline_off, dummy = self.ted.WEGetOffset((1, botlinepos-1))
+            botline_num = self.ted.WEOffsetToLine(botline_off)
+            botlineheight = self.ted.WEGetHeight(botline_num, botline_num+1)
 
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_cut(self):
-		self.ted.WESelView()
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECut()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_copy(self):
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECopy()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_paste(self):
-		self.ted.WESelView()
-		self.ted.WEPaste()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_clear(self):
-		self.ted.WESelView()
-		self.ted.WEDelete()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
+            if botlineheight == 0:
+                botlineheight = self.ted.WEGetHeight(botline_num-1, botline_num)
+            if botlineheight < toplineheight:
+                lineheight = botlineheight
+            else:
+                lineheight = toplineheight
+            if lineheight <= 0:
+                lineheight = 1
+            #
+            # Now do the command.
+            #
+            if what == 'set':
+                height = self.ted.WEGetHeight(0, 0x3fffffff)
+                cur = self.getscrollbarvalues()[1]
+                delta = (cur-value)*height/32767
+            if what == '-':
+                delta = lineheight
+            elif what == '--':
+                delta = (self.ted.WEGetViewRect()[3]-lineheight)
+                if delta <= 0:
+                    delta = lineheight
+            elif what == '+':
+                delta = -lineheight
+            elif what == '++':
+                delta = -(self.ted.WEGetViewRect()[3]-lineheight)
+                if delta >= 0:
+                    delta = -lineheight
+            self.ted.WEScroll(0, delta)
+        else:
+            if what == 'set':
+                return # XXXX
+            vr = self.ted.WEGetViewRect()
+            winwidth = vr[2]-vr[0]
+            if what == '-':
+                delta = winwidth/10
+            elif what == '--':
+                delta = winwidth/2
+            elif what == '+':
+                delta = -winwidth/10
+            elif what == '++':
+                delta = -winwidth/2
+            self.ted.WEScroll(delta, 0)
+        # Pin the scroll
+        l, t, r, b = self.ted.WEGetDestRect()
+        vl, vt, vr, vb = self.ted.WEGetViewRect()
+        if t > 0 or l > 0:
+            dx = dy = 0
+            if t > 0: dy = -t
+            if l > 0: dx = -l
+            self.ted.WEScroll(dx, dy)
+        elif b < vb:
+            self.ted.WEScroll(0, vb-b)
 
-	def menu_undo(self):
-		self.ted.WEUndo()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_setfont(self, font):
-		font = Fm.GetFNum(font)
-		self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
-		self.parent.updatemenubar()
-				
-	def menu_modface(self, face):
-		self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace, 
-			(0, face, 0, (0,0,0)))
 
-	def menu_setface(self, face):
-		self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace, 
-			(0, face, 0, (0,0,0)))
+    def do_activate(self, onoff, evt):
+        Qd.SetPort(self.wid)
+        ScrolledWindow.do_activate(self, onoff, evt)
+        if onoff:
+            self.ted.WEActivate()
+            self.parent.active = self
+            self.parent.updatemenubar()
+        else:
+            self.ted.WEDeactivate()
 
-	def menu_setsize(self, size):
-		self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
-								
-	def menu_incsize(self, size):
-		self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
+    def do_update(self, wid, event):
+        region = wid.GetWindowPort().visRgn
+        if Qd.EmptyRgn(region):
+            return
+        Qd.EraseRgn(region)
+        self.ted.WEUpdate(region)
+        self.updatescrollbars()
 
-	def mysetstyle(self, which, how):
-		self.ted.WESelView()
-		self.ted.WESetStyle(which, how)
-		self.parent.updatemenubar()
-								
-	def have_selection(self):
-		start, stop = self.ted.WEGetSelection()
-		return start < stop
-		
-	def can_paste(self):
-		return self.ted.WECanPaste()
-		
-	def can_undo(self):
-		which, redo = self.ted.WEGetUndoInfo()
-		which = UNDOLABELS[which]
-		if which == None: return None
-		if redo:
-			return "Redo "+which
-		else:
-			return "Undo "+which
-			
-	def getruninfo(self):
-		all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
-		dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
-		if not (mode & WASTEconst.weDoFont):
-			font = None
-		else:
-			font = Fm.GetFontName(font)
-		if not (mode & WASTEconst.weDoFace): fact = None
-		if not (mode & WASTEconst.weDoSize): size = None
-		return font, face, size
-		
-	#
-	# Methods for writer class for html formatter
-	#
-	
-	def html_init(self):
-		self.html_font = [12, 0, 0, 0]
-		self.html_style = 0
-		self.html_color = (0,0,0)
-		self.new_font(self.html_font)
-	
-	def new_font(self, font):
-		if font == None:
-			font = (12, 0, 0, 0)
-		font = map(lambda x:x, font)
-		for i in range(len(font)):
-			if font[i] == None:
-				font[i] = self.html_font[i]
-		[size, italic, bold, tt] = font
-		self.html_font = font[:]
-		if tt:
-			font = Fm.GetFNum('Courier')
-		else:
-			font = Fm.GetFNum('Times')
-		if HTML_SIZE.has_key(size):
-			size = HTML_SIZE[size]
-		else:
-			size = 12
-		face = 0
-		if bold: face = face | 1
-		if italic: face = face | 2
-		face = face | self.html_style
-		self.ted.WESetStyle(WASTEconst.weDoFont | WASTEconst.weDoFace | 
-				WASTEconst.weDoSize | WASTEconst.weDoColor,
-				(font, face, size, self.html_color))
-		
-	def new_margin(self, margin, level):
-		self.ted.WEInsert('[Margin %s %s]'%(margin, level), None, None)
-		
-	def new_spacing(self, spacing):
-		self.ted.WEInsert('[spacing %s]'%spacing, None, None)
-			
-	def new_styles(self, styles):
-		self.html_style = 0
-		self.html_color = (0,0,0)
-		if 'anchor' in styles:
-			self.html_style = self.html_style | 4
-			self.html_color = (0xffff, 0, 0)
-		self.new_font(self.html_font)
+    def do_postresize(self, width, height, window):
+        l, t, r, b = self.ted.WEGetViewRect()
+        vr = (l, t, l+width-15, t+height-15)
+        self.ted.WESetViewRect(vr)
+        self.wid.InvalWindowRect(vr)
+        ScrolledWindow.do_postresize(self, width, height, window)
 
-	def send_paragraph(self, blankline):
-		self.ted.WEInsert('\r'*(blankline+1), None, None)
-		
-	def send_line_break(self):
-		self.ted.WEInsert('\r', None, None)
-		
-	def send_hor_rule(self, *args, **kw):
-		# Ignore ruler options, for now
-		dummydata = Res.Resource('')
-		self.ted.WEInsertObject('rulr', dummydata, (0,0))
-		
-	def send_label_data(self, data):
-		self.ted.WEInsert(data, None, None)
-		
-	def send_flowing_data(self, data):
-		self.ted.WEInsert(data, None, None)
-		
-	def send_literal_data(self, data):
-		data = string.replace(data, '\n', '\r')
-		data = string.expandtabs(data)
-		self.ted.WEInsert(data, None, None)
-		
+    def do_contentclick(self, local, modifiers, evt):
+        (what, message, when, where, modifiers) = evt
+        self.ted.WEClick(local, modifiers, when)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def do_char(self, ch, event):
+        self.ted.WESelView()
+        (what, message, when, where, modifiers) = event
+        self.ted.WEKey(ord(ch), modifiers)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def close(self):
+        if self.ted.WEGetModCount():
+            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
+        #
+        # First save data
+        #
+        dhandle = self.ted.WEGetText()
+        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()
+        #
+        # Now save style and soup
+        #
+        oldresfile = Res.CurResFile()
+        try:
+            rf = Res.FSpOpenResFile(self.path, 3)
+        except Res.Error:
+            Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
+            rf = Res.FSpOpenResFile(self.path, 3)
+        styles = Res.Resource('')
+        soup = Res.Resource('')
+        self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
+        styles.AddResource('styl', 128, '')
+        soup.AddResource('SOUP', 128, '')
+        Res.CloseResFile(rf)
+        Res.UseResFile(oldresfile)
+
+        self.ted.WEResetModCount()
+
+    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_insert(self, fp):
+        self.ted.WESelView()
+        data = fp.read()
+        self.ted.WEInsert(data, None, None)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_insert_html(self, fp):
+        import htmllib
+        import formatter
+        f = formatter.AbstractFormatter(self)
+
+        # Remember where we are, and don't update
+        Qd.SetCursor(WATCH)
+        start, dummy = self.ted.WEGetSelection()
+        self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
+
+        self.html_init()
+        p = MyHTMLParser(f)
+        p.feed(fp.read())
+
+        # Restore updating, recalc, set focus
+        dummy, end = self.ted.WEGetSelection()
+        self.ted.WECalText()
+        self.ted.WESetSelection(start, end)
+        self.ted.WESelView()
+        self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
+        self.wid.InvalWindowRect(self.ted.WEGetViewRect())
+
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_cut(self):
+        self.ted.WESelView()
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECut()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_copy(self):
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECopy()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_paste(self):
+        self.ted.WESelView()
+        self.ted.WEPaste()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_clear(self):
+        self.ted.WESelView()
+        self.ted.WEDelete()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_undo(self):
+        self.ted.WEUndo()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_setfont(self, font):
+        font = Fm.GetFNum(font)
+        self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
+        self.parent.updatemenubar()
+
+    def menu_modface(self, face):
+        self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace,
+                (0, face, 0, (0,0,0)))
+
+    def menu_setface(self, face):
+        self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace,
+                (0, face, 0, (0,0,0)))
+
+    def menu_setsize(self, size):
+        self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
+
+    def menu_incsize(self, size):
+        self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
+
+    def mysetstyle(self, which, how):
+        self.ted.WESelView()
+        self.ted.WESetStyle(which, how)
+        self.parent.updatemenubar()
+
+    def have_selection(self):
+        start, stop = self.ted.WEGetSelection()
+        return start < stop
+
+    def can_paste(self):
+        return self.ted.WECanPaste()
+
+    def can_undo(self):
+        which, redo = self.ted.WEGetUndoInfo()
+        which = UNDOLABELS[which]
+        if which == None: return None
+        if redo:
+            return "Redo "+which
+        else:
+            return "Undo "+which
+
+    def getruninfo(self):
+        all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
+        dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
+        if not (mode & WASTEconst.weDoFont):
+            font = None
+        else:
+            font = Fm.GetFontName(font)
+        if not (mode & WASTEconst.weDoFace): fact = None
+        if not (mode & WASTEconst.weDoSize): size = None
+        return font, face, size
+
+    #
+    # Methods for writer class for html formatter
+    #
+
+    def html_init(self):
+        self.html_font = [12, 0, 0, 0]
+        self.html_style = 0
+        self.html_color = (0,0,0)
+        self.new_font(self.html_font)
+
+    def new_font(self, font):
+        if font == None:
+            font = (12, 0, 0, 0)
+        font = map(lambda x:x, font)
+        for i in range(len(font)):
+            if font[i] == None:
+                font[i] = self.html_font[i]
+        [size, italic, bold, tt] = font
+        self.html_font = font[:]
+        if tt:
+            font = Fm.GetFNum('Courier')
+        else:
+            font = Fm.GetFNum('Times')
+        if HTML_SIZE.has_key(size):
+            size = HTML_SIZE[size]
+        else:
+            size = 12
+        face = 0
+        if bold: face = face | 1
+        if italic: face = face | 2
+        face = face | self.html_style
+        self.ted.WESetStyle(WASTEconst.weDoFont | WASTEconst.weDoFace |
+                        WASTEconst.weDoSize | WASTEconst.weDoColor,
+                        (font, face, size, self.html_color))
+
+    def new_margin(self, margin, level):
+        self.ted.WEInsert('[Margin %s %s]'%(margin, level), None, None)
+
+    def new_spacing(self, spacing):
+        self.ted.WEInsert('[spacing %s]'%spacing, None, None)
+
+    def new_styles(self, styles):
+        self.html_style = 0
+        self.html_color = (0,0,0)
+        if 'anchor' in styles:
+            self.html_style = self.html_style | 4
+            self.html_color = (0xffff, 0, 0)
+        self.new_font(self.html_font)
+
+    def send_paragraph(self, blankline):
+        self.ted.WEInsert('\r'*(blankline+1), None, None)
+
+    def send_line_break(self):
+        self.ted.WEInsert('\r', None, None)
+
+    def send_hor_rule(self, *args, **kw):
+        # Ignore ruler options, for now
+        dummydata = Res.Resource('')
+        self.ted.WEInsertObject('rulr', dummydata, (0,0))
+
+    def send_label_data(self, data):
+        self.ted.WEInsert(data, None, None)
+
+    def send_flowing_data(self, data):
+        self.ted.WEInsert(data, None, None)
+
+    def send_literal_data(self, data):
+        data = string.replace(data, '\n', '\r')
+        data = string.expandtabs(data)
+        self.ted.WEInsert(data, None, None)
+
 class Wed(Application):
-	def __init__(self):
-		Application.__init__(self)
-		self.num = 0
-		self.active = None
-		self.updatemenubar()
-		waste.STDObjectHandlers()
-		# Handler for horizontal ruler
-		waste.WEInstallObjectHandler('rulr', 'new ', self.newRuler)
-		waste.WEInstallObjectHandler('rulr', 'draw', self.drawRuler)
-		
-	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.insertitem = MenuItem(m, "Insert plaintext...", "", self.insertfile)
-		self.htmlitem = MenuItem(m, "Insert HTML...", "", self.inserthtml)
-		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)
-		
-		self.makefontmenu()
-		
-		# Groups of items enabled together:
-		self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
-			self.editmenu, self.fontmenu, self.facemenu, self.sizemenu,
-			self.insertitem]
-		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.ffs_values = ()
-		
-	def makefontmenu(self):
-		self.fontmenu = Menu(self.menubar, "Font")
-		self.fontnames = getfontnames()
-		self.fontitems = []
-		for n in self.fontnames:
-			m = MenuItem(self.fontmenu, n, "", self.selfont)
-			self.fontitems.append(m)
-		self.facemenu = Menu(self.menubar, "Style")
-		self.faceitems = []
-		for n, shortcut in STYLES:
-			m = MenuItem(self.facemenu, n, shortcut, self.selface)
-			self.faceitems.append(m)
-		self.facemenu.addseparator()
-		self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N", 
-			self.selfacenormal)
-		self.sizemenu = Menu(self.menubar, "Size")
-		self.sizeitems = []
-		for n in SIZES:
-			m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
-			self.sizeitems.append(m)
-		self.sizemenu.addseparator()
-		self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+", 
-			self.selsizebigger)
-		self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-", 
-			self.selsizesmaller)
-					
-	def selfont(self, id, item, *rest):
-		if self.active:
-			font = self.fontnames[item-1]
-			self.active.menu_setfont(font)
-		else:
-			EasyDialogs.Message("No active window?")
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
+        waste.STDObjectHandlers()
+        # Handler for horizontal ruler
+        waste.WEInstallObjectHandler('rulr', 'new ', self.newRuler)
+        waste.WEInstallObjectHandler('rulr', 'draw', self.drawRuler)
 
-	def selface(self, id, item, *rest):
-		if self.active:
-			face = (1<<(item-1))
-			self.active.menu_modface(face)
-		else:
-			EasyDialogs.Message("No active window?")
+    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.insertitem = MenuItem(m, "Insert plaintext...", "", self.insertfile)
+        self.htmlitem = MenuItem(m, "Insert HTML...", "", self.inserthtml)
+        m.addseparator()
+        self.quititem = MenuItem(m, "Quit", "Q", self.quit)
 
-	def selfacenormal(self, *rest):
-		if self.active:
-			self.active.menu_setface(0)
-		else:
-			EasyDialogs.Message("No active window?")
+        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)
 
-	def selsize(self, id, item, *rest):
-		if self.active:
-			size = SIZES[item-1]
-			self.active.menu_setsize(size)
-		else:
-			EasyDialogs.Message("No active window?")
+        self.makefontmenu()
 
-	def selsizebigger(self, *rest):
-		if self.active:
-			self.active.menu_incsize(2)
-		else:
-			EasyDialogs.Message("No active window?")
+        # Groups of items enabled together:
+        self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
+                self.editmenu, self.fontmenu, self.facemenu, self.sizemenu,
+                self.insertitem]
+        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.ffs_values = ()
 
-	def selsizesmaller(self, *rest):
-		if self.active:
-			self.active.menu_incsize(-2)
-		else:
-			EasyDialogs.Message("No active window?")
+    def makefontmenu(self):
+        self.fontmenu = Menu(self.menubar, "Font")
+        self.fontnames = getfontnames()
+        self.fontitems = []
+        for n in self.fontnames:
+            m = MenuItem(self.fontmenu, n, "", self.selfont)
+            self.fontitems.append(m)
+        self.facemenu = Menu(self.menubar, "Style")
+        self.faceitems = []
+        for n, shortcut in STYLES:
+            m = MenuItem(self.facemenu, n, shortcut, self.selface)
+            self.faceitems.append(m)
+        self.facemenu.addseparator()
+        self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N",
+                self.selfacenormal)
+        self.sizemenu = Menu(self.menubar, "Size")
+        self.sizeitems = []
+        for n in SIZES:
+            m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
+            self.sizeitems.append(m)
+        self.sizemenu.addseparator()
+        self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+",
+                self.selsizebigger)
+        self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-",
+                self.selsizesmaller)
 
-	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
-			if self.updatefontmenus():
-				changed = 1
-		if changed:
-			DrawMenuBar()
-			
-	def updatefontmenus(self):
-		info = self.active.getruninfo()
-		if info == self.ffs_values:
-			return 0
-		# Remove old checkmarks
-		if self.ffs_values == ():
-			self.ffs_values = (None, None, None)
-		font, face, size = self.ffs_values
-		if font <> None:
-			fnum = self.fontnames.index(font)
-			self.fontitems[fnum].check(0)
-		if face <> None:
-			for i in range(len(self.faceitems)):
-				if face & (1<<i):
-					self.faceitems[i].check(0)
-		if size <> None:
-			for i in range(len(self.sizeitems)):
-				if SIZES[i] == size:
-					self.sizeitems[i].check(0)
-				
-		self.ffs_values = info
-		# Set new checkmarks
-		font, face, size = self.ffs_values
-		if font <> None:
-			fnum = self.fontnames.index(font)
-			self.fontitems[fnum].check(1)
-		if face <> None:
-			for i in range(len(self.faceitems)):
-				if face & (1<<i):
-					self.faceitems[i].check(1)
-		if size <> None:
-			for i in range(len(self.sizeitems)):
-				if SIZES[i] == size:
-					self.sizeitems[i].check(1)
-		# Set outline/normal for sizes
-		if font:
-			exists = getfontsizes(font, SIZES)
-			for i in range(len(self.sizeitems)):
-				if exists[i]:
-					self.sizeitems[i].setstyle(0)
-				else:
-					self.sizeitems[i].setstyle(8)
+    def selfont(self, id, item, *rest):
+        if self.active:
+            font = self.fontnames[item-1]
+            self.active.menu_setfont(font)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	#
-	# Apple menu
-	#
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("A simple single-font text editor based on WASTE")
-			
-	#
-	# File menu
-	#
+    def selface(self, id, item, *rest):
+        if self.active:
+            face = (1<<(item-1))
+            self.active.menu_modface(face)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	def open(self, *args):
-		self._open(0)
-		
-	def openfile(self, *args):
-		self._open(1)
+    def selfacenormal(self, *rest):
+        if self.active:
+            self.active.menu_setface(0)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	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, arg:
-				EasyDialogs.Message("IOERROR: %r" % (arg,))
-				return
-		else:
-			path = None
-			name = "Untitled %d"%self.num
-			data = ''
-		w = WasteWindow(self)
-		w.open(path, name, data)
-		self.num = self.num + 1
+    def selsize(self, id, item, *rest):
+        if self.active:
+            size = SIZES[item-1]
+            self.active.menu_setsize(size)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	def insertfile(self, *args):
-		if self.active:
-			path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
-			if not path:
-				return
-			try:
-				fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
-			except IOError, arg:
-				EasyDialogs.Message("IOERROR: %r" % (args,))
-				return
-			self.active.menu_insert(fp)
-		else:
-			EasyDialogs.Message("No active window?")
+    def selsizebigger(self, *rest):
+        if self.active:
+            self.active.menu_incsize(2)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	def inserthtml(self, *args):
-		if self.active:
-			path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
-			if not path:
-				return
-			try:
-				fp = open(path, 'r')
-			except IOError, arg:
-				EasyDialogs.Message("IOERROR: %r" % (arg,))
-				return
-			self.active.menu_insert_html(fp)
-		else:
-			EasyDialogs.Message("No active window?")
+    def selsizesmaller(self, *rest):
+        if self.active:
+            self.active.menu_incsize(-2)
+        else:
+            EasyDialogs.Message("No active window?")
 
-		
-	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 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 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
+            if self.updatefontmenus():
+                changed = 1
+        if changed:
+            DrawMenuBar()
 
-	def clear(self, *args):
-		if self.active:
-			self.active.menu_clear()
-		else:
-			EasyDialogs.Message("No active window?")
-		
-	#
-	# Other stuff
-	#	
+    def updatefontmenus(self):
+        info = self.active.getruninfo()
+        if info == self.ffs_values:
+            return 0
+        # Remove old checkmarks
+        if self.ffs_values == ():
+            self.ffs_values = (None, None, None)
+        font, face, size = self.ffs_values
+        if font <> None:
+            fnum = self.fontnames.index(font)
+            self.fontitems[fnum].check(0)
+        if face <> None:
+            for i in range(len(self.faceitems)):
+                if face & (1<<i):
+                    self.faceitems[i].check(0)
+        if size <> None:
+            for i in range(len(self.sizeitems)):
+                if SIZES[i] == size:
+                    self.sizeitems[i].check(0)
 
-	def idle(self, event):
-		if self.active:
-			self.active.do_idle(event)
-		else:
-			Qd.SetCursor(Qd.GetQDGlobalsArrow())
-			
-	def newRuler(self, obj):
-		"""Insert a new ruler. Make it as wide as the window minus 2 pxls"""
-		ted = obj.WEGetObjectOwner()
-		l, t, r, b = ted.WEGetDestRect()
-		return r-l, 4
-		
-	def drawRuler(self, (l, t, r, b), obj):
-		y = (t+b)/2
-		Qd.MoveTo(l+2, y)
-		Qd.LineTo(r-2, y)
-		return 0
-			
+        self.ffs_values = info
+        # Set new checkmarks
+        font, face, size = self.ffs_values
+        if font <> None:
+            fnum = self.fontnames.index(font)
+            self.fontitems[fnum].check(1)
+        if face <> None:
+            for i in range(len(self.faceitems)):
+                if face & (1<<i):
+                    self.faceitems[i].check(1)
+        if size <> None:
+            for i in range(len(self.sizeitems)):
+                if SIZES[i] == size:
+                    self.sizeitems[i].check(1)
+        # Set outline/normal for sizes
+        if font:
+            exists = getfontsizes(font, SIZES)
+            for i in range(len(self.sizeitems)):
+                if exists[i]:
+                    self.sizeitems[i].setstyle(0)
+                else:
+                    self.sizeitems[i].setstyle(8)
+
+    #
+    # Apple menu
+    #
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("A simple single-font text editor based on WASTE")
+
+    #
+    # 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, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+        else:
+            path = None
+            name = "Untitled %d"%self.num
+            data = ''
+        w = WasteWindow(self)
+        w.open(path, name, data)
+        self.num = self.num + 1
+
+    def insertfile(self, *args):
+        if self.active:
+            path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
+            if not path:
+                return
+            try:
+                fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
+            except IOError, arg:
+                EasyDialogs.Message("IOERROR: %r" % (args,))
+                return
+            self.active.menu_insert(fp)
+        else:
+            EasyDialogs.Message("No active window?")
+
+    def inserthtml(self, *args):
+        if self.active:
+            path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
+            if not path:
+                return
+            try:
+                fp = open(path, 'r')
+            except IOError, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+            self.active.menu_insert_html(fp)
+        else:
+            EasyDialogs.Message("No active window?")
+
+
+    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 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 newRuler(self, obj):
+        """Insert a new ruler. Make it as wide as the window minus 2 pxls"""
+        ted = obj.WEGetObjectOwner()
+        l, t, r, b = ted.WEGetDestRect()
+        return r-l, 4
+
+    def drawRuler(self, (l, t, r, b), obj):
+        y = (t+b)/2
+        Qd.MoveTo(l+2, y)
+        Qd.LineTo(r-2, y)
+        return 0
+
 class MyHTMLParser(htmllib.HTMLParser):
-	
+
     def anchor_bgn(self, href, name, type):
-	    self.anchor = href
-	    if self.anchor:
-		    self.anchorlist.append(href)
-		    self.formatter.push_style('anchor')
+        self.anchor = href
+        if self.anchor:
+            self.anchorlist.append(href)
+            self.formatter.push_style('anchor')
 
     def anchor_end(self):
-	    if self.anchor:
-		    self.anchor = None
-		    self.formatter.pop_style()
+        if self.anchor:
+            self.anchor = None
+            self.formatter.pop_style()
 
-			
+
 def getfontnames():
-	names = []
-	for i in range(256):
-		n = Fm.GetFontName(i)
-		if n: names.append(n)
-	return names
-	
+    names = []
+    for i in range(256):
+        n = Fm.GetFontName(i)
+        if n: names.append(n)
+    return names
+
 def getfontsizes(name, sizes):
-	exist = []
-	num = Fm.GetFNum(name)
-	for sz in sizes:
-		if Fm.RealFont(num, sz):
-			exist.append(1)
-		else:
-			exist.append(0)
-	return exist
+    exist = []
+    num = Fm.GetFNum(name)
+    for sz in sizes:
+        if Fm.RealFont(num, sz):
+            exist.append(1)
+        else:
+            exist.append(0)
+    return exist
 
 def main():
-	App = Wed()
-	App.mainloop()
-	
+    App = Wed()
+    App.mainloop()
+
 if __name__ == '__main__':
-	main()
-	
+    main()
diff --git a/Mac/Demo/waste/swed.py b/Mac/Demo/waste/swed.py
index ca77293..2078cce 100644
--- a/Mac/Demo/waste/swed.py
+++ b/Mac/Demo/waste/swed.py
@@ -16,620 +16,619 @@
 import macfs
 
 UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
-	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
-	
+        None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
+
 # Style and size menu. Note that style order is important (tied to bit values)
 STYLES = [
-	("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
-	("Shadow", ""), ("Condensed", ""), ("Extended", "")
-	]
+        ("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
+        ("Shadow", ""), ("Condensed", ""), ("Extended", "")
+        ]
 SIZES = [ 9, 10, 12, 14, 18, 24]
-	
+
 BIGREGION=Qd.NewRgn()
 Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
 
 class WasteWindow(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
-		vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
-		dr = (0, 0, 10240, 0)
-		Qd.SetPort(w)
-		Qd.TextFont(4)
-		Qd.TextSize(9)
-		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
-				WASTEconst.weDoUndo
-		self.ted = waste.WENew(dr, vr, flags)
-		self.ted.WEInstallTabHooks()
-		style, soup = self.getstylesoup()
-		self.ted.WEInsert(data, style, soup)
-		self.ted.WESetSelection(0,0)
-		self.ted.WECalText()
-		self.ted.WEResetModCount()
-		w.DrawGrowIcon()
-		self.scrollbars()
-		self.do_postopen()
-		self.do_activate(1, None)
-		
-	def getstylesoup(self):
-		if not self.path:
-			return None, None
-		oldrf = Res.CurResFile()
-		try:
-			rf = Res.FSpOpenResFile(self.path, 1)
-		except Res.Error:
-			return None, None
-		try:
-			hstyle = Res.Get1Resource('styl', 128)
-			hstyle.DetachResource()
-		except Res.Error:
-			hstyle = None
-		try:
-			hsoup = Res.Get1Resource('SOUP', 128)
-			hsoup.DetachResource()
-		except Res.Error:
-			hsoup = None
-		Res.CloseResFile(rf)
-		Res.UseResFile(oldrf)
-		return hstyle, hsoup
-				
-	def do_idle(self, event):
-		(what, message, when, where, modifiers) = event
-		Qd.SetPort(self.wid)
-		self.ted.WEIdle()	
-		if self.ted.WEAdjustCursor(where, BIGREGION):
-			return
-		Qd.SetCursor(Qd.GetQDGlobalsArrow())
-		
-	def getscrollbarvalues(self):
-		dr = self.ted.WEGetDestRect()
-		vr = self.ted.WEGetViewRect()
-		vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
-		vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
-		return vx, vy
-		
-	def scrollbar_callback(self, which, what, value):
-		if which == 'y':
-			if what == 'set':
-				height = self.ted.WEGetHeight(0, 0x3fffffff)
-				cur = self.getscrollbarvalues()[1]
-				delta = (cur-value)*height/32767
-			if what == '-':
-				topline_off,dummy = self.ted.WEGetOffset((1,1))
-				topline_num = self.ted.WEOffsetToLine(topline_off)
-				delta = self.ted.WEGetHeight(topline_num, topline_num+1)
-			elif what == '--':
-				delta = (self.ted.WEGetViewRect()[3]-10)
-				if delta <= 0:
-					delta = 10 # Random value
-			elif what == '+':
-				# XXXX Wrong: should be bottom line size
-				topline_off,dummy = self.ted.WEGetOffset((1,1))
-				topline_num = self.ted.WEOffsetToLine(topline_off)
-				delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
-			elif what == '++':
-				delta = -(self.ted.WEGetViewRect()[3]-10)
-				if delta >= 0:
-					delta = -10
-			self.ted.WEScroll(0, delta)
-		else:
-			if what == 'set':
-				return # XXXX
-			vr = self.ted.WEGetViewRect()
-			winwidth = vr[2]-vr[0]
-			if what == '-':
-				delta = winwidth/10
-			elif what == '--':
-				delta = winwidth/2
-			elif what == '+':
-				delta = -winwidth/10
-			elif what == '++':
-				delta = -winwidth/2
-			self.ted.WEScroll(delta, 0)
-		# Pin the scroll
-		l, t, r, b = self.ted.WEGetDestRect()
-		vl, vt, vr, vb = self.ted.WEGetViewRect()
-		if t > 0 or l > 0:
-			dx = dy = 0
-			if t > 0: dy = -t
-			if l > 0: dx = -l
-			self.ted.WEScroll(dx, dy)
-		elif b < vb:
-			self.ted.WEScroll(0, b-vb)
+    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
+        vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
+        dr = (0, 0, 10240, 0)
+        Qd.SetPort(w)
+        Qd.TextFont(4)
+        Qd.TextSize(9)
+        flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
+                        WASTEconst.weDoUndo
+        self.ted = waste.WENew(dr, vr, flags)
+        self.ted.WEInstallTabHooks()
+        style, soup = self.getstylesoup()
+        self.ted.WEInsert(data, style, soup)
+        self.ted.WESetSelection(0,0)
+        self.ted.WECalText()
+        self.ted.WEResetModCount()
+        w.DrawGrowIcon()
+        self.scrollbars()
+        self.do_postopen()
+        self.do_activate(1, None)
 
-		
-	def do_activate(self, onoff, evt):
-		Qd.SetPort(self.wid)
-		ScrolledWindow.do_activate(self, onoff, evt)
-		if onoff:
-			self.ted.WEActivate()
-			self.parent.active = self
-			self.parent.updatemenubar()
-		else:
-			self.ted.WEDeactivate()
+    def getstylesoup(self):
+        if not self.path:
+            return None, None
+        oldrf = Res.CurResFile()
+        try:
+            rf = Res.FSpOpenResFile(self.path, 1)
+        except Res.Error:
+            return None, None
+        try:
+            hstyle = Res.Get1Resource('styl', 128)
+            hstyle.DetachResource()
+        except Res.Error:
+            hstyle = None
+        try:
+            hsoup = Res.Get1Resource('SOUP', 128)
+            hsoup.DetachResource()
+        except Res.Error:
+            hsoup = None
+        Res.CloseResFile(rf)
+        Res.UseResFile(oldrf)
+        return hstyle, hsoup
 
-	def do_update(self, wid, event):
-		region = wid.GetWindowPort().visRgn
-		if Qd.EmptyRgn(region):
-			return
-		Qd.EraseRgn(region)
-		self.ted.WEUpdate(region)
-		self.updatescrollbars()
-		
-	def do_postresize(self, width, height, window):
-		l, t, r, b = self.ted.WEGetViewRect()
-		vr = (l, t, l+width-15, t+height-15)
-		self.ted.WESetViewRect(vr)
-		self.wid.InvalWindowRect(vr)
-		ScrolledWindow.do_postresize(self, width, height, window)
-		
-	def do_contentclick(self, local, modifiers, evt):
-		(what, message, when, where, modifiers) = evt
-		self.ted.WEClick(local, modifiers, when)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
+    def do_idle(self, event):
+        (what, message, when, where, modifiers) = event
+        Qd.SetPort(self.wid)
+        self.ted.WEIdle()
+        if self.ted.WEAdjustCursor(where, BIGREGION):
+            return
+        Qd.SetCursor(Qd.GetQDGlobalsArrow())
 
-	def do_char(self, ch, event):
-		self.ted.WESelView()
-		(what, message, when, where, modifiers) = event
-		self.ted.WEKey(ord(ch), modifiers)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def close(self):
-		if self.ted.WEGetModCount():
-			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
-		#
-		# First save data
-		#
-		dhandle = self.ted.WEGetText()
-		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()
-		#
-		# Now save style and soup
-		#
-		oldresfile = Res.CurResFile()
-		try:
-			rf = Res.FSpOpenResFile(self.path, 3)
-		except Res.Error:
-			Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
-			rf = Res.FSpOpenResFile(self.path, 3)
-		styles = Res.Resource('')
-		soup = Res.Resource('')
-		self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
-		styles.AddResource('styl', 128, '')
-		soup.AddResource('SOUP', 128, '')
-		Res.CloseResFile(rf)
-		Res.UseResFile(oldresfile)
-		
-		self.ted.WEResetModCount()
-		
-	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()
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECut()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_copy(self):
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECopy()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_paste(self):
-		self.ted.WESelView()
-		self.ted.WEPaste()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_clear(self):
-		self.ted.WESelView()
-		self.ted.WEDelete()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
+    def getscrollbarvalues(self):
+        dr = self.ted.WEGetDestRect()
+        vr = self.ted.WEGetViewRect()
+        vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
+        vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
+        return vx, vy
 
-	def menu_undo(self):
-		self.ted.WEUndo()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_setfont(self, font):
-		font = Fm.GetFNum(font)
-		self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
-		self.parent.updatemenubar()
-				
-	def menu_modface(self, face):
-		self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace, 
-			(0, face, 0, (0,0,0)))
+    def scrollbar_callback(self, which, what, value):
+        if which == 'y':
+            if what == 'set':
+                height = self.ted.WEGetHeight(0, 0x3fffffff)
+                cur = self.getscrollbarvalues()[1]
+                delta = (cur-value)*height/32767
+            if what == '-':
+                topline_off,dummy = self.ted.WEGetOffset((1,1))
+                topline_num = self.ted.WEOffsetToLine(topline_off)
+                delta = self.ted.WEGetHeight(topline_num, topline_num+1)
+            elif what == '--':
+                delta = (self.ted.WEGetViewRect()[3]-10)
+                if delta <= 0:
+                    delta = 10 # Random value
+            elif what == '+':
+                # XXXX Wrong: should be bottom line size
+                topline_off,dummy = self.ted.WEGetOffset((1,1))
+                topline_num = self.ted.WEOffsetToLine(topline_off)
+                delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
+            elif what == '++':
+                delta = -(self.ted.WEGetViewRect()[3]-10)
+                if delta >= 0:
+                    delta = -10
+            self.ted.WEScroll(0, delta)
+        else:
+            if what == 'set':
+                return # XXXX
+            vr = self.ted.WEGetViewRect()
+            winwidth = vr[2]-vr[0]
+            if what == '-':
+                delta = winwidth/10
+            elif what == '--':
+                delta = winwidth/2
+            elif what == '+':
+                delta = -winwidth/10
+            elif what == '++':
+                delta = -winwidth/2
+            self.ted.WEScroll(delta, 0)
+        # Pin the scroll
+        l, t, r, b = self.ted.WEGetDestRect()
+        vl, vt, vr, vb = self.ted.WEGetViewRect()
+        if t > 0 or l > 0:
+            dx = dy = 0
+            if t > 0: dy = -t
+            if l > 0: dx = -l
+            self.ted.WEScroll(dx, dy)
+        elif b < vb:
+            self.ted.WEScroll(0, b-vb)
 
-	def menu_setface(self, face):
-		self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace, 
-			(0, face, 0, (0,0,0)))
 
-	def menu_setsize(self, size):
-		self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
-								
-	def menu_incsize(self, size):
-		self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
+    def do_activate(self, onoff, evt):
+        Qd.SetPort(self.wid)
+        ScrolledWindow.do_activate(self, onoff, evt)
+        if onoff:
+            self.ted.WEActivate()
+            self.parent.active = self
+            self.parent.updatemenubar()
+        else:
+            self.ted.WEDeactivate()
 
-	def mysetstyle(self, which, how):
-		self.ted.WESelView()
-		self.ted.WESetStyle(which, how)
-		self.parent.updatemenubar()
-								
-	def have_selection(self):
-		start, stop = self.ted.WEGetSelection()
-		return start < stop
-		
-	def can_paste(self):
-		return self.ted.WECanPaste()
-		
-	def can_undo(self):
-		which, redo = self.ted.WEGetUndoInfo()
-		which = UNDOLABELS[which]
-		if which == None: return None
-		if redo:
-			return "Redo "+which
-		else:
-			return "Undo "+which
-			
-	def getruninfo(self):
-		all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
-		dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
-		if not (mode & WASTEconst.weDoFont):
-			font = None
-		else:
-			font = Fm.GetFontName(font)
-		if not (mode & WASTEconst.weDoFace): fact = None
-		if not (mode & WASTEconst.weDoSize): size = None
-		return font, face, size
+    def do_update(self, wid, event):
+        region = wid.GetWindowPort().visRgn
+        if Qd.EmptyRgn(region):
+            return
+        Qd.EraseRgn(region)
+        self.ted.WEUpdate(region)
+        self.updatescrollbars()
+
+    def do_postresize(self, width, height, window):
+        l, t, r, b = self.ted.WEGetViewRect()
+        vr = (l, t, l+width-15, t+height-15)
+        self.ted.WESetViewRect(vr)
+        self.wid.InvalWindowRect(vr)
+        ScrolledWindow.do_postresize(self, width, height, window)
+
+    def do_contentclick(self, local, modifiers, evt):
+        (what, message, when, where, modifiers) = evt
+        self.ted.WEClick(local, modifiers, when)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def do_char(self, ch, event):
+        self.ted.WESelView()
+        (what, message, when, where, modifiers) = event
+        self.ted.WEKey(ord(ch), modifiers)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def close(self):
+        if self.ted.WEGetModCount():
+            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
+        #
+        # First save data
+        #
+        dhandle = self.ted.WEGetText()
+        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()
+        #
+        # Now save style and soup
+        #
+        oldresfile = Res.CurResFile()
+        try:
+            rf = Res.FSpOpenResFile(self.path, 3)
+        except Res.Error:
+            Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
+            rf = Res.FSpOpenResFile(self.path, 3)
+        styles = Res.Resource('')
+        soup = Res.Resource('')
+        self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
+        styles.AddResource('styl', 128, '')
+        soup.AddResource('SOUP', 128, '')
+        Res.CloseResFile(rf)
+        Res.UseResFile(oldresfile)
+
+        self.ted.WEResetModCount()
+
+    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()
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECut()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_copy(self):
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECopy()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_paste(self):
+        self.ted.WESelView()
+        self.ted.WEPaste()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_clear(self):
+        self.ted.WESelView()
+        self.ted.WEDelete()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_undo(self):
+        self.ted.WEUndo()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_setfont(self, font):
+        font = Fm.GetFNum(font)
+        self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
+        self.parent.updatemenubar()
+
+    def menu_modface(self, face):
+        self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace,
+                (0, face, 0, (0,0,0)))
+
+    def menu_setface(self, face):
+        self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace,
+                (0, face, 0, (0,0,0)))
+
+    def menu_setsize(self, size):
+        self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
+
+    def menu_incsize(self, size):
+        self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
+
+    def mysetstyle(self, which, how):
+        self.ted.WESelView()
+        self.ted.WESetStyle(which, how)
+        self.parent.updatemenubar()
+
+    def have_selection(self):
+        start, stop = self.ted.WEGetSelection()
+        return start < stop
+
+    def can_paste(self):
+        return self.ted.WECanPaste()
+
+    def can_undo(self):
+        which, redo = self.ted.WEGetUndoInfo()
+        which = UNDOLABELS[which]
+        if which == None: return None
+        if redo:
+            return "Redo "+which
+        else:
+            return "Undo "+which
+
+    def getruninfo(self):
+        all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
+        dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
+        if not (mode & WASTEconst.weDoFont):
+            font = None
+        else:
+            font = Fm.GetFontName(font)
+        if not (mode & WASTEconst.weDoFace): fact = None
+        if not (mode & WASTEconst.weDoSize): size = None
+        return font, face, size
 
 class Wed(Application):
-	def __init__(self):
-		Application.__init__(self)
-		self.num = 0
-		self.active = None
-		self.updatemenubar()
-		waste.STDObjectHandlers()
-		
-	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)
-		
-		self.makefontmenu()
-		
-		# Groups of items enabled together:
-		self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
-			self.editmenu, self.fontmenu, self.facemenu, self.sizemenu]
-		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.ffs_values = ()
-		
-	def makefontmenu(self):
-		self.fontmenu = Menu(self.menubar, "Font")
-		self.fontnames = getfontnames()
-		self.fontitems = []
-		for n in self.fontnames:
-			m = MenuItem(self.fontmenu, n, "", self.selfont)
-			self.fontitems.append(m)
-		self.facemenu = Menu(self.menubar, "Style")
-		self.faceitems = []
-		for n, shortcut in STYLES:
-			m = MenuItem(self.facemenu, n, shortcut, self.selface)
-			self.faceitems.append(m)
-		self.facemenu.addseparator()
-		self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N", 
-			self.selfacenormal)
-		self.sizemenu = Menu(self.menubar, "Size")
-		self.sizeitems = []
-		for n in SIZES:
-			m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
-			self.sizeitems.append(m)
-		self.sizemenu.addseparator()
-		self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+", 
-			self.selsizebigger)
-		self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-", 
-			self.selsizesmaller)
-					
-	def selfont(self, id, item, *rest):
-		if self.active:
-			font = self.fontnames[item-1]
-			self.active.menu_setfont(font)
-		else:
-			EasyDialogs.Message("No active window?")
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
+        waste.STDObjectHandlers()
 
-	def selface(self, id, item, *rest):
-		if self.active:
-			face = (1<<(item-1))
-			self.active.menu_modface(face)
-		else:
-			EasyDialogs.Message("No active window?")
+    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)
 
-	def selfacenormal(self, *rest):
-		if self.active:
-			self.active.menu_setface(0)
-		else:
-			EasyDialogs.Message("No active window?")
+        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)
 
-	def selsize(self, id, item, *rest):
-		if self.active:
-			size = SIZES[item-1]
-			self.active.menu_setsize(size)
-		else:
-			EasyDialogs.Message("No active window?")
+        self.makefontmenu()
 
-	def selsizebigger(self, *rest):
-		if self.active:
-			self.active.menu_incsize(2)
-		else:
-			EasyDialogs.Message("No active window?")
+        # Groups of items enabled together:
+        self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
+                self.editmenu, self.fontmenu, self.facemenu, self.sizemenu]
+        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.ffs_values = ()
 
-	def selsizesmaller(self, *rest):
-		if self.active:
-			self.active.menu_incsize(-2)
-		else:
-			EasyDialogs.Message("No active window?")
+    def makefontmenu(self):
+        self.fontmenu = Menu(self.menubar, "Font")
+        self.fontnames = getfontnames()
+        self.fontitems = []
+        for n in self.fontnames:
+            m = MenuItem(self.fontmenu, n, "", self.selfont)
+            self.fontitems.append(m)
+        self.facemenu = Menu(self.menubar, "Style")
+        self.faceitems = []
+        for n, shortcut in STYLES:
+            m = MenuItem(self.facemenu, n, shortcut, self.selface)
+            self.faceitems.append(m)
+        self.facemenu.addseparator()
+        self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N",
+                self.selfacenormal)
+        self.sizemenu = Menu(self.menubar, "Size")
+        self.sizeitems = []
+        for n in SIZES:
+            m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
+            self.sizeitems.append(m)
+        self.sizemenu.addseparator()
+        self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+",
+                self.selsizebigger)
+        self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-",
+                self.selsizesmaller)
 
-	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
-			if self.updatefontmenus():
-				changed = 1
-		if changed:
-			DrawMenuBar()
-			
-	def updatefontmenus(self):
-		info = self.active.getruninfo()
-		if info == self.ffs_values:
-			return 0
-		# Remove old checkmarks
-		if self.ffs_values == ():
-			self.ffs_values = (None, None, None)
-		font, face, size = self.ffs_values
-		if font <> None:
-			fnum = self.fontnames.index(font)
-			self.fontitems[fnum].check(0)
-		if face <> None:
-			for i in range(len(self.faceitems)):
-				if face & (1<<i):
-					self.faceitems[i].check(0)
-		if size <> None:
-			for i in range(len(self.sizeitems)):
-				if SIZES[i] == size:
-					self.sizeitems[i].check(0)
-				
-		self.ffs_values = info
-		# Set new checkmarks
-		font, face, size = self.ffs_values
-		if font <> None:
-			fnum = self.fontnames.index(font)
-			self.fontitems[fnum].check(1)
-		if face <> None:
-			for i in range(len(self.faceitems)):
-				if face & (1<<i):
-					self.faceitems[i].check(1)
-		if size <> None:
-			for i in range(len(self.sizeitems)):
-				if SIZES[i] == size:
-					self.sizeitems[i].check(1)
-		# Set outline/normal for sizes
-		if font:
-			exists = getfontsizes(font, SIZES)
-			for i in range(len(self.sizeitems)):
-				if exists[i]:
-					self.sizeitems[i].setstyle(0)
-				else:
-					self.sizeitems[i].setstyle(8)
+    def selfont(self, id, item, *rest):
+        if self.active:
+            font = self.fontnames[item-1]
+            self.active.menu_setfont(font)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	#
-	# Apple menu
-	#
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("A simple single-font text editor based on WASTE")
-			
-	#
-	# File menu
-	#
+    def selface(self, id, item, *rest):
+        if self.active:
+            face = (1<<(item-1))
+            self.active.menu_modface(face)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	def open(self, *args):
-		self._open(0)
-		
-	def openfile(self, *args):
-		self._open(1)
+    def selfacenormal(self, *rest):
+        if self.active:
+            self.active.menu_setface(0)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	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, arg:
-				EasyDialogs.Message("IOERROR: %r" % (arg,))
-				return
-		else:
-			path = None
-			name = "Untitled %d"%self.num
-			data = ''
-		w = WasteWindow(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 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 selsize(self, id, item, *rest):
+        if self.active:
+            size = SIZES[item-1]
+            self.active.menu_setsize(size)
+        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 selsizebigger(self, *rest):
+        if self.active:
+            self.active.menu_incsize(2)
+        else:
+            EasyDialogs.Message("No active window?")
 
-	def idle(self, event):
-		if self.active:
-			self.active.do_idle(event)
-		else:
-			Qd.SetCursor(Qd.GetQDGlobalsArrow())
-			
+    def selsizesmaller(self, *rest):
+        if self.active:
+            self.active.menu_incsize(-2)
+        else:
+            EasyDialogs.Message("No active window?")
+
+    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
+            if self.updatefontmenus():
+                changed = 1
+        if changed:
+            DrawMenuBar()
+
+    def updatefontmenus(self):
+        info = self.active.getruninfo()
+        if info == self.ffs_values:
+            return 0
+        # Remove old checkmarks
+        if self.ffs_values == ():
+            self.ffs_values = (None, None, None)
+        font, face, size = self.ffs_values
+        if font <> None:
+            fnum = self.fontnames.index(font)
+            self.fontitems[fnum].check(0)
+        if face <> None:
+            for i in range(len(self.faceitems)):
+                if face & (1<<i):
+                    self.faceitems[i].check(0)
+        if size <> None:
+            for i in range(len(self.sizeitems)):
+                if SIZES[i] == size:
+                    self.sizeitems[i].check(0)
+
+        self.ffs_values = info
+        # Set new checkmarks
+        font, face, size = self.ffs_values
+        if font <> None:
+            fnum = self.fontnames.index(font)
+            self.fontitems[fnum].check(1)
+        if face <> None:
+            for i in range(len(self.faceitems)):
+                if face & (1<<i):
+                    self.faceitems[i].check(1)
+        if size <> None:
+            for i in range(len(self.sizeitems)):
+                if SIZES[i] == size:
+                    self.sizeitems[i].check(1)
+        # Set outline/normal for sizes
+        if font:
+            exists = getfontsizes(font, SIZES)
+            for i in range(len(self.sizeitems)):
+                if exists[i]:
+                    self.sizeitems[i].setstyle(0)
+                else:
+                    self.sizeitems[i].setstyle(8)
+
+    #
+    # Apple menu
+    #
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("A simple single-font text editor based on WASTE")
+
+    #
+    # 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, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+        else:
+            path = None
+            name = "Untitled %d"%self.num
+            data = ''
+        w = WasteWindow(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 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 getfontnames():
-	names = []
-	for i in range(256):
-		n = Fm.GetFontName(i)
-		if n: names.append(n)
-	return names
-	
+    names = []
+    for i in range(256):
+        n = Fm.GetFontName(i)
+        if n: names.append(n)
+    return names
+
 def getfontsizes(name, sizes):
-	exist = []
-	num = Fm.GetFNum(name)
-	for sz in sizes:
-		if Fm.RealFont(num, sz):
-			exist.append(1)
-		else:
-			exist.append(0)
-	return exist
+    exist = []
+    num = Fm.GetFNum(name)
+    for sz in sizes:
+        if Fm.RealFont(num, sz):
+            exist.append(1)
+        else:
+            exist.append(0)
+    return exist
 
 def main():
-	App = Wed()
-	App.mainloop()
-	
+    App = Wed()
+    App.mainloop()
+
 if __name__ == '__main__':
-	main()
-	
+    main()
diff --git a/Mac/Demo/waste/wed.py b/Mac/Demo/waste/wed.py
index 5d84b40..28ee938 100644
--- a/Mac/Demo/waste/wed.py
+++ b/Mac/Demo/waste/wed.py
@@ -15,413 +15,412 @@
 import EasyDialogs
 
 UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
-	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
-	
+        None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
+
 BIGREGION=Qd.NewRgn()
 Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
 
 class WasteWindow(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
-		vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
-		dr = (0, 0, 10240, 0)
-		Qd.SetPort(w)
-		Qd.TextFont(4)
-		Qd.TextSize(9)
-		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
-			WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
-		self.ted = waste.WENew(dr, vr, flags)
-		self.tedtexthandle = Res.Resource(data)
-		self.ted.WEUseText(self.tedtexthandle)
-		self.ted.WECalText()
-		w.DrawGrowIcon()
-		self.scrollbars()
-		self.changed = 0
-		self.do_postopen()
-		self.do_activate(1, None)
-		
-	def do_idle(self, event):
-		(what, message, when, where, modifiers) = event
-		Qd.SetPort(self.wid)
-		self.ted.WEIdle()	
-		if self.ted.WEAdjustCursor(where, BIGREGION):
-			return
-		Qd.SetCursor(Qd.GetQDGlobalsArrow())
-		
-	def getscrollbarvalues(self):
-		dr = self.ted.WEGetDestRect()
-		vr = self.ted.WEGetViewRect()
-		vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
-		vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
-##		print dr, vr, vx, vy
-		return vx, vy
-		
-	def scrollbar_callback(self, which, what, value):
-		if which == 'y':
-			if what == 'set':
-				height = self.ted.WEGetHeight(0, 0x3fffffff)
-				cur = self.getscrollbarvalues()[1]
-				delta = (cur-value)*height/32767
-			if what == '-':
-				topline_off,dummy = self.ted.WEGetOffset((1,1))
-				topline_num = self.ted.WEOffsetToLine(topline_off)
-				delta = self.ted.WEGetHeight(topline_num, topline_num+1)
-			elif what == '--':
-				delta = (self.ted.WEGetViewRect()[3]-10)
-				if delta <= 0:
-					delta = 10 # Random value
-			elif what == '+':
-				# XXXX Wrong: should be bottom line size
-				topline_off,dummy = self.ted.WEGetOffset((1,1))
-				topline_num = self.ted.WEOffsetToLine(topline_off)
-				delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
-			elif what == '++':
-				delta = -(self.ted.WEGetViewRect()[3]-10)
-				if delta >= 0:
-					delta = -10
-			self.ted.WEScroll(0, delta)
-##			print 'SCROLL Y', delta
-		else:
-			if what == 'set':
-				return # XXXX
-			vr = self.ted.WEGetViewRect()
-			winwidth = vr[2]-vr[0]
-			if what == '-':
-				delta = winwidth/10
-			elif what == '--':
-				delta = winwidth/2
-			elif what == '+':
-				delta = -winwidth/10
-			elif what == '++':
-				delta = -winwidth/2
-			self.ted.WEScroll(delta, 0)
-		# Pin the scroll
-		l, t, r, b = self.ted.WEGetDestRect()
-		vl, vt, vr, vb = self.ted.WEGetViewRect()
-		if t > 0 or l > 0:
-			dx = dy = 0
-			if t > 0: dy = -t
-			if l > 0: dx = -l
-##			print 'Extra scroll', dx, dy
-			self.ted.WEScroll(dx, dy)
-		elif b < vb:
-##			print 'Extra downscroll', b-vb
-			self.ted.WEScroll(0, b-vb)
+    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
+        vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
+        dr = (0, 0, 10240, 0)
+        Qd.SetPort(w)
+        Qd.TextFont(4)
+        Qd.TextSize(9)
+        flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
+                WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
+        self.ted = waste.WENew(dr, vr, flags)
+        self.tedtexthandle = Res.Resource(data)
+        self.ted.WEUseText(self.tedtexthandle)
+        self.ted.WECalText()
+        w.DrawGrowIcon()
+        self.scrollbars()
+        self.changed = 0
+        self.do_postopen()
+        self.do_activate(1, None)
 
-		
-	def do_activate(self, onoff, evt):
-##		print "ACTIVATE", onoff
-		Qd.SetPort(self.wid)
-		ScrolledWindow.do_activate(self, onoff, evt)
-		if onoff:
-			self.ted.WEActivate()
-			self.parent.active = self
-			self.parent.updatemenubar()
-		else:
-			self.ted.WEDeactivate()
+    def do_idle(self, event):
+        (what, message, when, where, modifiers) = event
+        Qd.SetPort(self.wid)
+        self.ted.WEIdle()
+        if self.ted.WEAdjustCursor(where, BIGREGION):
+            return
+        Qd.SetCursor(Qd.GetQDGlobalsArrow())
 
-	def do_update(self, wid, event):
-		region = wid.GetWindowPort().visRgn
-		if Qd.EmptyRgn(region):
-			return
-		Qd.EraseRgn(region)
-		self.ted.WEUpdate(region)
-		self.updatescrollbars()
-		
-	def do_postresize(self, width, height, window):
-		l, t, r, b = self.ted.WEGetViewRect()
-		vr = (l, t, l+width-15, t+height-15)
-		self.ted.WESetViewRect(vr)
-		self.wid.InvalWindowRect(vr)
-		ScrolledWindow.do_postresize(self, width, height, window)
-		
-	def do_contentclick(self, local, modifiers, evt):
-		(what, message, when, where, modifiers) = evt
-		self.ted.WEClick(local, modifiers, when)
-		self.updatescrollbars()
-		self.parent.updatemenubar()
+    def getscrollbarvalues(self):
+        dr = self.ted.WEGetDestRect()
+        vr = self.ted.WEGetViewRect()
+        vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
+        vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
+##              print dr, vr, vx, vy
+        return vx, vy
 
-	def do_char(self, ch, event):
-		self.ted.WESelView()
-		(what, message, when, where, modifiers) = event
-		self.ted.WEKey(ord(ch), modifiers)
-		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
-		del self.tedtexthandle
-		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.WEGetText()
-		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()
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECut()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		self.changed = 1
-		
-	def menu_copy(self):
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECopy()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		
-	def menu_paste(self):
-		self.ted.WESelView()
-		self.ted.WEPaste()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		self.changed = 1
-		
-	def menu_clear(self):
-		self.ted.WESelView()
-		self.ted.WEDelete()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-		self.changed = 1
+    def scrollbar_callback(self, which, what, value):
+        if which == 'y':
+            if what == 'set':
+                height = self.ted.WEGetHeight(0, 0x3fffffff)
+                cur = self.getscrollbarvalues()[1]
+                delta = (cur-value)*height/32767
+            if what == '-':
+                topline_off,dummy = self.ted.WEGetOffset((1,1))
+                topline_num = self.ted.WEOffsetToLine(topline_off)
+                delta = self.ted.WEGetHeight(topline_num, topline_num+1)
+            elif what == '--':
+                delta = (self.ted.WEGetViewRect()[3]-10)
+                if delta <= 0:
+                    delta = 10 # Random value
+            elif what == '+':
+                # XXXX Wrong: should be bottom line size
+                topline_off,dummy = self.ted.WEGetOffset((1,1))
+                topline_num = self.ted.WEOffsetToLine(topline_off)
+                delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
+            elif what == '++':
+                delta = -(self.ted.WEGetViewRect()[3]-10)
+                if delta >= 0:
+                    delta = -10
+            self.ted.WEScroll(0, delta)
+##                      print 'SCROLL Y', delta
+        else:
+            if what == 'set':
+                return # XXXX
+            vr = self.ted.WEGetViewRect()
+            winwidth = vr[2]-vr[0]
+            if what == '-':
+                delta = winwidth/10
+            elif what == '--':
+                delta = winwidth/2
+            elif what == '+':
+                delta = -winwidth/10
+            elif what == '++':
+                delta = -winwidth/2
+            self.ted.WEScroll(delta, 0)
+        # Pin the scroll
+        l, t, r, b = self.ted.WEGetDestRect()
+        vl, vt, vr, vb = self.ted.WEGetViewRect()
+        if t > 0 or l > 0:
+            dx = dy = 0
+            if t > 0: dy = -t
+            if l > 0: dx = -l
+##                      print 'Extra scroll', dx, dy
+            self.ted.WEScroll(dx, dy)
+        elif b < vb:
+##                      print 'Extra downscroll', b-vb
+            self.ted.WEScroll(0, b-vb)
 
-	def menu_undo(self):
-		self.ted.WEUndo()
-		self.updatescrollbars()
-		self.parent.updatemenubar()
-				
-	def have_selection(self):
-		start, stop = self.ted.WEGetSelection()
-		return start < stop
-		
-	def can_paste(self):
-		return self.ted.WECanPaste()
-		
-	def can_undo(self):
-		which, redo = self.ted.WEGetUndoInfo()
-		which = UNDOLABELS[which]
-		if which == None: return None
-		if redo:
-			return "Redo "+which
-		else:
-			return "Undo "+which
+
+    def do_activate(self, onoff, evt):
+##              print "ACTIVATE", onoff
+        Qd.SetPort(self.wid)
+        ScrolledWindow.do_activate(self, onoff, evt)
+        if onoff:
+            self.ted.WEActivate()
+            self.parent.active = self
+            self.parent.updatemenubar()
+        else:
+            self.ted.WEDeactivate()
+
+    def do_update(self, wid, event):
+        region = wid.GetWindowPort().visRgn
+        if Qd.EmptyRgn(region):
+            return
+        Qd.EraseRgn(region)
+        self.ted.WEUpdate(region)
+        self.updatescrollbars()
+
+    def do_postresize(self, width, height, window):
+        l, t, r, b = self.ted.WEGetViewRect()
+        vr = (l, t, l+width-15, t+height-15)
+        self.ted.WESetViewRect(vr)
+        self.wid.InvalWindowRect(vr)
+        ScrolledWindow.do_postresize(self, width, height, window)
+
+    def do_contentclick(self, local, modifiers, evt):
+        (what, message, when, where, modifiers) = evt
+        self.ted.WEClick(local, modifiers, when)
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def do_char(self, ch, event):
+        self.ted.WESelView()
+        (what, message, when, where, modifiers) = event
+        self.ted.WEKey(ord(ch), modifiers)
+        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
+        del self.tedtexthandle
+        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.WEGetText()
+        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()
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECut()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_copy(self):
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECopy()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def menu_paste(self):
+        self.ted.WESelView()
+        self.ted.WEPaste()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_clear(self):
+        self.ted.WESelView()
+        self.ted.WEDelete()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+        self.changed = 1
+
+    def menu_undo(self):
+        self.ted.WEUndo()
+        self.updatescrollbars()
+        self.parent.updatemenubar()
+
+    def have_selection(self):
+        start, stop = self.ted.WEGetSelection()
+        return start < stop
+
+    def can_paste(self):
+        return self.ted.WECanPaste()
+
+    def can_undo(self):
+        which, redo = self.ted.WEGetUndoInfo()
+        which = UNDOLABELS[which]
+        if which == None: return None
+        if redo:
+            return "Redo "+which
+        else:
+            return "Undo "+which
 
 class Wed(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)
-		
-		# 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"
-		
-	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
-		if changed:
-			DrawMenuBar()
+    def __init__(self):
+        Application.__init__(self)
+        self.num = 0
+        self.active = None
+        self.updatemenubar()
 
-	#
-	# Apple menu
-	#
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("A simple single-font text editor based on WASTE")
-			
-	#
-	# File menu
-	#
+    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)
 
-	def open(self, *args):
-		self._open(0)
-		
-	def openfile(self, *args):
-		self._open(1)
+        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)
 
-	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, arg:
-				EasyDialogs.Message("IOERROR: %r" % (arg,))
-				return
-		else:
-			path = None
-			name = "Untitled %d"%self.num
-			data = ''
-		w = WasteWindow(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 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?")
+        # 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"
 
-	def clear(self, *args):
-		if self.active:
-			self.active.menu_clear()
-		else:
-			EasyDialogs.Message("No active window?")
-		
-	#
-	# Other stuff
-	#	
+    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
+        if changed:
+            DrawMenuBar()
 
-	def idle(self, event):
-		if self.active:
-			self.active.do_idle(event)
-		else:
-			Qd.SetCursor(Qd.GetQDGlobalsArrow())
+    #
+    # Apple menu
+    #
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("A simple single-font text editor based on WASTE")
+
+    #
+    # 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, arg:
+                EasyDialogs.Message("IOERROR: %r" % (arg,))
+                return
+        else:
+            path = None
+            name = "Untitled %d"%self.num
+            data = ''
+        w = WasteWindow(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 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():
-	App = Wed()
-	App.mainloop()
-	
+    App = Wed()
+    App.mainloop()
+
 if __name__ == '__main__':
-	main()
-	
+    main()