diff --git a/Mac/Tools/IDE/BuildIDE.py b/Mac/Tools/IDE/BuildIDE.py
index 7e65869..914028c 100644
--- a/Mac/Tools/IDE/BuildIDE.py
+++ b/Mac/Tools/IDE/BuildIDE.py
@@ -1,4 +1,4 @@
-"""Build a "big" applet for the IDE, and put it in the Python home 
+"""Build a "big" applet for the IDE, and put it in the Python home
 directory. It will contain all IDE-specific modules as PYC resources,
 which reduces the startup time (especially on slower machines)."""
 
@@ -25,17 +25,16 @@
 files = os.listdir(ide_home)
 
 # skip this script and the main program
-files = filter(lambda x: x[-3:] == '.py' and 
-		x not in ("BuildIDE.py", "PythonIDE.py"), files)
+files = filter(lambda x: x[-3:] == '.py' and
+                x not in ("BuildIDE.py", "PythonIDE.py"), files)
 
 # add the modules as PYC resources
 for name in files:
-	print "adding", name
-	fullpath = os.path.join(ide_home, name)
-	id, name = py_resource.frompyfile(fullpath, name[:-3], preload=1,
-		ispackage=0)
+    print "adding", name
+    fullpath = os.path.join(ide_home, name)
+    id, name = py_resource.frompyfile(fullpath, name[:-3], preload=1,
+            ispackage=0)
 
 # add W resources
 wresref = Res.FSpOpenResFile(os.path.join(ide_home, "Widgets.rsrc"), 1)
 buildtools.copyres(wresref, targetref, [], 0)
-
diff --git a/Mac/Tools/IDE/FontSettings.py b/Mac/Tools/IDE/FontSettings.py
index af2bd80..d713438 100644
--- a/Mac/Tools/IDE/FontSettings.py
+++ b/Mac/Tools/IDE/FontSettings.py
@@ -1,9 +1,9 @@
-"""usage: 
-newsettings = FontDialog(('Chicago', 0, 12, (0, 0, 0)))	# font name or id, style flags, size, color (color is ignored)
+"""usage:
+newsettings = FontDialog(('Chicago', 0, 12, (0, 0, 0))) # font name or id, style flags, size, color (color is ignored)
 if newsettings:
-	fontsettings, tabsettings = newsettings
-	font, style, size, color = fontsettings	# 'font' is always the font name, not the id number
-	# do something
+        fontsettings, tabsettings = newsettings
+        font, style, size, color = fontsettings # 'font' is always the font name, not the id number
+        # do something
 """
 
 import W
@@ -15,209 +15,209 @@
 import sys
 import MacOS
 if hasattr(MacOS, "SysBeep"):
-	SysBeep = MacOS.SysBeep
+    SysBeep = MacOS.SysBeep
 else:
-	def SysBeep(*args):
-		pass
+    def SysBeep(*args):
+        pass
 
 _stylenames = ["Plain", "Bold", "Italic", "Underline", "Outline", "Shadow", "Condensed", "Extended"]
 
 
 class _FontDialog:
-	
-	#def __del__(self):
-	#	print "doei!"
-	
-	def __init__(self, fontsettings, tabsettings):
-		leftmargin = 60
-		leftmargin2 = leftmargin - 16
-		self.w = W.ModalDialog((440, 180), 'Font settings')
-		self.w.fonttitle = W.TextBox((10, 12, leftmargin2, 14), "Font:", TextEdit.teJustRight)
-		self.w.pop = W.FontMenu((leftmargin, 10, 16, 16), self.setfont)
-		self.w.fontname = W.TextBox((leftmargin + 20, 12, 150, 14))
-		self.w.sizetitle = W.TextBox((10, 38, leftmargin2, 14), "Size:", TextEdit.teJustRight)
-		self.w.sizeedit = W.EditText((leftmargin, 35, 40, 20), "", self.checksize)
-		styletop = 64
-		self.w.styletitle = W.TextBox((10, styletop + 2, leftmargin2, 14), "Style:", TextEdit.teJustRight)
-		for i in range(len(_stylenames)):
-			top = styletop + (i % 4) * 20
-			left = leftmargin + 80 * (i > 3) - 2
-			if i:
-				self.w[i] = W.CheckBox((left, top, 76, 16), _stylenames[i], self.dostyle)
-			else:
-				self.w[i] = W.CheckBox((left, top, 70, 16), _stylenames[i], self.doplain)
-		
-		if tabsettings:
-			self.lasttab, self.tabmode = tabsettings
-			self.w.tabsizetitle = W.TextBox((10, -26, leftmargin2, 14), "Tabsize:", TextEdit.teJustRight)
-			self.w.tabsizeedit = W.EditText((leftmargin, -29, 40, 20), "", self.checktab)
-			self.w.tabsizeedit.set(repr(self.lasttab))
-			radiobuttons = []
-			self.w.tabsizechars = W.RadioButton((leftmargin + 48, -26, 55, 14), "Spaces", 
-					radiobuttons, self.toggletabmode)
-			self.w.tabsizepixels = W.RadioButton((leftmargin + 110, -26, 55, 14), "Pixels", 
-					radiobuttons, self.toggletabmode)
-			if self.tabmode:
-				self.w.tabsizechars.set(1)
-			else:
-				self.w.tabsizepixels.set(1)
-		else:
-			self.tabmode = None
-		
-		self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
-		self.w.donebutton = W.Button((-90, -26, 80, 16), "Done", self.done)
-		
-		sampletext = "Sample text."
-		self.w.sample = W.EditText((230, 10, -10, 130), sampletext, 
-				fontsettings = fontsettings, tabsettings = tabsettings)
-		
-		self.w.setdefaultbutton(self.w.donebutton)
-		self.w.bind('cmd.', self.w.cancelbutton.push)
-		self.w.bind('cmdw', self.w.donebutton.push)
-		self.lastsize = fontsettings[2]
-		self._rv = None
-		self.set(fontsettings)
-		self.w.open()
-	
-	def toggletabmode(self, onoff):
-		if self.w.tabsizechars.get():
-			tabmode = 1
-		else:
-			tabmode = 0
-		if self.tabmode <> tabmode:
-			port = self.w.wid.GetWindowPort()
-			(font, style, size, color), (tabsize, dummy) = self.get()
-			savesettings = W.GetPortFontSettings(port)
-			W.SetPortFontSettings(port, (font, style, size))
-			spacewidth = Qd.StringWidth(' ')
-			W.SetPortFontSettings(port, savesettings)
-			if tabmode:
-				# convert pixels to spaces
-				self.lasttab = int(round(float(tabsize) / spacewidth))
-			else:
-				# convert spaces to pixels
-				self.lasttab = spacewidth * tabsize
-			self.w.tabsizeedit.set(repr(self.lasttab))
-			self.tabmode = tabmode
-			self.doit()
-	
-	def set(self, fontsettings):
-		font, style, size, color = fontsettings
-		if type(font) <> types.StringType:
-			from Carbon import Res
-			res = Res.GetResource('FOND', font)
-			font = res.GetResInfo()[2]
-		self.w.fontname.set(font)
-		self.w.sizeedit.set(str(size))
-		if style:
-			for i in range(1, len(_stylenames)):
-				self.w[i].set(style & 0x01)
-				style = style >> 1
-		else:
-			self.w[0].set(1)
-	
-	def get(self):
-		font = self.w.fontname.get()
-		style = 0
-		if not self.w[0].get():
-			flag = 0x01
-			for i in range(1, len(_stylenames)):
-				if self.w[i].get():
-					style = style | flag
-				flag = flag << 1
-		size = self.lastsize
-		if self.tabmode is None:
-			return (font, style, size, (0, 0, 0)), (32, 0)
-		else:
-			return (font, style, size, (0, 0, 0)), (self.lasttab, self.tabmode)
-	
-	def doit(self):
-		if self.w[0].get():
-			style = 0
-		else:
-			style = 0
-			for i in range(1, len(_stylenames)):
-				if self.w[i].get():
-					style = style | 2 ** (i - 1)
-		#self.w.sample.set(repr(style))
-		fontsettings, tabsettings = self.get()
-		self.w.sample.setfontsettings(fontsettings)
-		self.w.sample.settabsettings(tabsettings)
-	
-	def checktab(self):
-		tabsize = self.w.tabsizeedit.get()
-		if not tabsize:
-			return
-		try:
-			tabsize = string.atoi(tabsize)
-		except (ValueError, OverflowError):
-			good = 0
-			sys.exc_traceback = None
-		else:
-			good = 1 <= tabsize <= 500
-		if good:
-			if self.lasttab <> tabsize:
-				self.lasttab = tabsize
-				self.doit()
-		else:
-			SysBeep(0)
-			self.w.tabsizeedit.set(repr(self.lasttab))
-			self.w.tabsizeedit.selectall()
-	
-	def checksize(self):
-		size = self.w.sizeedit.get()
-		if not size:
-			return
-		try:
-			size = string.atoi(size)
-		except (ValueError, OverflowError):
-			good = 0
-			sys.exc_traceback = None
-		else:
-			good = 1 <= size <= 500
-		if good:
-			if self.lastsize <> size:
-				self.lastsize = size
-				self.doit()
-		else:
-			SysBeep(0)
-			self.w.sizeedit.set(repr(self.lastsize))
-			self.w.sizeedit.selectall()
-	
-	def doplain(self):
-		for i in range(1, len(_stylenames)):
-			self.w[i].set(0)
-		self.w[0].set(1)
-		self.doit()
-	
-	def dostyle(self):
-		for i in range(1, len(_stylenames)):
-			if self.w[i].get():
-				self.w[0].set(0)
-				break
-		else:
-			self.w[0].set(1)
-		self.doit()
-	
-	def close(self):
-		self.w.close()
-		del self.w
-	
-	def cancel(self):
-		self.close()
-	
-	def done(self):
-		self._rv = self.get()
-		self.close()
-	
-	def setfont(self, fontname):
-		self.w.fontname.set(fontname)
-		self.doit()
-	
+
+    #def __del__(self):
+    #       print "doei!"
+
+    def __init__(self, fontsettings, tabsettings):
+        leftmargin = 60
+        leftmargin2 = leftmargin - 16
+        self.w = W.ModalDialog((440, 180), 'Font settings')
+        self.w.fonttitle = W.TextBox((10, 12, leftmargin2, 14), "Font:", TextEdit.teJustRight)
+        self.w.pop = W.FontMenu((leftmargin, 10, 16, 16), self.setfont)
+        self.w.fontname = W.TextBox((leftmargin + 20, 12, 150, 14))
+        self.w.sizetitle = W.TextBox((10, 38, leftmargin2, 14), "Size:", TextEdit.teJustRight)
+        self.w.sizeedit = W.EditText((leftmargin, 35, 40, 20), "", self.checksize)
+        styletop = 64
+        self.w.styletitle = W.TextBox((10, styletop + 2, leftmargin2, 14), "Style:", TextEdit.teJustRight)
+        for i in range(len(_stylenames)):
+            top = styletop + (i % 4) * 20
+            left = leftmargin + 80 * (i > 3) - 2
+            if i:
+                self.w[i] = W.CheckBox((left, top, 76, 16), _stylenames[i], self.dostyle)
+            else:
+                self.w[i] = W.CheckBox((left, top, 70, 16), _stylenames[i], self.doplain)
+
+        if tabsettings:
+            self.lasttab, self.tabmode = tabsettings
+            self.w.tabsizetitle = W.TextBox((10, -26, leftmargin2, 14), "Tabsize:", TextEdit.teJustRight)
+            self.w.tabsizeedit = W.EditText((leftmargin, -29, 40, 20), "", self.checktab)
+            self.w.tabsizeedit.set(repr(self.lasttab))
+            radiobuttons = []
+            self.w.tabsizechars = W.RadioButton((leftmargin + 48, -26, 55, 14), "Spaces",
+                            radiobuttons, self.toggletabmode)
+            self.w.tabsizepixels = W.RadioButton((leftmargin + 110, -26, 55, 14), "Pixels",
+                            radiobuttons, self.toggletabmode)
+            if self.tabmode:
+                self.w.tabsizechars.set(1)
+            else:
+                self.w.tabsizepixels.set(1)
+        else:
+            self.tabmode = None
+
+        self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
+        self.w.donebutton = W.Button((-90, -26, 80, 16), "Done", self.done)
+
+        sampletext = "Sample text."
+        self.w.sample = W.EditText((230, 10, -10, 130), sampletext,
+                        fontsettings = fontsettings, tabsettings = tabsettings)
+
+        self.w.setdefaultbutton(self.w.donebutton)
+        self.w.bind('cmd.', self.w.cancelbutton.push)
+        self.w.bind('cmdw', self.w.donebutton.push)
+        self.lastsize = fontsettings[2]
+        self._rv = None
+        self.set(fontsettings)
+        self.w.open()
+
+    def toggletabmode(self, onoff):
+        if self.w.tabsizechars.get():
+            tabmode = 1
+        else:
+            tabmode = 0
+        if self.tabmode <> tabmode:
+            port = self.w.wid.GetWindowPort()
+            (font, style, size, color), (tabsize, dummy) = self.get()
+            savesettings = W.GetPortFontSettings(port)
+            W.SetPortFontSettings(port, (font, style, size))
+            spacewidth = Qd.StringWidth(' ')
+            W.SetPortFontSettings(port, savesettings)
+            if tabmode:
+                # convert pixels to spaces
+                self.lasttab = int(round(float(tabsize) / spacewidth))
+            else:
+                # convert spaces to pixels
+                self.lasttab = spacewidth * tabsize
+            self.w.tabsizeedit.set(repr(self.lasttab))
+            self.tabmode = tabmode
+            self.doit()
+
+    def set(self, fontsettings):
+        font, style, size, color = fontsettings
+        if type(font) <> types.StringType:
+            from Carbon import Res
+            res = Res.GetResource('FOND', font)
+            font = res.GetResInfo()[2]
+        self.w.fontname.set(font)
+        self.w.sizeedit.set(str(size))
+        if style:
+            for i in range(1, len(_stylenames)):
+                self.w[i].set(style & 0x01)
+                style = style >> 1
+        else:
+            self.w[0].set(1)
+
+    def get(self):
+        font = self.w.fontname.get()
+        style = 0
+        if not self.w[0].get():
+            flag = 0x01
+            for i in range(1, len(_stylenames)):
+                if self.w[i].get():
+                    style = style | flag
+                flag = flag << 1
+        size = self.lastsize
+        if self.tabmode is None:
+            return (font, style, size, (0, 0, 0)), (32, 0)
+        else:
+            return (font, style, size, (0, 0, 0)), (self.lasttab, self.tabmode)
+
+    def doit(self):
+        if self.w[0].get():
+            style = 0
+        else:
+            style = 0
+            for i in range(1, len(_stylenames)):
+                if self.w[i].get():
+                    style = style | 2 ** (i - 1)
+        #self.w.sample.set(repr(style))
+        fontsettings, tabsettings = self.get()
+        self.w.sample.setfontsettings(fontsettings)
+        self.w.sample.settabsettings(tabsettings)
+
+    def checktab(self):
+        tabsize = self.w.tabsizeedit.get()
+        if not tabsize:
+            return
+        try:
+            tabsize = string.atoi(tabsize)
+        except (ValueError, OverflowError):
+            good = 0
+            sys.exc_traceback = None
+        else:
+            good = 1 <= tabsize <= 500
+        if good:
+            if self.lasttab <> tabsize:
+                self.lasttab = tabsize
+                self.doit()
+        else:
+            SysBeep(0)
+            self.w.tabsizeedit.set(repr(self.lasttab))
+            self.w.tabsizeedit.selectall()
+
+    def checksize(self):
+        size = self.w.sizeedit.get()
+        if not size:
+            return
+        try:
+            size = string.atoi(size)
+        except (ValueError, OverflowError):
+            good = 0
+            sys.exc_traceback = None
+        else:
+            good = 1 <= size <= 500
+        if good:
+            if self.lastsize <> size:
+                self.lastsize = size
+                self.doit()
+        else:
+            SysBeep(0)
+            self.w.sizeedit.set(repr(self.lastsize))
+            self.w.sizeedit.selectall()
+
+    def doplain(self):
+        for i in range(1, len(_stylenames)):
+            self.w[i].set(0)
+        self.w[0].set(1)
+        self.doit()
+
+    def dostyle(self):
+        for i in range(1, len(_stylenames)):
+            if self.w[i].get():
+                self.w[0].set(0)
+                break
+        else:
+            self.w[0].set(1)
+        self.doit()
+
+    def close(self):
+        self.w.close()
+        del self.w
+
+    def cancel(self):
+        self.close()
+
+    def done(self):
+        self._rv = self.get()
+        self.close()
+
+    def setfont(self, fontname):
+        self.w.fontname.set(fontname)
+        self.doit()
+
 
 def FontDialog(fontsettings, tabsettings = (32, 0)):
-	fd = _FontDialog(fontsettings, tabsettings)
-	return fd._rv
+    fd = _FontDialog(fontsettings, tabsettings)
+    return fd._rv
 
 def test():
-	print FontDialog(('Zapata-Light', 0, 25, (0, 0, 0)))
+    print FontDialog(('Zapata-Light', 0, 25, (0, 0, 0)))
diff --git a/Mac/Tools/IDE/MacPrefs.py b/Mac/Tools/IDE/MacPrefs.py
index 25dda4f..3cf9153 100644
--- a/Mac/Tools/IDE/MacPrefs.py
+++ b/Mac/Tools/IDE/MacPrefs.py
@@ -4,105 +4,105 @@
 from Carbon import Folders
 
 class PrefObject:
-	
-	def __init__(self, dict = None):
-		if dict == None:
-			self._prefsdict = {}
-		else:
-			self._prefsdict = dict
-	
-	def __len__(self):
-		return len(self._prefsdict)
-	
-	def __delattr__(self, attr):
-		if self._prefsdict.has_key(attr):
-			del self._prefsdict[attr]
-		else:
-			raise AttributeError, 'delete non-existing instance attribute'
-	
-	def __getattr__(self, attr):
-		if attr == '__members__':
-			keys = self._prefsdict.keys()
-			keys.sort()
-			return keys
-		try:
-			return self._prefsdict[attr]
-		except KeyError:
-			raise AttributeError, attr
-	
-	def __setattr__(self, attr, value):
-		if attr[0] <> '_':
-			self._prefsdict[attr] = value
-		else:
-			self.__dict__[attr] = value
-	
-	def getprefsdict(self):
-		return self._prefsdict
+
+    def __init__(self, dict = None):
+        if dict == None:
+            self._prefsdict = {}
+        else:
+            self._prefsdict = dict
+
+    def __len__(self):
+        return len(self._prefsdict)
+
+    def __delattr__(self, attr):
+        if self._prefsdict.has_key(attr):
+            del self._prefsdict[attr]
+        else:
+            raise AttributeError, 'delete non-existing instance attribute'
+
+    def __getattr__(self, attr):
+        if attr == '__members__':
+            keys = self._prefsdict.keys()
+            keys.sort()
+            return keys
+        try:
+            return self._prefsdict[attr]
+        except KeyError:
+            raise AttributeError, attr
+
+    def __setattr__(self, attr, value):
+        if attr[0] <> '_':
+            self._prefsdict[attr] = value
+        else:
+            self.__dict__[attr] = value
+
+    def getprefsdict(self):
+        return self._prefsdict
 
 
 class PrefFile(PrefObject):
-	
-	def __init__(self, path, creator = 'Pyth'):
-		# Find the preferences folder and our prefs file, create if needed.
-		self.__path = path
-		self.__creator = creator
-		self._prefsdict = {}
-		try:
-			prefdict = marshal.load(open(self.__path, 'rb'))
-		except (IOError, ValueError):
-			# file not found, or currupt marshal data
-			pass
-		else:
-			for key, value in prefdict.items():
-				if type(value) == types.DictType:
-					self._prefsdict[key] = PrefObject(value)
-				else:
-					self._prefsdict[key] = value
-	
-	def save(self):
-		prefdict = {}
-		for key, value in self._prefsdict.items():
-			if type(value) == types.InstanceType:
-				prefdict[key] = value.getprefsdict()
-				if not prefdict[key]:
-					del prefdict[key]
-			else:
-				prefdict[key] = value
-		marshal.dump(prefdict, open(self.__path, 'wb'))
-		try:
-			MacOS.SetCreatorAndType(self.__path, self.__creator, 'pref')
-		except:
-			pass
-	
-	def __getattr__(self, attr):
-		if attr == '__members__':
-			keys = self._prefsdict.keys()
-			keys.sort()
-			return keys
-		try:
-			return self._prefsdict[attr]
-		except KeyError:
-			if attr[0] <> '_':
-				self._prefsdict[attr] = PrefObject()
-				return self._prefsdict[attr]
-			else:
-				raise AttributeError, attr
+
+    def __init__(self, path, creator = 'Pyth'):
+        # Find the preferences folder and our prefs file, create if needed.
+        self.__path = path
+        self.__creator = creator
+        self._prefsdict = {}
+        try:
+            prefdict = marshal.load(open(self.__path, 'rb'))
+        except (IOError, ValueError):
+            # file not found, or currupt marshal data
+            pass
+        else:
+            for key, value in prefdict.items():
+                if type(value) == types.DictType:
+                    self._prefsdict[key] = PrefObject(value)
+                else:
+                    self._prefsdict[key] = value
+
+    def save(self):
+        prefdict = {}
+        for key, value in self._prefsdict.items():
+            if type(value) == types.InstanceType:
+                prefdict[key] = value.getprefsdict()
+                if not prefdict[key]:
+                    del prefdict[key]
+            else:
+                prefdict[key] = value
+        marshal.dump(prefdict, open(self.__path, 'wb'))
+        try:
+            MacOS.SetCreatorAndType(self.__path, self.__creator, 'pref')
+        except:
+            pass
+
+    def __getattr__(self, attr):
+        if attr == '__members__':
+            keys = self._prefsdict.keys()
+            keys.sort()
+            return keys
+        try:
+            return self._prefsdict[attr]
+        except KeyError:
+            if attr[0] <> '_':
+                self._prefsdict[attr] = PrefObject()
+                return self._prefsdict[attr]
+            else:
+                raise AttributeError, attr
 
 
 _prefscache = {}
 
 def GetPrefs(prefname, creator = 'Pyth'):
-	import macostools, os
-	if _prefscache.has_key(prefname):
-		return _prefscache[prefname]
-	# Find the preferences folder and our prefs file, create if needed.
-	fsr = Folder.FSFindFolder(Folders.kOnSystemDisk, 'pref', 1)
-	prefsfolder = fsr.as_pathname()
-	path = os.path.join(prefsfolder, prefname)
-	head, tail = os.path.split(path)
-	# make sure the folder(s) exist
-	macostools.mkdirs(head)
-	
-	preffile = PrefFile(path, creator)
-	_prefscache[prefname] = preffile
-	return preffile
+    import macostools, os
+    if _prefscache.has_key(prefname):
+        return _prefscache[prefname]
+    # Find the preferences folder and our prefs file, create if needed.
+    fsr = Folder.FSFindFolder(Folders.kOnSystemDisk, 'pref', 1)
+    prefsfolder = fsr.as_pathname()
+    path = os.path.join(prefsfolder, prefname)
+    head, tail = os.path.split(path)
+    # make sure the folder(s) exist
+    macostools.mkdirs(head)
+
+    preffile = PrefFile(path, creator)
+    _prefscache[prefname] = preffile
+    return preffile
diff --git a/Mac/Tools/IDE/ModuleBrowser.py b/Mac/Tools/IDE/ModuleBrowser.py
index 0e8850f..9fe1064 100644
--- a/Mac/Tools/IDE/ModuleBrowser.py
+++ b/Mac/Tools/IDE/ModuleBrowser.py
@@ -6,172 +6,172 @@
 __author__ = "jvr"
 
 class _modulebrowser:
-	
-	def __init__(self):
-		self.editmodules = []
-		self.modules = []
-		self.window = W.Window((210, 1000), "Module Browser", minsize = (210, 160), maxsize = (340, 20000))
-		
-		self.window.openbutton = W.Button((10, 8, 90, 16), "Open", self.openbuttonhit)
-		self.window.browsebutton = W.Button((110, 8, 90, 16), "Browse\xc9", self.browsebuttonhit)
-		self.window.reloadbutton = W.Button((10, 32, 90, 16), "Reload", self.reloadbuttonhit)
-		self.window.openotherbutton = W.Button((110, 32, 90, 16), "Open other\xc9", self.openother)
-		
-		self.window.openbutton.enable(0)
-		self.window.reloadbutton.enable(0)
-		self.window.browsebutton.enable(0)
-		self.window.setdefaultbutton(self.window.browsebutton)
-		
-		self.window.bind("cmdr", self.window.reloadbutton.push)
-		self.window.bind("cmdb", self.window.browsebutton.push)
-	
-		self.window.bind("<activate>", self.activate)
-		self.window.bind("<close>", self.close)
-		
-		self.window.list = W.List((-1, 56, 1, -14), [], self.listhit)
-		
-		self.window.open()
-		self.checkbuttons()
-	
-	def close(self):
-		global _browser
-		_browser = None
-	
-	def activate(self, onoff):
-		if onoff:
-			self.makelist()
-		
-	def listhit(self, isdbl):
-		self.checkbuttons()
-		if isdbl:
-			if self.window._defaultbutton:
-				self.window._defaultbutton.push()
-	
-	def checkbuttons(self):
-		sel = self.window.list.getselection()
-		if sel:
-			for i in sel:
-				if self.editmodules[i]:
-					self.window.openbutton.enable(1)
-					self.window.reloadbutton.enable(1)
-					self.window.setdefaultbutton(self.window.openbutton)
-					break
-			else:
-				self.window.openbutton.enable(0)
-				self.window.reloadbutton.enable(0)
-				self.window.setdefaultbutton(self.window.browsebutton)
-			self.window.browsebutton.enable(1)
-		else:
-			#self.window.setdefaultbutton(self.window.browsebutton)
-			self.window.openbutton.enable(0)
-			self.window.reloadbutton.enable(0)
-			self.window.browsebutton.enable(0)
-	
-	def openbuttonhit(self):
-		import imp
-		sel = self.window.list.getselection()
-		W.SetCursor("watch")
-		for i in sel:
-			modname = self.window.list[i]
-			try:
-				self.openscript(sys.modules[modname].__file__, modname)
-			except IOError:
-				try:
-					file, path, description = imp.find_module(modname)
-				except ImportError:
-					W.SetCursor("arrow")
-					W.Message("Can't find file for module '%s'." 
-							% modname)
-				else:
-					self.openscript(path, modname)					
-	
-	def openscript(self, path, modname):
-		import os
-		if path[-3:] == '.py':
-			W.getapplication().openscript(path, modname=modname)
-		elif path[-4:] in ['.pyc', '.pyo']:
-			W.getapplication().openscript(path[:-1], modname=modname)
-		else:
-			W.Message("Can't edit '%s'; it might be a shared library or a .pyc file." 
-					% modname)
-	
-	def openother(self):
-		import imp
-		import EasyDialogs
-		
-		modname = EasyDialogs.AskString("Open module:")
-		if modname:
-			try:
-				file, path, description = imp.find_module(modname)
-			except ImportError:
-				if modname in sys.builtin_module_names:
-					alerttext = "'%s' is a builtin module, which you can't edit." % modname
-				else:
-					alerttext = "No module named '%s'." % modname
-				raise W.AlertError, alerttext
-			self.openscript(path, modname)
-	
-	def reloadbuttonhit(self):
-		sel = self.window.list.getselection()
-		W.SetCursor("watch")
-		for i in sel:
-			mname = self.window.list[i]
-			m = sys.modules[mname]
-			# Set the __name__ attribute of the module to its real name.
-			# reload() complains if it's __main__, which is true
-			# when it recently has been run as a script with "Run as __main__" 
-			# enabled.
-			m.__name__ = mname
-			reload(m)
-	
-	def browsebuttonhit(self):
-		sel = self.window.list.getselection()
-		if not sel:
-			return
-		import PyBrowser
-		for i in sel:
-			PyBrowser.Browser(sys.modules[self.window.list[i]])
-	
-	def makelist(self):
-		editmodules, modules = getmoduleslist()
-		if modules == self.modules:
-			return
-		self.editmodules, self.modules = editmodules, modules
-		self.window.list.setdrawingmode(0)
-		sel = self.window.list.getselectedobjects()
-		self.window.list.set(self.modules)
-		self.window.list.setselectedobjects(sel)
-		self.window.list.setdrawingmode(1)
+
+    def __init__(self):
+        self.editmodules = []
+        self.modules = []
+        self.window = W.Window((210, 1000), "Module Browser", minsize = (210, 160), maxsize = (340, 20000))
+
+        self.window.openbutton = W.Button((10, 8, 90, 16), "Open", self.openbuttonhit)
+        self.window.browsebutton = W.Button((110, 8, 90, 16), "Browse\xc9", self.browsebuttonhit)
+        self.window.reloadbutton = W.Button((10, 32, 90, 16), "Reload", self.reloadbuttonhit)
+        self.window.openotherbutton = W.Button((110, 32, 90, 16), "Open other\xc9", self.openother)
+
+        self.window.openbutton.enable(0)
+        self.window.reloadbutton.enable(0)
+        self.window.browsebutton.enable(0)
+        self.window.setdefaultbutton(self.window.browsebutton)
+
+        self.window.bind("cmdr", self.window.reloadbutton.push)
+        self.window.bind("cmdb", self.window.browsebutton.push)
+
+        self.window.bind("<activate>", self.activate)
+        self.window.bind("<close>", self.close)
+
+        self.window.list = W.List((-1, 56, 1, -14), [], self.listhit)
+
+        self.window.open()
+        self.checkbuttons()
+
+    def close(self):
+        global _browser
+        _browser = None
+
+    def activate(self, onoff):
+        if onoff:
+            self.makelist()
+
+    def listhit(self, isdbl):
+        self.checkbuttons()
+        if isdbl:
+            if self.window._defaultbutton:
+                self.window._defaultbutton.push()
+
+    def checkbuttons(self):
+        sel = self.window.list.getselection()
+        if sel:
+            for i in sel:
+                if self.editmodules[i]:
+                    self.window.openbutton.enable(1)
+                    self.window.reloadbutton.enable(1)
+                    self.window.setdefaultbutton(self.window.openbutton)
+                    break
+            else:
+                self.window.openbutton.enable(0)
+                self.window.reloadbutton.enable(0)
+                self.window.setdefaultbutton(self.window.browsebutton)
+            self.window.browsebutton.enable(1)
+        else:
+            #self.window.setdefaultbutton(self.window.browsebutton)
+            self.window.openbutton.enable(0)
+            self.window.reloadbutton.enable(0)
+            self.window.browsebutton.enable(0)
+
+    def openbuttonhit(self):
+        import imp
+        sel = self.window.list.getselection()
+        W.SetCursor("watch")
+        for i in sel:
+            modname = self.window.list[i]
+            try:
+                self.openscript(sys.modules[modname].__file__, modname)
+            except IOError:
+                try:
+                    file, path, description = imp.find_module(modname)
+                except ImportError:
+                    W.SetCursor("arrow")
+                    W.Message("Can't find file for module '%s'."
+                                    % modname)
+                else:
+                    self.openscript(path, modname)
+
+    def openscript(self, path, modname):
+        import os
+        if path[-3:] == '.py':
+            W.getapplication().openscript(path, modname=modname)
+        elif path[-4:] in ['.pyc', '.pyo']:
+            W.getapplication().openscript(path[:-1], modname=modname)
+        else:
+            W.Message("Can't edit '%s'; it might be a shared library or a .pyc file."
+                            % modname)
+
+    def openother(self):
+        import imp
+        import EasyDialogs
+
+        modname = EasyDialogs.AskString("Open module:")
+        if modname:
+            try:
+                file, path, description = imp.find_module(modname)
+            except ImportError:
+                if modname in sys.builtin_module_names:
+                    alerttext = "'%s' is a builtin module, which you can't edit." % modname
+                else:
+                    alerttext = "No module named '%s'." % modname
+                raise W.AlertError, alerttext
+            self.openscript(path, modname)
+
+    def reloadbuttonhit(self):
+        sel = self.window.list.getselection()
+        W.SetCursor("watch")
+        for i in sel:
+            mname = self.window.list[i]
+            m = sys.modules[mname]
+            # Set the __name__ attribute of the module to its real name.
+            # reload() complains if it's __main__, which is true
+            # when it recently has been run as a script with "Run as __main__"
+            # enabled.
+            m.__name__ = mname
+            reload(m)
+
+    def browsebuttonhit(self):
+        sel = self.window.list.getselection()
+        if not sel:
+            return
+        import PyBrowser
+        for i in sel:
+            PyBrowser.Browser(sys.modules[self.window.list[i]])
+
+    def makelist(self):
+        editmodules, modules = getmoduleslist()
+        if modules == self.modules:
+            return
+        self.editmodules, self.modules = editmodules, modules
+        self.window.list.setdrawingmode(0)
+        sel = self.window.list.getselectedobjects()
+        self.window.list.set(self.modules)
+        self.window.list.setselectedobjects(sel)
+        self.window.list.setdrawingmode(1)
 
 
 def getmoduleslist():
-	import PyBrowser	# for caselesssort function
-	moduleitems = sys.modules.items()
-	moduleitems = filter(lambda (name, module): module is not None, moduleitems)
-	modules = map(lambda (name, module): name, moduleitems)
-	modules = PyBrowser.caselesssort(modules)
-	editmodules = []
-	sysmodules = sys.modules
-	modulesappend = editmodules.append
-	for m in modules:
-		module = sysmodules[m]
-		try:
-			if sysmodules[m].__file__[-3:] == '.py' or \
-					sysmodules[m].__file__[-4:] in ['.pyc', '.pyo']:
-				modulesappend(1)
-			else:
-				modulesappend(0)
-		except AttributeError:
-			modulesappend(0)
-	return editmodules, modules
-	
-	
+    import PyBrowser        # for caselesssort function
+    moduleitems = sys.modules.items()
+    moduleitems = filter(lambda (name, module): module is not None, moduleitems)
+    modules = map(lambda (name, module): name, moduleitems)
+    modules = PyBrowser.caselesssort(modules)
+    editmodules = []
+    sysmodules = sys.modules
+    modulesappend = editmodules.append
+    for m in modules:
+        module = sysmodules[m]
+        try:
+            if sysmodules[m].__file__[-3:] == '.py' or \
+                            sysmodules[m].__file__[-4:] in ['.pyc', '.pyo']:
+                modulesappend(1)
+            else:
+                modulesappend(0)
+        except AttributeError:
+            modulesappend(0)
+    return editmodules, modules
+
+
 
 _browser = None
 
 def ModuleBrowser():
-	global _browser
-	if _browser is not None:
-		_browser.window.select()
-	else:
-		_browser = _modulebrowser()
+    global _browser
+    if _browser is not None:
+        _browser.window.select()
+    else:
+        _browser = _modulebrowser()
diff --git a/Mac/Tools/IDE/PackageManager.py b/Mac/Tools/IDE/PackageManager.py
index ee6355b..0041a17 100755
--- a/Mac/Tools/IDE/PackageManager.py
+++ b/Mac/Tools/IDE/PackageManager.py
@@ -1,37 +1,37 @@
 # Prelude to allow running this as a main program
 def _init():
-	import macresource
-	import sys, os
-	macresource.need('DITL', 468, "PythonIDE.rsrc")
-	widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
-	widgetresfile = os.path.join(*widgetrespathsegs)
-	if not os.path.exists(widgetresfile):
-		widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
-		widgetresfile = os.path.join(*widgetrespathsegs)
-	refno = macresource.need('CURS', 468, widgetresfile)
-	if os.environ.has_key('PYTHONIDEPATH'):
-		# For development set this environment variable
-		ide_path = os.environ['PYTHONIDEPATH']
-	elif refno:
-		# We're not a fullblown application
-		idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
-		ide_path = os.path.join(*idepathsegs)
-		if not os.path.exists(ide_path):
-			idepathsegs = [os.pardir, "Tools", "IDE"]
-			for p in sys.path:
-				ide_path = os.path.join(*([p]+idepathsegs))
-				if os.path.exists(ide_path):
-					break
-		
-	else:
-		# We are a fully frozen application
-		ide_path = sys.argv[0]
-	if ide_path not in sys.path:
-		sys.path.insert(0, ide_path)
-		
+    import macresource
+    import sys, os
+    macresource.need('DITL', 468, "PythonIDE.rsrc")
+    widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
+    widgetresfile = os.path.join(*widgetrespathsegs)
+    if not os.path.exists(widgetresfile):
+        widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
+        widgetresfile = os.path.join(*widgetrespathsegs)
+    refno = macresource.need('CURS', 468, widgetresfile)
+    if os.environ.has_key('PYTHONIDEPATH'):
+        # For development set this environment variable
+        ide_path = os.environ['PYTHONIDEPATH']
+    elif refno:
+        # We're not a fullblown application
+        idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
+        ide_path = os.path.join(*idepathsegs)
+        if not os.path.exists(ide_path):
+            idepathsegs = [os.pardir, "Tools", "IDE"]
+            for p in sys.path:
+                ide_path = os.path.join(*([p]+idepathsegs))
+                if os.path.exists(ide_path):
+                    break
+
+    else:
+        # We are a fully frozen application
+        ide_path = sys.argv[0]
+    if ide_path not in sys.path:
+        sys.path.insert(0, ide_path)
+
 if __name__ == '__main__':
-	_init()
-	
+    _init()
+
 import W
 import Wapplication
 from Carbon import Evt
@@ -48,424 +48,424 @@
 PACKMAN_HOMEPAGE="http://www.python.org/packman"
 
 ELIPSES = '...'
-		
+
 USER_INSTALL_DIR = os.path.join(os.environ.get('HOME', ''),
-								'Library',
-								'Python',
-								sys.version[:3],
-								'site-packages')
-								
+                                                                'Library',
+                                                                'Python',
+                                                                sys.version[:3],
+                                                                'site-packages')
+
 class PackageManagerMain(Wapplication.Application):
-	
-	def __init__(self):
-		self.preffilepath = os.path.join("Python", "Package Install Manager Prefs")
-		Wapplication.Application.__init__(self, 'Pimp')
-		from Carbon import AE
-		from Carbon import AppleEvents
-		self.defaulturl = ""
-		
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication, 
-				self.quitevent)
-		if 1:
-			import PyConsole
-			# With -D option (OSX command line only) keep stderr, for debugging the IDE
-			# itself.
-			debug_stderr = None
-			if len(sys.argv) >= 2 and sys.argv[1] == '-D':
-				debug_stderr = sys.stderr
-				del sys.argv[1]
-			PyConsole.installoutput()
-			if debug_stderr:
-				sys.stderr = debug_stderr
-		self.domenu_openstandard()
-		self.mainloop()
-		
-	def makeusermenus(self):
-		m = Wapplication.Menu(self.menubar, "File")
-		newitem = FrameWork.MenuItem(m, "Open Standard Database", "N", 'openstandard')
-		newexpitem = FrameWork.MenuItem(m, "Open Experimental Database", None, 'openexperimental')
-		newexpitem.enable(pimp.PIMP_VERSION >= "0.4")
-		openitem = FrameWork.MenuItem(m, "Open"+ELIPSES, "O", 'open')
-		openURLitem = FrameWork.MenuItem(m, "Open URL"+ELIPSES, "D", 'openURL')
-		FrameWork.Separator(m)
-		moreinfoitem = FrameWork.MenuItem(m, "More Databases", None, 'opendatabasepage')
-		FrameWork.Separator(m)
-		closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
-##		saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
-##		saveasitem = FrameWork.MenuItem(m, "Save as"+ELIPSES, None, 'save_as')
-##		FrameWork.Separator(m)
-		
-		m = Wapplication.Menu(self.menubar, "Edit")
-		undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
-		FrameWork.Separator(m)
-		cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
-		copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
-		pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
-		FrameWork.MenuItem(m, "Clear", None,  "clear")
-		FrameWork.Separator(m)
-		selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
-		
-		m = Wapplication.Menu(self.menubar, "Package")
-		runitem = FrameWork.MenuItem(m, "Install", "I", 'install')
-		homepageitem = FrameWork.MenuItem(m, "Visit Homepage", None, 'homepage')
-		
-		self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
-		self.makeopenwindowsmenu()
-		self.makehelpmenu()
-		self._menustocheck = [closeitem, 
-				undoitem, cutitem, copyitem, pasteitem, 
-				selallitem,
-				runitem, homepageitem]
-			
-	def makehelpmenu(self):
-		python_app = os.path.join(sys.prefix, 'Resources/Python.app')
-		help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
-		hashelp = os.path.isdir(help_source)
 
-		self.helpmenu = m = self.gethelpmenu()
-		helpitem1 = FrameWork.MenuItem(m, "PackageManager Help", None, self.domenu_packmanhelp)
-		helpitem1.enable(hashelp)
-		helpitem2 = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_pythonhelp)
-		helpitem2.enable(hashelp)
+    def __init__(self):
+        self.preffilepath = os.path.join("Python", "Package Install Manager Prefs")
+        Wapplication.Application.__init__(self, 'Pimp')
+        from Carbon import AE
+        from Carbon import AppleEvents
+        self.defaulturl = ""
 
-	def quitevent(self, theAppleEvent, theReply):
-		self._quit()
-		
-	def ignoreevent(self, theAppleEvent, theReply):
-		pass
-	
-	def opendocsevent(self, theAppleEvent, theReply):
-		W.SetCursor('watch')
-		import aetools
-		parameters, args = aetools.unpackevent(theAppleEvent)
-		docs = parameters['----']
-		if type(docs) <> type([]):
-			docs = [docs]
-		for doc in docs:
-			fsr, a = doc.FSResolveAlias(None)
-			path = fsr.as_pathname()
-			path = urllib.pathname2url(path)
-			self.opendoc(path)
-	
-	def opendoc(self, url):
-		if url:
-			self.defaulturl = url
-		PackageBrowser(url)
-	
-	def getabouttext(self):
-		return "About Package Manager"+ELIPSES
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("Package Install Manager for Python\nPackMan engine (pimp) version: %s" %
-			pimp.PIMP_VERSION)
-	
-	def domenu_openstandard(self, *args):
-		if pimp.PIMP_VERSION >= "0.4":
-			url = pimp.getDefaultDatabase()
-		else:
-			# 0.3 compatibility
-			url = None
-		self.opendoc(url)
-		
-	def domenu_openexperimental(self, *args):
-		database = pimp.getDefaultDatabase(experimental=True)
-		self.opendoc(database)
-		
-	def domenu_open(self, *args):
-		filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
-		if filename:
-			filename = urllib.pathname2url(filename)
-			self.opendoc(filename)
-			
-	def domenu_openURL(self, *args):
-		ok = EasyDialogs.AskYesNoCancel(
-			"Warning: by opening a non-standard database "
-			"you are trusting the maintainer of it "
-			"to run arbitrary code on your machine.",
-			yes="OK", no="")
-		if ok <= 0: return
-		url = EasyDialogs.AskString("URL of database to open:", 
-			default=self.defaulturl, ok="Open")
-		if url:
-			self.opendoc(url)
-	
-	def domenu_opendatabasepage(self):
-		import ic
-			
-		icr = ic.IC()
-		icr.launchurl(PACKMAN_HOMEPAGE)
-	def makeopenwindowsmenu(self):
-		for i in range(len(self.openwindowsmenu.items)):
-			self.openwindowsmenu.menu.DeleteMenuItem(1)
-			self.openwindowsmenu.items = []
-		windows = []
-		self._openwindows = {}
-		for window in self._windows.keys():
-			title = window.GetWTitle()
-			if not title:
-				title = "<no title>"
-			windows.append((title, window))
-		windows.sort()
-		for title, window in windows:
-			shortcut = None
-			item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
-			self._openwindows[item.item] = window
-		self._openwindowscheckmark = 0
-		self.checkopenwindowsmenu()
-		
-	def domenu_openwindows(self, id, item, window, event):
-		w = self._openwindows[item]
-		w.ShowWindow()
-		w.SelectWindow()
-	
-	def domenu_quit(self):
-		self._quit()
-	
-	def domenu_save(self, *args):
-		print "Save"
-	
-	def domenu_pythonhelp(self, *args):
-		from Carbon import AH
-		AH.AHGotoPage("MacPython Help", None, None)
-		
-	def domenu_packmanhelp(self, *args):
-		from Carbon import AH
-		AH.AHGotoPage("MacPython Help", "packman.html", None)
-		
-	def _quit(self):
-##		import PyConsole, PyEdit
-		for window in self._windows.values():
-			try:
-				rv = window.close() # ignore any errors while quitting
-			except:
-				rv = 0	 # (otherwise, we can get stuck!)
-			if rv and rv > 0:
-				return
-##		try:
-##			PyConsole.console.writeprefs()
-##			PyConsole.output.writeprefs()
-##			PyEdit.searchengine.writeprefs()
-##		except:
-##			# Write to __stderr__ so the msg end up in Console.app and has
-##			# at least _some_ chance of getting read...
-##			# But: this is a workaround for way more serious problems with
-##			# the Python 2.2 Jaguar addon.
-##			sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
-		self.quitting = 1
-		
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication,
+                        self.quitevent)
+        if 1:
+            import PyConsole
+            # With -D option (OSX command line only) keep stderr, for debugging the IDE
+            # itself.
+            debug_stderr = None
+            if len(sys.argv) >= 2 and sys.argv[1] == '-D':
+                debug_stderr = sys.stderr
+                del sys.argv[1]
+            PyConsole.installoutput()
+            if debug_stderr:
+                sys.stderr = debug_stderr
+        self.domenu_openstandard()
+        self.mainloop()
+
+    def makeusermenus(self):
+        m = Wapplication.Menu(self.menubar, "File")
+        newitem = FrameWork.MenuItem(m, "Open Standard Database", "N", 'openstandard')
+        newexpitem = FrameWork.MenuItem(m, "Open Experimental Database", None, 'openexperimental')
+        newexpitem.enable(pimp.PIMP_VERSION >= "0.4")
+        openitem = FrameWork.MenuItem(m, "Open"+ELIPSES, "O", 'open')
+        openURLitem = FrameWork.MenuItem(m, "Open URL"+ELIPSES, "D", 'openURL')
+        FrameWork.Separator(m)
+        moreinfoitem = FrameWork.MenuItem(m, "More Databases", None, 'opendatabasepage')
+        FrameWork.Separator(m)
+        closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
+##              saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
+##              saveasitem = FrameWork.MenuItem(m, "Save as"+ELIPSES, None, 'save_as')
+##              FrameWork.Separator(m)
+
+        m = Wapplication.Menu(self.menubar, "Edit")
+        undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
+        FrameWork.Separator(m)
+        cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
+        copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
+        pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
+        FrameWork.MenuItem(m, "Clear", None,  "clear")
+        FrameWork.Separator(m)
+        selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
+
+        m = Wapplication.Menu(self.menubar, "Package")
+        runitem = FrameWork.MenuItem(m, "Install", "I", 'install')
+        homepageitem = FrameWork.MenuItem(m, "Visit Homepage", None, 'homepage')
+
+        self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
+        self.makeopenwindowsmenu()
+        self.makehelpmenu()
+        self._menustocheck = [closeitem,
+                        undoitem, cutitem, copyitem, pasteitem,
+                        selallitem,
+                        runitem, homepageitem]
+
+    def makehelpmenu(self):
+        python_app = os.path.join(sys.prefix, 'Resources/Python.app')
+        help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
+        hashelp = os.path.isdir(help_source)
+
+        self.helpmenu = m = self.gethelpmenu()
+        helpitem1 = FrameWork.MenuItem(m, "PackageManager Help", None, self.domenu_packmanhelp)
+        helpitem1.enable(hashelp)
+        helpitem2 = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_pythonhelp)
+        helpitem2.enable(hashelp)
+
+    def quitevent(self, theAppleEvent, theReply):
+        self._quit()
+
+    def ignoreevent(self, theAppleEvent, theReply):
+        pass
+
+    def opendocsevent(self, theAppleEvent, theReply):
+        W.SetCursor('watch')
+        import aetools
+        parameters, args = aetools.unpackevent(theAppleEvent)
+        docs = parameters['----']
+        if type(docs) <> type([]):
+            docs = [docs]
+        for doc in docs:
+            fsr, a = doc.FSResolveAlias(None)
+            path = fsr.as_pathname()
+            path = urllib.pathname2url(path)
+            self.opendoc(path)
+
+    def opendoc(self, url):
+        if url:
+            self.defaulturl = url
+        PackageBrowser(url)
+
+    def getabouttext(self):
+        return "About Package Manager"+ELIPSES
+
+    def do_about(self, id, item, window, event):
+        EasyDialogs.Message("Package Install Manager for Python\nPackMan engine (pimp) version: %s" %
+                pimp.PIMP_VERSION)
+
+    def domenu_openstandard(self, *args):
+        if pimp.PIMP_VERSION >= "0.4":
+            url = pimp.getDefaultDatabase()
+        else:
+            # 0.3 compatibility
+            url = None
+        self.opendoc(url)
+
+    def domenu_openexperimental(self, *args):
+        database = pimp.getDefaultDatabase(experimental=True)
+        self.opendoc(database)
+
+    def domenu_open(self, *args):
+        filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
+        if filename:
+            filename = urllib.pathname2url(filename)
+            self.opendoc(filename)
+
+    def domenu_openURL(self, *args):
+        ok = EasyDialogs.AskYesNoCancel(
+                "Warning: by opening a non-standard database "
+                "you are trusting the maintainer of it "
+                "to run arbitrary code on your machine.",
+                yes="OK", no="")
+        if ok <= 0: return
+        url = EasyDialogs.AskString("URL of database to open:",
+                default=self.defaulturl, ok="Open")
+        if url:
+            self.opendoc(url)
+
+    def domenu_opendatabasepage(self):
+        import ic
+
+        icr = ic.IC()
+        icr.launchurl(PACKMAN_HOMEPAGE)
+    def makeopenwindowsmenu(self):
+        for i in range(len(self.openwindowsmenu.items)):
+            self.openwindowsmenu.menu.DeleteMenuItem(1)
+            self.openwindowsmenu.items = []
+        windows = []
+        self._openwindows = {}
+        for window in self._windows.keys():
+            title = window.GetWTitle()
+            if not title:
+                title = "<no title>"
+            windows.append((title, window))
+        windows.sort()
+        for title, window in windows:
+            shortcut = None
+            item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
+            self._openwindows[item.item] = window
+        self._openwindowscheckmark = 0
+        self.checkopenwindowsmenu()
+
+    def domenu_openwindows(self, id, item, window, event):
+        w = self._openwindows[item]
+        w.ShowWindow()
+        w.SelectWindow()
+
+    def domenu_quit(self):
+        self._quit()
+
+    def domenu_save(self, *args):
+        print "Save"
+
+    def domenu_pythonhelp(self, *args):
+        from Carbon import AH
+        AH.AHGotoPage("MacPython Help", None, None)
+
+    def domenu_packmanhelp(self, *args):
+        from Carbon import AH
+        AH.AHGotoPage("MacPython Help", "packman.html", None)
+
+    def _quit(self):
+##              import PyConsole, PyEdit
+        for window in self._windows.values():
+            try:
+                rv = window.close() # ignore any errors while quitting
+            except:
+                rv = 0   # (otherwise, we can get stuck!)
+            if rv and rv > 0:
+                return
+##              try:
+##                      PyConsole.console.writeprefs()
+##                      PyConsole.output.writeprefs()
+##                      PyEdit.searchengine.writeprefs()
+##              except:
+##                      # Write to __stderr__ so the msg end up in Console.app and has
+##                      # at least _some_ chance of getting read...
+##                      # But: this is a workaround for way more serious problems with
+##                      # the Python 2.2 Jaguar addon.
+##                      sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
+        self.quitting = 1
+
 class PimpInterface:
 
-	def setuppimp(self, url):
-		self.pimpprefs = pimp.PimpPreferences()
-		self.pimpdb = pimp.PimpDatabase(self.pimpprefs)
-		if not url:
-			url = self.pimpprefs.pimpDatabase
-		try:
-			self.pimpdb.appendURL(url)
-		except IOError, arg:
-			rv = "Cannot open %s: %s\n" % (url, arg)
-			rv += "\nSee MacPython Package Manager help page."
-			return rv
-		except:
-			rv = "Unspecified error while parsing database: %s\n" % url
-			rv += "Usually, this means the database is not correctly formatted.\n"
-			rv += "\nSee MacPython Package Manager help page."
-			return rv
-		# Check whether we can write the installation directory.
-		# If not, set to the per-user directory, possibly
-		# creating it, if needed.
-		installDir = self.pimpprefs.installDir
-		if not os.access(installDir, os.R_OK|os.W_OK|os.X_OK):
-			rv = self.setuserinstall(1)
-			if rv: return rv
-		return self.pimpprefs.check()
-		
-	def closepimp(self):
-		self.pimpdb.close()
-		self.pimpprefs = None
-		self.pimpdb = None
-		self.packages = []
+    def setuppimp(self, url):
+        self.pimpprefs = pimp.PimpPreferences()
+        self.pimpdb = pimp.PimpDatabase(self.pimpprefs)
+        if not url:
+            url = self.pimpprefs.pimpDatabase
+        try:
+            self.pimpdb.appendURL(url)
+        except IOError, arg:
+            rv = "Cannot open %s: %s\n" % (url, arg)
+            rv += "\nSee MacPython Package Manager help page."
+            return rv
+        except:
+            rv = "Unspecified error while parsing database: %s\n" % url
+            rv += "Usually, this means the database is not correctly formatted.\n"
+            rv += "\nSee MacPython Package Manager help page."
+            return rv
+        # Check whether we can write the installation directory.
+        # If not, set to the per-user directory, possibly
+        # creating it, if needed.
+        installDir = self.pimpprefs.installDir
+        if not os.access(installDir, os.R_OK|os.W_OK|os.X_OK):
+            rv = self.setuserinstall(1)
+            if rv: return rv
+        return self.pimpprefs.check()
 
-	def setuserinstall(self, onoff):
-		rv = ""
-		if onoff:
-			if not os.path.exists(USER_INSTALL_DIR):
-				try:
-					os.makedirs(USER_INSTALL_DIR)
-				except OSError, arg:
-					rv = rv + arg + "\n"
-			if not USER_INSTALL_DIR in sys.path:
-				import site
-				reload(site)
-			self.pimpprefs.setInstallDir(USER_INSTALL_DIR)
-		else:
-			self.pimpprefs.setInstallDir(None)
-		rv = rv + self.pimpprefs.check()
-		return rv
-		
-	def getuserinstall(self):
-		return self.pimpprefs.installDir == USER_INSTALL_DIR
-			
-	def getbrowserdata(self, show_hidden=1):
-		packages = self.pimpdb.list()
-		if show_hidden:
-			self.packages = packages
-		else:
-			self.packages = []
-			for pkg in packages:
-				name = pkg.fullname()
-				if name[0] == '(' and name[-1] == ')' and not show_hidden:
-					continue
-				self.packages.append(pkg)			
-		rv = []
-		for pkg in self.packages:
-			name = pkg.fullname()
-			status, _ = pkg.installed()
-			description = pkg.description()
-			description_line1 = description.split('\n')[0]
-			rv.append((status, name, description_line1))
-		return rv
-		
-	def getstatus(self, number):
-		pkg = self.packages[number]
-		return pkg.installed()
-		
-	def installpackage(self, sel, output, recursive, force):
-		pkg = self.packages[sel]
-		pimpinstaller = pimp.PimpInstaller(self.pimpdb)
-		list, messages = pimpinstaller.prepareInstall(pkg, force, recursive)
-		if messages:
-			return messages
-		messages = pimpinstaller.install(list, output)
-		return messages
-			
+    def closepimp(self):
+        self.pimpdb.close()
+        self.pimpprefs = None
+        self.pimpdb = None
+        self.packages = []
+
+    def setuserinstall(self, onoff):
+        rv = ""
+        if onoff:
+            if not os.path.exists(USER_INSTALL_DIR):
+                try:
+                    os.makedirs(USER_INSTALL_DIR)
+                except OSError, arg:
+                    rv = rv + arg + "\n"
+            if not USER_INSTALL_DIR in sys.path:
+                import site
+                reload(site)
+            self.pimpprefs.setInstallDir(USER_INSTALL_DIR)
+        else:
+            self.pimpprefs.setInstallDir(None)
+        rv = rv + self.pimpprefs.check()
+        return rv
+
+    def getuserinstall(self):
+        return self.pimpprefs.installDir == USER_INSTALL_DIR
+
+    def getbrowserdata(self, show_hidden=1):
+        packages = self.pimpdb.list()
+        if show_hidden:
+            self.packages = packages
+        else:
+            self.packages = []
+            for pkg in packages:
+                name = pkg.fullname()
+                if name[0] == '(' and name[-1] == ')' and not show_hidden:
+                    continue
+                self.packages.append(pkg)
+        rv = []
+        for pkg in self.packages:
+            name = pkg.fullname()
+            status, _ = pkg.installed()
+            description = pkg.description()
+            description_line1 = description.split('\n')[0]
+            rv.append((status, name, description_line1))
+        return rv
+
+    def getstatus(self, number):
+        pkg = self.packages[number]
+        return pkg.installed()
+
+    def installpackage(self, sel, output, recursive, force):
+        pkg = self.packages[sel]
+        pimpinstaller = pimp.PimpInstaller(self.pimpdb)
+        list, messages = pimpinstaller.prepareInstall(pkg, force, recursive)
+        if messages:
+            return messages
+        messages = pimpinstaller.install(list, output)
+        return messages
+
 class PackageBrowser(PimpInterface):
-	
-	def __init__(self, url = None):
-		self.ic = None
-		messages = self.setuppimp(url)
-		self.setupwidgets()
-		self.updatestatus()
-		self.showmessages(messages)
-		
-	def close(self):
-		self.closepimp()
-	
-	def setupwidgets(self):
-		DESCRIPTION_HEIGHT = 140
-		INSTALL_POS = -30
-		STATUS_POS = INSTALL_POS - (70 + DESCRIPTION_HEIGHT)
-		self.w = W.Window((580, 600), "Python Install Manager", minsize = (400, 400), tabbable = 0)
-		self.w.titlebar = W.TextBox((4, 8, 60, 18), 'Packages:')
-		self.w.hidden_button = W.CheckBox((-100, 4, 0, 18), 'Show Hidden', self.updatestatus)
-		data = self.getbrowserdata()
-		self.w.packagebrowser = W.MultiList((4, 24, 0, STATUS_POS-2), data, self.listhit, cols=3)
-		
-		self.w.installed_l = W.TextBox((4, STATUS_POS, 70, 12), 'Installed:')
-		self.w.installed = W.TextBox((74, STATUS_POS, 0, 12), '')
-		self.w.message_l = W.TextBox((4, STATUS_POS+20, 70, 12), 'Status:')
-		self.w.message = W.TextBox((74, STATUS_POS+20, 0, 12), '')
-		self.w.homepage_button = W.Button((4, STATUS_POS+40, 96, 18), 'View homepage', self.do_homepage)
-		self.w.description_l = W.TextBox((4, STATUS_POS+70, 70, 12), 'Description:')
-		self.w.description = W.EditText((74, STATUS_POS+70, 0, DESCRIPTION_HEIGHT-4))
-		
-		self.w.divline = W.HorizontalLine((0, INSTALL_POS-4, 0, 0))
-		self.w.verbose_button = W.CheckBox((84, INSTALL_POS+4, 60, 18), 'Verbose')
-		self.w.recursive_button = W.CheckBox((146, INSTALL_POS+4, 120, 18), 'Install dependencies', self.updatestatus)
-		self.w.recursive_button.set(1)
-		self.w.force_button = W.CheckBox((268, INSTALL_POS+4, 70, 18), 'Overwrite', self.updatestatus)
-		self.w.user_button = W.CheckBox((340, INSTALL_POS+4, 140, 18), 'For Current User Only', self.do_user)
-		self.w.install_button = W.Button((4, INSTALL_POS+4, 56, 18), 'Install:', self.do_install)
-		self.w.open()
-		self.w.description.enable(0)
-		
-	def updatestatus(self):
-		topcell = self.w.packagebrowser.gettopcell()
-		sel = self.w.packagebrowser.getselection()
-		data = self.getbrowserdata(self.w.hidden_button.get())
-		self.w.packagebrowser.setitems(data)
-		self.w.user_button.set(self.getuserinstall())
-		if len(sel) != 1:
-			self.w.installed.set('')
-			self.w.message.set('')
-			self.w.install_button.enable(0)
-			self.w.homepage_button.enable(0)
-			self.w.description.set('')
-			self.w.verbose_button.enable(0)
-			self.w.recursive_button.enable(0)
-			self.w.force_button.enable(0)
-			self.w.user_button.enable(0)
-		else:
-			sel = sel[0]
-			if sel >= len(self.packages):
-				sel = 0
-			self.w.packagebrowser.setselection([sel])
-			installed, message = self.getstatus(sel)
-			self.w.installed.set(installed)
-			self.w.message.set(message)
-			self.w.install_button.enable(installed != "yes" or self.w.force_button.get())
-			self.w.homepage_button.enable(not not self.packages[sel].homepage())
-			description = self.packages[sel].description()
-			description = description.splitlines()
-			description = '\r'.join(description)
-			self.w.description.set(description)
-			self.w.verbose_button.enable(1)
-			self.w.recursive_button.enable(1)
-			self.w.force_button.enable(1)
-			self.w.user_button.enable(1)
-		self.w.packagebrowser.settopcell(topcell)
-		
-	def listhit(self, *args, **kwargs):
-		self.updatestatus()
-		
-	def do_install(self):
-		sel = self.w.packagebrowser.getselection()[0]
-		if self.w.verbose_button.get():
-			output = sys.stdout
-		else:
-			output = None
-		recursive = self.w.recursive_button.get()
-		force = self.w.force_button.get()
-		messages = self.installpackage(sel, output, recursive, force)
-		
-		# Re-read .pth files
-		import site
-		reload(site)
-		
-		self.updatestatus()
-		self.showmessages(messages)
-		
-	def showmessages(self, messages):
-		if messages:
-			# To be on the safe side we always show the hidden packages,
-			# they may be referred to in the error messages.
-			if not self.w.hidden_button.get():
-				self.w.hidden_button.set(1)
-				self.updatestatus()
-			if type(messages) == list:
-				messages = '\n'.join(messages)
-			if self.w.verbose_button.get():
-				sys.stdout.write(messages + '\n')
-			EasyDialogs.Message(messages)
-		
-	def do_homepage(self):
-		sel = self.w.packagebrowser.getselection()[0]
-		if not self.ic:
-			import ic
-			
-			self.ic = ic.IC()
-		self.ic.launchurl(self.packages[sel].homepage())
-		
-	def do_user(self):
-		messages = self.setuserinstall(self.w.user_button.get())
-		self.updatestatus()
-		self.showmessages(messages)
-		
+
+    def __init__(self, url = None):
+        self.ic = None
+        messages = self.setuppimp(url)
+        self.setupwidgets()
+        self.updatestatus()
+        self.showmessages(messages)
+
+    def close(self):
+        self.closepimp()
+
+    def setupwidgets(self):
+        DESCRIPTION_HEIGHT = 140
+        INSTALL_POS = -30
+        STATUS_POS = INSTALL_POS - (70 + DESCRIPTION_HEIGHT)
+        self.w = W.Window((580, 600), "Python Install Manager", minsize = (400, 400), tabbable = 0)
+        self.w.titlebar = W.TextBox((4, 8, 60, 18), 'Packages:')
+        self.w.hidden_button = W.CheckBox((-100, 4, 0, 18), 'Show Hidden', self.updatestatus)
+        data = self.getbrowserdata()
+        self.w.packagebrowser = W.MultiList((4, 24, 0, STATUS_POS-2), data, self.listhit, cols=3)
+
+        self.w.installed_l = W.TextBox((4, STATUS_POS, 70, 12), 'Installed:')
+        self.w.installed = W.TextBox((74, STATUS_POS, 0, 12), '')
+        self.w.message_l = W.TextBox((4, STATUS_POS+20, 70, 12), 'Status:')
+        self.w.message = W.TextBox((74, STATUS_POS+20, 0, 12), '')
+        self.w.homepage_button = W.Button((4, STATUS_POS+40, 96, 18), 'View homepage', self.do_homepage)
+        self.w.description_l = W.TextBox((4, STATUS_POS+70, 70, 12), 'Description:')
+        self.w.description = W.EditText((74, STATUS_POS+70, 0, DESCRIPTION_HEIGHT-4))
+
+        self.w.divline = W.HorizontalLine((0, INSTALL_POS-4, 0, 0))
+        self.w.verbose_button = W.CheckBox((84, INSTALL_POS+4, 60, 18), 'Verbose')
+        self.w.recursive_button = W.CheckBox((146, INSTALL_POS+4, 120, 18), 'Install dependencies', self.updatestatus)
+        self.w.recursive_button.set(1)
+        self.w.force_button = W.CheckBox((268, INSTALL_POS+4, 70, 18), 'Overwrite', self.updatestatus)
+        self.w.user_button = W.CheckBox((340, INSTALL_POS+4, 140, 18), 'For Current User Only', self.do_user)
+        self.w.install_button = W.Button((4, INSTALL_POS+4, 56, 18), 'Install:', self.do_install)
+        self.w.open()
+        self.w.description.enable(0)
+
+    def updatestatus(self):
+        topcell = self.w.packagebrowser.gettopcell()
+        sel = self.w.packagebrowser.getselection()
+        data = self.getbrowserdata(self.w.hidden_button.get())
+        self.w.packagebrowser.setitems(data)
+        self.w.user_button.set(self.getuserinstall())
+        if len(sel) != 1:
+            self.w.installed.set('')
+            self.w.message.set('')
+            self.w.install_button.enable(0)
+            self.w.homepage_button.enable(0)
+            self.w.description.set('')
+            self.w.verbose_button.enable(0)
+            self.w.recursive_button.enable(0)
+            self.w.force_button.enable(0)
+            self.w.user_button.enable(0)
+        else:
+            sel = sel[0]
+            if sel >= len(self.packages):
+                sel = 0
+            self.w.packagebrowser.setselection([sel])
+            installed, message = self.getstatus(sel)
+            self.w.installed.set(installed)
+            self.w.message.set(message)
+            self.w.install_button.enable(installed != "yes" or self.w.force_button.get())
+            self.w.homepage_button.enable(not not self.packages[sel].homepage())
+            description = self.packages[sel].description()
+            description = description.splitlines()
+            description = '\r'.join(description)
+            self.w.description.set(description)
+            self.w.verbose_button.enable(1)
+            self.w.recursive_button.enable(1)
+            self.w.force_button.enable(1)
+            self.w.user_button.enable(1)
+        self.w.packagebrowser.settopcell(topcell)
+
+    def listhit(self, *args, **kwargs):
+        self.updatestatus()
+
+    def do_install(self):
+        sel = self.w.packagebrowser.getselection()[0]
+        if self.w.verbose_button.get():
+            output = sys.stdout
+        else:
+            output = None
+        recursive = self.w.recursive_button.get()
+        force = self.w.force_button.get()
+        messages = self.installpackage(sel, output, recursive, force)
+
+        # Re-read .pth files
+        import site
+        reload(site)
+
+        self.updatestatus()
+        self.showmessages(messages)
+
+    def showmessages(self, messages):
+        if messages:
+            # To be on the safe side we always show the hidden packages,
+            # they may be referred to in the error messages.
+            if not self.w.hidden_button.get():
+                self.w.hidden_button.set(1)
+                self.updatestatus()
+            if type(messages) == list:
+                messages = '\n'.join(messages)
+            if self.w.verbose_button.get():
+                sys.stdout.write(messages + '\n')
+            EasyDialogs.Message(messages)
+
+    def do_homepage(self):
+        sel = self.w.packagebrowser.getselection()[0]
+        if not self.ic:
+            import ic
+
+            self.ic = ic.IC()
+        self.ic.launchurl(self.packages[sel].homepage())
+
+    def do_user(self):
+        messages = self.setuserinstall(self.w.user_button.get())
+        self.updatestatus()
+        self.showmessages(messages)
+
 if __name__ == '__main__':
-	PackageManagerMain()
+    PackageManagerMain()
diff --git a/Mac/Tools/IDE/ProfileBrowser.py b/Mac/Tools/IDE/ProfileBrowser.py
index a19641c..a2dafdd 100644
--- a/Mac/Tools/IDE/ProfileBrowser.py
+++ b/Mac/Tools/IDE/ProfileBrowser.py
@@ -9,84 +9,84 @@
 
 # increase precision
 def f8(x):
-	return string.rjust(fpformat.fix(x, 4), 8)
+    return string.rjust(fpformat.fix(x, 4), 8)
 pstats.f8 = f8
 
 # hacking around a hack
 if sys.version[:3] > '1.4':
-	timer = Evt.TickCount
+    timer = Evt.TickCount
 else:
-	def timer(TickCount = Evt.TickCount):
-		return TickCount() / 60.0
+    def timer(TickCount = Evt.TickCount):
+        return TickCount() / 60.0
 
 class ProfileBrowser:
-	
-	def __init__(self, stats = None):
-		self.sortkeys = ('calls',)
-		self.setupwidgets()
-		self.setstats(stats)
-	
-	def setupwidgets(self): 
-		self.w = W.Window((580, 400), "Profile Statistics", minsize = (200, 100), tabbable = 0)
-		self.w.divline = W.HorizontalLine((0, 20, 0, 0))
-		self.w.titlebar = W.TextBox((4, 4, 40, 12), 'Sort by:')
-		self.buttons = []
-		x = 54
-		width1 = 50
-		width2 = 75
-		for name in ["calls", "time", "cumulative", "stdname", "file", "line", "name"]:
-			if len(name) > 6:
-				width = width2
-			else:
-				width = width1
-			self.w["button_" + name] = W.RadioButton((x, 4, width, 12), name, self.buttons, self.setsort)
-			x += width + 10
-		self.w.button_calls.set(1)
-		self.w.text = W.TextEditor((0, 21, -15, -15), inset = (6, 5), 
-				readonly = 1, wrap = 0, fontsettings = ('Monaco', 0, 9, (0, 0, 0)))
-		self.w._bary = W.Scrollbar((-15, 20, 16, -14), self.w.text.vscroll, max = 32767)
-		self.w._barx = W.Scrollbar((-1, -15, -14, 16), self.w.text.hscroll, max = 32767)
-		self.w.open()
-	
-	def setstats(self, stats):
-		self.stats = stats
-		self.stats.strip_dirs()
-		self.displaystats()
-	
-	def setsort(self):
-		# Grmpf. The callback doesn't give us the button:-(
-		for b in self.buttons:
-			if b.get():
-				if b._title == self.sortkeys[0]:
-					return
-				self.sortkeys = (b._title,) + self.sortkeys[:3]
-				break
-		self.displaystats()
-	
-	def displaystats(self):
-		W.SetCursor('watch')
-		apply(self.stats.sort_stats, self.sortkeys)
-		saveout = sys.stdout
-		try:
-			s = sys.stdout = StringIO.StringIO()
-			self.stats.print_stats()
-		finally:
-			sys.stdout = saveout
-		text = string.join(string.split(s.getvalue(), '\n'), '\r')
-		self.w.text.set(text)
+
+    def __init__(self, stats = None):
+        self.sortkeys = ('calls',)
+        self.setupwidgets()
+        self.setstats(stats)
+
+    def setupwidgets(self):
+        self.w = W.Window((580, 400), "Profile Statistics", minsize = (200, 100), tabbable = 0)
+        self.w.divline = W.HorizontalLine((0, 20, 0, 0))
+        self.w.titlebar = W.TextBox((4, 4, 40, 12), 'Sort by:')
+        self.buttons = []
+        x = 54
+        width1 = 50
+        width2 = 75
+        for name in ["calls", "time", "cumulative", "stdname", "file", "line", "name"]:
+            if len(name) > 6:
+                width = width2
+            else:
+                width = width1
+            self.w["button_" + name] = W.RadioButton((x, 4, width, 12), name, self.buttons, self.setsort)
+            x += width + 10
+        self.w.button_calls.set(1)
+        self.w.text = W.TextEditor((0, 21, -15, -15), inset = (6, 5),
+                        readonly = 1, wrap = 0, fontsettings = ('Monaco', 0, 9, (0, 0, 0)))
+        self.w._bary = W.Scrollbar((-15, 20, 16, -14), self.w.text.vscroll, max = 32767)
+        self.w._barx = W.Scrollbar((-1, -15, -14, 16), self.w.text.hscroll, max = 32767)
+        self.w.open()
+
+    def setstats(self, stats):
+        self.stats = stats
+        self.stats.strip_dirs()
+        self.displaystats()
+
+    def setsort(self):
+        # Grmpf. The callback doesn't give us the button:-(
+        for b in self.buttons:
+            if b.get():
+                if b._title == self.sortkeys[0]:
+                    return
+                self.sortkeys = (b._title,) + self.sortkeys[:3]
+                break
+        self.displaystats()
+
+    def displaystats(self):
+        W.SetCursor('watch')
+        apply(self.stats.sort_stats, self.sortkeys)
+        saveout = sys.stdout
+        try:
+            s = sys.stdout = StringIO.StringIO()
+            self.stats.print_stats()
+        finally:
+            sys.stdout = saveout
+        text = string.join(string.split(s.getvalue(), '\n'), '\r')
+        self.w.text.set(text)
 
 
 def main():
-	import pstats
-	args = sys.argv[1:]
-	for i in args:
-		stats = pstats.Stats(i)
-		browser = ProfileBrowser(stats)
-	else:
-		filename = EasyDialogs.AskFileForOpen(message='Profiler data')
-		if not filename: sys.exit(0)
-		stats = pstats.Stats(filename)
-		browser = ProfileBrowser(stats)
+    import pstats
+    args = sys.argv[1:]
+    for i in args:
+        stats = pstats.Stats(i)
+        browser = ProfileBrowser(stats)
+    else:
+        filename = EasyDialogs.AskFileForOpen(message='Profiler data')
+        if not filename: sys.exit(0)
+        stats = pstats.Stats(filename)
+        browser = ProfileBrowser(stats)
 
 if __name__ == '__main__':
-	main()
+    main()
diff --git a/Mac/Tools/IDE/PyBrowser.py b/Mac/Tools/IDE/PyBrowser.py
index 397347e..0ad3a9a 100644
--- a/Mac/Tools/IDE/PyBrowser.py
+++ b/Mac/Tools/IDE/PyBrowser.py
@@ -18,600 +18,599 @@
 
 has_ctlcharsRE = re.compile(r'[\000-\037\177-\377]')
 def ctlcharsREsearch(str):
-	if has_ctlcharsRE.search(str) is None:
-		return -1
-	return 1
-	
-def double_repr(key, value, truncvalue = 0, 
-			type = type, StringType = types.StringType,
-			has_ctlchars = ctlcharsREsearch, _repr = repr, str = str):
-	if type(key) == StringType and has_ctlchars(key) < 0:
-		key = str(key)
-	else:
-		key = _repr(key)
-	if key == '__builtins__':
-		value = "<" + type(value).__name__ + " '__builtin__'>"
-	elif key == '__return__':
-		# bleh, when returning from a class codeblock we get infinite recursion in repr. 
-		# Use safe repr instead.
-		import repr
-		value = repr.repr(value)
-	else:
-		try:
-			value = _repr(value)
-			'' + value	# test to see if it is a string, in case a __repr__ method is buggy
-		except:
-			value = '\xa5\xa5\xa5 exception in repr()'
-	if truncvalue:
-		return key + '\t' + value[:255]
-	return key + '\t' + value
+    if has_ctlcharsRE.search(str) is None:
+        return -1
+    return 1
+
+def double_repr(key, value, truncvalue = 0,
+                        type = type, StringType = types.StringType,
+                        has_ctlchars = ctlcharsREsearch, _repr = repr, str = str):
+    if type(key) == StringType and has_ctlchars(key) < 0:
+        key = str(key)
+    else:
+        key = _repr(key)
+    if key == '__builtins__':
+        value = "<" + type(value).__name__ + " '__builtin__'>"
+    elif key == '__return__':
+        # bleh, when returning from a class codeblock we get infinite recursion in repr.
+        # Use safe repr instead.
+        import repr
+        value = repr.repr(value)
+    else:
+        try:
+            value = _repr(value)
+            '' + value      # test to see if it is a string, in case a __repr__ method is buggy
+        except:
+            value = '\xa5\xa5\xa5 exception in repr()'
+    if truncvalue:
+        return key + '\t' + value[:255]
+    return key + '\t' + value
 
 
 def truncString(s, maxwid):
-	if maxwid < 1:
-		return 1, ""
-	strlen = len(s)
-	strwid = Qd.TextWidth(s, 0, strlen);
-	if strwid <= maxwid:
-		return 0, s
-	
-	Qd.TextFace(QuickDraw.condense)
-	strwid = Qd.TextWidth(s, 0, strlen)
-	ellipsis = Qd.StringWidth('\xc9')
-	
-	if strwid <= maxwid:
-		Qd.TextFace(0)
-		return 1, s
-	if strwid < 1:
-		Qd.TextFace(0)
-		return 1, ""
-	
-	mid = int(strlen * maxwid / strwid)
-	while 1:
-		if mid <= 0:
-			mid = 0
-			break
-		strwid = Qd.TextWidth(s, 0, mid) + ellipsis
-		strwid2 = Qd.TextWidth(s, 0, mid + 1) + ellipsis
-		if strwid <= maxwid and maxwid <= strwid2:
-			if maxwid == strwid2:
-				mid += 1
-			break
-		if strwid > maxwid:
-			mid -= 1
-			if mid <= 0:
-				mid = 0
-				break
-		elif strwid2 < maxwid:
-			mid += 1
-	Qd.TextFace(0)
-	return 1, s[:mid] + '\xc9'
+    if maxwid < 1:
+        return 1, ""
+    strlen = len(s)
+    strwid = Qd.TextWidth(s, 0, strlen);
+    if strwid <= maxwid:
+        return 0, s
+
+    Qd.TextFace(QuickDraw.condense)
+    strwid = Qd.TextWidth(s, 0, strlen)
+    ellipsis = Qd.StringWidth('\xc9')
+
+    if strwid <= maxwid:
+        Qd.TextFace(0)
+        return 1, s
+    if strwid < 1:
+        Qd.TextFace(0)
+        return 1, ""
+
+    mid = int(strlen * maxwid / strwid)
+    while 1:
+        if mid <= 0:
+            mid = 0
+            break
+        strwid = Qd.TextWidth(s, 0, mid) + ellipsis
+        strwid2 = Qd.TextWidth(s, 0, mid + 1) + ellipsis
+        if strwid <= maxwid and maxwid <= strwid2:
+            if maxwid == strwid2:
+                mid += 1
+            break
+        if strwid > maxwid:
+            mid -= 1
+            if mid <= 0:
+                mid = 0
+                break
+        elif strwid2 < maxwid:
+            mid += 1
+    Qd.TextFace(0)
+    return 1, s[:mid] + '\xc9'
 
 
 def drawTextCell(text, cellRect, ascent, theList):
-	l, t, r, b = cellRect
-	cellwidth = r - l
-	Qd.MoveTo(int(l + 2), int(t + ascent))
-	condense, text = truncString(text, cellwidth - 3)
-	if condense:
-		Qd.TextFace(QuickDraw.condense)
-	Qd.DrawText(text, 0, len(text))
-	Qd.TextFace(0)
+    l, t, r, b = cellRect
+    cellwidth = r - l
+    Qd.MoveTo(int(l + 2), int(t + ascent))
+    condense, text = truncString(text, cellwidth - 3)
+    if condense:
+        Qd.TextFace(QuickDraw.condense)
+    Qd.DrawText(text, 0, len(text))
+    Qd.TextFace(0)
 
 
 PICTWIDTH = 16
 
 
 class BrowserWidget(W.CustomList):
-	
-	def __init__(self, possize, object = None, col = 100, closechildren = 0):
-		W.List.__init__(self, possize, callback = self.listhit)
-		self.object = (None,)
-		self.indent = 16
-		self.lastmaxindent = 0
-		self.closechildren = closechildren
-		self.children = []
-		self.mincol = 64
-		self.setcolumn(col)
-		self.bind('return', self.openselection)
-		self.bind('enter', self.openselection)
-		if object is not None:
-			self.set(object)
-	
-	def set(self, object):
-		if self.object[0] is not object:
-			self.object = object,
-			self[:] = self.unpack(object, 0)
-		elif self._parentwindow is not None and self._parentwindow.wid:
-			self.update()
-	
-	def unpack(self, object, indent):
-		return unpack_object(object, indent)
-	
-	def update(self):
-		# for now...
-		W.SetCursor('watch')
-		self.setdrawingmode(0)
-		sel = self.getselectedobjects()
-		fold = self.getunfoldedobjects()
-		topcell = self.gettopcell()
-		self[:] = self.unpack(self.object[0], 0)
-		self.unfoldobjects(fold)
-		self.setselectedobjects(sel)
-		self.settopcell(topcell)
-		self.setdrawingmode(1)
-	
-	def setcolumn(self, col):
-		self.col = col
-		self.colstr = struct.pack('h', col)
-		if self._list:
-			sel = self.getselection()
-			self.setitems(self.items)
-			self.setselection(sel)
-	
-	def key(self, char, event):
-		if char in (Wkeys.leftarrowkey, Wkeys.rightarrowkey):
-			sel = self.getselection()
-			sel.reverse()
-			self.setdrawingmode(0)
-			for index in sel:
-				self.fold(index, char == Wkeys.rightarrowkey)
-			self.setdrawingmode(1)
-		else:
-			W.List.key(self, char, event)
-	
-	def rollover(self, (x, y), onoff):
-		if onoff:
-			if self.incolumn((x, y)):
-				W.SetCursor('hmover')
-			else:
-				W.SetCursor('arrow')
-	
-	def inarrow(self, (x, y)):
-		cl, ct, cr, cb = self._list.LRect((0, 0))
-		l, t, r, b = self._bounds
-		if (x - cl) < 16:
-			cellheight = cb - ct
-			index = (y - ct) / cellheight
-			if index < len(self.items):
-				return 1, index
-		return None, None
-	
-	def incolumn(self, (x, y)):
-		l, t, r, b = self._list.LRect((0, 0))
-		abscol = l + self.col
-		return abs(abscol - x) < 3
-	
-	def trackcolumn(self, (x, y)):
-		from Carbon import Qd, QuickDraw, Evt
-		self.SetPort()
-		l, t, r, b = self._bounds
-		bounds = l, t, r, b = l + 1, t + 1, r - 16, b - 1
-		abscol = l + self.col
-		mincol = l + self.mincol
-		maxcol = r - 10
-		diff = abscol - x
-		Qd.PenPat('\000\377\000\377\000\377\000\377')
-		Qd.PenMode(QuickDraw.srcXor)
-		rect = abscol - 1, t, abscol, b
-		Qd.PaintRect(rect)
-		lastpoint = (x, y)
-		newcol = -1
-		#W.SetCursor('fist')
-		while Evt.Button():
-			Evt.WaitNextEvent(0, 1, None)  # needed for OSX
-			(x, y) = Evt.GetMouse()
-			if (x, y) <> lastpoint:
-				newcol = x + diff
-				newcol = max(newcol, mincol)
-				newcol = min(newcol, maxcol)
-				Qd.PaintRect(rect)
-				rect = newcol - 1, t, newcol, b
-				Qd.PaintRect(rect)
-				lastpoint = (x, y)
-		Qd.PaintRect(rect)
-		Qd.PenPat(Qd.GetQDGlobalsBlack())
-		Qd.PenNormal()
-		if newcol > 0 and newcol <> abscol:
-			self.setcolumn(newcol - l)
-	
-	def click(self, point, modifiers):
-		if point == (-1, -1):	# gross.
-			W.List.click(self, point ,modifiers)
-			return
-		hit, index = self.inarrow(point)
-		if hit:
-			(key, value, arrow, indent) = self.items[index]
-			self.fold(index, arrow == 1)
-		elif self.incolumn(point):
-			self.trackcolumn(point)
-		else:
-			W.List.click(self, point, modifiers)
-	
-	# for W.List.key
-	def findmatch(self, tag):
-		lower = string.lower
-		items = self.items
-		taglen = len(tag)
-		match = '\377' * 100
-		match_i = -1
-		for i in range(len(items)):
-			item = lower(str(items[i][0]))
-			if tag <= item < match:
-				match = item
-				match_i = i
-		if match_i >= 0:
-			return match_i
-		else:
-			return len(items) - 1
-	
-	def close(self):
-		if self.closechildren:
-			for window in self.children:
-				window.close()
-		self.children = []
-		W.List.close(self)
-	
-	def fold(self, index, onoff):
-		(key, value, arrow, indent) = self.items[index]
-		if arrow == 0 or (onoff and arrow == 2) or (not onoff and arrow == 1):
-			return
-		W.SetCursor('watch')
-		topcell = self.gettopcell()
-		if onoff:
-			self[index] = (key, value, 4, indent)
-			self.setdrawingmode(0)
-			self[index+1:index+1] = self.unpack(value, indent + 1)
-			self[index] = (key, value, 2, indent)
-		else:
-			self[index] = (key, value, 3, indent)
-			self.setdrawingmode(0)
-			count = 0
-			for i in range(index + 1, len(self.items)):
-				(dummy, dummy, dummy, subindent) = self.items[i]
-				if subindent <= indent:
-					break
-				count = count + 1
-			self[index+1:index+1+count] = []
-			self[index] = (key, value, 1, indent)
-		maxindent = self.getmaxindent()
-		if maxindent <> self.lastmaxindent:
-			newabsindent = self.col + (maxindent - self.lastmaxindent) * self.indent
-			if newabsindent >= self.mincol:
-				self.setcolumn(newabsindent)
-			self.lastmaxindent = maxindent
-		self.settopcell(topcell)
-		self.setdrawingmode(1)
-	
-	def unfoldobjects(self, objects):
-		for obj in objects:
-			try:
-				index = self.items.index(obj)
-			except ValueError:
-				pass
-			else:
-				self.fold(index, 1)
-	
-	def getunfoldedobjects(self):
-		curindent = 0
-		objects = []
-		for index in range(len(self.items)):
-			(key, value, arrow, indent) = self.items[index]
-			if indent > curindent:
-				(k, v, a, i) = self.items[index - 1]
-				objects.append((k, v, 1, i))
-				curindent = indent
-			elif indent < curindent:
-				curindent = indent
-		return objects
-	
-	def listhit(self, isdbl):
-		if isdbl:
-			self.openselection()
-	
-	def openselection(self):
-		import os
-		sel = self.getselection()
-		for index in sel:
-			(key, value, arrow, indent) = self[index]
-			if arrow:
-				self.children.append(Browser(value))
-			elif type(value) == types.StringType and '\0' not in value:
-				editor = self._parentwindow.parent.getscript(value)
-				if editor:
-					editor.select()
-					return
-				elif os.path.exists(value) and os.path.isfile(value):
-					if MacOS.GetCreatorAndType(value)[1] in ('TEXT', '\0\0\0\0'):
-						W.getapplication().openscript(value)
-	
-	def itemrepr(self, (key, value, arrow, indent), str = str, double_repr = double_repr, 
-			arrows = arrows, pack = struct.pack):
-		arrow = arrows[arrow]
-		return arrow + pack('h', self.indent * indent) + self.colstr + \
-				double_repr(key, value, 1)
-	
-	def getmaxindent(self, max = max):
-		maxindent = 0
-		for item in self.items:
-			maxindent = max(maxindent, item[3])
-		return maxindent
-	
-	def domenu_copy(self, *args):
-		sel = self.getselectedobjects()
-		selitems = []
-		for key, value, dummy, dummy in sel:
-			selitems.append(double_repr(key, value))
-		text = string.join(selitems, '\r')
-		if text:
-			from Carbon import Scrap
-			if hasattr(Scrap, 'PutScrap'):
-				Scrap.ZeroScrap()
-				Scrap.PutScrap('TEXT', text)
-			else:
-				Scrap.ClearCurrentScrap()
-				sc = Scrap.GetCurrentScrap()
-				sc.PutScrapFlavor('TEXT', 0, text)
 
-	def listDefDraw(self, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList):
-		self.myDrawCell(0, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList)
-	
-	def listDefHighlight(self, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList):
-		self.myDrawCell(1, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList)
-	
-	def myDrawCell(self, onlyHilite, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList):
-		savedPort = Qd.GetPort()
-		Qd.SetPort(theList.GetListPort())
-		savedClip = Qd.NewRgn()
-		Qd.GetClip(savedClip)
-		Qd.ClipRect(cellRect)
-		savedPenState = Qd.GetPenState()
-		Qd.PenNormal()
-		
-		l, t, r, b = cellRect
-		
-		if not onlyHilite:
-			Qd.EraseRect(cellRect)
-			
-			ascent, descent, leading, size, hm = Fm.FontMetrics()
-			linefeed = ascent + descent + leading
-			
-			if dataLen >= 6:
-				data = theList.LGetCell(dataLen, theCell)
-				iconId, indent, tab = struct.unpack("hhh", data[:6])
-				try:
-					key, value = data[6:].split("\t", 1)
-				except ValueError:
-					# bogus data, at least don't crash.
-					indent = 0
-					tab = 0
-					iconId = 0
-					key = ""
-					value = data[6:]
-				
-				if iconId:
-					try:
-						theIcon = Icn.GetCIcon(iconId)
-					except Icn.Error:
-						pass
-					else:
-						rect = (0, 0, 16, 16)
-						rect = Qd.OffsetRect(rect, l, t)
-						rect = Qd.OffsetRect(rect, 0, (theList.cellSize[1] - (rect[3] - rect[1])) / 2)
-						Icn.PlotCIcon(rect, theIcon)
-				
-				if len(key) >= 0:
-					cl, ct, cr, cb = cellRect
-					vl, vt, vr, vb = self._viewbounds
-					cl = vl + PICTWIDTH + indent
-					cr = vl + tab
-					if cr > vr:
-						cr = vr
-					if cl < cr:
-						drawTextCell(key, (cl, ct, cr, cb), ascent, theList)
-					cl = vl + tab
-					cr = vr
-					if cl < cr:
-						drawTextCell(value, (cl, ct, cr, cb), ascent, theList)
-			#elif dataLen != 0:
-			#	drawTextCell("???", 3, cellRect, ascent, theList)
-			else:
-				return  # we have bogus data
-			
-			# draw nice dotted line
-			l, t, r, b = cellRect
-			l = self._viewbounds[0] + tab
-			r = l + 1;
-			if not (theList.cellSize[1] & 0x01) or (t & 0x01):
-				myPat = "\xff\x00\xff\x00\xff\x00\xff\x00"
-			else:
-				myPat = "\x00\xff\x00\xff\x00\xff\x00\xff"
-			Qd.PenPat(myPat)
-			Qd.PenMode(QuickDraw.srcCopy)
-			Qd.PaintRect((l, t, r, b))
-			Qd.PenNormal()
-		
-		if selected or onlyHilite:
-			l, t, r, b = cellRect
-			l = self._viewbounds[0] + PICTWIDTH
-			r = self._viewbounds[2]
-			Qd.PenMode(hilitetransfermode)
-			Qd.PaintRect((l, t, r, b))
-		
-		# restore graphics environment
-		Qd.SetPort(savedPort)
-		Qd.SetClip(savedClip)
-		Qd.DisposeRgn(savedClip)
-		Qd.SetPenState(savedPenState)
+    def __init__(self, possize, object = None, col = 100, closechildren = 0):
+        W.List.__init__(self, possize, callback = self.listhit)
+        self.object = (None,)
+        self.indent = 16
+        self.lastmaxindent = 0
+        self.closechildren = closechildren
+        self.children = []
+        self.mincol = 64
+        self.setcolumn(col)
+        self.bind('return', self.openselection)
+        self.bind('enter', self.openselection)
+        if object is not None:
+            self.set(object)
+
+    def set(self, object):
+        if self.object[0] is not object:
+            self.object = object,
+            self[:] = self.unpack(object, 0)
+        elif self._parentwindow is not None and self._parentwindow.wid:
+            self.update()
+
+    def unpack(self, object, indent):
+        return unpack_object(object, indent)
+
+    def update(self):
+        # for now...
+        W.SetCursor('watch')
+        self.setdrawingmode(0)
+        sel = self.getselectedobjects()
+        fold = self.getunfoldedobjects()
+        topcell = self.gettopcell()
+        self[:] = self.unpack(self.object[0], 0)
+        self.unfoldobjects(fold)
+        self.setselectedobjects(sel)
+        self.settopcell(topcell)
+        self.setdrawingmode(1)
+
+    def setcolumn(self, col):
+        self.col = col
+        self.colstr = struct.pack('h', col)
+        if self._list:
+            sel = self.getselection()
+            self.setitems(self.items)
+            self.setselection(sel)
+
+    def key(self, char, event):
+        if char in (Wkeys.leftarrowkey, Wkeys.rightarrowkey):
+            sel = self.getselection()
+            sel.reverse()
+            self.setdrawingmode(0)
+            for index in sel:
+                self.fold(index, char == Wkeys.rightarrowkey)
+            self.setdrawingmode(1)
+        else:
+            W.List.key(self, char, event)
+
+    def rollover(self, (x, y), onoff):
+        if onoff:
+            if self.incolumn((x, y)):
+                W.SetCursor('hmover')
+            else:
+                W.SetCursor('arrow')
+
+    def inarrow(self, (x, y)):
+        cl, ct, cr, cb = self._list.LRect((0, 0))
+        l, t, r, b = self._bounds
+        if (x - cl) < 16:
+            cellheight = cb - ct
+            index = (y - ct) / cellheight
+            if index < len(self.items):
+                return 1, index
+        return None, None
+
+    def incolumn(self, (x, y)):
+        l, t, r, b = self._list.LRect((0, 0))
+        abscol = l + self.col
+        return abs(abscol - x) < 3
+
+    def trackcolumn(self, (x, y)):
+        from Carbon import Qd, QuickDraw, Evt
+        self.SetPort()
+        l, t, r, b = self._bounds
+        bounds = l, t, r, b = l + 1, t + 1, r - 16, b - 1
+        abscol = l + self.col
+        mincol = l + self.mincol
+        maxcol = r - 10
+        diff = abscol - x
+        Qd.PenPat('\000\377\000\377\000\377\000\377')
+        Qd.PenMode(QuickDraw.srcXor)
+        rect = abscol - 1, t, abscol, b
+        Qd.PaintRect(rect)
+        lastpoint = (x, y)
+        newcol = -1
+        #W.SetCursor('fist')
+        while Evt.Button():
+            Evt.WaitNextEvent(0, 1, None)  # needed for OSX
+            (x, y) = Evt.GetMouse()
+            if (x, y) <> lastpoint:
+                newcol = x + diff
+                newcol = max(newcol, mincol)
+                newcol = min(newcol, maxcol)
+                Qd.PaintRect(rect)
+                rect = newcol - 1, t, newcol, b
+                Qd.PaintRect(rect)
+                lastpoint = (x, y)
+        Qd.PaintRect(rect)
+        Qd.PenPat(Qd.GetQDGlobalsBlack())
+        Qd.PenNormal()
+        if newcol > 0 and newcol <> abscol:
+            self.setcolumn(newcol - l)
+
+    def click(self, point, modifiers):
+        if point == (-1, -1):   # gross.
+            W.List.click(self, point ,modifiers)
+            return
+        hit, index = self.inarrow(point)
+        if hit:
+            (key, value, arrow, indent) = self.items[index]
+            self.fold(index, arrow == 1)
+        elif self.incolumn(point):
+            self.trackcolumn(point)
+        else:
+            W.List.click(self, point, modifiers)
+
+    # for W.List.key
+    def findmatch(self, tag):
+        lower = string.lower
+        items = self.items
+        taglen = len(tag)
+        match = '\377' * 100
+        match_i = -1
+        for i in range(len(items)):
+            item = lower(str(items[i][0]))
+            if tag <= item < match:
+                match = item
+                match_i = i
+        if match_i >= 0:
+            return match_i
+        else:
+            return len(items) - 1
+
+    def close(self):
+        if self.closechildren:
+            for window in self.children:
+                window.close()
+        self.children = []
+        W.List.close(self)
+
+    def fold(self, index, onoff):
+        (key, value, arrow, indent) = self.items[index]
+        if arrow == 0 or (onoff and arrow == 2) or (not onoff and arrow == 1):
+            return
+        W.SetCursor('watch')
+        topcell = self.gettopcell()
+        if onoff:
+            self[index] = (key, value, 4, indent)
+            self.setdrawingmode(0)
+            self[index+1:index+1] = self.unpack(value, indent + 1)
+            self[index] = (key, value, 2, indent)
+        else:
+            self[index] = (key, value, 3, indent)
+            self.setdrawingmode(0)
+            count = 0
+            for i in range(index + 1, len(self.items)):
+                (dummy, dummy, dummy, subindent) = self.items[i]
+                if subindent <= indent:
+                    break
+                count = count + 1
+            self[index+1:index+1+count] = []
+            self[index] = (key, value, 1, indent)
+        maxindent = self.getmaxindent()
+        if maxindent <> self.lastmaxindent:
+            newabsindent = self.col + (maxindent - self.lastmaxindent) * self.indent
+            if newabsindent >= self.mincol:
+                self.setcolumn(newabsindent)
+            self.lastmaxindent = maxindent
+        self.settopcell(topcell)
+        self.setdrawingmode(1)
+
+    def unfoldobjects(self, objects):
+        for obj in objects:
+            try:
+                index = self.items.index(obj)
+            except ValueError:
+                pass
+            else:
+                self.fold(index, 1)
+
+    def getunfoldedobjects(self):
+        curindent = 0
+        objects = []
+        for index in range(len(self.items)):
+            (key, value, arrow, indent) = self.items[index]
+            if indent > curindent:
+                (k, v, a, i) = self.items[index - 1]
+                objects.append((k, v, 1, i))
+                curindent = indent
+            elif indent < curindent:
+                curindent = indent
+        return objects
+
+    def listhit(self, isdbl):
+        if isdbl:
+            self.openselection()
+
+    def openselection(self):
+        import os
+        sel = self.getselection()
+        for index in sel:
+            (key, value, arrow, indent) = self[index]
+            if arrow:
+                self.children.append(Browser(value))
+            elif type(value) == types.StringType and '\0' not in value:
+                editor = self._parentwindow.parent.getscript(value)
+                if editor:
+                    editor.select()
+                    return
+                elif os.path.exists(value) and os.path.isfile(value):
+                    if MacOS.GetCreatorAndType(value)[1] in ('TEXT', '\0\0\0\0'):
+                        W.getapplication().openscript(value)
+
+    def itemrepr(self, (key, value, arrow, indent), str = str, double_repr = double_repr,
+                    arrows = arrows, pack = struct.pack):
+        arrow = arrows[arrow]
+        return arrow + pack('h', self.indent * indent) + self.colstr + \
+                        double_repr(key, value, 1)
+
+    def getmaxindent(self, max = max):
+        maxindent = 0
+        for item in self.items:
+            maxindent = max(maxindent, item[3])
+        return maxindent
+
+    def domenu_copy(self, *args):
+        sel = self.getselectedobjects()
+        selitems = []
+        for key, value, dummy, dummy in sel:
+            selitems.append(double_repr(key, value))
+        text = string.join(selitems, '\r')
+        if text:
+            from Carbon import Scrap
+            if hasattr(Scrap, 'PutScrap'):
+                Scrap.ZeroScrap()
+                Scrap.PutScrap('TEXT', text)
+            else:
+                Scrap.ClearCurrentScrap()
+                sc = Scrap.GetCurrentScrap()
+                sc.PutScrapFlavor('TEXT', 0, text)
+
+    def listDefDraw(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        self.myDrawCell(0, selected, cellRect, theCell,
+                dataOffset, dataLen, theList)
+
+    def listDefHighlight(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        self.myDrawCell(1, selected, cellRect, theCell,
+                dataOffset, dataLen, theList)
+
+    def myDrawCell(self, onlyHilite, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        savedPort = Qd.GetPort()
+        Qd.SetPort(theList.GetListPort())
+        savedClip = Qd.NewRgn()
+        Qd.GetClip(savedClip)
+        Qd.ClipRect(cellRect)
+        savedPenState = Qd.GetPenState()
+        Qd.PenNormal()
+
+        l, t, r, b = cellRect
+
+        if not onlyHilite:
+            Qd.EraseRect(cellRect)
+
+            ascent, descent, leading, size, hm = Fm.FontMetrics()
+            linefeed = ascent + descent + leading
+
+            if dataLen >= 6:
+                data = theList.LGetCell(dataLen, theCell)
+                iconId, indent, tab = struct.unpack("hhh", data[:6])
+                try:
+                    key, value = data[6:].split("\t", 1)
+                except ValueError:
+                    # bogus data, at least don't crash.
+                    indent = 0
+                    tab = 0
+                    iconId = 0
+                    key = ""
+                    value = data[6:]
+
+                if iconId:
+                    try:
+                        theIcon = Icn.GetCIcon(iconId)
+                    except Icn.Error:
+                        pass
+                    else:
+                        rect = (0, 0, 16, 16)
+                        rect = Qd.OffsetRect(rect, l, t)
+                        rect = Qd.OffsetRect(rect, 0, (theList.cellSize[1] - (rect[3] - rect[1])) / 2)
+                        Icn.PlotCIcon(rect, theIcon)
+
+                if len(key) >= 0:
+                    cl, ct, cr, cb = cellRect
+                    vl, vt, vr, vb = self._viewbounds
+                    cl = vl + PICTWIDTH + indent
+                    cr = vl + tab
+                    if cr > vr:
+                        cr = vr
+                    if cl < cr:
+                        drawTextCell(key, (cl, ct, cr, cb), ascent, theList)
+                    cl = vl + tab
+                    cr = vr
+                    if cl < cr:
+                        drawTextCell(value, (cl, ct, cr, cb), ascent, theList)
+            #elif dataLen != 0:
+            #       drawTextCell("???", 3, cellRect, ascent, theList)
+            else:
+                return  # we have bogus data
+
+            # draw nice dotted line
+            l, t, r, b = cellRect
+            l = self._viewbounds[0] + tab
+            r = l + 1;
+            if not (theList.cellSize[1] & 0x01) or (t & 0x01):
+                myPat = "\xff\x00\xff\x00\xff\x00\xff\x00"
+            else:
+                myPat = "\x00\xff\x00\xff\x00\xff\x00\xff"
+            Qd.PenPat(myPat)
+            Qd.PenMode(QuickDraw.srcCopy)
+            Qd.PaintRect((l, t, r, b))
+            Qd.PenNormal()
+
+        if selected or onlyHilite:
+            l, t, r, b = cellRect
+            l = self._viewbounds[0] + PICTWIDTH
+            r = self._viewbounds[2]
+            Qd.PenMode(hilitetransfermode)
+            Qd.PaintRect((l, t, r, b))
+
+        # restore graphics environment
+        Qd.SetPort(savedPort)
+        Qd.SetClip(savedClip)
+        Qd.DisposeRgn(savedClip)
+        Qd.SetPenState(savedPenState)
 
 
 
 class Browser:
-	
-	def __init__(self, object = None, title = None, closechildren = 0):
-		if hasattr(object, '__name__'):
-			name = object.__name__
-		else:
-			name = ''
-		if title is None:
-			title = 'Object browser'
-			if name:
-				title = title + ': ' + name
-		self.w = w = W.Window((300, 400), title, minsize = (100, 100))
-		w.info = W.TextBox((18, 8, -70, 15))
-		w.updatebutton = W.BevelButton((-64, 4, 50, 16), 'Update', self.update)
-		w.browser = BrowserWidget((-1, 24, 1, -14), None)
-		w.bind('cmdu', w.updatebutton.push)
-		w.open()
-		self.set(object, name)
-	
-	def close(self):
-		if self.w.wid:
-			self.w.close()
-	
-	def set(self, object, name = ''):
-		W.SetCursor('watch')
-		tp = type(object).__name__
-		try:
-			length = len(object)
-		except:
-			length = -1
-		if not name and hasattr(object, '__name__'):
-			name = object.__name__
-		if name:
-			info = name + ': ' + tp
-		else:
-			info = tp
-		if length >= 0:
-			if length == 1:
-				info = info + ' (%d element)' % length
-			else:
-				info = info + ' (%d elements)' % length
-		self.w.info.set(info)
-		self.w.browser.set(object)
-	
-	def update(self):
-		self.w.browser.update()
+
+    def __init__(self, object = None, title = None, closechildren = 0):
+        if hasattr(object, '__name__'):
+            name = object.__name__
+        else:
+            name = ''
+        if title is None:
+            title = 'Object browser'
+            if name:
+                title = title + ': ' + name
+        self.w = w = W.Window((300, 400), title, minsize = (100, 100))
+        w.info = W.TextBox((18, 8, -70, 15))
+        w.updatebutton = W.BevelButton((-64, 4, 50, 16), 'Update', self.update)
+        w.browser = BrowserWidget((-1, 24, 1, -14), None)
+        w.bind('cmdu', w.updatebutton.push)
+        w.open()
+        self.set(object, name)
+
+    def close(self):
+        if self.w.wid:
+            self.w.close()
+
+    def set(self, object, name = ''):
+        W.SetCursor('watch')
+        tp = type(object).__name__
+        try:
+            length = len(object)
+        except:
+            length = -1
+        if not name and hasattr(object, '__name__'):
+            name = object.__name__
+        if name:
+            info = name + ': ' + tp
+        else:
+            info = tp
+        if length >= 0:
+            if length == 1:
+                info = info + ' (%d element)' % length
+            else:
+                info = info + ' (%d elements)' % length
+        self.w.info.set(info)
+        self.w.browser.set(object)
+
+    def update(self):
+        self.w.browser.update()
 
 
 SIMPLE_TYPES = (
-	type(None),
-	int,
-	long,
-	float,
-	complex,
-	str,
-	unicode,
+        type(None),
+        int,
+        long,
+        float,
+        complex,
+        str,
+        unicode,
 )
 
 def get_ivars(obj):
-	"""Return a list the names of all (potential) instance variables."""
-	# __mro__ recipe from Guido
-	slots = {}
-	# old-style C objects
-	if hasattr(obj, "__members__"):
-		for name in obj.__members__:
-			slots[name] = None
-	if hasattr(obj, "__methods__"):
-		for name in obj.__methods__:
-			slots[name] = None
-	# generic type
-	if hasattr(obj, "__dict__"):
-		slots.update(obj.__dict__)
-	cls = type(obj)
-	if hasattr(cls, "__mro__"):
-		# new-style class, use descriptors
-		for base in cls.__mro__:
-			for name, value in base.__dict__.items():
-				# XXX using callable() is a heuristic which isn't 100%
-				# foolproof.
-				if hasattr(value, "__get__") and not callable(value):
-					slots[name] = None
-	if "__dict__" in slots:
-		del slots["__dict__"]
-	slots = slots.keys()
-	slots.sort()
-	return slots
+    """Return a list the names of all (potential) instance variables."""
+    # __mro__ recipe from Guido
+    slots = {}
+    # old-style C objects
+    if hasattr(obj, "__members__"):
+        for name in obj.__members__:
+            slots[name] = None
+    if hasattr(obj, "__methods__"):
+        for name in obj.__methods__:
+            slots[name] = None
+    # generic type
+    if hasattr(obj, "__dict__"):
+        slots.update(obj.__dict__)
+    cls = type(obj)
+    if hasattr(cls, "__mro__"):
+        # new-style class, use descriptors
+        for base in cls.__mro__:
+            for name, value in base.__dict__.items():
+                # XXX using callable() is a heuristic which isn't 100%
+                # foolproof.
+                if hasattr(value, "__get__") and not callable(value):
+                    slots[name] = None
+    if "__dict__" in slots:
+        del slots["__dict__"]
+    slots = slots.keys()
+    slots.sort()
+    return slots
 
 def unpack_object(object, indent = 0):
-	tp = type(object)
-	if isinstance(object, SIMPLE_TYPES) and object is not None:
-		raise TypeError, "can't browse simple type: %s" % tp.__name__
-	elif isinstance(object, dict):
-		return unpack_dict(object, indent)
-	elif isinstance(object, (tuple, list)):
-		return unpack_sequence(object, indent)
-	elif isinstance(object, types.ModuleType):
-		return unpack_dict(object.__dict__, indent)
-	else:
-		return unpack_other(object, indent)
+    tp = type(object)
+    if isinstance(object, SIMPLE_TYPES) and object is not None:
+        raise TypeError, "can't browse simple type: %s" % tp.__name__
+    elif isinstance(object, dict):
+        return unpack_dict(object, indent)
+    elif isinstance(object, (tuple, list)):
+        return unpack_sequence(object, indent)
+    elif isinstance(object, types.ModuleType):
+        return unpack_dict(object.__dict__, indent)
+    else:
+        return unpack_other(object, indent)
 
 def unpack_sequence(seq, indent = 0):
-	return [(i, v, not isinstance(v, SIMPLE_TYPES), indent)
-	         for i, v in enumerate(seq)]
+    return [(i, v, not isinstance(v, SIMPLE_TYPES), indent)
+             for i, v in enumerate(seq)]
 
 def unpack_dict(dict, indent = 0):
-	items = dict.items()
-	return pack_items(items, indent)
+    items = dict.items()
+    return pack_items(items, indent)
 
 def unpack_instance(inst, indent = 0):
-	if hasattr(inst, '__pybrowse_unpack__'):
-		return unpack_object(inst.__pybrowse_unpack__(), indent)
-	else:
-		items = [('__class__', inst.__class__)] + inst.__dict__.items()
-		return pack_items(items, indent)
+    if hasattr(inst, '__pybrowse_unpack__'):
+        return unpack_object(inst.__pybrowse_unpack__(), indent)
+    else:
+        items = [('__class__', inst.__class__)] + inst.__dict__.items()
+        return pack_items(items, indent)
 
 def unpack_class(clss, indent = 0):
-	items = [('__bases__', clss.__bases__), ('__name__', clss.__name__)] + clss.__dict__.items()
-	return pack_items(items, indent)
+    items = [('__bases__', clss.__bases__), ('__name__', clss.__name__)] + clss.__dict__.items()
+    return pack_items(items, indent)
 
 def unpack_other(object, indent = 0):
-	attrs = get_ivars(object)
-	items = []
-	for attr in attrs:
-		try:
-			value = getattr(object, attr)
-		except:
-			pass
-		else:
-			items.append((attr, value))
-	return pack_items(items, indent)
+    attrs = get_ivars(object)
+    items = []
+    for attr in attrs:
+        try:
+            value = getattr(object, attr)
+        except:
+            pass
+        else:
+            items.append((attr, value))
+    return pack_items(items, indent)
 
 def pack_items(items, indent = 0):
-	items = [(k, v, not isinstance(v, SIMPLE_TYPES), indent)
-	         for k, v in items]
-	return tuple_caselesssort(items)
+    items = [(k, v, not isinstance(v, SIMPLE_TYPES), indent)
+             for k, v in items]
+    return tuple_caselesssort(items)
 
 def caselesssort(alist):
-	"""Return a sorted copy of a list. If there are only strings in the list, 
-	it will not consider case"""
-	
-	try:
-		# turn ['FOO',  'aaBc', 'ABcD'] into [('foo', 'FOO'), ('aabc', 'aaBc'), ('abcd', 'ABcD')], if possible
-		tupledlist = map(lambda item, lower = string.lower: (lower(item), item), alist)
-	except TypeError:
-		# at least one element in alist is not a string, proceed the normal way...
-		alist = alist[:]
-		alist.sort()
-		return alist
-	else:
-		tupledlist.sort()
-		# turn [('aabc', 'aaBc'), ('abcd', 'ABcD'), ('foo', 'FOO')] into ['aaBc', 'ABcD', 'FOO']
-		return map(lambda x: x[1], tupledlist)
+    """Return a sorted copy of a list. If there are only strings in the list,
+    it will not consider case"""
+
+    try:
+        # turn ['FOO',  'aaBc', 'ABcD'] into [('foo', 'FOO'), ('aabc', 'aaBc'), ('abcd', 'ABcD')], if possible
+        tupledlist = map(lambda item, lower = string.lower: (lower(item), item), alist)
+    except TypeError:
+        # at least one element in alist is not a string, proceed the normal way...
+        alist = alist[:]
+        alist.sort()
+        return alist
+    else:
+        tupledlist.sort()
+        # turn [('aabc', 'aaBc'), ('abcd', 'ABcD'), ('foo', 'FOO')] into ['aaBc', 'ABcD', 'FOO']
+        return map(lambda x: x[1], tupledlist)
 
 def tuple_caselesssort(items):
-	try:
-		tupledlist = map(lambda tuple, lower = string.lower: (lower(tuple[0]), tuple), items)
-	except (AttributeError, TypeError):
-		items = items[:]
-		items.sort()
-		return items
-	else:
-		tupledlist.sort()
-		return map(lambda (low, tuple): tuple, tupledlist)
-
+    try:
+        tupledlist = map(lambda tuple, lower = string.lower: (lower(tuple[0]), tuple), items)
+    except (AttributeError, TypeError):
+        items = items[:]
+        items.sort()
+        return items
+    else:
+        tupledlist.sort()
+        return map(lambda (low, tuple): tuple, tupledlist)
diff --git a/Mac/Tools/IDE/PyConsole.py b/Mac/Tools/IDE/PyConsole.py
index 6f398d1..b8d6489 100644
--- a/Mac/Tools/IDE/PyConsole.py
+++ b/Mac/Tools/IDE/PyConsole.py
@@ -14,424 +14,424 @@
 import PyInteractive
 
 if not hasattr(sys, 'ps1'):
-	sys.ps1 = '>>> '
+    sys.ps1 = '>>> '
 if not hasattr(sys, 'ps2'):
-	sys.ps2 = '... '
+    sys.ps2 = '... '
 
-def inspect(foo):			# JJS 1/25/99
-	"Launch the browser on the given object.  This is a general built-in function."
-	import PyBrowser
-	PyBrowser.Browser(foo)
+def inspect(foo):                       # JJS 1/25/99
+    "Launch the browser on the given object.  This is a general built-in function."
+    import PyBrowser
+    PyBrowser.Browser(foo)
 
 class ConsoleTextWidget(W.EditText):
-	
-	def __init__(self, *args, **kwargs):
-		apply(W.EditText.__init__, (self,) + args, kwargs)
-		self._inputstart = 0
-		self._buf = ''
-		self.pyinteractive = PyInteractive.PyInteractive()
-	
-		import __main__
-		self._namespace = __main__.__dict__
-		self._namespace['inspect'] = inspect			# JJS 1/25/99
-	
-	def insert(self, text):
-		self.checkselection()
-		self.ted.WEInsert(text, None, None)
-		self.changed = 1
-		self.selchanged = 1
-	
-	def set_namespace(self, dict):
-		if type(dict) <> DictionaryType:
-			raise TypeError, "The namespace needs to be a dictionary"
-		if 'inspect' not in dict.keys(): dict['inspect'] = inspect			# JJS 1/25/99
-		self._namespace = dict
-	
-	def open(self):
-		import __main__
-		W.EditText.open(self)
-		self.write('Python %s\n' % sys.version)
-		self.write('Type "copyright", "credits" or "license" for more information.\n')
-		self.write('MacPython IDE %s\n' % __main__.__version__)
-		self.write(sys.ps1)
-		self.flush()
-	
-	def key(self, char, event):
-		(what, message, when, where, modifiers) = event
-		if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
-			if char not in Wkeys.navigationkeys:
-				self.checkselection()
-			if char == Wkeys.enterkey:
-				char = Wkeys.returnkey
-			selstart, selend = self.getselection()
-			if char == Wkeys.backspacekey:
-				if selstart <= (self._inputstart - (selstart <> selend)):
-					return
-			self.ted.WEKey(ord(char), modifiers)
-			if char not in Wkeys.navigationkeys:
-				self.changed = 1
-			if char not in Wkeys.scrollkeys:
-				self.selchanged = 1
-			self.updatescrollbars()
-			if char == Wkeys.returnkey:
-				text = self.get()[self._inputstart:selstart]
-				text = string.join(string.split(text, "\r"), "\n")
-				if hasattr(MacOS, 'EnableAppswitch'):
-					saveyield = MacOS.EnableAppswitch(0)
-				self._scriptDone = False
-				if sys.platform == "darwin":
-					# see identical construct in PyEdit.py
-					from threading import Thread
-					t = Thread(target=self._userCancelledMonitor,
-							name="UserCancelledMonitor")
-					t.start()
-				try:
-					self.pyinteractive.executeline(text, self, self._namespace)
-				finally:
-					self._scriptDone = True
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(saveyield)
-				selstart, selend = self.getselection()
-				self._inputstart = selstart
-	
-	def _userCancelledMonitor(self):
-		# XXX duplicate code from PyEdit.py
-		import time, os
-		from signal import SIGINT
-		from Carbon import Evt
-		while not self._scriptDone:
-			if Evt.CheckEventQueueForUserCancel():
-				# Send a SIGINT signal to ourselves.
-				# This gets delivered to the main thread,
-				# cancelling the running script.
-				os.kill(os.getpid(), SIGINT)
-				break
-			time.sleep(0.25)
-	
-	def domenu_save_as(self, *args):
-		filename = EasyDialogs.AskFileForSave(message='Save console text as:', 
-			savedFileName='console.txt')
-		if not filename:
-			return
-		f = open(filename, 'wb')
-		f.write(self.get())
-		f.close()
-		MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
-	
-	def write(self, text):
-		self._buf = self._buf + text
-		if '\n' in self._buf:
-			self.flush()
-	
-	def flush(self):
-		stuff = string.split(self._buf, '\n')
-		stuff = string.join(stuff, '\r')
-		self.setselection_at_end()
-		try:
-			self.ted.WEInsert(stuff, None, None)
-		finally:
-			self._buf = ""
-		selstart, selend = self.getselection()
-		self._inputstart = selstart
-		self.ted.WEClearUndo()
-		self.updatescrollbars()
-		if self._parentwindow.wid.GetWindowPort().QDIsPortBuffered():
-			self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
-	
-	def selection_ok(self):
-		selstart, selend = self.getselection()
-		return not (selstart < self._inputstart or selend < self._inputstart)
-	
-	def checkselection(self):
-		if not self.selection_ok():
-			self.setselection_at_end()
-	
-	def setselection_at_end(self):
-		end = self.ted.WEGetTextLength()
-		self.setselection(end, end)
-		self.updatescrollbars()
-		
-	def domenu_cut(self, *args):
-		if not self.selection_ok():
-			return
-		W.EditText.domenu_cut(self)
-	
-	def domenu_paste(self, *args):
-		if not self.selection_ok():
-			self.setselection_at_end()
-		W.EditText.domenu_paste(self)
-	
-	def domenu_clear(self, *args):
-		if not self.selection_ok():
-			return
-		W.EditText.domenu_clear(self)
+
+    def __init__(self, *args, **kwargs):
+        apply(W.EditText.__init__, (self,) + args, kwargs)
+        self._inputstart = 0
+        self._buf = ''
+        self.pyinteractive = PyInteractive.PyInteractive()
+
+        import __main__
+        self._namespace = __main__.__dict__
+        self._namespace['inspect'] = inspect                    # JJS 1/25/99
+
+    def insert(self, text):
+        self.checkselection()
+        self.ted.WEInsert(text, None, None)
+        self.changed = 1
+        self.selchanged = 1
+
+    def set_namespace(self, dict):
+        if type(dict) <> DictionaryType:
+            raise TypeError, "The namespace needs to be a dictionary"
+        if 'inspect' not in dict.keys(): dict['inspect'] = inspect                      # JJS 1/25/99
+        self._namespace = dict
+
+    def open(self):
+        import __main__
+        W.EditText.open(self)
+        self.write('Python %s\n' % sys.version)
+        self.write('Type "copyright", "credits" or "license" for more information.\n')
+        self.write('MacPython IDE %s\n' % __main__.__version__)
+        self.write(sys.ps1)
+        self.flush()
+
+    def key(self, char, event):
+        (what, message, when, where, modifiers) = event
+        if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
+            if char not in Wkeys.navigationkeys:
+                self.checkselection()
+            if char == Wkeys.enterkey:
+                char = Wkeys.returnkey
+            selstart, selend = self.getselection()
+            if char == Wkeys.backspacekey:
+                if selstart <= (self._inputstart - (selstart <> selend)):
+                    return
+            self.ted.WEKey(ord(char), modifiers)
+            if char not in Wkeys.navigationkeys:
+                self.changed = 1
+            if char not in Wkeys.scrollkeys:
+                self.selchanged = 1
+            self.updatescrollbars()
+            if char == Wkeys.returnkey:
+                text = self.get()[self._inputstart:selstart]
+                text = string.join(string.split(text, "\r"), "\n")
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    saveyield = MacOS.EnableAppswitch(0)
+                self._scriptDone = False
+                if sys.platform == "darwin":
+                    # see identical construct in PyEdit.py
+                    from threading import Thread
+                    t = Thread(target=self._userCancelledMonitor,
+                                    name="UserCancelledMonitor")
+                    t.start()
+                try:
+                    self.pyinteractive.executeline(text, self, self._namespace)
+                finally:
+                    self._scriptDone = True
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(saveyield)
+                selstart, selend = self.getselection()
+                self._inputstart = selstart
+
+    def _userCancelledMonitor(self):
+        # XXX duplicate code from PyEdit.py
+        import time, os
+        from signal import SIGINT
+        from Carbon import Evt
+        while not self._scriptDone:
+            if Evt.CheckEventQueueForUserCancel():
+                # Send a SIGINT signal to ourselves.
+                # This gets delivered to the main thread,
+                # cancelling the running script.
+                os.kill(os.getpid(), SIGINT)
+                break
+            time.sleep(0.25)
+
+    def domenu_save_as(self, *args):
+        filename = EasyDialogs.AskFileForSave(message='Save console text as:',
+                savedFileName='console.txt')
+        if not filename:
+            return
+        f = open(filename, 'wb')
+        f.write(self.get())
+        f.close()
+        MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
+
+    def write(self, text):
+        self._buf = self._buf + text
+        if '\n' in self._buf:
+            self.flush()
+
+    def flush(self):
+        stuff = string.split(self._buf, '\n')
+        stuff = string.join(stuff, '\r')
+        self.setselection_at_end()
+        try:
+            self.ted.WEInsert(stuff, None, None)
+        finally:
+            self._buf = ""
+        selstart, selend = self.getselection()
+        self._inputstart = selstart
+        self.ted.WEClearUndo()
+        self.updatescrollbars()
+        if self._parentwindow.wid.GetWindowPort().QDIsPortBuffered():
+            self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
+
+    def selection_ok(self):
+        selstart, selend = self.getselection()
+        return not (selstart < self._inputstart or selend < self._inputstart)
+
+    def checkselection(self):
+        if not self.selection_ok():
+            self.setselection_at_end()
+
+    def setselection_at_end(self):
+        end = self.ted.WEGetTextLength()
+        self.setselection(end, end)
+        self.updatescrollbars()
+
+    def domenu_cut(self, *args):
+        if not self.selection_ok():
+            return
+        W.EditText.domenu_cut(self)
+
+    def domenu_paste(self, *args):
+        if not self.selection_ok():
+            self.setselection_at_end()
+        W.EditText.domenu_paste(self)
+
+    def domenu_clear(self, *args):
+        if not self.selection_ok():
+            return
+        W.EditText.domenu_clear(self)
 
 
 class PyConsole(W.Window):
-	
-	def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), 
-			tabsettings = (32, 0), unclosable = 0):
-		W.Window.__init__(self,
-					bounds, 
-					"Python Interactive", 
-					minsize = (200, 100), 
-					tabbable = 0, 
-					show = show)
-		
-		self._unclosable = unclosable
-		consoletext = ConsoleTextWidget((-1, -1, -14, 1), inset = (6, 5), 
-				fontsettings = fontsettings, tabsettings = tabsettings)
-		self._bary = W.Scrollbar((-15, 14, 16, -14), consoletext.vscroll, max = 32767)
-		self.consoletext = consoletext
-		self.namespacemenu = W.PopupMenu((-15, -1, 16, 16), [], self.consoletext.set_namespace)
-		self.namespacemenu.bind('<click>', self.makenamespacemenu)
-		self.open()
-	
-	def makenamespacemenu(self, *args):
-		W.SetCursor('watch')
-		namespacelist = self.getnamespacelist()
-		self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings), 
-				["Namespace"] + namespacelist, ("Browse namespace\xc9", self.browsenamespace)])
-		currentname = self.consoletext._namespace["__name__"]
-		for i in range(len(namespacelist)):
-			if namespacelist[i][0] == currentname:
-				break
-		else:
-			return
-		# XXX this functionality should be generally available in Wmenus
-		submenuid = self.namespacemenu.menu.menu.GetItemMark(3)
-		menu = self.namespacemenu.menu.bar.menus[submenuid]
-		menu.menu.CheckMenuItem(i + 1, 1)
-	
-	def browsenamespace(self):
-		import PyBrowser, W
-		W.SetCursor('watch')
-		PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
-	
-	def clearbuffer(self):
-		from Carbon import Res
-		self.consoletext.ted.WEUseText(Res.Resource(''))
-		self.consoletext.write(sys.ps1)
-		self.consoletext.flush()
-	
-	def getnamespacelist(self):
-		import os
-		import __main__
-		editors = filter(lambda x: x.__class__.__name__ == "Editor", self.parent._windows.values())
-		
-		namespaces = [ ("__main__",__main__.__dict__) ]
-		for ed in editors:
-			modname = os.path.splitext(ed.title)[0]
-			if sys.modules.has_key(modname):
-				module = sys.modules[modname] 
-				namespaces.append((modname, module.__dict__))
-			else:
-				if ed.title[-3:] == '.py':
-					modname = ed.title[:-3]
-				else:
-					modname = ed.title
-				ed.globals["__name__"] = modname
-				namespaces.append((modname, ed.globals))
-		return namespaces
-	
-	def dofontsettings(self):
-		import FontSettings
-		settings = FontSettings.FontDialog(self.consoletext.getfontsettings(),
-				self.consoletext.gettabsettings())
-		if settings:
-			fontsettings, tabsettings = settings
-			self.consoletext.setfontsettings(fontsettings)
-			self.consoletext.settabsettings(tabsettings)
-	
-	def show(self, onoff = 1):
-		W.Window.show(self, onoff)
-		if onoff:
-			self.select()
-	
-	def close(self):
-		if self._unclosable:
-			self.show(0)
-			return -1
-		W.Window.close(self)
-	
-	def writeprefs(self):
-		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-		prefs.console.show = self.isvisible()
-		prefs.console.windowbounds = self.getbounds()
-		prefs.console.fontsettings = self.consoletext.getfontsettings()
-		prefs.console.tabsettings = self.consoletext.gettabsettings()
-		prefs.save()
 
-	def getselectedtext(self):
-		return self.consoletext.getselectedtext()
-	
+    def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)),
+                    tabsettings = (32, 0), unclosable = 0):
+        W.Window.__init__(self,
+                                bounds,
+                                "Python Interactive",
+                                minsize = (200, 100),
+                                tabbable = 0,
+                                show = show)
+
+        self._unclosable = unclosable
+        consoletext = ConsoleTextWidget((-1, -1, -14, 1), inset = (6, 5),
+                        fontsettings = fontsettings, tabsettings = tabsettings)
+        self._bary = W.Scrollbar((-15, 14, 16, -14), consoletext.vscroll, max = 32767)
+        self.consoletext = consoletext
+        self.namespacemenu = W.PopupMenu((-15, -1, 16, 16), [], self.consoletext.set_namespace)
+        self.namespacemenu.bind('<click>', self.makenamespacemenu)
+        self.open()
+
+    def makenamespacemenu(self, *args):
+        W.SetCursor('watch')
+        namespacelist = self.getnamespacelist()
+        self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings),
+                        ["Namespace"] + namespacelist, ("Browse namespace\xc9", self.browsenamespace)])
+        currentname = self.consoletext._namespace["__name__"]
+        for i in range(len(namespacelist)):
+            if namespacelist[i][0] == currentname:
+                break
+        else:
+            return
+        # XXX this functionality should be generally available in Wmenus
+        submenuid = self.namespacemenu.menu.menu.GetItemMark(3)
+        menu = self.namespacemenu.menu.bar.menus[submenuid]
+        menu.menu.CheckMenuItem(i + 1, 1)
+
+    def browsenamespace(self):
+        import PyBrowser, W
+        W.SetCursor('watch')
+        PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
+
+    def clearbuffer(self):
+        from Carbon import Res
+        self.consoletext.ted.WEUseText(Res.Resource(''))
+        self.consoletext.write(sys.ps1)
+        self.consoletext.flush()
+
+    def getnamespacelist(self):
+        import os
+        import __main__
+        editors = filter(lambda x: x.__class__.__name__ == "Editor", self.parent._windows.values())
+
+        namespaces = [ ("__main__",__main__.__dict__) ]
+        for ed in editors:
+            modname = os.path.splitext(ed.title)[0]
+            if sys.modules.has_key(modname):
+                module = sys.modules[modname]
+                namespaces.append((modname, module.__dict__))
+            else:
+                if ed.title[-3:] == '.py':
+                    modname = ed.title[:-3]
+                else:
+                    modname = ed.title
+                ed.globals["__name__"] = modname
+                namespaces.append((modname, ed.globals))
+        return namespaces
+
+    def dofontsettings(self):
+        import FontSettings
+        settings = FontSettings.FontDialog(self.consoletext.getfontsettings(),
+                        self.consoletext.gettabsettings())
+        if settings:
+            fontsettings, tabsettings = settings
+            self.consoletext.setfontsettings(fontsettings)
+            self.consoletext.settabsettings(tabsettings)
+
+    def show(self, onoff = 1):
+        W.Window.show(self, onoff)
+        if onoff:
+            self.select()
+
+    def close(self):
+        if self._unclosable:
+            self.show(0)
+            return -1
+        W.Window.close(self)
+
+    def writeprefs(self):
+        prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+        prefs.console.show = self.isvisible()
+        prefs.console.windowbounds = self.getbounds()
+        prefs.console.fontsettings = self.consoletext.getfontsettings()
+        prefs.console.tabsettings = self.consoletext.gettabsettings()
+        prefs.save()
+
+    def getselectedtext(self):
+        return self.consoletext.getselectedtext()
+
 class OutputTextWidget(W.EditText):
-	
-	def domenu_save_as(self, *args):
-		title = self._parentwindow.gettitle()
-		filename = EasyDialogs.AskFileForSave(message='Save %s text as:' % title, 
-			savedFileName=title + '.txt')
-		if not filename:
-			return
-		f = open(filename, 'wb')
-		f.write(self.get())
-		f.close()
-		MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
-	
-	def domenu_cut(self, *args):
-		self.domenu_copy(*args)
-	
-	def domenu_clear(self, *args):
-		self.set('')
+
+    def domenu_save_as(self, *args):
+        title = self._parentwindow.gettitle()
+        filename = EasyDialogs.AskFileForSave(message='Save %s text as:' % title,
+                savedFileName=title + '.txt')
+        if not filename:
+            return
+        f = open(filename, 'wb')
+        f.write(self.get())
+        f.close()
+        MacOS.SetCreatorAndType(filename, W._signature, 'TEXT')
+
+    def domenu_cut(self, *args):
+        self.domenu_copy(*args)
+
+    def domenu_clear(self, *args):
+        self.set('')
 
 
 class PyOutput:
-	
-	def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), tabsettings = (32, 0)):
-		self.bounds = bounds
-		self.fontsettings = fontsettings
-		self.tabsettings = tabsettings
-		self.w = None
-		self.closed = 1
-		self._buf = ''
-		# should be able to set this
-		self.savestdout, self.savestderr = sys.stdout, sys.stderr
-		sys.stderr = sys.stdout = self
-		if show:
-			self.show()
-	
-	def setupwidgets(self):
-		self.w = W.Window(self.bounds, "Output", 
-				minsize = (200, 100), 
-				tabbable = 0)
-		self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5), 
-				fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1)
-		menuitems = [("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings)]
-		self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems)
-		
-		self.w._bary = W.Scrollbar((-15, 14, 16, -14), self.w.outputtext.vscroll, max = 32767)
-		self.w.bind("<close>", self.close)
-		self.w.bind("<activate>", self.activate)
-	
-	def write(self, text):
-		if hasattr(MacOS, 'EnableAppswitch'):
-			oldyield = MacOS.EnableAppswitch(-1)
-		try:
-			self._buf = self._buf + text
-			if '\n' in self._buf:
-				self.flush()
-		finally:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(oldyield)
-	
-	def flush(self):
-		self.show()
-		stuff = string.split(self._buf, '\n')
-		stuff = string.join(stuff, '\r')
-		end = self.w.outputtext.ted.WEGetTextLength()
-		self.w.outputtext.setselection(end, end)
-		self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
-		try:
-			self.w.outputtext.ted.WEInsert(stuff, None, None)
-		finally:
-			self._buf = ""
-		self.w.outputtext.updatescrollbars()
-		self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
-		if self.w.wid.GetWindowPort().QDIsPortBuffered():
-			self.w.wid.GetWindowPort().QDFlushPortBuffer(None)
-	
-	def show(self):
-		if self.closed:
-			if not self.w:
-				self.setupwidgets()
-				self.w.open()
-				self.w.outputtext.updatescrollbars()
-				self.closed = 0
-			else:
-				self.w.show(1)
-				self.closed = 0
-				self.w.select()
-	
-	def writeprefs(self):
-		if self.w is not None:
-			prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-			prefs.output.show = self.w.isvisible()
-			prefs.output.windowbounds = self.w.getbounds()
-			prefs.output.fontsettings = self.w.outputtext.getfontsettings()
-			prefs.output.tabsettings = self.w.outputtext.gettabsettings()
-			prefs.save()
-	
-	def dofontsettings(self):
-		import FontSettings
-		settings = FontSettings.FontDialog(self.w.outputtext.getfontsettings(),
-				self.w.outputtext.gettabsettings())
-		if settings:
-			fontsettings, tabsettings = settings
-			self.w.outputtext.setfontsettings(fontsettings)
-			self.w.outputtext.settabsettings(tabsettings)
-	
-	def clearbuffer(self):
-		from Carbon import Res
-		self.w.outputtext.set('')
-	
-	def activate(self, onoff):
-		if onoff:
-			self.closed = 0
-	
-	def close(self):
-		self.w.show(0)
-		self.closed = 1
-		return -1
+
+    def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), tabsettings = (32, 0)):
+        self.bounds = bounds
+        self.fontsettings = fontsettings
+        self.tabsettings = tabsettings
+        self.w = None
+        self.closed = 1
+        self._buf = ''
+        # should be able to set this
+        self.savestdout, self.savestderr = sys.stdout, sys.stderr
+        sys.stderr = sys.stdout = self
+        if show:
+            self.show()
+
+    def setupwidgets(self):
+        self.w = W.Window(self.bounds, "Output",
+                        minsize = (200, 100),
+                        tabbable = 0)
+        self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5),
+                        fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1)
+        menuitems = [("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings)]
+        self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems)
+
+        self.w._bary = W.Scrollbar((-15, 14, 16, -14), self.w.outputtext.vscroll, max = 32767)
+        self.w.bind("<close>", self.close)
+        self.w.bind("<activate>", self.activate)
+
+    def write(self, text):
+        if hasattr(MacOS, 'EnableAppswitch'):
+            oldyield = MacOS.EnableAppswitch(-1)
+        try:
+            self._buf = self._buf + text
+            if '\n' in self._buf:
+                self.flush()
+        finally:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(oldyield)
+
+    def flush(self):
+        self.show()
+        stuff = string.split(self._buf, '\n')
+        stuff = string.join(stuff, '\r')
+        end = self.w.outputtext.ted.WEGetTextLength()
+        self.w.outputtext.setselection(end, end)
+        self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
+        try:
+            self.w.outputtext.ted.WEInsert(stuff, None, None)
+        finally:
+            self._buf = ""
+        self.w.outputtext.updatescrollbars()
+        self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
+        if self.w.wid.GetWindowPort().QDIsPortBuffered():
+            self.w.wid.GetWindowPort().QDFlushPortBuffer(None)
+
+    def show(self):
+        if self.closed:
+            if not self.w:
+                self.setupwidgets()
+                self.w.open()
+                self.w.outputtext.updatescrollbars()
+                self.closed = 0
+            else:
+                self.w.show(1)
+                self.closed = 0
+                self.w.select()
+
+    def writeprefs(self):
+        if self.w is not None:
+            prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+            prefs.output.show = self.w.isvisible()
+            prefs.output.windowbounds = self.w.getbounds()
+            prefs.output.fontsettings = self.w.outputtext.getfontsettings()
+            prefs.output.tabsettings = self.w.outputtext.gettabsettings()
+            prefs.save()
+
+    def dofontsettings(self):
+        import FontSettings
+        settings = FontSettings.FontDialog(self.w.outputtext.getfontsettings(),
+                        self.w.outputtext.gettabsettings())
+        if settings:
+            fontsettings, tabsettings = settings
+            self.w.outputtext.setfontsettings(fontsettings)
+            self.w.outputtext.settabsettings(tabsettings)
+
+    def clearbuffer(self):
+        from Carbon import Res
+        self.w.outputtext.set('')
+
+    def activate(self, onoff):
+        if onoff:
+            self.closed = 0
+
+    def close(self):
+        self.w.show(0)
+        self.closed = 1
+        return -1
 
 
 class SimpleStdin:
-	
-	def readline(self):
-		import EasyDialogs
-		# A trick to make the input dialog box a bit more palatable
-		if hasattr(sys.stdout, '_buf'):
-			prompt = sys.stdout._buf
-		else:
-			prompt = ""
-		if not prompt:
-			prompt = "Stdin input:"
-		sys.stdout.flush()
-		rv = EasyDialogs.AskString(prompt)
-		if rv is None:
-			return ""
-		rv = rv + "\n"  # readline should include line terminator
-		sys.stdout.write(rv)  # echo user's reply
-		return rv
+
+    def readline(self):
+        import EasyDialogs
+        # A trick to make the input dialog box a bit more palatable
+        if hasattr(sys.stdout, '_buf'):
+            prompt = sys.stdout._buf
+        else:
+            prompt = ""
+        if not prompt:
+            prompt = "Stdin input:"
+        sys.stdout.flush()
+        rv = EasyDialogs.AskString(prompt)
+        if rv is None:
+            return ""
+        rv = rv + "\n"  # readline should include line terminator
+        sys.stdout.write(rv)  # echo user's reply
+        return rv
 
 
 def installconsole(defaultshow = 1):
-	global console
-	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-	if not prefs.console or not hasattr(prefs.console, 'show'):
-		prefs.console.show = defaultshow
-	if not hasattr(prefs.console, "windowbounds"):
-		prefs.console.windowbounds = (450, 250)
-	if not hasattr(prefs.console, "fontsettings"):
-		prefs.console.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
-	if not hasattr(prefs.console, "tabsettings"):
-		prefs.console.tabsettings = (32, 0)
-	console = PyConsole(prefs.console.windowbounds, prefs.console.show, 
-			prefs.console.fontsettings, prefs.console.tabsettings, 1)
+    global console
+    prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+    if not prefs.console or not hasattr(prefs.console, 'show'):
+        prefs.console.show = defaultshow
+    if not hasattr(prefs.console, "windowbounds"):
+        prefs.console.windowbounds = (450, 250)
+    if not hasattr(prefs.console, "fontsettings"):
+        prefs.console.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
+    if not hasattr(prefs.console, "tabsettings"):
+        prefs.console.tabsettings = (32, 0)
+    console = PyConsole(prefs.console.windowbounds, prefs.console.show,
+                    prefs.console.fontsettings, prefs.console.tabsettings, 1)
 
 def installoutput(defaultshow = 0, OutPutWindow = PyOutput):
-	global output
-	
-	# quick 'n' dirty std in emulation
-	sys.stdin = SimpleStdin()
-	
-	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-	if not prefs.output or not hasattr(prefs.output, 'show'):
-		prefs.output.show = defaultshow
-	if not hasattr(prefs.output, "windowbounds"):
-		prefs.output.windowbounds = (450, 250)
-	if not hasattr(prefs.output, "fontsettings"):
-		prefs.output.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
-	if not hasattr(prefs.output, "tabsettings"):
-		prefs.output.tabsettings = (32, 0)
-	output = OutPutWindow(prefs.output.windowbounds, prefs.output.show, 
-			prefs.output.fontsettings, prefs.output.tabsettings)
+    global output
+
+    # quick 'n' dirty std in emulation
+    sys.stdin = SimpleStdin()
+
+    prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+    if not prefs.output or not hasattr(prefs.output, 'show'):
+        prefs.output.show = defaultshow
+    if not hasattr(prefs.output, "windowbounds"):
+        prefs.output.windowbounds = (450, 250)
+    if not hasattr(prefs.output, "fontsettings"):
+        prefs.output.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
+    if not hasattr(prefs.output, "tabsettings"):
+        prefs.output.tabsettings = (32, 0)
+    output = OutPutWindow(prefs.output.windowbounds, prefs.output.show,
+                    prefs.output.fontsettings, prefs.output.tabsettings)
diff --git a/Mac/Tools/IDE/PyDebugger.py b/Mac/Tools/IDE/PyDebugger.py
index 51ba753..5ee92d5 100644
--- a/Mac/Tools/IDE/PyDebugger.py
+++ b/Mac/Tools/IDE/PyDebugger.py
@@ -13,882 +13,882 @@
 _filenames = {}
 
 SIMPLE_TYPES = (
-	types.NoneType,
-	types.IntType,
-	types.LongType,
-	types.FloatType,
-	types.ComplexType,
-	types.StringType
+        types.NoneType,
+        types.IntType,
+        types.LongType,
+        types.FloatType,
+        types.ComplexType,
+        types.StringType
 )
 
 
 class Debugger(bdb.Bdb):
-	
-	def __init__(self, title = 'Debugger'):
-		bdb.Bdb.__init__(self)
-		self.closed = 1
-		self.title = title
-		self.breaksviewer = None
-		self.reset()
-		self.tracing = 0
-		self.tracingmonitortime = Evt.TickCount()
-		self.editors = {}
-		
-		prefs = W.getapplication().getprefs()
-		if prefs.debugger:
-			for file, breaks in prefs.debugger.breaks.items():
-				for b in breaks:
-					self.set_break(file, b)
-			self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings
-			self.tracemagic = prefs.debugger.tracemagic
-		else:
-			self.breaks = {}
-			self.horpanes = (0.4, 0.6)
-			self.verpanes = (0.3, 0.35, 0.35)
-			self.bounds = (600, 400)
-			self.tracemagic = 0
-		self.laststacksel = None
-	
-	def canonic(self, filename):
-		# override: the provided canonic() method breaks our
-		# file-less Untitled windows
-		return filename
-	
-	def reset(self):
-		self.currentframe = None
-		self.file = None
-		self.laststack = None
-		self.reason = 'Not running'
-		self.continuewithoutdebugger = 0
-		bdb.Bdb.reset(self)
-		self.forget()
-	
-	def start(self, bottomframe = None, running = 0):
-		W.getapplication().DebuggerQuit = bdb.BdbQuit
-		from Carbon import Menu
-		Menu.HiliteMenu(0)
-		if self.closed:
-			self.setupwidgets(self.title)
-			self.closed = 0
-		if not self.w.parent.debugger_quitting:
-			self.w.select()
-			raise W.AlertError, 'There is another debugger session busy.'
-		self.reset()
-		self.botframe = bottomframe
-		if running:
-			self.set_continue()
-			self.reason = 'Running\xc9'
-			self.setstate('running')
-		else:
-			self.set_step()
-			self.reason = 'stopped'
-			self.setstate('stopped')
-		sys.settrace(self.trace_dispatch)
-	
-	def stop(self):
-		self.set_quit()
-		if self.w.parent:
-			self.exit_mainloop()
-			self.resetwidgets()
-	
-	def set_continue_without_debugger(self):
-		sys.settrace(None)
-		self.set_quit()
-		self.clear_tracefuncs()
-		self.continuewithoutdebugger = 1
-		if hasattr(self, "w") and self.w.parent:
-			self.exit_mainloop()
-			self.resetwidgets()
-	
-	def clear_tracefuncs(self):
-		try:
-			raise 'spam'
-		except:
-			pass
-		frame = sys.exc_traceback.tb_frame
-		while frame is not None:
-			del frame.f_trace
-			frame = frame.f_back
-	
-	def postmortem(self, exc_type, exc_value, traceback):
-		if self.closed:
-			self.setupwidgets(self.title)
-			self.closed = 0
-		if not self.w.parent.debugger_quitting:
-			raise W.AlertError, 'There is another debugger session busy.'
-		self.reset()
-		if traceback:
-			self.botframe = traceback.tb_frame
-			while traceback.tb_next <> None:
-				traceback = traceback.tb_next
-			frame = traceback.tb_frame
-		else:
-			self.botframe = None
-			frame = None
-		self.w.panes.bottom.buttons.killbutton.enable(1)
-		self.reason = '(dead) ' + self.formatexception(exc_type, exc_value)
-		self.w.select()
-		self.setup(frame, traceback)
-		self.setstate('dead')
-		self.showstack(self.curindex)
-		self.showframe(self.curindex)
-	
-	def setupwidgets(self, title):
-		self.w = w = W.Window(self.bounds, title, minsize = (500, 300))
-		
-		w.panes = W.HorizontalPanes((8, 4, -8, -8), self.horpanes)
-		
-		w.panes.browserpanes = browserpanes = W.VerticalPanes(None, self.verpanes)
-		
-		browserpanes.stacklist = W.Group(None)
-		browserpanes.stacklist.title = W.TextBox((4, 0, 0, 12), 'Stack')
-		browserpanes.stacklist.stack = W.List((0, 16, 0, 0), callback = self.do_stack, flags = Lists.lOnlyOne)
-		
-		browserpanes.locals = W.Group(None)
-		browserpanes.locals.title = W.TextBox((4, 0, 0, 12), 'Local variables')
-		browserpanes.locals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
-		
-		browserpanes.globals = W.Group(None)
-		browserpanes.globals.title = W.TextBox((4, 0, 0, 12), 'Global variables')
-		browserpanes.globals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
-		
-		w.panes.bottom = bottom = W.Group(None)
-		bottom.src = src = W.Group((0, 64, 0, 0))
-		source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self)
-		src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), [])
-		src.optionsmenu.bind('<click>', self.makeoptionsmenu)
-		
-		src._barx = W.Scrollbar((0, -16, -15, 16), source.hscroll, max = 32767)
-		src._bary = W.Scrollbar((-16, 15, 16, -15), source.vscroll, max = 32767)
-		src.source = source
-		src.frame = W.Frame((0, 0, -15, -15))
-		
-		bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6))
-		bottom.state = W.TextBox((12, 24, 0, 16), self.reason)
-		
-		bottom.srctitle = W.TextBox((12, 44, 0, 16))
-		bottom.buttons = buttons = W.Group((12, 0, 0, 20))
-		
-		buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run)
-		buttons.stopbutton = W.Button((58, 0, 50, 16), "Stop", self.do_stop)
-		buttons.killbutton = W.Button((116, 0, 50, 16), "Kill", self.do_kill)
-		buttons.line = W.VerticalLine((173, 0, 0, 0))
-		buttons.stepbutton = W.Button((181, 0, 60, 16), "Step", self.do_step)
-		buttons.stepinbutton = W.Button((249, 0, 60, 16), "Step in", self.do_stepin)
-		buttons.stepoutbutton = W.Button((317, 0, 60, 16), "Step out", self.do_stepout)
-		
-		w.bind('cmdr', buttons.runbutton.push)
-		w.bind('cmd.', buttons.stopbutton.push)
-		w.bind('cmdk', buttons.killbutton.push)
-		w.bind('cmds', buttons.stepbutton.push)
-		w.bind('cmdt', buttons.stepinbutton.push)
-		w.bind('cmdu', buttons.stepoutbutton.push)
-		
-		w.bind('<close>', self.close)
-		
-		w.open()
-		w.xxx___select(w.panes.bottom.src.source)
-	
-	def makeoptionsmenu(self):
-		options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints), 
-				('Clear all breakpoints', self.clear_all_breaks),
-				('Edit breakpoints\xc9', self.edit_breaks), '-',
-				(self.tracemagic and 
-					'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)]
-		self.w.panes.bottom.src.optionsmenu.set(options)
-	
-	def edit_breaks(self):
-		if self.breaksviewer:
-			self.breaksviewer.select()
-		else:
-			self.breaksviewer = BreakpointsViewer(self)
-	
-	def togglemagic(self):
-		self.tracemagic = not self.tracemagic
-	
-	def setstate(self, state):
-		self.w.panes.bottom.tracingmonitor.reset()
-		self.w.panes.bottom.state.set(self.reason)
-		buttons = self.w.panes.bottom.buttons
-		if state == 'stopped':
-			buttons.runbutton.enable(1)
-			buttons.stopbutton.enable(0)
-			buttons.killbutton.enable(1)
-			buttons.stepbutton.enable(1)
-			buttons.stepinbutton.enable(1)
-			buttons.stepoutbutton.enable(1)
-		elif state == 'running':
-			buttons.runbutton.enable(0)
-			buttons.stopbutton.enable(1)
-			buttons.killbutton.enable(1)
-			buttons.stepbutton.enable(0)
-			buttons.stepinbutton.enable(0)
-			buttons.stepoutbutton.enable(0)
-		elif state == 'idle':
-			buttons.runbutton.enable(0)
-			buttons.stopbutton.enable(0)
-			buttons.killbutton.enable(0)
-			buttons.stepbutton.enable(0)
-			buttons.stepinbutton.enable(0)
-			buttons.stepoutbutton.enable(0)
-		elif state == 'dead':
-			buttons.runbutton.enable(0)
-			buttons.stopbutton.enable(0)
-			buttons.killbutton.enable(1)
-			buttons.stepbutton.enable(0)
-			buttons.stepinbutton.enable(0)
-			buttons.stepoutbutton.enable(0)
-		else:
-			print 'unknown state:', state
-	
-	def resetwidgets(self):
-		self.reason = ''
-		self.w.panes.bottom.srctitle.set('')
-		self.w.panes.bottom.src.source.set('')
-		self.w.panes.browserpanes.stacklist.stack.set([])
-		self.w.panes.browserpanes.locals.browser.set({})
-		self.w.panes.browserpanes.globals.browser.set({})
-		self.setstate('idle')
-	
-	# W callbacks
-	
-	def close(self):
-		self.set_quit()
-		self.exit_mainloop()
-		self.closed = 1
-		
-		self.unregister_editor(self.w.panes.bottom.src.source, 
-				self.w.panes.bottom.src.source.file)
-		self.horpanes = self.w.panes.getpanesizes()
-		self.verpanes = self.w.panes.browserpanes.getpanesizes()
-		self.bounds = self.w.getbounds()
-		prefs = W.getapplication().getprefs()
-		prefs.debugger.breaks = self.breaks
-		prefs.debugger.windowsettings = self.bounds, self.horpanes, self.verpanes
-		prefs.debugger.tracemagic = self.tracemagic
-		prefs.save()
-	
-	# stack list callback
-	
-	def do_stack(self, isdbl):
-		sel = self.w.panes.browserpanes.stacklist.stack.getselection()
-		if isdbl:
-			if sel:
-				frame, lineno = self.stack[sel[0] + 1]
-				filename = frame.f_code.co_filename
-				editor = self.w._parentwindow.parent.openscript(filename, lineno)
-				if self.breaks.has_key(filename):
-					editor.showbreakpoints(1)
-		else:
-			if sel and sel <> self.laststacksel:
-				self.showframe(sel[0] + 1)
-			self.laststacksel = sel
-	
-	def geteditor(self, filename):
-		if filename[:1] == '<' and filename[-1:] == '>':
-			editor = W.getapplication().getscript(filename[1:-1])
-		else:
-			editor = W.getapplication().getscript(filename)
-		return editor
-	
-	# button callbacks
-	
-	def do_run(self):
-		self.running()
-		self.set_continue()
-		self.exit_mainloop()
-	
-	def do_stop(self):
-		self.set_step()
-	
-	def do_kill(self):
-		self.set_quit()
-		self.exit_mainloop()
-		self.resetwidgets()
-	
-	def do_step(self):
-		self.running()
-		self.set_next(self.curframe)
-		self.exit_mainloop()
-	
-	def do_stepin(self):
-		self.running()
-		self.set_step()
-		self.exit_mainloop()
-	
-	def do_stepout(self):
-		self.running()
-		self.set_return(self.curframe)
-		self.exit_mainloop()
-	
-	def running(self):
-		W.SetCursor('watch')
-		self.reason = 'Running\xc9'
-		self.setstate('running')
-		#self.w.panes.bottom.src.source.set('')
-		#self.w.panes.browserpanes.stacklist.stack.set([])
-		#self.w.panes.browserpanes.locals.browser.set({})
-		#self.w.panes.browserpanes.globals.browser.set({})
-	
-	def exit_mainloop(self):
-		self.w.parent.debugger_quitting = 1
-	
-	#
-	
-	def showframe(self, stackindex):
-		(frame, lineno) = self.stack[stackindex]
-		W.SetCursor('watch')
-		filename = frame.f_code.co_filename
-		if filename <> self.file:
-			editor = self.geteditor(filename)
-			if editor:
-				self.w.panes.bottom.src.source.set(editor.get(), filename)
-			else:
-				try:
-					f = open(filename, 'rU')
-					data = f.read()
-					f.close()
-				except IOError:
-					if filename[-3:] == '.py':
-						import imp
-						modname = os.path.basename(filename)[:-3]
-						try:
-							f, filename, (suff, mode, dummy) = imp.find_module(modname)
-						except ImportError:
-							self.w.panes.bottom.src.source.set("can't find file")
-						else:
-							if f:
-								f.close()
-							if f and suff == '.py':
-								f = open(filename, 'rU')
-								data = f.read()
-								f.close()
-								self.w.panes.bottom.src.source.set(data, filename)
-							else:
-								self.w.panes.bottom.src.source.set("can't find file")
-					else:
-						self.w.panes.bottom.src.source.set("can't find file")
-				else:
-					data = data.replace('\n', '\r')
-					self.w.panes.bottom.src.source.set(data, filename)
-			self.file = filename
-		self.w.panes.bottom.srctitle.set('Source: ' + filename + ((lineno > 0) and (' (line %d)' % lineno) or ' '))
-		self.goto_line(lineno)
-		self.lineno = lineno
-		self.showvars((frame, lineno))
-	
-	def showvars(self, (frame, lineno)):
-		if frame.f_locals is not frame.f_globals:
-			locals = frame.f_locals
-		else:
-			locals = {'Same as Globals':''}
-		filteredlocals = {}
-		for key, value in locals.items():
-			# empty key is magic for Python 1.4; '.' is magic for 1.5...
-			if not key or key[0] <> '.':
-				filteredlocals[key] = value
-		self.w.panes.browserpanes.locals.browser.set(filteredlocals)
-		self.w.panes.browserpanes.globals.browser.set(frame.f_globals)
-	
-	def showstack(self, stackindex):
-		stack = []
-		for frame, lineno in self.stack[1:]:
-			filename = frame.f_code.co_filename
-			try:
-				filename = _filenames[filename]
-			except KeyError:
-				if filename[:1] + filename[-1:] <> '<>':
-					filename = os.path.basename(filename)
-				_filenames[frame.f_code.co_filename] = filename
-			funcname = frame.f_code.co_name
-			if funcname == '?':
-				funcname = '<toplevel>'
-			stack.append(filename + ': ' + funcname)
-		if stack <> self.laststack:
-			self.w.panes.browserpanes.stacklist.stack.set(stack)
-			self.laststack = stack
-		sel = [stackindex - 1]
-		self.w.panes.browserpanes.stacklist.stack.setselection(sel)
-		self.laststacksel = sel
-	
-	def goto_line(self, lineno):
-		if lineno > 0:
-			self.w.panes.bottom.src.source.selectline(lineno - 1)
-		else:
-			self.w.panes.bottom.src.source.setselection(0, 0)
-	
-	# bdb entry points
-	
-#	def user_call(self, frame, argument_list):
-#		self.reason = 'Calling'
-#		self.interaction(frame, None)
-	
-	def user_line(self, frame):
-		# This function is called when we stop or break at this line
-		self.reason = 'Stopped'
-		self.interaction(frame, None)
-	
-	def user_return(self, frame, return_value):
-		# This function is called when a return trap is set here
-		fname = frame.f_code.co_name
-		if fname <> '?':
-			self.reason = 'Returning from %s()' % frame.f_code.co_name
-			frame.f_locals['__return__'] = return_value
-		elif frame.f_back is self.botframe:
-			self.reason = 'Done'
-		else:
-			self.reason = 'Returning'
-		self.interaction(frame, None, 1)
-	
-	def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
-		# This function is called when we stop or break at this line
-		self.reason = self.formatexception(exc_type, exc_value)
-		self.interaction(frame, exc_traceback)
-	
-	def formatexception(self, exc_type, exc_value):
-		if exc_type == SyntaxError:
-			try:
-				value, (filename, lineno, charno, line) = exc_value
-			except:
-				pass
-			else:
-				return str(exc_type) + ': ' + str(value)
-		if type(exc_type) == types.ClassType:
-			nice = exc_type.__name__
-		else:
-			nice = str(exc_type)
-		value = str(exc_value)
-		if exc_value and value:
-			nice = nice + ": " + value
-		return nice
-	
-	def forget(self):
-		self.stack = []
-		self.curindex = 0
-		self.curframe = None
-	
-	def setup(self, f, t, isreturning = 0):
-		self.forget()
-		self.stack, self.curindex = self.get_stack(f, t)
-		self.curframe = self.stack[self.curindex - isreturning][0]
-	
-	def interaction(self, frame, traceback, isreturning = 0):
-		saveport = Qd.GetPort()
-		self.w.select()
-		try:
-			self.setup(frame, traceback, isreturning)
-			self.setstate('stopped')
-			stackindex = self.curindex
-			if isreturning:
-				if frame.f_back is not self.botframe:
-					stackindex = stackindex - 1
-			self.showstack(stackindex)
-			self.showframe(stackindex)
-			self.w.parent.debugger_mainloop()
-			self.forget()
-		finally:
-			Qd.SetPort(saveport)
-	
-	# bdb customization
-	
-	def trace_dispatch(self, frame, event, arg, TickCount = Evt.TickCount):
-		if TickCount() - self.tracingmonitortime > 15:
-			self.tracingmonitortime = TickCount()
-			self.w.panes.bottom.tracingmonitor.toggle()
-		try:
-			try:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(0)
-				if self.quitting:
-					# returning None is not enough, a former BdbQuit exception
-					# might have been eaten by the print statement
-					raise bdb.BdbQuit
-				if event == 'line':
-					return self.dispatch_line(frame)
-				if event == 'call':
-					return self.dispatch_call(frame, arg)
-				if event == 'return':
-					return self.dispatch_return(frame, arg)
-				if event == 'exception':
-					return self.dispatch_exception(frame, arg)
-				print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
-				return self.trace_dispatch
-			finally:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(-1)
-		except KeyboardInterrupt:
-			self.set_step()
-			return self.trace_dispatch
-		except bdb.BdbQuit:
-			if self.continuewithoutdebugger:
-				self.clear_tracefuncs()
-				return
-			else:
-				raise bdb.BdbQuit
-		except:
-			print 'XXX Exception during debugger interaction.', \
-					self.formatexception(sys.exc_type, sys.exc_value)
-			import traceback
-			traceback.print_exc()
-			return self.trace_dispatch
-	
-	def dispatch_call(self, frame, arg):
-		if not self.tracemagic and \
-				frame.f_code.co_name[:2] == '__' == frame.f_code.co_name[-2:] and \
-				frame.f_code.co_name <> '__init__':
-			return
-		if self.botframe is None:
-			# First call of dispatch since reset()
-			self.botframe = frame.f_back	# xxx !!! added f_back
-			return self.trace_dispatch
-		if not (self.stop_here(frame) or self.break_anywhere(frame)):
-			# No need to trace this function
-			return # None
-		self.user_call(frame, arg)
-		if self.quitting:
-			raise bdb.BdbQuit
-		return self.trace_dispatch
-	
-	def set_continue(self):
-		# Don't stop except at breakpoints or when finished
-		self.stopframe = self.botframe
-		self.returnframe = None
-		self.quitting = 0
-		# unlike in bdb/pdb, there's a chance that breakpoints change 
-		# *while* a program (this program ;-) is running. It's actually quite likely.
-		# So we don't delete frame.f_trace until the bottom frame if there are no breakpoints.
-	
-	def set_break(self, filename, lineno):
-		if not self.breaks.has_key(filename):
-			self.breaks[filename] = []
-		list = self.breaks[filename]
-		if lineno in list:
-			return 'There is already a breakpoint there!'
-		list.append(lineno)
-		list.sort()	# I want to keep them neatly sorted; easier for drawing
-		if hasattr(bdb, "Breakpoint"):
-			# 1.5.2b1 specific
-			bp = bdb.Breakpoint(filename, lineno, 0, None)
-		self.update_breaks(filename)
-	
-	def clear_break(self, filename, lineno):
-		bdb.Bdb.clear_break(self, filename, lineno)
-		self.update_breaks(filename)
-	
-	def clear_all_file_breaks(self, filename):
-		bdb.Bdb.clear_all_file_breaks(self, filename)
-		self.update_breaks(filename)
-	
-	def clear_all_breaks(self):
-		bdb.Bdb.clear_all_breaks(self)
-		for editors in self.editors.values():
-			for editor in editors:
-				editor.drawbreakpoints()
-	
-	# special
-	
-	def toggle_break(self, filename, lineno):
-		if self.get_break(filename, lineno):
-			self.clear_break(filename, lineno)
-		else:
-			self.set_break(filename, lineno)
-	
-	def clear_breaks_above(self, filename, above):
-		if not self.breaks.has_key(filename):
-			return 'There are no breakpoints in that file!'
-		for lineno in self.breaks[filename][:]:
-			if lineno > above:
-				self.breaks[filename].remove(lineno)
-		if not self.breaks[filename]:
-			del self.breaks[filename]
-	
-	# editor stuff
-	
-	def update_breaks(self, filename):
-		if self.breaksviewer:
-			self.breaksviewer.update()
-		if self.editors.has_key(filename):
-			for editor in self.editors[filename]:
-				if editor._debugger:	# XXX
-					editor.drawbreakpoints()
-				else:
-					print 'xxx dead editor!'
-	
-	def update_allbreaks(self):
-		if self.breaksviewer:
-			self.breaksviewer.update()
-		for filename in self.breaks.keys():
-			if self.editors.has_key(filename):
-				for editor in self.editors[filename]:
-					if editor._debugger:	# XXX
-						editor.drawbreakpoints()
-					else:
-						print 'xxx dead editor!'
-	
-	def register_editor(self, editor, filename):
-		if not filename:
-			return
-		if not self.editors.has_key(filename):
-			self.editors[filename] = [editor]
-		elif editor not in self.editors[filename]:
-			self.editors[filename].append(editor)
-	
-	def unregister_editor(self, editor, filename):
-		if not filename:
-			return
-		try:
-			self.editors[filename].remove(editor)
-			if not self.editors[filename]:
-				del self.editors[filename]
-				# if this was an untitled window, clear the breaks.
-				if filename[:1] == '<' and filename[-1:] == '>' and \
-						self.breaks.has_key(filename):
-					self.clear_all_file_breaks(filename)
-		except (KeyError, ValueError):
-			pass
-		
+
+    def __init__(self, title = 'Debugger'):
+        bdb.Bdb.__init__(self)
+        self.closed = 1
+        self.title = title
+        self.breaksviewer = None
+        self.reset()
+        self.tracing = 0
+        self.tracingmonitortime = Evt.TickCount()
+        self.editors = {}
+
+        prefs = W.getapplication().getprefs()
+        if prefs.debugger:
+            for file, breaks in prefs.debugger.breaks.items():
+                for b in breaks:
+                    self.set_break(file, b)
+            self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings
+            self.tracemagic = prefs.debugger.tracemagic
+        else:
+            self.breaks = {}
+            self.horpanes = (0.4, 0.6)
+            self.verpanes = (0.3, 0.35, 0.35)
+            self.bounds = (600, 400)
+            self.tracemagic = 0
+        self.laststacksel = None
+
+    def canonic(self, filename):
+        # override: the provided canonic() method breaks our
+        # file-less Untitled windows
+        return filename
+
+    def reset(self):
+        self.currentframe = None
+        self.file = None
+        self.laststack = None
+        self.reason = 'Not running'
+        self.continuewithoutdebugger = 0
+        bdb.Bdb.reset(self)
+        self.forget()
+
+    def start(self, bottomframe = None, running = 0):
+        W.getapplication().DebuggerQuit = bdb.BdbQuit
+        from Carbon import Menu
+        Menu.HiliteMenu(0)
+        if self.closed:
+            self.setupwidgets(self.title)
+            self.closed = 0
+        if not self.w.parent.debugger_quitting:
+            self.w.select()
+            raise W.AlertError, 'There is another debugger session busy.'
+        self.reset()
+        self.botframe = bottomframe
+        if running:
+            self.set_continue()
+            self.reason = 'Running\xc9'
+            self.setstate('running')
+        else:
+            self.set_step()
+            self.reason = 'stopped'
+            self.setstate('stopped')
+        sys.settrace(self.trace_dispatch)
+
+    def stop(self):
+        self.set_quit()
+        if self.w.parent:
+            self.exit_mainloop()
+            self.resetwidgets()
+
+    def set_continue_without_debugger(self):
+        sys.settrace(None)
+        self.set_quit()
+        self.clear_tracefuncs()
+        self.continuewithoutdebugger = 1
+        if hasattr(self, "w") and self.w.parent:
+            self.exit_mainloop()
+            self.resetwidgets()
+
+    def clear_tracefuncs(self):
+        try:
+            raise 'spam'
+        except:
+            pass
+        frame = sys.exc_traceback.tb_frame
+        while frame is not None:
+            del frame.f_trace
+            frame = frame.f_back
+
+    def postmortem(self, exc_type, exc_value, traceback):
+        if self.closed:
+            self.setupwidgets(self.title)
+            self.closed = 0
+        if not self.w.parent.debugger_quitting:
+            raise W.AlertError, 'There is another debugger session busy.'
+        self.reset()
+        if traceback:
+            self.botframe = traceback.tb_frame
+            while traceback.tb_next <> None:
+                traceback = traceback.tb_next
+            frame = traceback.tb_frame
+        else:
+            self.botframe = None
+            frame = None
+        self.w.panes.bottom.buttons.killbutton.enable(1)
+        self.reason = '(dead) ' + self.formatexception(exc_type, exc_value)
+        self.w.select()
+        self.setup(frame, traceback)
+        self.setstate('dead')
+        self.showstack(self.curindex)
+        self.showframe(self.curindex)
+
+    def setupwidgets(self, title):
+        self.w = w = W.Window(self.bounds, title, minsize = (500, 300))
+
+        w.panes = W.HorizontalPanes((8, 4, -8, -8), self.horpanes)
+
+        w.panes.browserpanes = browserpanes = W.VerticalPanes(None, self.verpanes)
+
+        browserpanes.stacklist = W.Group(None)
+        browserpanes.stacklist.title = W.TextBox((4, 0, 0, 12), 'Stack')
+        browserpanes.stacklist.stack = W.List((0, 16, 0, 0), callback = self.do_stack, flags = Lists.lOnlyOne)
+
+        browserpanes.locals = W.Group(None)
+        browserpanes.locals.title = W.TextBox((4, 0, 0, 12), 'Local variables')
+        browserpanes.locals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
+
+        browserpanes.globals = W.Group(None)
+        browserpanes.globals.title = W.TextBox((4, 0, 0, 12), 'Global variables')
+        browserpanes.globals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0))
+
+        w.panes.bottom = bottom = W.Group(None)
+        bottom.src = src = W.Group((0, 64, 0, 0))
+        source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self)
+        src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), [])
+        src.optionsmenu.bind('<click>', self.makeoptionsmenu)
+
+        src._barx = W.Scrollbar((0, -16, -15, 16), source.hscroll, max = 32767)
+        src._bary = W.Scrollbar((-16, 15, 16, -15), source.vscroll, max = 32767)
+        src.source = source
+        src.frame = W.Frame((0, 0, -15, -15))
+
+        bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6))
+        bottom.state = W.TextBox((12, 24, 0, 16), self.reason)
+
+        bottom.srctitle = W.TextBox((12, 44, 0, 16))
+        bottom.buttons = buttons = W.Group((12, 0, 0, 20))
+
+        buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run)
+        buttons.stopbutton = W.Button((58, 0, 50, 16), "Stop", self.do_stop)
+        buttons.killbutton = W.Button((116, 0, 50, 16), "Kill", self.do_kill)
+        buttons.line = W.VerticalLine((173, 0, 0, 0))
+        buttons.stepbutton = W.Button((181, 0, 60, 16), "Step", self.do_step)
+        buttons.stepinbutton = W.Button((249, 0, 60, 16), "Step in", self.do_stepin)
+        buttons.stepoutbutton = W.Button((317, 0, 60, 16), "Step out", self.do_stepout)
+
+        w.bind('cmdr', buttons.runbutton.push)
+        w.bind('cmd.', buttons.stopbutton.push)
+        w.bind('cmdk', buttons.killbutton.push)
+        w.bind('cmds', buttons.stepbutton.push)
+        w.bind('cmdt', buttons.stepinbutton.push)
+        w.bind('cmdu', buttons.stepoutbutton.push)
+
+        w.bind('<close>', self.close)
+
+        w.open()
+        w.xxx___select(w.panes.bottom.src.source)
+
+    def makeoptionsmenu(self):
+        options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints),
+                        ('Clear all breakpoints', self.clear_all_breaks),
+                        ('Edit breakpoints\xc9', self.edit_breaks), '-',
+                        (self.tracemagic and
+                                'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)]
+        self.w.panes.bottom.src.optionsmenu.set(options)
+
+    def edit_breaks(self):
+        if self.breaksviewer:
+            self.breaksviewer.select()
+        else:
+            self.breaksviewer = BreakpointsViewer(self)
+
+    def togglemagic(self):
+        self.tracemagic = not self.tracemagic
+
+    def setstate(self, state):
+        self.w.panes.bottom.tracingmonitor.reset()
+        self.w.panes.bottom.state.set(self.reason)
+        buttons = self.w.panes.bottom.buttons
+        if state == 'stopped':
+            buttons.runbutton.enable(1)
+            buttons.stopbutton.enable(0)
+            buttons.killbutton.enable(1)
+            buttons.stepbutton.enable(1)
+            buttons.stepinbutton.enable(1)
+            buttons.stepoutbutton.enable(1)
+        elif state == 'running':
+            buttons.runbutton.enable(0)
+            buttons.stopbutton.enable(1)
+            buttons.killbutton.enable(1)
+            buttons.stepbutton.enable(0)
+            buttons.stepinbutton.enable(0)
+            buttons.stepoutbutton.enable(0)
+        elif state == 'idle':
+            buttons.runbutton.enable(0)
+            buttons.stopbutton.enable(0)
+            buttons.killbutton.enable(0)
+            buttons.stepbutton.enable(0)
+            buttons.stepinbutton.enable(0)
+            buttons.stepoutbutton.enable(0)
+        elif state == 'dead':
+            buttons.runbutton.enable(0)
+            buttons.stopbutton.enable(0)
+            buttons.killbutton.enable(1)
+            buttons.stepbutton.enable(0)
+            buttons.stepinbutton.enable(0)
+            buttons.stepoutbutton.enable(0)
+        else:
+            print 'unknown state:', state
+
+    def resetwidgets(self):
+        self.reason = ''
+        self.w.panes.bottom.srctitle.set('')
+        self.w.panes.bottom.src.source.set('')
+        self.w.panes.browserpanes.stacklist.stack.set([])
+        self.w.panes.browserpanes.locals.browser.set({})
+        self.w.panes.browserpanes.globals.browser.set({})
+        self.setstate('idle')
+
+    # W callbacks
+
+    def close(self):
+        self.set_quit()
+        self.exit_mainloop()
+        self.closed = 1
+
+        self.unregister_editor(self.w.panes.bottom.src.source,
+                        self.w.panes.bottom.src.source.file)
+        self.horpanes = self.w.panes.getpanesizes()
+        self.verpanes = self.w.panes.browserpanes.getpanesizes()
+        self.bounds = self.w.getbounds()
+        prefs = W.getapplication().getprefs()
+        prefs.debugger.breaks = self.breaks
+        prefs.debugger.windowsettings = self.bounds, self.horpanes, self.verpanes
+        prefs.debugger.tracemagic = self.tracemagic
+        prefs.save()
+
+    # stack list callback
+
+    def do_stack(self, isdbl):
+        sel = self.w.panes.browserpanes.stacklist.stack.getselection()
+        if isdbl:
+            if sel:
+                frame, lineno = self.stack[sel[0] + 1]
+                filename = frame.f_code.co_filename
+                editor = self.w._parentwindow.parent.openscript(filename, lineno)
+                if self.breaks.has_key(filename):
+                    editor.showbreakpoints(1)
+        else:
+            if sel and sel <> self.laststacksel:
+                self.showframe(sel[0] + 1)
+            self.laststacksel = sel
+
+    def geteditor(self, filename):
+        if filename[:1] == '<' and filename[-1:] == '>':
+            editor = W.getapplication().getscript(filename[1:-1])
+        else:
+            editor = W.getapplication().getscript(filename)
+        return editor
+
+    # button callbacks
+
+    def do_run(self):
+        self.running()
+        self.set_continue()
+        self.exit_mainloop()
+
+    def do_stop(self):
+        self.set_step()
+
+    def do_kill(self):
+        self.set_quit()
+        self.exit_mainloop()
+        self.resetwidgets()
+
+    def do_step(self):
+        self.running()
+        self.set_next(self.curframe)
+        self.exit_mainloop()
+
+    def do_stepin(self):
+        self.running()
+        self.set_step()
+        self.exit_mainloop()
+
+    def do_stepout(self):
+        self.running()
+        self.set_return(self.curframe)
+        self.exit_mainloop()
+
+    def running(self):
+        W.SetCursor('watch')
+        self.reason = 'Running\xc9'
+        self.setstate('running')
+        #self.w.panes.bottom.src.source.set('')
+        #self.w.panes.browserpanes.stacklist.stack.set([])
+        #self.w.panes.browserpanes.locals.browser.set({})
+        #self.w.panes.browserpanes.globals.browser.set({})
+
+    def exit_mainloop(self):
+        self.w.parent.debugger_quitting = 1
+
+    #
+
+    def showframe(self, stackindex):
+        (frame, lineno) = self.stack[stackindex]
+        W.SetCursor('watch')
+        filename = frame.f_code.co_filename
+        if filename <> self.file:
+            editor = self.geteditor(filename)
+            if editor:
+                self.w.panes.bottom.src.source.set(editor.get(), filename)
+            else:
+                try:
+                    f = open(filename, 'rU')
+                    data = f.read()
+                    f.close()
+                except IOError:
+                    if filename[-3:] == '.py':
+                        import imp
+                        modname = os.path.basename(filename)[:-3]
+                        try:
+                            f, filename, (suff, mode, dummy) = imp.find_module(modname)
+                        except ImportError:
+                            self.w.panes.bottom.src.source.set("can't find file")
+                        else:
+                            if f:
+                                f.close()
+                            if f and suff == '.py':
+                                f = open(filename, 'rU')
+                                data = f.read()
+                                f.close()
+                                self.w.panes.bottom.src.source.set(data, filename)
+                            else:
+                                self.w.panes.bottom.src.source.set("can't find file")
+                    else:
+                        self.w.panes.bottom.src.source.set("can't find file")
+                else:
+                    data = data.replace('\n', '\r')
+                    self.w.panes.bottom.src.source.set(data, filename)
+            self.file = filename
+        self.w.panes.bottom.srctitle.set('Source: ' + filename + ((lineno > 0) and (' (line %d)' % lineno) or ' '))
+        self.goto_line(lineno)
+        self.lineno = lineno
+        self.showvars((frame, lineno))
+
+    def showvars(self, (frame, lineno)):
+        if frame.f_locals is not frame.f_globals:
+            locals = frame.f_locals
+        else:
+            locals = {'Same as Globals':''}
+        filteredlocals = {}
+        for key, value in locals.items():
+            # empty key is magic for Python 1.4; '.' is magic for 1.5...
+            if not key or key[0] <> '.':
+                filteredlocals[key] = value
+        self.w.panes.browserpanes.locals.browser.set(filteredlocals)
+        self.w.panes.browserpanes.globals.browser.set(frame.f_globals)
+
+    def showstack(self, stackindex):
+        stack = []
+        for frame, lineno in self.stack[1:]:
+            filename = frame.f_code.co_filename
+            try:
+                filename = _filenames[filename]
+            except KeyError:
+                if filename[:1] + filename[-1:] <> '<>':
+                    filename = os.path.basename(filename)
+                _filenames[frame.f_code.co_filename] = filename
+            funcname = frame.f_code.co_name
+            if funcname == '?':
+                funcname = '<toplevel>'
+            stack.append(filename + ': ' + funcname)
+        if stack <> self.laststack:
+            self.w.panes.browserpanes.stacklist.stack.set(stack)
+            self.laststack = stack
+        sel = [stackindex - 1]
+        self.w.panes.browserpanes.stacklist.stack.setselection(sel)
+        self.laststacksel = sel
+
+    def goto_line(self, lineno):
+        if lineno > 0:
+            self.w.panes.bottom.src.source.selectline(lineno - 1)
+        else:
+            self.w.panes.bottom.src.source.setselection(0, 0)
+
+    # bdb entry points
+
+#       def user_call(self, frame, argument_list):
+#               self.reason = 'Calling'
+#               self.interaction(frame, None)
+
+    def user_line(self, frame):
+        # This function is called when we stop or break at this line
+        self.reason = 'Stopped'
+        self.interaction(frame, None)
+
+    def user_return(self, frame, return_value):
+        # This function is called when a return trap is set here
+        fname = frame.f_code.co_name
+        if fname <> '?':
+            self.reason = 'Returning from %s()' % frame.f_code.co_name
+            frame.f_locals['__return__'] = return_value
+        elif frame.f_back is self.botframe:
+            self.reason = 'Done'
+        else:
+            self.reason = 'Returning'
+        self.interaction(frame, None, 1)
+
+    def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
+        # This function is called when we stop or break at this line
+        self.reason = self.formatexception(exc_type, exc_value)
+        self.interaction(frame, exc_traceback)
+
+    def formatexception(self, exc_type, exc_value):
+        if exc_type == SyntaxError:
+            try:
+                value, (filename, lineno, charno, line) = exc_value
+            except:
+                pass
+            else:
+                return str(exc_type) + ': ' + str(value)
+        if type(exc_type) == types.ClassType:
+            nice = exc_type.__name__
+        else:
+            nice = str(exc_type)
+        value = str(exc_value)
+        if exc_value and value:
+            nice = nice + ": " + value
+        return nice
+
+    def forget(self):
+        self.stack = []
+        self.curindex = 0
+        self.curframe = None
+
+    def setup(self, f, t, isreturning = 0):
+        self.forget()
+        self.stack, self.curindex = self.get_stack(f, t)
+        self.curframe = self.stack[self.curindex - isreturning][0]
+
+    def interaction(self, frame, traceback, isreturning = 0):
+        saveport = Qd.GetPort()
+        self.w.select()
+        try:
+            self.setup(frame, traceback, isreturning)
+            self.setstate('stopped')
+            stackindex = self.curindex
+            if isreturning:
+                if frame.f_back is not self.botframe:
+                    stackindex = stackindex - 1
+            self.showstack(stackindex)
+            self.showframe(stackindex)
+            self.w.parent.debugger_mainloop()
+            self.forget()
+        finally:
+            Qd.SetPort(saveport)
+
+    # bdb customization
+
+    def trace_dispatch(self, frame, event, arg, TickCount = Evt.TickCount):
+        if TickCount() - self.tracingmonitortime > 15:
+            self.tracingmonitortime = TickCount()
+            self.w.panes.bottom.tracingmonitor.toggle()
+        try:
+            try:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(0)
+                if self.quitting:
+                    # returning None is not enough, a former BdbQuit exception
+                    # might have been eaten by the print statement
+                    raise bdb.BdbQuit
+                if event == 'line':
+                    return self.dispatch_line(frame)
+                if event == 'call':
+                    return self.dispatch_call(frame, arg)
+                if event == 'return':
+                    return self.dispatch_return(frame, arg)
+                if event == 'exception':
+                    return self.dispatch_exception(frame, arg)
+                print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
+                return self.trace_dispatch
+            finally:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(-1)
+        except KeyboardInterrupt:
+            self.set_step()
+            return self.trace_dispatch
+        except bdb.BdbQuit:
+            if self.continuewithoutdebugger:
+                self.clear_tracefuncs()
+                return
+            else:
+                raise bdb.BdbQuit
+        except:
+            print 'XXX Exception during debugger interaction.', \
+                            self.formatexception(sys.exc_type, sys.exc_value)
+            import traceback
+            traceback.print_exc()
+            return self.trace_dispatch
+
+    def dispatch_call(self, frame, arg):
+        if not self.tracemagic and \
+                        frame.f_code.co_name[:2] == '__' == frame.f_code.co_name[-2:] and \
+                        frame.f_code.co_name <> '__init__':
+            return
+        if self.botframe is None:
+            # First call of dispatch since reset()
+            self.botframe = frame.f_back    # xxx !!! added f_back
+            return self.trace_dispatch
+        if not (self.stop_here(frame) or self.break_anywhere(frame)):
+            # No need to trace this function
+            return # None
+        self.user_call(frame, arg)
+        if self.quitting:
+            raise bdb.BdbQuit
+        return self.trace_dispatch
+
+    def set_continue(self):
+        # Don't stop except at breakpoints or when finished
+        self.stopframe = self.botframe
+        self.returnframe = None
+        self.quitting = 0
+        # unlike in bdb/pdb, there's a chance that breakpoints change
+        # *while* a program (this program ;-) is running. It's actually quite likely.
+        # So we don't delete frame.f_trace until the bottom frame if there are no breakpoints.
+
+    def set_break(self, filename, lineno):
+        if not self.breaks.has_key(filename):
+            self.breaks[filename] = []
+        list = self.breaks[filename]
+        if lineno in list:
+            return 'There is already a breakpoint there!'
+        list.append(lineno)
+        list.sort()     # I want to keep them neatly sorted; easier for drawing
+        if hasattr(bdb, "Breakpoint"):
+            # 1.5.2b1 specific
+            bp = bdb.Breakpoint(filename, lineno, 0, None)
+        self.update_breaks(filename)
+
+    def clear_break(self, filename, lineno):
+        bdb.Bdb.clear_break(self, filename, lineno)
+        self.update_breaks(filename)
+
+    def clear_all_file_breaks(self, filename):
+        bdb.Bdb.clear_all_file_breaks(self, filename)
+        self.update_breaks(filename)
+
+    def clear_all_breaks(self):
+        bdb.Bdb.clear_all_breaks(self)
+        for editors in self.editors.values():
+            for editor in editors:
+                editor.drawbreakpoints()
+
+    # special
+
+    def toggle_break(self, filename, lineno):
+        if self.get_break(filename, lineno):
+            self.clear_break(filename, lineno)
+        else:
+            self.set_break(filename, lineno)
+
+    def clear_breaks_above(self, filename, above):
+        if not self.breaks.has_key(filename):
+            return 'There are no breakpoints in that file!'
+        for lineno in self.breaks[filename][:]:
+            if lineno > above:
+                self.breaks[filename].remove(lineno)
+        if not self.breaks[filename]:
+            del self.breaks[filename]
+
+    # editor stuff
+
+    def update_breaks(self, filename):
+        if self.breaksviewer:
+            self.breaksviewer.update()
+        if self.editors.has_key(filename):
+            for editor in self.editors[filename]:
+                if editor._debugger:    # XXX
+                    editor.drawbreakpoints()
+                else:
+                    print 'xxx dead editor!'
+
+    def update_allbreaks(self):
+        if self.breaksviewer:
+            self.breaksviewer.update()
+        for filename in self.breaks.keys():
+            if self.editors.has_key(filename):
+                for editor in self.editors[filename]:
+                    if editor._debugger:    # XXX
+                        editor.drawbreakpoints()
+                    else:
+                        print 'xxx dead editor!'
+
+    def register_editor(self, editor, filename):
+        if not filename:
+            return
+        if not self.editors.has_key(filename):
+            self.editors[filename] = [editor]
+        elif editor not in self.editors[filename]:
+            self.editors[filename].append(editor)
+
+    def unregister_editor(self, editor, filename):
+        if not filename:
+            return
+        try:
+            self.editors[filename].remove(editor)
+            if not self.editors[filename]:
+                del self.editors[filename]
+                # if this was an untitled window, clear the breaks.
+                if filename[:1] == '<' and filename[-1:] == '>' and \
+                                self.breaks.has_key(filename):
+                    self.clear_all_file_breaks(filename)
+        except (KeyError, ValueError):
+            pass
+
 
 class SourceViewer(W.PyEditor):
-	
-	def __init__(self, *args, **kwargs):
-		apply(W.PyEditor.__init__, (self,) + args, kwargs)
-		self.bind('<click>', self.clickintercept)
-	
-	def clickintercept(self, point, modifiers):
-		if self._parentwindow._currentwidget <> self and not self.pt_in_breaks(point):
-			self._parentwindow.xxx___select(self)
-			return 1
-	
-	def _getviewrect(self):
-		l, t, r, b = self._bounds
-		if self._debugger:
-			return (l + 12, t + 2, r - 1, b - 2)
-		else:
-			return (l + 5, t + 2, r - 1, b - 2)
-	
-	def select(self, onoff, isclick = 0):
-		if W.SelectableWidget.select(self, onoff):
-			return
-		self.SetPort()
-		#if onoff:
-		#	self.ted.WEActivate()
-		#else:
-		#	self.ted.WEDeactivate()
-		self.drawselframe(onoff)
-	
-	def drawselframe(self, onoff):
-		pass
+
+    def __init__(self, *args, **kwargs):
+        apply(W.PyEditor.__init__, (self,) + args, kwargs)
+        self.bind('<click>', self.clickintercept)
+
+    def clickintercept(self, point, modifiers):
+        if self._parentwindow._currentwidget <> self and not self.pt_in_breaks(point):
+            self._parentwindow.xxx___select(self)
+            return 1
+
+    def _getviewrect(self):
+        l, t, r, b = self._bounds
+        if self._debugger:
+            return (l + 12, t + 2, r - 1, b - 2)
+        else:
+            return (l + 5, t + 2, r - 1, b - 2)
+
+    def select(self, onoff, isclick = 0):
+        if W.SelectableWidget.select(self, onoff):
+            return
+        self.SetPort()
+        #if onoff:
+        #       self.ted.WEActivate()
+        #else:
+        #       self.ted.WEDeactivate()
+        self.drawselframe(onoff)
+
+    def drawselframe(self, onoff):
+        pass
 
 
 class BreakpointsViewer:
-	
-	def __init__(self, debugger):
-		self.debugger = debugger
-		self.w = W.Window((300, 250), 'Breakpoints', minsize = (200, 200))
-		self.w.panes = W.HorizontalPanes((8, 8, -8, -32), (0.3, 0.7))
-		self.w.panes.files = W.List(None, callback = self.filehit)		#, flags = Lists.lOnlyOne)
-		self.w.panes.gr = W.Group(None)
-		self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit)	#, flags = Lists.lOnlyOne)
-		self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit)
-		self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit)
-		
-		self.w.bind('<close>', self.close)
-		self.w.bind('backspace', self.w.panes.gr.deletebutton.push)
-		
-		self.setup()
-		self.w.open()
-		self.w.panes.gr.openbutton.enable(0)
-		self.w.panes.gr.deletebutton.enable(0)
-		self.curfile = None
-	
-	def deletebuttonhit(self):
-		if self.w._currentwidget == self.w.panes.files:
-			self.del_filename()
-		else:
-			self.del_number()
-		self.checkbuttons()
-	
-	def del_number(self):
-		if self.curfile is None:
-			return
-		sel = self.w.panes.gr.breaks.getselectedobjects()
-		for lineno in sel:
-			self.debugger.clear_break(self.curfile, lineno)
-	
-	def del_filename(self):
-		sel = self.w.panes.files.getselectedobjects()
-		for filename in sel:
-			self.debugger.clear_all_file_breaks(filename)
-		self.debugger.update_allbreaks()
-	
-	def setup(self):
-		files = self.debugger.breaks.keys()
-		files.sort()
-		self.w.panes.files.set(files)
-	
-	def close(self):
-		self.debugger.breaksviewer = None
-		self.debugger = None
-	
-	def update(self):
-		sel = self.w.panes.files.getselectedobjects()
-		self.setup()
-		self.w.panes.files.setselectedobjects(sel)
-		sel = self.w.panes.files.getselection()
-		if len(sel) == 0 and self.curfile:
-			self.w.panes.files.setselectedobjects([self.curfile])
-		self.filehit(0)
-	
-	def select(self):
-		self.w.select()
-	
-	def selectfile(self, file):
-		self.w.panes.files.setselectedobjects([file])
-		self.filehit(0)			
-	
-	def openbuttonhit(self):
-		self.filehit(1)
-	
-	def filehit(self, isdbl):
-		sel = self.w.panes.files.getselectedobjects()
-		if isdbl:
-			for filename in sel:
-				lineno = None
-				if filename == self.curfile:
-					linesel = self.w.panes.gr.breaks.getselectedobjects()
-					if linesel:
-						lineno = linesel[-1]
-					elif self.w.panes.gr.breaks:
-						lineno = self.w.panes.gr.breaks[0]
-				editor = self.w._parentwindow.parent.openscript(filename, lineno)
-				editor.showbreakpoints(1)
-			return
-		if len(sel) == 1:
-			file = sel[0]
-			filebreaks = self.debugger.breaks[file][:]
-			if self.curfile == file:
-				linesel = self.w.panes.gr.breaks.getselectedobjects()
-			self.w.panes.gr.breaks.set(filebreaks)
-			if self.curfile == file:
-				self.w.panes.gr.breaks.setselectedobjects(linesel)
-			self.curfile = file
-		else:
-			if len(sel) <> 0:
-				self.curfile = None
-			self.w.panes.gr.breaks.set([])
-		self.checkbuttons()
-	
-	def linehit(self, isdbl):
-		if isdbl:
-			files = self.w.panes.files.getselectedobjects()
-			if len(files) <> 1:
-				return
-			filename = files[0]
-			linenos = self.w.panes.gr.breaks.getselectedobjects()
-			if not linenos:
-				return
-			lineno = linenos[-1]
-			editor = self.w._parentwindow.parent.openscript(filename, lineno)
-			editor.showbreakpoints(1)
-		self.checkbuttons()
-	
-	def checkbuttons(self):
-		if self.w.panes.files.getselection():
-			self.w.panes.gr.openbutton.enable(1)
-			self.w._parentwindow.setdefaultbutton(self.w.panes.gr.openbutton)
-			if self.w._currentwidget == self.w.panes.files:
-				if self.w.panes.files.getselection():
-					self.w.panes.gr.deletebutton.enable(1)
-				else:
-					self.w.panes.gr.deletebutton.enable(0)
-			else:
-				if self.w.panes.gr.breaks.getselection():
-					self.w.panes.gr.deletebutton.enable(1)
-				else:
-					self.w.panes.gr.deletebutton.enable(0)
-		else:
-			self.w.panes.gr.openbutton.enable(0)
-			self.w.panes.gr.deletebutton.enable(0)
+
+    def __init__(self, debugger):
+        self.debugger = debugger
+        self.w = W.Window((300, 250), 'Breakpoints', minsize = (200, 200))
+        self.w.panes = W.HorizontalPanes((8, 8, -8, -32), (0.3, 0.7))
+        self.w.panes.files = W.List(None, callback = self.filehit)              #, flags = Lists.lOnlyOne)
+        self.w.panes.gr = W.Group(None)
+        self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit)       #, flags = Lists.lOnlyOne)
+        self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit)
+        self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit)
+
+        self.w.bind('<close>', self.close)
+        self.w.bind('backspace', self.w.panes.gr.deletebutton.push)
+
+        self.setup()
+        self.w.open()
+        self.w.panes.gr.openbutton.enable(0)
+        self.w.panes.gr.deletebutton.enable(0)
+        self.curfile = None
+
+    def deletebuttonhit(self):
+        if self.w._currentwidget == self.w.panes.files:
+            self.del_filename()
+        else:
+            self.del_number()
+        self.checkbuttons()
+
+    def del_number(self):
+        if self.curfile is None:
+            return
+        sel = self.w.panes.gr.breaks.getselectedobjects()
+        for lineno in sel:
+            self.debugger.clear_break(self.curfile, lineno)
+
+    def del_filename(self):
+        sel = self.w.panes.files.getselectedobjects()
+        for filename in sel:
+            self.debugger.clear_all_file_breaks(filename)
+        self.debugger.update_allbreaks()
+
+    def setup(self):
+        files = self.debugger.breaks.keys()
+        files.sort()
+        self.w.panes.files.set(files)
+
+    def close(self):
+        self.debugger.breaksviewer = None
+        self.debugger = None
+
+    def update(self):
+        sel = self.w.panes.files.getselectedobjects()
+        self.setup()
+        self.w.panes.files.setselectedobjects(sel)
+        sel = self.w.panes.files.getselection()
+        if len(sel) == 0 and self.curfile:
+            self.w.panes.files.setselectedobjects([self.curfile])
+        self.filehit(0)
+
+    def select(self):
+        self.w.select()
+
+    def selectfile(self, file):
+        self.w.panes.files.setselectedobjects([file])
+        self.filehit(0)
+
+    def openbuttonhit(self):
+        self.filehit(1)
+
+    def filehit(self, isdbl):
+        sel = self.w.panes.files.getselectedobjects()
+        if isdbl:
+            for filename in sel:
+                lineno = None
+                if filename == self.curfile:
+                    linesel = self.w.panes.gr.breaks.getselectedobjects()
+                    if linesel:
+                        lineno = linesel[-1]
+                    elif self.w.panes.gr.breaks:
+                        lineno = self.w.panes.gr.breaks[0]
+                editor = self.w._parentwindow.parent.openscript(filename, lineno)
+                editor.showbreakpoints(1)
+            return
+        if len(sel) == 1:
+            file = sel[0]
+            filebreaks = self.debugger.breaks[file][:]
+            if self.curfile == file:
+                linesel = self.w.panes.gr.breaks.getselectedobjects()
+            self.w.panes.gr.breaks.set(filebreaks)
+            if self.curfile == file:
+                self.w.panes.gr.breaks.setselectedobjects(linesel)
+            self.curfile = file
+        else:
+            if len(sel) <> 0:
+                self.curfile = None
+            self.w.panes.gr.breaks.set([])
+        self.checkbuttons()
+
+    def linehit(self, isdbl):
+        if isdbl:
+            files = self.w.panes.files.getselectedobjects()
+            if len(files) <> 1:
+                return
+            filename = files[0]
+            linenos = self.w.panes.gr.breaks.getselectedobjects()
+            if not linenos:
+                return
+            lineno = linenos[-1]
+            editor = self.w._parentwindow.parent.openscript(filename, lineno)
+            editor.showbreakpoints(1)
+        self.checkbuttons()
+
+    def checkbuttons(self):
+        if self.w.panes.files.getselection():
+            self.w.panes.gr.openbutton.enable(1)
+            self.w._parentwindow.setdefaultbutton(self.w.panes.gr.openbutton)
+            if self.w._currentwidget == self.w.panes.files:
+                if self.w.panes.files.getselection():
+                    self.w.panes.gr.deletebutton.enable(1)
+                else:
+                    self.w.panes.gr.deletebutton.enable(0)
+            else:
+                if self.w.panes.gr.breaks.getselection():
+                    self.w.panes.gr.deletebutton.enable(1)
+                else:
+                    self.w.panes.gr.deletebutton.enable(0)
+        else:
+            self.w.panes.gr.openbutton.enable(0)
+            self.w.panes.gr.deletebutton.enable(0)
 
 
 class TracingMonitor(W.Widget):
-	
-	def __init__(self, *args, **kwargs):
-		apply(W.Widget.__init__, (self,) + args, kwargs)
-		self.state = 0
-	
-	def toggle(self):
-		if hasattr(self, "_parentwindow") and self._parentwindow is not None:
-			self.state = self.state % 2 + 1
-			port = Qd.GetPort()
-			self.SetPort()
-			self.draw()
-			Qd.SetPort(port)
-	
-	def reset(self):
-		if self._parentwindow:
-			self.state = 0
-			port = Qd.GetPort()
-			self.SetPort()
-			self.draw()
-			Qd.SetPort(port)
-	
-	def draw(self, visRgn = None):
-		if self.state == 2:
-			Qd.PaintOval(self._bounds)
-		else:
-			Qd.EraseOval(self._bounds)
+
+    def __init__(self, *args, **kwargs):
+        apply(W.Widget.__init__, (self,) + args, kwargs)
+        self.state = 0
+
+    def toggle(self):
+        if hasattr(self, "_parentwindow") and self._parentwindow is not None:
+            self.state = self.state % 2 + 1
+            port = Qd.GetPort()
+            self.SetPort()
+            self.draw()
+            Qd.SetPort(port)
+
+    def reset(self):
+        if self._parentwindow:
+            self.state = 0
+            port = Qd.GetPort()
+            self.SetPort()
+            self.draw()
+            Qd.SetPort(port)
+
+    def draw(self, visRgn = None):
+        if self.state == 2:
+            Qd.PaintOval(self._bounds)
+        else:
+            Qd.EraseOval(self._bounds)
 
 
 # convenience funcs
 
 def postmortem(exc_type, exc_value, tb):
-	d = getdebugger()
-	d.postmortem(exc_type, exc_value, tb)
+    d = getdebugger()
+    d.postmortem(exc_type, exc_value, tb)
 
 def start(bottomframe = None):
-	d = getdebugger()
-	d.start(bottomframe)
+    d = getdebugger()
+    d.start(bottomframe)
 
 def startfromhere():
-	d = getdebugger()
-	try:
-		raise 'spam'
-	except:
-		frame = sys.exc_traceback.tb_frame.f_back
-	d.start(frame)
+    d = getdebugger()
+    try:
+        raise 'spam'
+    except:
+        frame = sys.exc_traceback.tb_frame.f_back
+    d.start(frame)
 
 def startfrombottom():
-	d = getdebugger()
-	d.start(_getbottomframe(), 1)
+    d = getdebugger()
+    d.start(_getbottomframe(), 1)
 
 def stop():
-	d = getdebugger()
-	d.stop()
+    d = getdebugger()
+    d.stop()
 
 def cont():
-	sys.settrace(None)
-	d = getdebugger()
-	d.set_continue_without_debugger()
+    sys.settrace(None)
+    d = getdebugger()
+    d.set_continue_without_debugger()
 
 def _getbottomframe():
-	try:
-		raise 'spam'
-	except:
-		pass
-	frame = sys.exc_traceback.tb_frame
-	while 1:
-		if frame.f_code.co_name == 'mainloop' or frame.f_back is None:
-			break
-		frame = frame.f_back
-	return frame
+    try:
+        raise 'spam'
+    except:
+        pass
+    frame = sys.exc_traceback.tb_frame
+    while 1:
+        if frame.f_code.co_name == 'mainloop' or frame.f_back is None:
+            break
+        frame = frame.f_back
+    return frame
 
 _debugger = None
 
 def getdebugger():
-	if not __debug__:
-		raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)"
-	global _debugger
-	if _debugger is None:
-		_debugger = Debugger()
-	return _debugger
+    if not __debug__:
+        raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)"
+    global _debugger
+    if _debugger is None:
+        _debugger = Debugger()
+    return _debugger
diff --git a/Mac/Tools/IDE/PyDocSearch.py b/Mac/Tools/IDE/PyDocSearch.py
index 1abd4cd..ec666b6 100644
--- a/Mac/Tools/IDE/PyDocSearch.py
+++ b/Mac/Tools/IDE/PyDocSearch.py
@@ -13,244 +13,244 @@
 _titlepat = re.compile('<title>\([^<]*\)</title>')
 
 def sucktitle(path):
-	f = open(path)
-	text = f.read(1024) # assume the title is in the first 1024 bytes
-	f.close()
-	lowertext = text.lower()
-	matcher = _titlepat.search(lowertext)
-	if matcher:
-		return matcher.group(1)
-	return path
+    f = open(path)
+    text = f.read(1024) # assume the title is in the first 1024 bytes
+    f.close()
+    lowertext = text.lower()
+    matcher = _titlepat.search(lowertext)
+    if matcher:
+        return matcher.group(1)
+    return path
 
 def verifydocpath(docpath):
-	try:
-		tut = os.path.join(docpath, "tut")
-		lib = os.path.join(docpath, "lib")
-		ref = os.path.join(docpath, "ref")
-		for path in [tut, lib, ref]:
-			if not os.path.exists(path):
-				return 0
-	except:
-		return 0
-	return 1
+    try:
+        tut = os.path.join(docpath, "tut")
+        lib = os.path.join(docpath, "lib")
+        ref = os.path.join(docpath, "ref")
+        for path in [tut, lib, ref]:
+            if not os.path.exists(path):
+                return 0
+    except:
+        return 0
+    return 1
 
 
 _resultscounter = 1
 
 class Results:
-	
-	def __init__(self, hits):
-		global _resultscounter
-		hits = map(lambda (path, hits): (sucktitle(path), path, hits), hits)
-		hits.sort()
-		self.hits = hits
-		nicehits = map(
-				lambda (title, path, hits):
-				title + '\r' + string.join(
-				map(lambda (c, p): "%s (%d)" % (p, c), hits), ', '), hits)
-		nicehits.sort()
-		self.w = W.Window((440, 300), "Search results %d" % _resultscounter, minsize = (200, 100))
-		self.w.results = W.TwoLineList((-1, -1, 1, -14), nicehits, self.listhit)
-		self.w.open()
-		self.w.bind('return', self.listhit)
-		self.w.bind('enter', self.listhit)
-		_resultscounter = _resultscounter + 1
-	
-	def listhit(self, isdbl = 1):
-		if isdbl:
-			for i in self.w.results.getselection():
-				path = self.hits[i][1]
-				url = "file://" + "/".join(path.split(":"))
-				webbrowser.open(url)
+
+    def __init__(self, hits):
+        global _resultscounter
+        hits = map(lambda (path, hits): (sucktitle(path), path, hits), hits)
+        hits.sort()
+        self.hits = hits
+        nicehits = map(
+                        lambda (title, path, hits):
+                        title + '\r' + string.join(
+                        map(lambda (c, p): "%s (%d)" % (p, c), hits), ', '), hits)
+        nicehits.sort()
+        self.w = W.Window((440, 300), "Search results %d" % _resultscounter, minsize = (200, 100))
+        self.w.results = W.TwoLineList((-1, -1, 1, -14), nicehits, self.listhit)
+        self.w.open()
+        self.w.bind('return', self.listhit)
+        self.w.bind('enter', self.listhit)
+        _resultscounter = _resultscounter + 1
+
+    def listhit(self, isdbl = 1):
+        if isdbl:
+            for i in self.w.results.getselection():
+                path = self.hits[i][1]
+                url = "file://" + "/".join(path.split(":"))
+                webbrowser.open(url)
 
 
 class Status:
-	
-	def __init__(self):
-		self.w = W.Dialog((440, 64), "Searching\xc9")
-		self.w.searching = W.TextBox((4, 4, -4, 16), "")
-		self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0")
-		self.w.canceltip = W.TextBox((4, 44, -4, 16), "Type cmd-period (.) to cancel.")
-		self.w.open()
-	
-	def set(self, path, hits):
-		self.w.searching.set(path)
-		self.w.hits.set('Hits: %r' % (hits,))
-		app.breathe()
-	
-	def close(self):
-		self.w.close()
+
+    def __init__(self):
+        self.w = W.Dialog((440, 64), "Searching\xc9")
+        self.w.searching = W.TextBox((4, 4, -4, 16), "")
+        self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0")
+        self.w.canceltip = W.TextBox((4, 44, -4, 16), "Type cmd-period (.) to cancel.")
+        self.w.open()
+
+    def set(self, path, hits):
+        self.w.searching.set(path)
+        self.w.hits.set('Hits: %r' % (hits,))
+        app.breathe()
+
+    def close(self):
+        self.w.close()
 
 
 def match(text, patterns, all):
-	hits = []
-	hitsappend = hits.append
-	stringcount = string.count
-	for pat in patterns:
-		c = stringcount(text, pat)
-		if c > 0:
-			hitsappend((c, pat))
-		elif all:
-			hits[:] = []
-			break
-	hits.sort()
-	hits.reverse()
-	return hits
+    hits = []
+    hitsappend = hits.append
+    stringcount = string.count
+    for pat in patterns:
+        c = stringcount(text, pat)
+        if c > 0:
+            hitsappend((c, pat))
+        elif all:
+            hits[:] = []
+            break
+    hits.sort()
+    hits.reverse()
+    return hits
 
 
 def dosearch(docpath, searchstring, settings):
-	(docpath, kind, case, word, tut, lib, ref, ext, api) = settings
-	books = [(tut, 'tut'), (lib, 'lib'), (ref, 'ref'), (ext, 'ext'), (api, 'api')]
-	if not case:
-		searchstring = string.lower(searchstring)
-	
-	if kind == 1:
-		patterns = string.split(searchstring)
-		all = 1
-	elif kind == 2:
-		patterns = string.split(searchstring)
-		all = 0
-	else:
-		patterns = [searchstring]
-		all = 0 # not relevant
-	
-	ospathjoin = os.path.join
-	stringlower = string.lower
-	status = Status()
-	statusset = status.set
-	_match = match
-	_open = open
-	hits = {}
-	try:
-		if hasattr(MacOS, 'EnableAppswitch'):
-			MacOS.EnableAppswitch(0)
-		try:
-			for do, name in books:
-				if not do:
-					continue
-				bookpath = ospathjoin(docpath, name)
-				if not os.path.exists(bookpath):
-					continue
-				files = os.listdir(bookpath)
-				for file in files:
-					fullpath = ospathjoin(bookpath, file)
-					if fullpath[-5:] <> '.html':
-						continue
-					statusset(fullpath, len(hits))
-					f = _open(fullpath)
-					text = f.read()
-					if not case:
-						text = stringlower(text)
-					f.close()
-					filehits = _match(text, patterns, all)
-					if filehits:
-						hits[fullpath] = filehits
-		finally:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(-1)
-			status.close()
-	except KeyboardInterrupt:
-		pass
-	hits = hits.items()
-	hits.sort()
-	return hits
+    (docpath, kind, case, word, tut, lib, ref, ext, api) = settings
+    books = [(tut, 'tut'), (lib, 'lib'), (ref, 'ref'), (ext, 'ext'), (api, 'api')]
+    if not case:
+        searchstring = string.lower(searchstring)
+
+    if kind == 1:
+        patterns = string.split(searchstring)
+        all = 1
+    elif kind == 2:
+        patterns = string.split(searchstring)
+        all = 0
+    else:
+        patterns = [searchstring]
+        all = 0 # not relevant
+
+    ospathjoin = os.path.join
+    stringlower = string.lower
+    status = Status()
+    statusset = status.set
+    _match = match
+    _open = open
+    hits = {}
+    try:
+        if hasattr(MacOS, 'EnableAppswitch'):
+            MacOS.EnableAppswitch(0)
+        try:
+            for do, name in books:
+                if not do:
+                    continue
+                bookpath = ospathjoin(docpath, name)
+                if not os.path.exists(bookpath):
+                    continue
+                files = os.listdir(bookpath)
+                for file in files:
+                    fullpath = ospathjoin(bookpath, file)
+                    if fullpath[-5:] <> '.html':
+                        continue
+                    statusset(fullpath, len(hits))
+                    f = _open(fullpath)
+                    text = f.read()
+                    if not case:
+                        text = stringlower(text)
+                    f.close()
+                    filehits = _match(text, patterns, all)
+                    if filehits:
+                        hits[fullpath] = filehits
+        finally:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(-1)
+            status.close()
+    except KeyboardInterrupt:
+        pass
+    hits = hits.items()
+    hits.sort()
+    return hits
 
 
 class PyDocSearch:
-	
-	def __init__(self):
-		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-		try:
-			(docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine
-		except:
-			(docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine = \
-				("", 0, 0, 0, 1, 1, 0, 0, 0)
-		
-		if docpath and not verifydocpath(docpath):
-			docpath = ""
-		
-		self.w = W.Window((400, 200), "Search the Python Documentation")
-		self.w.searchtext = W.EditText((10, 10, -100, 20), callback = self.checkbuttons)
-		self.w.searchbutton = W.Button((-90, 12, 80, 16), "Search", self.search)
-		buttons = []
-		
-		gutter = 10
-		width = 130
-		bookstart = width + 2 * gutter
-		self.w.phraseradio = W.RadioButton((10, 38, width, 16), "As a phrase", buttons)
-		self.w.allwordsradio = W.RadioButton((10, 58, width, 16), "All words", buttons)
-		self.w.anywordsradio = W.RadioButton((10, 78, width, 16), "Any word", buttons)
-		self.w.casesens = W.CheckBox((10, 98, width, 16), "Case sensitive")
-		self.w.wholewords = W.CheckBox((10, 118, width, 16), "Whole words")
-		self.w.tutorial = W.CheckBox((bookstart, 38, -10, 16), "Tutorial")
-		self.w.library = W.CheckBox((bookstart, 58, -10, 16), "Library reference")
-		self.w.langueref = W.CheckBox((bookstart, 78, -10, 16), "Lanuage reference manual")
-		self.w.extending = W.CheckBox((bookstart, 98, -10, 16), "Extending & embedding")
-		self.w.api = W.CheckBox((bookstart, 118, -10, 16), "C/C++ API")
-		
-		self.w.setdocfolderbutton = W.Button((10, -30, 100, 16), "Set doc folder", self.setdocpath)
-		
-		if docpath:
-			self.w.setdefaultbutton(self.w.searchbutton)
-		else:
-			self.w.setdefaultbutton(self.w.setdocfolderbutton)
-		
-		self.docpath = docpath
-		if not docpath:
-			docpath = "(please select the Python html documentation folder)"
-		self.w.docfolder = W.TextBox((120, -28, -10, 16), docpath)
-		
-		[self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio][kind].set(1)
-		
-		self.w.casesens.set(case)
-		self.w.wholewords.set(word)
-		self.w.tutorial.set(tut)
-		self.w.library.set(lib)
-		self.w.langueref.set(ref)
-		self.w.extending.set(ext)
-		self.w.api.set(api)
-		
-		self.w.open()
-		self.w.wholewords.enable(0)
-		self.w.bind('<close>', self.close)
-		self.w.searchbutton.enable(0)
-	
-	def search(self):
-		hits = dosearch(self.docpath, self.w.searchtext.get(), self.getsettings())
-		if hits:
-			Results(hits)
-		elif hasattr(MacOS, 'SysBeep'):
-			MacOS.SysBeep(0)
-	
-	def setdocpath(self):
-		docpath = EasyDialogs.AskFolder()
-		if docpath:
-			if not verifydocpath(docpath):
-				W.Message("This does not seem to be a Python documentation folder...")
-			else:
-				self.docpath = docpath
-				self.w.docfolder.set(docpath)
-				self.w.setdefaultbutton(self.w.searchbutton)
-	
-	def close(self):
-		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-		prefs.docsearchengine = self.getsettings()
-	
-	def getsettings(self):
-		radiobuttons = [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio]
-		for i in range(3):
-			if radiobuttons[i].get():
-				kind = i
-				break
-		docpath = self.docpath
-		case = self.w.casesens.get()
-		word = self.w.wholewords.get()
-		tut = self.w.tutorial.get()
-		lib = self.w.library.get()
-		ref = self.w.langueref.get()
-		ext = self.w.extending.get()
-		api = self.w.api.get()
-		return (docpath, kind, case, word, tut, lib, ref, ext, api)
-	
-	def checkbuttons(self):
-		self.w.searchbutton.enable(not not self.w.searchtext.get())
+
+    def __init__(self):
+        prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+        try:
+            (docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine
+        except:
+            (docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine = \
+                    ("", 0, 0, 0, 1, 1, 0, 0, 0)
+
+        if docpath and not verifydocpath(docpath):
+            docpath = ""
+
+        self.w = W.Window((400, 200), "Search the Python Documentation")
+        self.w.searchtext = W.EditText((10, 10, -100, 20), callback = self.checkbuttons)
+        self.w.searchbutton = W.Button((-90, 12, 80, 16), "Search", self.search)
+        buttons = []
+
+        gutter = 10
+        width = 130
+        bookstart = width + 2 * gutter
+        self.w.phraseradio = W.RadioButton((10, 38, width, 16), "As a phrase", buttons)
+        self.w.allwordsradio = W.RadioButton((10, 58, width, 16), "All words", buttons)
+        self.w.anywordsradio = W.RadioButton((10, 78, width, 16), "Any word", buttons)
+        self.w.casesens = W.CheckBox((10, 98, width, 16), "Case sensitive")
+        self.w.wholewords = W.CheckBox((10, 118, width, 16), "Whole words")
+        self.w.tutorial = W.CheckBox((bookstart, 38, -10, 16), "Tutorial")
+        self.w.library = W.CheckBox((bookstart, 58, -10, 16), "Library reference")
+        self.w.langueref = W.CheckBox((bookstart, 78, -10, 16), "Lanuage reference manual")
+        self.w.extending = W.CheckBox((bookstart, 98, -10, 16), "Extending & embedding")
+        self.w.api = W.CheckBox((bookstart, 118, -10, 16), "C/C++ API")
+
+        self.w.setdocfolderbutton = W.Button((10, -30, 100, 16), "Set doc folder", self.setdocpath)
+
+        if docpath:
+            self.w.setdefaultbutton(self.w.searchbutton)
+        else:
+            self.w.setdefaultbutton(self.w.setdocfolderbutton)
+
+        self.docpath = docpath
+        if not docpath:
+            docpath = "(please select the Python html documentation folder)"
+        self.w.docfolder = W.TextBox((120, -28, -10, 16), docpath)
+
+        [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio][kind].set(1)
+
+        self.w.casesens.set(case)
+        self.w.wholewords.set(word)
+        self.w.tutorial.set(tut)
+        self.w.library.set(lib)
+        self.w.langueref.set(ref)
+        self.w.extending.set(ext)
+        self.w.api.set(api)
+
+        self.w.open()
+        self.w.wholewords.enable(0)
+        self.w.bind('<close>', self.close)
+        self.w.searchbutton.enable(0)
+
+    def search(self):
+        hits = dosearch(self.docpath, self.w.searchtext.get(), self.getsettings())
+        if hits:
+            Results(hits)
+        elif hasattr(MacOS, 'SysBeep'):
+            MacOS.SysBeep(0)
+
+    def setdocpath(self):
+        docpath = EasyDialogs.AskFolder()
+        if docpath:
+            if not verifydocpath(docpath):
+                W.Message("This does not seem to be a Python documentation folder...")
+            else:
+                self.docpath = docpath
+                self.w.docfolder.set(docpath)
+                self.w.setdefaultbutton(self.w.searchbutton)
+
+    def close(self):
+        prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+        prefs.docsearchengine = self.getsettings()
+
+    def getsettings(self):
+        radiobuttons = [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio]
+        for i in range(3):
+            if radiobuttons[i].get():
+                kind = i
+                break
+        docpath = self.docpath
+        case = self.w.casesens.get()
+        word = self.w.wholewords.get()
+        tut = self.w.tutorial.get()
+        lib = self.w.library.get()
+        ref = self.w.langueref.get()
+        ext = self.w.extending.get()
+        api = self.w.api.get()
+        return (docpath, kind, case, word, tut, lib, ref, ext, api)
+
+    def checkbuttons(self):
+        self.w.searchbutton.enable(not not self.w.searchtext.get())
diff --git a/Mac/Tools/IDE/PyEdit.py b/Mac/Tools/IDE/PyEdit.py
index ce228ff..88c72ac 100644
--- a/Mac/Tools/IDE/PyEdit.py
+++ b/Mac/Tools/IDE/PyEdit.py
@@ -21,9 +21,9 @@
 smAllScripts = -3
 
 if hasattr(Win, "FrontNonFloatingWindow"):
-	MyFrontWindow = Win.FrontNonFloatingWindow
+    MyFrontWindow = Win.FrontNonFloatingWindow
 else:
-	MyFrontWindow = Win.FrontWindow
+    MyFrontWindow = Win.FrontWindow
 
 
 _scriptuntitledcounter = 1
@@ -35,1328 +35,1328 @@
 
 
 class Editor(W.Window):
-	
-	def __init__(self, path = "", title = ""):
-		defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
-		global _scriptuntitledcounter
-		if not path:
-			if title:
-				self.title = title
-			else:
-				self.title = "Untitled Script %r" % (_scriptuntitledcounter,)
-				_scriptuntitledcounter = _scriptuntitledcounter + 1
-			text = ""
-			self._creator = W._signature
-			self._eoln = os.linesep
-		elif os.path.exists(path):
-			path = resolvealiases(path)
-			dir, name = os.path.split(path)
-			self.title = name
-			f = open(path, "rb")
-			text = f.read()
-			f.close()
-			self._creator, filetype = MacOS.GetCreatorAndType(path)
-			self.addrecentfile(path)
-			if '\n' in text:
-				if string.find(text, '\r\n') >= 0:
-					self._eoln = '\r\n'
-				else:
-					self._eoln = '\n'
-				text = string.replace(text, self._eoln, '\r')
-			else:
-				self._eoln = '\r'
-		else:
-			raise IOError, "file '%s' does not exist" % path
-		self.path = path
-		
-		self.settings = {}
-		if self.path:
-			self.readwindowsettings()
-		if self.settings.has_key("windowbounds"):
-			bounds = self.settings["windowbounds"]
-		else:
-			bounds = defaultwindowsize
-		if self.settings.has_key("fontsettings"):
-			self.fontsettings = self.settings["fontsettings"]
-		else:
-			self.fontsettings = defaultfontsettings
-		if self.settings.has_key("tabsize"):
-			try:
-				self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
-			except:
-				self.tabsettings = defaulttabsettings
-		else:
-			self.tabsettings = defaulttabsettings
-		
-		W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
-		self.setupwidgets(text)
-		
-		if self.settings.has_key("selection"):
-			selstart, selend = self.settings["selection"]
-			self.setselection(selstart, selend)
-		self.open()
-		self.setinfotext()
-		self.globals = {}
-		self._buf = ""  # for write method
-		self.debugging = 0
-		self.profiling = 0
-		self.run_as_main = self.settings.get("run_as_main", 0)
-		self.run_with_interpreter = self.settings.get("run_with_interpreter", 0)
-		self.run_with_cl_interpreter = self.settings.get("run_with_cl_interpreter", 0)
-	
-	def readwindowsettings(self):
-		try:
-			resref = Res.FSpOpenResFile(self.path, 1)
-		except Res.Error:
-			return
-		try:
-			Res.UseResFile(resref)
-			data = Res.Get1Resource('PyWS', 128)
-			self.settings = marshal.loads(data.data)
-		except:
-			pass
-		Res.CloseResFile(resref)
-		
-	def writewindowsettings(self):
-		try:
-			resref = Res.FSpOpenResFile(self.path, 3)
-		except Res.Error:
-			Res.FSpCreateResFile(self.path, self._creator, 'TEXT', smAllScripts)
-			resref = Res.FSpOpenResFile(self.path, 3)
-		try:
-			data = Res.Resource(marshal.dumps(self.settings))
-			Res.UseResFile(resref)
-			try:
-				temp = Res.Get1Resource('PyWS', 128)
-				temp.RemoveResource()
-			except Res.Error:
-				pass
-			data.AddResource('PyWS', 128, "window settings")
-		finally:
-			Res.UpdateResFile(resref)
-			Res.CloseResFile(resref)
-	
-	def getsettings(self):
-		self.settings = {}
-		self.settings["windowbounds"] = self.getbounds()
-		self.settings["selection"] = self.getselection()
-		self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
-		self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
-		self.settings["run_as_main"] = self.run_as_main
-		self.settings["run_with_interpreter"] = self.run_with_interpreter
-		self.settings["run_with_cl_interpreter"] = self.run_with_cl_interpreter
-	
-	def get(self):
-		return self.editgroup.editor.get()
-	
-	def getselection(self):
-		return self.editgroup.editor.ted.WEGetSelection()
-	
-	def setselection(self, selstart, selend):
-		self.editgroup.editor.setselection(selstart, selend)
-		
-	def getselectedtext(self):
-		return self.editgroup.editor.getselectedtext()
-	
-	def getfilename(self):
-		if self.path:
-			return self.path
-		return '<%s>' % self.title
-	
-	def setupwidgets(self, text):
-		topbarheight = 24
-		popfieldwidth = 80
-		self.lastlineno = None
-		
-		# make an editor
-		self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
-		editor = W.PyEditor((0, 0, -15,-15), text, 
-				fontsettings = self.fontsettings, 
-				tabsettings = self.tabsettings,
-				file = self.getfilename())
-		
-		# make the widgets
-		self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
-		self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
-		self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
-		self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
-		self.editgroup.editor = editor	# add editor *after* scrollbars
-		
-		self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
-		self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
-		
-		self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
-		self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
-		self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
-		self.runbutton = W.BevelButton((6, 4, 80, 16), runButtonLabels[0], self.run)
-		self.runselbutton = W.BevelButton((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
-		
-		# bind some keys
-		editor.bind("cmdr", self.runbutton.push)
-		editor.bind("enter", self.runselbutton.push)
-		editor.bind("cmdj", self.domenu_gotoline)
-		editor.bind("cmdd", self.domenu_toggledebugger)
-		editor.bind("<idle>", self.updateselection)
-		
-		editor.bind("cmde", searchengine.setfindstring)
-		editor.bind("cmdf", searchengine.show)
-		editor.bind("cmdg", searchengine.findnext)
-		editor.bind("cmdshiftr", searchengine.replace)
-		editor.bind("cmdt", searchengine.replacefind)
-		
-		self.linefield.bind("return", self.dolinefield)
-		self.linefield.bind("enter", self.dolinefield)
-		self.linefield.bind("tab", self.dolinefield)
-		
-		# intercept clicks
-		editor.bind("<click>", self.clickeditor)
-		self.linefield.bind("<click>", self.clicklinefield)
-	
-	def makeoptionsmenu(self):
-		menuitems = [('Font settings\xc9', self.domenu_fontsettings), 
-				("Save options\xc9", self.domenu_options),
-				'-',
-				('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main), 
-				#('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_dtoggle_run_with_interpreter), 
-				('\0' + chr(self.run_with_cl_interpreter) + 'Run with commandline Python', self.domenu_toggle_run_with_cl_interpreter), 
-				'-',
-				('Modularize', self.domenu_modularize),
-				('Browse namespace\xc9', self.domenu_browsenamespace), 
-				'-']
-		if self.profiling:
-			menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
-		else:
-			menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
-		if self.editgroup.editor._debugger:
-			menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
-				('Clear breakpoints', self.domenu_clearbreakpoints),
-				('Edit breakpoints\xc9', self.domenu_editbreakpoints)]
-		else:
-			menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
-		self.editgroup.optionsmenu.set(menuitems)
-	
-	def domenu_toggle_run_as_main(self):
-		self.run_as_main = not self.run_as_main
-		self.run_with_interpreter = 0
-		self.run_with_cl_interpreter = 0
-		self.editgroup.editor.selectionchanged()
-	
-	def XXdomenu_toggle_run_with_interpreter(self):
-		self.run_with_interpreter = not self.run_with_interpreter
-		self.run_as_main = 0
-		self.run_with_cl_interpreter = 0
-		self.editgroup.editor.selectionchanged()
-	
-	def domenu_toggle_run_with_cl_interpreter(self):
-		self.run_with_cl_interpreter = not self.run_with_cl_interpreter
-		self.run_as_main = 0
-		self.run_with_interpreter = 0
-		self.editgroup.editor.selectionchanged()
-	
-	def showbreakpoints(self, onoff):
-		self.editgroup.editor.showbreakpoints(onoff)
-		self.debugging = onoff
-	
-	def domenu_clearbreakpoints(self, *args):
-		self.editgroup.editor.clearbreakpoints()
-	
-	def domenu_editbreakpoints(self, *args):
-		self.editgroup.editor.editbreakpoints()
-	
-	def domenu_toggledebugger(self, *args):
-		if not self.debugging:
-			W.SetCursor('watch')
-		self.debugging = not self.debugging
-		self.editgroup.editor.togglebreakpoints()
-		
-	def domenu_toggleprofiler(self, *args):
-		self.profiling = not self.profiling
-	
-	def domenu_browsenamespace(self, *args):
-		import PyBrowser, W
-		W.SetCursor('watch')
-		globals, file, modname = self.getenvironment()
-		if not modname:
-			modname = self.title
-		PyBrowser.Browser(globals, "Object browser: " + modname)
-	
-	def domenu_modularize(self, *args):
-		modname = _filename_as_modname(self.title)
-		if not modname:
-			raise W.AlertError, "Can't modularize \"%s\"" % self.title
-		run_as_main = self.run_as_main
-		self.run_as_main = 0
-		self.run()
-		self.run_as_main = run_as_main
-		if self.path:
-			file = self.path
-		else:
-			file = self.title
-		
-		if self.globals and not sys.modules.has_key(modname):
-			module = imp.new_module(modname)
-			for attr in self.globals.keys():
-				setattr(module,attr,self.globals[attr])
-			sys.modules[modname] = module
-			self.globals = {}
-	
-	def domenu_fontsettings(self, *args):
-		import FontSettings
-		fontsettings = self.editgroup.editor.getfontsettings()
-		tabsettings = self.editgroup.editor.gettabsettings()
-		settings = FontSettings.FontDialog(fontsettings, tabsettings)
-		if settings:
-			fontsettings, tabsettings = settings
-			self.editgroup.editor.setfontsettings(fontsettings)
-			self.editgroup.editor.settabsettings(tabsettings)
-	
-	def domenu_options(self, *args):
-		rv = SaveOptions(self._creator, self._eoln)
-		if rv:
-			self.editgroup.editor.selectionchanged() # ouch...
-			self._creator, self._eoln = rv
-	
-	def clicklinefield(self):
-		if self._currentwidget <> self.linefield:
-			self.linefield.select(1)
-			self.linefield.selectall()
-			return 1
-	
-	def clickeditor(self):
-		if self._currentwidget <> self.editgroup.editor:
-			self.dolinefield()
-			return 1
-	
-	def updateselection(self, force = 0):
-		sel = min(self.editgroup.editor.getselection())
-		lineno = self.editgroup.editor.offsettoline(sel)
-		if lineno <> self.lastlineno or force:
-			self.lastlineno = lineno
-			self.linefield.set(str(lineno + 1))
-			self.linefield.selview()
-	
-	def dolinefield(self):
-		try:
-			lineno = string.atoi(self.linefield.get()) - 1
-			if lineno <> self.lastlineno:
-				self.editgroup.editor.selectline(lineno)
-				self.updateselection(1)
-		except:
-			self.updateselection(1)
-		self.editgroup.editor.select(1)
-	
-	def setinfotext(self):
-		if not hasattr(self, 'infotext'):
-			return
-		if self.path:
-			self.infotext.set(self.path)
-		else:
-			self.infotext.set("")
-	
-	def close(self):
-		if self.editgroup.editor.changed:
-			Qd.InitCursor()
-			save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title,
-					default=1, no="Don\xd5t save")
-			if save > 0:
-				if self.domenu_save():
-					return 1
-			elif save < 0:
-				return 1
-		self.globals = None
-		W.Window.close(self)
-	
-	def domenu_close(self, *args):
-		return self.close()
-	
-	def domenu_save(self, *args):
-		if not self.path:
-			# Will call us recursively
-			return self.domenu_save_as()
-		data = self.editgroup.editor.get()
-		if self._eoln != '\r':
-			data = string.replace(data, '\r', self._eoln)
-		fp = open(self.path, 'wb')  # open file in binary mode, data has '\r' line-endings
-		fp.write(data)
-		fp.close()
-		MacOS.SetCreatorAndType(self.path, self._creator, 'TEXT')
-		self.getsettings()
-		self.writewindowsettings()
-		self.editgroup.editor.changed = 0
-		self.editgroup.editor.selchanged = 0
-		import linecache
-		if linecache.cache.has_key(self.path):
-			del linecache.cache[self.path]
-		import macostools
-		macostools.touched(self.path)
-		self.addrecentfile(self.path)
-	
-	def can_save(self, menuitem):
-		return self.editgroup.editor.changed or self.editgroup.editor.selchanged
-	
-	def domenu_save_as(self, *args):
-		path = EasyDialogs.AskFileForSave(message='Save as:', savedFileName=self.title)
-		if not path: 
-			return 1
-		self.showbreakpoints(0)
-		self.path = path
-		self.setinfotext()
-		self.title = os.path.split(self.path)[-1]
-		self.wid.SetWTitle(self.title)
-		self.domenu_save()
-		self.editgroup.editor.setfile(self.getfilename())
-		app = W.getapplication()
-		app.makeopenwindowsmenu()
-		if hasattr(app, 'makescriptsmenu'):
-			app = W.getapplication()
-			fsr, changed = app.scriptsfolder.FSResolveAlias(None)
-			path = fsr.as_pathname()
-			if path == self.path[:len(path)]:
-				W.getapplication().makescriptsmenu()
-	
-	def domenu_save_as_applet(self, *args):
-		import buildtools
-		
-		buildtools.DEBUG = 0	# ouch.
-		
-		if self.title[-3:] == ".py":
-			destname = self.title[:-3]
-		else:
-			destname = self.title + ".applet"
-		destname = EasyDialogs.AskFileForSave(message='Save as Applet:', 
-			savedFileName=destname)
-		if not destname: 
-			return 1
-		W.SetCursor("watch")
-		if self.path:
-			filename = self.path
-			if filename[-3:] == ".py":
-				rsrcname = filename[:-3] + '.rsrc'
-			else:
-				rsrcname = filename + '.rsrc'
-		else:
-			filename = self.title
-			rsrcname = ""
-		
-		pytext = self.editgroup.editor.get()
-		pytext = string.split(pytext, '\r')
-		pytext = string.join(pytext, '\n') + '\n'
-		try:
-			code = compile(pytext, filename, "exec")
-		except (SyntaxError, EOFError):
-			raise buildtools.BuildError, "Syntax error in script %r" % (filename,)
-			
-		import tempfile
-		tmpdir = tempfile.mkdtemp()
-		
-		if filename[-3:] != ".py":
-			filename = filename + ".py"
-		filename = os.path.join(tmpdir, os.path.split(filename)[1])
-		fp = open(filename, "w")
-		fp.write(pytext)
-		fp.close()
-		
-		# Try removing the output file
-		try:
-			os.remove(destname)
-		except os.error:
-			pass
-		template = buildtools.findtemplate()
-		buildtools.process(template, filename, destname, 1, rsrcname=rsrcname, progress=None)
-		try:
-			os.remove(filename)
-			os.rmdir(tmpdir)
-		except os.error:
-			pass
-	
-	def domenu_gotoline(self, *args):
-		self.linefield.selectall()
-		self.linefield.select(1)
-		self.linefield.selectall()
-	
-	def domenu_selectline(self, *args):
-		self.editgroup.editor.expandselection()
-	
-	def domenu_find(self, *args):
-		searchengine.show()
-	
-	def domenu_entersearchstring(self, *args):
-		searchengine.setfindstring()
-	
-	def domenu_replace(self, *args):
-		searchengine.replace()
-	
-	def domenu_findnext(self, *args):
-		searchengine.findnext()
-	
-	def domenu_replacefind(self, *args):
-		searchengine.replacefind()
-	
-	def domenu_run(self, *args):
-		self.runbutton.push()
-	
-	def domenu_runselection(self, *args):
-		self.runselbutton.push()
-	
-	def run(self):
-		self._run()
-	
-	def _run(self):
-		if self.run_with_interpreter:
-			if self.editgroup.editor.changed:
-				Qd.InitCursor()
-				save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
-				if save > 0:
-					if self.domenu_save():
-						return
-				elif save < 0:
-					return
-			if not self.path:
-				raise W.AlertError, "Can't run unsaved file"
-			self._run_with_interpreter()
-		elif self.run_with_cl_interpreter:
-			if self.editgroup.editor.changed:
-				Qd.InitCursor()
-				save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
-				if save > 0:
-					if self.domenu_save():
-						return
-				elif save < 0:
-					return
-			if not self.path:
-				raise W.AlertError, "Can't run unsaved file"
-			self._run_with_cl_interpreter()
-		else:
-			pytext = self.editgroup.editor.get()
-			globals, file, modname = self.getenvironment()
-			self.execstring(pytext, globals, globals, file, modname)
-	
-	def _run_with_interpreter(self):
-		interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
-		if not os.path.exists(interp_path):
-			raise W.AlertError, "Can't find interpreter"
-		import findertools
-		XXX
 
-	def _run_with_cl_interpreter(self):
-		import Terminal
-		interp_path = os.path.join(sys.exec_prefix, 
-			"Resources", "Python.app", "Contents", "MacOS", "Python")
-		if not os.path.exists(interp_path):
-			interp_path = os.path.join(sys.exec_prefix, "bin", "python")
-		file_path = self.path
-		if not os.path.exists(interp_path):
-			# This "can happen" if we are running IDE under MacPython-OS9.
-			raise W.AlertError, "Can't find command-line Python"
-		cmd = '"%s" "%s" ; exit' % (interp_path, file_path)
-		t = Terminal.Terminal()
-		t.do_script(cmd)
-	
-	def runselection(self):
-		self._runselection()
-	
-	def _runselection(self):
-		if self.run_with_interpreter or self.run_with_cl_interpreter:
-			raise W.AlertError, "Can't run selection with Interpreter"
-		globals, file, modname = self.getenvironment()
-		locals = globals
-		# select whole lines
-		self.editgroup.editor.expandselection()
-		
-		# get lineno of first selected line
-		selstart, selend = self.editgroup.editor.getselection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		selfirstline = self.editgroup.editor.offsettoline(selstart)
-		alltext = self.editgroup.editor.get()
-		pytext = alltext[selstart:selend]
-		lines = string.split(pytext, '\r')
-		indent = getminindent(lines)
-		if indent == 1:
-			classname = ''
-			alllines = string.split(alltext, '\r')
-			for i in range(selfirstline - 1, -1, -1):
-				line = alllines[i]
-				if line[:6] == 'class ':
-					classname = string.split(string.strip(line[6:]))[0]
-					classend = identifieRE_match(classname)
-					if classend < 1:
-						raise W.AlertError, "Can't find a class."
-					classname = classname[:classend]
-					break
-				elif line and line[0] not in '\t#':
-					raise W.AlertError, "Can't find a class."
-			else:
-				raise W.AlertError, "Can't find a class."
-			if globals.has_key(classname):
-				klass = globals[classname]
-			else:
-				raise W.AlertError, "Can't find class \"%s\"." % classname
-			# add class def
-			pytext = ("class %s:\n" % classname) + pytext
-			selfirstline = selfirstline - 1
-		elif indent > 0:
-			raise W.AlertError, "Can't run indented code."
-		
-		# add "newlines" to fool compile/exec: 
-		# now a traceback will give the right line number
-		pytext = selfirstline * '\r' + pytext
-		self.execstring(pytext, globals, locals, file, modname)
-		if indent == 1 and globals[classname] is not klass:
-			# update the class in place
-			klass.__dict__.update(globals[classname].__dict__)
-			globals[classname] = klass
-	
-	def execstring(self, pytext, globals, locals, file, modname):
-		tracebackwindow.hide()
-		# update windows
-		W.getapplication().refreshwindows()
-		if self.run_as_main:
-			modname = "__main__"
-		if self.path:
-			dir = os.path.dirname(self.path)
-			savedir = os.getcwd()
-			os.chdir(dir)
-			sys.path.insert(0, dir)
-		self._scriptDone = False
-		if sys.platform == "darwin":
-			# On MacOSX, MacPython doesn't poll for command-period
-			# (cancel), so to enable the user to cancel a running
-			# script, we have to spawn a thread which does the
-			# polling. It will send a SIGINT to the main thread
-			# (in which the script is running) when the user types
-			# command-period.
-			from threading import Thread
-			t = Thread(target=self._userCancelledMonitor,
-					name="UserCancelledMonitor")
-			t.start()
-		try:
-			execstring(pytext, globals, locals, file, self.debugging, 
-					modname, self.profiling)
-		finally:
-			self._scriptDone = True
-			if self.path:
-				os.chdir(savedir)
-				del sys.path[0]
-	
-	def _userCancelledMonitor(self):
-		import time
-		from signal import SIGINT
-		while not self._scriptDone:
-			if Evt.CheckEventQueueForUserCancel():
-				# Send a SIGINT signal to ourselves.
-				# This gets delivered to the main thread,
-				# cancelling the running script.
-				os.kill(os.getpid(), SIGINT)
-				break
-			time.sleep(0.25)
-	
-	def getenvironment(self):
-		if self.path:
-			file = self.path
-			dir = os.path.dirname(file)
-			# check if we're part of a package
-			modname = ""
-			while os.path.exists(os.path.join(dir, "__init__.py")):
-				dir, dirname = os.path.split(dir)
-				modname = dirname + '.' + modname
-			subname = _filename_as_modname(self.title)
-			if subname is None:
-				return self.globals, file, None
-			if modname:
-				if subname == "__init__":
-					# strip trailing period
-					modname = modname[:-1]
-				else:
-					modname = modname + subname
-			else:
-				modname = subname
-			if sys.modules.has_key(modname):
-				globals = sys.modules[modname].__dict__
-				self.globals = {}
-			else:
-				globals = self.globals
-				modname = subname
-		else:
-			file = '<%s>' % self.title
-			globals = self.globals
-			modname = file
-		return globals, file, modname
-	
-	def write(self, stuff):
-		"""for use as stdout"""
-		self._buf = self._buf + stuff
-		if '\n' in self._buf:
-			self.flush()
-	
-	def flush(self):
-		stuff = string.split(self._buf, '\n')
-		stuff = string.join(stuff, '\r')
-		end = self.editgroup.editor.ted.WEGetTextLength()
-		self.editgroup.editor.ted.WESetSelection(end, end)
-		self.editgroup.editor.ted.WEInsert(stuff, None, None)
-		self.editgroup.editor.updatescrollbars()
-		self._buf = ""
-		# ? optional:
-		#self.wid.SelectWindow()
-	
-	def getclasslist(self):
-		from string import find, strip
-		methodRE = re.compile(r"\r[ \t]+def ")
-		findMethod = methodRE.search
-		editor = self.editgroup.editor
-		text = editor.get()
-		list = []
-		append = list.append
-		functag = "func"
-		classtag = "class"
-		methodtag = "method"
-		pos = -1
-		if text[:4] == 'def ':
-			append((pos + 4, functag))
-			pos = 4
-		while 1:
-			pos = find(text, '\rdef ', pos + 1)
-			if pos < 0:
-				break
-			append((pos + 5, functag))
-		pos = -1
-		if text[:6] == 'class ':
-			append((pos + 6, classtag))
-			pos = 6
-		while 1:
-			pos = find(text, '\rclass ', pos + 1)
-			if pos < 0:
-				break
-			append((pos + 7, classtag))
-		pos = 0
-		while 1:
-			m = findMethod(text, pos + 1)
-			if m is None:
-				break
-			pos = m.regs[0][0]
-			#pos = find(text, '\r\tdef ', pos + 1)
-			append((m.regs[0][1], methodtag))
-		list.sort()
-		classlist = []
-		methodlistappend = None
-		offsetToLine = editor.ted.WEOffsetToLine
-		getLineRange = editor.ted.WEGetLineRange
-		append = classlist.append
-		for pos, tag in list:
-			lineno = offsetToLine(pos)
-			lineStart, lineEnd = getLineRange(lineno)
-			line = strip(text[pos:lineEnd])
-			line = line[:identifieRE_match(line)]
-			if tag is functag:
-				append(("def " + line, lineno + 1))
-				methodlistappend = None
-			elif tag is classtag:
-				append(["class " + line])
-				methodlistappend = classlist[-1].append
-			elif methodlistappend and tag is methodtag:
-				methodlistappend(("def " + line, lineno + 1))
-		return classlist
-	
-	def popselectline(self, lineno):
-		self.editgroup.editor.selectline(lineno - 1)
-	
-	def selectline(self, lineno, charoffset = 0):
-		self.editgroup.editor.selectline(lineno - 1, charoffset)
-		
-	def addrecentfile(self, filename):
-		app = W.getapplication()
-		app.addrecentfile(filename)
+    def __init__(self, path = "", title = ""):
+        defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
+        global _scriptuntitledcounter
+        if not path:
+            if title:
+                self.title = title
+            else:
+                self.title = "Untitled Script %r" % (_scriptuntitledcounter,)
+                _scriptuntitledcounter = _scriptuntitledcounter + 1
+            text = ""
+            self._creator = W._signature
+            self._eoln = os.linesep
+        elif os.path.exists(path):
+            path = resolvealiases(path)
+            dir, name = os.path.split(path)
+            self.title = name
+            f = open(path, "rb")
+            text = f.read()
+            f.close()
+            self._creator, filetype = MacOS.GetCreatorAndType(path)
+            self.addrecentfile(path)
+            if '\n' in text:
+                if string.find(text, '\r\n') >= 0:
+                    self._eoln = '\r\n'
+                else:
+                    self._eoln = '\n'
+                text = string.replace(text, self._eoln, '\r')
+            else:
+                self._eoln = '\r'
+        else:
+            raise IOError, "file '%s' does not exist" % path
+        self.path = path
+
+        self.settings = {}
+        if self.path:
+            self.readwindowsettings()
+        if self.settings.has_key("windowbounds"):
+            bounds = self.settings["windowbounds"]
+        else:
+            bounds = defaultwindowsize
+        if self.settings.has_key("fontsettings"):
+            self.fontsettings = self.settings["fontsettings"]
+        else:
+            self.fontsettings = defaultfontsettings
+        if self.settings.has_key("tabsize"):
+            try:
+                self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
+            except:
+                self.tabsettings = defaulttabsettings
+        else:
+            self.tabsettings = defaulttabsettings
+
+        W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
+        self.setupwidgets(text)
+
+        if self.settings.has_key("selection"):
+            selstart, selend = self.settings["selection"]
+            self.setselection(selstart, selend)
+        self.open()
+        self.setinfotext()
+        self.globals = {}
+        self._buf = ""  # for write method
+        self.debugging = 0
+        self.profiling = 0
+        self.run_as_main = self.settings.get("run_as_main", 0)
+        self.run_with_interpreter = self.settings.get("run_with_interpreter", 0)
+        self.run_with_cl_interpreter = self.settings.get("run_with_cl_interpreter", 0)
+
+    def readwindowsettings(self):
+        try:
+            resref = Res.FSpOpenResFile(self.path, 1)
+        except Res.Error:
+            return
+        try:
+            Res.UseResFile(resref)
+            data = Res.Get1Resource('PyWS', 128)
+            self.settings = marshal.loads(data.data)
+        except:
+            pass
+        Res.CloseResFile(resref)
+
+    def writewindowsettings(self):
+        try:
+            resref = Res.FSpOpenResFile(self.path, 3)
+        except Res.Error:
+            Res.FSpCreateResFile(self.path, self._creator, 'TEXT', smAllScripts)
+            resref = Res.FSpOpenResFile(self.path, 3)
+        try:
+            data = Res.Resource(marshal.dumps(self.settings))
+            Res.UseResFile(resref)
+            try:
+                temp = Res.Get1Resource('PyWS', 128)
+                temp.RemoveResource()
+            except Res.Error:
+                pass
+            data.AddResource('PyWS', 128, "window settings")
+        finally:
+            Res.UpdateResFile(resref)
+            Res.CloseResFile(resref)
+
+    def getsettings(self):
+        self.settings = {}
+        self.settings["windowbounds"] = self.getbounds()
+        self.settings["selection"] = self.getselection()
+        self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
+        self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
+        self.settings["run_as_main"] = self.run_as_main
+        self.settings["run_with_interpreter"] = self.run_with_interpreter
+        self.settings["run_with_cl_interpreter"] = self.run_with_cl_interpreter
+
+    def get(self):
+        return self.editgroup.editor.get()
+
+    def getselection(self):
+        return self.editgroup.editor.ted.WEGetSelection()
+
+    def setselection(self, selstart, selend):
+        self.editgroup.editor.setselection(selstart, selend)
+
+    def getselectedtext(self):
+        return self.editgroup.editor.getselectedtext()
+
+    def getfilename(self):
+        if self.path:
+            return self.path
+        return '<%s>' % self.title
+
+    def setupwidgets(self, text):
+        topbarheight = 24
+        popfieldwidth = 80
+        self.lastlineno = None
+
+        # make an editor
+        self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
+        editor = W.PyEditor((0, 0, -15,-15), text,
+                        fontsettings = self.fontsettings,
+                        tabsettings = self.tabsettings,
+                        file = self.getfilename())
+
+        # make the widgets
+        self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
+        self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
+        self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
+        self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
+        self.editgroup.editor = editor  # add editor *after* scrollbars
+
+        self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
+        self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
+
+        self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
+        self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
+        self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
+        self.runbutton = W.BevelButton((6, 4, 80, 16), runButtonLabels[0], self.run)
+        self.runselbutton = W.BevelButton((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
+
+        # bind some keys
+        editor.bind("cmdr", self.runbutton.push)
+        editor.bind("enter", self.runselbutton.push)
+        editor.bind("cmdj", self.domenu_gotoline)
+        editor.bind("cmdd", self.domenu_toggledebugger)
+        editor.bind("<idle>", self.updateselection)
+
+        editor.bind("cmde", searchengine.setfindstring)
+        editor.bind("cmdf", searchengine.show)
+        editor.bind("cmdg", searchengine.findnext)
+        editor.bind("cmdshiftr", searchengine.replace)
+        editor.bind("cmdt", searchengine.replacefind)
+
+        self.linefield.bind("return", self.dolinefield)
+        self.linefield.bind("enter", self.dolinefield)
+        self.linefield.bind("tab", self.dolinefield)
+
+        # intercept clicks
+        editor.bind("<click>", self.clickeditor)
+        self.linefield.bind("<click>", self.clicklinefield)
+
+    def makeoptionsmenu(self):
+        menuitems = [('Font settings\xc9', self.domenu_fontsettings),
+                        ("Save options\xc9", self.domenu_options),
+                        '-',
+                        ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
+                        #('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_dtoggle_run_with_interpreter),
+                        ('\0' + chr(self.run_with_cl_interpreter) + 'Run with commandline Python', self.domenu_toggle_run_with_cl_interpreter),
+                        '-',
+                        ('Modularize', self.domenu_modularize),
+                        ('Browse namespace\xc9', self.domenu_browsenamespace),
+                        '-']
+        if self.profiling:
+            menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
+        else:
+            menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
+        if self.editgroup.editor._debugger:
+            menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
+                    ('Clear breakpoints', self.domenu_clearbreakpoints),
+                    ('Edit breakpoints\xc9', self.domenu_editbreakpoints)]
+        else:
+            menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
+        self.editgroup.optionsmenu.set(menuitems)
+
+    def domenu_toggle_run_as_main(self):
+        self.run_as_main = not self.run_as_main
+        self.run_with_interpreter = 0
+        self.run_with_cl_interpreter = 0
+        self.editgroup.editor.selectionchanged()
+
+    def XXdomenu_toggle_run_with_interpreter(self):
+        self.run_with_interpreter = not self.run_with_interpreter
+        self.run_as_main = 0
+        self.run_with_cl_interpreter = 0
+        self.editgroup.editor.selectionchanged()
+
+    def domenu_toggle_run_with_cl_interpreter(self):
+        self.run_with_cl_interpreter = not self.run_with_cl_interpreter
+        self.run_as_main = 0
+        self.run_with_interpreter = 0
+        self.editgroup.editor.selectionchanged()
+
+    def showbreakpoints(self, onoff):
+        self.editgroup.editor.showbreakpoints(onoff)
+        self.debugging = onoff
+
+    def domenu_clearbreakpoints(self, *args):
+        self.editgroup.editor.clearbreakpoints()
+
+    def domenu_editbreakpoints(self, *args):
+        self.editgroup.editor.editbreakpoints()
+
+    def domenu_toggledebugger(self, *args):
+        if not self.debugging:
+            W.SetCursor('watch')
+        self.debugging = not self.debugging
+        self.editgroup.editor.togglebreakpoints()
+
+    def domenu_toggleprofiler(self, *args):
+        self.profiling = not self.profiling
+
+    def domenu_browsenamespace(self, *args):
+        import PyBrowser, W
+        W.SetCursor('watch')
+        globals, file, modname = self.getenvironment()
+        if not modname:
+            modname = self.title
+        PyBrowser.Browser(globals, "Object browser: " + modname)
+
+    def domenu_modularize(self, *args):
+        modname = _filename_as_modname(self.title)
+        if not modname:
+            raise W.AlertError, "Can't modularize \"%s\"" % self.title
+        run_as_main = self.run_as_main
+        self.run_as_main = 0
+        self.run()
+        self.run_as_main = run_as_main
+        if self.path:
+            file = self.path
+        else:
+            file = self.title
+
+        if self.globals and not sys.modules.has_key(modname):
+            module = imp.new_module(modname)
+            for attr in self.globals.keys():
+                setattr(module,attr,self.globals[attr])
+            sys.modules[modname] = module
+            self.globals = {}
+
+    def domenu_fontsettings(self, *args):
+        import FontSettings
+        fontsettings = self.editgroup.editor.getfontsettings()
+        tabsettings = self.editgroup.editor.gettabsettings()
+        settings = FontSettings.FontDialog(fontsettings, tabsettings)
+        if settings:
+            fontsettings, tabsettings = settings
+            self.editgroup.editor.setfontsettings(fontsettings)
+            self.editgroup.editor.settabsettings(tabsettings)
+
+    def domenu_options(self, *args):
+        rv = SaveOptions(self._creator, self._eoln)
+        if rv:
+            self.editgroup.editor.selectionchanged() # ouch...
+            self._creator, self._eoln = rv
+
+    def clicklinefield(self):
+        if self._currentwidget <> self.linefield:
+            self.linefield.select(1)
+            self.linefield.selectall()
+            return 1
+
+    def clickeditor(self):
+        if self._currentwidget <> self.editgroup.editor:
+            self.dolinefield()
+            return 1
+
+    def updateselection(self, force = 0):
+        sel = min(self.editgroup.editor.getselection())
+        lineno = self.editgroup.editor.offsettoline(sel)
+        if lineno <> self.lastlineno or force:
+            self.lastlineno = lineno
+            self.linefield.set(str(lineno + 1))
+            self.linefield.selview()
+
+    def dolinefield(self):
+        try:
+            lineno = string.atoi(self.linefield.get()) - 1
+            if lineno <> self.lastlineno:
+                self.editgroup.editor.selectline(lineno)
+                self.updateselection(1)
+        except:
+            self.updateselection(1)
+        self.editgroup.editor.select(1)
+
+    def setinfotext(self):
+        if not hasattr(self, 'infotext'):
+            return
+        if self.path:
+            self.infotext.set(self.path)
+        else:
+            self.infotext.set("")
+
+    def close(self):
+        if self.editgroup.editor.changed:
+            Qd.InitCursor()
+            save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title,
+                            default=1, no="Don\xd5t save")
+            if save > 0:
+                if self.domenu_save():
+                    return 1
+            elif save < 0:
+                return 1
+        self.globals = None
+        W.Window.close(self)
+
+    def domenu_close(self, *args):
+        return self.close()
+
+    def domenu_save(self, *args):
+        if not self.path:
+            # Will call us recursively
+            return self.domenu_save_as()
+        data = self.editgroup.editor.get()
+        if self._eoln != '\r':
+            data = string.replace(data, '\r', self._eoln)
+        fp = open(self.path, 'wb')  # open file in binary mode, data has '\r' line-endings
+        fp.write(data)
+        fp.close()
+        MacOS.SetCreatorAndType(self.path, self._creator, 'TEXT')
+        self.getsettings()
+        self.writewindowsettings()
+        self.editgroup.editor.changed = 0
+        self.editgroup.editor.selchanged = 0
+        import linecache
+        if linecache.cache.has_key(self.path):
+            del linecache.cache[self.path]
+        import macostools
+        macostools.touched(self.path)
+        self.addrecentfile(self.path)
+
+    def can_save(self, menuitem):
+        return self.editgroup.editor.changed or self.editgroup.editor.selchanged
+
+    def domenu_save_as(self, *args):
+        path = EasyDialogs.AskFileForSave(message='Save as:', savedFileName=self.title)
+        if not path:
+            return 1
+        self.showbreakpoints(0)
+        self.path = path
+        self.setinfotext()
+        self.title = os.path.split(self.path)[-1]
+        self.wid.SetWTitle(self.title)
+        self.domenu_save()
+        self.editgroup.editor.setfile(self.getfilename())
+        app = W.getapplication()
+        app.makeopenwindowsmenu()
+        if hasattr(app, 'makescriptsmenu'):
+            app = W.getapplication()
+            fsr, changed = app.scriptsfolder.FSResolveAlias(None)
+            path = fsr.as_pathname()
+            if path == self.path[:len(path)]:
+                W.getapplication().makescriptsmenu()
+
+    def domenu_save_as_applet(self, *args):
+        import buildtools
+
+        buildtools.DEBUG = 0    # ouch.
+
+        if self.title[-3:] == ".py":
+            destname = self.title[:-3]
+        else:
+            destname = self.title + ".applet"
+        destname = EasyDialogs.AskFileForSave(message='Save as Applet:',
+                savedFileName=destname)
+        if not destname:
+            return 1
+        W.SetCursor("watch")
+        if self.path:
+            filename = self.path
+            if filename[-3:] == ".py":
+                rsrcname = filename[:-3] + '.rsrc'
+            else:
+                rsrcname = filename + '.rsrc'
+        else:
+            filename = self.title
+            rsrcname = ""
+
+        pytext = self.editgroup.editor.get()
+        pytext = string.split(pytext, '\r')
+        pytext = string.join(pytext, '\n') + '\n'
+        try:
+            code = compile(pytext, filename, "exec")
+        except (SyntaxError, EOFError):
+            raise buildtools.BuildError, "Syntax error in script %r" % (filename,)
+
+        import tempfile
+        tmpdir = tempfile.mkdtemp()
+
+        if filename[-3:] != ".py":
+            filename = filename + ".py"
+        filename = os.path.join(tmpdir, os.path.split(filename)[1])
+        fp = open(filename, "w")
+        fp.write(pytext)
+        fp.close()
+
+        # Try removing the output file
+        try:
+            os.remove(destname)
+        except os.error:
+            pass
+        template = buildtools.findtemplate()
+        buildtools.process(template, filename, destname, 1, rsrcname=rsrcname, progress=None)
+        try:
+            os.remove(filename)
+            os.rmdir(tmpdir)
+        except os.error:
+            pass
+
+    def domenu_gotoline(self, *args):
+        self.linefield.selectall()
+        self.linefield.select(1)
+        self.linefield.selectall()
+
+    def domenu_selectline(self, *args):
+        self.editgroup.editor.expandselection()
+
+    def domenu_find(self, *args):
+        searchengine.show()
+
+    def domenu_entersearchstring(self, *args):
+        searchengine.setfindstring()
+
+    def domenu_replace(self, *args):
+        searchengine.replace()
+
+    def domenu_findnext(self, *args):
+        searchengine.findnext()
+
+    def domenu_replacefind(self, *args):
+        searchengine.replacefind()
+
+    def domenu_run(self, *args):
+        self.runbutton.push()
+
+    def domenu_runselection(self, *args):
+        self.runselbutton.push()
+
+    def run(self):
+        self._run()
+
+    def _run(self):
+        if self.run_with_interpreter:
+            if self.editgroup.editor.changed:
+                Qd.InitCursor()
+                save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
+                if save > 0:
+                    if self.domenu_save():
+                        return
+                elif save < 0:
+                    return
+            if not self.path:
+                raise W.AlertError, "Can't run unsaved file"
+            self._run_with_interpreter()
+        elif self.run_with_cl_interpreter:
+            if self.editgroup.editor.changed:
+                Qd.InitCursor()
+                save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
+                if save > 0:
+                    if self.domenu_save():
+                        return
+                elif save < 0:
+                    return
+            if not self.path:
+                raise W.AlertError, "Can't run unsaved file"
+            self._run_with_cl_interpreter()
+        else:
+            pytext = self.editgroup.editor.get()
+            globals, file, modname = self.getenvironment()
+            self.execstring(pytext, globals, globals, file, modname)
+
+    def _run_with_interpreter(self):
+        interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
+        if not os.path.exists(interp_path):
+            raise W.AlertError, "Can't find interpreter"
+        import findertools
+        XXX
+
+    def _run_with_cl_interpreter(self):
+        import Terminal
+        interp_path = os.path.join(sys.exec_prefix,
+                "Resources", "Python.app", "Contents", "MacOS", "Python")
+        if not os.path.exists(interp_path):
+            interp_path = os.path.join(sys.exec_prefix, "bin", "python")
+        file_path = self.path
+        if not os.path.exists(interp_path):
+            # This "can happen" if we are running IDE under MacPython-OS9.
+            raise W.AlertError, "Can't find command-line Python"
+        cmd = '"%s" "%s" ; exit' % (interp_path, file_path)
+        t = Terminal.Terminal()
+        t.do_script(cmd)
+
+    def runselection(self):
+        self._runselection()
+
+    def _runselection(self):
+        if self.run_with_interpreter or self.run_with_cl_interpreter:
+            raise W.AlertError, "Can't run selection with Interpreter"
+        globals, file, modname = self.getenvironment()
+        locals = globals
+        # select whole lines
+        self.editgroup.editor.expandselection()
+
+        # get lineno of first selected line
+        selstart, selend = self.editgroup.editor.getselection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        selfirstline = self.editgroup.editor.offsettoline(selstart)
+        alltext = self.editgroup.editor.get()
+        pytext = alltext[selstart:selend]
+        lines = string.split(pytext, '\r')
+        indent = getminindent(lines)
+        if indent == 1:
+            classname = ''
+            alllines = string.split(alltext, '\r')
+            for i in range(selfirstline - 1, -1, -1):
+                line = alllines[i]
+                if line[:6] == 'class ':
+                    classname = string.split(string.strip(line[6:]))[0]
+                    classend = identifieRE_match(classname)
+                    if classend < 1:
+                        raise W.AlertError, "Can't find a class."
+                    classname = classname[:classend]
+                    break
+                elif line and line[0] not in '\t#':
+                    raise W.AlertError, "Can't find a class."
+            else:
+                raise W.AlertError, "Can't find a class."
+            if globals.has_key(classname):
+                klass = globals[classname]
+            else:
+                raise W.AlertError, "Can't find class \"%s\"." % classname
+            # add class def
+            pytext = ("class %s:\n" % classname) + pytext
+            selfirstline = selfirstline - 1
+        elif indent > 0:
+            raise W.AlertError, "Can't run indented code."
+
+        # add "newlines" to fool compile/exec:
+        # now a traceback will give the right line number
+        pytext = selfirstline * '\r' + pytext
+        self.execstring(pytext, globals, locals, file, modname)
+        if indent == 1 and globals[classname] is not klass:
+            # update the class in place
+            klass.__dict__.update(globals[classname].__dict__)
+            globals[classname] = klass
+
+    def execstring(self, pytext, globals, locals, file, modname):
+        tracebackwindow.hide()
+        # update windows
+        W.getapplication().refreshwindows()
+        if self.run_as_main:
+            modname = "__main__"
+        if self.path:
+            dir = os.path.dirname(self.path)
+            savedir = os.getcwd()
+            os.chdir(dir)
+            sys.path.insert(0, dir)
+        self._scriptDone = False
+        if sys.platform == "darwin":
+            # On MacOSX, MacPython doesn't poll for command-period
+            # (cancel), so to enable the user to cancel a running
+            # script, we have to spawn a thread which does the
+            # polling. It will send a SIGINT to the main thread
+            # (in which the script is running) when the user types
+            # command-period.
+            from threading import Thread
+            t = Thread(target=self._userCancelledMonitor,
+                            name="UserCancelledMonitor")
+            t.start()
+        try:
+            execstring(pytext, globals, locals, file, self.debugging,
+                            modname, self.profiling)
+        finally:
+            self._scriptDone = True
+            if self.path:
+                os.chdir(savedir)
+                del sys.path[0]
+
+    def _userCancelledMonitor(self):
+        import time
+        from signal import SIGINT
+        while not self._scriptDone:
+            if Evt.CheckEventQueueForUserCancel():
+                # Send a SIGINT signal to ourselves.
+                # This gets delivered to the main thread,
+                # cancelling the running script.
+                os.kill(os.getpid(), SIGINT)
+                break
+            time.sleep(0.25)
+
+    def getenvironment(self):
+        if self.path:
+            file = self.path
+            dir = os.path.dirname(file)
+            # check if we're part of a package
+            modname = ""
+            while os.path.exists(os.path.join(dir, "__init__.py")):
+                dir, dirname = os.path.split(dir)
+                modname = dirname + '.' + modname
+            subname = _filename_as_modname(self.title)
+            if subname is None:
+                return self.globals, file, None
+            if modname:
+                if subname == "__init__":
+                    # strip trailing period
+                    modname = modname[:-1]
+                else:
+                    modname = modname + subname
+            else:
+                modname = subname
+            if sys.modules.has_key(modname):
+                globals = sys.modules[modname].__dict__
+                self.globals = {}
+            else:
+                globals = self.globals
+                modname = subname
+        else:
+            file = '<%s>' % self.title
+            globals = self.globals
+            modname = file
+        return globals, file, modname
+
+    def write(self, stuff):
+        """for use as stdout"""
+        self._buf = self._buf + stuff
+        if '\n' in self._buf:
+            self.flush()
+
+    def flush(self):
+        stuff = string.split(self._buf, '\n')
+        stuff = string.join(stuff, '\r')
+        end = self.editgroup.editor.ted.WEGetTextLength()
+        self.editgroup.editor.ted.WESetSelection(end, end)
+        self.editgroup.editor.ted.WEInsert(stuff, None, None)
+        self.editgroup.editor.updatescrollbars()
+        self._buf = ""
+        # ? optional:
+        #self.wid.SelectWindow()
+
+    def getclasslist(self):
+        from string import find, strip
+        methodRE = re.compile(r"\r[ \t]+def ")
+        findMethod = methodRE.search
+        editor = self.editgroup.editor
+        text = editor.get()
+        list = []
+        append = list.append
+        functag = "func"
+        classtag = "class"
+        methodtag = "method"
+        pos = -1
+        if text[:4] == 'def ':
+            append((pos + 4, functag))
+            pos = 4
+        while 1:
+            pos = find(text, '\rdef ', pos + 1)
+            if pos < 0:
+                break
+            append((pos + 5, functag))
+        pos = -1
+        if text[:6] == 'class ':
+            append((pos + 6, classtag))
+            pos = 6
+        while 1:
+            pos = find(text, '\rclass ', pos + 1)
+            if pos < 0:
+                break
+            append((pos + 7, classtag))
+        pos = 0
+        while 1:
+            m = findMethod(text, pos + 1)
+            if m is None:
+                break
+            pos = m.regs[0][0]
+            #pos = find(text, '\r\tdef ', pos + 1)
+            append((m.regs[0][1], methodtag))
+        list.sort()
+        classlist = []
+        methodlistappend = None
+        offsetToLine = editor.ted.WEOffsetToLine
+        getLineRange = editor.ted.WEGetLineRange
+        append = classlist.append
+        for pos, tag in list:
+            lineno = offsetToLine(pos)
+            lineStart, lineEnd = getLineRange(lineno)
+            line = strip(text[pos:lineEnd])
+            line = line[:identifieRE_match(line)]
+            if tag is functag:
+                append(("def " + line, lineno + 1))
+                methodlistappend = None
+            elif tag is classtag:
+                append(["class " + line])
+                methodlistappend = classlist[-1].append
+            elif methodlistappend and tag is methodtag:
+                methodlistappend(("def " + line, lineno + 1))
+        return classlist
+
+    def popselectline(self, lineno):
+        self.editgroup.editor.selectline(lineno - 1)
+
+    def selectline(self, lineno, charoffset = 0):
+        self.editgroup.editor.selectline(lineno - 1, charoffset)
+
+    def addrecentfile(self, filename):
+        app = W.getapplication()
+        app.addrecentfile(filename)
 
 class _saveoptions:
-	
-	def __init__(self, creator, eoln):
-		self.rv = None
-		self.eoln = eoln
-		self.w = w = W.ModalDialog((260, 160), 'Save options')
-		radiobuttons = []
-		w.label = W.TextBox((8, 8, 80, 18), "File creator:")
-		w.ide_radio = W.RadioButton((8, 22, 160, 18), "PythonIDE", radiobuttons, self.ide_hit)
-		w.interp_radio = W.RadioButton((8, 42, 160, 18), "MacPython-OS9 Interpreter", radiobuttons, self.interp_hit)
-		w.interpx_radio = W.RadioButton((8, 62, 160, 18), "PythonLauncher", radiobuttons, self.interpx_hit)
-		w.other_radio = W.RadioButton((8, 82, 50, 18), "Other:", radiobuttons)
-		w.other_creator = W.EditText((62, 82, 40, 20), creator, self.otherselect)
-		w.none_radio = W.RadioButton((8, 102, 160, 18), "None", radiobuttons, self.none_hit)
-		w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
-		w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
-		w.setdefaultbutton(w.okbutton)
-		if creator == 'Pyth':
-			w.interp_radio.set(1)
-		elif creator == W._signature:
-			w.ide_radio.set(1)
-		elif creator == 'PytX':
-			w.interpx_radio.set(1)
-		elif creator == '\0\0\0\0':
-			w.none_radio.set(1)
-		else:
-			w.other_radio.set(1)
-			
-		w.eolnlabel = W.TextBox((168, 8, 80, 18), "Newline style:")
-		radiobuttons = []
-		w.unix_radio = W.RadioButton((168, 22, 80, 18), "Unix", radiobuttons, self.unix_hit)
-		w.mac_radio = W.RadioButton((168, 42, 80, 18), "Macintosh", radiobuttons, self.mac_hit)
-		w.win_radio = W.RadioButton((168, 62, 80, 18), "Windows", radiobuttons, self.win_hit)
-		if self.eoln == '\n':
-			w.unix_radio.set(1)
-		elif self.eoln == '\r\n':
-			w.win_radio.set(1)
-		else:
-			w.mac_radio.set(1)
-		
-		w.bind("cmd.", w.cancelbutton.push)
-		w.open()
-	
-	def ide_hit(self):
-		self.w.other_creator.set(W._signature)
-	
-	def interp_hit(self):
-		self.w.other_creator.set("Pyth")
-	
-	def interpx_hit(self):
-		self.w.other_creator.set("PytX")
-	
-	def none_hit(self):
-		self.w.other_creator.set("\0\0\0\0")
-	
-	def otherselect(self, *args):
-		sel_from, sel_to = self.w.other_creator.getselection()
-		creator = self.w.other_creator.get()[:4]
-		creator = creator + " " * (4 - len(creator))
-		self.w.other_creator.set(creator)
-		self.w.other_creator.setselection(sel_from, sel_to)
-		self.w.other_radio.set(1)
-	
-	def mac_hit(self):
-		self.eoln = '\r'
-		
-	def unix_hit(self):
-		self.eoln = '\n'
-		
-	def win_hit(self):
-		self.eoln = '\r\n'
-		
-	def cancelbuttonhit(self):
-		self.w.close()
-	
-	def okbuttonhit(self):
-		self.rv = (self.w.other_creator.get()[:4], self.eoln)
-		self.w.close()
+
+    def __init__(self, creator, eoln):
+        self.rv = None
+        self.eoln = eoln
+        self.w = w = W.ModalDialog((260, 160), 'Save options')
+        radiobuttons = []
+        w.label = W.TextBox((8, 8, 80, 18), "File creator:")
+        w.ide_radio = W.RadioButton((8, 22, 160, 18), "PythonIDE", radiobuttons, self.ide_hit)
+        w.interp_radio = W.RadioButton((8, 42, 160, 18), "MacPython-OS9 Interpreter", radiobuttons, self.interp_hit)
+        w.interpx_radio = W.RadioButton((8, 62, 160, 18), "PythonLauncher", radiobuttons, self.interpx_hit)
+        w.other_radio = W.RadioButton((8, 82, 50, 18), "Other:", radiobuttons)
+        w.other_creator = W.EditText((62, 82, 40, 20), creator, self.otherselect)
+        w.none_radio = W.RadioButton((8, 102, 160, 18), "None", radiobuttons, self.none_hit)
+        w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
+        w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
+        w.setdefaultbutton(w.okbutton)
+        if creator == 'Pyth':
+            w.interp_radio.set(1)
+        elif creator == W._signature:
+            w.ide_radio.set(1)
+        elif creator == 'PytX':
+            w.interpx_radio.set(1)
+        elif creator == '\0\0\0\0':
+            w.none_radio.set(1)
+        else:
+            w.other_radio.set(1)
+
+        w.eolnlabel = W.TextBox((168, 8, 80, 18), "Newline style:")
+        radiobuttons = []
+        w.unix_radio = W.RadioButton((168, 22, 80, 18), "Unix", radiobuttons, self.unix_hit)
+        w.mac_radio = W.RadioButton((168, 42, 80, 18), "Macintosh", radiobuttons, self.mac_hit)
+        w.win_radio = W.RadioButton((168, 62, 80, 18), "Windows", radiobuttons, self.win_hit)
+        if self.eoln == '\n':
+            w.unix_radio.set(1)
+        elif self.eoln == '\r\n':
+            w.win_radio.set(1)
+        else:
+            w.mac_radio.set(1)
+
+        w.bind("cmd.", w.cancelbutton.push)
+        w.open()
+
+    def ide_hit(self):
+        self.w.other_creator.set(W._signature)
+
+    def interp_hit(self):
+        self.w.other_creator.set("Pyth")
+
+    def interpx_hit(self):
+        self.w.other_creator.set("PytX")
+
+    def none_hit(self):
+        self.w.other_creator.set("\0\0\0\0")
+
+    def otherselect(self, *args):
+        sel_from, sel_to = self.w.other_creator.getselection()
+        creator = self.w.other_creator.get()[:4]
+        creator = creator + " " * (4 - len(creator))
+        self.w.other_creator.set(creator)
+        self.w.other_creator.setselection(sel_from, sel_to)
+        self.w.other_radio.set(1)
+
+    def mac_hit(self):
+        self.eoln = '\r'
+
+    def unix_hit(self):
+        self.eoln = '\n'
+
+    def win_hit(self):
+        self.eoln = '\r\n'
+
+    def cancelbuttonhit(self):
+        self.w.close()
+
+    def okbuttonhit(self):
+        self.rv = (self.w.other_creator.get()[:4], self.eoln)
+        self.w.close()
 
 
 def SaveOptions(creator, eoln):
-	s = _saveoptions(creator, eoln)
-	return s.rv
+    s = _saveoptions(creator, eoln)
+    return s.rv
 
 
-def _escape(where, what) : 
-	return string.join(string.split(where, what), '\\' + what)
+def _escape(where, what) :
+    return string.join(string.split(where, what), '\\' + what)
 
 def _makewholewordpattern(word):
-	# first, escape special regex chars
-	for esc in "\\[]()|.*^+$?":
-		word = _escape(word, esc)
-	notwordcharspat = '[^' + _wordchars + ']'
-	pattern = '(' + word + ')'
-	if word[0] in _wordchars:
-		pattern = notwordcharspat + pattern
-	if word[-1] in _wordchars:
-		pattern = pattern + notwordcharspat
-	return re.compile(pattern)
+    # first, escape special regex chars
+    for esc in "\\[]()|.*^+$?":
+        word = _escape(word, esc)
+    notwordcharspat = '[^' + _wordchars + ']'
+    pattern = '(' + word + ')'
+    if word[0] in _wordchars:
+        pattern = notwordcharspat + pattern
+    if word[-1] in _wordchars:
+        pattern = pattern + notwordcharspat
+    return re.compile(pattern)
 
 
 class SearchEngine:
-	
-	def __init__(self):
-		self.visible = 0
-		self.w = None
-		self.parms = {  "find": "",
-					"replace": "",
-					"wrap": 1,
-					"casesens": 1,
-					"wholeword": 1
-				}
-		import MacPrefs
-		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-		if prefs.searchengine:
-			self.parms["casesens"] = prefs.searchengine.casesens
-			self.parms["wrap"] = prefs.searchengine.wrap
-			self.parms["wholeword"] = prefs.searchengine.wholeword
-	
-	def show(self):
-		self.visible = 1
-		if self.w:
-			self.w.wid.ShowWindow()
-			self.w.wid.SelectWindow()
-			self.w.find.edit.select(1)
-			self.w.find.edit.selectall()
-			return
-		self.w = W.Dialog((420, 150), "Find")
-		
-		self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
-		self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
-		
-		self.w.boxes = W.Group((10, 50, 300, 40))
-		self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
-		self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
-		self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
-		
-		self.buttons = [	("Find",		"cmdf",	 self.find), 
-					("Replace",	     "cmdr",	 self.replace), 
-					("Replace all",	 None,   self.replaceall), 
-					("Don't find",  "cmdd",	 self.dont), 
-					("Cancel",	      "cmd.",	 self.cancel)
-				]
-		for i in range(len(self.buttons)):
-			bounds = -90, 22 + i * 24, 80, 16
-			title, shortcut, callback = self.buttons[i]
-			self.w[title] = W.Button(bounds, title, callback)
-			if shortcut:
-				self.w.bind(shortcut, self.w[title].push)
-		self.w.setdefaultbutton(self.w["Don't find"])
-		self.w.find.edit.bind("<key>", self.key)
-		self.w.bind("<activate>", self.activate)
-		self.w.bind("<close>", self.close)
-		self.w.open()
-		self.setparms()
-		self.w.find.edit.select(1)
-		self.w.find.edit.selectall()
-		self.checkbuttons()
-	
-	def close(self):
-		self.hide()
-		return -1
-	
-	def key(self, char, modifiers):
-		self.w.find.edit.key(char, modifiers)
-		self.checkbuttons()
-		return 1
-	
-	def activate(self, onoff):
-		if onoff:
-			self.checkbuttons()
-	
-	def checkbuttons(self):
-		editor = findeditor(self)
-		if editor:
-			if self.w.find.get():
-				for title, cmd, call in self.buttons[:-2]:
-					self.w[title].enable(1)
-				self.w.setdefaultbutton(self.w["Find"])
-			else:
-				for title, cmd, call in self.buttons[:-2]:
-					self.w[title].enable(0)
-				self.w.setdefaultbutton(self.w["Don't find"])
-		else:
-			for title, cmd, call in self.buttons[:-2]:
-				self.w[title].enable(0)
-			self.w.setdefaultbutton(self.w["Don't find"])
-	
-	def find(self):
-		self.getparmsfromwindow()
-		if self.findnext():
-			self.hide()
-	
-	def replace(self):
-		editor = findeditor(self)
-		if not editor:
-			return
-		if self.visible:
-			self.getparmsfromwindow()
-		text = editor.getselectedtext()
-		find = self.parms["find"]
-		if not self.parms["casesens"]:
-			find = string.lower(find)
-			text = string.lower(text)
-		if text == find:
-			self.hide()
-			editor.insert(self.parms["replace"])
-	
-	def replaceall(self):
-		editor = findeditor(self)
-		if not editor:
-			return
-		if self.visible:
-			self.getparmsfromwindow()
-		W.SetCursor("watch")
-		find = self.parms["find"]
-		if not find:
-			return
-		findlen = len(find)
-		replace = self.parms["replace"]
-		replacelen = len(replace)
-		Text = editor.get()
-		if not self.parms["casesens"]:
-			find = string.lower(find)
-			text = string.lower(Text)
-		else:
-			text = Text
-		newtext = ""
-		pos = 0
-		counter = 0
-		while 1:
-			if self.parms["wholeword"]:
-				wholewordRE = _makewholewordpattern(find)
-				match = wholewordRE.search(text, pos)
-				if match:
-					pos = match.start(1)
-				else:
-					pos = -1
-			else:
-				pos = string.find(text, find, pos)
-			if pos < 0:
-				break
-			counter = counter + 1
-			text = text[:pos] + replace + text[pos + findlen:]
-			Text = Text[:pos] + replace + Text[pos + findlen:]
-			pos = pos + replacelen
-		W.SetCursor("arrow")
-		if counter:
-			self.hide()
-			from Carbon import Res
-			editor.textchanged()
-			editor.selectionchanged()
-			editor.set(Text)
-			EasyDialogs.Message("Replaced %d occurrences" % counter)
-	
-	def dont(self):
-		self.getparmsfromwindow()
-		self.hide()
-	
-	def replacefind(self):
-		self.replace()
-		self.findnext()
-	
-	def setfindstring(self):
-		editor = findeditor(self)
-		if not editor:
-			return
-		find = editor.getselectedtext()
-		if not find:
-			return
-		self.parms["find"] = find
-		if self.w:
-			self.w.find.edit.set(self.parms["find"])
-			self.w.find.edit.selectall()
-	
-	def findnext(self):
-		editor = findeditor(self)
-		if not editor:
-			return
-		find = self.parms["find"]
-		if not find:
-			return
-		text = editor.get()
-		if not self.parms["casesens"]:
-			find = string.lower(find)
-			text = string.lower(text)
-		selstart, selend = editor.getselection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		if self.parms["wholeword"]:
-			wholewordRE = _makewholewordpattern(find)
-			match = wholewordRE.search(text, selend)
-			if match:
-				pos = match.start(1)
-			else:
-				pos = -1
-		else:
-			pos = string.find(text, find, selend)
-		if pos >= 0:
-			editor.setselection(pos, pos + len(find))
-			return 1
-		elif self.parms["wrap"]:
-			if self.parms["wholeword"]:
-				match = wholewordRE.search(text, 0)
-				if match:
-					pos = match.start(1)
-				else:
-					pos = -1
-			else:
-				pos = string.find(text, find)
-			if selstart > pos >= 0:
-				editor.setselection(pos, pos + len(find))
-				return 1
-	
-	def setparms(self):
-		for key, value in self.parms.items():
-			try:
-				self.w[key].set(value)
-			except KeyError:
-				self.w.boxes[key].set(value)
-	
-	def getparmsfromwindow(self):
-		if not self.w:
-			return
-		for key, value in self.parms.items():
-			try:
-				value = self.w[key].get()
-			except KeyError:
-				value = self.w.boxes[key].get()
-			self.parms[key] = value
-	
-	def cancel(self):
-		self.hide()
-		self.setparms()
-	
-	def hide(self):
-		if self.w:
-			self.w.wid.HideWindow()
-			self.visible = 0
-	
-	def writeprefs(self):
-		import MacPrefs
-		self.getparmsfromwindow()
-		prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-		prefs.searchengine.casesens = self.parms["casesens"]
-		prefs.searchengine.wrap = self.parms["wrap"]
-		prefs.searchengine.wholeword = self.parms["wholeword"]
-		prefs.save()
-	
+
+    def __init__(self):
+        self.visible = 0
+        self.w = None
+        self.parms = {  "find": "",
+                                "replace": "",
+                                "wrap": 1,
+                                "casesens": 1,
+                                "wholeword": 1
+                        }
+        import MacPrefs
+        prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+        if prefs.searchengine:
+            self.parms["casesens"] = prefs.searchengine.casesens
+            self.parms["wrap"] = prefs.searchengine.wrap
+            self.parms["wholeword"] = prefs.searchengine.wholeword
+
+    def show(self):
+        self.visible = 1
+        if self.w:
+            self.w.wid.ShowWindow()
+            self.w.wid.SelectWindow()
+            self.w.find.edit.select(1)
+            self.w.find.edit.selectall()
+            return
+        self.w = W.Dialog((420, 150), "Find")
+
+        self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
+        self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
+
+        self.w.boxes = W.Group((10, 50, 300, 40))
+        self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
+        self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
+        self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
+
+        self.buttons = [        ("Find",                "cmdf",  self.find),
+                                ("Replace",          "cmdr",     self.replace),
+                                ("Replace all",  None,   self.replaceall),
+                                ("Don't find",  "cmdd",  self.dont),
+                                ("Cancel",            "cmd.",    self.cancel)
+                        ]
+        for i in range(len(self.buttons)):
+            bounds = -90, 22 + i * 24, 80, 16
+            title, shortcut, callback = self.buttons[i]
+            self.w[title] = W.Button(bounds, title, callback)
+            if shortcut:
+                self.w.bind(shortcut, self.w[title].push)
+        self.w.setdefaultbutton(self.w["Don't find"])
+        self.w.find.edit.bind("<key>", self.key)
+        self.w.bind("<activate>", self.activate)
+        self.w.bind("<close>", self.close)
+        self.w.open()
+        self.setparms()
+        self.w.find.edit.select(1)
+        self.w.find.edit.selectall()
+        self.checkbuttons()
+
+    def close(self):
+        self.hide()
+        return -1
+
+    def key(self, char, modifiers):
+        self.w.find.edit.key(char, modifiers)
+        self.checkbuttons()
+        return 1
+
+    def activate(self, onoff):
+        if onoff:
+            self.checkbuttons()
+
+    def checkbuttons(self):
+        editor = findeditor(self)
+        if editor:
+            if self.w.find.get():
+                for title, cmd, call in self.buttons[:-2]:
+                    self.w[title].enable(1)
+                self.w.setdefaultbutton(self.w["Find"])
+            else:
+                for title, cmd, call in self.buttons[:-2]:
+                    self.w[title].enable(0)
+                self.w.setdefaultbutton(self.w["Don't find"])
+        else:
+            for title, cmd, call in self.buttons[:-2]:
+                self.w[title].enable(0)
+            self.w.setdefaultbutton(self.w["Don't find"])
+
+    def find(self):
+        self.getparmsfromwindow()
+        if self.findnext():
+            self.hide()
+
+    def replace(self):
+        editor = findeditor(self)
+        if not editor:
+            return
+        if self.visible:
+            self.getparmsfromwindow()
+        text = editor.getselectedtext()
+        find = self.parms["find"]
+        if not self.parms["casesens"]:
+            find = string.lower(find)
+            text = string.lower(text)
+        if text == find:
+            self.hide()
+            editor.insert(self.parms["replace"])
+
+    def replaceall(self):
+        editor = findeditor(self)
+        if not editor:
+            return
+        if self.visible:
+            self.getparmsfromwindow()
+        W.SetCursor("watch")
+        find = self.parms["find"]
+        if not find:
+            return
+        findlen = len(find)
+        replace = self.parms["replace"]
+        replacelen = len(replace)
+        Text = editor.get()
+        if not self.parms["casesens"]:
+            find = string.lower(find)
+            text = string.lower(Text)
+        else:
+            text = Text
+        newtext = ""
+        pos = 0
+        counter = 0
+        while 1:
+            if self.parms["wholeword"]:
+                wholewordRE = _makewholewordpattern(find)
+                match = wholewordRE.search(text, pos)
+                if match:
+                    pos = match.start(1)
+                else:
+                    pos = -1
+            else:
+                pos = string.find(text, find, pos)
+            if pos < 0:
+                break
+            counter = counter + 1
+            text = text[:pos] + replace + text[pos + findlen:]
+            Text = Text[:pos] + replace + Text[pos + findlen:]
+            pos = pos + replacelen
+        W.SetCursor("arrow")
+        if counter:
+            self.hide()
+            from Carbon import Res
+            editor.textchanged()
+            editor.selectionchanged()
+            editor.set(Text)
+            EasyDialogs.Message("Replaced %d occurrences" % counter)
+
+    def dont(self):
+        self.getparmsfromwindow()
+        self.hide()
+
+    def replacefind(self):
+        self.replace()
+        self.findnext()
+
+    def setfindstring(self):
+        editor = findeditor(self)
+        if not editor:
+            return
+        find = editor.getselectedtext()
+        if not find:
+            return
+        self.parms["find"] = find
+        if self.w:
+            self.w.find.edit.set(self.parms["find"])
+            self.w.find.edit.selectall()
+
+    def findnext(self):
+        editor = findeditor(self)
+        if not editor:
+            return
+        find = self.parms["find"]
+        if not find:
+            return
+        text = editor.get()
+        if not self.parms["casesens"]:
+            find = string.lower(find)
+            text = string.lower(text)
+        selstart, selend = editor.getselection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        if self.parms["wholeword"]:
+            wholewordRE = _makewholewordpattern(find)
+            match = wholewordRE.search(text, selend)
+            if match:
+                pos = match.start(1)
+            else:
+                pos = -1
+        else:
+            pos = string.find(text, find, selend)
+        if pos >= 0:
+            editor.setselection(pos, pos + len(find))
+            return 1
+        elif self.parms["wrap"]:
+            if self.parms["wholeword"]:
+                match = wholewordRE.search(text, 0)
+                if match:
+                    pos = match.start(1)
+                else:
+                    pos = -1
+            else:
+                pos = string.find(text, find)
+            if selstart > pos >= 0:
+                editor.setselection(pos, pos + len(find))
+                return 1
+
+    def setparms(self):
+        for key, value in self.parms.items():
+            try:
+                self.w[key].set(value)
+            except KeyError:
+                self.w.boxes[key].set(value)
+
+    def getparmsfromwindow(self):
+        if not self.w:
+            return
+        for key, value in self.parms.items():
+            try:
+                value = self.w[key].get()
+            except KeyError:
+                value = self.w.boxes[key].get()
+            self.parms[key] = value
+
+    def cancel(self):
+        self.hide()
+        self.setparms()
+
+    def hide(self):
+        if self.w:
+            self.w.wid.HideWindow()
+            self.visible = 0
+
+    def writeprefs(self):
+        import MacPrefs
+        self.getparmsfromwindow()
+        prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+        prefs.searchengine.casesens = self.parms["casesens"]
+        prefs.searchengine.wrap = self.parms["wrap"]
+        prefs.searchengine.wholeword = self.parms["wholeword"]
+        prefs.save()
+
 
 class TitledEditText(W.Group):
-	
-	def __init__(self, possize, title, text = ""):
-		W.Group.__init__(self, possize)
-		self.title = W.TextBox((0, 0, 0, 16), title)
-		self.edit = W.EditText((0, 16, 0, 0), text)
-	
-	def set(self, value):
-		self.edit.set(value)
-	
-	def get(self):
-		return self.edit.get()
+
+    def __init__(self, possize, title, text = ""):
+        W.Group.__init__(self, possize)
+        self.title = W.TextBox((0, 0, 0, 16), title)
+        self.edit = W.EditText((0, 16, 0, 0), text)
+
+    def set(self, value):
+        self.edit.set(value)
+
+    def get(self):
+        return self.edit.get()
 
 
 class ClassFinder(W.PopupWidget):
-	
-	def click(self, point, modifiers):
-		W.SetCursor("watch")
-		self.set(self._parentwindow.getclasslist())
-		W.PopupWidget.click(self, point, modifiers)
+
+    def click(self, point, modifiers):
+        W.SetCursor("watch")
+        self.set(self._parentwindow.getclasslist())
+        W.PopupWidget.click(self, point, modifiers)
 
 
 def getminindent(lines):
-	indent = -1
-	for line in lines:
-		stripped = string.strip(line)
-		if not stripped or stripped[0] == '#':
-			continue
-		if indent < 0 or line[:indent] <> indent * '\t':
-			indent = 0
-			for c in line:
-				if c <> '\t':
-					break
-				indent = indent + 1
-	return indent
+    indent = -1
+    for line in lines:
+        stripped = string.strip(line)
+        if not stripped or stripped[0] == '#':
+            continue
+        if indent < 0 or line[:indent] <> indent * '\t':
+            indent = 0
+            for c in line:
+                if c <> '\t':
+                    break
+                indent = indent + 1
+    return indent
 
 
 def getoptionkey():
-	return not not ord(Evt.GetKeys()[7]) & 0x04
+    return not not ord(Evt.GetKeys()[7]) & 0x04
 
 
-def execstring(pytext, globals, locals, filename="<string>", debugging=0, 
-			modname="__main__", profiling=0):
-	if debugging:
-		import PyDebugger, bdb
-		BdbQuit = bdb.BdbQuit
-	else:
-		BdbQuit = 'BdbQuitDummyException'
-	pytext = string.split(pytext, '\r')
-	pytext = string.join(pytext, '\n') + '\n'
-	W.SetCursor("watch")
-	globals['__name__'] = modname
-	globals['__file__'] = filename
-	sys.argv = [filename]
-	try:
-		code = compile(pytext, filename, "exec")
-	except:
-		# XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError 
-		# special. That's wrong because THIS case is special (could be literal 
-		# overflow!) and SyntaxError could mean we need a traceback (syntax error 
-		# in imported module!!!
-		tracebackwindow.traceback(1, filename)
-		return
-	try:
-		if debugging:
-			PyDebugger.startfromhere()
-		else:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(0)
-		try:
-			if profiling:
-				import profile, ProfileBrowser
-				p = profile.Profile()
-				p.set_cmd(filename)
-				try:
-					p.runctx(code, globals, locals)
-				finally:
-					import pstats
-					
-					stats = pstats.Stats(p)
-					ProfileBrowser.ProfileBrowser(stats)
-			else:
-				exec code in globals, locals
-		finally:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(-1)
-	except W.AlertError, detail:
-		raise W.AlertError, detail
-	except (KeyboardInterrupt, BdbQuit):
-		pass
-	except SystemExit, arg:
-		if arg.code:
-			sys.stderr.write("Script exited with status code: %s\n" % repr(arg.code))
-	except:
-		if debugging:
-			sys.settrace(None)
-			PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
-			return
-		else:
-			tracebackwindow.traceback(1, filename)
-	if debugging:
-		sys.settrace(None)
-		PyDebugger.stop()
+def execstring(pytext, globals, locals, filename="<string>", debugging=0,
+                        modname="__main__", profiling=0):
+    if debugging:
+        import PyDebugger, bdb
+        BdbQuit = bdb.BdbQuit
+    else:
+        BdbQuit = 'BdbQuitDummyException'
+    pytext = string.split(pytext, '\r')
+    pytext = string.join(pytext, '\n') + '\n'
+    W.SetCursor("watch")
+    globals['__name__'] = modname
+    globals['__file__'] = filename
+    sys.argv = [filename]
+    try:
+        code = compile(pytext, filename, "exec")
+    except:
+        # XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError
+        # special. That's wrong because THIS case is special (could be literal
+        # overflow!) and SyntaxError could mean we need a traceback (syntax error
+        # in imported module!!!
+        tracebackwindow.traceback(1, filename)
+        return
+    try:
+        if debugging:
+            PyDebugger.startfromhere()
+        else:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(0)
+        try:
+            if profiling:
+                import profile, ProfileBrowser
+                p = profile.Profile()
+                p.set_cmd(filename)
+                try:
+                    p.runctx(code, globals, locals)
+                finally:
+                    import pstats
+
+                    stats = pstats.Stats(p)
+                    ProfileBrowser.ProfileBrowser(stats)
+            else:
+                exec code in globals, locals
+        finally:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(-1)
+    except W.AlertError, detail:
+        raise W.AlertError, detail
+    except (KeyboardInterrupt, BdbQuit):
+        pass
+    except SystemExit, arg:
+        if arg.code:
+            sys.stderr.write("Script exited with status code: %s\n" % repr(arg.code))
+    except:
+        if debugging:
+            sys.settrace(None)
+            PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
+            return
+        else:
+            tracebackwindow.traceback(1, filename)
+    if debugging:
+        sys.settrace(None)
+        PyDebugger.stop()
 
 
 _identifieRE = re.compile(r"[A-Za-z_][A-Za-z_0-9]*")
 
 def identifieRE_match(str):
-	match = _identifieRE.match(str)
-	if not match:
-		return -1
-	return match.end()
+    match = _identifieRE.match(str)
+    if not match:
+        return -1
+    return match.end()
 
 def _filename_as_modname(fname):
-	if fname[-3:] == '.py':
-		modname = fname[:-3]
-		match = _identifieRE.match(modname)
-		if match and match.start() == 0 and match.end() == len(modname):
-			return string.join(string.split(modname, '.'), '_')
+    if fname[-3:] == '.py':
+        modname = fname[:-3]
+        match = _identifieRE.match(modname)
+        if match and match.start() == 0 and match.end() == len(modname):
+            return string.join(string.split(modname, '.'), '_')
 
 def findeditor(topwindow, fromtop = 0):
-	wid = MyFrontWindow()
-	if not fromtop:
-		if topwindow.w and wid == topwindow.w.wid:
-			wid = topwindow.w.wid.GetNextWindow()
-	if not wid:
-		return
-	app = W.getapplication()
-	if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
-		window = W.getapplication()._windows[wid]
-	else:
-		return
-	if not isinstance(window, Editor):
-		return
-	return window.editgroup.editor
+    wid = MyFrontWindow()
+    if not fromtop:
+        if topwindow.w and wid == topwindow.w.wid:
+            wid = topwindow.w.wid.GetNextWindow()
+    if not wid:
+        return
+    app = W.getapplication()
+    if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
+        window = W.getapplication()._windows[wid]
+    else:
+        return
+    if not isinstance(window, Editor):
+        return
+    return window.editgroup.editor
 
 
 class _EditorDefaultSettings:
-	
-	def __init__(self):
-		self.template = "%s, %d point"
-		self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
-		self.w = W.Dialog((328, 120), "Editor default settings")
-		self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont)
-		self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
-		
-		self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
-		self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
-		self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
-		self.w.xsize = W.EditText((98, 48, 40, 20), repr(self.windowsize[0]))
-		self.w.ysize = W.EditText((148, 48, 40, 20), repr(self.windowsize[1]))
-		
-		self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
-		self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
-		self.w.setdefaultbutton(self.w.okbutton)
-		self.w.bind('cmd.', self.w.cancelbutton.push)
-		self.w.open()
-	
-	def picksize(self):
-		app = W.getapplication()
-		editor = findeditor(self)
-		if editor is not None:
-			width, height = editor._parentwindow._bounds[2:]
-			self.w.xsize.set(repr(width))
-			self.w.ysize.set(repr(height))
-		else:
-			raise W.AlertError, "No edit window found"
-	
-	def dofont(self):
-		import FontSettings
-		settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
-		if settings:
-			self.fontsettings, self.tabsettings = settings
-			sys.exc_traceback = None
-			self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
-	
-	def close(self):
-		self.w.close()
-		del self.w
-	
-	def cancel(self):
-		self.close()
-	
-	def ok(self):
-		try:
-			width = string.atoi(self.w.xsize.get())
-		except:
-			self.w.xsize.select(1)
-			self.w.xsize.selectall()
-			raise W.AlertError, "Bad number for window width"
-		try:
-			height = string.atoi(self.w.ysize.get())
-		except:
-			self.w.ysize.select(1)
-			self.w.ysize.selectall()
-			raise W.AlertError, "Bad number for window height"
-		self.windowsize = width, height
-		seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
-		self.close()
+
+    def __init__(self):
+        self.template = "%s, %d point"
+        self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
+        self.w = W.Dialog((328, 120), "Editor default settings")
+        self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont)
+        self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
+
+        self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
+        self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
+        self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
+        self.w.xsize = W.EditText((98, 48, 40, 20), repr(self.windowsize[0]))
+        self.w.ysize = W.EditText((148, 48, 40, 20), repr(self.windowsize[1]))
+
+        self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
+        self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
+        self.w.setdefaultbutton(self.w.okbutton)
+        self.w.bind('cmd.', self.w.cancelbutton.push)
+        self.w.open()
+
+    def picksize(self):
+        app = W.getapplication()
+        editor = findeditor(self)
+        if editor is not None:
+            width, height = editor._parentwindow._bounds[2:]
+            self.w.xsize.set(repr(width))
+            self.w.ysize.set(repr(height))
+        else:
+            raise W.AlertError, "No edit window found"
+
+    def dofont(self):
+        import FontSettings
+        settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
+        if settings:
+            self.fontsettings, self.tabsettings = settings
+            sys.exc_traceback = None
+            self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
+
+    def close(self):
+        self.w.close()
+        del self.w
+
+    def cancel(self):
+        self.close()
+
+    def ok(self):
+        try:
+            width = string.atoi(self.w.xsize.get())
+        except:
+            self.w.xsize.select(1)
+            self.w.xsize.selectall()
+            raise W.AlertError, "Bad number for window width"
+        try:
+            height = string.atoi(self.w.ysize.get())
+        except:
+            self.w.ysize.select(1)
+            self.w.ysize.selectall()
+            raise W.AlertError, "Bad number for window height"
+        self.windowsize = width, height
+        seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
+        self.close()
 
 def geteditorprefs():
-	import MacPrefs
-	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-	try:
-		fontsettings = prefs.pyedit.fontsettings
-		tabsettings = prefs.pyedit.tabsettings
-		windowsize = prefs.pyedit.windowsize
-	except:
-		fontsettings = prefs.pyedit.fontsettings = ("Geneva", 0, 10, (0, 0, 0))
-		tabsettings = prefs.pyedit.tabsettings = (8, 1)
-		windowsize = prefs.pyedit.windowsize = (500, 250)
-		sys.exc_traceback = None
-	return fontsettings, tabsettings, windowsize
+    import MacPrefs
+    prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+    try:
+        fontsettings = prefs.pyedit.fontsettings
+        tabsettings = prefs.pyedit.tabsettings
+        windowsize = prefs.pyedit.windowsize
+    except:
+        fontsettings = prefs.pyedit.fontsettings = ("Geneva", 0, 10, (0, 0, 0))
+        tabsettings = prefs.pyedit.tabsettings = (8, 1)
+        windowsize = prefs.pyedit.windowsize = (500, 250)
+        sys.exc_traceback = None
+    return fontsettings, tabsettings, windowsize
 
 def seteditorprefs(fontsettings, tabsettings, windowsize):
-	import MacPrefs
-	prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
-	prefs.pyedit.fontsettings = fontsettings
-	prefs.pyedit.tabsettings = tabsettings
-	prefs.pyedit.windowsize = windowsize
-	prefs.save()
+    import MacPrefs
+    prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+    prefs.pyedit.fontsettings = fontsettings
+    prefs.pyedit.tabsettings = tabsettings
+    prefs.pyedit.windowsize = windowsize
+    prefs.save()
 
 _defaultSettingsEditor = None
 
 def EditorDefaultSettings():
-	global _defaultSettingsEditor
-	if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
-		_defaultSettingsEditor = _EditorDefaultSettings()
-	else:
-		_defaultSettingsEditor.w.select()
+    global _defaultSettingsEditor
+    if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
+        _defaultSettingsEditor = _EditorDefaultSettings()
+    else:
+        _defaultSettingsEditor.w.select()
 
 def resolvealiases(path):
-	try:
-		fsr, d1, d2 = File.FSResolveAliasFile(path, 1)
-		path = fsr.as_pathname()
-		return path
-	except (File.Error, ValueError), (error, str):
-		if error <> -120:
-			raise
-		dir, file = os.path.split(path)
-		return os.path.join(resolvealiases(dir), file)
+    try:
+        fsr, d1, d2 = File.FSResolveAliasFile(path, 1)
+        path = fsr.as_pathname()
+        return path
+    except (File.Error, ValueError), (error, str):
+        if error <> -120:
+            raise
+        dir, file = os.path.split(path)
+        return os.path.join(resolvealiases(dir), file)
 
 searchengine = SearchEngine()
 tracebackwindow = Wtraceback.TraceBack()
diff --git a/Mac/Tools/IDE/PyFontify.py b/Mac/Tools/IDE/PyFontify.py
index eb37ad3..41f1942 100644
--- a/Mac/Tools/IDE/PyFontify.py
+++ b/Mac/Tools/IDE/PyFontify.py
@@ -1,29 +1,29 @@
 """Module to analyze Python source code; for syntax coloring tools.
 
 Interface:
-	tags = fontify(pytext, searchfrom, searchto)
+        tags = fontify(pytext, searchfrom, searchto)
 
 The 'pytext' argument is a string containing Python source code.
-The (optional) arguments 'searchfrom' and 'searchto' may contain a slice in pytext. 
+The (optional) arguments 'searchfrom' and 'searchto' may contain a slice in pytext.
 The returned value is a list of tuples, formatted like this:
-	[('keyword', 0, 6, None), ('keyword', 11, 17, None), ('comment', 23, 53, None), etc. ]
+        [('keyword', 0, 6, None), ('keyword', 11, 17, None), ('comment', 23, 53, None), etc. ]
 The tuple contents are always like this:
-	(tag, startindex, endindex, sublist)
+        (tag, startindex, endindex, sublist)
 tag is one of 'keyword', 'string', 'comment' or 'identifier'
-sublist is not used, hence always None. 
+sublist is not used, hence always None.
 """
 
 # Based on FontText.py by Mitchell S. Chapman,
 # which was modified by Zachary Roadhouse,
 # then un-Tk'd by Just van Rossum.
 # Many thanks for regular expression debugging & authoring are due to:
-#	Tim (the-incredib-ly y'rs) Peters and Cristian Tismer
+#       Tim (the-incredib-ly y'rs) Peters and Cristian Tismer
 # So, who owns the copyright? ;-) How about this:
-# Copyright 1996-2001: 
-#	Mitchell S. Chapman,
-#	Zachary Roadhouse,
-#	Tim Peters,
-#	Just van Rossum
+# Copyright 1996-2001:
+#       Mitchell S. Chapman,
+#       Zachary Roadhouse,
+#       Tim Peters,
+#       Just van Rossum
 
 __version__ = "0.4"
 
@@ -33,18 +33,18 @@
 # First a little helper, since I don't like to repeat things. (Tismer speaking)
 import string
 def replace(where, what, with):
-	return string.join(string.split(where, what), with)
+    return string.join(string.split(where, what), with)
 
 # This list of keywords is taken from ref/node13.html of the
 # Python 1.3 HTML documentation. ("access" is intentionally omitted.)
 keywordsList = [
-	"assert", "exec",
-	"del", "from", "lambda", "return",
-	"and", "elif", "global", "not", "try",
-	"break", "else", "if", "or", "while",
-	"class", "except", "import", "pass",
-	"continue", "finally", "in", "print",
-	"def", "for", "is", "raise", "yield"]
+        "assert", "exec",
+        "del", "from", "lambda", "return",
+        "and", "elif", "global", "not", "try",
+        "break", "else", "if", "or", "while",
+        "class", "except", "import", "pass",
+        "continue", "finally", "in", "print",
+        "def", "for", "is", "raise", "yield"]
 
 # Build up a regular expression which will match anything
 # interesting, including multi-line triple-quoted strings.
@@ -55,24 +55,24 @@
 
 # Way to go, Tim!
 pat = r"""
-	qqq
-	[^\\q]*
-	(
-		(	\\[\000-\377]
-		|	q
-			(	\\[\000-\377]
-			|	[^\q]
-			|	q
-				(	\\[\000-\377]
-				|	[^\\q]
-				)
-			)
-		)
-		[^\\q]*
-	)*
-	qqq
+        qqq
+        [^\\q]*
+        (
+                (       \\[\000-\377]
+                |       q
+                        (       \\[\000-\377]
+                        |       [^\q]
+                        |       q
+                                (       \\[\000-\377]
+                                |       [^\\q]
+                                )
+                        )
+                )
+                [^\\q]*
+        )*
+        qqq
 """
-pat = string.join(string.split(pat), '')	# get rid of whitespace
+pat = string.join(string.split(pat), '')        # get rid of whitespace
 tripleQuotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
 
 # Build up a regular expression which matches all and only
@@ -87,69 +87,69 @@
 matchPat = commentPat + "|" + keyPat + "|" + tripleQuotePat + "|" + quotePat
 matchRE = re.compile(matchPat)
 
-idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*"	# Ident w. leading whitespace.
+idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*"      # Ident w. leading whitespace.
 idRE = re.compile(idKeyPat)
 
 
 def fontify(pytext, searchfrom = 0, searchto = None):
-	if searchto is None:
-		searchto = len(pytext)
-	# Cache a few attributes for quicker reference.
-	search = matchRE.search
-	idSearch = idRE.search
-	
-	tags = []
-	tags_append = tags.append
-	commentTag = 'comment'
-	stringTag = 'string'
-	keywordTag = 'keyword'
-	identifierTag = 'identifier'
-	
-	start = 0
-	end = searchfrom
-	while 1:
-		m = search(pytext, end)
-		if m is None:
-			break	# EXIT LOOP
-		start = m.start()
-		if start >= searchto:
-			break	# EXIT LOOP
-		match = m.group(0)
-		end = start + len(match)
-		c = match[0]
-		if c not in "#'\"":
-			# Must have matched a keyword.
-			if start <> searchfrom:
-				# there's still a redundant char before and after it, strip!
-				match = match[1:-1]
-				start = start + 1
-			else:
-				# this is the first keyword in the text.
-				# Only a space at the end.
-				match = match[:-1]
-			end = end - 1
-			tags_append((keywordTag, start, end, None))
-			# If this was a defining keyword, look ahead to the
-			# following identifier.
-			if match in ["def", "class"]:
-				m = idSearch(pytext, end)
-				if m is not None:
-					start = m.start()
-					if start == end:
-						match = m.group(0)
-						end = start + len(match)
-						tags_append((identifierTag, start, end, None))
-		elif c == "#":
-			tags_append((commentTag, start, end, None))
-		else:
-			tags_append((stringTag, start, end, None))
-	return tags
+    if searchto is None:
+        searchto = len(pytext)
+    # Cache a few attributes for quicker reference.
+    search = matchRE.search
+    idSearch = idRE.search
+
+    tags = []
+    tags_append = tags.append
+    commentTag = 'comment'
+    stringTag = 'string'
+    keywordTag = 'keyword'
+    identifierTag = 'identifier'
+
+    start = 0
+    end = searchfrom
+    while 1:
+        m = search(pytext, end)
+        if m is None:
+            break   # EXIT LOOP
+        start = m.start()
+        if start >= searchto:
+            break   # EXIT LOOP
+        match = m.group(0)
+        end = start + len(match)
+        c = match[0]
+        if c not in "#'\"":
+            # Must have matched a keyword.
+            if start <> searchfrom:
+                # there's still a redundant char before and after it, strip!
+                match = match[1:-1]
+                start = start + 1
+            else:
+                # this is the first keyword in the text.
+                # Only a space at the end.
+                match = match[:-1]
+            end = end - 1
+            tags_append((keywordTag, start, end, None))
+            # If this was a defining keyword, look ahead to the
+            # following identifier.
+            if match in ["def", "class"]:
+                m = idSearch(pytext, end)
+                if m is not None:
+                    start = m.start()
+                    if start == end:
+                        match = m.group(0)
+                        end = start + len(match)
+                        tags_append((identifierTag, start, end, None))
+        elif c == "#":
+            tags_append((commentTag, start, end, None))
+        else:
+            tags_append((stringTag, start, end, None))
+    return tags
 
 
 def test(path):
-	f = open(path)
-	text = f.read()
-	f.close()
-	tags = fontify(text)
-	for tag, start, end, sublist in tags:
-		print tag, repr(text[start:end])
+    f = open(path)
+    text = f.read()
+    f.close()
+    tags = fontify(text)
+    for tag, start, end, sublist in tags:
+        print tag, repr(text[start:end])
diff --git a/Mac/Tools/IDE/PyInteractive.py b/Mac/Tools/IDE/PyInteractive.py
index 3ad02c5..987eec5 100644
--- a/Mac/Tools/IDE/PyInteractive.py
+++ b/Mac/Tools/IDE/PyInteractive.py
@@ -4,114 +4,114 @@
 
 
 try:
-	sys.ps1
+    sys.ps1
 except AttributeError:
-	sys.ps1 = ">>> "
+    sys.ps1 = ">>> "
 try:
-	sys.ps2
+    sys.ps2
 except AttributeError:
-	sys.ps2 = "... "
+    sys.ps2 = "... "
 
 
 def print_exc(limit=None, file=None):
-	if not file:
-		file = sys.stderr
-	# we're going to skip the outermost traceback object, we don't
-	# want people to see the line which excecuted their code.
-	tb = sys.exc_traceback
-	if tb:
-		tb = tb.tb_next
-	try:
-		sys.last_type = sys.exc_type
-		sys.last_value = sys.exc_value
-		sys.last_traceback = tb
-		traceback.print_exception(sys.last_type, sys.last_value, 
-					sys.last_traceback, limit, file)
-	except:
-		print '--- hola! ---'
-		traceback.print_exception(sys.exc_type, sys.exc_value, 
-					sys.exc_traceback, limit, file)
+    if not file:
+        file = sys.stderr
+    # we're going to skip the outermost traceback object, we don't
+    # want people to see the line which excecuted their code.
+    tb = sys.exc_traceback
+    if tb:
+        tb = tb.tb_next
+    try:
+        sys.last_type = sys.exc_type
+        sys.last_value = sys.exc_value
+        sys.last_traceback = tb
+        traceback.print_exception(sys.last_type, sys.last_value,
+                                sys.last_traceback, limit, file)
+    except:
+        print '--- hola! ---'
+        traceback.print_exception(sys.exc_type, sys.exc_value,
+                                sys.exc_traceback, limit, file)
 
 
 class PyInteractive:
-	
-	def __init__(self):
-		import codeop
-		self._pybuf = ""
-		self._compile = codeop.Compile()
-	
-	def executeline(self, stuff, out = None, env = None):
-		if env is None:
-			import __main__
-			env = __main__.__dict__
-		if out:
-			saveerr, saveout = sys.stderr, sys.stdout
-			sys.stderr = sys.stdout = out
-		try:
-			if self._pybuf:
-				self._pybuf = self._pybuf + '\n' + stuff
-			else:
-				self._pybuf = stuff
-			
-			# Compile three times: as is, with \n, and with \n\n appended.
-			# If it compiles as is, it's complete.  If it compiles with
-			# one \n appended, we expect more.  If it doesn't compile
-			# either way, we compare the error we get when compiling with
-			# \n or \n\n appended.  If the errors are the same, the code
-			# is broken.  But if the errors are different, we expect more.
-			# Not intuitive; not even guaranteed to hold in future
-			# releases; but this matches the compiler's behavior in Python
-			# 1.4 and 1.5.
-			err = err1 = err2 = None
-			code = code1 = code2 = None
-			
-			# quickly get out of here when the line is 'empty' or is a comment
-			stripped = string.strip(self._pybuf)
-			if not stripped or stripped[0] == '#':
-				self._pybuf = ''
-				sys.stdout.write(sys.ps1)
-				sys.stdout.flush()
-				return
-			
-			try:
-				code = self._compile(self._pybuf, "<input>", "single")
-			except SyntaxError, err:
-				pass
-			except:
-				# OverflowError. More?
-				print_exc()
-				self._pybuf = ""
-				sys.stdout.write(sys.ps1)
-				sys.stdout.flush()
-				return
-			
-			try:
-				code1 = self._compile(self._pybuf + "\n", "<input>", "single")
-			except SyntaxError, err1:
-				pass
-			
-			try:
-				code2 = self._compile(self._pybuf + "\n\n", "<input>", "single")
-			except SyntaxError, err2:
-				pass
-			
-			if code:
-				try:
-					exec code in env
-				except:
-					print_exc()
-				self._pybuf = ""
-			elif code1:
-				pass
-			elif err1 == err2 or (not stuff and self._pybuf):
-				print_exc()
-				self._pybuf = ""
-			if self._pybuf:
-				sys.stdout.write(sys.ps2)
-				sys.stdout.flush()
-			else:
-				sys.stdout.write(sys.ps1)
-				sys.stdout.flush()
-		finally:
-			if out:
-				sys.stderr, sys.stdout = saveerr, saveout
+
+    def __init__(self):
+        import codeop
+        self._pybuf = ""
+        self._compile = codeop.Compile()
+
+    def executeline(self, stuff, out = None, env = None):
+        if env is None:
+            import __main__
+            env = __main__.__dict__
+        if out:
+            saveerr, saveout = sys.stderr, sys.stdout
+            sys.stderr = sys.stdout = out
+        try:
+            if self._pybuf:
+                self._pybuf = self._pybuf + '\n' + stuff
+            else:
+                self._pybuf = stuff
+
+            # Compile three times: as is, with \n, and with \n\n appended.
+            # If it compiles as is, it's complete.  If it compiles with
+            # one \n appended, we expect more.  If it doesn't compile
+            # either way, we compare the error we get when compiling with
+            # \n or \n\n appended.  If the errors are the same, the code
+            # is broken.  But if the errors are different, we expect more.
+            # Not intuitive; not even guaranteed to hold in future
+            # releases; but this matches the compiler's behavior in Python
+            # 1.4 and 1.5.
+            err = err1 = err2 = None
+            code = code1 = code2 = None
+
+            # quickly get out of here when the line is 'empty' or is a comment
+            stripped = string.strip(self._pybuf)
+            if not stripped or stripped[0] == '#':
+                self._pybuf = ''
+                sys.stdout.write(sys.ps1)
+                sys.stdout.flush()
+                return
+
+            try:
+                code = self._compile(self._pybuf, "<input>", "single")
+            except SyntaxError, err:
+                pass
+            except:
+                # OverflowError. More?
+                print_exc()
+                self._pybuf = ""
+                sys.stdout.write(sys.ps1)
+                sys.stdout.flush()
+                return
+
+            try:
+                code1 = self._compile(self._pybuf + "\n", "<input>", "single")
+            except SyntaxError, err1:
+                pass
+
+            try:
+                code2 = self._compile(self._pybuf + "\n\n", "<input>", "single")
+            except SyntaxError, err2:
+                pass
+
+            if code:
+                try:
+                    exec code in env
+                except:
+                    print_exc()
+                self._pybuf = ""
+            elif code1:
+                pass
+            elif err1 == err2 or (not stuff and self._pybuf):
+                print_exc()
+                self._pybuf = ""
+            if self._pybuf:
+                sys.stdout.write(sys.ps2)
+                sys.stdout.flush()
+            else:
+                sys.stdout.write(sys.ps1)
+                sys.stdout.flush()
+        finally:
+            if out:
+                sys.stderr, sys.stdout = saveerr, saveout
diff --git a/Mac/Tools/IDE/PythonIDE.py b/Mac/Tools/IDE/PythonIDE.py
index 1ea7711..b8f54a9 100644
--- a/Mac/Tools/IDE/PythonIDE.py
+++ b/Mac/Tools/IDE/PythonIDE.py
@@ -1,6 +1,6 @@
 # copyright 1996-2001 Just van Rossum, Letterror. just@letterror.com
 
-# keep this (__main__) as clean as possible, since we are using 
+# keep this (__main__) as clean as possible, since we are using
 # it like the "normal" interpreter.
 
 __version__ = '1.0.2'
@@ -8,48 +8,48 @@
 import os
 
 def init():
-	import MacOS
-	if hasattr(MacOS, 'EnableAppswitch'):
-		MacOS.EnableAppswitch(-1)
-	
-	try:
-		import autoGIL
-	except ImportError:
-		pass
-	else:
-		autoGIL.installAutoGIL()
-	
-	from Carbon import Qd, QuickDraw
-	Qd.SetCursor(Qd.GetCursor(QuickDraw.watchCursor).data)
-	
-	import macresource
-	import sys, os
-	macresource.need('DITL', 468, "PythonIDE.rsrc")
-	widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
-	widgetresfile = os.path.join(*widgetrespathsegs)
-	if not os.path.exists(widgetresfile):
-		widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
-		widgetresfile = os.path.join(*widgetrespathsegs)
-	refno = macresource.need('CURS', 468, widgetresfile)
-	if os.environ.has_key('PYTHONIDEPATH'):
-		# For development set this environment variable
-		ide_path = os.environ['PYTHONIDEPATH']
-	elif refno:
-		# We're not a fullblown application
-		idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
-		ide_path = os.path.join(*idepathsegs)
-		if not os.path.exists(ide_path):
-			idepathsegs = [os.pardir, "Tools", "IDE"]
-			for p in sys.path:
-				ide_path = os.path.join(*([p]+idepathsegs))
-				if os.path.exists(ide_path):
-					break
-		
-	else:
-		# We are a fully frozen application
-		ide_path = sys.argv[0]
-	if ide_path not in sys.path:
-		sys.path.insert(1, ide_path)
+    import MacOS
+    if hasattr(MacOS, 'EnableAppswitch'):
+        MacOS.EnableAppswitch(-1)
+
+    try:
+        import autoGIL
+    except ImportError:
+        pass
+    else:
+        autoGIL.installAutoGIL()
+
+    from Carbon import Qd, QuickDraw
+    Qd.SetCursor(Qd.GetCursor(QuickDraw.watchCursor).data)
+
+    import macresource
+    import sys, os
+    macresource.need('DITL', 468, "PythonIDE.rsrc")
+    widgetrespathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE", "Widgets.rsrc"]
+    widgetresfile = os.path.join(*widgetrespathsegs)
+    if not os.path.exists(widgetresfile):
+        widgetrespathsegs = [os.pardir, "Tools", "IDE", "Widgets.rsrc"]
+        widgetresfile = os.path.join(*widgetrespathsegs)
+    refno = macresource.need('CURS', 468, widgetresfile)
+    if os.environ.has_key('PYTHONIDEPATH'):
+        # For development set this environment variable
+        ide_path = os.environ['PYTHONIDEPATH']
+    elif refno:
+        # We're not a fullblown application
+        idepathsegs = [sys.exec_prefix, "Mac", "Tools", "IDE"]
+        ide_path = os.path.join(*idepathsegs)
+        if not os.path.exists(ide_path):
+            idepathsegs = [os.pardir, "Tools", "IDE"]
+            for p in sys.path:
+                ide_path = os.path.join(*([p]+idepathsegs))
+                if os.path.exists(ide_path):
+                    break
+
+    else:
+        # We are a fully frozen application
+        ide_path = sys.argv[0]
+    if ide_path not in sys.path:
+        sys.path.insert(1, ide_path)
 
 
 init()
diff --git a/Mac/Tools/IDE/PythonIDEMain.py b/Mac/Tools/IDE/PythonIDEMain.py
index 111a0b0..4dbe92a 100644
--- a/Mac/Tools/IDE/PythonIDEMain.py
+++ b/Mac/Tools/IDE/PythonIDEMain.py
@@ -13,476 +13,476 @@
 from Carbon import Files
 
 if MacOS.runtimemodel == 'macho':
-	ELLIPSIS = '...'
+    ELLIPSIS = '...'
 else:
-	ELLIPSIS = '\xc9'
+    ELLIPSIS = '\xc9'
 
 def runningOnOSX():
-	from gestalt import gestalt
-	gestaltMenuMgrAquaLayoutBit = 1  # menus have the Aqua 1.0 layout
-	gestaltMenuMgrAquaLayoutMask = (1L << gestaltMenuMgrAquaLayoutBit)
-	value = gestalt("menu") & gestaltMenuMgrAquaLayoutMask
-	return not not value
+    from gestalt import gestalt
+    gestaltMenuMgrAquaLayoutBit = 1  # menus have the Aqua 1.0 layout
+    gestaltMenuMgrAquaLayoutMask = (1L << gestaltMenuMgrAquaLayoutBit)
+    value = gestalt("menu") & gestaltMenuMgrAquaLayoutMask
+    return not not value
 
 def getmodtime(file):
-	file = File.FSRef(file)
-	catinfo, d1, d2, d3 = file.FSGetCatalogInfo(Files.kFSCatInfoContentMod)
-	return catinfo.contentModDate
+    file = File.FSRef(file)
+    catinfo, d1, d2, d3 = file.FSGetCatalogInfo(Files.kFSCatInfoContentMod)
+    return catinfo.contentModDate
 
 class PythonIDE(Wapplication.Application):
-	
-	def __init__(self):
-		if sys.platform == "darwin":
-			if len(sys.argv) > 1 and sys.argv[1].startswith("-psn"):
-				home = os.getenv("HOME")
-				if home:
-					os.chdir(home)
-		self.preffilepath = os.path.join("Python", "PythonIDE preferences")
-		Wapplication.Application.__init__(self, 'Pide')
-		from Carbon import AE
-		from Carbon import AppleEvents
-		
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments, 
-				self.ignoreevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenDocuments, 
-				self.opendocsevent)
-		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication, 
-				self.quitevent)
-		import PyConsole, PyEdit
-		Splash.wait()
-		# With -D option (OSX command line only) keep stderr, for debugging the IDE
-		# itself.
-		debug_stderr = None
-		if len(sys.argv) >= 2 and sys.argv[1] == '-D':
-			debug_stderr = sys.stderr
-			del sys.argv[1]
-		PyConsole.installoutput()
-		PyConsole.installconsole()
-		if debug_stderr:
-			sys.stderr = debug_stderr
-		for path in sys.argv[1:]:
-			if path.startswith("-p"):
-				# process number added by the OS
-				continue
-			self.opendoc(path)
-		self.mainloop()
-	
-	def makeusermenus(self):
-		m = Wapplication.Menu(self.menubar, "File")
-		newitem = FrameWork.MenuItem(m, "New", "N", 'new')
-		openitem = FrameWork.MenuItem(m, "Open"+ELLIPSIS, "O", 'open')
-		openbynameitem = FrameWork.MenuItem(m, "Open File by Name"+ELLIPSIS, "D", 'openbyname')
-		self.openrecentmenu = FrameWork.SubMenu(m, "Open Recent")
-		self.makeopenrecentmenu()
-		FrameWork.Separator(m)
-		closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
-		saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
-		saveasitem = FrameWork.MenuItem(m, "Save as"+ELLIPSIS, None, 'save_as')
-		FrameWork.Separator(m)
-		saveasappletitem = FrameWork.MenuItem(m, "Save as Applet"+ELLIPSIS, None, 'save_as_applet')
-		FrameWork.Separator(m)
-		instmgritem = FrameWork.MenuItem(m, "Package Manager", None, 'openpackagemanager')
-		gensuiteitem = FrameWork.MenuItem(m, "Generate OSA Suite...", None, 'gensuite')
-		if not runningOnOSX():
-			# On OSX there's a special "magic" quit menu, so we shouldn't add
-			# it to the File menu.
-			FrameWork.Separator(m)
-			quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit')
-		
-		m = Wapplication.Menu(self.menubar, "Edit")
-		undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
-		FrameWork.Separator(m)
-		cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
-		copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
-		pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
-		FrameWork.MenuItem(m, "Clear", None,  "clear")
-		FrameWork.Separator(m)
-		selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
-		sellineitem = FrameWork.MenuItem(m, "Select line", "L", "selectline")
-		FrameWork.Separator(m)
-		finditem = FrameWork.MenuItem(m, "Find"+ELLIPSIS, "F", "find")
-		findagainitem = FrameWork.MenuItem(m, "Find again", 'G', "findnext")
-		enterselitem = FrameWork.MenuItem(m, "Enter search string", "E", "entersearchstring")
-		replaceitem = FrameWork.MenuItem(m, "Replace", None, "replace")
-		replacefinditem = FrameWork.MenuItem(m, "Replace & find again", 'T', "replacefind")
-		FrameWork.Separator(m)
-		shiftleftitem = FrameWork.MenuItem(m, "Shift left", "[", "shiftleft")
-		shiftrightitem = FrameWork.MenuItem(m, "Shift right", "]", "shiftright")
-		
-		m = Wapplication.Menu(self.menubar, "Python")
-		runitem = FrameWork.MenuItem(m, "Run window", "R", 'run')
-		runselitem = FrameWork.MenuItem(m, "Run selection", None, 'runselection')
-		FrameWork.Separator(m)
-		moditem = FrameWork.MenuItem(m, "Module browser"+ELLIPSIS, "M", self.domenu_modulebrowser)
-		FrameWork.Separator(m)
-		mm = FrameWork.SubMenu(m, "Preferences")
-		FrameWork.MenuItem(mm, "Set Scripts folder"+ELLIPSIS, None, self.do_setscriptsfolder)
-		FrameWork.MenuItem(mm, "Editor default settings"+ELLIPSIS, None, self.do_editorprefs)
-		FrameWork.MenuItem(mm, "Set default window font"+ELLIPSIS, None, self.do_setwindowfont)
-		
-		self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
-		self.makeopenwindowsmenu()
-		self._menustocheck = [closeitem, saveitem, saveasitem, saveasappletitem,
-				undoitem, cutitem, copyitem, pasteitem, 
-				selallitem, sellineitem, 
-				finditem, findagainitem, enterselitem, replaceitem, replacefinditem,
-				shiftleftitem, shiftrightitem, 
-				runitem, runselitem]
-		
-		prefs = self.getprefs()
-		try:
-			fsr, d = File.Alias(rawdata=prefs.scriptsfolder).FSResolveAlias(None)
-			self.scriptsfolder = fsr.FSNewAliasMinimal()
-		except:
-			path = os.path.join(os.getcwd(), "Mac", "IDE scripts")
-			if not os.path.exists(path):
-				if sys.platform == "darwin":
-					path = os.path.join(os.getenv("HOME"), "Library", "Python", "IDE-Scripts")
-				else:
-					path = os.path.join(os.getcwd(), "Scripts")
-				if not os.path.exists(path):
-					os.makedirs(path)
-					f = open(os.path.join(path, "Place your scripts here"+ELLIPSIS), "w")
-					f.close()
-			fsr = File.FSRef(path)
-			self.scriptsfolder = fsr.FSNewAliasMinimal()
-			self.scriptsfoldermodtime = getmodtime(fsr)
-		else:
-			self.scriptsfoldermodtime = getmodtime(fsr)
-		prefs.scriptsfolder = self.scriptsfolder.data
-		self._scripts = {}
-		self.scriptsmenu = None
-		self.makescriptsmenu()
-		self.makehelpmenu()
-	
-	def quitevent(self, theAppleEvent, theReply):
-		self._quit()
-	
-	def suspendresume(self, onoff):
-		if onoff:
-			fsr, changed = self.scriptsfolder.FSResolveAlias(None)
-			modtime = getmodtime(fsr)
-			if self.scriptsfoldermodtime <> modtime or changed:
-				self.scriptsfoldermodtime = modtime
-				W.SetCursor('watch')
-				self.makescriptsmenu()
-	
-	def ignoreevent(self, theAppleEvent, theReply):
-		pass
-	
-	def opendocsevent(self, theAppleEvent, theReply):
-		W.SetCursor('watch')
-		import aetools
-		parameters, args = aetools.unpackevent(theAppleEvent)
-		docs = parameters['----']
-		if type(docs) <> type([]):
-			docs = [docs]
-		for doc in docs:
-			fsr, a = doc.FSResolveAlias(None)
-			path = fsr.as_pathname()
-			self.opendoc(path)
-	
-	def opendoc(self, path):
-		fcreator, ftype = MacOS.GetCreatorAndType(path)
-		if ftype == 'TEXT':
-			self.openscript(path)
-		elif ftype == '\0\0\0\0' and path[-3:] == '.py':
-			self.openscript(path)
-		else:
-			W.Message("Can't open file of type '%s'." % ftype)
-	
-	def getabouttext(self):
-		return "About Python IDE"+ELLIPSIS
-	
-	def do_about(self, id, item, window, event):
-		Splash.about()
-	
-	def do_setscriptsfolder(self, *args):
-		fsr = EasyDialogs.AskFolder(message="Select Scripts Folder",
-			wanted=File.FSRef)
-		if fsr:
-			prefs = self.getprefs()
-			alis = fsr.FSNewAliasMinimal()
-			prefs.scriptsfolder = alis.data
-			self.scriptsfolder = alis
-			self.makescriptsmenu()
-			prefs.save()
-	
-	def domenu_modulebrowser(self, *args):
-		W.SetCursor('watch')
-		import ModuleBrowser
-		ModuleBrowser.ModuleBrowser()
-	
-	def domenu_open(self, *args):
-		filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
-		if filename:
-			self.openscript(filename)
-	
-	def domenu_openbyname(self, *args):
-		# Open a file by name. If the clipboard contains a filename
-		# use that as the default.
-		from Carbon import Scrap
-		try:
-			sc = Scrap.GetCurrentScrap()
-			dft = sc.GetScrapFlavorData("TEXT")
-		except Scrap.Error:
-			dft = ""
-		else:
-			if not os.path.exists(dft):
-				dft = ""
-		filename = EasyDialogs.AskString("Open File Named:", default=dft, ok="Open")
-		if filename:
-			self.openscript(filename)
-	
-	def domenu_new(self, *args):
-		W.SetCursor('watch')
-		import PyEdit
-		return PyEdit.Editor()
-	
-	def makescriptsmenu(self):
-		W.SetCursor('watch')
-		if self._scripts:
-			for id, item in self._scripts.keys():
-				if self.menubar.menus.has_key(id):
-					m = self.menubar.menus[id]
-					m.delete()
-			self._scripts = {}
-		if self.scriptsmenu:
-			if hasattr(self.scriptsmenu, 'id') and self.menubar.menus.has_key(self.scriptsmenu.id):
-				self.scriptsmenu.delete()
-		self.scriptsmenu = FrameWork.Menu(self.menubar, "Scripts")
-		#FrameWork.MenuItem(self.scriptsmenu, "New script", None, self.domenu_new)
-		#self.scriptsmenu.addseparator()
-		fsr, d1 = self.scriptsfolder.FSResolveAlias(None)
-		self.scriptswalk(fsr.as_pathname(), self.scriptsmenu)
-	
-	def makeopenwindowsmenu(self):
-		for i in range(len(self.openwindowsmenu.items)):
-			self.openwindowsmenu.menu.DeleteMenuItem(1)
-			self.openwindowsmenu.items = []
-		windows = []
-		self._openwindows = {}
-		for window in self._windows.keys():
-			title = window.GetWTitle()
-			if not title:
-				title = "<no title>"
-			windows.append((title, window))
-		windows.sort()
-		for title, window in windows:
-			if title == "Python Interactive":	# ugly but useful hack by Joe Strout
-				shortcut = '0'
-			else: 
-				shortcut = None
-			item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
-			self._openwindows[item.item] = window
-		self._openwindowscheckmark = 0
-		self.checkopenwindowsmenu()
-		
-	def makeopenrecentmenu(self):
-		for i in range(len(self.openrecentmenu.items)):
-			self.openrecentmenu.menu.DeleteMenuItem(1)
-			self.openrecentmenu.items = []
-		prefs = self.getprefs()
-		filelist = prefs.recentfiles
-		if not filelist:
-			self.openrecentmenu.enable(0)
-			return
-		self.openrecentmenu.enable(1)
-		for filename in filelist:
-			item = FrameWork.MenuItem(self.openrecentmenu, filename, None, callback = self.domenu_openrecent)
-		
-	def addrecentfile(self, file):
-		prefs = self.getprefs()
-		filelist = prefs.recentfiles
-		if not filelist:
-			filelist = []
-		
-		if file in filelist:
-			if file == filelist[0]:
-				return
-			filelist.remove(file)
-		filelist.insert(0, file)
-		filelist = filelist[:10]
-		prefs.recentfiles = filelist
-		prefs.save()
-		self.makeopenrecentmenu()
-		
-	def domenu_openwindows(self, id, item, window, event):
-		w = self._openwindows[item]
-		w.ShowWindow()
-		w.SelectWindow()
-	
-	def domenu_openrecent(self, id, item, window, event):
-		prefs = self.getprefs()
-		filelist = prefs.recentfiles
-		if not filelist:
-			filelist = []
-		item = item - 1
-		filename = filelist[item]
-		self.openscript(filename)
-	
-	def domenu_quit(self):
-		self._quit()
-	
-	def domenu_save(self, *args):
-		print "Save"
-	
-	def _quit(self):
-		import PyConsole, PyEdit
-		for window in self._windows.values():
-			try:
-				rv = window.close() # ignore any errors while quitting
-			except:
-				rv = 0   # (otherwise, we can get stuck!)
-			if rv and rv > 0:
-				return
-		try:
-			PyConsole.console.writeprefs()
-			PyConsole.output.writeprefs()
-			PyEdit.searchengine.writeprefs()
-		except:
-			# Write to __stderr__ so the msg end up in Console.app and has
-			# at least _some_ chance of getting read...
-			# But: this is a workaround for way more serious problems with
-			# the Python 2.2 Jaguar addon.
-			sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
-		self.quitting = 1
-		
-	def domenu_openpackagemanager(self):
-		import PackageManager
-		PackageManager.PackageBrowser()
-		
-	def domenu_gensuite(self):
-		import gensuitemodule
-		gensuitemodule.main_interactive()
-		
-	def makehelpmenu(self):
-		hashelp, hasdocs = self.installdocumentation()
-		self.helpmenu = m = self.gethelpmenu()
-		helpitem = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_localhelp)
-		helpitem.enable(hashelp)
-		docitem = FrameWork.MenuItem(m, "Python Documentation", None, self.domenu_localdocs)
-		docitem.enable(hasdocs)
-		finditem = FrameWork.MenuItem(m, "Lookup in Python Documentation", None, 'lookuppython')
-		finditem.enable(hasdocs)
-		if runningOnOSX():
-			FrameWork.Separator(m)
-			doc2item = FrameWork.MenuItem(m, "Apple Developer Documentation", None, self.domenu_appledocs)
-			find2item = FrameWork.MenuItem(m, "Lookup in Carbon Documentation", None, 'lookupcarbon')
-		FrameWork.Separator(m)
-		webitem = FrameWork.MenuItem(m, "Python Documentation on the Web", None, self.domenu_webdocs)
-		web2item = FrameWork.MenuItem(m, "Python on the Web", None, self.domenu_webpython)
-		web3item = FrameWork.MenuItem(m, "MacPython on the Web", None, self.domenu_webmacpython)
-		
-	def domenu_localdocs(self, *args):
-		from Carbon import AH
-		AH.AHGotoPage("Python Documentation", None, None)
-		
-	def domenu_localhelp(self, *args):
-		from Carbon import AH
-		AH.AHGotoPage("MacPython Help", None, None)
-		
-	def domenu_appledocs(self, *args):
-		from Carbon import AH, AppleHelp
-		try:
-			AH.AHGotoMainTOC(AppleHelp.kAHTOCTypeDeveloper)
-		except AH.Error, arg:
-			if arg[0] == -50:
-				W.Message("Developer documentation not installed")
-			else:
-				W.Message("AppleHelp Error: %r" % (arg,))
-		
-	def domenu_lookuppython(self, *args):
-		from Carbon import AH
-		searchstring = self._getsearchstring()
-		if not searchstring:
-			return
-		try:
-			AH.AHSearch("Python Documentation", searchstring)
-		except AH.Error, arg:
-			W.Message("AppleHelp Error: %r" % (arg,))
-			
-	def domenu_lookupcarbon(self, *args):
-		from Carbon import AH
-		searchstring = self._getsearchstring()
-		if not searchstring:
-			return
-		try:
-			AH.AHSearch("Carbon", searchstring)
-		except AH.Error, arg:
-			W.Message("AppleHelp Error: %r" % (arg,))
-			
-	def _getsearchstring(self):
-		# First we get the frontmost window
-		front = self.getfrontwindow()
-		if front and hasattr(front, 'getselectedtext'):
-			text = front.getselectedtext()
-			if text:
-				return text
-		# This is a cop-out. We should have disabled the menus
-		# if there is no selection, but the can_ methods only seem
-		# to work for Windows. Or not for the Help menu, maybe?
-		text = EasyDialogs.AskString("Search documentation for", ok="Search")
-		return text
-		
-	def domenu_webdocs(self, *args):
-		import webbrowser
-		major, minor, micro, state, nano = sys.version_info
-		if state in ('alpha', 'beta'):
-			docversion = 'dev/doc/devel'
-		elif micro == 0:
-			docversion = 'doc/%d.%d' % (major, minor)
-		else:
-			docversion = 'doc/%d.%d.%d' % (major, minor, micro)
-		webbrowser.open("http://www.python.org/%s" % docversion)
-		
-	def domenu_webpython(self, *args):
-		import webbrowser
-		webbrowser.open("http://www.python.org/")
-		
-	def domenu_webmacpython(self, *args):
-		import webbrowser
-		webbrowser.open("http://www.cwi.nl/~jack/macpython.html")
-		
-	def installdocumentation(self):
-		# This is rather much of a hack. Someone has to tell the Help Viewer
-		# about the Python documentation, so why not us. The documentation
-		# is located in the framework, but there's a symlink in Python.app.
-		# And as AHRegisterHelpBook wants a bundle (with the right bits in
-		# the plist file) we refer it to Python.app
-		#
-		# To make matters worse we have to look in two places: first in the IDE
-		# itself, then in the Python application inside the framework.
-		has_help = False
-		has_doc = False
-		ide_path_components = sys.argv[0].split("/")
-		if ide_path_components[-3:] == ["Contents", "Resources", "PythonIDE.py"]:
-			ide_app = "/".join(ide_path_components[:-3])
-			help_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/Documentation')
-			doc_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/PythonDocumentation')
-			has_help = os.path.isdir(help_source)
-			has_doc = os.path.isdir(doc_source)
-			if has_help or has_doc:
-				try:
-					from Carbon import AH
-					AH.AHRegisterHelpBook(ide_app)
-				except (ImportError, MacOS.Error), arg:
-					pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
-		python_app = os.path.join(sys.prefix, 'Resources/Python.app')
-		if not has_help:
-			help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
-			has_help = os.path.isdir(help_source)
-		if not has_doc:
-			doc_source = os.path.join(python_app, 'Contents/Resources/English.lproj/PythonDocumentation')
-			has_doc = os.path.isdir(doc_source)
-		if has_help or has_doc:
-			try:
-				from Carbon import AH
-				AH.AHRegisterHelpBook(python_app)
-			except (ImportError, MacOS.Error), arg:
-				pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
-		return has_help, has_doc
+
+    def __init__(self):
+        if sys.platform == "darwin":
+            if len(sys.argv) > 1 and sys.argv[1].startswith("-psn"):
+                home = os.getenv("HOME")
+                if home:
+                    os.chdir(home)
+        self.preffilepath = os.path.join("Python", "PythonIDE preferences")
+        Wapplication.Application.__init__(self, 'Pide')
+        from Carbon import AE
+        from Carbon import AppleEvents
+
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEReopenApplication,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments,
+                        self.ignoreevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenDocuments,
+                        self.opendocsevent)
+        AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication,
+                        self.quitevent)
+        import PyConsole, PyEdit
+        Splash.wait()
+        # With -D option (OSX command line only) keep stderr, for debugging the IDE
+        # itself.
+        debug_stderr = None
+        if len(sys.argv) >= 2 and sys.argv[1] == '-D':
+            debug_stderr = sys.stderr
+            del sys.argv[1]
+        PyConsole.installoutput()
+        PyConsole.installconsole()
+        if debug_stderr:
+            sys.stderr = debug_stderr
+        for path in sys.argv[1:]:
+            if path.startswith("-p"):
+                # process number added by the OS
+                continue
+            self.opendoc(path)
+        self.mainloop()
+
+    def makeusermenus(self):
+        m = Wapplication.Menu(self.menubar, "File")
+        newitem = FrameWork.MenuItem(m, "New", "N", 'new')
+        openitem = FrameWork.MenuItem(m, "Open"+ELLIPSIS, "O", 'open')
+        openbynameitem = FrameWork.MenuItem(m, "Open File by Name"+ELLIPSIS, "D", 'openbyname')
+        self.openrecentmenu = FrameWork.SubMenu(m, "Open Recent")
+        self.makeopenrecentmenu()
+        FrameWork.Separator(m)
+        closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
+        saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
+        saveasitem = FrameWork.MenuItem(m, "Save as"+ELLIPSIS, None, 'save_as')
+        FrameWork.Separator(m)
+        saveasappletitem = FrameWork.MenuItem(m, "Save as Applet"+ELLIPSIS, None, 'save_as_applet')
+        FrameWork.Separator(m)
+        instmgritem = FrameWork.MenuItem(m, "Package Manager", None, 'openpackagemanager')
+        gensuiteitem = FrameWork.MenuItem(m, "Generate OSA Suite...", None, 'gensuite')
+        if not runningOnOSX():
+            # On OSX there's a special "magic" quit menu, so we shouldn't add
+            # it to the File menu.
+            FrameWork.Separator(m)
+            quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit')
+
+        m = Wapplication.Menu(self.menubar, "Edit")
+        undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
+        FrameWork.Separator(m)
+        cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
+        copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
+        pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
+        FrameWork.MenuItem(m, "Clear", None,  "clear")
+        FrameWork.Separator(m)
+        selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")
+        sellineitem = FrameWork.MenuItem(m, "Select line", "L", "selectline")
+        FrameWork.Separator(m)
+        finditem = FrameWork.MenuItem(m, "Find"+ELLIPSIS, "F", "find")
+        findagainitem = FrameWork.MenuItem(m, "Find again", 'G', "findnext")
+        enterselitem = FrameWork.MenuItem(m, "Enter search string", "E", "entersearchstring")
+        replaceitem = FrameWork.MenuItem(m, "Replace", None, "replace")
+        replacefinditem = FrameWork.MenuItem(m, "Replace & find again", 'T', "replacefind")
+        FrameWork.Separator(m)
+        shiftleftitem = FrameWork.MenuItem(m, "Shift left", "[", "shiftleft")
+        shiftrightitem = FrameWork.MenuItem(m, "Shift right", "]", "shiftright")
+
+        m = Wapplication.Menu(self.menubar, "Python")
+        runitem = FrameWork.MenuItem(m, "Run window", "R", 'run')
+        runselitem = FrameWork.MenuItem(m, "Run selection", None, 'runselection')
+        FrameWork.Separator(m)
+        moditem = FrameWork.MenuItem(m, "Module browser"+ELLIPSIS, "M", self.domenu_modulebrowser)
+        FrameWork.Separator(m)
+        mm = FrameWork.SubMenu(m, "Preferences")
+        FrameWork.MenuItem(mm, "Set Scripts folder"+ELLIPSIS, None, self.do_setscriptsfolder)
+        FrameWork.MenuItem(mm, "Editor default settings"+ELLIPSIS, None, self.do_editorprefs)
+        FrameWork.MenuItem(mm, "Set default window font"+ELLIPSIS, None, self.do_setwindowfont)
+
+        self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows')
+        self.makeopenwindowsmenu()
+        self._menustocheck = [closeitem, saveitem, saveasitem, saveasappletitem,
+                        undoitem, cutitem, copyitem, pasteitem,
+                        selallitem, sellineitem,
+                        finditem, findagainitem, enterselitem, replaceitem, replacefinditem,
+                        shiftleftitem, shiftrightitem,
+                        runitem, runselitem]
+
+        prefs = self.getprefs()
+        try:
+            fsr, d = File.Alias(rawdata=prefs.scriptsfolder).FSResolveAlias(None)
+            self.scriptsfolder = fsr.FSNewAliasMinimal()
+        except:
+            path = os.path.join(os.getcwd(), "Mac", "IDE scripts")
+            if not os.path.exists(path):
+                if sys.platform == "darwin":
+                    path = os.path.join(os.getenv("HOME"), "Library", "Python", "IDE-Scripts")
+                else:
+                    path = os.path.join(os.getcwd(), "Scripts")
+                if not os.path.exists(path):
+                    os.makedirs(path)
+                    f = open(os.path.join(path, "Place your scripts here"+ELLIPSIS), "w")
+                    f.close()
+            fsr = File.FSRef(path)
+            self.scriptsfolder = fsr.FSNewAliasMinimal()
+            self.scriptsfoldermodtime = getmodtime(fsr)
+        else:
+            self.scriptsfoldermodtime = getmodtime(fsr)
+        prefs.scriptsfolder = self.scriptsfolder.data
+        self._scripts = {}
+        self.scriptsmenu = None
+        self.makescriptsmenu()
+        self.makehelpmenu()
+
+    def quitevent(self, theAppleEvent, theReply):
+        self._quit()
+
+    def suspendresume(self, onoff):
+        if onoff:
+            fsr, changed = self.scriptsfolder.FSResolveAlias(None)
+            modtime = getmodtime(fsr)
+            if self.scriptsfoldermodtime <> modtime or changed:
+                self.scriptsfoldermodtime = modtime
+                W.SetCursor('watch')
+                self.makescriptsmenu()
+
+    def ignoreevent(self, theAppleEvent, theReply):
+        pass
+
+    def opendocsevent(self, theAppleEvent, theReply):
+        W.SetCursor('watch')
+        import aetools
+        parameters, args = aetools.unpackevent(theAppleEvent)
+        docs = parameters['----']
+        if type(docs) <> type([]):
+            docs = [docs]
+        for doc in docs:
+            fsr, a = doc.FSResolveAlias(None)
+            path = fsr.as_pathname()
+            self.opendoc(path)
+
+    def opendoc(self, path):
+        fcreator, ftype = MacOS.GetCreatorAndType(path)
+        if ftype == 'TEXT':
+            self.openscript(path)
+        elif ftype == '\0\0\0\0' and path[-3:] == '.py':
+            self.openscript(path)
+        else:
+            W.Message("Can't open file of type '%s'." % ftype)
+
+    def getabouttext(self):
+        return "About Python IDE"+ELLIPSIS
+
+    def do_about(self, id, item, window, event):
+        Splash.about()
+
+    def do_setscriptsfolder(self, *args):
+        fsr = EasyDialogs.AskFolder(message="Select Scripts Folder",
+                wanted=File.FSRef)
+        if fsr:
+            prefs = self.getprefs()
+            alis = fsr.FSNewAliasMinimal()
+            prefs.scriptsfolder = alis.data
+            self.scriptsfolder = alis
+            self.makescriptsmenu()
+            prefs.save()
+
+    def domenu_modulebrowser(self, *args):
+        W.SetCursor('watch')
+        import ModuleBrowser
+        ModuleBrowser.ModuleBrowser()
+
+    def domenu_open(self, *args):
+        filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",))
+        if filename:
+            self.openscript(filename)
+
+    def domenu_openbyname(self, *args):
+        # Open a file by name. If the clipboard contains a filename
+        # use that as the default.
+        from Carbon import Scrap
+        try:
+            sc = Scrap.GetCurrentScrap()
+            dft = sc.GetScrapFlavorData("TEXT")
+        except Scrap.Error:
+            dft = ""
+        else:
+            if not os.path.exists(dft):
+                dft = ""
+        filename = EasyDialogs.AskString("Open File Named:", default=dft, ok="Open")
+        if filename:
+            self.openscript(filename)
+
+    def domenu_new(self, *args):
+        W.SetCursor('watch')
+        import PyEdit
+        return PyEdit.Editor()
+
+    def makescriptsmenu(self):
+        W.SetCursor('watch')
+        if self._scripts:
+            for id, item in self._scripts.keys():
+                if self.menubar.menus.has_key(id):
+                    m = self.menubar.menus[id]
+                    m.delete()
+            self._scripts = {}
+        if self.scriptsmenu:
+            if hasattr(self.scriptsmenu, 'id') and self.menubar.menus.has_key(self.scriptsmenu.id):
+                self.scriptsmenu.delete()
+        self.scriptsmenu = FrameWork.Menu(self.menubar, "Scripts")
+        #FrameWork.MenuItem(self.scriptsmenu, "New script", None, self.domenu_new)
+        #self.scriptsmenu.addseparator()
+        fsr, d1 = self.scriptsfolder.FSResolveAlias(None)
+        self.scriptswalk(fsr.as_pathname(), self.scriptsmenu)
+
+    def makeopenwindowsmenu(self):
+        for i in range(len(self.openwindowsmenu.items)):
+            self.openwindowsmenu.menu.DeleteMenuItem(1)
+            self.openwindowsmenu.items = []
+        windows = []
+        self._openwindows = {}
+        for window in self._windows.keys():
+            title = window.GetWTitle()
+            if not title:
+                title = "<no title>"
+            windows.append((title, window))
+        windows.sort()
+        for title, window in windows:
+            if title == "Python Interactive":       # ugly but useful hack by Joe Strout
+                shortcut = '0'
+            else:
+                shortcut = None
+            item = FrameWork.MenuItem(self.openwindowsmenu, title, shortcut, callback = self.domenu_openwindows)
+            self._openwindows[item.item] = window
+        self._openwindowscheckmark = 0
+        self.checkopenwindowsmenu()
+
+    def makeopenrecentmenu(self):
+        for i in range(len(self.openrecentmenu.items)):
+            self.openrecentmenu.menu.DeleteMenuItem(1)
+            self.openrecentmenu.items = []
+        prefs = self.getprefs()
+        filelist = prefs.recentfiles
+        if not filelist:
+            self.openrecentmenu.enable(0)
+            return
+        self.openrecentmenu.enable(1)
+        for filename in filelist:
+            item = FrameWork.MenuItem(self.openrecentmenu, filename, None, callback = self.domenu_openrecent)
+
+    def addrecentfile(self, file):
+        prefs = self.getprefs()
+        filelist = prefs.recentfiles
+        if not filelist:
+            filelist = []
+
+        if file in filelist:
+            if file == filelist[0]:
+                return
+            filelist.remove(file)
+        filelist.insert(0, file)
+        filelist = filelist[:10]
+        prefs.recentfiles = filelist
+        prefs.save()
+        self.makeopenrecentmenu()
+
+    def domenu_openwindows(self, id, item, window, event):
+        w = self._openwindows[item]
+        w.ShowWindow()
+        w.SelectWindow()
+
+    def domenu_openrecent(self, id, item, window, event):
+        prefs = self.getprefs()
+        filelist = prefs.recentfiles
+        if not filelist:
+            filelist = []
+        item = item - 1
+        filename = filelist[item]
+        self.openscript(filename)
+
+    def domenu_quit(self):
+        self._quit()
+
+    def domenu_save(self, *args):
+        print "Save"
+
+    def _quit(self):
+        import PyConsole, PyEdit
+        for window in self._windows.values():
+            try:
+                rv = window.close() # ignore any errors while quitting
+            except:
+                rv = 0   # (otherwise, we can get stuck!)
+            if rv and rv > 0:
+                return
+        try:
+            PyConsole.console.writeprefs()
+            PyConsole.output.writeprefs()
+            PyEdit.searchengine.writeprefs()
+        except:
+            # Write to __stderr__ so the msg end up in Console.app and has
+            # at least _some_ chance of getting read...
+            # But: this is a workaround for way more serious problems with
+            # the Python 2.2 Jaguar addon.
+            sys.__stderr__.write("*** PythonIDE: Can't write preferences ***\n")
+        self.quitting = 1
+
+    def domenu_openpackagemanager(self):
+        import PackageManager
+        PackageManager.PackageBrowser()
+
+    def domenu_gensuite(self):
+        import gensuitemodule
+        gensuitemodule.main_interactive()
+
+    def makehelpmenu(self):
+        hashelp, hasdocs = self.installdocumentation()
+        self.helpmenu = m = self.gethelpmenu()
+        helpitem = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_localhelp)
+        helpitem.enable(hashelp)
+        docitem = FrameWork.MenuItem(m, "Python Documentation", None, self.domenu_localdocs)
+        docitem.enable(hasdocs)
+        finditem = FrameWork.MenuItem(m, "Lookup in Python Documentation", None, 'lookuppython')
+        finditem.enable(hasdocs)
+        if runningOnOSX():
+            FrameWork.Separator(m)
+            doc2item = FrameWork.MenuItem(m, "Apple Developer Documentation", None, self.domenu_appledocs)
+            find2item = FrameWork.MenuItem(m, "Lookup in Carbon Documentation", None, 'lookupcarbon')
+        FrameWork.Separator(m)
+        webitem = FrameWork.MenuItem(m, "Python Documentation on the Web", None, self.domenu_webdocs)
+        web2item = FrameWork.MenuItem(m, "Python on the Web", None, self.domenu_webpython)
+        web3item = FrameWork.MenuItem(m, "MacPython on the Web", None, self.domenu_webmacpython)
+
+    def domenu_localdocs(self, *args):
+        from Carbon import AH
+        AH.AHGotoPage("Python Documentation", None, None)
+
+    def domenu_localhelp(self, *args):
+        from Carbon import AH
+        AH.AHGotoPage("MacPython Help", None, None)
+
+    def domenu_appledocs(self, *args):
+        from Carbon import AH, AppleHelp
+        try:
+            AH.AHGotoMainTOC(AppleHelp.kAHTOCTypeDeveloper)
+        except AH.Error, arg:
+            if arg[0] == -50:
+                W.Message("Developer documentation not installed")
+            else:
+                W.Message("AppleHelp Error: %r" % (arg,))
+
+    def domenu_lookuppython(self, *args):
+        from Carbon import AH
+        searchstring = self._getsearchstring()
+        if not searchstring:
+            return
+        try:
+            AH.AHSearch("Python Documentation", searchstring)
+        except AH.Error, arg:
+            W.Message("AppleHelp Error: %r" % (arg,))
+
+    def domenu_lookupcarbon(self, *args):
+        from Carbon import AH
+        searchstring = self._getsearchstring()
+        if not searchstring:
+            return
+        try:
+            AH.AHSearch("Carbon", searchstring)
+        except AH.Error, arg:
+            W.Message("AppleHelp Error: %r" % (arg,))
+
+    def _getsearchstring(self):
+        # First we get the frontmost window
+        front = self.getfrontwindow()
+        if front and hasattr(front, 'getselectedtext'):
+            text = front.getselectedtext()
+            if text:
+                return text
+        # This is a cop-out. We should have disabled the menus
+        # if there is no selection, but the can_ methods only seem
+        # to work for Windows. Or not for the Help menu, maybe?
+        text = EasyDialogs.AskString("Search documentation for", ok="Search")
+        return text
+
+    def domenu_webdocs(self, *args):
+        import webbrowser
+        major, minor, micro, state, nano = sys.version_info
+        if state in ('alpha', 'beta'):
+            docversion = 'dev/doc/devel'
+        elif micro == 0:
+            docversion = 'doc/%d.%d' % (major, minor)
+        else:
+            docversion = 'doc/%d.%d.%d' % (major, minor, micro)
+        webbrowser.open("http://www.python.org/%s" % docversion)
+
+    def domenu_webpython(self, *args):
+        import webbrowser
+        webbrowser.open("http://www.python.org/")
+
+    def domenu_webmacpython(self, *args):
+        import webbrowser
+        webbrowser.open("http://www.cwi.nl/~jack/macpython.html")
+
+    def installdocumentation(self):
+        # This is rather much of a hack. Someone has to tell the Help Viewer
+        # about the Python documentation, so why not us. The documentation
+        # is located in the framework, but there's a symlink in Python.app.
+        # And as AHRegisterHelpBook wants a bundle (with the right bits in
+        # the plist file) we refer it to Python.app
+        #
+        # To make matters worse we have to look in two places: first in the IDE
+        # itself, then in the Python application inside the framework.
+        has_help = False
+        has_doc = False
+        ide_path_components = sys.argv[0].split("/")
+        if ide_path_components[-3:] == ["Contents", "Resources", "PythonIDE.py"]:
+            ide_app = "/".join(ide_path_components[:-3])
+            help_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/Documentation')
+            doc_source = os.path.join(ide_app, 'Contents/Resources/English.lproj/PythonDocumentation')
+            has_help = os.path.isdir(help_source)
+            has_doc = os.path.isdir(doc_source)
+            if has_help or has_doc:
+                try:
+                    from Carbon import AH
+                    AH.AHRegisterHelpBook(ide_app)
+                except (ImportError, MacOS.Error), arg:
+                    pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
+        python_app = os.path.join(sys.prefix, 'Resources/Python.app')
+        if not has_help:
+            help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation')
+            has_help = os.path.isdir(help_source)
+        if not has_doc:
+            doc_source = os.path.join(python_app, 'Contents/Resources/English.lproj/PythonDocumentation')
+            has_doc = os.path.isdir(doc_source)
+        if has_help or has_doc:
+            try:
+                from Carbon import AH
+                AH.AHRegisterHelpBook(python_app)
+            except (ImportError, MacOS.Error), arg:
+                pass # W.Message("Cannot register Python Documentation: %s" % str(arg))
+        return has_help, has_doc
diff --git a/Mac/Tools/IDE/Splash.py b/Mac/Tools/IDE/Splash.py
index 86009d2..ab36fa4 100644
--- a/Mac/Tools/IDE/Splash.py
+++ b/Mac/Tools/IDE/Splash.py
@@ -25,88 +25,88 @@
 %s
 See: <http://www.python.org/> for information and documentation."""
 
-flauwekul = [	"Goodday, Bruce.", 
-			"What's new?",
-			"Nudge, nudge, say no more!", 
-			"No, no sir, it's not dead. It's resting.",
-			"Albatros!",
-			"It's . . .",
-			"Is your name not Bruce, then?",
-			"""But Mr F.G. Superman has a secret identity . . . 
-when trouble strikes at any time . . . 
-at any place . . . he is ready to become . . . 
+flauwekul = [   "Goodday, Bruce.",
+                        "What's new?",
+                        "Nudge, nudge, say no more!",
+                        "No, no sir, it's not dead. It's resting.",
+                        "Albatros!",
+                        "It's . . .",
+                        "Is your name not Bruce, then?",
+                        """But Mr F.G. Superman has a secret identity . . .
+when trouble strikes at any time . . .
+at any place . . . he is ready to become . . .
 Bicycle Repair Man!"""
-			]
+                        ]
 
 def skipdoublereturns(text):
-	return string.replace(text, '\n\n', '\n')
+    return string.replace(text, '\n\n', '\n')
 
 def nl2return(text):
-	return string.replace(text, '\n', '\r')
+    return string.replace(text, '\n', '\r')
 
 def UpdateSplash(drawdialog = 0, what = 0):
-	if drawdialog:
-		splash.DrawDialog()
-	drawtext(what)
-	splash.GetDialogWindow().ValidWindowRect(splash.GetDialogPort().GetPortBounds())
-	splash.GetDialogWindow().GetWindowPort().QDFlushPortBuffer(None)
+    if drawdialog:
+        splash.DrawDialog()
+    drawtext(what)
+    splash.GetDialogWindow().ValidWindowRect(splash.GetDialogPort().GetPortBounds())
+    splash.GetDialogWindow().GetWindowPort().QDFlushPortBuffer(None)
 
 def drawtext(what = 0):
-	Qd.SetPort(splash)
-	fontID = Fm.GetFNum("Python-Sans")
-	if not fontID:
-		fontID = geneva
-	Qd.TextFont(fontID)
-	Qd.TextSize(9)
-	rect = (10, 115, _about_width - 10, _about_height - 30)
-	if not what:
-		import __main__
-		abouttxt = nl2return(abouttext1 % (
-				__main__.__version__, sys.version, skipdoublereturns(sys.copyright)))
-	else:
-		import random
-		abouttxt = nl2return(random.choice(flauwekul))
-	TE.TETextBox(abouttxt, rect, teJustCenter)
+    Qd.SetPort(splash)
+    fontID = Fm.GetFNum("Python-Sans")
+    if not fontID:
+        fontID = geneva
+    Qd.TextFont(fontID)
+    Qd.TextSize(9)
+    rect = (10, 115, _about_width - 10, _about_height - 30)
+    if not what:
+        import __main__
+        abouttxt = nl2return(abouttext1 % (
+                        __main__.__version__, sys.version, skipdoublereturns(sys.copyright)))
+    else:
+        import random
+        abouttxt = nl2return(random.choice(flauwekul))
+    TE.TETextBox(abouttxt, rect, teJustCenter)
 
 UpdateSplash(1)
 
 def wait():
-	from Carbon import Evt
-	from Carbon import Events
-	global splash
-	try:
-		splash
-	except NameError:
-		return
-	Qd.InitCursor()
-	time = Evt.TickCount()
-	whattext = 0
-	drawtext(whattext)
-	while _keepsplashscreenopen:
-		ok, event = Evt.EventAvail(Events.highLevelEventMask)
-		if ok:
-			# got apple event, back to mainloop
-			break
-		ok, event = Evt.EventAvail(Events.mDownMask | Events.keyDownMask | Events.updateMask)
-		if ok:
-			ok, event = Evt.WaitNextEvent(Events.mDownMask | Events.keyDownMask | Events.updateMask, 30)
-			if ok:
-				(what, message, when, where, modifiers) = event
-				if what == Events.updateEvt:
-					if Win.WhichWindow(message) == splash:
-						UpdateSplash(1, whattext)
-				else:
-					break
-		if Evt.TickCount() - time > 360:
-			whattext = not whattext
-			drawtext(whattext)
-			time = Evt.TickCount()
-	del splash
+    from Carbon import Evt
+    from Carbon import Events
+    global splash
+    try:
+        splash
+    except NameError:
+        return
+    Qd.InitCursor()
+    time = Evt.TickCount()
+    whattext = 0
+    drawtext(whattext)
+    while _keepsplashscreenopen:
+        ok, event = Evt.EventAvail(Events.highLevelEventMask)
+        if ok:
+            # got apple event, back to mainloop
+            break
+        ok, event = Evt.EventAvail(Events.mDownMask | Events.keyDownMask | Events.updateMask)
+        if ok:
+            ok, event = Evt.WaitNextEvent(Events.mDownMask | Events.keyDownMask | Events.updateMask, 30)
+            if ok:
+                (what, message, when, where, modifiers) = event
+                if what == Events.updateEvt:
+                    if Win.WhichWindow(message) == splash:
+                        UpdateSplash(1, whattext)
+                else:
+                    break
+        if Evt.TickCount() - time > 360:
+            whattext = not whattext
+            drawtext(whattext)
+            time = Evt.TickCount()
+    del splash
 
 
 def about():
-	global splash, splashresfile, _keepsplashscreenopen
-	_keepsplashscreenopen = 1
-	splash = Dlg.GetNewDialog(468, -1)
-	splash.DrawDialog()
-	wait()
+    global splash, splashresfile, _keepsplashscreenopen
+    _keepsplashscreenopen = 1
+    splash = Dlg.GetNewDialog(468, -1)
+    splash.DrawDialog()
+    wait()
diff --git a/Mac/Tools/IDE/W.py b/Mac/Tools/IDE/W.py
index 397b211..3ddeb76 100644
--- a/Mac/Tools/IDE/W.py
+++ b/Mac/Tools/IDE/W.py
@@ -15,27 +15,26 @@
 AlertError = 'AlertError'
 
 def setapplication(app, sig):
-	global _application, _signature
-	_application = app
-	_signature = sig
+    global _application, _signature
+    _application = app
+    _signature = sig
 
 def getapplication():
-	if _application is None:
-		raise WidgetsError, 'W not properly initialized: unknown Application'
-	return _application
+    if _application is None:
+        raise WidgetsError, 'W not properly initialized: unknown Application'
+    return _application
 
 def getdefaultfont():
-	prefs = getapplication().getprefs()
-	if not prefs.defaultfont:
-		prefs.defaultfont = ("Geneva", 0, 10, (0, 0, 0))
-	return prefs.defaultfont
+    prefs = getapplication().getprefs()
+    if not prefs.defaultfont:
+        prefs.defaultfont = ("Geneva", 0, 10, (0, 0, 0))
+    return prefs.defaultfont
 
 def Message(text):
-	import EasyDialogs, string
-	from Carbon import Qd
-	Qd.InitCursor()
-	text = string.replace(text, "\n", "\r")
-	if not text:
-		text = '<Alert text not specified>'
-	EasyDialogs.Message(text)
-
+    import EasyDialogs, string
+    from Carbon import Qd
+    Qd.InitCursor()
+    text = string.replace(text, "\n", "\r")
+    if not text:
+        text = '<Alert text not specified>'
+    EasyDialogs.Message(text)
diff --git a/Mac/Tools/IDE/Wapplication.py b/Mac/Tools/IDE/Wapplication.py
index 553391e..4cfc77b 100644
--- a/Mac/Tools/IDE/Wapplication.py
+++ b/Mac/Tools/IDE/Wapplication.py
@@ -11,472 +11,471 @@
 from Carbon import File
 
 if hasattr(Win, "FrontNonFloatingWindow"):
-	MyFrontWindow = Win.FrontNonFloatingWindow
+    MyFrontWindow = Win.FrontNonFloatingWindow
 else:
-	MyFrontWindow = Win.FrontWindow
+    MyFrontWindow = Win.FrontWindow
 
 
 KILLUNKNOWNWINDOWS = 0  # Set to 0 for debugging.
 
 class Application(FrameWork.Application):
-	
-	def __init__(self, signature='Pyth'):
-		# Open our resource file, if it is not open yet
-		macresource.need('CURS', 468, "Widgets.rsrc")
-		import W
-		W.setapplication(self, signature)
-		FrameWork.Application.__init__(self)
-		self._suspended = 0
-		self.quitting = 0
-		self.debugger_quitting = 1
-		self.DebuggerQuit = 'DebuggerQuitDummyException'
-		self._idlefuncs = []
-		# map certain F key codes to equivalent command-letter combos (JJS)
-		self.fkeymaps = {122:"z", 120:"x", 99:"c", 118:"v"}
-	
-	def mainloop(self, mask=FrameWork.everyEvent, wait=None):
-		import W
-		self.quitting = 0
-		if hasattr(MacOS, 'EnableAppswitch'):
-			saveyield = MacOS.EnableAppswitch(-1)
-		try:
-			while not self.quitting:
-				try:
-					self.do1event(mask, wait)
-				except W.AlertError, detail:
-					if hasattr(MacOS, 'EnableAppswitch'):
-						MacOS.EnableAppswitch(-1)
-					W.Message(detail)
-				except self.DebuggerQuit:
-					if hasattr(MacOS, 'EnableAppswitch'):
-						MacOS.EnableAppswitch(-1)
-				except:
-					if hasattr(MacOS, 'EnableAppswitch'):
-						MacOS.EnableAppswitch(-1)
-					import PyEdit
-					PyEdit.tracebackwindow.traceback()
-		finally:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(1)
-	
-	def debugger_mainloop(self, mask=FrameWork.everyEvent, wait=None):
-		import W
-		self.debugger_quitting = 0
-		if hasattr(MacOS, 'EnableAppswitch'):
-			saveyield = MacOS.EnableAppswitch(-1)
-		try:
-			while not self.quitting and not self.debugger_quitting:
-				try:
-					self.do1event(mask, wait)
-				except W.AlertError, detail:
-					W.Message(detail)
-				except:
-					import PyEdit
-					PyEdit.tracebackwindow.traceback()
-		finally:
-			if hasattr(MacOS, 'EnableAppswitch'):
-				MacOS.EnableAppswitch(saveyield)
-	
-	def breathe(self, wait=1):
-		import W
-		ok, event = Evt.WaitNextEvent(FrameWork.updateMask | 
-				FrameWork.mDownMask | FrameWork.osMask |
-				FrameWork.activMask, 
-				wait)
-		if ok:
-			(what, message, when, where, modifiers) = event
-			#print FrameWork.eventname[what]
-			if FrameWork.eventname[what] == 'mouseDown':
-				partcode, wid = Win.FindWindow(where)
-				if FrameWork.partname[partcode] <> 'inDesk':
-					return
-			else:
-				W.SetCursor('watch')
-			self.dispatch(event)
-	
-	def refreshwindows(self, wait=1):
-		import W
-		while 1:
-			ok, event = Evt.WaitNextEvent(FrameWork.updateMask, wait)
-			if not ok:
-				break
-			self.dispatch(event)
-	
-	def addidlefunc(self, func):
-		self._idlefuncs.append(func)
-	
-	def removeidlefunc(self, func):
-		self._idlefuncs.remove(func)
-	
-	def idle(self, event):
-		if not self._suspended:
-			if not self.do_frontWindowMethod("idle", event):
-				Qd.InitCursor()
-		if self._idlefuncs:
-			for func in self._idlefuncs:
-				try:
-					func()
-				except:
-					import sys
-					sys.stderr.write("exception in idle function %r; killed:\n" % (func,))
-					traceback.print_exc()
-					self._idlefuncs.remove(func)
-					break
-	
-	def do_frontWindowMethod(self, attr, *args):
-		wid = MyFrontWindow()
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			if hasattr(window, attr):
-				handler = getattr(window, attr)
-				apply(handler, args)
-				return 1
-				
-	def getfrontwindow(self):
-		wid = MyFrontWindow()
-		if wid and self._windows.has_key(wid):
-			return self._windows[wid]
-		return None
-	
-	def appendwindow(self, wid, window):
-		self._windows[wid] = window
-		self.makeopenwindowsmenu()
-		
-	def removewindow(self, wid):
-		del self._windows[wid]
-		self.makeopenwindowsmenu()
-	
-	def makeopenwindowsmenu(self):
-		# dummy; could be the full version from PythonIDEMain.py
-		self._openwindows = {}
-		self._openwindowscheckmark = 0
-		if not hasattr(self, "_menustocheck"):
-			self._menustocheck = []
-	
-	def do_key(self, event):
-		(what, message, when, where, modifiers) = event
-		ch = chr(message & FrameWork.charCodeMask)
-		rest = message & ~FrameWork.charCodeMask
-		keycode = (message & FrameWork.keyCodeMask) >> 8
-		if keycode in self.fkeymaps.keys():		# JJS
-			ch = self.fkeymaps[keycode]
-			modifiers = modifiers | FrameWork.cmdKey
-		wid = MyFrontWindow()
-		if modifiers & FrameWork.cmdKey and not modifiers & FrameWork.shiftKey:
-			if wid and self._windows.has_key(wid):
-				self.checkmenus(self._windows[wid])
-			else:
-				self.checkmenus(None)
-			event = (what, ord(ch) | rest, when, where, modifiers)
-			result = MenuToolbox.MenuKey(ord(ch))
-			id = (result>>16) & 0xffff	# Hi word
-			item = result & 0xffff		# Lo word
-			if id:
-				self.do_rawmenu(id, item, None, event)
-				return	# here! we had a menukey! 
-			#else:
-			#	print "XXX Command-%r" % ch
-		# See whether the front window wants it
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			try:
-				do_char = window.do_char
-			except AttributeError:
-				do_char = self.do_char
-			do_char(ch, event)
-		# else it wasn't for us, sigh...
-	
-	def do_inMenuBar(self, partcode, window, event):
-		Qd.InitCursor()
-		(what, message, when, where, modifiers) = event
-		self.checkopenwindowsmenu()
-		wid = MyFrontWindow()
-		if wid and self._windows.has_key(wid):
-			self.checkmenus(self._windows[wid])
-		else:
-			self.checkmenus(None)
-		result = MenuToolbox.MenuSelect(where)
-		id = (result>>16) & 0xffff	# Hi word
-		if id >= 0x8000:
-			id = -0x10000 + id
-		item = result & 0xffff		# Lo word
-		self.do_rawmenu(id, item, window, event)
-	
-	def do_updateEvt(self, event):
-		(what, message, when, where, modifiers) = event
-		wid = Win.WhichWindow(message)
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			window.do_rawupdate(wid, event)
-		else:
-			if KILLUNKNOWNWINDOWS and wid:
-				wid.HideWindow()
-				import sys
-				sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
-			else:
-				if hasattr(MacOS, 'HandleEvent'):
-					MacOS.HandleEvent(event)
-				else:
-					print 'Unexpected updateEvent:', event
-	
-	def suspendresume(self, onoff):
-		pass
-	
-	def do_suspendresume(self, event):
-		self._suspended = not event[1] & 1
-		FrameWork.Application.do_suspendresume(self, event)
-	
-	def checkopenwindowsmenu(self):
-		if self._openwindowscheckmark:
-			self.openwindowsmenu.menu.CheckMenuItem(self._openwindowscheckmark, 0)
-		window = MyFrontWindow()
-		if window:
-			for item, wid in self._openwindows.items():
-				if wid == window:
-					#self.pythonwindowsmenuitem.check(1)
-					self.openwindowsmenu.menu.CheckMenuItem(item, 1)
-					self._openwindowscheckmark = item
-					break
-		else:
-			self._openwindowscheckmark = 0
-		#if self._openwindows:
-		#	self.pythonwindowsmenuitem.enable(1)
-		#else:
-		#	self.pythonwindowsmenuitem.enable(0)
-	
-	def checkmenus(self, window):
-		for item in self._menustocheck:
-			callback = item.menu.items[item.item-1][2]
-			if type(callback) <> StringType:
-				item.enable(1)
-			elif hasattr(window, "domenu_" + callback):
-				if hasattr(window, "can_" + callback):
-					canhandler = getattr(window, "can_" + callback)
-					if canhandler(item):
-						item.enable(1)
-					else:
-						item.enable(0)
-				else:
-					item.enable(1)
-			else:
-				item.enable(0)
-	
-	def enablemenubar(self, onoff):
-		for m in self.menubar.menus.values():
-			if onoff:
-				m.menu.EnableMenuItem(0)
-			elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
-				m.menu.DisableMenuItem(0)
-		MenuToolbox.DrawMenuBar()
-	
-	def makemenubar(self):
-		self.menubar = MenuBar(self)
-		FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
-		self.makeusermenus()
-	
-	def scriptswalk(self, top, menu, done=None):
-		if menu.id > 200:
-			import W
-			W.Message("Scripts folder not completely traversed: running out of menus")
-			return False
-		if done is None:
-			done = {}
-		if done.has_key(top):
-			return True
-		done[top] = 1
-		import os, string
-		try:
-			names = os.listdir(top)
-		except os.error:
-			FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
-			return True
-		savedir = os.getcwd()
-		os.chdir(top)
-		for name in names:
-			if name == "CVS":
-				continue
-			try:
-				fsr, isdir, isalias = File.FSResolveAliasFile(name, 1)
-			except:
-				# maybe a broken alias
-				continue
-			path = fsr.as_pathname()
-			if done.has_key(path):
-				continue
-			name = string.strip(name)
-			if os.name == "posix":
-				name = unicode(name, "utf-8")
-			if name[-3:] == '---':
-				menu.addseparator()
-			elif isdir:
-				submenu = FrameWork.SubMenu(menu, name)
-				if not self.scriptswalk(path, submenu, done):
-					return False
-			else:
-				creator, type = MacOS.GetCreatorAndType(path)
-				if type == 'TEXT':
-					if name[-3:] == '.py':
-						name = name[:-3]
-					item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
-					self._scripts[(menu.id, item.item)] = path
-			done[path] = 1
-		os.chdir(savedir)
-		return True
-	
-	def domenu_script(self, id, item, window, event):
-		(what, message, when, where, modifiers) = event
-		path = self._scripts[(id, item)]
-		import os
-		if not os.path.exists(path):
-			self.makescriptsmenu()
-			import W
-			raise W.AlertError, "File not found."
-		if ord(Evt.GetKeys()[7]) & 4:
-			self.openscript(path)
-		else:
-			import W, MacOS, sys
-			W.SetCursor("watch")
-			sys.argv = [path]
-			#cwd = os.getcwd()
-			#os.chdir(os.path.dirname(path) + ':')
-			try:
-				# xxx if there is a script window for this file,
-				# exec in that window's namespace.
-				# xxx what to do when it's not saved???
-				# promt to save?
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(0)
-				execfile(path, {'__name__': '__main__', '__file__': path})
-			except W.AlertError, detail:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(-1)
-				raise W.AlertError, detail
-			except KeyboardInterrupt:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(-1)
-			except:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(-1)
-				import PyEdit
-				PyEdit.tracebackwindow.traceback(1)
-			else:
-				if hasattr(MacOS, 'EnableAppswitch'):
-					MacOS.EnableAppswitch(-1)
-			#os.chdir(cwd)
-	
-	def openscript(self, filename, lineno=None, charoffset=0, modname=""):
-		import os, PyEdit, W
-		editor = self.getscript(filename)
-		if editor:
-			editor.select()
-		elif os.path.exists(filename):
-			editor = PyEdit.Editor(filename)
-		elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
-			import imp
-			if not modname:
-				if filename[-1] == 'c':
-					modname = os.path.basename(filename)[:-4]
-				else:
-					modname = os.path.basename(filename)[:-3]
-			try:
-				# XXX This does not work correctly with packages!
-				# XXX The docs say we should do it manually, pack, then sub, then sub2 etc. 
-				# XXX It says we should use imp.load_module(), but that *reloads* a package,
-				# XXX and that's the last thing we want here.
-				f, filename, (suff, mode, dummy) = imp.find_module(modname)
-			except ImportError:
-				raise W.AlertError, "Can't find file for \"%s\"" % modname
-			else:
-				if not f:
-					raise W.AlertError, "Can't find file for \"%s\"" % modname
-				f.close()
-			if suff == '.py':
-				self.openscript(filename, lineno, charoffset)
-				return
-			else:
-				raise W.AlertError, "Can't find file for \"%s\"" % modname
-		else:
-			raise W.AlertError, "Can't find file \"%s\"" % filename
-		if lineno is not None:
-			editor.selectline(lineno, charoffset)
-		return editor
-	
-	def getscript(self, filename):
-		if filename[:1] == '<' and filename[-1:] == '>':
-			filename = filename[1:-1]
-		import string
-		lowpath = string.lower(filename)
-		for wid, window in self._windows.items():
-			if hasattr(window, "path") and type(window.path) == StringType and \
-					lowpath == string.lower(window.path):
-				return window
-			elif hasattr(window, "path") and filename == wid.GetWTitle():
-				return window
-	
-	def getprefs(self):
-		import MacPrefs
-		return MacPrefs.GetPrefs(self.preffilepath)
-	
-	def do_editorprefs(self, *args):
-		import PyEdit
-		PyEdit.EditorDefaultSettings()
-	
-	def do_setwindowfont(self, *args):
-		import FontSettings, W
-		prefs = self.getprefs()
-		settings = FontSettings.FontDialog(prefs.defaultfont)
-		if settings:
-			prefs.defaultfont, tabsettings = settings
-			raise W.AlertError, "Note that changes will only affect new windows!"
+
+    def __init__(self, signature='Pyth'):
+        # Open our resource file, if it is not open yet
+        macresource.need('CURS', 468, "Widgets.rsrc")
+        import W
+        W.setapplication(self, signature)
+        FrameWork.Application.__init__(self)
+        self._suspended = 0
+        self.quitting = 0
+        self.debugger_quitting = 1
+        self.DebuggerQuit = 'DebuggerQuitDummyException'
+        self._idlefuncs = []
+        # map certain F key codes to equivalent command-letter combos (JJS)
+        self.fkeymaps = {122:"z", 120:"x", 99:"c", 118:"v"}
+
+    def mainloop(self, mask=FrameWork.everyEvent, wait=None):
+        import W
+        self.quitting = 0
+        if hasattr(MacOS, 'EnableAppswitch'):
+            saveyield = MacOS.EnableAppswitch(-1)
+        try:
+            while not self.quitting:
+                try:
+                    self.do1event(mask, wait)
+                except W.AlertError, detail:
+                    if hasattr(MacOS, 'EnableAppswitch'):
+                        MacOS.EnableAppswitch(-1)
+                    W.Message(detail)
+                except self.DebuggerQuit:
+                    if hasattr(MacOS, 'EnableAppswitch'):
+                        MacOS.EnableAppswitch(-1)
+                except:
+                    if hasattr(MacOS, 'EnableAppswitch'):
+                        MacOS.EnableAppswitch(-1)
+                    import PyEdit
+                    PyEdit.tracebackwindow.traceback()
+        finally:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(1)
+
+    def debugger_mainloop(self, mask=FrameWork.everyEvent, wait=None):
+        import W
+        self.debugger_quitting = 0
+        if hasattr(MacOS, 'EnableAppswitch'):
+            saveyield = MacOS.EnableAppswitch(-1)
+        try:
+            while not self.quitting and not self.debugger_quitting:
+                try:
+                    self.do1event(mask, wait)
+                except W.AlertError, detail:
+                    W.Message(detail)
+                except:
+                    import PyEdit
+                    PyEdit.tracebackwindow.traceback()
+        finally:
+            if hasattr(MacOS, 'EnableAppswitch'):
+                MacOS.EnableAppswitch(saveyield)
+
+    def breathe(self, wait=1):
+        import W
+        ok, event = Evt.WaitNextEvent(FrameWork.updateMask |
+                        FrameWork.mDownMask | FrameWork.osMask |
+                        FrameWork.activMask,
+                        wait)
+        if ok:
+            (what, message, when, where, modifiers) = event
+            #print FrameWork.eventname[what]
+            if FrameWork.eventname[what] == 'mouseDown':
+                partcode, wid = Win.FindWindow(where)
+                if FrameWork.partname[partcode] <> 'inDesk':
+                    return
+            else:
+                W.SetCursor('watch')
+            self.dispatch(event)
+
+    def refreshwindows(self, wait=1):
+        import W
+        while 1:
+            ok, event = Evt.WaitNextEvent(FrameWork.updateMask, wait)
+            if not ok:
+                break
+            self.dispatch(event)
+
+    def addidlefunc(self, func):
+        self._idlefuncs.append(func)
+
+    def removeidlefunc(self, func):
+        self._idlefuncs.remove(func)
+
+    def idle(self, event):
+        if not self._suspended:
+            if not self.do_frontWindowMethod("idle", event):
+                Qd.InitCursor()
+        if self._idlefuncs:
+            for func in self._idlefuncs:
+                try:
+                    func()
+                except:
+                    import sys
+                    sys.stderr.write("exception in idle function %r; killed:\n" % (func,))
+                    traceback.print_exc()
+                    self._idlefuncs.remove(func)
+                    break
+
+    def do_frontWindowMethod(self, attr, *args):
+        wid = MyFrontWindow()
+        if wid and self._windows.has_key(wid):
+            window = self._windows[wid]
+            if hasattr(window, attr):
+                handler = getattr(window, attr)
+                apply(handler, args)
+                return 1
+
+    def getfrontwindow(self):
+        wid = MyFrontWindow()
+        if wid and self._windows.has_key(wid):
+            return self._windows[wid]
+        return None
+
+    def appendwindow(self, wid, window):
+        self._windows[wid] = window
+        self.makeopenwindowsmenu()
+
+    def removewindow(self, wid):
+        del self._windows[wid]
+        self.makeopenwindowsmenu()
+
+    def makeopenwindowsmenu(self):
+        # dummy; could be the full version from PythonIDEMain.py
+        self._openwindows = {}
+        self._openwindowscheckmark = 0
+        if not hasattr(self, "_menustocheck"):
+            self._menustocheck = []
+
+    def do_key(self, event):
+        (what, message, when, where, modifiers) = event
+        ch = chr(message & FrameWork.charCodeMask)
+        rest = message & ~FrameWork.charCodeMask
+        keycode = (message & FrameWork.keyCodeMask) >> 8
+        if keycode in self.fkeymaps.keys():             # JJS
+            ch = self.fkeymaps[keycode]
+            modifiers = modifiers | FrameWork.cmdKey
+        wid = MyFrontWindow()
+        if modifiers & FrameWork.cmdKey and not modifiers & FrameWork.shiftKey:
+            if wid and self._windows.has_key(wid):
+                self.checkmenus(self._windows[wid])
+            else:
+                self.checkmenus(None)
+            event = (what, ord(ch) | rest, when, where, modifiers)
+            result = MenuToolbox.MenuKey(ord(ch))
+            id = (result>>16) & 0xffff      # Hi word
+            item = result & 0xffff          # Lo word
+            if id:
+                self.do_rawmenu(id, item, None, event)
+                return  # here! we had a menukey!
+            #else:
+            #       print "XXX Command-%r" % ch
+        # See whether the front window wants it
+        if wid and self._windows.has_key(wid):
+            window = self._windows[wid]
+            try:
+                do_char = window.do_char
+            except AttributeError:
+                do_char = self.do_char
+            do_char(ch, event)
+        # else it wasn't for us, sigh...
+
+    def do_inMenuBar(self, partcode, window, event):
+        Qd.InitCursor()
+        (what, message, when, where, modifiers) = event
+        self.checkopenwindowsmenu()
+        wid = MyFrontWindow()
+        if wid and self._windows.has_key(wid):
+            self.checkmenus(self._windows[wid])
+        else:
+            self.checkmenus(None)
+        result = MenuToolbox.MenuSelect(where)
+        id = (result>>16) & 0xffff      # Hi word
+        if id >= 0x8000:
+            id = -0x10000 + id
+        item = result & 0xffff          # Lo word
+        self.do_rawmenu(id, item, window, event)
+
+    def do_updateEvt(self, event):
+        (what, message, when, where, modifiers) = event
+        wid = Win.WhichWindow(message)
+        if wid and self._windows.has_key(wid):
+            window = self._windows[wid]
+            window.do_rawupdate(wid, event)
+        else:
+            if KILLUNKNOWNWINDOWS and wid:
+                wid.HideWindow()
+                import sys
+                sys.stderr.write("XXX killed unknown (crashed?) Python window.\n")
+            else:
+                if hasattr(MacOS, 'HandleEvent'):
+                    MacOS.HandleEvent(event)
+                else:
+                    print 'Unexpected updateEvent:', event
+
+    def suspendresume(self, onoff):
+        pass
+
+    def do_suspendresume(self, event):
+        self._suspended = not event[1] & 1
+        FrameWork.Application.do_suspendresume(self, event)
+
+    def checkopenwindowsmenu(self):
+        if self._openwindowscheckmark:
+            self.openwindowsmenu.menu.CheckMenuItem(self._openwindowscheckmark, 0)
+        window = MyFrontWindow()
+        if window:
+            for item, wid in self._openwindows.items():
+                if wid == window:
+                    #self.pythonwindowsmenuitem.check(1)
+                    self.openwindowsmenu.menu.CheckMenuItem(item, 1)
+                    self._openwindowscheckmark = item
+                    break
+        else:
+            self._openwindowscheckmark = 0
+        #if self._openwindows:
+        #       self.pythonwindowsmenuitem.enable(1)
+        #else:
+        #       self.pythonwindowsmenuitem.enable(0)
+
+    def checkmenus(self, window):
+        for item in self._menustocheck:
+            callback = item.menu.items[item.item-1][2]
+            if type(callback) <> StringType:
+                item.enable(1)
+            elif hasattr(window, "domenu_" + callback):
+                if hasattr(window, "can_" + callback):
+                    canhandler = getattr(window, "can_" + callback)
+                    if canhandler(item):
+                        item.enable(1)
+                    else:
+                        item.enable(0)
+                else:
+                    item.enable(1)
+            else:
+                item.enable(0)
+
+    def enablemenubar(self, onoff):
+        for m in self.menubar.menus.values():
+            if onoff:
+                m.menu.EnableMenuItem(0)
+            elif m.menu.GetMenuItemText(3) <> 'Cut': # ew...
+                m.menu.DisableMenuItem(0)
+        MenuToolbox.DrawMenuBar()
+
+    def makemenubar(self):
+        self.menubar = MenuBar(self)
+        FrameWork.AppleMenu(self.menubar, self.getabouttext(), self.do_about)
+        self.makeusermenus()
+
+    def scriptswalk(self, top, menu, done=None):
+        if menu.id > 200:
+            import W
+            W.Message("Scripts folder not completely traversed: running out of menus")
+            return False
+        if done is None:
+            done = {}
+        if done.has_key(top):
+            return True
+        done[top] = 1
+        import os, string
+        try:
+            names = os.listdir(top)
+        except os.error:
+            FrameWork.MenuItem(menu, '(Scripts Folder not found)', None, None)
+            return True
+        savedir = os.getcwd()
+        os.chdir(top)
+        for name in names:
+            if name == "CVS":
+                continue
+            try:
+                fsr, isdir, isalias = File.FSResolveAliasFile(name, 1)
+            except:
+                # maybe a broken alias
+                continue
+            path = fsr.as_pathname()
+            if done.has_key(path):
+                continue
+            name = string.strip(name)
+            if os.name == "posix":
+                name = unicode(name, "utf-8")
+            if name[-3:] == '---':
+                menu.addseparator()
+            elif isdir:
+                submenu = FrameWork.SubMenu(menu, name)
+                if not self.scriptswalk(path, submenu, done):
+                    return False
+            else:
+                creator, type = MacOS.GetCreatorAndType(path)
+                if type == 'TEXT':
+                    if name[-3:] == '.py':
+                        name = name[:-3]
+                    item = FrameWork.MenuItem(menu, name, None, self.domenu_script)
+                    self._scripts[(menu.id, item.item)] = path
+            done[path] = 1
+        os.chdir(savedir)
+        return True
+
+    def domenu_script(self, id, item, window, event):
+        (what, message, when, where, modifiers) = event
+        path = self._scripts[(id, item)]
+        import os
+        if not os.path.exists(path):
+            self.makescriptsmenu()
+            import W
+            raise W.AlertError, "File not found."
+        if ord(Evt.GetKeys()[7]) & 4:
+            self.openscript(path)
+        else:
+            import W, MacOS, sys
+            W.SetCursor("watch")
+            sys.argv = [path]
+            #cwd = os.getcwd()
+            #os.chdir(os.path.dirname(path) + ':')
+            try:
+                # xxx if there is a script window for this file,
+                # exec in that window's namespace.
+                # xxx what to do when it's not saved???
+                # promt to save?
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(0)
+                execfile(path, {'__name__': '__main__', '__file__': path})
+            except W.AlertError, detail:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(-1)
+                raise W.AlertError, detail
+            except KeyboardInterrupt:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(-1)
+            except:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(-1)
+                import PyEdit
+                PyEdit.tracebackwindow.traceback(1)
+            else:
+                if hasattr(MacOS, 'EnableAppswitch'):
+                    MacOS.EnableAppswitch(-1)
+            #os.chdir(cwd)
+
+    def openscript(self, filename, lineno=None, charoffset=0, modname=""):
+        import os, PyEdit, W
+        editor = self.getscript(filename)
+        if editor:
+            editor.select()
+        elif os.path.exists(filename):
+            editor = PyEdit.Editor(filename)
+        elif filename[-3:] == '.py' or filename[-4:] == '.pyc':
+            import imp
+            if not modname:
+                if filename[-1] == 'c':
+                    modname = os.path.basename(filename)[:-4]
+                else:
+                    modname = os.path.basename(filename)[:-3]
+            try:
+                # XXX This does not work correctly with packages!
+                # XXX The docs say we should do it manually, pack, then sub, then sub2 etc.
+                # XXX It says we should use imp.load_module(), but that *reloads* a package,
+                # XXX and that's the last thing we want here.
+                f, filename, (suff, mode, dummy) = imp.find_module(modname)
+            except ImportError:
+                raise W.AlertError, "Can't find file for \"%s\"" % modname
+            else:
+                if not f:
+                    raise W.AlertError, "Can't find file for \"%s\"" % modname
+                f.close()
+            if suff == '.py':
+                self.openscript(filename, lineno, charoffset)
+                return
+            else:
+                raise W.AlertError, "Can't find file for \"%s\"" % modname
+        else:
+            raise W.AlertError, "Can't find file \"%s\"" % filename
+        if lineno is not None:
+            editor.selectline(lineno, charoffset)
+        return editor
+
+    def getscript(self, filename):
+        if filename[:1] == '<' and filename[-1:] == '>':
+            filename = filename[1:-1]
+        import string
+        lowpath = string.lower(filename)
+        for wid, window in self._windows.items():
+            if hasattr(window, "path") and type(window.path) == StringType and \
+                            lowpath == string.lower(window.path):
+                return window
+            elif hasattr(window, "path") and filename == wid.GetWTitle():
+                return window
+
+    def getprefs(self):
+        import MacPrefs
+        return MacPrefs.GetPrefs(self.preffilepath)
+
+    def do_editorprefs(self, *args):
+        import PyEdit
+        PyEdit.EditorDefaultSettings()
+
+    def do_setwindowfont(self, *args):
+        import FontSettings, W
+        prefs = self.getprefs()
+        settings = FontSettings.FontDialog(prefs.defaultfont)
+        if settings:
+            prefs.defaultfont, tabsettings = settings
+            raise W.AlertError, "Note that changes will only affect new windows!"
 
 
 
 class MenuBar(FrameWork.MenuBar):
-	
-	possibleIDs = range(10, 256)
-	
-	def getnextid(self):
-		id = self.possibleIDs[0]
-		del self.possibleIDs[0]
-		return id
-	
-	def __init__(self, parent = None):
-		self.bar = MenuToolbox.GetMenuBar()
-		MenuToolbox.ClearMenuBar()
-		self.menus = {}
-		self.parent = parent
-	
-	def dispatch(self, id, item, window, event):
-		if self.menus.has_key(id):
-			self.menus[id].dispatch(id, item, window, event)
-	
-	def delmenu(self, id):
-		MenuToolbox.DeleteMenu(id)
-		if id in self.possibleIDs:
-			print "XXX duplicate menu ID!", id
-		self.possibleIDs.append(id)
-	
+
+    possibleIDs = range(10, 256)
+
+    def getnextid(self):
+        id = self.possibleIDs[0]
+        del self.possibleIDs[0]
+        return id
+
+    def __init__(self, parent = None):
+        self.bar = MenuToolbox.GetMenuBar()
+        MenuToolbox.ClearMenuBar()
+        self.menus = {}
+        self.parent = parent
+
+    def dispatch(self, id, item, window, event):
+        if self.menus.has_key(id):
+            self.menus[id].dispatch(id, item, window, event)
+
+    def delmenu(self, id):
+        MenuToolbox.DeleteMenu(id)
+        if id in self.possibleIDs:
+            print "XXX duplicate menu ID!", id
+        self.possibleIDs.append(id)
+
 
 class Menu(FrameWork.Menu):
-	
-	def dispatch(self, id, item, window, event):
-		title, shortcut, callback, kind = self.items[item-1]
-		if type(callback) == StringType:
-			callback = self._getmenuhandler(callback)
-		if callback:
-			import W
-			W.CallbackCall(callback, 0, id, item, window, event)
-	
-	def _getmenuhandler(self, callback):
-		menuhandler = None
-		wid = MyFrontWindow()
-		if wid and self.bar.parent._windows.has_key(wid):
-			window = self.bar.parent._windows[wid]
-			if hasattr(window, "domenu_" + callback):
-				menuhandler = getattr(window, "domenu_" + callback)
-			elif hasattr(self.bar.parent, "domenu_" + callback):
-				menuhandler = getattr(self.bar.parent, "domenu_" + callback)
-		elif hasattr(self.bar.parent, "domenu_" + callback):
-			menuhandler = getattr(self.bar.parent, "domenu_" + callback)
-		return menuhandler
 
+    def dispatch(self, id, item, window, event):
+        title, shortcut, callback, kind = self.items[item-1]
+        if type(callback) == StringType:
+            callback = self._getmenuhandler(callback)
+        if callback:
+            import W
+            W.CallbackCall(callback, 0, id, item, window, event)
+
+    def _getmenuhandler(self, callback):
+        menuhandler = None
+        wid = MyFrontWindow()
+        if wid and self.bar.parent._windows.has_key(wid):
+            window = self.bar.parent._windows[wid]
+            if hasattr(window, "domenu_" + callback):
+                menuhandler = getattr(window, "domenu_" + callback)
+            elif hasattr(self.bar.parent, "domenu_" + callback):
+                menuhandler = getattr(self.bar.parent, "domenu_" + callback)
+        elif hasattr(self.bar.parent, "domenu_" + callback):
+            menuhandler = getattr(self.bar.parent, "domenu_" + callback)
+        return menuhandler
diff --git a/Mac/Tools/IDE/Wbase.py b/Mac/Tools/IDE/Wbase.py
index a5d556b..4eef120 100644
--- a/Mac/Tools/IDE/Wbase.py
+++ b/Mac/Tools/IDE/Wbase.py
@@ -9,790 +9,790 @@
 
 
 def _intRect((l, t, r, b)):
-	return (int(l), int(t), int(r), int(b))
+    return (int(l), int(t), int(r), int(b))
 
 
 class Widget:
-	
-	"""Base class for all widgets."""
-	
-	_selectable = 0
-	
-	def __init__(self, possize):
-		self._widgets = []
-		self._widgetsdict = {}
-		self._possize = possize
-		self._bounds = None
-		self._visible = 1
-		self._enabled = 0
-		self._selected = 0
-		self._activated = 0
-		self._callback = None
-		self._parent = None
-		self._parentwindow = None
-		self._bindings = {}
-		self._backcolor = None
-	
-	def show(self, onoff):
-		self._visible = onoff
-		for w in self._widgets:
-			w.show(onoff)
-		if self._parentwindow is not None and self._parentwindow.wid is not None:
-			self.SetPort()
-			if onoff:
-				self.draw()
-			else:
-				Qd.EraseRect(self._bounds)
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			# draw your stuff here
-			pass
-	
-	def getpossize(self):
-		return self._possize
-	
-	def getbounds(self):
-		return self._bounds
-	
-	def move(self, x, y = None):
-		"""absolute move"""
-		if y == None:
-			x, y = x
-		if type(self._possize) <> TupleType:
-			raise WidgetsError, "can't move widget with bounds function"
-		l, t, r, b = self._possize
-		self.resize(x, y, r, b)
-	
-	def rmove(self, x, y = None):
-		"""relative move"""
-		if y == None:
-			x, y = x
-		if type(self._possize) <> TupleType:
-			raise WidgetsError, "can't move widget with bounds function"
-		l, t, r, b = self._possize
-		self.resize(l + x, t + y, r, b)
-		
-	def resize(self, *args):
-		if len(args) == 1:
-			if type(args[0]) == FunctionType or type(args[0]) == MethodType:
-				self._possize = args[0]
-			else:
-				apply(self.resize, args[0])
-		elif len(args) == 2:
-			self._possize = (0, 0) + args
-		elif len(args) == 4:
-			self._possize = args
-		else:
-			raise TypeError, "wrong number of arguments"
-		self._calcbounds()
-	
-	def open(self):
-		self._calcbounds()
-	
-	def close(self):
-		del self._callback
-		del self._possize
-		del self._bindings
-		del self._parent
-		del self._parentwindow
-	
-	def bind(self, key, callback):
-		"""bind a key or an 'event' to a callback"""
-		if callback:
-			self._bindings[key] = callback
-		elif self._bindings.has_key(key):
-			del self._bindings[key]
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(oldbounds)
-		self.GetWindow().InvalWindowRect(self._bounds)
-	
-	def _calcbounds(self):
-		# calculate absolute bounds relative to the window origin from our
-		# abstract _possize attribute, which is either a 4-tuple or a callable object
-		oldbounds = self._bounds
-		pl, pt, pr, pb = self._parent._bounds
-		if callable(self._possize):
-			# _possize is callable, let it figure it out by itself: it should return 
-			# the bounds relative to our parent widget.
-			width = pr - pl
-			height = pb - pt
-			self._bounds = Qd.OffsetRect(_intRect(self._possize(width, height)), pl, pt)
-		else:
-			# _possize must be a 4-tuple. This is where the algorithm by Peter Kriens and
-			# Petr van Blokland kicks in. (*** Parts of this algorithm are applied for 
-			# patents by Ericsson, Sweden ***)
-			l, t, r, b = self._possize
-			# depending on the values of l(eft), t(op), r(right) and b(ottom), 
-			# they mean different things:
-			if l < -1:
-				# l is less than -1, this mean it measures from the *right* of it's parent
-				l = pr + l
-			else:
-				# l is -1 or greater, this mean it measures from the *left* of it's parent
-				l = pl + l
-			if t < -1:
-				# t is less than -1, this mean it measures from the *bottom* of it's parent
-				t = pb + t
-			else:
-				# t is -1 or greater, this mean it measures from the *top* of it's parent
-				t = pt + t
-			if r > 1:
-				# r is greater than 1, this means r is the *width* of the widget
-				r = l + r
-			else:
-				# r is less than 1, this means it measures from the *right* of it's parent
-				r = pr + r
-			if b > 1:
-				# b is greater than 1, this means b is the *height* of the widget
-				b = t + b
-			else:
-				# b is less than 1, this means it measures from the *bottom* of it's parent
-				b = pb + b
-			self._bounds = (l, t, r, b)
-		if oldbounds and oldbounds <> self._bounds:
-			self.adjust(oldbounds)
-		for w in self._widgets:
-			w._calcbounds()
-	
-	def test(self, point):
-		if Qd.PtInRect(point, self._bounds):
-			return 1
-	
-	def click(self, point, modifiers):
-		pass
-	
-	def findwidget(self, point, onlyenabled = 1):
-		if self.test(point):
-			for w in self._widgets:
-				widget = w.findwidget(point)
-				if widget is not None:
-					return widget
-			if self._enabled or not onlyenabled:
-				return self
-	
-	def forall(self, methodname, *args):
-		for w in self._widgets:
-			rv = apply(w.forall, (methodname,) + args)
-			if rv: 
-				return rv
-		if self._bindings.has_key("<" + methodname + ">"):
-			callback = self._bindings["<" + methodname + ">"]
-			rv = apply(callback, args)
-			if rv: 
-				return rv
-		if hasattr(self, methodname):
-			method = getattr(self, methodname)
-			return apply(method, args)
-	
-	def forall_butself(self, methodname, *args):
-		for w in self._widgets:
-			rv = apply(w.forall, (methodname,) + args)
-			if rv: 
-				return rv
-	
-	def forall_frombottom(self, methodname, *args):
-		if self._bindings.has_key("<" + methodname + ">"):
-			callback = self._bindings["<" + methodname + ">"]
-			rv = apply(callback, args)
-			if rv: 
-				return rv
-		if hasattr(self, methodname):
-			method = getattr(self, methodname)
-			rv = apply(method, args)
-			if rv: 
-				return rv
-		for w in self._widgets:
-			rv = apply(w.forall_frombottom, (methodname,) + args)
-			if rv: 
-				return rv
-	
-	def _addwidget(self, key, widget):
-		if widget in self._widgets:
-			raise ValueError, "duplicate widget"
-		if self._widgetsdict.has_key(key):
-			self._removewidget(key)
-		self._widgets.append(widget)
-		self._widgetsdict[key] = widget
-		widget._parent = self
-		self._setparentwindow(widget)
-		if self._parentwindow and self._parentwindow.wid:
-			widget.forall_frombottom("open")
-			self.GetWindow().InvalWindowRect(widget._bounds)
-	
-	def _setparentwindow(self, widget):
-		widget._parentwindow = self._parentwindow
-		for w in widget._widgets:
-			self._setparentwindow(w)
-	
-	def _removewidget(self, key):
-		if not self._widgetsdict.has_key(key):
-			raise KeyError, "no widget with key %r" % (key,)
-		widget = self._widgetsdict[key]
-		for k in widget._widgetsdict.keys():
-			widget._removewidget(k)
-		if self._parentwindow._currentwidget == widget:
-			widget.select(0)
-			self._parentwindow._currentwidget = None
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(widget._bounds)
-		widget.close()
-		del self._widgetsdict[key]
-		self._widgets.remove(widget)
-	
-	def __setattr__(self, attr, value):
-		if type(value) == InstanceType and isinstance(value, Widget) and	\
-				attr not in ("_currentwidget", "_lastrollover", 
-				"_parent", "_parentwindow", "_defaultbutton"):
-			if hasattr(self, attr):
-				raise ValueError, "Can't replace existing attribute: " + attr
-			self._addwidget(attr, value)
-		self.__dict__[attr] = value
-	
-	def __delattr__(self, attr):
-		if attr == "_widgetsdict":
-			raise AttributeError, "cannot delete attribute _widgetsdict"
-		if self._widgetsdict.has_key(attr):
-			self._removewidget(attr)
-			if self.__dict__.has_key(attr):
-				del self.__dict__[attr]
-		elif self.__dict__.has_key(attr):
-			del self.__dict__[attr]
-		else:
-			raise AttributeError, attr
-	
-	def __setitem__(self, key, value):
-		self._addwidget(key, value)
-	
-	def __getitem__(self, key):
-		if not self._widgetsdict.has_key(key):
-			raise KeyError, key
-		return self._widgetsdict[key]
-	
-	def __delitem__(self, key):
-		self._removewidget(key)
-	
-	def SetPort(self):
-		self._parentwindow.SetPort()
-		
 
-	def GetWindow(self):
-		return self._parentwindow.GetWindow()
-		
-	def __del__(self):
-		if DEBUG:
-			print "%s instance deleted" % self.__class__.__name__
-	
-	def _drawbounds(self):
-		Qd.FrameRect(self._bounds)
+    """Base class for all widgets."""
+
+    _selectable = 0
+
+    def __init__(self, possize):
+        self._widgets = []
+        self._widgetsdict = {}
+        self._possize = possize
+        self._bounds = None
+        self._visible = 1
+        self._enabled = 0
+        self._selected = 0
+        self._activated = 0
+        self._callback = None
+        self._parent = None
+        self._parentwindow = None
+        self._bindings = {}
+        self._backcolor = None
+
+    def show(self, onoff):
+        self._visible = onoff
+        for w in self._widgets:
+            w.show(onoff)
+        if self._parentwindow is not None and self._parentwindow.wid is not None:
+            self.SetPort()
+            if onoff:
+                self.draw()
+            else:
+                Qd.EraseRect(self._bounds)
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            # draw your stuff here
+            pass
+
+    def getpossize(self):
+        return self._possize
+
+    def getbounds(self):
+        return self._bounds
+
+    def move(self, x, y = None):
+        """absolute move"""
+        if y == None:
+            x, y = x
+        if type(self._possize) <> TupleType:
+            raise WidgetsError, "can't move widget with bounds function"
+        l, t, r, b = self._possize
+        self.resize(x, y, r, b)
+
+    def rmove(self, x, y = None):
+        """relative move"""
+        if y == None:
+            x, y = x
+        if type(self._possize) <> TupleType:
+            raise WidgetsError, "can't move widget with bounds function"
+        l, t, r, b = self._possize
+        self.resize(l + x, t + y, r, b)
+
+    def resize(self, *args):
+        if len(args) == 1:
+            if type(args[0]) == FunctionType or type(args[0]) == MethodType:
+                self._possize = args[0]
+            else:
+                apply(self.resize, args[0])
+        elif len(args) == 2:
+            self._possize = (0, 0) + args
+        elif len(args) == 4:
+            self._possize = args
+        else:
+            raise TypeError, "wrong number of arguments"
+        self._calcbounds()
+
+    def open(self):
+        self._calcbounds()
+
+    def close(self):
+        del self._callback
+        del self._possize
+        del self._bindings
+        del self._parent
+        del self._parentwindow
+
+    def bind(self, key, callback):
+        """bind a key or an 'event' to a callback"""
+        if callback:
+            self._bindings[key] = callback
+        elif self._bindings.has_key(key):
+            del self._bindings[key]
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(oldbounds)
+        self.GetWindow().InvalWindowRect(self._bounds)
+
+    def _calcbounds(self):
+        # calculate absolute bounds relative to the window origin from our
+        # abstract _possize attribute, which is either a 4-tuple or a callable object
+        oldbounds = self._bounds
+        pl, pt, pr, pb = self._parent._bounds
+        if callable(self._possize):
+            # _possize is callable, let it figure it out by itself: it should return
+            # the bounds relative to our parent widget.
+            width = pr - pl
+            height = pb - pt
+            self._bounds = Qd.OffsetRect(_intRect(self._possize(width, height)), pl, pt)
+        else:
+            # _possize must be a 4-tuple. This is where the algorithm by Peter Kriens and
+            # Petr van Blokland kicks in. (*** Parts of this algorithm are applied for
+            # patents by Ericsson, Sweden ***)
+            l, t, r, b = self._possize
+            # depending on the values of l(eft), t(op), r(right) and b(ottom),
+            # they mean different things:
+            if l < -1:
+                # l is less than -1, this mean it measures from the *right* of it's parent
+                l = pr + l
+            else:
+                # l is -1 or greater, this mean it measures from the *left* of it's parent
+                l = pl + l
+            if t < -1:
+                # t is less than -1, this mean it measures from the *bottom* of it's parent
+                t = pb + t
+            else:
+                # t is -1 or greater, this mean it measures from the *top* of it's parent
+                t = pt + t
+            if r > 1:
+                # r is greater than 1, this means r is the *width* of the widget
+                r = l + r
+            else:
+                # r is less than 1, this means it measures from the *right* of it's parent
+                r = pr + r
+            if b > 1:
+                # b is greater than 1, this means b is the *height* of the widget
+                b = t + b
+            else:
+                # b is less than 1, this means it measures from the *bottom* of it's parent
+                b = pb + b
+            self._bounds = (l, t, r, b)
+        if oldbounds and oldbounds <> self._bounds:
+            self.adjust(oldbounds)
+        for w in self._widgets:
+            w._calcbounds()
+
+    def test(self, point):
+        if Qd.PtInRect(point, self._bounds):
+            return 1
+
+    def click(self, point, modifiers):
+        pass
+
+    def findwidget(self, point, onlyenabled = 1):
+        if self.test(point):
+            for w in self._widgets:
+                widget = w.findwidget(point)
+                if widget is not None:
+                    return widget
+            if self._enabled or not onlyenabled:
+                return self
+
+    def forall(self, methodname, *args):
+        for w in self._widgets:
+            rv = apply(w.forall, (methodname,) + args)
+            if rv:
+                return rv
+        if self._bindings.has_key("<" + methodname + ">"):
+            callback = self._bindings["<" + methodname + ">"]
+            rv = apply(callback, args)
+            if rv:
+                return rv
+        if hasattr(self, methodname):
+            method = getattr(self, methodname)
+            return apply(method, args)
+
+    def forall_butself(self, methodname, *args):
+        for w in self._widgets:
+            rv = apply(w.forall, (methodname,) + args)
+            if rv:
+                return rv
+
+    def forall_frombottom(self, methodname, *args):
+        if self._bindings.has_key("<" + methodname + ">"):
+            callback = self._bindings["<" + methodname + ">"]
+            rv = apply(callback, args)
+            if rv:
+                return rv
+        if hasattr(self, methodname):
+            method = getattr(self, methodname)
+            rv = apply(method, args)
+            if rv:
+                return rv
+        for w in self._widgets:
+            rv = apply(w.forall_frombottom, (methodname,) + args)
+            if rv:
+                return rv
+
+    def _addwidget(self, key, widget):
+        if widget in self._widgets:
+            raise ValueError, "duplicate widget"
+        if self._widgetsdict.has_key(key):
+            self._removewidget(key)
+        self._widgets.append(widget)
+        self._widgetsdict[key] = widget
+        widget._parent = self
+        self._setparentwindow(widget)
+        if self._parentwindow and self._parentwindow.wid:
+            widget.forall_frombottom("open")
+            self.GetWindow().InvalWindowRect(widget._bounds)
+
+    def _setparentwindow(self, widget):
+        widget._parentwindow = self._parentwindow
+        for w in widget._widgets:
+            self._setparentwindow(w)
+
+    def _removewidget(self, key):
+        if not self._widgetsdict.has_key(key):
+            raise KeyError, "no widget with key %r" % (key,)
+        widget = self._widgetsdict[key]
+        for k in widget._widgetsdict.keys():
+            widget._removewidget(k)
+        if self._parentwindow._currentwidget == widget:
+            widget.select(0)
+            self._parentwindow._currentwidget = None
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(widget._bounds)
+        widget.close()
+        del self._widgetsdict[key]
+        self._widgets.remove(widget)
+
+    def __setattr__(self, attr, value):
+        if type(value) == InstanceType and isinstance(value, Widget) and        \
+                        attr not in ("_currentwidget", "_lastrollover",
+                        "_parent", "_parentwindow", "_defaultbutton"):
+            if hasattr(self, attr):
+                raise ValueError, "Can't replace existing attribute: " + attr
+            self._addwidget(attr, value)
+        self.__dict__[attr] = value
+
+    def __delattr__(self, attr):
+        if attr == "_widgetsdict":
+            raise AttributeError, "cannot delete attribute _widgetsdict"
+        if self._widgetsdict.has_key(attr):
+            self._removewidget(attr)
+            if self.__dict__.has_key(attr):
+                del self.__dict__[attr]
+        elif self.__dict__.has_key(attr):
+            del self.__dict__[attr]
+        else:
+            raise AttributeError, attr
+
+    def __setitem__(self, key, value):
+        self._addwidget(key, value)
+
+    def __getitem__(self, key):
+        if not self._widgetsdict.has_key(key):
+            raise KeyError, key
+        return self._widgetsdict[key]
+
+    def __delitem__(self, key):
+        self._removewidget(key)
+
+    def SetPort(self):
+        self._parentwindow.SetPort()
+
+
+    def GetWindow(self):
+        return self._parentwindow.GetWindow()
+
+    def __del__(self):
+        if DEBUG:
+            print "%s instance deleted" % self.__class__.__name__
+
+    def _drawbounds(self):
+        Qd.FrameRect(self._bounds)
 
 
 class ClickableWidget(Widget):
-	
-	"""Base class for clickable widgets. (note: self._enabled must be true to receive click events.)"""
-	
-	def click(self, point, modifiers):
-		pass
-	
-	def enable(self, onoff):
-		self._enabled = onoff
-		self.SetPort()
-		self.draw()
-	
-	def callback(self):
-		if self._callback:
-			return CallbackCall(self._callback, 1)
-	
+
+    """Base class for clickable widgets. (note: self._enabled must be true to receive click events.)"""
+
+    def click(self, point, modifiers):
+        pass
+
+    def enable(self, onoff):
+        self._enabled = onoff
+        self.SetPort()
+        self.draw()
+
+    def callback(self):
+        if self._callback:
+            return CallbackCall(self._callback, 1)
+
 
 class SelectableWidget(ClickableWidget):
 
-	"""Base class for selectable widgets."""
-	
-	_selectable = 1
-	
-	def select(self, onoff, isclick = 0):
-		if onoff == self._selected:
-			return 1
-		if self._bindings.has_key("<select>"):
-			callback = self._bindings["<select>"]
-			if callback(onoff):
-				return 1
-		self._selected = onoff
-		if onoff:
-			if self._parentwindow._currentwidget is not None:
-				self._parentwindow._currentwidget.select(0)
-			self._parentwindow._currentwidget = self
-		else:
-			self._parentwindow._currentwidget = None
-	
-	def key(self, char, event):
-		pass
-	
-	def drawselframe(self, onoff):
-		if not self._parentwindow._hasselframes:
-			return
-		App.DrawThemeFocusRect(self._bounds, onoff)
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		if self._selected:
-			self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
-			self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
-		else:
-			self.GetWindow().InvalWindowRect(oldbounds)
-			self.GetWindow().InvalWindowRect(self._bounds)
+    """Base class for selectable widgets."""
+
+    _selectable = 1
+
+    def select(self, onoff, isclick = 0):
+        if onoff == self._selected:
+            return 1
+        if self._bindings.has_key("<select>"):
+            callback = self._bindings["<select>"]
+            if callback(onoff):
+                return 1
+        self._selected = onoff
+        if onoff:
+            if self._parentwindow._currentwidget is not None:
+                self._parentwindow._currentwidget.select(0)
+            self._parentwindow._currentwidget = self
+        else:
+            self._parentwindow._currentwidget = None
+
+    def key(self, char, event):
+        pass
+
+    def drawselframe(self, onoff):
+        if not self._parentwindow._hasselframes:
+            return
+        App.DrawThemeFocusRect(self._bounds, onoff)
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        if self._selected:
+            self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
+            self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
+        else:
+            self.GetWindow().InvalWindowRect(oldbounds)
+            self.GetWindow().InvalWindowRect(self._bounds)
 
 
 class _Line(Widget):
-	
-	def __init__(self, possize, thickness = 1):
-		Widget.__init__(self, possize)
-		self._thickness = thickness
-	
-	def open(self):
-		self._calcbounds()
-		self.SetPort()
-		self.draw()
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			Qd.PaintRect(self._bounds)
-	
-	def _drawbounds(self):
-		pass
+
+    def __init__(self, possize, thickness = 1):
+        Widget.__init__(self, possize)
+        self._thickness = thickness
+
+    def open(self):
+        self._calcbounds()
+        self.SetPort()
+        self.draw()
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            Qd.PaintRect(self._bounds)
+
+    def _drawbounds(self):
+        pass
 
 class HorizontalLine(_Line):
-	
-	def _calcbounds(self):
-		Widget._calcbounds(self)
-		l, t, r, b = self._bounds
-		self._bounds = l, t, r, t + self._thickness
+
+    def _calcbounds(self):
+        Widget._calcbounds(self)
+        l, t, r, b = self._bounds
+        self._bounds = l, t, r, t + self._thickness
 
 class VerticalLine(_Line):
-	
-	def _calcbounds(self):
-		Widget._calcbounds(self)
-		l, t, r, b = self._bounds
-		self._bounds = l, t, l + self._thickness, b
+
+    def _calcbounds(self):
+        Widget._calcbounds(self)
+        l, t, r, b = self._bounds
+        self._bounds = l, t, l + self._thickness, b
 
 
 class Frame(Widget):
-	
-	def __init__(self, possize, pattern = Qd.GetQDGlobalsBlack(), color = (0, 0, 0)):
-		Widget.__init__(self, possize)
-		self._framepattern = pattern
-		self._framecolor = color
-	
-	def setcolor(self, color):
-		self._framecolor = color
-		self.SetPort()
-		self.draw()
-	
-	def setpattern(self, pattern):
-		self._framepattern = pattern
-		self.SetPort()
-		self.draw()
-		
-	def draw(self, visRgn = None):
-		if self._visible:
-			penstate = Qd.GetPenState()
-			Qd.PenPat(self._framepattern)
-			Qd.RGBForeColor(self._framecolor)
-			Qd.FrameRect(self._bounds)
-			Qd.RGBForeColor((0, 0, 0))
-			Qd.SetPenState(penstate)
+
+    def __init__(self, possize, pattern = Qd.GetQDGlobalsBlack(), color = (0, 0, 0)):
+        Widget.__init__(self, possize)
+        self._framepattern = pattern
+        self._framecolor = color
+
+    def setcolor(self, color):
+        self._framecolor = color
+        self.SetPort()
+        self.draw()
+
+    def setpattern(self, pattern):
+        self._framepattern = pattern
+        self.SetPort()
+        self.draw()
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            penstate = Qd.GetPenState()
+            Qd.PenPat(self._framepattern)
+            Qd.RGBForeColor(self._framecolor)
+            Qd.FrameRect(self._bounds)
+            Qd.RGBForeColor((0, 0, 0))
+            Qd.SetPenState(penstate)
 
 def _darkencolor((r, g, b)):
-	return int(0.75 * r), int(0.75 * g), int(0.75 * b)
+    return int(0.75 * r), int(0.75 * g), int(0.75 * b)
 
 class BevelBox(Widget):
-	
-	"""'Platinum' beveled rectangle."""
-	
-	def __init__(self, possize, color = (0xe000, 0xe000, 0xe000)):
-		Widget.__init__(self, possize)
-		self._color = color
-		self._darkercolor = _darkencolor(color)
-	
-	def setcolor(self, color):
-		self._color = color
-		self.SetPort()
-		self.draw()
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
-			Qd.RGBForeColor(self._color)
-			Qd.PaintRect((l, t, r, b))
-			Qd.RGBForeColor(self._darkercolor)
-			Qd.MoveTo(l, b)
-			Qd.LineTo(r, b)
-			Qd.LineTo(r, t)
-			Qd.RGBForeColor((0, 0, 0))
+
+    """'Platinum' beveled rectangle."""
+
+    def __init__(self, possize, color = (0xe000, 0xe000, 0xe000)):
+        Widget.__init__(self, possize)
+        self._color = color
+        self._darkercolor = _darkencolor(color)
+
+    def setcolor(self, color):
+        self._color = color
+        self.SetPort()
+        self.draw()
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
+            Qd.RGBForeColor(self._color)
+            Qd.PaintRect((l, t, r, b))
+            Qd.RGBForeColor(self._darkercolor)
+            Qd.MoveTo(l, b)
+            Qd.LineTo(r, b)
+            Qd.LineTo(r, t)
+            Qd.RGBForeColor((0, 0, 0))
 
 
 class Group(Widget):
-	
-	"""A container for subwidgets"""
+
+    """A container for subwidgets"""
 
 
 class HorizontalPanes(Widget):
-	
-	"""Panes, a.k.a. frames. Works a bit like a group. Devides the widget area into "panes",
-	which can be resized by the user by clicking and dragging between the subwidgets."""
-	
-	_direction = 1
-	
-	def __init__(self, possize, panesizes = None, gutter = 8):
-		"""panesizes should be a tuple of numbers. The length of the tuple is the number of panes, 
-		the items in the tuple are the relative sizes of these panes; these numbers should add up 
-		to 1 (the total size of all panes)."""
-		Widget.__init__(self, possize)
-		self._panesizes = panesizes
-		self._gutter = gutter
-		self._enabled = 1
-		self.setuppanes()
-	
-	#def open(self):
-	#	self.installbounds()
-	#	ClickableWidget.open(self)
-	
-	def _calcbounds(self):
-		# hmmm. It should not neccesary be override _calcbounds :-(
-		self.installbounds()
-		Widget._calcbounds(self)
-	
-	def setuppanes(self):
-		panesizes = self._panesizes
-		total = 0
-		if panesizes is not None:
-			#if len(self._widgets) <> len(panesizes):
-			#	raise TypeError, 'number of widgets does not match number of panes'
-			for panesize in panesizes:
-				if not 0 < panesize < 1:
-					raise TypeError, 'pane sizes must be between 0 and 1, not including.'
-				total = total + panesize
-			if round(total, 4) <> 1.0:
-				raise TypeError, 'pane sizes must add up to 1'
-		else:
-			# XXX does not work!
-			step = 1.0 / len(self._widgets)
-			panesizes = []
-			for i in range(len(self._widgets)):
-				panesizes.append(step)
-		current = 0
-		self._panesizes = []
-		self._gutters = []
-		for panesize in panesizes:
-			if current:
-				self._gutters.append(current)
-			self._panesizes.append((current, current + panesize))
-			current = current + panesize
-		self.makepanebounds()
-	
-	def getpanesizes(self):
-		return map(lambda (fr, to): to-fr,  self._panesizes)
-	
-	boundstemplate = "lambda width, height: (0, height * %s + %d, width, height * %s + %d)"
-	
-	def makepanebounds(self):
-		halfgutter = self._gutter / 2
-		self._panebounds = []
-		for i in range(len(self._panesizes)):
-			panestart, paneend = self._panesizes[i]
-			boundsstring = self.boundstemplate % (repr(panestart), panestart and halfgutter, 
-							repr(paneend), (paneend <> 1.0) and -halfgutter)
-			self._panebounds.append(eval(boundsstring))
-	
-	def installbounds(self):
-		#self.setuppanes()
-		for i in range(len(self._widgets)):
-			w = self._widgets[i]
-			w._possize = self._panebounds[i]
-			#if hasattr(w, "setuppanes"):
-			#	w.setuppanes()
-			if hasattr(w, "installbounds"):
-				w.installbounds()
-	
-	def rollover(self, point, onoff):
-		if onoff:
-			orgmouse = point[self._direction]
-			halfgutter = self._gutter / 2
-			l, t, r, b = self._bounds
-			if self._direction:
-				begin, end = t, b
-			else:
-				begin, end = l, r
-			
-			i = self.findgutter(orgmouse, begin, end)
-			if i is None:
-				SetCursor("arrow")
-			else:
-				SetCursor(self._direction and 'vmover' or 'hmover')
-	
-	def findgutter(self, orgmouse, begin, end):
-		tolerance = max(4, self._gutter) / 2
-		for i in range(len(self._gutters)):
-			pos = begin + (end - begin) * self._gutters[i]
-			if abs(orgmouse - pos) <= tolerance:
-				break
-		else:
-			return
-		return i
-	
-	def click(self, point, modifiers):
-		# what a mess...
-		orgmouse = point[self._direction]
-		halfgutter = self._gutter / 2
-		l, t, r, b = self._bounds
-		if self._direction:
-			begin, end = t, b
-		else:
-			begin, end = l, r
-		
-		i = self.findgutter(orgmouse, begin, end)
-		if i is None:
-			return
-		
-		pos = orgpos = begin + (end - begin) * self._gutters[i]	# init pos too, for fast click on border, bug done by Petr
-		
-		minpos = self._panesizes[i][0]
-		maxpos = self._panesizes[i+1][1]
-		minpos = begin + (end - begin) * minpos + 64
-		maxpos = begin + (end - begin) * maxpos - 64
-		if minpos > orgpos and maxpos < orgpos:
-			return
-		
-		#SetCursor("fist")
-		self.SetPort()
-		if self._direction:
-			rect = l, orgpos - 1, r, orgpos
-		else:
-			rect = orgpos - 1, t, orgpos, b
-		
-		# track mouse --- XXX  move to separate method?
-		Qd.PenMode(QuickDraw.srcXor)
-		Qd.PenPat(Qd.GetQDGlobalsGray())
-		Qd.PaintRect(_intRect(rect))
-		lastpos = None
-		while Evt.Button():
-			pos = orgpos - orgmouse + Evt.GetMouse()[self._direction]
-			pos = max(pos, minpos)
-			pos = min(pos, maxpos)
-			if pos == lastpos:
-				continue
-			Qd.PenPat(Qd.GetQDGlobalsGray())
-			Qd.PaintRect(_intRect(rect))
-			if self._direction:
-				rect = l, pos - 1, r, pos
-			else:
-				rect = pos - 1, t, pos, b
-			Qd.PenPat(Qd.GetQDGlobalsGray())
-			Qd.PaintRect(_intRect(rect))
-			lastpos = pos
-			self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
-			Evt.WaitNextEvent(0, 3)
-		Qd.PaintRect(_intRect(rect))
-		Qd.PenNormal()
-		SetCursor("watch")
-		
-		newpos = (pos - begin) / float(end - begin)
-		self._gutters[i] = newpos
-		self._panesizes[i] = self._panesizes[i][0], newpos
-		self._panesizes[i+1] = newpos, self._panesizes[i+1][1]
-		self.makepanebounds()
-		self.installbounds()
-		self._calcbounds()
+
+    """Panes, a.k.a. frames. Works a bit like a group. Devides the widget area into "panes",
+    which can be resized by the user by clicking and dragging between the subwidgets."""
+
+    _direction = 1
+
+    def __init__(self, possize, panesizes = None, gutter = 8):
+        """panesizes should be a tuple of numbers. The length of the tuple is the number of panes,
+        the items in the tuple are the relative sizes of these panes; these numbers should add up
+        to 1 (the total size of all panes)."""
+        Widget.__init__(self, possize)
+        self._panesizes = panesizes
+        self._gutter = gutter
+        self._enabled = 1
+        self.setuppanes()
+
+    #def open(self):
+    #       self.installbounds()
+    #       ClickableWidget.open(self)
+
+    def _calcbounds(self):
+        # hmmm. It should not neccesary be override _calcbounds :-(
+        self.installbounds()
+        Widget._calcbounds(self)
+
+    def setuppanes(self):
+        panesizes = self._panesizes
+        total = 0
+        if panesizes is not None:
+            #if len(self._widgets) <> len(panesizes):
+            #       raise TypeError, 'number of widgets does not match number of panes'
+            for panesize in panesizes:
+                if not 0 < panesize < 1:
+                    raise TypeError, 'pane sizes must be between 0 and 1, not including.'
+                total = total + panesize
+            if round(total, 4) <> 1.0:
+                raise TypeError, 'pane sizes must add up to 1'
+        else:
+            # XXX does not work!
+            step = 1.0 / len(self._widgets)
+            panesizes = []
+            for i in range(len(self._widgets)):
+                panesizes.append(step)
+        current = 0
+        self._panesizes = []
+        self._gutters = []
+        for panesize in panesizes:
+            if current:
+                self._gutters.append(current)
+            self._panesizes.append((current, current + panesize))
+            current = current + panesize
+        self.makepanebounds()
+
+    def getpanesizes(self):
+        return map(lambda (fr, to): to-fr,  self._panesizes)
+
+    boundstemplate = "lambda width, height: (0, height * %s + %d, width, height * %s + %d)"
+
+    def makepanebounds(self):
+        halfgutter = self._gutter / 2
+        self._panebounds = []
+        for i in range(len(self._panesizes)):
+            panestart, paneend = self._panesizes[i]
+            boundsstring = self.boundstemplate % (repr(panestart), panestart and halfgutter,
+                                            repr(paneend), (paneend <> 1.0) and -halfgutter)
+            self._panebounds.append(eval(boundsstring))
+
+    def installbounds(self):
+        #self.setuppanes()
+        for i in range(len(self._widgets)):
+            w = self._widgets[i]
+            w._possize = self._panebounds[i]
+            #if hasattr(w, "setuppanes"):
+            #       w.setuppanes()
+            if hasattr(w, "installbounds"):
+                w.installbounds()
+
+    def rollover(self, point, onoff):
+        if onoff:
+            orgmouse = point[self._direction]
+            halfgutter = self._gutter / 2
+            l, t, r, b = self._bounds
+            if self._direction:
+                begin, end = t, b
+            else:
+                begin, end = l, r
+
+            i = self.findgutter(orgmouse, begin, end)
+            if i is None:
+                SetCursor("arrow")
+            else:
+                SetCursor(self._direction and 'vmover' or 'hmover')
+
+    def findgutter(self, orgmouse, begin, end):
+        tolerance = max(4, self._gutter) / 2
+        for i in range(len(self._gutters)):
+            pos = begin + (end - begin) * self._gutters[i]
+            if abs(orgmouse - pos) <= tolerance:
+                break
+        else:
+            return
+        return i
+
+    def click(self, point, modifiers):
+        # what a mess...
+        orgmouse = point[self._direction]
+        halfgutter = self._gutter / 2
+        l, t, r, b = self._bounds
+        if self._direction:
+            begin, end = t, b
+        else:
+            begin, end = l, r
+
+        i = self.findgutter(orgmouse, begin, end)
+        if i is None:
+            return
+
+        pos = orgpos = begin + (end - begin) * self._gutters[i] # init pos too, for fast click on border, bug done by Petr
+
+        minpos = self._panesizes[i][0]
+        maxpos = self._panesizes[i+1][1]
+        minpos = begin + (end - begin) * minpos + 64
+        maxpos = begin + (end - begin) * maxpos - 64
+        if minpos > orgpos and maxpos < orgpos:
+            return
+
+        #SetCursor("fist")
+        self.SetPort()
+        if self._direction:
+            rect = l, orgpos - 1, r, orgpos
+        else:
+            rect = orgpos - 1, t, orgpos, b
+
+        # track mouse --- XXX  move to separate method?
+        Qd.PenMode(QuickDraw.srcXor)
+        Qd.PenPat(Qd.GetQDGlobalsGray())
+        Qd.PaintRect(_intRect(rect))
+        lastpos = None
+        while Evt.Button():
+            pos = orgpos - orgmouse + Evt.GetMouse()[self._direction]
+            pos = max(pos, minpos)
+            pos = min(pos, maxpos)
+            if pos == lastpos:
+                continue
+            Qd.PenPat(Qd.GetQDGlobalsGray())
+            Qd.PaintRect(_intRect(rect))
+            if self._direction:
+                rect = l, pos - 1, r, pos
+            else:
+                rect = pos - 1, t, pos, b
+            Qd.PenPat(Qd.GetQDGlobalsGray())
+            Qd.PaintRect(_intRect(rect))
+            lastpos = pos
+            self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)
+            Evt.WaitNextEvent(0, 3)
+        Qd.PaintRect(_intRect(rect))
+        Qd.PenNormal()
+        SetCursor("watch")
+
+        newpos = (pos - begin) / float(end - begin)
+        self._gutters[i] = newpos
+        self._panesizes[i] = self._panesizes[i][0], newpos
+        self._panesizes[i+1] = newpos, self._panesizes[i+1][1]
+        self.makepanebounds()
+        self.installbounds()
+        self._calcbounds()
 
 
 class VerticalPanes(HorizontalPanes):
-	"""see HorizontalPanes"""
-	_direction = 0
-	boundstemplate = "lambda width, height: (width * %s + %d, 0, width * %s + %d, height)"
+    """see HorizontalPanes"""
+    _direction = 0
+    boundstemplate = "lambda width, height: (width * %s + %d, 0, width * %s + %d, height)"
 
 
 class ColorPicker(ClickableWidget):
-	
-	"""Color picker widget. Allows the user to choose a color."""
-	
-	def __init__(self, possize, color = (0, 0, 0), callback = None):
-		ClickableWidget.__init__(self, possize)
-		self._color = color
-		self._callback = callback
-		self._enabled = 1
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		import ColorPicker
-		newcolor, ok = ColorPicker.GetColor("", self._color)
-		if ok:
-			self._color = newcolor
-			self.SetPort()
-			self.draw()
-			if self._callback:
-				return CallbackCall(self._callback, 0, self._color)
-	
-	def set(self, color):
-		self._color = color
-		self.SetPort()
-		self.draw()
-	
-	def get(self):
-		return self._color
-	
-	def draw(self, visRgn=None):
-		if self._visible:
-			if not visRgn:
-				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
-			Qd.PenPat(Qd.GetQDGlobalsGray())
-			rect = self._bounds
-			Qd.FrameRect(rect)
-			rect = Qd.InsetRect(rect, 3, 3)
-			Qd.PenNormal()
-			Qd.RGBForeColor(self._color)
-			Qd.PaintRect(rect)
-			Qd.RGBForeColor((0, 0, 0))
-			
+
+    """Color picker widget. Allows the user to choose a color."""
+
+    def __init__(self, possize, color = (0, 0, 0), callback = None):
+        ClickableWidget.__init__(self, possize)
+        self._color = color
+        self._callback = callback
+        self._enabled = 1
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        import ColorPicker
+        newcolor, ok = ColorPicker.GetColor("", self._color)
+        if ok:
+            self._color = newcolor
+            self.SetPort()
+            self.draw()
+            if self._callback:
+                return CallbackCall(self._callback, 0, self._color)
+
+    def set(self, color):
+        self._color = color
+        self.SetPort()
+        self.draw()
+
+    def get(self):
+        return self._color
+
+    def draw(self, visRgn=None):
+        if self._visible:
+            if not visRgn:
+                visRgn = self._parentwindow.wid.GetWindowPort().visRgn
+            Qd.PenPat(Qd.GetQDGlobalsGray())
+            rect = self._bounds
+            Qd.FrameRect(rect)
+            rect = Qd.InsetRect(rect, 3, 3)
+            Qd.PenNormal()
+            Qd.RGBForeColor(self._color)
+            Qd.PaintRect(rect)
+            Qd.RGBForeColor((0, 0, 0))
+
 
 # misc utils
 
 def CallbackCall(callback, mustfit, *args):
-	"""internal helper routine for W"""
-	# XXX this function should die.
-	if type(callback) == FunctionType:
-		func = callback
-		maxargs = func.func_code.co_argcount
-	elif type(callback) == MethodType:
-		func = callback.im_func
-		maxargs = func.func_code.co_argcount - 1
-	else:
-		if callable(callback):
-			return apply(callback, args)
-		else:
-			raise TypeError, "uncallable callback object"
-	
-	if func.func_defaults:
-		minargs = maxargs - len(func.func_defaults)
-	else:
-		minargs = maxargs
-	if minargs <= len(args) <= maxargs:
-		return apply(callback, args)
-	elif not mustfit and minargs == 0:
-		return callback()
-	else:
-		if mustfit:
-			raise TypeError, "callback accepts wrong number of arguments: %r" % len(args)
-		else:
-			raise TypeError, "callback accepts wrong number of arguments: 0 or %r" % len(args)
+    """internal helper routine for W"""
+    # XXX this function should die.
+    if type(callback) == FunctionType:
+        func = callback
+        maxargs = func.func_code.co_argcount
+    elif type(callback) == MethodType:
+        func = callback.im_func
+        maxargs = func.func_code.co_argcount - 1
+    else:
+        if callable(callback):
+            return apply(callback, args)
+        else:
+            raise TypeError, "uncallable callback object"
+
+    if func.func_defaults:
+        minargs = maxargs - len(func.func_defaults)
+    else:
+        minargs = maxargs
+    if minargs <= len(args) <= maxargs:
+        return apply(callback, args)
+    elif not mustfit and minargs == 0:
+        return callback()
+    else:
+        if mustfit:
+            raise TypeError, "callback accepts wrong number of arguments: %r" % len(args)
+        else:
+            raise TypeError, "callback accepts wrong number of arguments: 0 or %r" % len(args)
 
 
 def HasBaseClass(obj, class_):
-	try:
-		raise obj
-	except class_:
-		return 1
-	except:
-		pass
-	return 0
+    try:
+        raise obj
+    except class_:
+        return 1
+    except:
+        pass
+    return 0
 
 
 #
 # To remove the dependence of Widgets.rsrc we hardcode the cursor
 # data below.
 #_cursors = {
-#	"watch"	: Qd.GetCursor(QuickDraw.watchCursor).data,
-#	"arrow"	: Qd.GetQDGlobalsArrow(),
-#	"iBeam"	: Qd.GetCursor(QuickDraw.iBeamCursor).data,
-#	"cross"	: Qd.GetCursor(QuickDraw.crossCursor).data,
-#	"plus"		: Qd.GetCursor(QuickDraw.plusCursor).data,
-#	"hand"	: Qd.GetCursor(468).data,
-#	"fist"		: Qd.GetCursor(469).data,
-#	"hmover"	: Qd.GetCursor(470).data,
-#	"vmover"	: Qd.GetCursor(471).data,
-#	"zoomin"	: Qd.GetCursor(472).data,
-#	"zoomout"	: Qd.GetCursor(473).data,
-#	"zoom"	: Qd.GetCursor(474).data,
+#       "watch" : Qd.GetCursor(QuickDraw.watchCursor).data,
+#       "arrow" : Qd.GetQDGlobalsArrow(),
+#       "iBeam" : Qd.GetCursor(QuickDraw.iBeamCursor).data,
+#       "cross" : Qd.GetCursor(QuickDraw.crossCursor).data,
+#       "plus"          : Qd.GetCursor(QuickDraw.plusCursor).data,
+#       "hand"  : Qd.GetCursor(468).data,
+#       "fist"          : Qd.GetCursor(469).data,
+#       "hmover"        : Qd.GetCursor(470).data,
+#       "vmover"        : Qd.GetCursor(471).data,
+#       "zoomin"        : Qd.GetCursor(472).data,
+#       "zoomout"       : Qd.GetCursor(473).data,
+#       "zoom"  : Qd.GetCursor(474).data,
 #}
 
 _cursors = {
-	'arrow':
-	'\x00\x00\x40\x00\x60\x00\x70\x00\x78\x00\x7c\x00\x7e\x00\x7f\x00'
-	'\x7f\x80\x7c\x00\x6c\x00\x46\x00\x06\x00\x03\x00\x03\x00\x00\x00'
-	'\xc0\x00\xe0\x00\xf0\x00\xf8\x00\xfc\x00\xfe\x00\xff\x00\xff\x80'
-	'\xff\xc0\xff\xe0\xfe\x00\xef\x00\xcf\x00\x87\x80\x07\x80\x03\x80'
-	'\x00\x01\x00\x01',
-	'cross':
-	'\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\xff\xe0\x04\x00\x04\x00'
-	'\x04\x00\x04\x00\x04\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-	'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-	'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-	'\x00\x05\x00\x05',
-	'fist':
-	'\x00\x00\x00\x00\x0d\x80\x12\x70\x12\x4c\x12\x4a\x28\x0a\x28\x02'
-	'\x48\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
-	'\x00\x00\x00\x00\x0d\x80\x1f\xf0\x1f\xfc\x1f\xfe\x3f\xfe\x3f\xfe'
-	'\x7f\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
-	'\x00\x09\x00\x08',
-	'hand':
-	'\x01\x80\x1a\x70\x26\x48\x26\x4a\x12\x4d\x12\x49\x68\x09\x98\x01'
-	'\x88\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
-	'\x01\x80\x1b\xf0\x3f\xf8\x3f\xfa\x1f\xff\x1f\xff\x6f\xff\xff\xff'
-	'\xff\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
-	'\x00\x09\x00\x08',
-	'hmover':
-	'\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x11\x88\x31\x8c\x7f\xfe'
-	'\x31\x8c\x11\x88\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00'
-	'\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x1b\xd8\x3b\xdc\x7f\xfe\xff\xff'
-	'\x7f\xfe\x3b\xdc\x1b\xd8\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x00\x00'
-	'\x00\x07\x00\x07',
-	'iBeam':
-	'\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
-	'\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
-	'\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
-	'\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
-	'\x00\x04\x00\x07',
-	'plus':
-	'\x00\x00\x07\xc0\x04\x60\x04\x60\x04\x60\x7c\x7c\x43\x86\x42\x86'
-	'\x43\x86\x7c\x7e\x3c\x7e\x04\x60\x04\x60\x07\xe0\x03\xe0\x00\x00'
-	'\x0f\xc0\x0f\xe0\x0f\xf0\x0f\xf0\xff\xff\xff\xfe\xfc\x7f\xfc\x7f'
-	'\xfc\x7f\xff\xff\x7f\xff\x7f\xff\x0f\xf0\x0f\xf0\x07\xf0\x03\xe0'
-	'\x00\x08\x00\x08',
-	'vmover':
-	'\x00\x00\x01\x00\x03\x80\x07\xc0\x01\x00\x01\x00\x01\x00\x7f\xfc'
-	'\x7f\xfc\x01\x00\x01\x00\x01\x00\x07\xc0\x03\x80\x01\x00\x00\x00'
-	'\x01\x00\x03\x80\x07\xc0\x0f\xe0\x0f\xe0\x03\x80\xff\xfe\xff\xfe'
-	'\xff\xfe\xff\xfe\x03\x80\x0f\xe0\x0f\xe0\x07\xc0\x03\x80\x01\x00'
-	'\x00\x07\x00\x07',
-	'watch':
-	'\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x40\x80\x84\x40\x84\x40\x84\x60'
-	'\x9c\x60\x80\x40\x80\x40\x40\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
-	'\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x7f\x80\xff\xc0\xff\xc0\xff\xc0'
-	'\xff\xc0\xff\xc0\xff\xc0\x7f\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
-	'\x00\x08\x00\x08',
-	'zoom':
-	'\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x80\x10\x80\x10\x80\x10'
-	'\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
-	'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x00\x06\x00\x06',
-	'zoomin':
-	'\x0f\x00\x30\xc0\x40\x20\x46\x20\x86\x10\x9f\x90\x9f\x90\x86\x10'
-	'\x46\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
-	'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x00\x06\x00\x06',
-	'zoomout':
-	'\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x9f\x90\x9f\x90\x80\x10'
-	'\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
-	'\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
-	'\x00\x06\x00\x06',
+        'arrow':
+        '\x00\x00\x40\x00\x60\x00\x70\x00\x78\x00\x7c\x00\x7e\x00\x7f\x00'
+        '\x7f\x80\x7c\x00\x6c\x00\x46\x00\x06\x00\x03\x00\x03\x00\x00\x00'
+        '\xc0\x00\xe0\x00\xf0\x00\xf8\x00\xfc\x00\xfe\x00\xff\x00\xff\x80'
+        '\xff\xc0\xff\xe0\xfe\x00\xef\x00\xcf\x00\x87\x80\x07\x80\x03\x80'
+        '\x00\x01\x00\x01',
+        'cross':
+        '\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\xff\xe0\x04\x00\x04\x00'
+        '\x04\x00\x04\x00\x04\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        '\x00\x05\x00\x05',
+        'fist':
+        '\x00\x00\x00\x00\x0d\x80\x12\x70\x12\x4c\x12\x4a\x28\x0a\x28\x02'
+        '\x48\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
+        '\x00\x00\x00\x00\x0d\x80\x1f\xf0\x1f\xfc\x1f\xfe\x3f\xfe\x3f\xfe'
+        '\x7f\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
+        '\x00\x09\x00\x08',
+        'hand':
+        '\x01\x80\x1a\x70\x26\x48\x26\x4a\x12\x4d\x12\x49\x68\x09\x98\x01'
+        '\x88\x02\x40\x02\x20\x02\x20\x04\x10\x04\x08\x08\x04\x08\x04\x08'
+        '\x01\x80\x1b\xf0\x3f\xf8\x3f\xfa\x1f\xff\x1f\xff\x6f\xff\xff\xff'
+        '\xff\xfe\x7f\xfe\x3f\xfe\x3f\xfc\x1f\xfc\x0f\xf8\x07\xf8\x07\xf8'
+        '\x00\x09\x00\x08',
+        'hmover':
+        '\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x11\x88\x31\x8c\x7f\xfe'
+        '\x31\x8c\x11\x88\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00'
+        '\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x1b\xd8\x3b\xdc\x7f\xfe\xff\xff'
+        '\x7f\xfe\x3b\xdc\x1b\xd8\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x00\x00'
+        '\x00\x07\x00\x07',
+        'iBeam':
+        '\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
+        '\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
+        '\x0c\x60\x02\x80\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00'
+        '\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x80\x0c\x60'
+        '\x00\x04\x00\x07',
+        'plus':
+        '\x00\x00\x07\xc0\x04\x60\x04\x60\x04\x60\x7c\x7c\x43\x86\x42\x86'
+        '\x43\x86\x7c\x7e\x3c\x7e\x04\x60\x04\x60\x07\xe0\x03\xe0\x00\x00'
+        '\x0f\xc0\x0f\xe0\x0f\xf0\x0f\xf0\xff\xff\xff\xfe\xfc\x7f\xfc\x7f'
+        '\xfc\x7f\xff\xff\x7f\xff\x7f\xff\x0f\xf0\x0f\xf0\x07\xf0\x03\xe0'
+        '\x00\x08\x00\x08',
+        'vmover':
+        '\x00\x00\x01\x00\x03\x80\x07\xc0\x01\x00\x01\x00\x01\x00\x7f\xfc'
+        '\x7f\xfc\x01\x00\x01\x00\x01\x00\x07\xc0\x03\x80\x01\x00\x00\x00'
+        '\x01\x00\x03\x80\x07\xc0\x0f\xe0\x0f\xe0\x03\x80\xff\xfe\xff\xfe'
+        '\xff\xfe\xff\xfe\x03\x80\x0f\xe0\x0f\xe0\x07\xc0\x03\x80\x01\x00'
+        '\x00\x07\x00\x07',
+        'watch':
+        '\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x40\x80\x84\x40\x84\x40\x84\x60'
+        '\x9c\x60\x80\x40\x80\x40\x40\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
+        '\x3f\x00\x3f\x00\x3f\x00\x3f\x00\x7f\x80\xff\xc0\xff\xc0\xff\xc0'
+        '\xff\xc0\xff\xc0\xff\xc0\x7f\x80\x3f\x00\x3f\x00\x3f\x00\x3f\x00'
+        '\x00\x08\x00\x08',
+        'zoom':
+        '\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x80\x10\x80\x10\x80\x10'
+        '\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
+        '\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x00\x06\x00\x06',
+        'zoomin':
+        '\x0f\x00\x30\xc0\x40\x20\x46\x20\x86\x10\x9f\x90\x9f\x90\x86\x10'
+        '\x46\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
+        '\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x00\x06\x00\x06',
+        'zoomout':
+        '\x0f\x00\x30\xc0\x40\x20\x40\x20\x80\x10\x9f\x90\x9f\x90\x80\x10'
+        '\x40\x20\x40\x20\x30\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x0f\x00\x3f\xc0\x7f\xe0\x7f\xe0\xff\xf0\xff\xf0\xff\xf0\xff\xf0'
+        '\x7f\xe0\x7f\xe0\x3f\xf0\x0f\x38\x00\x1c\x00\x0e\x00\x07\x00\x02'
+        '\x00\x06\x00\x06',
 }
 
 def SetCursor(what):
-	"""Set the cursorshape to any of these: 'arrow', 'cross', 'fist', 'hand', 'hmover', 'iBeam', 
-	'plus', 'vmover', 'watch', 'zoom', 'zoomin', 'zoomout'."""
-	Qd.SetCursor(_cursors[what])
+    """Set the cursorshape to any of these: 'arrow', 'cross', 'fist', 'hand', 'hmover', 'iBeam',
+    'plus', 'vmover', 'watch', 'zoom', 'zoomin', 'zoomout'."""
+    Qd.SetCursor(_cursors[what])
diff --git a/Mac/Tools/IDE/Wcontrols.py b/Mac/Tools/IDE/Wcontrols.py
index 58fc31b..00b06ac 100644
--- a/Mac/Tools/IDE/Wcontrols.py
+++ b/Mac/Tools/IDE/Wcontrols.py
@@ -4,430 +4,429 @@
 
 
 class ControlWidget(Wbase.ClickableWidget):
-	
-	"""Baseclass for all native controls."""
-	
-	def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1, viewsize = 0):
-		Wbase.ClickableWidget.__init__(self, possize)
-		self._control = None
-		self._title = title
-		self._callback = callback
-		self._procID = procID
-		self._value = value
-		self._min = min
-		self._max = max
-		self._enabled = 1
-		self._viewsize = viewsize
-	
-	def open(self):
-		self._calcbounds()
-		
-		# NewControl doesn't accept 32-bit value, min, or max, so for consistency
-		# with the new 32-bit set/get methods, out-of-range values are initially
-		# set as zero, followed by a 32-bit set of the actual value.
-		# Values not representable in 16 bits will fail on MacOS 8.1, however
-		# the vast majority of control usage should still be compatible.
-		_value, _min, _max = self._value, self._min, self._max
-		if -32768 <= _value <= 32767:
-			bigvalue = None
-		else:
-			bigvalue = _value
-			_value = 0
-		if -32768 <= _min <= 32767:
-			bigmin = None
-		else:
-			bigmin = _min
-			_min = 0
-		if -32768 <= _max <= 32767:
-			bigmax = None
-		else:
-			bigmax = _max
-			_max = 0
-		self._control = Ctl.NewControl(self._parentwindow.wid, 
-						self._bounds, 
-						self._title, 
-						1, 
-						_value, 
-						_min, 
-						_max, 
-						self._procID, 
-						0)
-		if bigvalue:
-			self._control.SetControl32BitValue(bigvalue)
-		if bigmin:
-			self._control.SetControl32BitMinimum(bigmin)
-		if bigmax:
-			self._control.SetControl32BitMaximum(bigmax)
-		if self._viewsize:
-			try:
-				self._control.SetControlViewSize(self._viewsize)
-				# Not available in MacOS 8.1, but that's OK since it only affects
-				# proportional scrollbars which weren't available in 8.1 either.
-			except NotImplementedError:
-				pass
-		self.enable(self._enabled)
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		self._control.HideControl()
-		self._control.MoveControl(self._bounds[0], self._bounds[1])
-		self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
-		if self._visible:
-			Qd.EraseRect(self._bounds)
-			self._control.ShowControl()
-			self.GetWindow().ValidWindowRect(self._bounds)
-	
-	def close(self):
-		self._control.HideControl()
-		self._control = None
-		Wbase.ClickableWidget.close(self)
-	
-	def enable(self, onoff):
-		if self._control and self._enabled <> onoff:
-			self._control.HiliteControl((not onoff) and 255)
-			self._enabled = onoff
-	
-	def show(self, onoff):
-		self._visible = onoff
-		for w in self._widgets:
-			w.show(onoff)
-		if onoff:
-			self._control.ShowControl()
-		else:
-			self._control.HideControl()
-	
-	def activate(self, onoff):
-		self._activated = onoff
-		if self._enabled:
-			if onoff:
-				self._control.ActivateControl()
-			else:
-				self._control.DeactivateControl()
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			self._control.Draw1Control()
-	
-	def test(self, point):
-		if Qd.PtInRect(point, self._bounds) and self._enabled:
-			return 1
-		#ctltype, control = Ctl.FindControl(point, self._parentwindow.wid)
-		#if self._enabled and control == self._control:
-		#	return 1
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		part = self._control.TrackControl(point)
-		if part:
-			if self._callback:
-				Wbase.CallbackCall(self._callback, 0)
-	
-	def settitle(self, title):
-		if self._control:
-			self._control.SetControlTitle(title)
-		self._title = title
-	
-	def gettitle(self):
-		return self._title
-	
-	def set(self, value):
-		if self._control:
-			if -32768 <= value <= 32767:
-				# No 32-bit control support in MacOS 8.1, so use
-				# the 16-bit interface when possible.
-				self._control.SetControlValue(value)
-			else:
-				self._control.SetControl32BitValue(value)
-		else:
-			self._value = value
-	
-	def get(self):
-		if self._control:
-			try:
-				return self._control.GetControl32BitValue()
-				# No 32-bit control support in MacOS 8.1, so fall
-				# back to the 16-bit interface when needed.
-			except NotImplementedError:
-				return self._control.GetControlValue()
-		else:
-			return self._value
+
+    """Baseclass for all native controls."""
+
+    def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1, viewsize = 0):
+        Wbase.ClickableWidget.__init__(self, possize)
+        self._control = None
+        self._title = title
+        self._callback = callback
+        self._procID = procID
+        self._value = value
+        self._min = min
+        self._max = max
+        self._enabled = 1
+        self._viewsize = viewsize
+
+    def open(self):
+        self._calcbounds()
+
+        # NewControl doesn't accept 32-bit value, min, or max, so for consistency
+        # with the new 32-bit set/get methods, out-of-range values are initially
+        # set as zero, followed by a 32-bit set of the actual value.
+        # Values not representable in 16 bits will fail on MacOS 8.1, however
+        # the vast majority of control usage should still be compatible.
+        _value, _min, _max = self._value, self._min, self._max
+        if -32768 <= _value <= 32767:
+            bigvalue = None
+        else:
+            bigvalue = _value
+            _value = 0
+        if -32768 <= _min <= 32767:
+            bigmin = None
+        else:
+            bigmin = _min
+            _min = 0
+        if -32768 <= _max <= 32767:
+            bigmax = None
+        else:
+            bigmax = _max
+            _max = 0
+        self._control = Ctl.NewControl(self._parentwindow.wid,
+                                        self._bounds,
+                                        self._title,
+                                        1,
+                                        _value,
+                                        _min,
+                                        _max,
+                                        self._procID,
+                                        0)
+        if bigvalue:
+            self._control.SetControl32BitValue(bigvalue)
+        if bigmin:
+            self._control.SetControl32BitMinimum(bigmin)
+        if bigmax:
+            self._control.SetControl32BitMaximum(bigmax)
+        if self._viewsize:
+            try:
+                self._control.SetControlViewSize(self._viewsize)
+                # Not available in MacOS 8.1, but that's OK since it only affects
+                # proportional scrollbars which weren't available in 8.1 either.
+            except NotImplementedError:
+                pass
+        self.enable(self._enabled)
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        self._control.HideControl()
+        self._control.MoveControl(self._bounds[0], self._bounds[1])
+        self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
+        if self._visible:
+            Qd.EraseRect(self._bounds)
+            self._control.ShowControl()
+            self.GetWindow().ValidWindowRect(self._bounds)
+
+    def close(self):
+        self._control.HideControl()
+        self._control = None
+        Wbase.ClickableWidget.close(self)
+
+    def enable(self, onoff):
+        if self._control and self._enabled <> onoff:
+            self._control.HiliteControl((not onoff) and 255)
+            self._enabled = onoff
+
+    def show(self, onoff):
+        self._visible = onoff
+        for w in self._widgets:
+            w.show(onoff)
+        if onoff:
+            self._control.ShowControl()
+        else:
+            self._control.HideControl()
+
+    def activate(self, onoff):
+        self._activated = onoff
+        if self._enabled:
+            if onoff:
+                self._control.ActivateControl()
+            else:
+                self._control.DeactivateControl()
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            self._control.Draw1Control()
+
+    def test(self, point):
+        if Qd.PtInRect(point, self._bounds) and self._enabled:
+            return 1
+        #ctltype, control = Ctl.FindControl(point, self._parentwindow.wid)
+        #if self._enabled and control == self._control:
+        #       return 1
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        part = self._control.TrackControl(point)
+        if part:
+            if self._callback:
+                Wbase.CallbackCall(self._callback, 0)
+
+    def settitle(self, title):
+        if self._control:
+            self._control.SetControlTitle(title)
+        self._title = title
+
+    def gettitle(self):
+        return self._title
+
+    def set(self, value):
+        if self._control:
+            if -32768 <= value <= 32767:
+                # No 32-bit control support in MacOS 8.1, so use
+                # the 16-bit interface when possible.
+                self._control.SetControlValue(value)
+            else:
+                self._control.SetControl32BitValue(value)
+        else:
+            self._value = value
+
+    def get(self):
+        if self._control:
+            try:
+                return self._control.GetControl32BitValue()
+                # No 32-bit control support in MacOS 8.1, so fall
+                # back to the 16-bit interface when needed.
+            except NotImplementedError:
+                return self._control.GetControlValue()
+        else:
+            return self._value
 
 
 class Button(ControlWidget):
-	
-	"""Standard push button."""
-	
-	procID = Controls.pushButProc | Controls.useWFont
-	
-	def __init__(self, possize, title = "Button", callback = None):
-		ControlWidget.__init__(self, possize, title, self.procID, callback, 0, 0, 1)
-		self._isdefault = 0
-	
-	def push(self):
-		if not self._enabled:
-			return
-		# emulate the pushing of the button
-		import time
-		self._control.HiliteControl(Controls.kControlButtonPart)
-		self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)  # needed under OSX
-		time.sleep(0.1)
-		self._control.HiliteControl(0)
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0)
-	
-	def enable(self, onoff):
-		if self._control and self._enabled <> onoff:
-			self._control.HiliteControl((not onoff) and 255)
-			self._enabled = onoff
-	
-	def show(self, onoff):
-		ControlWidget.show(self, onoff)
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			self._control.Draw1Control()
-	
-	def open(self):
-		ControlWidget.open(self)
-		if self._isdefault:
-			self._setdefault(self._isdefault)
-	
-	def _setdefault(self, onoff):
-		c = self._control
-		if c is not None:
-			if onoff:
-				data = "\xFF"
-			else:
-				data = "\0"
-			# hide before changing state, otherwise the button isn't always
-			# redrawn correctly, although it's quite different under Aqua
-			# and Classic...
-			c.HideControl()
-			c.SetControlData(Controls.kControlNoPart,
-					Controls.kControlPushButtonDefaultTag, data)
-			c.ShowControl()
-		self._isdefault = onoff
-	
-	def adjust(self, oldbounds):
-		if self._isdefault:
-			old = Qd.InsetRect(oldbounds, -4, -4)
-			new = Qd.InsetRect(self._bounds, -4, -4)
-			Qd.EraseRect(old)
-			self.GetWindow().InvalWindowRect(old)
-			self.GetWindow().InvalWindowRect(new)
-		ControlWidget.adjust(self, oldbounds)
+
+    """Standard push button."""
+
+    procID = Controls.pushButProc | Controls.useWFont
+
+    def __init__(self, possize, title = "Button", callback = None):
+        ControlWidget.__init__(self, possize, title, self.procID, callback, 0, 0, 1)
+        self._isdefault = 0
+
+    def push(self):
+        if not self._enabled:
+            return
+        # emulate the pushing of the button
+        import time
+        self._control.HiliteControl(Controls.kControlButtonPart)
+        self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)  # needed under OSX
+        time.sleep(0.1)
+        self._control.HiliteControl(0)
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0)
+
+    def enable(self, onoff):
+        if self._control and self._enabled <> onoff:
+            self._control.HiliteControl((not onoff) and 255)
+            self._enabled = onoff
+
+    def show(self, onoff):
+        ControlWidget.show(self, onoff)
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            self._control.Draw1Control()
+
+    def open(self):
+        ControlWidget.open(self)
+        if self._isdefault:
+            self._setdefault(self._isdefault)
+
+    def _setdefault(self, onoff):
+        c = self._control
+        if c is not None:
+            if onoff:
+                data = "\xFF"
+            else:
+                data = "\0"
+            # hide before changing state, otherwise the button isn't always
+            # redrawn correctly, although it's quite different under Aqua
+            # and Classic...
+            c.HideControl()
+            c.SetControlData(Controls.kControlNoPart,
+                            Controls.kControlPushButtonDefaultTag, data)
+            c.ShowControl()
+        self._isdefault = onoff
+
+    def adjust(self, oldbounds):
+        if self._isdefault:
+            old = Qd.InsetRect(oldbounds, -4, -4)
+            new = Qd.InsetRect(self._bounds, -4, -4)
+            Qd.EraseRect(old)
+            self.GetWindow().InvalWindowRect(old)
+            self.GetWindow().InvalWindowRect(new)
+        ControlWidget.adjust(self, oldbounds)
 
 
 class BevelButton(Button):
-	procID = Controls.kControlBevelButtonNormalBevelProc | Controls.useWFont
+    procID = Controls.kControlBevelButtonNormalBevelProc | Controls.useWFont
 
 
 class CheckBox(ControlWidget):
-	
-	"""Standard checkbox."""
-	
-	def __init__(self, possize, title = "Checkbox", callback = None, value = 0):
-		procID = Controls.checkBoxProc | Controls.useWFont
-		ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		part = self._control.TrackControl(point)
-		if part:
-			self.toggle()
-			if self._callback:
-				Wbase.CallbackCall(self._callback, 0, self.get())
-	
-	def push(self):
-		if not self._enabled:
-			return
-		self.toggle()
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, self.get())
-	
-	def toggle(self):
-		self.set(not self.get())
+
+    """Standard checkbox."""
+
+    def __init__(self, possize, title = "Checkbox", callback = None, value = 0):
+        procID = Controls.checkBoxProc | Controls.useWFont
+        ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        part = self._control.TrackControl(point)
+        if part:
+            self.toggle()
+            if self._callback:
+                Wbase.CallbackCall(self._callback, 0, self.get())
+
+    def push(self):
+        if not self._enabled:
+            return
+        self.toggle()
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, self.get())
+
+    def toggle(self):
+        self.set(not self.get())
 
 
 class RadioButton(ControlWidget):
-	
-	"""Standard radiobutton."""
-	
-	# XXX We need a radiogroup widget; this is too kludgy.
-	
-	def __init__(self, possize, title, thebuttons, callback = None, value = 0):
-		procID = Controls.radioButProc | Controls.useWFont
-		ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
-		self.thebuttons = thebuttons
-		thebuttons.append(self)
-	
-	def close(self):
-		self.thebuttons = None
-		ControlWidget.close(self)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		part = self._control.TrackControl(point)
-		if part:
-			self.set(1)
-			if self._callback:
-				Wbase.CallbackCall(self._callback, 0, 1)
-	
-	def push(self):
-		if not self._enabled:
-			return
-		self.set(1)
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, 1)
-	
-	def set(self, value):
-		for button in self.thebuttons:
-			if button._control:
-				button._control.SetControlValue(button == self)
-			else:
-				button._value = (button == self)
+
+    """Standard radiobutton."""
+
+    # XXX We need a radiogroup widget; this is too kludgy.
+
+    def __init__(self, possize, title, thebuttons, callback = None, value = 0):
+        procID = Controls.radioButProc | Controls.useWFont
+        ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
+        self.thebuttons = thebuttons
+        thebuttons.append(self)
+
+    def close(self):
+        self.thebuttons = None
+        ControlWidget.close(self)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        part = self._control.TrackControl(point)
+        if part:
+            self.set(1)
+            if self._callback:
+                Wbase.CallbackCall(self._callback, 0, 1)
+
+    def push(self):
+        if not self._enabled:
+            return
+        self.set(1)
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, 1)
+
+    def set(self, value):
+        for button in self.thebuttons:
+            if button._control:
+                button._control.SetControlValue(button == self)
+            else:
+                button._value = (button == self)
 
 
 class Scrollbar(ControlWidget):
-	
-	"""Standard scrollbar."""
-	
-	def __init__(self, possize, callback=None, value=0, min=0, max=0, livefeedback=1):
-		if livefeedback:
-			procID = Controls.kControlScrollBarLiveProc
-		else:
-			procID = Controls.scrollBarProc
-		ControlWidget.__init__(self, possize, "", procID, callback, value, min, max)
-	
-	# interface
-#	def set(self, value):
-#		if self._callback:
-#			Wbase.CallbackCall(self._callback, 1, value)
-	
-	def up(self):
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 1, '+')
-	
-	def down(self):
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 1, '-')
-	
-	def pageup(self):
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 1, '++')
-	
-	def pagedown(self):
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 1, '--')
-	
-	def setmin(self, min):
-		if self._control is not None:
-			if -32768 <= min <= 32767:
-				# No 32-bit control support in MacOS 8.1, so use
-				# the 16-bit interface when possible.
-				self._control.SetControlMinimum(min)
-			else:
-				self._control.SetControl32BitMinimum(min)
-		else:
-			self._min = min
-	
-	def setmax(self, max):
-		if self._control is not None:
-			if -32768 <= max <= 32767:
-				# No 32-bit control support in MacOS 8.1, so use
-				# the 16-bit interface when possible.
-				self._control.SetControlMaximum(max)
-			else:
-				self._control.SetControl32BitMaximum(max)
-		else:
-			self._max = max
-	
-	def setviewsize(self, viewsize):
-		if self._control is not None:
-			try:
-				self._control.SetControlViewSize(viewsize)
-				# Not available in MacOS 8.1, but that's OK since it only affects
-				# proportional scrollbars which weren't available in 8.1 either.
-			except NotImplementedError:
-				pass
-		else:
-			self._viewsize = viewsize
-	
-	def getmin(self):
-		try:
-			return self._control.GetControl32BitMinimum()
-			# No 32-bit control support in MacOS 8.1, so fall
-			# back to the 16-bit interface when needed.
-		except NotImplementedError:
-			return self._control.GetControlMinimum()
-	
-	def getmax(self):
-		try:
-			return self._control.GetControl32BitMaximum()
-			# No 32-bit control support in MacOS 8.1, so fall
-			# back to the 16-bit interface when needed.
-		except NotImplementedError:
-			return self._control.GetControlMaximum()
-	
-	# internals
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		def hitter(ctl, part, self=self):
-			if part:
-				self._hit(part)
-		part = self._control.TrackControl(point, hitter)
-	
-	def _hit(self, part):
-		value = None
-		if part == Controls.inThumb:
-			try:
-				value = self._control.GetControl32BitValue()
-				# No 32-bit control support in MacOS 8.1, so fall
-				# back to the 16-bit interface when needed.
-			except NotImplementedError:
-				value = self._control.GetControlValue()
-		elif part == Controls.inUpButton:
-			value = "+"
-		elif part == Controls.inDownButton:
-			value = "-"
-		elif part == Controls.inPageUp:
-			value = "++"
-		elif part == Controls.inPageDown:
-			value = "--"
-		if value is not None and self._callback:
-			Wbase.CallbackCall(self._callback, 1, value)
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			self._control.Draw1Control()
-			#Qd.FrameRect(self._bounds)
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(oldbounds)
-		self._control.HideControl()
-		self._control.MoveControl(self._bounds[0], self._bounds[1])
-		self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
-		if self._visible:
-			Qd.EraseRect(self._bounds)
-			if self._activated:
-				self._control.ShowControl()
-			else:
-				Qd.FrameRect(self._bounds)
-			self.GetWindow().ValidWindowRect(self._bounds)
+
+    """Standard scrollbar."""
+
+    def __init__(self, possize, callback=None, value=0, min=0, max=0, livefeedback=1):
+        if livefeedback:
+            procID = Controls.kControlScrollBarLiveProc
+        else:
+            procID = Controls.scrollBarProc
+        ControlWidget.__init__(self, possize, "", procID, callback, value, min, max)
+
+    # interface
+#       def set(self, value):
+#               if self._callback:
+#                       Wbase.CallbackCall(self._callback, 1, value)
+
+    def up(self):
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 1, '+')
+
+    def down(self):
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 1, '-')
+
+    def pageup(self):
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 1, '++')
+
+    def pagedown(self):
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 1, '--')
+
+    def setmin(self, min):
+        if self._control is not None:
+            if -32768 <= min <= 32767:
+                # No 32-bit control support in MacOS 8.1, so use
+                # the 16-bit interface when possible.
+                self._control.SetControlMinimum(min)
+            else:
+                self._control.SetControl32BitMinimum(min)
+        else:
+            self._min = min
+
+    def setmax(self, max):
+        if self._control is not None:
+            if -32768 <= max <= 32767:
+                # No 32-bit control support in MacOS 8.1, so use
+                # the 16-bit interface when possible.
+                self._control.SetControlMaximum(max)
+            else:
+                self._control.SetControl32BitMaximum(max)
+        else:
+            self._max = max
+
+    def setviewsize(self, viewsize):
+        if self._control is not None:
+            try:
+                self._control.SetControlViewSize(viewsize)
+                # Not available in MacOS 8.1, but that's OK since it only affects
+                # proportional scrollbars which weren't available in 8.1 either.
+            except NotImplementedError:
+                pass
+        else:
+            self._viewsize = viewsize
+
+    def getmin(self):
+        try:
+            return self._control.GetControl32BitMinimum()
+            # No 32-bit control support in MacOS 8.1, so fall
+            # back to the 16-bit interface when needed.
+        except NotImplementedError:
+            return self._control.GetControlMinimum()
+
+    def getmax(self):
+        try:
+            return self._control.GetControl32BitMaximum()
+            # No 32-bit control support in MacOS 8.1, so fall
+            # back to the 16-bit interface when needed.
+        except NotImplementedError:
+            return self._control.GetControlMaximum()
+
+    # internals
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        def hitter(ctl, part, self=self):
+            if part:
+                self._hit(part)
+        part = self._control.TrackControl(point, hitter)
+
+    def _hit(self, part):
+        value = None
+        if part == Controls.inThumb:
+            try:
+                value = self._control.GetControl32BitValue()
+                # No 32-bit control support in MacOS 8.1, so fall
+                # back to the 16-bit interface when needed.
+            except NotImplementedError:
+                value = self._control.GetControlValue()
+        elif part == Controls.inUpButton:
+            value = "+"
+        elif part == Controls.inDownButton:
+            value = "-"
+        elif part == Controls.inPageUp:
+            value = "++"
+        elif part == Controls.inPageDown:
+            value = "--"
+        if value is not None and self._callback:
+            Wbase.CallbackCall(self._callback, 1, value)
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            self._control.Draw1Control()
+            #Qd.FrameRect(self._bounds)
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(oldbounds)
+        self._control.HideControl()
+        self._control.MoveControl(self._bounds[0], self._bounds[1])
+        self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
+        if self._visible:
+            Qd.EraseRect(self._bounds)
+            if self._activated:
+                self._control.ShowControl()
+            else:
+                Qd.FrameRect(self._bounds)
+            self.GetWindow().ValidWindowRect(self._bounds)
 
 
 def _scalebarvalue(absmin, absmax, curmin, curmax):
-	if curmin <= absmin and curmax >= absmax:
-		return None
-	if curmin <= absmin:
-		return 0
-	if curmax >= absmax:
-		return 32767
-	perc = float(curmin-absmin) / float((absmax - absmin) - (curmax - curmin))
-	return int(perc*32767)
-
+    if curmin <= absmin and curmax >= absmax:
+        return None
+    if curmin <= absmin:
+        return 0
+    if curmax >= absmax:
+        return 32767
+    perc = float(curmin-absmin) / float((absmax - absmin) - (curmax - curmin))
+    return int(perc*32767)
diff --git a/Mac/Tools/IDE/Wkeys.py b/Mac/Tools/IDE/Wkeys.py
index 876f02f..9bc4522 100644
--- a/Mac/Tools/IDE/Wkeys.py
+++ b/Mac/Tools/IDE/Wkeys.py
@@ -1,45 +1,45 @@
-spacekey		= ' '
-returnkey 		= '\r'
-tabkey 		= '\t'
-enterkey 		= '\003'
-backspacekey 	= '\010'
-deletekey 		= '\177'
-clearkey		= '\033'
-helpkey 		= '\005'
+spacekey                = ' '
+returnkey               = '\r'
+tabkey          = '\t'
+enterkey                = '\003'
+backspacekey    = '\010'
+deletekey               = '\177'
+clearkey                = '\033'
+helpkey                 = '\005'
 
-leftarrowkey 	= '\034'
-rightarrowkey 	= '\035'
-uparrowkey 		= '\036'
-downarrowkey 	= '\037'
-arrowkeys 		= [leftarrowkey, rightarrowkey, uparrowkey, downarrowkey]
+leftarrowkey    = '\034'
+rightarrowkey   = '\035'
+uparrowkey              = '\036'
+downarrowkey    = '\037'
+arrowkeys               = [leftarrowkey, rightarrowkey, uparrowkey, downarrowkey]
 
-topkey 		= '\001'
-bottomkey 		= '\004'
-pageupkey 		= '\013'
-pagedownkey 	= '\014'
-scrollkeys 		= [topkey, bottomkey, pageupkey, pagedownkey]
+topkey          = '\001'
+bottomkey               = '\004'
+pageupkey               = '\013'
+pagedownkey     = '\014'
+scrollkeys              = [topkey, bottomkey, pageupkey, pagedownkey]
 
 navigationkeys = arrowkeys + scrollkeys
 
 keycodes = {
-	"space"		: ' ',
-	"return"		: '\r',
-	"tab" 			: '\t',
-	"enter" 		: '\003',
-	"backspace"	: '\010',
-	"delete"		: '\177',
-	"help" 		: '\005',
-	"leftarrow"		: '\034',
-	"rightarrow" 	: '\035',
-	"uparrow" 		: '\036',
-	"downarrow"	: '\037',
-	"top" 			: '\001',
-	"bottom" 		: '\004',
-	"pageup" 		: '\013',
-	"pagedown" 	: '\014'
+        "space"         : ' ',
+        "return"                : '\r',
+        "tab"                   : '\t',
+        "enter"                 : '\003',
+        "backspace"     : '\010',
+        "delete"                : '\177',
+        "help"          : '\005',
+        "leftarrow"             : '\034',
+        "rightarrow"    : '\035',
+        "uparrow"               : '\036',
+        "downarrow"     : '\037',
+        "top"                   : '\001',
+        "bottom"                : '\004',
+        "pageup"                : '\013',
+        "pagedown"      : '\014'
 }
 
 keynames = {}
 for k, v in keycodes.items():
-	keynames[v] = k
+    keynames[v] = k
 del k, v
diff --git a/Mac/Tools/IDE/Wlists.py b/Mac/Tools/IDE/Wlists.py
index 1b66a8b..9aeb7c4 100644
--- a/Mac/Tools/IDE/Wlists.py
+++ b/Mac/Tools/IDE/Wlists.py
@@ -10,573 +10,572 @@
 
 
 class List(Wbase.SelectableWidget):
-	
-	"""Standard list widget."""
-	
-	LDEF_ID = 0
-	
-	def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1, typingcasesens=0):
-		if items is None:
-			items = []
-		self.items = items
-		Wbase.SelectableWidget.__init__(self, possize)
-		self._selected = 0
-		self._enabled = 1
-		self._list = None
-		self._cols = cols
-		self._callback = callback
-		self._flags = flags
-		self.typingcasesens = typingcasesens
-		self.lasttyping = ""
-		self.lasttime = Evt.TickCount()
-		self.timelimit = 30
-		self.setitems(items)
-		self.drawingmode = 0
-	
-	def open(self):
-		self.setdrawingmode(0)
-		self.createlist()
-		self.setdrawingmode(1)
-	
-	def createlist(self):
-		self._calcbounds()
-		self.SetPort()
-		rect = self._bounds
-		rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
-		self._viewbounds = rect
-		self._list = LNew(rect, (0, 0, self._cols, 0), (0, 0), self.LDEF_ID, self._parentwindow.wid,
-					0, 1, 0, 1)
-		if self.drawingmode:
-			self._list.LSetDrawingMode(0)
-		self._list.selFlags = self._flags
-		self.setitems(self.items)
-		if hasattr(self, "_sel"):
-			self.setselection(self._sel)
-			del self._sel
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		# Appearance frames are drawn outside the specified bounds,
-		# so we always need to outset the invalidated area.
-		self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
-		self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
 
-		if oldbounds[:2] == self._bounds[:2]:
-			# set visRgn to empty, to prevent nasty drawing side effect of LSize()
-			Qd.RectRgn(self._parentwindow.wid.GetWindowPort().visRgn, (0, 0, 0, 0))
-			# list still has the same upper/left coordinates, use LSize
-			l, t, r, b = self._bounds
-			width = r - l - 17
-			height = b - t - 2
-			vl, vt, vr, vb = self._viewbounds
-			self._viewbounds = vl, vt, vl + width, vt + height
-			self._list.LSize(width, height)
-			# now *why* doesn't the list manager recalc the cellrect???
-			l, t, r, b = self._list.LRect((0,0))
-			cellheight = b - t
-			self._list.LCellSize((width/self._cols, cellheight))
-			# reset visRgn
-			self._parentwindow.wid.CalcVis()
-		else:
-			# oh well, since the list manager doesn't have a LMove call,
-			# we have to make the list all over again...
-			sel = self.getselection()
-			topcell = self.gettopcell()
-			self._list = None
-			self.setdrawingmode(0)
-			self.createlist()
-			self.setselection(sel)
-			self.settopcell(topcell)
-			self.setdrawingmode(1)
-	
-	def close(self):
-		self._list = None
-		self._callback = None
-		self.items = []
-		Wbase.SelectableWidget.close(self)
-	
-	def set(self, items):
-		self.setitems(items)
-	
-	def setitems(self, items):
-		self.items = items
-		the_list = self._list
-		if not self._parent or not self._list:
-			return
-		self.setdrawingmode(0)
-		topcell = self.gettopcell()
-		the_list.LDelRow(0, 1)
-		the_list.LAddRow(len(self.items), 0)
-		self_itemrepr = self.itemrepr
-		set_cell = the_list.LSetCell
-		for i in range(len(items)):
-			set_cell(self_itemrepr(items[i]), (0, i))
-		self.settopcell(topcell)
-		self.setdrawingmode(1)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		isdoubleclick = self._list.LClick(point, modifiers)
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, isdoubleclick)
-		return 1
-	
-	def key(self, char, event):
-		(what, message, when, where, modifiers) = event
-		sel = self.getselection()
-		newselection = []
-		if char == Wkeys.uparrowkey:
-			if len(sel) >= 1 and min(sel) > 0:
-				newselection = [min(sel) - 1]
-			else:
-				newselection = [0]
-		elif char == Wkeys.downarrowkey:
-			if len(sel) >= 1 and max(sel) < (len(self.items) - 1):
-					newselection = [max(sel) + 1]
-			else:
-				newselection = [len(self.items) - 1]
-		else:
-			modifiers = 0
-			if (self.lasttime + self.timelimit) < Evt.TickCount():
-				self.lasttyping = ""
-			if self.typingcasesens:
-				self.lasttyping = self.lasttyping + char
-			else:
-				self.lasttyping = self.lasttyping + string.lower(char)
-			self.lasttime = Evt.TickCount()
-			i = self.findmatch(self.lasttyping)
-			newselection = [i]
-		if modifiers & Events.shiftKey and not self._list.selFlags & Lists.lOnlyOne:
-			newselection = newselection + sel
-		self.setselection(newselection)
-		self._list.LAutoScroll()
-		self.click((-1, -1), 0)
-	
-	def findmatch(self, tag):
-		lower = string.lower
-		items = self.items
-		typingcasesens = self.typingcasesens
-		taglen = len(tag)
-		match = '\377' * 100
-		match_i = -1
-		for i in range(len(items)):
-			item = str(items[i])
-			if not typingcasesens:
-				item = lower(item)
-			if tag <= item < match:
-				match = item
-				match_i = i
-		if match_i >= 0:
-			return match_i
-		else:
-			return len(items) - 1
-	
-	def domenu_copy(self, *args):
-		sel = self.getselection()
-		selitems = []
-		for i in sel:
-			selitems.append(str(self.items[i]))
-		text = string.join(selitems, '\r')
-		if text:
-			if hasattr(Scrap, 'PutScrap'):
-				Scrap.ZeroScrap()
-				Scrap.PutScrap('TEXT', text)
-			else:
-				Scrap.ClearCurrentScrap()
-				sc = Scrap.GetCurrentScrap()
-				sc.PutScrapFlavor('TEXT', 0, text)
-	
-	def can_copy(self, *args):
-		return len(self.getselection()) <> 0
-	
-	def domenu_selectall(self, *args):
-		self.selectall()
-	
-	def can_selectall(self, *args):
-		return not self._list.selFlags & Lists.lOnlyOne
-	
-	def selectall(self):
-		if not self._list.selFlags & Lists.lOnlyOne:
-			self.setselection(range(len(self.items)))
-			self._list.LAutoScroll()
-			self.click((-1, -1), 0)
-	
-	def getselection(self):
-		if not self._parent or not self._list:
-			if hasattr(self, "_sel"):
-				return self._sel
-			return []
-		items = []
-		point = (0,0)
-		while 1:
-			ok, point = self._list.LGetSelect(1, point)
-			if not ok:
-				break
-			items.append(point[1])
-			point = point[0], point[1]+1
-		return items
-	
-	def setselection(self, selection):
-		if not self._parent or not self._list:
-			self._sel = selection
-			return
-		set_sel = self._list.LSetSelect
-		for i in range(len(self.items)):
-			if i in selection:
-				set_sel(1, (0, i))
-			else:
-				set_sel(0, (0, i))
-		self._list.LAutoScroll()
-	
-	def getselectedobjects(self):
-		sel = self.getselection()
-		objects = []
-		for i in sel:
-			objects.append(self.items[i])
-		return objects
-	
-	def setselectedobjects(self, objects):
-		sel = []
-		for o in objects:
-			try:
-				sel.append(self.items.index(o))
-			except:
-				pass
-		self.setselection(sel)
-	
-	def gettopcell(self):
-		l, t, r, b = self._bounds
-		t = t + 1
-		cl, ct, cr, cb = self._list.LRect((0, 0))
-		cellheight = cb - ct
-		return (t - ct) / cellheight
-	
-	def settopcell(self, topcell):
-		top = self.gettopcell()
-		diff = topcell - top
-		self._list.LScroll(0, diff)
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			if not visRgn:
-				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
-			self._list.LUpdate(visRgn)
-			state = [kThemeStateActive, kThemeStateInactive][not self._activated]
-			App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
-			if self._selected and self._activated:
-				self.drawselframe(1)
-	
-	def select(self, onoff, isclick = 0):
-		if Wbase.SelectableWidget.select(self, onoff):
-			return
-		self.SetPort()
-		self.drawselframe(onoff)
-	
-	def activate(self, onoff):
-		self._activated = onoff
-		if self._visible:
-			self._list.LActivate(onoff)
-			#state = [kThemeStateActive, kThemeStateInactive][not onoff]
-			#App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
-			if self._selected:
-				self.drawselframe(onoff)
-	
-	def get(self):
-		return self.items
-	
-	def itemrepr(self, item):
-		return str(item)[:255]
-	
-	def __getitem__(self, index):
-		return self.items[index]
-	
-	def __setitem__(self, index, item):
-		if self._parent and self._list:
-			self._list.LSetCell(self.itemrepr(item), (0, index))
-		self.items[index] = item
-	
-	def __delitem__(self, index):
-		if self._parent and self._list:
-			self._list.LDelRow(1, index)
-		del self.items[index]
-	
-	def __getslice__(self, a, b):
-		return self.items[a:b]
-	
-	def __delslice__(self, a, b):
-		if b-a:
-			if self._parent and self._list:
-				self._list.LDelRow(b-a, a)
-			del self.items[a:b]
-	
-	def __setslice__(self, a, b, items):
-		if self._parent and self._list:
-			l = len(items)
-			the_list = self._list
-			self.setdrawingmode(0)
-			if b-a:
-				if b > len(self.items):
-					# fix for new 1.5 "feature" where b is sys.maxint instead of len(self)...
-					# LDelRow doesn't like maxint.
-					b = len(self.items)
-				the_list.LDelRow(b-a, a)
-			the_list.LAddRow(l, a)
-			self_itemrepr = self.itemrepr
-			set_cell = the_list.LSetCell
-			for i in range(len(items)):
-				set_cell(self_itemrepr(items[i]), (0, i + a))
-			self.items[a:b] = items
-			self.setdrawingmode(1)
-		else:
-			self.items[a:b] = items
-	
-	def __len__(self):
-		return len(self.items)
-	
-	def append(self, item):
-		if self._parent and self._list:
-			index = len(self.items)
-			self._list.LAddRow(1, index)
-			self._list.LSetCell(self.itemrepr(item), (0, index))
-		self.items.append(item)
-	
-	def remove(self, item):
-		index = self.items.index(item)
-		self.__delitem__(index)
-	
-	def index(self, item):
-		return self.items.index(item)
-	
-	def insert(self, index, item):
-		if index < 0:
-			index = 0
-		if self._parent and self._list:
-			self._list.LAddRow(1, index)
-			self._list.LSetCell(self.itemrepr(item), (0, index))
-		self.items.insert(index, item)
-	
-	def setdrawingmode(self, onoff):
-		if onoff:
-			self.drawingmode = self.drawingmode - 1
-			if self.drawingmode == 0 and self._list is not None:
-				self._list.LSetDrawingMode(1)
-				if self._visible:
-					bounds = l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
-					cl, ct, cr, cb = self._list.LRect((0, len(self.items)-1))
-					if cb < b:
-						self.SetPort()
-						Qd.EraseRect((l, cb, cr, b))
-					self._list.LUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
-					self.GetWindow().ValidWindowRect(bounds)
-		else:
-			if self.drawingmode == 0 and self._list is not None:
-				self._list.LSetDrawingMode(0)
-			self.drawingmode = self.drawingmode + 1
+    """Standard list widget."""
+
+    LDEF_ID = 0
+
+    def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1, typingcasesens=0):
+        if items is None:
+            items = []
+        self.items = items
+        Wbase.SelectableWidget.__init__(self, possize)
+        self._selected = 0
+        self._enabled = 1
+        self._list = None
+        self._cols = cols
+        self._callback = callback
+        self._flags = flags
+        self.typingcasesens = typingcasesens
+        self.lasttyping = ""
+        self.lasttime = Evt.TickCount()
+        self.timelimit = 30
+        self.setitems(items)
+        self.drawingmode = 0
+
+    def open(self):
+        self.setdrawingmode(0)
+        self.createlist()
+        self.setdrawingmode(1)
+
+    def createlist(self):
+        self._calcbounds()
+        self.SetPort()
+        rect = self._bounds
+        rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
+        self._viewbounds = rect
+        self._list = LNew(rect, (0, 0, self._cols, 0), (0, 0), self.LDEF_ID, self._parentwindow.wid,
+                                0, 1, 0, 1)
+        if self.drawingmode:
+            self._list.LSetDrawingMode(0)
+        self._list.selFlags = self._flags
+        self.setitems(self.items)
+        if hasattr(self, "_sel"):
+            self.setselection(self._sel)
+            del self._sel
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        # Appearance frames are drawn outside the specified bounds,
+        # so we always need to outset the invalidated area.
+        self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
+        self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
+
+        if oldbounds[:2] == self._bounds[:2]:
+            # set visRgn to empty, to prevent nasty drawing side effect of LSize()
+            Qd.RectRgn(self._parentwindow.wid.GetWindowPort().visRgn, (0, 0, 0, 0))
+            # list still has the same upper/left coordinates, use LSize
+            l, t, r, b = self._bounds
+            width = r - l - 17
+            height = b - t - 2
+            vl, vt, vr, vb = self._viewbounds
+            self._viewbounds = vl, vt, vl + width, vt + height
+            self._list.LSize(width, height)
+            # now *why* doesn't the list manager recalc the cellrect???
+            l, t, r, b = self._list.LRect((0,0))
+            cellheight = b - t
+            self._list.LCellSize((width/self._cols, cellheight))
+            # reset visRgn
+            self._parentwindow.wid.CalcVis()
+        else:
+            # oh well, since the list manager doesn't have a LMove call,
+            # we have to make the list all over again...
+            sel = self.getselection()
+            topcell = self.gettopcell()
+            self._list = None
+            self.setdrawingmode(0)
+            self.createlist()
+            self.setselection(sel)
+            self.settopcell(topcell)
+            self.setdrawingmode(1)
+
+    def close(self):
+        self._list = None
+        self._callback = None
+        self.items = []
+        Wbase.SelectableWidget.close(self)
+
+    def set(self, items):
+        self.setitems(items)
+
+    def setitems(self, items):
+        self.items = items
+        the_list = self._list
+        if not self._parent or not self._list:
+            return
+        self.setdrawingmode(0)
+        topcell = self.gettopcell()
+        the_list.LDelRow(0, 1)
+        the_list.LAddRow(len(self.items), 0)
+        self_itemrepr = self.itemrepr
+        set_cell = the_list.LSetCell
+        for i in range(len(items)):
+            set_cell(self_itemrepr(items[i]), (0, i))
+        self.settopcell(topcell)
+        self.setdrawingmode(1)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        isdoubleclick = self._list.LClick(point, modifiers)
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, isdoubleclick)
+        return 1
+
+    def key(self, char, event):
+        (what, message, when, where, modifiers) = event
+        sel = self.getselection()
+        newselection = []
+        if char == Wkeys.uparrowkey:
+            if len(sel) >= 1 and min(sel) > 0:
+                newselection = [min(sel) - 1]
+            else:
+                newselection = [0]
+        elif char == Wkeys.downarrowkey:
+            if len(sel) >= 1 and max(sel) < (len(self.items) - 1):
+                newselection = [max(sel) + 1]
+            else:
+                newselection = [len(self.items) - 1]
+        else:
+            modifiers = 0
+            if (self.lasttime + self.timelimit) < Evt.TickCount():
+                self.lasttyping = ""
+            if self.typingcasesens:
+                self.lasttyping = self.lasttyping + char
+            else:
+                self.lasttyping = self.lasttyping + string.lower(char)
+            self.lasttime = Evt.TickCount()
+            i = self.findmatch(self.lasttyping)
+            newselection = [i]
+        if modifiers & Events.shiftKey and not self._list.selFlags & Lists.lOnlyOne:
+            newselection = newselection + sel
+        self.setselection(newselection)
+        self._list.LAutoScroll()
+        self.click((-1, -1), 0)
+
+    def findmatch(self, tag):
+        lower = string.lower
+        items = self.items
+        typingcasesens = self.typingcasesens
+        taglen = len(tag)
+        match = '\377' * 100
+        match_i = -1
+        for i in range(len(items)):
+            item = str(items[i])
+            if not typingcasesens:
+                item = lower(item)
+            if tag <= item < match:
+                match = item
+                match_i = i
+        if match_i >= 0:
+            return match_i
+        else:
+            return len(items) - 1
+
+    def domenu_copy(self, *args):
+        sel = self.getselection()
+        selitems = []
+        for i in sel:
+            selitems.append(str(self.items[i]))
+        text = string.join(selitems, '\r')
+        if text:
+            if hasattr(Scrap, 'PutScrap'):
+                Scrap.ZeroScrap()
+                Scrap.PutScrap('TEXT', text)
+            else:
+                Scrap.ClearCurrentScrap()
+                sc = Scrap.GetCurrentScrap()
+                sc.PutScrapFlavor('TEXT', 0, text)
+
+    def can_copy(self, *args):
+        return len(self.getselection()) <> 0
+
+    def domenu_selectall(self, *args):
+        self.selectall()
+
+    def can_selectall(self, *args):
+        return not self._list.selFlags & Lists.lOnlyOne
+
+    def selectall(self):
+        if not self._list.selFlags & Lists.lOnlyOne:
+            self.setselection(range(len(self.items)))
+            self._list.LAutoScroll()
+            self.click((-1, -1), 0)
+
+    def getselection(self):
+        if not self._parent or not self._list:
+            if hasattr(self, "_sel"):
+                return self._sel
+            return []
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self._list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        return items
+
+    def setselection(self, selection):
+        if not self._parent or not self._list:
+            self._sel = selection
+            return
+        set_sel = self._list.LSetSelect
+        for i in range(len(self.items)):
+            if i in selection:
+                set_sel(1, (0, i))
+            else:
+                set_sel(0, (0, i))
+        self._list.LAutoScroll()
+
+    def getselectedobjects(self):
+        sel = self.getselection()
+        objects = []
+        for i in sel:
+            objects.append(self.items[i])
+        return objects
+
+    def setselectedobjects(self, objects):
+        sel = []
+        for o in objects:
+            try:
+                sel.append(self.items.index(o))
+            except:
+                pass
+        self.setselection(sel)
+
+    def gettopcell(self):
+        l, t, r, b = self._bounds
+        t = t + 1
+        cl, ct, cr, cb = self._list.LRect((0, 0))
+        cellheight = cb - ct
+        return (t - ct) / cellheight
+
+    def settopcell(self, topcell):
+        top = self.gettopcell()
+        diff = topcell - top
+        self._list.LScroll(0, diff)
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            if not visRgn:
+                visRgn = self._parentwindow.wid.GetWindowPort().visRgn
+            self._list.LUpdate(visRgn)
+            state = [kThemeStateActive, kThemeStateInactive][not self._activated]
+            App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
+            if self._selected and self._activated:
+                self.drawselframe(1)
+
+    def select(self, onoff, isclick = 0):
+        if Wbase.SelectableWidget.select(self, onoff):
+            return
+        self.SetPort()
+        self.drawselframe(onoff)
+
+    def activate(self, onoff):
+        self._activated = onoff
+        if self._visible:
+            self._list.LActivate(onoff)
+            #state = [kThemeStateActive, kThemeStateInactive][not onoff]
+            #App.DrawThemeListBoxFrame(Qd.InsetRect(self._bounds, 1, 1), state)
+            if self._selected:
+                self.drawselframe(onoff)
+
+    def get(self):
+        return self.items
+
+    def itemrepr(self, item):
+        return str(item)[:255]
+
+    def __getitem__(self, index):
+        return self.items[index]
+
+    def __setitem__(self, index, item):
+        if self._parent and self._list:
+            self._list.LSetCell(self.itemrepr(item), (0, index))
+        self.items[index] = item
+
+    def __delitem__(self, index):
+        if self._parent and self._list:
+            self._list.LDelRow(1, index)
+        del self.items[index]
+
+    def __getslice__(self, a, b):
+        return self.items[a:b]
+
+    def __delslice__(self, a, b):
+        if b-a:
+            if self._parent and self._list:
+                self._list.LDelRow(b-a, a)
+            del self.items[a:b]
+
+    def __setslice__(self, a, b, items):
+        if self._parent and self._list:
+            l = len(items)
+            the_list = self._list
+            self.setdrawingmode(0)
+            if b-a:
+                if b > len(self.items):
+                # fix for new 1.5 "feature" where b is sys.maxint instead of len(self)...
+                # LDelRow doesn't like maxint.
+                    b = len(self.items)
+                the_list.LDelRow(b-a, a)
+            the_list.LAddRow(l, a)
+            self_itemrepr = self.itemrepr
+            set_cell = the_list.LSetCell
+            for i in range(len(items)):
+                set_cell(self_itemrepr(items[i]), (0, i + a))
+            self.items[a:b] = items
+            self.setdrawingmode(1)
+        else:
+            self.items[a:b] = items
+
+    def __len__(self):
+        return len(self.items)
+
+    def append(self, item):
+        if self._parent and self._list:
+            index = len(self.items)
+            self._list.LAddRow(1, index)
+            self._list.LSetCell(self.itemrepr(item), (0, index))
+        self.items.append(item)
+
+    def remove(self, item):
+        index = self.items.index(item)
+        self.__delitem__(index)
+
+    def index(self, item):
+        return self.items.index(item)
+
+    def insert(self, index, item):
+        if index < 0:
+            index = 0
+        if self._parent and self._list:
+            self._list.LAddRow(1, index)
+            self._list.LSetCell(self.itemrepr(item), (0, index))
+        self.items.insert(index, item)
+
+    def setdrawingmode(self, onoff):
+        if onoff:
+            self.drawingmode = self.drawingmode - 1
+            if self.drawingmode == 0 and self._list is not None:
+                self._list.LSetDrawingMode(1)
+                if self._visible:
+                    bounds = l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
+                    cl, ct, cr, cb = self._list.LRect((0, len(self.items)-1))
+                    if cb < b:
+                        self.SetPort()
+                        Qd.EraseRect((l, cb, cr, b))
+                    self._list.LUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
+                    self.GetWindow().ValidWindowRect(bounds)
+        else:
+            if self.drawingmode == 0 and self._list is not None:
+                self._list.LSetDrawingMode(0)
+            self.drawingmode = self.drawingmode + 1
 
 
 class CustomList(List):
-	
-	"""Base class for writing custom list definitions."""
-	
-	_cellHeight = 0
-	
-	def createlist(self):
-		self._calcbounds()
-		self.SetPort()
-		rect = self._bounds
-		rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
-		self._viewbounds = rect
-		self._list = CreateCustomList(
-				rect,
-				(0, 0, 1, 0),
-				(0, self._cellHeight),
-				(kListDefUserProcType, self.listDefinitionFunc),
-				self._parentwindow.wid,
-				0, 1, 0, 1)
-		if self.drawingmode:
-			self._list.LSetDrawingMode(0)
-		self._list.selFlags = self._flags
-		self.setitems(self.items)
-		if hasattr(self, "_sel"):
-			self.setselection(self._sel)
-			del self._sel
-	
-	def listDefinitionFunc(self, message, selected, cellRect, theCell,
-			dataOffset, dataLen, theList):
-		"""The LDEF message dispatcher routine, no need to override."""
-		if message == lInitMsg:
-			self.listDefInit(theList)
-		elif message == lDrawMsg:
-			self.listDefDraw(selected, cellRect, theCell,
-					dataOffset, dataLen, theList)
-		elif message == lHiliteMsg:
-			self.listDefHighlight(selected, cellRect, theCell,
-					dataOffset, dataLen, theList)
-		elif message == lCloseMsg:
-			self.listDefClose(theList)
-	
-	def listDefInit(self, theList):
-		pass
-	def listDefClose(self, theList):
-		pass
-	def listDefDraw(self, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList):
-		pass
-	def listDefHighlight(self, selected, cellRect, theCell, 
-			dataOffset, dataLen, theList):
-		pass
+
+    """Base class for writing custom list definitions."""
+
+    _cellHeight = 0
+
+    def createlist(self):
+        self._calcbounds()
+        self.SetPort()
+        rect = self._bounds
+        rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
+        self._viewbounds = rect
+        self._list = CreateCustomList(
+                        rect,
+                        (0, 0, 1, 0),
+                        (0, self._cellHeight),
+                        (kListDefUserProcType, self.listDefinitionFunc),
+                        self._parentwindow.wid,
+                        0, 1, 0, 1)
+        if self.drawingmode:
+            self._list.LSetDrawingMode(0)
+        self._list.selFlags = self._flags
+        self.setitems(self.items)
+        if hasattr(self, "_sel"):
+            self.setselection(self._sel)
+            del self._sel
+
+    def listDefinitionFunc(self, message, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        """The LDEF message dispatcher routine, no need to override."""
+        if message == lInitMsg:
+            self.listDefInit(theList)
+        elif message == lDrawMsg:
+            self.listDefDraw(selected, cellRect, theCell,
+                            dataOffset, dataLen, theList)
+        elif message == lHiliteMsg:
+            self.listDefHighlight(selected, cellRect, theCell,
+                            dataOffset, dataLen, theList)
+        elif message == lCloseMsg:
+            self.listDefClose(theList)
+
+    def listDefInit(self, theList):
+        pass
+    def listDefClose(self, theList):
+        pass
+    def listDefDraw(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        pass
+    def listDefHighlight(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        pass
 
 
 class TwoLineList(CustomList):
-	
-	_cellHeight = 28
-	
-	def listDefDraw(self, selected, cellRect, theCell,
-			dataOffset, dataLen, theList):
-		savedPort = Qd.GetPort()
-		Qd.SetPort(theList.GetListPort())
-		savedClip = Qd.NewRgn()
-		Qd.GetClip(savedClip)
-		Qd.ClipRect(cellRect)
-		savedPenState = Qd.GetPenState()
-		Qd.PenNormal()
-		Qd.EraseRect(cellRect)
-		
-		#draw the cell if it contains data
-		ascent, descent, leading, size, hm = Fm.FontMetrics()
-		linefeed = ascent + descent + leading
-		
-		if dataLen:
-			left, top, right, bottom = cellRect
-			data = theList.LGetCell(dataLen, theCell)
-			lines = data.split("\r")
-			line1 = lines[0]
-			if len(lines) > 1:
-				line2 = lines[1]
-			else:
-				line2 = ""
-			Qd.MoveTo(int(left + 4), int(top + ascent))
-			Qd.DrawText(line1, 0, len(line1))
-			if line2:
-				Qd.MoveTo(int(left + 4), int(top + ascent + linefeed))
-				Qd.DrawText(line2, 0, len(line2))
-			Qd.PenPat("\x11\x11\x11\x11\x11\x11\x11\x11")
-			bottom = top + theList.cellSize[1]
-			Qd.MoveTo(left, bottom - 1)
-			Qd.LineTo(right, bottom - 1)
-		if selected:
-			self.listDefHighlight(selected, cellRect, theCell,
-					dataOffset, dataLen, theList)
-		#restore graphics environment
-		Qd.SetPort(savedPort)
-		Qd.SetClip(savedClip)
-		Qd.DisposeRgn(savedClip)
-		Qd.SetPenState(savedPenState)
-	
-	def listDefHighlight(self, selected, cellRect, theCell,
-			dataOffset, dataLen, theList):
-		savedPort = Qd.GetPort()
-		Qd.SetPort(theList.GetListPort())
-		savedClip = Qd.NewRgn()
-		Qd.GetClip(savedClip)
-		Qd.ClipRect(cellRect)
-		savedPenState = Qd.GetPenState()
-		Qd.PenNormal()
-		Qd.PenMode(hilitetransfermode)
-		Qd.PaintRect(cellRect)
-		
-		#restore graphics environment
-		Qd.SetPort(savedPort)
-		Qd.SetClip(savedClip)
-		Qd.DisposeRgn(savedClip)
-		Qd.SetPenState(savedPenState)
-	
+
+    _cellHeight = 28
+
+    def listDefDraw(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        savedPort = Qd.GetPort()
+        Qd.SetPort(theList.GetListPort())
+        savedClip = Qd.NewRgn()
+        Qd.GetClip(savedClip)
+        Qd.ClipRect(cellRect)
+        savedPenState = Qd.GetPenState()
+        Qd.PenNormal()
+        Qd.EraseRect(cellRect)
+
+        #draw the cell if it contains data
+        ascent, descent, leading, size, hm = Fm.FontMetrics()
+        linefeed = ascent + descent + leading
+
+        if dataLen:
+            left, top, right, bottom = cellRect
+            data = theList.LGetCell(dataLen, theCell)
+            lines = data.split("\r")
+            line1 = lines[0]
+            if len(lines) > 1:
+                line2 = lines[1]
+            else:
+                line2 = ""
+            Qd.MoveTo(int(left + 4), int(top + ascent))
+            Qd.DrawText(line1, 0, len(line1))
+            if line2:
+                Qd.MoveTo(int(left + 4), int(top + ascent + linefeed))
+                Qd.DrawText(line2, 0, len(line2))
+            Qd.PenPat("\x11\x11\x11\x11\x11\x11\x11\x11")
+            bottom = top + theList.cellSize[1]
+            Qd.MoveTo(left, bottom - 1)
+            Qd.LineTo(right, bottom - 1)
+        if selected:
+            self.listDefHighlight(selected, cellRect, theCell,
+                            dataOffset, dataLen, theList)
+        #restore graphics environment
+        Qd.SetPort(savedPort)
+        Qd.SetClip(savedClip)
+        Qd.DisposeRgn(savedClip)
+        Qd.SetPenState(savedPenState)
+
+    def listDefHighlight(self, selected, cellRect, theCell,
+                    dataOffset, dataLen, theList):
+        savedPort = Qd.GetPort()
+        Qd.SetPort(theList.GetListPort())
+        savedClip = Qd.NewRgn()
+        Qd.GetClip(savedClip)
+        Qd.ClipRect(cellRect)
+        savedPenState = Qd.GetPenState()
+        Qd.PenNormal()
+        Qd.PenMode(hilitetransfermode)
+        Qd.PaintRect(cellRect)
+
+        #restore graphics environment
+        Qd.SetPort(savedPort)
+        Qd.SetClip(savedClip)
+        Qd.DisposeRgn(savedClip)
+        Qd.SetPenState(savedPenState)
+
 
 class ResultsWindow:
-	
-	"""Simple results window. The user cannot make this window go away completely:
-	closing it will just hide it. It will remain in the windows list. The owner of this window
-	should call the done() method to indicate it's done with it.
-	"""
-	
-	def __init__(self, possize=None, title="Results", callback=None):
-		import W
-		if possize is None:
-			possize = (500, 200)
-		self.w = W.Window(possize, title, minsize=(200, 100))
-		self.w.results = W.TwoLineList((-1, -1, 1, -14), callback=None)
-		self.w.bind("<close>", self.hide)
-		self.w.open()
-		self._done = 0
-	
-	def done(self):
-		self._done = 1
-		if not self.w.isvisible():
-			self.w.close()
-	
-	def hide(self):
-		if not self._done:
-			self.w.show(0)
-			return -1
-	
-	def append(self, msg):
-		if not self.w.isvisible():
-			self.w.show(1)
-			self.w.select()
-		msg = string.replace(msg, '\n', '\r')
-		self.w.results.append(msg)
-		self.w.results.setselection([len(self.w.results)-1])
-	
-	def __getattr__(self, attr):
-		return getattr(self.w.results, attr)
+
+    """Simple results window. The user cannot make this window go away completely:
+    closing it will just hide it. It will remain in the windows list. The owner of this window
+    should call the done() method to indicate it's done with it.
+    """
+
+    def __init__(self, possize=None, title="Results", callback=None):
+        import W
+        if possize is None:
+            possize = (500, 200)
+        self.w = W.Window(possize, title, minsize=(200, 100))
+        self.w.results = W.TwoLineList((-1, -1, 1, -14), callback=None)
+        self.w.bind("<close>", self.hide)
+        self.w.open()
+        self._done = 0
+
+    def done(self):
+        self._done = 1
+        if not self.w.isvisible():
+            self.w.close()
+
+    def hide(self):
+        if not self._done:
+            self.w.show(0)
+            return -1
+
+    def append(self, msg):
+        if not self.w.isvisible():
+            self.w.show(1)
+            self.w.select()
+        msg = string.replace(msg, '\n', '\r')
+        self.w.results.append(msg)
+        self.w.results.setselection([len(self.w.results)-1])
+
+    def __getattr__(self, attr):
+        return getattr(self.w.results, attr)
 
 
 class MultiList(List):
-	
-	"""XXX Experimantal!!!"""
-	
-	def setitems(self, items):
-		self.items = items
-		if not self._parent or not self._list:
-			return
-		self._list.LDelRow(0, 1)
-		self.setdrawingmode(0)
-		self._list.LAddRow(len(self.items), 0)
-		self_itemrepr = self.itemrepr
-		set_cell = self._list.LSetCell
-		for i in range(len(items)):
-			row = items[i]
-			for j in range(len(row)):
-				item = row[j]
-				set_cell(self_itemrepr(item), (j, i))
-		self.setdrawingmode(1)
-	
-	def getselection(self):
-		if not self._parent or not self._list:
-			if hasattr(self, "_sel"):
-				return self._sel
-			return []
-		items = []
-		point = (0,0)
-		while 1:
-			ok, point = self._list.LGetSelect(1, point)
-			if not ok:
-				break
-			items.append(point[1])
-			point = point[0], point[1]+1
-		return items
-	
-	def setselection(self, selection):
-		if not self._parent or not self._list:
-			self._sel = selection
-			return
-		set_sel = self._list.LSetSelect
-		for i in range(len(self.items)):
-			for j in range(len(self.items[i])):
-				if i in selection:
-					set_sel(1, (j, i))
-				else:
-					set_sel(0, (j, i))
-		#self._list.LAutoScroll()
 
+    """XXX Experimantal!!!"""
+
+    def setitems(self, items):
+        self.items = items
+        if not self._parent or not self._list:
+            return
+        self._list.LDelRow(0, 1)
+        self.setdrawingmode(0)
+        self._list.LAddRow(len(self.items), 0)
+        self_itemrepr = self.itemrepr
+        set_cell = self._list.LSetCell
+        for i in range(len(items)):
+            row = items[i]
+            for j in range(len(row)):
+                item = row[j]
+                set_cell(self_itemrepr(item), (j, i))
+        self.setdrawingmode(1)
+
+    def getselection(self):
+        if not self._parent or not self._list:
+            if hasattr(self, "_sel"):
+                return self._sel
+            return []
+        items = []
+        point = (0,0)
+        while 1:
+            ok, point = self._list.LGetSelect(1, point)
+            if not ok:
+                break
+            items.append(point[1])
+            point = point[0], point[1]+1
+        return items
+
+    def setselection(self, selection):
+        if not self._parent or not self._list:
+            self._sel = selection
+            return
+        set_sel = self._list.LSetSelect
+        for i in range(len(self.items)):
+            for j in range(len(self.items[i])):
+                if i in selection:
+                    set_sel(1, (j, i))
+                else:
+                    set_sel(0, (j, i))
+        #self._list.LAutoScroll()
diff --git a/Mac/Tools/IDE/Wmenus.py b/Mac/Tools/IDE/Wmenus.py
index bd119a5..01a8e1c 100644
--- a/Mac/Tools/IDE/Wmenus.py
+++ b/Mac/Tools/IDE/Wmenus.py
@@ -8,252 +8,252 @@
 #_arrowdown = Qd.GetPicture(473)
 
 _arrowright = Res.Resource(
-	'\x00I\x00\x00\x00\x00\x00\n\x00\n\x11\x01\x01\x00\n\x00\x00\x00'
-	'\x00\x00\n\x00\n\x90\x00\x02\x00\x00\x00\x00\x00\n\x00\n\x00\x00'
-	'\x00\x00\x00\n\x00\n\x00\x00\x00\x00\x00\n\x00\n\x00\x00\x10\x00'
-	'\x18\x00\x1c\x00\x1e\x00\x1f\x00\x1f\x00\x1e\x00\x1c\x00\x18\x00'
-	'\x10\x00\xff')
+        '\x00I\x00\x00\x00\x00\x00\n\x00\n\x11\x01\x01\x00\n\x00\x00\x00'
+        '\x00\x00\n\x00\n\x90\x00\x02\x00\x00\x00\x00\x00\n\x00\n\x00\x00'
+        '\x00\x00\x00\n\x00\n\x00\x00\x00\x00\x00\n\x00\n\x00\x00\x10\x00'
+        '\x18\x00\x1c\x00\x1e\x00\x1f\x00\x1f\x00\x1e\x00\x1c\x00\x18\x00'
+        '\x10\x00\xff')
 
 
 class PopupControl(Wcontrols.ControlWidget):
-	
-	def __init__(self, possize, items=None, callback=None):
-		if items is None:
-			items = []
-		procID = Controls.popupMenuProc|Controls.popupFixedWidth|Controls.useWFont
-		Wcontrols.ControlWidget.__init__(self, possize, "", procID, callback, 0, 0, 0)
-		self._items = items[:]
-	
-	def set(self, value):
-		self._control.SetControlValue(value+1)
-	
-	def get(self):
-		return self._control.GetControlValue() - 1
-	
-	def open(self):
-		self.menu = menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
-		
-		for i in range(len(self._items)):
-			item = self._items[i]
-			if type(item) == StringType:
-				menuitemtext = object = item
-			elif type(item) == TupleType and len(item) == 2:
-				menuitemtext, object = item
-				self._items[i] = object
-			else:
-				raise Wbase.WidgetsError, "illegal itemlist for popup menu"
-			menuitem = FrameWork.MenuItem(menu, menuitemtext, None, None)
-		
-		self._calcbounds()
-		self._control = Ctl.NewControl(self._parentwindow.wid, 
-						self._bounds, 
-						self._title, 
-						1, 
-						self._value, 
-						self.menu.id, 
-						self._max, 
-						self._procID, 
-						0)
-		self.SetPort()
-		self.enable(self._enabled)
-	
-	def close(self):
-		self.menu.delete()
-		return Wcontrols.ControlWidget.close(self)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		part = self._control.TrackControl(point, -1)
-		if part:
-			if self._callback:
-				Wbase.CallbackCall(self._callback, 0, self._items[self.get()])
+
+    def __init__(self, possize, items=None, callback=None):
+        if items is None:
+            items = []
+        procID = Controls.popupMenuProc|Controls.popupFixedWidth|Controls.useWFont
+        Wcontrols.ControlWidget.__init__(self, possize, "", procID, callback, 0, 0, 0)
+        self._items = items[:]
+
+    def set(self, value):
+        self._control.SetControlValue(value+1)
+
+    def get(self):
+        return self._control.GetControlValue() - 1
+
+    def open(self):
+        self.menu = menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
+
+        for i in range(len(self._items)):
+            item = self._items[i]
+            if type(item) == StringType:
+                menuitemtext = object = item
+            elif type(item) == TupleType and len(item) == 2:
+                menuitemtext, object = item
+                self._items[i] = object
+            else:
+                raise Wbase.WidgetsError, "illegal itemlist for popup menu"
+            menuitem = FrameWork.MenuItem(menu, menuitemtext, None, None)
+
+        self._calcbounds()
+        self._control = Ctl.NewControl(self._parentwindow.wid,
+                                        self._bounds,
+                                        self._title,
+                                        1,
+                                        self._value,
+                                        self.menu.id,
+                                        self._max,
+                                        self._procID,
+                                        0)
+        self.SetPort()
+        self.enable(self._enabled)
+
+    def close(self):
+        self.menu.delete()
+        return Wcontrols.ControlWidget.close(self)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        part = self._control.TrackControl(point, -1)
+        if part:
+            if self._callback:
+                Wbase.CallbackCall(self._callback, 0, self._items[self.get()])
 
 
 class PopupWidget(Wbase.ClickableWidget):
-	
-	"""Simple title-less popup widget. Should be 16x16 pixels. 
-	Builds the menu items on the fly, good for dynamic popup menus."""
-	
-	def __init__(self, possize, items=None, callback=None):
-		Wbase.ClickableWidget.__init__(self, possize)
-		if items is None:
-			items = []
-		self._items = items
-		self._itemsdict = {}
-		self._callback = callback
-		self._enabled = 1
-	
-	def close(self):
-		Wbase.ClickableWidget.close(self)
-		self._items = None
-		self._itemsdict = {}
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			Qd.FrameRect(self._bounds)
-			Qd.EraseRect(Qd.InsetRect(self._bounds, 1, 1))
-			l, t, r, b = self._bounds
-			l = l + 2
-			t = t + 3
-			pictframe = (l, t, l + 10, t + 10)
-			Qd.DrawPicture(_arrowright, pictframe)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		self.menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
-		self._additems(self._items, self.menu)
-		self.SetPort()
-		l, t, r, b = self._bounds
-		l, t = Qd.LocalToGlobal((l+1, t+1))
-		Wbase.SetCursor("arrow")
-		self.menu.menu.EnableMenuItem(0)
-		reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
-		if reply:
-			id = reply >> 16
-			item = reply & 0xffff
-			self._menu_callback(id, item)
-		self._emptymenu()
-	
-	def set(self, items):
-		self._items = items
-	
-	def get(self):
-		return self._items
-	
-	def _additems(self, items, menu):
-		from FrameWork import SubMenu, MenuItem
-		menu_id = menu.id
-		for item in items:
-			if item == "-":
-				menu.addseparator()
-				continue
-			elif type(item) == ListType:
-				submenu = SubMenu(menu, item[0])
-				self._additems(item[1:], submenu)
-				continue
-			elif type(item) == StringType:
-				menuitemtext = object = item
-			elif type(item) == TupleType and len(item) == 2:
-				menuitemtext, object = item
-			else:
-				raise Wbase.WidgetsError, "illegal itemlist for popup menu"
-			
-			if menuitemtext[:1] == '\0':
-				check = ord(menuitemtext[1])
-				menuitemtext = menuitemtext[2:]
-			else:
-				check = 0
-			menuitem = MenuItem(menu, menuitemtext, None, None)
-			if check:
-				menuitem.check(1)
-			self._itemsdict[(menu_id, menuitem.item)] = object
-	
-	def _emptymenu(self):
-		menus = self._parentwindow.parent.menubar.menus
-		for id, item in self._itemsdict.keys():
-			if menus.has_key(id):
-				self.menu = menus[id]
-				self.menu.delete()
-		self._itemsdict = {}
-	
-	def _menu_callback(self, id, item):
-		thing = self._itemsdict[(id, item)]
-		if callable(thing):
-			thing()
-		elif self._callback:
-			Wbase.CallbackCall(self._callback, 0, thing)
+
+    """Simple title-less popup widget. Should be 16x16 pixels.
+    Builds the menu items on the fly, good for dynamic popup menus."""
+
+    def __init__(self, possize, items=None, callback=None):
+        Wbase.ClickableWidget.__init__(self, possize)
+        if items is None:
+            items = []
+        self._items = items
+        self._itemsdict = {}
+        self._callback = callback
+        self._enabled = 1
+
+    def close(self):
+        Wbase.ClickableWidget.close(self)
+        self._items = None
+        self._itemsdict = {}
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            Qd.FrameRect(self._bounds)
+            Qd.EraseRect(Qd.InsetRect(self._bounds, 1, 1))
+            l, t, r, b = self._bounds
+            l = l + 2
+            t = t + 3
+            pictframe = (l, t, l + 10, t + 10)
+            Qd.DrawPicture(_arrowright, pictframe)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        self.menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
+        self._additems(self._items, self.menu)
+        self.SetPort()
+        l, t, r, b = self._bounds
+        l, t = Qd.LocalToGlobal((l+1, t+1))
+        Wbase.SetCursor("arrow")
+        self.menu.menu.EnableMenuItem(0)
+        reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
+        if reply:
+            id = reply >> 16
+            item = reply & 0xffff
+            self._menu_callback(id, item)
+        self._emptymenu()
+
+    def set(self, items):
+        self._items = items
+
+    def get(self):
+        return self._items
+
+    def _additems(self, items, menu):
+        from FrameWork import SubMenu, MenuItem
+        menu_id = menu.id
+        for item in items:
+            if item == "-":
+                menu.addseparator()
+                continue
+            elif type(item) == ListType:
+                submenu = SubMenu(menu, item[0])
+                self._additems(item[1:], submenu)
+                continue
+            elif type(item) == StringType:
+                menuitemtext = object = item
+            elif type(item) == TupleType and len(item) == 2:
+                menuitemtext, object = item
+            else:
+                raise Wbase.WidgetsError, "illegal itemlist for popup menu"
+
+            if menuitemtext[:1] == '\0':
+                check = ord(menuitemtext[1])
+                menuitemtext = menuitemtext[2:]
+            else:
+                check = 0
+            menuitem = MenuItem(menu, menuitemtext, None, None)
+            if check:
+                menuitem.check(1)
+            self._itemsdict[(menu_id, menuitem.item)] = object
+
+    def _emptymenu(self):
+        menus = self._parentwindow.parent.menubar.menus
+        for id, item in self._itemsdict.keys():
+            if menus.has_key(id):
+                self.menu = menus[id]
+                self.menu.delete()
+        self._itemsdict = {}
+
+    def _menu_callback(self, id, item):
+        thing = self._itemsdict[(id, item)]
+        if callable(thing):
+            thing()
+        elif self._callback:
+            Wbase.CallbackCall(self._callback, 0, thing)
 
 
 class PopupMenu(PopupWidget):
-	
-	"""Simple title-less popup widget. Should be 16x16 pixels. 
-	Prebuilds the menu items, good for static (non changing) popup menus."""
-	
-	def open(self):
-		self._calcbounds()
-		self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
-		self._additems(self._items, self.menu)
-	
-	def close(self):
-		self._emptymenu()
-		Wbase.Widget.close(self)
-		self._items = None
-		self._itemsdict = {}
-		self.menu = None
-	
-	def set(self, items):
-		if self._itemsdict:
-			self._emptymenu()
-		self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
-		self._items = items
-		self._additems(self._items, self.menu)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		self.SetPort()
-		l, t, r, b = self._bounds
-		l, t = Qd.LocalToGlobal((l+1, t+1))
-		Wbase.SetCursor("arrow")
-		self.menu.menu.EnableMenuItem(0)
-		reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
-		if reply:
-			id = reply >> 16
-			item = reply & 0xffff
-			self._menu_callback(id, item)
+
+    """Simple title-less popup widget. Should be 16x16 pixels.
+    Prebuilds the menu items, good for static (non changing) popup menus."""
+
+    def open(self):
+        self._calcbounds()
+        self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
+        self._additems(self._items, self.menu)
+
+    def close(self):
+        self._emptymenu()
+        Wbase.Widget.close(self)
+        self._items = None
+        self._itemsdict = {}
+        self.menu = None
+
+    def set(self, items):
+        if self._itemsdict:
+            self._emptymenu()
+        self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
+        self._items = items
+        self._additems(self._items, self.menu)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        self.SetPort()
+        l, t, r, b = self._bounds
+        l, t = Qd.LocalToGlobal((l+1, t+1))
+        Wbase.SetCursor("arrow")
+        self.menu.menu.EnableMenuItem(0)
+        reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
+        if reply:
+            id = reply >> 16
+            item = reply & 0xffff
+            self._menu_callback(id, item)
 
 
 class FontMenu(PopupMenu):
-	
-	"""A font popup menu."""
-	
-	menu = None
-	
-	def __init__(self, possize, callback):
-		PopupMenu.__init__(self, possize)
-		_makefontmenu()
-		self._callback = callback
-		self._enabled = 1
-	
-	def open(self):
-		self._calcbounds()
-	
-	def close(self):
-		del self._callback
-	
-	def set(self):
-		raise Wbase.WidgetsError, "can't change font menu widget"
-	
-	def _menu_callback(self, id, item):
-		fontname = self.menu.menu.GetMenuItemText(item)
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, fontname)
 
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		_makefontmenu()
-		return PopupMenu.click(self, point, modifiers)
-	
+    """A font popup menu."""
+
+    menu = None
+
+    def __init__(self, possize, callback):
+        PopupMenu.__init__(self, possize)
+        _makefontmenu()
+        self._callback = callback
+        self._enabled = 1
+
+    def open(self):
+        self._calcbounds()
+
+    def close(self):
+        del self._callback
+
+    def set(self):
+        raise Wbase.WidgetsError, "can't change font menu widget"
+
+    def _menu_callback(self, id, item):
+        fontname = self.menu.menu.GetMenuItemText(item)
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, fontname)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        _makefontmenu()
+        return PopupMenu.click(self, point, modifiers)
+
 
 def _makefontmenu():
-	"""helper for font menu"""
-	if FontMenu.menu is not None:
-		return
-	import W
-	FontMenu.menu = Wapplication.Menu(W.getapplication().menubar, 'Foo', -1)
-	W.SetCursor('watch')
-	for i in range(FontMenu.menu.menu.CountMenuItems(), 0, -1):
-		FontMenu.menu.menu.DeleteMenuItem(i)
-	FontMenu.menu.menu.AppendResMenu('FOND')
+    """helper for font menu"""
+    if FontMenu.menu is not None:
+        return
+    import W
+    FontMenu.menu = Wapplication.Menu(W.getapplication().menubar, 'Foo', -1)
+    W.SetCursor('watch')
+    for i in range(FontMenu.menu.menu.CountMenuItems(), 0, -1):
+        FontMenu.menu.menu.DeleteMenuItem(i)
+    FontMenu.menu.menu.AppendResMenu('FOND')
 
 
 def _getfontlist():
-	from Carbon import Res
-	fontnames = []
-	for i in range(1, Res.CountResources('FOND') + 1):
-		r = Res.GetIndResource('FOND', i)
-		fontnames.append(r.GetResInfo()[2])
-	return fontnames
+    from Carbon import Res
+    fontnames = []
+    for i in range(1, Res.CountResources('FOND') + 1):
+        r = Res.GetIndResource('FOND', i)
+        fontnames.append(r.GetResInfo()[2])
+    return fontnames
diff --git a/Mac/Tools/IDE/Wminiapp.py b/Mac/Tools/IDE/Wminiapp.py
index e09e334..0c51583 100644
--- a/Mac/Tools/IDE/Wminiapp.py
+++ b/Mac/Tools/IDE/Wminiapp.py
@@ -5,18 +5,18 @@
 import os
 
 class TestApp(Wapplication.Application):
-	
-	def __init__(self):
-		from Carbon import Res
-#		macresource.open_pathname("Widgets.rsrc")
-		self._menustocheck = []
-		self.preffilepath = os.path.join("Python", "PythonIDE preferences")
-		Wapplication.Application.__init__(self, 'Pyth')
-		# open a new text editor
-		import PyEdit
-		PyEdit.Editor()
-		# start the mainloop
-		self.mainloop()
-	
+
+    def __init__(self):
+        from Carbon import Res
+#               macresource.open_pathname("Widgets.rsrc")
+        self._menustocheck = []
+        self.preffilepath = os.path.join("Python", "PythonIDE preferences")
+        Wapplication.Application.__init__(self, 'Pyth')
+        # open a new text editor
+        import PyEdit
+        PyEdit.Editor()
+        # start the mainloop
+        self.mainloop()
+
 
 TestApp()
diff --git a/Mac/Tools/IDE/Wquicktime.py b/Mac/Tools/IDE/Wquicktime.py
index 421d558..671aa09 100644
--- a/Mac/Tools/IDE/Wquicktime.py
+++ b/Mac/Tools/IDE/Wquicktime.py
@@ -9,106 +9,105 @@
 _moviesinitialized = 0
 
 def EnterMovies():
-	global _moviesinitialized
-	if not _moviesinitialized:
-		Qt.EnterMovies()
-		_moviesinitialized = 1
+    global _moviesinitialized
+    if not _moviesinitialized:
+        Qt.EnterMovies()
+        _moviesinitialized = 1
 
 class Movie(W.Widget):
-	
-	def __init__(self, possize):
-		EnterMovies()
-		self.movie = None
-		self.running = 0
-		W.Widget.__init__(self, possize)
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(oldbounds)
-		self.GetWindow().InvalWindowRect(self._bounds)
-		self.calcmoviebox()
-	
-	def set(self, path_or_fss, start = 0):
-		self.SetPort()
-		if self.movie:
-			#self.GetWindow().InvalWindowRect(self.movie.GetMovieBox())
-			Qd.PaintRect(self.movie.GetMovieBox())
-		path = File.pathname(path)
-		self.movietitle = os.path.basename(path)
-		movieResRef = Qt.OpenMovieFile(path_or_fss, 1)
-		self.movie, dummy, dummy = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
-		self.moviebox = self.movie.GetMovieBox()
-		self.calcmoviebox()
-		Qd.ObscureCursor()	# XXX does this work at all?
-		self.movie.GoToBeginningOfMovie()
-		if start:
-			self.movie.StartMovie()
-			self.running = 1
-		else:
-			self.running = 0
-			self.movie.MoviesTask(0)
-	
-	def get(self):
-		return self.movie
-	
-	def getmovietitle(self):
-		return self.movietitle
-	
-	def start(self):
-		if self.movie:
-			Qd.ObscureCursor()
-			self.movie.StartMovie()
-			self.running = 1
-	
-	def stop(self):
-		if self.movie:
-			self.movie.StopMovie()
-			self.running = 0
-	
-	def rewind(self):
-		if self.movie:
-			self.movie.GoToBeginningOfMovie()
-	
-	def calcmoviebox(self):
-		if not self.movie:
-			return
-		ml, mt, mr, mb = self.moviebox
-		wl, wt, wr, wb = widgetbox = self._bounds
-		mheight = mb - mt
-		mwidth = mr - ml
-		wheight = wb - wt
-		wwidth = wr - wl
-		if (mheight * 2 < wheight) and (mwidth * 2 < wwidth):
-			scale = 2
-		elif mheight > wheight or mwidth > wwidth:
-			scale = min(float(wheight) / mheight, float(wwidth) / mwidth)
-		else:
-			scale = 1
-		mwidth, mheight = mwidth * scale, mheight * scale
-		ml, mt = wl + (wwidth - mwidth) / 2, wt + (wheight - mheight) / 2
-		mr, mb = ml + mwidth, mt + mheight
-		self.movie.SetMovieBox((ml, mt, mr, mb))
-	
-	def idle(self, *args):
-		if self.movie:
-			if not self.movie.IsMovieDone() and self.running:
-				Qd.ObscureCursor()
-				while 1:
-					self.movie.MoviesTask(0)
-					gotone, event = Evt.EventAvail(Events.everyEvent)
-					if gotone or self.movie.IsMovieDone():
-						break
-			elif self.running:
-				box = self.movie.GetMovieBox()
-				self.SetPort()
-				self.GetWindow().InvalWindowRect(box)
-				self.movie = None
-				self.running = 0
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			Qd.PaintRect(self._bounds)
-			if self.movie:
-				self.movie.UpdateMovie()
-				self.movie.MoviesTask(0)
 
+    def __init__(self, possize):
+        EnterMovies()
+        self.movie = None
+        self.running = 0
+        W.Widget.__init__(self, possize)
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(oldbounds)
+        self.GetWindow().InvalWindowRect(self._bounds)
+        self.calcmoviebox()
+
+    def set(self, path_or_fss, start = 0):
+        self.SetPort()
+        if self.movie:
+            #self.GetWindow().InvalWindowRect(self.movie.GetMovieBox())
+            Qd.PaintRect(self.movie.GetMovieBox())
+        path = File.pathname(path)
+        self.movietitle = os.path.basename(path)
+        movieResRef = Qt.OpenMovieFile(path_or_fss, 1)
+        self.movie, dummy, dummy = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
+        self.moviebox = self.movie.GetMovieBox()
+        self.calcmoviebox()
+        Qd.ObscureCursor()      # XXX does this work at all?
+        self.movie.GoToBeginningOfMovie()
+        if start:
+            self.movie.StartMovie()
+            self.running = 1
+        else:
+            self.running = 0
+            self.movie.MoviesTask(0)
+
+    def get(self):
+        return self.movie
+
+    def getmovietitle(self):
+        return self.movietitle
+
+    def start(self):
+        if self.movie:
+            Qd.ObscureCursor()
+            self.movie.StartMovie()
+            self.running = 1
+
+    def stop(self):
+        if self.movie:
+            self.movie.StopMovie()
+            self.running = 0
+
+    def rewind(self):
+        if self.movie:
+            self.movie.GoToBeginningOfMovie()
+
+    def calcmoviebox(self):
+        if not self.movie:
+            return
+        ml, mt, mr, mb = self.moviebox
+        wl, wt, wr, wb = widgetbox = self._bounds
+        mheight = mb - mt
+        mwidth = mr - ml
+        wheight = wb - wt
+        wwidth = wr - wl
+        if (mheight * 2 < wheight) and (mwidth * 2 < wwidth):
+            scale = 2
+        elif mheight > wheight or mwidth > wwidth:
+            scale = min(float(wheight) / mheight, float(wwidth) / mwidth)
+        else:
+            scale = 1
+        mwidth, mheight = mwidth * scale, mheight * scale
+        ml, mt = wl + (wwidth - mwidth) / 2, wt + (wheight - mheight) / 2
+        mr, mb = ml + mwidth, mt + mheight
+        self.movie.SetMovieBox((ml, mt, mr, mb))
+
+    def idle(self, *args):
+        if self.movie:
+            if not self.movie.IsMovieDone() and self.running:
+                Qd.ObscureCursor()
+                while 1:
+                    self.movie.MoviesTask(0)
+                    gotone, event = Evt.EventAvail(Events.everyEvent)
+                    if gotone or self.movie.IsMovieDone():
+                        break
+            elif self.running:
+                box = self.movie.GetMovieBox()
+                self.SetPort()
+                self.GetWindow().InvalWindowRect(box)
+                self.movie = None
+                self.running = 0
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            Qd.PaintRect(self._bounds)
+            if self.movie:
+                self.movie.UpdateMovie()
+                self.movie.MoviesTask(0)
diff --git a/Mac/Tools/IDE/Wsocket.py b/Mac/Tools/IDE/Wsocket.py
index 913797c..eb5936d 100644
--- a/Mac/Tools/IDE/Wsocket.py
+++ b/Mac/Tools/IDE/Wsocket.py
@@ -17,375 +17,375 @@
 VERBOSE = 1
 
 class Server(asyncore.dispatcher):
-	
-	"""Generic asynchronous server class"""
-	
-	def __init__(self, port, handler_class, backlog=1, host=""):
-		"""arguments:
-		- port: the port to listen to
-		- handler_class: class to handle requests
-		- backlog: backlog queue size (optional) (don't fully understand, see socket docs)
-		- host: host name (optional: can be empty to use default host name)
-		"""
-		if VERBOSE:
-			print "Starting", self.__class__.__name__
-		self.handler_class = handler_class
-		asyncore.dispatcher.__init__(self)
-		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
-		self.bind((host, port))
-		self.listen(backlog)
-	
-	def handle_accept(self):
-		conn, addr = self.accept()
-		if VERBOSE:
-			print 'Incoming Connection from %s:%d' % addr
-		self.handler_class(conn)
+
+    """Generic asynchronous server class"""
+
+    def __init__(self, port, handler_class, backlog=1, host=""):
+        """arguments:
+        - port: the port to listen to
+        - handler_class: class to handle requests
+        - backlog: backlog queue size (optional) (don't fully understand, see socket docs)
+        - host: host name (optional: can be empty to use default host name)
+        """
+        if VERBOSE:
+            print "Starting", self.__class__.__name__
+        self.handler_class = handler_class
+        asyncore.dispatcher.__init__(self)
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.bind((host, port))
+        self.listen(backlog)
+
+    def handle_accept(self):
+        conn, addr = self.accept()
+        if VERBOSE:
+            print 'Incoming Connection from %s:%d' % addr
+        self.handler_class(conn)
 
 
 class ProxyServer(Server):
-	
-	"""Generic proxy server class"""
-	
-	def __init__(self, port, handler_class, proxyaddr=None, closepartners=0):
-		"""arguments:
-		- port: the port to listen to
-		- handler_class: proxy class to handle requests
-		- proxyaddr: a tuple containing the address and 
-		  port of a remote host to connect to (optional)
-		- closepartners: boolean, specifies whether we should close
-		  all proxy connections or not (optional). http seems to *not*
-		  want this, but telnet does...
-		"""
-		Server.__init__(self, port, handler_class, 1, "")
-		self.proxyaddr = proxyaddr
-		self.closepartners = closepartners
-	
-	def handle_accept(self):
-		conn, addr = self.accept()
-		if VERBOSE:
-			print 'Incoming Connection from %s:%d' % addr
-		self.handler_class(conn, self.proxyaddr, closepartner=self.closepartners)
+
+    """Generic proxy server class"""
+
+    def __init__(self, port, handler_class, proxyaddr=None, closepartners=0):
+        """arguments:
+        - port: the port to listen to
+        - handler_class: proxy class to handle requests
+        - proxyaddr: a tuple containing the address and
+          port of a remote host to connect to (optional)
+        - closepartners: boolean, specifies whether we should close
+          all proxy connections or not (optional). http seems to *not*
+          want this, but telnet does...
+        """
+        Server.__init__(self, port, handler_class, 1, "")
+        self.proxyaddr = proxyaddr
+        self.closepartners = closepartners
+
+    def handle_accept(self):
+        conn, addr = self.accept()
+        if VERBOSE:
+            print 'Incoming Connection from %s:%d' % addr
+        self.handler_class(conn, self.proxyaddr, closepartner=self.closepartners)
 
 
 class Connection(asyncore.dispatcher):
-	
-	"""Generic connection class"""
-	
-	def __init__(self, sock_or_address=None, readfunc=None, terminator=None):
-		"""arguments: 
-		- sock_or_address: either a socket, or a tuple containing the name 
-		and port number of a remote host
-		- readfunc: callback function (optional). Will be called whenever
-		  there is some data available, or when an appropraite terminator
-		  is found.
-		- terminator: string which specifies when a read is complete (optional)"""
-		self._out_buffer = ""
-		self._in_buffer = ""
-		self.readfunc = readfunc
-		self.terminator = terminator
-		asyncore.dispatcher.__init__(self)
-		if hasattr(sock_or_address, "fileno"):
-			self.set_socket(sock_or_address)
-		else:
-			sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-			sock.setblocking(0)
-			self.set_socket(sock)
-			if sock_or_address:
-				self.connect(sock_or_address)
-	
-	# public methods
-	def send(self, data):
-		self._out_buffer = self._out_buffer + data
-	
-	def recv(self, bytes=-1):
-		if bytes == -1:
-			bytes = len(self._in_buffer)
-		data = self._in_buffer[:bytes]
-		self._in_buffer = self._in_buffer[bytes:]
-		return data
-	
-	def set_terminator(self, terminator):
-		self.terminator = terminator
-	
-	# override this if you want to control the incoming data stream 
-	def handle_incoming_data(self, data):
-		if self.readfunc:
-			if self.terminator:
-				self._in_buffer = self._in_buffer + data
-				pos = string.find(self._in_buffer, self.terminator)
-				if pos < 0:
-					return
-				data = self._in_buffer[:pos]
-				self._in_buffer = self._in_buffer[pos + len(self.terminator):]
-				self.readfunc(data)
-			else:
-				self.readfunc(self._in_buffer + data)
-				self._in_buffer = ""
-		else:
-			self._in_buffer = self._in_buffer + data
-	
-	# internal muck
-	def handle_read(self):
-		data = asyncore.dispatcher.recv(self, BUFSIZE)
-		if data:
-			if VERBOSE > 2:
-				print "incoming -> %x %r" % (id(self), data)
-			self.handle_incoming_data(data)
-	
-	def handle_write(self):
-		if self._out_buffer:
-			sent = self.socket.send(self._out_buffer[:BUFSIZE])
-			if VERBOSE > 2:
-				print "outgoing -> %x %r" % (id(self), self._out_buffer[:sent])
-			self._out_buffer = self._out_buffer[sent:]
-	
-	def close(self):
-		if self.readfunc and self._in_buffer:
-			self.readfunc(self._in_buffer)
-			self._in_buffer = ""
-		#elif VERBOSE > 1 and self._in_buffer:
-		#	print "--- there is unread data: %r", (self._in_buffer,)
-		asyncore.dispatcher.close(self)
-	
-	def handle_close(self):
-		self.close()
-	
-	def handle_connect(self):
-		pass
+
+    """Generic connection class"""
+
+    def __init__(self, sock_or_address=None, readfunc=None, terminator=None):
+        """arguments:
+        - sock_or_address: either a socket, or a tuple containing the name
+        and port number of a remote host
+        - readfunc: callback function (optional). Will be called whenever
+          there is some data available, or when an appropraite terminator
+          is found.
+        - terminator: string which specifies when a read is complete (optional)"""
+        self._out_buffer = ""
+        self._in_buffer = ""
+        self.readfunc = readfunc
+        self.terminator = terminator
+        asyncore.dispatcher.__init__(self)
+        if hasattr(sock_or_address, "fileno"):
+            self.set_socket(sock_or_address)
+        else:
+            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            sock.setblocking(0)
+            self.set_socket(sock)
+            if sock_or_address:
+                self.connect(sock_or_address)
+
+    # public methods
+    def send(self, data):
+        self._out_buffer = self._out_buffer + data
+
+    def recv(self, bytes=-1):
+        if bytes == -1:
+            bytes = len(self._in_buffer)
+        data = self._in_buffer[:bytes]
+        self._in_buffer = self._in_buffer[bytes:]
+        return data
+
+    def set_terminator(self, terminator):
+        self.terminator = terminator
+
+    # override this if you want to control the incoming data stream
+    def handle_incoming_data(self, data):
+        if self.readfunc:
+            if self.terminator:
+                self._in_buffer = self._in_buffer + data
+                pos = string.find(self._in_buffer, self.terminator)
+                if pos < 0:
+                    return
+                data = self._in_buffer[:pos]
+                self._in_buffer = self._in_buffer[pos + len(self.terminator):]
+                self.readfunc(data)
+            else:
+                self.readfunc(self._in_buffer + data)
+                self._in_buffer = ""
+        else:
+            self._in_buffer = self._in_buffer + data
+
+    # internal muck
+    def handle_read(self):
+        data = asyncore.dispatcher.recv(self, BUFSIZE)
+        if data:
+            if VERBOSE > 2:
+                print "incoming -> %x %r" % (id(self), data)
+            self.handle_incoming_data(data)
+
+    def handle_write(self):
+        if self._out_buffer:
+            sent = self.socket.send(self._out_buffer[:BUFSIZE])
+            if VERBOSE > 2:
+                print "outgoing -> %x %r" % (id(self), self._out_buffer[:sent])
+            self._out_buffer = self._out_buffer[sent:]
+
+    def close(self):
+        if self.readfunc and self._in_buffer:
+            self.readfunc(self._in_buffer)
+            self._in_buffer = ""
+        #elif VERBOSE > 1 and self._in_buffer:
+        #       print "--- there is unread data: %r", (self._in_buffer,)
+        asyncore.dispatcher.close(self)
+
+    def handle_close(self):
+        self.close()
+
+    def handle_connect(self):
+        pass
 
 
 class ConnectionUI:
-	
-	"""Glue to let a connection tell things to the UI in a standardized way.
-	
-	The protocoll defines four functions, which the connection will call:
-	
-		def settotal(int total): gets called when the connection knows the data size
-		def setcurrent(int current): gets called when some new data has arrived
-		def done(): gets called when the transaction is complete
-		def error(type, value, tb): gets called wheneven an error occured
-	"""
-	
-	def __init__(self, settotal_func, setcurrent_func, done_func, error_func):
-		self.settotal = settotal_func
-		self.setcurrent = setcurrent_func
-		self.done = done_func
-		self.error = error_func
+
+    """Glue to let a connection tell things to the UI in a standardized way.
+
+    The protocoll defines four functions, which the connection will call:
+
+            def settotal(int total): gets called when the connection knows the data size
+            def setcurrent(int current): gets called when some new data has arrived
+            def done(): gets called when the transaction is complete
+            def error(type, value, tb): gets called wheneven an error occured
+    """
+
+    def __init__(self, settotal_func, setcurrent_func, done_func, error_func):
+        self.settotal = settotal_func
+        self.setcurrent = setcurrent_func
+        self.done = done_func
+        self.error = error_func
 
 
 class HTTPError(socket.error): pass
 
 
 class HTTPClient(Connection, httplib.HTTP):
-	
-	"""Asynchronous HTTP connection"""
-	
-	def __init__(self, (host, port), datahandler, ui=None):
-		Connection.__init__(self, (host, port))
-		self.datahandler = datahandler
-		self.ui = ui
-		self.buf = ""
-		self.doneheaders = 0
-		self.done = 0
-		self.headers = None
-		self.length = None
-		self.pos = 0
-	
-	def getreply(self):
-		raise TypeError, "getreply() is not supported in async HTTP connection"
-	
-	def handle_incoming_data(self, data):
-		assert not self.done
-		if not self.doneheaders:
-			self.buf = self.buf + data
-			pos = string.find(self.buf, "\r\n\r\n")
-			if pos >= 0:
-				self.handle_reply(self.buf[:pos+4])
-				length = self.headers.getheader("Content-Length")
-				if length is not None:
-					self.length = int(length)
-					if self.ui is not None:
-						self.ui.settotal(self.length)
-				else:
-					self.length = -1
-				self.doneheaders = 1
-				self.handle_data(self.buf[pos+4:])
-				self.buf = ""
-		else:
-			self.handle_data(data)
-	
-	def handle_reply(self, data):
-		f = cStringIO.StringIO(data)
-		ver, code, msg = string.split(f.readline(), None, 2)
-		code = int(code)
-		msg = string.strip(msg)
-		if code <> 200:
-			# Hm, this is what *I* need, but probably not correct...
-			raise HTTPError, (code, msg)
-		self.headers = mimetools.Message(f)
-	
-	def handle_data(self, data):
-		self.pos = self.pos + len(data)
-		if self.ui is not None:
-			self.ui.setcurrent(self.pos)
-		self.datahandler(data)
-		if self.pos >= self.length:
-			self.datahandler("")
-			self.done = 1
-			if self.ui is not None:
-				self.ui.done()
-	
-	def handle_error(self, type, value, tb):
-		if self.ui is not None:
-			self.ui.error(type, value, tb)
-		else:
-			Connection.handle_error(self, type, value, tb)
-	
-	def log(self, message):
-		if VERBOSE:
-			print 'LOG:', message
+
+    """Asynchronous HTTP connection"""
+
+    def __init__(self, (host, port), datahandler, ui=None):
+        Connection.__init__(self, (host, port))
+        self.datahandler = datahandler
+        self.ui = ui
+        self.buf = ""
+        self.doneheaders = 0
+        self.done = 0
+        self.headers = None
+        self.length = None
+        self.pos = 0
+
+    def getreply(self):
+        raise TypeError, "getreply() is not supported in async HTTP connection"
+
+    def handle_incoming_data(self, data):
+        assert not self.done
+        if not self.doneheaders:
+            self.buf = self.buf + data
+            pos = string.find(self.buf, "\r\n\r\n")
+            if pos >= 0:
+                self.handle_reply(self.buf[:pos+4])
+                length = self.headers.getheader("Content-Length")
+                if length is not None:
+                    self.length = int(length)
+                    if self.ui is not None:
+                        self.ui.settotal(self.length)
+                else:
+                    self.length = -1
+                self.doneheaders = 1
+                self.handle_data(self.buf[pos+4:])
+                self.buf = ""
+        else:
+            self.handle_data(data)
+
+    def handle_reply(self, data):
+        f = cStringIO.StringIO(data)
+        ver, code, msg = string.split(f.readline(), None, 2)
+        code = int(code)
+        msg = string.strip(msg)
+        if code <> 200:
+            # Hm, this is what *I* need, but probably not correct...
+            raise HTTPError, (code, msg)
+        self.headers = mimetools.Message(f)
+
+    def handle_data(self, data):
+        self.pos = self.pos + len(data)
+        if self.ui is not None:
+            self.ui.setcurrent(self.pos)
+        self.datahandler(data)
+        if self.pos >= self.length:
+            self.datahandler("")
+            self.done = 1
+            if self.ui is not None:
+                self.ui.done()
+
+    def handle_error(self, type, value, tb):
+        if self.ui is not None:
+            self.ui.error(type, value, tb)
+        else:
+            Connection.handle_error(self, type, value, tb)
+
+    def log(self, message):
+        if VERBOSE:
+            print 'LOG:', message
 
 
 class PyMessage:
-	
-	def __init__(self):
-		self._buf = ""
-		self._len = None
-		self._checksum = None
-	
-	def feed(self, data):
-		self._buf = self._buf + data
-		if self._len is None:
-			if len(self._buf) >= 8:
-				import struct
-				self._len, self._checksum = struct.unpack("ll", self._buf[:8])
-				self._buf = self._buf[8:]
-		if self._len is not None:
-			if len(self._buf) >= self._len:
-				import zlib
-				data = self._buf[:self._len]
-				leftover = self._buf[self._len:]
-				self._buf = None
-				assert self._checksum == zlib.adler32(data), "corrupt data"
-				self.data = data
-				return 1, leftover
-			else:
-				return 0, None
-		else:
-			return 0, None
+
+    def __init__(self):
+        self._buf = ""
+        self._len = None
+        self._checksum = None
+
+    def feed(self, data):
+        self._buf = self._buf + data
+        if self._len is None:
+            if len(self._buf) >= 8:
+                import struct
+                self._len, self._checksum = struct.unpack("ll", self._buf[:8])
+                self._buf = self._buf[8:]
+        if self._len is not None:
+            if len(self._buf) >= self._len:
+                import zlib
+                data = self._buf[:self._len]
+                leftover = self._buf[self._len:]
+                self._buf = None
+                assert self._checksum == zlib.adler32(data), "corrupt data"
+                self.data = data
+                return 1, leftover
+            else:
+                return 0, None
+        else:
+            return 0, None
 
 
 class PyConnection(Connection):
-	
-	def __init__(self, sock_or_address):
-		Connection.__init__(self, sock_or_address)
-		self.currentmessage = PyMessage()
-	
-	def handle_incoming_data(self, data):
-		while data:
-			done, data = self.currentmessage.feed(data)
-			if done:
-				import cPickle
-				self.handle_object(cPickle.loads(self.currentmessage.data))
-				self.currentmessage = PyMessage()
-	
-	def handle_object(self, object):
-		print 'unhandled object:', repr(object)
-	
-	def send(self, object):
-		import cPickle, zlib, struct
-		data = cPickle.dumps(object, 1)
-		length = len(data)
-		checksum = zlib.adler32(data)
-		data = struct.pack("ll", length, checksum) + data
-		Connection.send(self, data)
+
+    def __init__(self, sock_or_address):
+        Connection.__init__(self, sock_or_address)
+        self.currentmessage = PyMessage()
+
+    def handle_incoming_data(self, data):
+        while data:
+            done, data = self.currentmessage.feed(data)
+            if done:
+                import cPickle
+                self.handle_object(cPickle.loads(self.currentmessage.data))
+                self.currentmessage = PyMessage()
+
+    def handle_object(self, object):
+        print 'unhandled object:', repr(object)
+
+    def send(self, object):
+        import cPickle, zlib, struct
+        data = cPickle.dumps(object, 1)
+        length = len(data)
+        checksum = zlib.adler32(data)
+        data = struct.pack("ll", length, checksum) + data
+        Connection.send(self, data)
 
 
 class Echo(Connection):
-	
-	"""Simple echoing connection: it sends everything back it receives.""" 
-	
-	def handle_incoming_data(self, data):
-		self.send(data)
+
+    """Simple echoing connection: it sends everything back it receives."""
+
+    def handle_incoming_data(self, data):
+        self.send(data)
 
 
 class Proxy(Connection):
-	
-	"""Generic proxy connection"""
-	
-	def __init__(self, sock_or_address=None, proxyaddr=None, closepartner=0):
-		"""arguments:
-		- sock_or_address is either a socket or a tuple containing the 
-		name and port number of a remote host
-		- proxyaddr: a tuple containing a name and a port number of a 
-		  remote host (optional).
-		- closepartner: boolean, specifies whether we should close
-		  the proxy connection (optional)"""
-		
-		Connection.__init__(self, sock_or_address)
-		self.other = None
-		self.proxyaddr = proxyaddr
-		self.closepartner = closepartner
-	
-	def close(self):
-		if self.other:
-			other = self.other
-			self.other = None
-			other.other = None
-			if self.closepartner:
-				other.close()
-		Connection.close(self)
-	
-	def handle_incoming_data(self, data):
-		if not self.other:
-			# pass data for possible automatic remote host detection
-			# (see HTTPProxy)
-			data = self.connectproxy(data)
-		self.other.send(data)
-	
-	def connectproxy(self, data):
-		other = self.__class__(self.proxyaddr, closepartner=self.closepartner)
-		self.other = other
-		other.other = self
-		return data
+
+    """Generic proxy connection"""
+
+    def __init__(self, sock_or_address=None, proxyaddr=None, closepartner=0):
+        """arguments:
+        - sock_or_address is either a socket or a tuple containing the
+        name and port number of a remote host
+        - proxyaddr: a tuple containing a name and a port number of a
+          remote host (optional).
+        - closepartner: boolean, specifies whether we should close
+          the proxy connection (optional)"""
+
+        Connection.__init__(self, sock_or_address)
+        self.other = None
+        self.proxyaddr = proxyaddr
+        self.closepartner = closepartner
+
+    def close(self):
+        if self.other:
+            other = self.other
+            self.other = None
+            other.other = None
+            if self.closepartner:
+                other.close()
+        Connection.close(self)
+
+    def handle_incoming_data(self, data):
+        if not self.other:
+            # pass data for possible automatic remote host detection
+            # (see HTTPProxy)
+            data = self.connectproxy(data)
+        self.other.send(data)
+
+    def connectproxy(self, data):
+        other = self.__class__(self.proxyaddr, closepartner=self.closepartner)
+        self.other = other
+        other.other = self
+        return data
 
 
 class HTTPProxy(Proxy):
-	
-	"""Simple, useless, http proxy. It figures out itself where to connect to."""
-	
-	def connectproxy(self, data):
-		if VERBOSE:
-			print "--- proxy request", repr(data)
-		addr, data = de_proxify(data)
-		other = Proxy(addr)
-		self.other = other
-		other.other = self
-		return data
+
+    """Simple, useless, http proxy. It figures out itself where to connect to."""
+
+    def connectproxy(self, data):
+        if VERBOSE:
+            print "--- proxy request", repr(data)
+        addr, data = de_proxify(data)
+        other = Proxy(addr)
+        self.other = other
+        other.other = self
+        return data
 
 
 # helper for HTTPProxy
 def de_proxify(data):
-	import re
-	req_pattern = "GET http://([a-zA-Z0-9-_.]+)(:([0-9]+))?"
-	m = re.match(req_pattern, data)
-	host, dummy, port = m.groups()
-	if not port:
-		port = 80
-	else:
-		port = int(port)
-	# change "GET http://xx.xx.xx/yy" into "GET /yy"
-	data = re.sub(req_pattern, "GET ", data)
-	return (host, port), data
+    import re
+    req_pattern = "GET http://([a-zA-Z0-9-_.]+)(:([0-9]+))?"
+    m = re.match(req_pattern, data)
+    host, dummy, port = m.groups()
+    if not port:
+        port = 80
+    else:
+        port = int(port)
+    # change "GET http://xx.xx.xx/yy" into "GET /yy"
+    data = re.sub(req_pattern, "GET ", data)
+    return (host, port), data
 
 
 # if we're running "under W", let's register the socket poller to the event loop
 try:
-	import W
+    import W
 except:
-	pass
+    pass
 else:
-	W.getapplication().addidlefunc(asyncore.poll)
+    W.getapplication().addidlefunc(asyncore.poll)
 
 
 ## testing muck
diff --git a/Mac/Tools/IDE/Wtext.py b/Mac/Tools/IDE/Wtext.py
index 3894e16..b3d2f8e 100644
--- a/Mac/Tools/IDE/Wtext.py
+++ b/Mac/Tools/IDE/Wtext.py
@@ -14,640 +14,640 @@
 
 
 class TextBox(Wbase.Widget):
-	
-	"""A static text widget"""
-	
-	def __init__(self, possize, text="", align=TextEdit.teJustLeft, 
-				fontsettings=None,
-				backgroundcolor=(0xffff, 0xffff, 0xffff)
-				):
-		if fontsettings is None:
-			import W
-			fontsettings = W.getdefaultfont()
-		Wbase.Widget.__init__(self, possize)
-		self.fontsettings = fontsettings
-		self.text = text
-		self.align = align
-		self._backgroundcolor = backgroundcolor
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			(font, style, size, color) = self.fontsettings
-			fontid = GetFNum(font)
-			savestate = Qd.GetPenState()
-			Qd.TextFont(fontid)
-			Qd.TextFace(style)
-			Qd.TextSize(size)
-			Qd.RGBForeColor(color)
-			Qd.RGBBackColor(self._backgroundcolor)
-			TE.TETextBox(self.text, self._bounds, self.align)
-			Qd.RGBBackColor((0xffff, 0xffff, 0xffff))
-			Qd.SetPenState(savestate)
-	
-	def get(self):
-		return self.text
-	
-	def set(self, text):
-		self.text = text
-		if self._parentwindow and self._parentwindow.wid:
-			self.SetPort()
-			self.draw()
+
+    """A static text widget"""
+
+    def __init__(self, possize, text="", align=TextEdit.teJustLeft,
+                            fontsettings=None,
+                            backgroundcolor=(0xffff, 0xffff, 0xffff)
+                            ):
+        if fontsettings is None:
+            import W
+            fontsettings = W.getdefaultfont()
+        Wbase.Widget.__init__(self, possize)
+        self.fontsettings = fontsettings
+        self.text = text
+        self.align = align
+        self._backgroundcolor = backgroundcolor
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            (font, style, size, color) = self.fontsettings
+            fontid = GetFNum(font)
+            savestate = Qd.GetPenState()
+            Qd.TextFont(fontid)
+            Qd.TextFace(style)
+            Qd.TextSize(size)
+            Qd.RGBForeColor(color)
+            Qd.RGBBackColor(self._backgroundcolor)
+            TE.TETextBox(self.text, self._bounds, self.align)
+            Qd.RGBBackColor((0xffff, 0xffff, 0xffff))
+            Qd.SetPenState(savestate)
+
+    def get(self):
+        return self.text
+
+    def set(self, text):
+        self.text = text
+        if self._parentwindow and self._parentwindow.wid:
+            self.SetPort()
+            self.draw()
 
 
 class _ScrollWidget:
-	
-	# to be overridden
-	def getscrollrects(self):
-		"""Return (destrect, viewrect)."""
-		return None, None
-	
-	# internal method
-	
-	def updatescrollbars(self):
-		(dl, dt, dr, db), (vl, vt, vr, vb) = self.getscrollrects()
-		if self._parent._barx:
-			viewwidth = vr - vl
-			destwidth = dr - dl
-			bar = self._parent._barx
-			bar.setmax(destwidth - viewwidth)
-			
-			# MacOS 8.1 doesn't automatically disable
-			# scrollbars whose max <= min
-			bar.enable(destwidth > viewwidth)
-			
-			bar.setviewsize(viewwidth)
-			bar.set(vl - dl)
-		if self._parent._bary:
-			viewheight = vb - vt
-			destheight = db - dt
-			bar = self._parent._bary
-			bar.setmax(destheight - viewheight)
-			
-			# MacOS 8.1 doesn't automatically disable
-			# scrollbars whose max <= min
-			bar.enable(destheight > viewheight)
-			
-			bar.setviewsize(viewheight)
-			bar.set(vt - dt)
+
+    # to be overridden
+    def getscrollrects(self):
+        """Return (destrect, viewrect)."""
+        return None, None
+
+    # internal method
+
+    def updatescrollbars(self):
+        (dl, dt, dr, db), (vl, vt, vr, vb) = self.getscrollrects()
+        if self._parent._barx:
+            viewwidth = vr - vl
+            destwidth = dr - dl
+            bar = self._parent._barx
+            bar.setmax(destwidth - viewwidth)
+
+            # MacOS 8.1 doesn't automatically disable
+            # scrollbars whose max <= min
+            bar.enable(destwidth > viewwidth)
+
+            bar.setviewsize(viewwidth)
+            bar.set(vl - dl)
+        if self._parent._bary:
+            viewheight = vb - vt
+            destheight = db - dt
+            bar = self._parent._bary
+            bar.setmax(destheight - viewheight)
+
+            # MacOS 8.1 doesn't automatically disable
+            # scrollbars whose max <= min
+            bar.enable(destheight > viewheight)
+
+            bar.setviewsize(viewheight)
+            bar.set(vt - dt)
 
 
-UNDOLABELS = [	# Indexed by WEGetUndoInfo() value
-	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style",
-	"Ruler", "backspace", "delete", "transform", "resize"]
+UNDOLABELS = [  # Indexed by WEGetUndoInfo() value
+        None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style",
+        "Ruler", "backspace", "delete", "transform", "resize"]
 
 
 class EditText(Wbase.SelectableWidget, _ScrollWidget):
-	
-	"""A text edit widget, mainly for simple entry fields."""
-	
-	def __init__(self, possize, text="", 
-				callback=None, inset=(3, 3), 
-				fontsettings=None,
-				tabsettings = (32, 0),
-				readonly = 0):
-		if fontsettings is None:
-			import W
-			fontsettings = W.getdefaultfont()
-		Wbase.SelectableWidget.__init__(self, possize)
-		self.temptext = text
-		self.ted = None
-		self.selection = None
-		self.oldselection = None
-		self._callback = callback
-		self.changed = 0
-		self.selchanged = 0
-		self._selected = 0
-		self._enabled = 1
-		self.wrap = 1
-		self.readonly = readonly
-		self.fontsettings = fontsettings
-		self.tabsettings = tabsettings
-		if type(inset) <> TupleType:
-			self.inset = (inset, inset)
-		else:
-			self.inset = inset
-	
-	def open(self):
-		if not hasattr(self._parent, "_barx"):
-			self._parent._barx = None
-		if not hasattr(self._parent, "_bary"):
-			self._parent._bary = None
-		self._calcbounds()
-		self.SetPort()
-		viewrect, destrect = self._calctextbounds()
-		flags = self._getflags()
-		self.ted = waste.WENew(destrect, viewrect, flags)
-		self.ted.WEInstallTabHooks()
-		self.ted.WESetAlignment(WASTEconst.weFlushLeft)
-		self.setfontsettings(self.fontsettings)
-		self.settabsettings(self.tabsettings)
-		self.ted.WEUseText(Res.Resource(self.temptext))
-		self.ted.WECalText()
-		if self.selection:
-			self.setselection(self.selection[0], self.selection[1])
-			self.selection = None
-		else:
-			self.selview()
-		self.temptext = None
-		self.updatescrollbars()
-		self.bind("pageup", self.scrollpageup)
-		self.bind("pagedown", self.scrollpagedown)
-		self.bind("top", self.scrolltop)
-		self.bind("bottom", self.scrollbottom)
-		self.selchanged = 0
-	
-	def close(self):
-		self._parent._barx = None
-		self._parent._bary = None
-		self.ted = None
-		self.temptext = None
-		Wbase.SelectableWidget.close(self)
-	
-	def textchanged(self, all=0):
-		self.changed = 1
-	
-	def selectionchanged(self):
-		self.selchanged = 1
-		self.oldselection = self.getselection()
-	
-	def gettabsettings(self):
-		return self.tabsettings
-	
-	def settabsettings(self, (tabsize, tabmode)):
-		self.tabsettings = (tabsize, tabmode)
-		if hasattr(self.ted, "WESetTabSize"):
-			port = self._parentwindow.wid.GetWindowPort()
-			if tabmode:
-				(font, style, size, color) = self.getfontsettings()
-				savesettings = GetPortFontSettings(port)
-				SetPortFontSettings(port, (font, style, size))
-				tabsize = Qd.StringWidth(' ' * tabsize)
-				SetPortFontSettings(port, savesettings)
-			tabsize = max(tabsize, 1)
-			self.ted.WESetTabSize(tabsize)
-			self.SetPort()
-			Qd.EraseRect(self.ted.WEGetViewRect())
-			self.ted.WEUpdate(port.visRgn)
-	
-	def getfontsettings(self):
-		from Carbon import Res
-		(font, style, size, color) = self.ted.WEGetRunInfo(0)[4]
-		font = Fm.GetFontName(font)
-		return (font, style, size, color)
-	
-	def setfontsettings(self, (font, style, size, color)):
-		self.SetPort()
-		if type(font) <> StringType:
-			font = Fm.GetFontName(font)
-		self.fontsettings = (font, style, size, color)
-		fontid = GetFNum(font)
-		readonly = self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, -1)
-		if readonly:
-			self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
-		try:
-			self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
-			selstart, selend = self.ted.WEGetSelection()
-			self.ted.WESetSelection(0, self.ted.WEGetTextLength())
-			self.ted.WESetStyle(WASTEconst.weDoFace, (0, 0, 0, (0, 0, 0)))
-			self.ted.WESetStyle(WASTEconst.weDoFace | 
-						WASTEconst.weDoColor | 
-						WASTEconst.weDoFont | 
-						WASTEconst.weDoSize, 
-						(fontid, style, size, color))
-			self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
-			self.ted.WECalText()
-			self.ted.WESetSelection(selstart, selend)
-		finally:
-			if readonly:
-				self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
-		viewrect = self.ted.WEGetViewRect()
-		Qd.EraseRect(viewrect)
-		self.ted.WEUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
-		self.selectionchanged()
-		self.updatescrollbars()
-	
-	def adjust(self, oldbounds):
-		self.SetPort()
-		# Note: if App.DrawThemeEditTextFrame is ever used, it will be necessary
-		# to unconditionally outset the invalidated rectangles, since Appearance
-		# frames are drawn outside the bounds.
-		if self._selected and self._parentwindow._hasselframes:
-			self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
-			self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
-		else:
-			self.GetWindow().InvalWindowRect(oldbounds)
-			self.GetWindow().InvalWindowRect(self._bounds)
-		viewrect, destrect = self._calctextbounds()
-		self.ted.WESetViewRect(viewrect)
-		self.ted.WESetDestRect(destrect)
-		if self.wrap:
-			self.ted.WECalText()
-		if self.ted.WEGetDestRect()[3] < viewrect[1]:
-			self.selview()
-		self.updatescrollbars()
-	
-	# interface -----------------------
-	# selection stuff
-	def selview(self):
-		self.ted.WESelView()
-	
-	def selectall(self):
-		self.ted.WESetSelection(0, self.ted.WEGetTextLength())
-		self.selectionchanged()
-		self.updatescrollbars()
-	
-	def selectline(self, lineno, charoffset = 0):
-		newselstart, newselend = self.ted.WEGetLineRange(lineno)
-		# Autoscroll makes the *end* of the selection visible, which, 
-		# in the case of a whole line, is the beginning of the *next* line. 
-		# So sometimes it leaves our line just above the view rect. 
-		# Let's fool Waste by initially selecting one char less:
-		self.ted.WESetSelection(newselstart + charoffset, newselend-1)
-		self.ted.WESetSelection(newselstart + charoffset, newselend)
-		self.selectionchanged()
-		self.updatescrollbars()
-	
-	def getselection(self):
-		if self.ted:
-			return self.ted.WEGetSelection()
-		else:
-			return self.selection
-	
-	def setselection(self, selstart, selend):
-		self.selectionchanged()
-		if self.ted:
-			self.ted.WESetSelection(selstart, selend)
-			self.ted.WESelView()
-			self.updatescrollbars()
-		else:
-			self.selection = selstart, selend
-	
-	def offsettoline(self, offset):
-		return self.ted.WEOffsetToLine(offset)
-	
-	def countlines(self):
-		return self.ted.WECountLines()
-	
-	def getselectedtext(self):
-		selstart, selend = self.ted.WEGetSelection()
-		return self.ted.WEGetText().data[selstart:selend]
-	
-	def expandselection(self):
-		oldselstart, oldselend = self.ted.WEGetSelection()
-		selstart, selend = min(oldselstart, oldselend), max(oldselstart, oldselend)
-		if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r':
-			selend = selend - 1
-		newselstart, dummy = self.ted.WEFindLine(selstart, 1)
-		dummy, newselend = self.ted.WEFindLine(selend, 1)
-		if oldselstart <> newselstart or  oldselend <> newselend:
-			self.ted.WESetSelection(newselstart, newselend)
-			self.updatescrollbars()
-		self.selectionchanged()
-	
-	def insert(self, text):
-		self.ted.WEInsert(text, None, None)
-		self.textchanged()
-		self.selectionchanged()
-	
-	# text
-	def set(self, text):
-		if not self.ted:
-			self.temptext = text
-		else:
-			self.ted.WEUseText(Res.Resource(text))
-			self.ted.WECalText()
-			self.SetPort()
-			viewrect, destrect = self._calctextbounds()
-			self.ted.WESetViewRect(viewrect)
-			self.ted.WESetDestRect(destrect)
-			rgn = Qd.NewRgn()
-			Qd.RectRgn(rgn, viewrect)
-			Qd.EraseRect(viewrect)
-			self.draw(rgn)
-			self.updatescrollbars()
-			self.textchanged(1)
-	
-	def get(self):
-		if not self._parent:
-			return self.temptext
-		else:
-			return self.ted.WEGetText().data
-	
-	# events
-	def key(self, char, event):
-		(what, message, when, where, modifiers) = event
-		if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
-			self.ted.WEKey(ord(char), modifiers)
-			if char not in Wkeys.navigationkeys:
-				self.textchanged()
-			if char not in Wkeys.scrollkeys:
-				self.selectionchanged()
-			self.updatescrollbars()
-			if self._callback:
-				Wbase.CallbackCall(self._callback, 0, char, modifiers)
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		self.ted.WEClick(point, modifiers, Evt.TickCount())
-		self.selectionchanged()
-		self.updatescrollbars()
-		return 1
-	
-	def idle(self):
-		self.SetPort()
-		self.ted.WEIdle()
-	
-	def rollover(self, point, onoff):
-		if onoff:
-			Wbase.SetCursor("iBeam")
-	
-	def activate(self, onoff):
-		self._activated = onoff
-		if self._visible:
-			self.SetPort()
-			
-			# DISABLED!  There are too many places where it is assumed that
-			# the frame of an EditText item is 1 pixel, inside the bounds.
-			#state = [kThemeStateActive, kThemeStateInactive][not onoff]
-			#App.DrawThemeEditTextFrame(Qd.InsetRect(self._bounds, 1, 1), state)
-			
-			if self._selected:
-				if onoff:
-					self.ted.WEActivate()
-				else:
-					self.ted.WEDeactivate()
-				self.drawselframe(onoff)
-	
-	def select(self, onoff, isclick = 0):
-		if Wbase.SelectableWidget.select(self, onoff):
-			return
-		self.SetPort()
-		if onoff:
-			self.ted.WEActivate()
-			if self._parentwindow._tabbable and not isclick:
-				self.selectall()
-		else:
-			self.ted.WEDeactivate()
-		self.drawselframe(onoff)
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			if not visRgn:
-				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
-			self.ted.WEUpdate(visRgn)
 
-			# DISABLED!  There are too many places where it is assumed that
-			# the frame of an EditText item is 1 pixel, inside the bounds.
-			#state = [kThemeStateActive, kThemeStateInactive][not self._activated]
-			#App.DrawThemeEditTextFrame(Qd.InsetRect(self._bounds, 1, 1), state)
-			Qd.FrameRect(self._bounds)
+    """A text edit widget, mainly for simple entry fields."""
 
-			if self._selected and self._activated:
-				self.drawselframe(1)
-	
-	# scrolling
-	def scrollpageup(self):
-		if self._parent._bary and self._parent._bary._enabled:
-			self.vscroll("++")
-	
-	def scrollpagedown(self):
-		if self._parent._bary and self._parent._bary._enabled:
-			self.vscroll("--")
-	
-	def scrolltop(self):
-		if self._parent._bary and self._parent._bary._enabled:
-			self.vscroll(self._parent._bary.getmin())
-		if self._parent._barx and self._parent._barx._enabled:
-			self.hscroll(self._parent._barx.getmin())
-	
-	def scrollbottom(self):
-		if self._parent._bary and self._parent._bary._enabled:
-			self.vscroll(self._parent._bary.getmax())
-	
-	# menu handlers
-	def domenu_copy(self, *args):
-		selbegin, selend = self.ted.WEGetSelection()
-		if selbegin == selend:
-			return
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECopy()
-		self.updatescrollbars()
-	
-	def domenu_cut(self, *args):
-		selbegin, selend = self.ted.WEGetSelection()
-		if selbegin == selend:
-			return
-		if hasattr(Scrap, 'ZeroScrap'):
-			Scrap.ZeroScrap()
-		else:
-			Scrap.ClearCurrentScrap()
-		self.ted.WECut()
-		self.updatescrollbars()
-		self.selview()
-		self.textchanged()
-		self.selectionchanged()
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, "", None)
-	
-	def domenu_paste(self, *args):
-		if not self.ted.WECanPaste():
-			return
-		self.selview()
-		self.ted.WEPaste()
-		self.updatescrollbars()
-		self.textchanged()
-		self.selectionchanged()
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, "", None)
-	
-	def domenu_clear(self, *args):
-		self.ted.WEDelete()
-		self.selview()
-		self.updatescrollbars()
-		self.textchanged()
-		self.selectionchanged()
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, "", None)
-	
-	def domenu_undo(self, *args):
-		which, redo = self.ted.WEGetUndoInfo()
-		if not which: 
-			return
-		self.ted.WEUndo()
-		self.updatescrollbars()
-		self.textchanged()
-		self.selectionchanged()
-		if self._callback:
-			Wbase.CallbackCall(self._callback, 0, "", None)
-	
-	def can_undo(self, menuitem):
-		#doundo = self.ted.WEFeatureFlag(WASTEconst.weFUndo, -1)
-		#print doundo
-		#if not doundo:
-		#	return 0
-		which, redo = self.ted.WEGetUndoInfo()
-		if which < len(UNDOLABELS):
-			which = UNDOLABELS[which]
-		else:
-			which = ""
-		if which == None: 
-			return None
-		if redo:
-			which = "Redo "+which
-		else:
-			which = "Undo "+which
-		menuitem.settext(which)
-		return 1
-	
-	def domenu_selectall(self, *args):
-		self.selectall()
-	
-	# private
-	def getscrollrects(self):
-		return self.ted.WEGetDestRect(), self.ted.WEGetViewRect()
-	
-	def vscroll(self, value):
-		lineheight = self.ted.WEGetHeight(0, 1)
-		dr = self.ted.WEGetDestRect()
-		vr = self.ted.WEGetViewRect()
-		viewheight = vr[3] - vr[1]
-		maxdelta = vr[1] - dr[1]
-		mindelta = vr[3] - dr[3]
-		if value == "+":
-			delta = lineheight
-		elif value == "-":
-			delta = - lineheight
-		elif value == "++":
-			delta = viewheight - lineheight
-		elif value == "--":
-			delta = lineheight - viewheight
-		else:	# in thumb
-			delta = vr[1] - dr[1] - value
-		delta = min(maxdelta, delta)
-		delta = max(mindelta, delta)
-		delta = int(delta)
-		self.ted.WEScroll(0, delta)
-		self.updatescrollbars()
-	
-	def hscroll(self, value):
-		dr = self.ted.WEGetDestRect()
-		vr = self.ted.WEGetViewRect()
-		destwidth = dr[2] - dr[0]
-		viewwidth = vr[2] - vr[0]
-		viewoffset = maxdelta = vr[0] - dr[0]
-		mindelta = vr[2] - dr[2]
-		if value == "+":
-			delta = 32
-		elif value == "-":
-			delta = - 32
-		elif value == "++":
-			delta = 0.5 * (vr[2] - vr[0])
-		elif value == "--":
-			delta = 0.5 * (vr[0] - vr[2])
-		else:	# in thumb
-			delta = vr[0] - dr[0] - value
-			#cur = (32767 * viewoffset) / (destwidth - viewwidth)
-			#delta = (cur-value)*(destwidth - viewwidth)/32767
-			#if abs(delta - viewoffset) <=2:
-			#	# compensate for irritating rounding error
-			#	delta = viewoffset
-		delta = min(maxdelta, delta)
-		delta = max(mindelta, delta)
-		delta = int(delta)
-		self.ted.WEScroll(delta, 0)
-		self.updatescrollbars()
-	
-	# some internals
-	def _getflags(self):
-		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled
-		if self.readonly:
-			flags = flags | WASTEconst.weDoReadOnly
-		else:
-			flags = flags | WASTEconst.weDoUndo
-		return flags
-	
-	def _getviewrect(self):
-		return Qd.InsetRect(self._bounds, self.inset[0], self.inset[1])
-	
-	def _calctextbounds(self):
-		viewrect = l, t, r, b = self._getviewrect()
-		if self.ted:
-			dl, dt, dr, db = self.ted.WEGetDestRect()
-			vl, vt, vr, vb = self.ted.WEGetViewRect()
-			yshift = t - vt
-			if (db - dt) < (b - t):
-				destrect = viewrect
-			else:
-				destrect = l, dt + yshift, r, db + yshift
-		else:
-			destrect = viewrect
-		return viewrect, destrect
-		
+    def __init__(self, possize, text="",
+                            callback=None, inset=(3, 3),
+                            fontsettings=None,
+                            tabsettings = (32, 0),
+                            readonly = 0):
+        if fontsettings is None:
+            import W
+            fontsettings = W.getdefaultfont()
+        Wbase.SelectableWidget.__init__(self, possize)
+        self.temptext = text
+        self.ted = None
+        self.selection = None
+        self.oldselection = None
+        self._callback = callback
+        self.changed = 0
+        self.selchanged = 0
+        self._selected = 0
+        self._enabled = 1
+        self.wrap = 1
+        self.readonly = readonly
+        self.fontsettings = fontsettings
+        self.tabsettings = tabsettings
+        if type(inset) <> TupleType:
+            self.inset = (inset, inset)
+        else:
+            self.inset = inset
+
+    def open(self):
+        if not hasattr(self._parent, "_barx"):
+            self._parent._barx = None
+        if not hasattr(self._parent, "_bary"):
+            self._parent._bary = None
+        self._calcbounds()
+        self.SetPort()
+        viewrect, destrect = self._calctextbounds()
+        flags = self._getflags()
+        self.ted = waste.WENew(destrect, viewrect, flags)
+        self.ted.WEInstallTabHooks()
+        self.ted.WESetAlignment(WASTEconst.weFlushLeft)
+        self.setfontsettings(self.fontsettings)
+        self.settabsettings(self.tabsettings)
+        self.ted.WEUseText(Res.Resource(self.temptext))
+        self.ted.WECalText()
+        if self.selection:
+            self.setselection(self.selection[0], self.selection[1])
+            self.selection = None
+        else:
+            self.selview()
+        self.temptext = None
+        self.updatescrollbars()
+        self.bind("pageup", self.scrollpageup)
+        self.bind("pagedown", self.scrollpagedown)
+        self.bind("top", self.scrolltop)
+        self.bind("bottom", self.scrollbottom)
+        self.selchanged = 0
+
+    def close(self):
+        self._parent._barx = None
+        self._parent._bary = None
+        self.ted = None
+        self.temptext = None
+        Wbase.SelectableWidget.close(self)
+
+    def textchanged(self, all=0):
+        self.changed = 1
+
+    def selectionchanged(self):
+        self.selchanged = 1
+        self.oldselection = self.getselection()
+
+    def gettabsettings(self):
+        return self.tabsettings
+
+    def settabsettings(self, (tabsize, tabmode)):
+        self.tabsettings = (tabsize, tabmode)
+        if hasattr(self.ted, "WESetTabSize"):
+            port = self._parentwindow.wid.GetWindowPort()
+            if tabmode:
+                (font, style, size, color) = self.getfontsettings()
+                savesettings = GetPortFontSettings(port)
+                SetPortFontSettings(port, (font, style, size))
+                tabsize = Qd.StringWidth(' ' * tabsize)
+                SetPortFontSettings(port, savesettings)
+            tabsize = max(tabsize, 1)
+            self.ted.WESetTabSize(tabsize)
+            self.SetPort()
+            Qd.EraseRect(self.ted.WEGetViewRect())
+            self.ted.WEUpdate(port.visRgn)
+
+    def getfontsettings(self):
+        from Carbon import Res
+        (font, style, size, color) = self.ted.WEGetRunInfo(0)[4]
+        font = Fm.GetFontName(font)
+        return (font, style, size, color)
+
+    def setfontsettings(self, (font, style, size, color)):
+        self.SetPort()
+        if type(font) <> StringType:
+            font = Fm.GetFontName(font)
+        self.fontsettings = (font, style, size, color)
+        fontid = GetFNum(font)
+        readonly = self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, -1)
+        if readonly:
+            self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
+        try:
+            self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
+            selstart, selend = self.ted.WEGetSelection()
+            self.ted.WESetSelection(0, self.ted.WEGetTextLength())
+            self.ted.WESetStyle(WASTEconst.weDoFace, (0, 0, 0, (0, 0, 0)))
+            self.ted.WESetStyle(WASTEconst.weDoFace |
+                                    WASTEconst.weDoColor |
+                                    WASTEconst.weDoFont |
+                                    WASTEconst.weDoSize,
+                                    (fontid, style, size, color))
+            self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
+            self.ted.WECalText()
+            self.ted.WESetSelection(selstart, selend)
+        finally:
+            if readonly:
+                self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
+        viewrect = self.ted.WEGetViewRect()
+        Qd.EraseRect(viewrect)
+        self.ted.WEUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
+        self.selectionchanged()
+        self.updatescrollbars()
+
+    def adjust(self, oldbounds):
+        self.SetPort()
+        # Note: if App.DrawThemeEditTextFrame is ever used, it will be necessary
+        # to unconditionally outset the invalidated rectangles, since Appearance
+        # frames are drawn outside the bounds.
+        if self._selected and self._parentwindow._hasselframes:
+            self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
+            self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
+        else:
+            self.GetWindow().InvalWindowRect(oldbounds)
+            self.GetWindow().InvalWindowRect(self._bounds)
+        viewrect, destrect = self._calctextbounds()
+        self.ted.WESetViewRect(viewrect)
+        self.ted.WESetDestRect(destrect)
+        if self.wrap:
+            self.ted.WECalText()
+        if self.ted.WEGetDestRect()[3] < viewrect[1]:
+            self.selview()
+        self.updatescrollbars()
+
+    # interface -----------------------
+    # selection stuff
+    def selview(self):
+        self.ted.WESelView()
+
+    def selectall(self):
+        self.ted.WESetSelection(0, self.ted.WEGetTextLength())
+        self.selectionchanged()
+        self.updatescrollbars()
+
+    def selectline(self, lineno, charoffset = 0):
+        newselstart, newselend = self.ted.WEGetLineRange(lineno)
+        # Autoscroll makes the *end* of the selection visible, which,
+        # in the case of a whole line, is the beginning of the *next* line.
+        # So sometimes it leaves our line just above the view rect.
+        # Let's fool Waste by initially selecting one char less:
+        self.ted.WESetSelection(newselstart + charoffset, newselend-1)
+        self.ted.WESetSelection(newselstart + charoffset, newselend)
+        self.selectionchanged()
+        self.updatescrollbars()
+
+    def getselection(self):
+        if self.ted:
+            return self.ted.WEGetSelection()
+        else:
+            return self.selection
+
+    def setselection(self, selstart, selend):
+        self.selectionchanged()
+        if self.ted:
+            self.ted.WESetSelection(selstart, selend)
+            self.ted.WESelView()
+            self.updatescrollbars()
+        else:
+            self.selection = selstart, selend
+
+    def offsettoline(self, offset):
+        return self.ted.WEOffsetToLine(offset)
+
+    def countlines(self):
+        return self.ted.WECountLines()
+
+    def getselectedtext(self):
+        selstart, selend = self.ted.WEGetSelection()
+        return self.ted.WEGetText().data[selstart:selend]
+
+    def expandselection(self):
+        oldselstart, oldselend = self.ted.WEGetSelection()
+        selstart, selend = min(oldselstart, oldselend), max(oldselstart, oldselend)
+        if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r':
+            selend = selend - 1
+        newselstart, dummy = self.ted.WEFindLine(selstart, 1)
+        dummy, newselend = self.ted.WEFindLine(selend, 1)
+        if oldselstart <> newselstart or  oldselend <> newselend:
+            self.ted.WESetSelection(newselstart, newselend)
+            self.updatescrollbars()
+        self.selectionchanged()
+
+    def insert(self, text):
+        self.ted.WEInsert(text, None, None)
+        self.textchanged()
+        self.selectionchanged()
+
+    # text
+    def set(self, text):
+        if not self.ted:
+            self.temptext = text
+        else:
+            self.ted.WEUseText(Res.Resource(text))
+            self.ted.WECalText()
+            self.SetPort()
+            viewrect, destrect = self._calctextbounds()
+            self.ted.WESetViewRect(viewrect)
+            self.ted.WESetDestRect(destrect)
+            rgn = Qd.NewRgn()
+            Qd.RectRgn(rgn, viewrect)
+            Qd.EraseRect(viewrect)
+            self.draw(rgn)
+            self.updatescrollbars()
+            self.textchanged(1)
+
+    def get(self):
+        if not self._parent:
+            return self.temptext
+        else:
+            return self.ted.WEGetText().data
+
+    # events
+    def key(self, char, event):
+        (what, message, when, where, modifiers) = event
+        if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
+            self.ted.WEKey(ord(char), modifiers)
+            if char not in Wkeys.navigationkeys:
+                self.textchanged()
+            if char not in Wkeys.scrollkeys:
+                self.selectionchanged()
+            self.updatescrollbars()
+            if self._callback:
+                Wbase.CallbackCall(self._callback, 0, char, modifiers)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        self.ted.WEClick(point, modifiers, Evt.TickCount())
+        self.selectionchanged()
+        self.updatescrollbars()
+        return 1
+
+    def idle(self):
+        self.SetPort()
+        self.ted.WEIdle()
+
+    def rollover(self, point, onoff):
+        if onoff:
+            Wbase.SetCursor("iBeam")
+
+    def activate(self, onoff):
+        self._activated = onoff
+        if self._visible:
+            self.SetPort()
+
+            # DISABLED!  There are too many places where it is assumed that
+            # the frame of an EditText item is 1 pixel, inside the bounds.
+            #state = [kThemeStateActive, kThemeStateInactive][not onoff]
+            #App.DrawThemeEditTextFrame(Qd.InsetRect(self._bounds, 1, 1), state)
+
+            if self._selected:
+                if onoff:
+                    self.ted.WEActivate()
+                else:
+                    self.ted.WEDeactivate()
+                self.drawselframe(onoff)
+
+    def select(self, onoff, isclick = 0):
+        if Wbase.SelectableWidget.select(self, onoff):
+            return
+        self.SetPort()
+        if onoff:
+            self.ted.WEActivate()
+            if self._parentwindow._tabbable and not isclick:
+                self.selectall()
+        else:
+            self.ted.WEDeactivate()
+        self.drawselframe(onoff)
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            if not visRgn:
+                visRgn = self._parentwindow.wid.GetWindowPort().visRgn
+            self.ted.WEUpdate(visRgn)
+
+            # DISABLED!  There are too many places where it is assumed that
+            # the frame of an EditText item is 1 pixel, inside the bounds.
+            #state = [kThemeStateActive, kThemeStateInactive][not self._activated]
+            #App.DrawThemeEditTextFrame(Qd.InsetRect(self._bounds, 1, 1), state)
+            Qd.FrameRect(self._bounds)
+
+            if self._selected and self._activated:
+                self.drawselframe(1)
+
+    # scrolling
+    def scrollpageup(self):
+        if self._parent._bary and self._parent._bary._enabled:
+            self.vscroll("++")
+
+    def scrollpagedown(self):
+        if self._parent._bary and self._parent._bary._enabled:
+            self.vscroll("--")
+
+    def scrolltop(self):
+        if self._parent._bary and self._parent._bary._enabled:
+            self.vscroll(self._parent._bary.getmin())
+        if self._parent._barx and self._parent._barx._enabled:
+            self.hscroll(self._parent._barx.getmin())
+
+    def scrollbottom(self):
+        if self._parent._bary and self._parent._bary._enabled:
+            self.vscroll(self._parent._bary.getmax())
+
+    # menu handlers
+    def domenu_copy(self, *args):
+        selbegin, selend = self.ted.WEGetSelection()
+        if selbegin == selend:
+            return
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECopy()
+        self.updatescrollbars()
+
+    def domenu_cut(self, *args):
+        selbegin, selend = self.ted.WEGetSelection()
+        if selbegin == selend:
+            return
+        if hasattr(Scrap, 'ZeroScrap'):
+            Scrap.ZeroScrap()
+        else:
+            Scrap.ClearCurrentScrap()
+        self.ted.WECut()
+        self.updatescrollbars()
+        self.selview()
+        self.textchanged()
+        self.selectionchanged()
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, "", None)
+
+    def domenu_paste(self, *args):
+        if not self.ted.WECanPaste():
+            return
+        self.selview()
+        self.ted.WEPaste()
+        self.updatescrollbars()
+        self.textchanged()
+        self.selectionchanged()
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, "", None)
+
+    def domenu_clear(self, *args):
+        self.ted.WEDelete()
+        self.selview()
+        self.updatescrollbars()
+        self.textchanged()
+        self.selectionchanged()
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, "", None)
+
+    def domenu_undo(self, *args):
+        which, redo = self.ted.WEGetUndoInfo()
+        if not which:
+            return
+        self.ted.WEUndo()
+        self.updatescrollbars()
+        self.textchanged()
+        self.selectionchanged()
+        if self._callback:
+            Wbase.CallbackCall(self._callback, 0, "", None)
+
+    def can_undo(self, menuitem):
+        #doundo = self.ted.WEFeatureFlag(WASTEconst.weFUndo, -1)
+        #print doundo
+        #if not doundo:
+        #       return 0
+        which, redo = self.ted.WEGetUndoInfo()
+        if which < len(UNDOLABELS):
+            which = UNDOLABELS[which]
+        else:
+            which = ""
+        if which == None:
+            return None
+        if redo:
+            which = "Redo "+which
+        else:
+            which = "Undo "+which
+        menuitem.settext(which)
+        return 1
+
+    def domenu_selectall(self, *args):
+        self.selectall()
+
+    # private
+    def getscrollrects(self):
+        return self.ted.WEGetDestRect(), self.ted.WEGetViewRect()
+
+    def vscroll(self, value):
+        lineheight = self.ted.WEGetHeight(0, 1)
+        dr = self.ted.WEGetDestRect()
+        vr = self.ted.WEGetViewRect()
+        viewheight = vr[3] - vr[1]
+        maxdelta = vr[1] - dr[1]
+        mindelta = vr[3] - dr[3]
+        if value == "+":
+            delta = lineheight
+        elif value == "-":
+            delta = - lineheight
+        elif value == "++":
+            delta = viewheight - lineheight
+        elif value == "--":
+            delta = lineheight - viewheight
+        else:   # in thumb
+            delta = vr[1] - dr[1] - value
+        delta = min(maxdelta, delta)
+        delta = max(mindelta, delta)
+        delta = int(delta)
+        self.ted.WEScroll(0, delta)
+        self.updatescrollbars()
+
+    def hscroll(self, value):
+        dr = self.ted.WEGetDestRect()
+        vr = self.ted.WEGetViewRect()
+        destwidth = dr[2] - dr[0]
+        viewwidth = vr[2] - vr[0]
+        viewoffset = maxdelta = vr[0] - dr[0]
+        mindelta = vr[2] - dr[2]
+        if value == "+":
+            delta = 32
+        elif value == "-":
+            delta = - 32
+        elif value == "++":
+            delta = 0.5 * (vr[2] - vr[0])
+        elif value == "--":
+            delta = 0.5 * (vr[0] - vr[2])
+        else:   # in thumb
+            delta = vr[0] - dr[0] - value
+            #cur = (32767 * viewoffset) / (destwidth - viewwidth)
+            #delta = (cur-value)*(destwidth - viewwidth)/32767
+            #if abs(delta - viewoffset) <=2:
+            #       # compensate for irritating rounding error
+            #       delta = viewoffset
+        delta = min(maxdelta, delta)
+        delta = max(mindelta, delta)
+        delta = int(delta)
+        self.ted.WEScroll(delta, 0)
+        self.updatescrollbars()
+
+    # some internals
+    def _getflags(self):
+        flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled
+        if self.readonly:
+            flags = flags | WASTEconst.weDoReadOnly
+        else:
+            flags = flags | WASTEconst.weDoUndo
+        return flags
+
+    def _getviewrect(self):
+        return Qd.InsetRect(self._bounds, self.inset[0], self.inset[1])
+
+    def _calctextbounds(self):
+        viewrect = l, t, r, b = self._getviewrect()
+        if self.ted:
+            dl, dt, dr, db = self.ted.WEGetDestRect()
+            vl, vt, vr, vb = self.ted.WEGetViewRect()
+            yshift = t - vt
+            if (db - dt) < (b - t):
+                destrect = viewrect
+            else:
+                destrect = l, dt + yshift, r, db + yshift
+        else:
+            destrect = viewrect
+        return viewrect, destrect
+
 
 class TextEditor(EditText):
-	
-	"""A text edit widget."""
-	
-	def __init__(self, possize, text="", callback=None, wrap=1, inset=(4, 4),
-				fontsettings=None,
-				tabsettings=(32, 0),
-				readonly=0):
-		EditText.__init__(self, possize, text, callback, inset, fontsettings, tabsettings, readonly)
-		self.wrap = wrap
-	
-	def _getflags(self):
-		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled | \
-				WASTEconst.weDoOutlineHilite
-		if self.readonly:
-			flags = flags | WASTEconst.weDoReadOnly
-		else:
-			flags = flags | WASTEconst.weDoUndo
-		return flags
-	
-	def _getviewrect(self):
-		l, t, r, b = self._bounds
-		return (l + 5, t + 2, r, b - 2)
-	
-	def _calctextbounds(self):
-		if self.wrap:
-			return EditText._calctextbounds(self)
-		else:
-			viewrect = l, t, r, b = self._getviewrect()
-			if self.ted:
-				dl, dt, dr, db = self.ted.WEGetDestRect()
-				vl, vt, vr, vb = self.ted.WEGetViewRect()
-				xshift = l - vl
-				yshift = t - vt
-				if (db - dt) < (b - t):
-					yshift = t - dt
-				destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
-			else:
-				destrect = (l, t, r + 5000, b)
-			return viewrect, destrect
-	
-	def draw(self, visRgn = None):
-		if self._visible:
-			if not visRgn:
-				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
-			self.ted.WEUpdate(visRgn)
-			if self._selected and self._activated:
-				self.drawselframe(1)
 
-	def activate(self, onoff):
-		self._activated = onoff
-		if self._visible:
-			self.SetPort()
-			# doesn't draw frame, as EditText.activate does
-			if self._selected:
-				if onoff:
-					self.ted.WEActivate()
-				else:
-					self.ted.WEDeactivate()
-				self.drawselframe(onoff)
+    """A text edit widget."""
+
+    def __init__(self, possize, text="", callback=None, wrap=1, inset=(4, 4),
+                            fontsettings=None,
+                            tabsettings=(32, 0),
+                            readonly=0):
+        EditText.__init__(self, possize, text, callback, inset, fontsettings, tabsettings, readonly)
+        self.wrap = wrap
+
+    def _getflags(self):
+        flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled | \
+                        WASTEconst.weDoOutlineHilite
+        if self.readonly:
+            flags = flags | WASTEconst.weDoReadOnly
+        else:
+            flags = flags | WASTEconst.weDoUndo
+        return flags
+
+    def _getviewrect(self):
+        l, t, r, b = self._bounds
+        return (l + 5, t + 2, r, b - 2)
+
+    def _calctextbounds(self):
+        if self.wrap:
+            return EditText._calctextbounds(self)
+        else:
+            viewrect = l, t, r, b = self._getviewrect()
+            if self.ted:
+                dl, dt, dr, db = self.ted.WEGetDestRect()
+                vl, vt, vr, vb = self.ted.WEGetViewRect()
+                xshift = l - vl
+                yshift = t - vt
+                if (db - dt) < (b - t):
+                    yshift = t - dt
+                destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
+            else:
+                destrect = (l, t, r + 5000, b)
+            return viewrect, destrect
+
+    def draw(self, visRgn = None):
+        if self._visible:
+            if not visRgn:
+                visRgn = self._parentwindow.wid.GetWindowPort().visRgn
+            self.ted.WEUpdate(visRgn)
+            if self._selected and self._activated:
+                self.drawselframe(1)
+
+    def activate(self, onoff):
+        self._activated = onoff
+        if self._visible:
+            self.SetPort()
+            # doesn't draw frame, as EditText.activate does
+            if self._selected:
+                if onoff:
+                    self.ted.WEActivate()
+                else:
+                    self.ted.WEDeactivate()
+                self.drawselframe(onoff)
 
 
 import re
@@ -658,479 +658,479 @@
 
 
 class PyEditor(TextEditor):
-	
-	"""A specialized Python source edit widget"""
-	
-	def __init__(self, possize, text="", callback=None, inset=(4, 4),
-				fontsettings=None,
-				tabsettings=(32, 0),
-				readonly=0,
-				debugger=None,
-				file=''):
-		TextEditor.__init__(self, possize, text, callback, 0, inset, fontsettings, tabsettings, readonly)
-		self.bind("cmd[", self.domenu_shiftleft)
-		self.bind("cmd]", self.domenu_shiftright)
-		self.bind("cmdshift[", self.domenu_uncomment)
-		self.bind("cmdshift]", self.domenu_comment)
-		self.bind("cmdshiftd", self.alldirty)
-		self.file = file	# only for debugger reference
-		self._debugger = debugger
-		if debugger:
-			debugger.register_editor(self, self.file)
-		self._dirty = (0, None)
-		self.do_fontify = 0
-	
-	#def open(self):
-	#	TextEditor.open(self)
-	#	if self.do_fontify:
-	#		self.fontify()
-	#	self._dirty = (None, None)
-	
-	def _getflags(self):
-		flags = (WASTEconst.weDoDrawOffscreen | WASTEconst.weDoUseTempMem |
-				WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite)
-		if self.readonly:
-			flags = flags | WASTEconst.weDoReadOnly
-		else:
-			flags = flags | WASTEconst.weDoUndo
-		return flags
-	
-	def textchanged(self, all=0):
-		self.changed = 1
-		if all:
-			self._dirty = (0, None)
-			return
-		oldsel = self.oldselection
-		sel = self.getselection()
-		if not sel:
-			# XXX what to do?
-			return
-		selstart, selend = sel
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		if oldsel:
-			oldselstart, oldselend = min(oldsel), max(oldsel)
-			selstart, selend = min(selstart, oldselstart), max(selend, oldselend)
-		startline = self.offsettoline(selstart)
-		endline = self.offsettoline(selend)
-		selstart, _ = self.ted.WEGetLineRange(startline)
-		_, selend = self.ted.WEGetLineRange(endline)
-		if selstart > 0:
-			selstart = selstart - 1
-		self._dirty = (selstart, selend)
-	
-	def idle(self):
-		self.SetPort()
-		self.ted.WEIdle()
-		if not self.do_fontify:
-			return
-		start, end = self._dirty
-		if start is None:
-			return
-		textLength = self.ted.WEGetTextLength()
-		if end is None:
-			end = textLength
-		if start >= end:
-			self._dirty = (None, None)
-		else:
-			self.fontify(start, end)
-			self._dirty = (None, None)
-	
-	def alldirty(self, *args):
-		self._dirty = (0, None)
-	
-	def fontify(self, start=0, end=None):
-		#W.SetCursor('watch')
-		if self.readonly:
-			self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
-		self.ted.WEFeatureFlag(WASTEconst.weFOutlineHilite, 0)
-		self.ted.WEDeactivate()
-		self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
-		self.ted.WEFeatureFlag(WASTEconst.weFUndo, 0)
-		pytext = self.get().replace("\r", "\n")
-		if end is None:
-			end = len(pytext)
-		else:
-			end = min(end, len(pytext))
-		selstart, selend = self.ted.WEGetSelection()
-		self.ted.WESetSelection(start, end)
-		self.ted.WESetStyle(WASTEconst.weDoFace | WASTEconst.weDoColor, 
-				(0, 0, 12, (0, 0, 0)))
-		
-		tags = PyFontify.fontify(pytext, start, end)
-		styles = {
-			'string': (WASTEconst.weDoColor, (0, 0, 0, kStringColor)),
-			'keyword': (WASTEconst.weDoFace, (0, 1, 0, (0, 0, 0))),
-			'comment': (WASTEconst.weDoFace | WASTEconst.weDoColor, (0, 0, 0, kCommentColor)),
-			'identifier': (WASTEconst.weDoColor, (0, 0, 0, (0xbfff, 0, 0)))
-		}
-		setselection = self.ted.WESetSelection
-		setstyle = self.ted.WESetStyle
-		for tag, start, end, sublist in tags:
-			setselection(start, end)
-			mode, style = styles[tag]
-			setstyle(mode, style)
-		self.ted.WESetSelection(selstart, selend)
-		self.SetPort()
-		self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
-		self.ted.WEFeatureFlag(WASTEconst.weFUndo, 1)
-		self.ted.WEActivate()
-		self.ted.WEFeatureFlag(WASTEconst.weFOutlineHilite, 1)
-		if self.readonly:
-			self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
-	
-	def domenu_shiftleft(self):
-		self.expandselection()
-		selstart, selend = self.ted.WEGetSelection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		snippet = self.getselectedtext()
-		lines = string.split(snippet, '\r')
-		for i in range(len(lines)):
-			if lines[i][:1] == '\t':
-				lines[i] = lines[i][1:]
-		snippet = string.join(lines, '\r')
-		self.insert(snippet)
-		self.ted.WESetSelection(selstart, selstart + len(snippet))
-	
-	def domenu_shiftright(self):
-		self.expandselection()
-		selstart, selend = self.ted.WEGetSelection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		snippet = self.getselectedtext()
-		lines = string.split(snippet, '\r')
-		for i in range(len(lines) - (not lines[-1])):
-			lines[i] = '\t' + lines[i]
-		snippet = string.join(lines, '\r')
-		self.insert(snippet)
-		self.ted.WESetSelection(selstart, selstart + len(snippet))
-	
-	def domenu_uncomment(self):
-		self.expandselection()
-		selstart, selend = self.ted.WEGetSelection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		snippet = self.getselectedtext()
-		lines = string.split(snippet, '\r')
-		for i in range(len(lines)):
-			m = commentPat.match(lines[i])
-			if m:
-				pos = m.start(1)
-				lines[i] = lines[i][:pos] + lines[i][pos+1:]
-		snippet = string.join(lines, '\r')
-		self.insert(snippet)
-		self.ted.WESetSelection(selstart, selstart + len(snippet))
-	
-	def domenu_comment(self):
-		self.expandselection()
-		selstart, selend = self.ted.WEGetSelection()
-		selstart, selend = min(selstart, selend), max(selstart, selend)
-		snippet = self.getselectedtext()
-		lines = string.split(snippet, '\r')
-		indent = 3000 # arbitrary large number...
-		for line in lines:
-			if string.strip(line):
-				m = indentPat.match(line)
-				if m:
-					indent = min(indent, m.regs[0][1])
-				else:
-					indent = 0
-					break
-		for i in range(len(lines) - (not lines[-1])):
-			lines[i] = lines[i][:indent] + "#" + lines[i][indent:]
-		snippet = string.join(lines, '\r')
-		self.insert(snippet)
-		self.ted.WESetSelection(selstart, selstart + len(snippet))
-	
-	def setfile(self, file):
-		self.file = file
-	
-	def set(self, text, file = ''):
-		oldfile = self.file
-		self.file = file
-		if self._debugger:
-			self._debugger.unregister_editor(self, oldfile)
-			self._debugger.register_editor(self, file)
-		TextEditor.set(self, text)
-	
-	def close(self):
-		if self._debugger:
-			self._debugger.unregister_editor(self, self.file)
-			self._debugger = None
-		TextEditor.close(self)		
-	
-	def click(self, point, modifiers):
-		if not self._enabled:
-			return
-		if self._debugger and self.pt_in_breaks(point):
-			self.breakhit(point, modifiers)
-		elif self._debugger:
-			bl, bt, br, bb = self._getbreakrect()
-			Qd.EraseRect((bl, bt, br-1, bb))
-			TextEditor.click(self, point, modifiers)
-			self.drawbreakpoints()
-		else:
-			TextEditor.click(self, point, modifiers)
-			if self.ted.WEGetClickCount() >= 3:
-				# select block with our indent
-				lines = string.split(self.get(), '\r')
-				selstart, selend = self.ted.WEGetSelection()
-				lineno = self.ted.WEOffsetToLine(selstart)
-				tabs = 0
-				line = lines[lineno]
-				while line[tabs:] and line[tabs] == '\t':
-					tabs = tabs + 1
-				tabstag = '\t' * tabs
-				fromline = 0
-				toline = len(lines)
-				if tabs:
-					for i in range(lineno - 1, -1, -1):
-						line = lines[i]
-						if line[:tabs] <> tabstag:
-							fromline = i + 1
-							break
-					for i in range(lineno + 1, toline):
-						line = lines[i]
-						if line[:tabs] <> tabstag:
-							toline = i - 1
-							break
-				selstart, dummy = self.ted.WEGetLineRange(fromline)
-				dummy, selend = self.ted.WEGetLineRange(toline)
-				self.ted.WESetSelection(selstart, selend)
-	
-	def breakhit(self, point, modifiers):
-		if not self.file:
-			return
-		destrect = self.ted.WEGetDestRect()
-		offset, edge = self.ted.WEGetOffset(point)
-		lineno = self.ted.WEOffsetToLine(offset) + 1
-		if point[1] <= destrect[3]:
-			self._debugger.clear_breaks_above(self.file, self.countlines())
-			self._debugger.toggle_break(self.file, lineno)
-		else:
-			self._debugger.clear_breaks_above(self.file, lineno)
-	
-	def key(self, char, event):
-		(what, message, when, where, modifiers) = event
-		if modifiers & Events.cmdKey and not char in Wkeys.arrowkeys:
-			return
-		if char == '\r':
-			selstart, selend = self.ted.WEGetSelection()
-			selstart, selend = min(selstart, selend), max(selstart, selend)
-			lastchar = chr(self.ted.WEGetChar(selstart-1))
-			if lastchar <> '\r' and selstart:
-				pos, dummy = self.ted.WEFindLine(selstart, 0)
-				lineres = Res.Resource('')
-				self.ted.WECopyRange(pos, selstart, lineres, None, None)
-				line = lineres.data + '\n'
-				tabcount = self.extratabs(line)
-				self.ted.WEKey(ord('\r'), 0)
-				for i in range(tabcount):
-					self.ted.WEKey(ord('\t'), 0)
-			else:
-				self.ted.WEKey(ord('\r'), 0)
-		elif char in ')]}':
-			self.ted.WEKey(ord(char), modifiers)
-			self.balanceparens(char)
-		else:
-			self.ted.WEKey(ord(char), modifiers)
-		if char not in Wkeys.navigationkeys:
-			self.textchanged()
-		self.selectionchanged()
-		self.updatescrollbars()
-	
-	def balanceparens(self, char):
-		if char == ')':
-			target = '('
-		elif char == ']':
-			target = '['
-		elif char == '}':
-			target = '{'
-		recursionlevel = 1
-		selstart, selend = self.ted.WEGetSelection()
-		count = min(selstart, selend) - 2
-		mincount = max(0, count - 2048)
-		lastquote = None
-		while count > mincount:
-			testchar = chr(self.ted.WEGetChar(count))
-			if testchar in "\"'" and chr(self.ted.WEGetChar(count - 1)) <> '\\':
-				if lastquote == testchar:
-					recursionlevel = recursionlevel - 1
-					lastquote = None
-				elif not lastquote:
-					recursionlevel = recursionlevel + 1
-					lastquote = testchar
-			elif not lastquote and testchar == char:
-				recursionlevel = recursionlevel + 1
-			elif not lastquote and testchar == target:
-				recursionlevel = recursionlevel - 1
-				if recursionlevel == 0:
-					import time
-					autoscroll = self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, -1)
-					if autoscroll:
-						self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
-					self.ted.WESetSelection(count, count + 1)
-					self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)  # needed under OSX
-					time.sleep(0.2)
-					self.ted.WESetSelection(selstart, selend)
-					if autoscroll:
-						self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
-					break
-			count = count - 1
-	
-	def extratabs(self, line):
-		tabcount = 0
-		for c in line:
-			if c <> '\t':
-				break
-			tabcount = tabcount + 1
-		last = 0
-		cleanline = ''
-		tags = PyFontify.fontify(line)
-		# strip comments and strings
-		for tag, start, end, sublist in tags:
-			if tag in ('string', 'comment'):
-				cleanline = cleanline + line[last:start]
-				last = end
-		cleanline = cleanline + line[last:]
-		cleanline = string.strip(cleanline)
-		if cleanline and cleanline[-1] == ':':
-			tabcount = tabcount + 1
-		else:
-			# extra indent after unbalanced (, [ or {
-			for open, close in (('(', ')'), ('[', ']'), ('{', '}')):
-				count = string.count(cleanline, open)
-				if count and count > string.count(cleanline, close):
-					tabcount = tabcount + 2
-					break
-		return tabcount
-	
-	def rollover(self, point, onoff):
-		if onoff:
-			if self._debugger and self.pt_in_breaks(point):
-				Wbase.SetCursor("arrow")
-			else:
-				Wbase.SetCursor("iBeam")
-	
-	def draw(self, visRgn = None):
-		TextEditor.draw(self, visRgn)
-		if self._debugger:
-			self.drawbreakpoints()
-	
-	def showbreakpoints(self, onoff):
-		if (not not self._debugger) <> onoff:
-			if onoff:
-				if not __debug__:
-					import W
-					raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)"
-				import PyDebugger
-				self._debugger = PyDebugger.getdebugger()
-				self._debugger.register_editor(self, self.file)
-			elif self._debugger:
-				self._debugger.unregister_editor(self, self.file)
-				self._debugger = None
-			self.adjust(self._bounds)
-	
-	def togglebreakpoints(self):
-		self.showbreakpoints(not self._debugger)
-	
-	def clearbreakpoints(self):
-		if self.file:
-			self._debugger.clear_all_file_breaks(self.file)
-	
-	def editbreakpoints(self):
-		if self._debugger:
-			self._debugger.edit_breaks()
-			self._debugger.breaksviewer.selectfile(self.file)
-	
-	def drawbreakpoints(self, eraseall = 0):
-		breakrect = bl, bt, br, bb = self._getbreakrect()
-		br = br - 1
-		self.SetPort()
-		Qd.PenPat(Qd.GetQDGlobalsGray())
-		Qd.PaintRect((br, bt, br + 1, bb))
-		Qd.PenNormal()
-		self._parentwindow.tempcliprect(breakrect)
-		Qd.RGBForeColor((0xffff, 0, 0))
-		try:
-			lasttop = bt
-			self_ted = self.ted
-			Qd_PaintOval = Qd.PaintOval
-			Qd_EraseRect = Qd.EraseRect
-			for lineno in self._debugger.get_file_breaks(self.file):
-				start, end = self_ted.WEGetLineRange(lineno - 1)
-				if lineno <> self_ted.WEOffsetToLine(start) + 1:
-					# breakpoints beyond our text: erase rest, and back out
-					Qd_EraseRect((bl, lasttop, br, bb))
-					break
-				(x, y), h = self_ted.WEGetPoint(start, 0)
-				bottom = y + h
-				#print y, (lasttop, bottom)
-				if bottom > lasttop:
-					Qd_EraseRect((bl, lasttop, br, y + h * eraseall))
-					lasttop = bottom
-				redbullet = bl + 2, y + 3, bl + 8, y + 9
-				Qd_PaintOval(redbullet)
-			else:
-				Qd_EraseRect((bl, lasttop, br, bb))
-			Qd.RGBForeColor((0, 0, 0))
-		finally:
-			self._parentwindow.restoreclip()
-	
-	def updatescrollbars(self):
-		if self._debugger:
-			self.drawbreakpoints(1)
-		TextEditor.updatescrollbars(self)
-	
-	def pt_in_breaks(self, point):
-		return Qd.PtInRect(point, self._getbreakrect())
-	
-	def _getbreakrect(self):
-		if self._debugger:
-			l, t, r, b = self._bounds
-			return (l+1, t+1, l + 12, b-1)
-		else:
-			return (0, 0, 0, 0)
-	
-	def _getviewrect(self):
-		l, t, r, b = self._bounds
-		if self._debugger:
-			return (l + 17, t + 2, r, b - 2)
-		else:
-			return (l + 5, t + 2, r, b - 2)
-	
-	def _calctextbounds(self):
-		viewrect = l, t, r, b = self._getviewrect()
-		if self.ted:
-			dl, dt, dr, db = self.ted.WEGetDestRect()
-			vl, vt, vr, vb = self.ted.WEGetViewRect()
-			xshift = l - vl
-			yshift = t - vt
-			if (db - dt) < (b - t):
-				yshift = t - dt
-			destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
-		else:
-			destrect = (l, t, r + 5000, b)
-		return viewrect, destrect
+
+    """A specialized Python source edit widget"""
+
+    def __init__(self, possize, text="", callback=None, inset=(4, 4),
+                            fontsettings=None,
+                            tabsettings=(32, 0),
+                            readonly=0,
+                            debugger=None,
+                            file=''):
+        TextEditor.__init__(self, possize, text, callback, 0, inset, fontsettings, tabsettings, readonly)
+        self.bind("cmd[", self.domenu_shiftleft)
+        self.bind("cmd]", self.domenu_shiftright)
+        self.bind("cmdshift[", self.domenu_uncomment)
+        self.bind("cmdshift]", self.domenu_comment)
+        self.bind("cmdshiftd", self.alldirty)
+        self.file = file        # only for debugger reference
+        self._debugger = debugger
+        if debugger:
+            debugger.register_editor(self, self.file)
+        self._dirty = (0, None)
+        self.do_fontify = 0
+
+    #def open(self):
+    #       TextEditor.open(self)
+    #       if self.do_fontify:
+    #               self.fontify()
+    #       self._dirty = (None, None)
+
+    def _getflags(self):
+        flags = (WASTEconst.weDoDrawOffscreen | WASTEconst.weDoUseTempMem |
+                        WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite)
+        if self.readonly:
+            flags = flags | WASTEconst.weDoReadOnly
+        else:
+            flags = flags | WASTEconst.weDoUndo
+        return flags
+
+    def textchanged(self, all=0):
+        self.changed = 1
+        if all:
+            self._dirty = (0, None)
+            return
+        oldsel = self.oldselection
+        sel = self.getselection()
+        if not sel:
+            # XXX what to do?
+            return
+        selstart, selend = sel
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        if oldsel:
+            oldselstart, oldselend = min(oldsel), max(oldsel)
+            selstart, selend = min(selstart, oldselstart), max(selend, oldselend)
+        startline = self.offsettoline(selstart)
+        endline = self.offsettoline(selend)
+        selstart, _ = self.ted.WEGetLineRange(startline)
+        _, selend = self.ted.WEGetLineRange(endline)
+        if selstart > 0:
+            selstart = selstart - 1
+        self._dirty = (selstart, selend)
+
+    def idle(self):
+        self.SetPort()
+        self.ted.WEIdle()
+        if not self.do_fontify:
+            return
+        start, end = self._dirty
+        if start is None:
+            return
+        textLength = self.ted.WEGetTextLength()
+        if end is None:
+            end = textLength
+        if start >= end:
+            self._dirty = (None, None)
+        else:
+            self.fontify(start, end)
+            self._dirty = (None, None)
+
+    def alldirty(self, *args):
+        self._dirty = (0, None)
+
+    def fontify(self, start=0, end=None):
+        #W.SetCursor('watch')
+        if self.readonly:
+            self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
+        self.ted.WEFeatureFlag(WASTEconst.weFOutlineHilite, 0)
+        self.ted.WEDeactivate()
+        self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
+        self.ted.WEFeatureFlag(WASTEconst.weFUndo, 0)
+        pytext = self.get().replace("\r", "\n")
+        if end is None:
+            end = len(pytext)
+        else:
+            end = min(end, len(pytext))
+        selstart, selend = self.ted.WEGetSelection()
+        self.ted.WESetSelection(start, end)
+        self.ted.WESetStyle(WASTEconst.weDoFace | WASTEconst.weDoColor,
+                        (0, 0, 12, (0, 0, 0)))
+
+        tags = PyFontify.fontify(pytext, start, end)
+        styles = {
+                'string': (WASTEconst.weDoColor, (0, 0, 0, kStringColor)),
+                'keyword': (WASTEconst.weDoFace, (0, 1, 0, (0, 0, 0))),
+                'comment': (WASTEconst.weDoFace | WASTEconst.weDoColor, (0, 0, 0, kCommentColor)),
+                'identifier': (WASTEconst.weDoColor, (0, 0, 0, (0xbfff, 0, 0)))
+        }
+        setselection = self.ted.WESetSelection
+        setstyle = self.ted.WESetStyle
+        for tag, start, end, sublist in tags:
+            setselection(start, end)
+            mode, style = styles[tag]
+            setstyle(mode, style)
+        self.ted.WESetSelection(selstart, selend)
+        self.SetPort()
+        self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
+        self.ted.WEFeatureFlag(WASTEconst.weFUndo, 1)
+        self.ted.WEActivate()
+        self.ted.WEFeatureFlag(WASTEconst.weFOutlineHilite, 1)
+        if self.readonly:
+            self.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
+
+    def domenu_shiftleft(self):
+        self.expandselection()
+        selstart, selend = self.ted.WEGetSelection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        snippet = self.getselectedtext()
+        lines = string.split(snippet, '\r')
+        for i in range(len(lines)):
+            if lines[i][:1] == '\t':
+                lines[i] = lines[i][1:]
+        snippet = string.join(lines, '\r')
+        self.insert(snippet)
+        self.ted.WESetSelection(selstart, selstart + len(snippet))
+
+    def domenu_shiftright(self):
+        self.expandselection()
+        selstart, selend = self.ted.WEGetSelection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        snippet = self.getselectedtext()
+        lines = string.split(snippet, '\r')
+        for i in range(len(lines) - (not lines[-1])):
+            lines[i] = '\t' + lines[i]
+        snippet = string.join(lines, '\r')
+        self.insert(snippet)
+        self.ted.WESetSelection(selstart, selstart + len(snippet))
+
+    def domenu_uncomment(self):
+        self.expandselection()
+        selstart, selend = self.ted.WEGetSelection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        snippet = self.getselectedtext()
+        lines = string.split(snippet, '\r')
+        for i in range(len(lines)):
+            m = commentPat.match(lines[i])
+            if m:
+                pos = m.start(1)
+                lines[i] = lines[i][:pos] + lines[i][pos+1:]
+        snippet = string.join(lines, '\r')
+        self.insert(snippet)
+        self.ted.WESetSelection(selstart, selstart + len(snippet))
+
+    def domenu_comment(self):
+        self.expandselection()
+        selstart, selend = self.ted.WEGetSelection()
+        selstart, selend = min(selstart, selend), max(selstart, selend)
+        snippet = self.getselectedtext()
+        lines = string.split(snippet, '\r')
+        indent = 3000 # arbitrary large number...
+        for line in lines:
+            if string.strip(line):
+                m = indentPat.match(line)
+                if m:
+                    indent = min(indent, m.regs[0][1])
+                else:
+                    indent = 0
+                    break
+        for i in range(len(lines) - (not lines[-1])):
+            lines[i] = lines[i][:indent] + "#" + lines[i][indent:]
+        snippet = string.join(lines, '\r')
+        self.insert(snippet)
+        self.ted.WESetSelection(selstart, selstart + len(snippet))
+
+    def setfile(self, file):
+        self.file = file
+
+    def set(self, text, file = ''):
+        oldfile = self.file
+        self.file = file
+        if self._debugger:
+            self._debugger.unregister_editor(self, oldfile)
+            self._debugger.register_editor(self, file)
+        TextEditor.set(self, text)
+
+    def close(self):
+        if self._debugger:
+            self._debugger.unregister_editor(self, self.file)
+            self._debugger = None
+        TextEditor.close(self)
+
+    def click(self, point, modifiers):
+        if not self._enabled:
+            return
+        if self._debugger and self.pt_in_breaks(point):
+            self.breakhit(point, modifiers)
+        elif self._debugger:
+            bl, bt, br, bb = self._getbreakrect()
+            Qd.EraseRect((bl, bt, br-1, bb))
+            TextEditor.click(self, point, modifiers)
+            self.drawbreakpoints()
+        else:
+            TextEditor.click(self, point, modifiers)
+            if self.ted.WEGetClickCount() >= 3:
+                # select block with our indent
+                lines = string.split(self.get(), '\r')
+                selstart, selend = self.ted.WEGetSelection()
+                lineno = self.ted.WEOffsetToLine(selstart)
+                tabs = 0
+                line = lines[lineno]
+                while line[tabs:] and line[tabs] == '\t':
+                    tabs = tabs + 1
+                tabstag = '\t' * tabs
+                fromline = 0
+                toline = len(lines)
+                if tabs:
+                    for i in range(lineno - 1, -1, -1):
+                        line = lines[i]
+                        if line[:tabs] <> tabstag:
+                            fromline = i + 1
+                            break
+                    for i in range(lineno + 1, toline):
+                        line = lines[i]
+                        if line[:tabs] <> tabstag:
+                            toline = i - 1
+                            break
+                selstart, dummy = self.ted.WEGetLineRange(fromline)
+                dummy, selend = self.ted.WEGetLineRange(toline)
+                self.ted.WESetSelection(selstart, selend)
+
+    def breakhit(self, point, modifiers):
+        if not self.file:
+            return
+        destrect = self.ted.WEGetDestRect()
+        offset, edge = self.ted.WEGetOffset(point)
+        lineno = self.ted.WEOffsetToLine(offset) + 1
+        if point[1] <= destrect[3]:
+            self._debugger.clear_breaks_above(self.file, self.countlines())
+            self._debugger.toggle_break(self.file, lineno)
+        else:
+            self._debugger.clear_breaks_above(self.file, lineno)
+
+    def key(self, char, event):
+        (what, message, when, where, modifiers) = event
+        if modifiers & Events.cmdKey and not char in Wkeys.arrowkeys:
+            return
+        if char == '\r':
+            selstart, selend = self.ted.WEGetSelection()
+            selstart, selend = min(selstart, selend), max(selstart, selend)
+            lastchar = chr(self.ted.WEGetChar(selstart-1))
+            if lastchar <> '\r' and selstart:
+                pos, dummy = self.ted.WEFindLine(selstart, 0)
+                lineres = Res.Resource('')
+                self.ted.WECopyRange(pos, selstart, lineres, None, None)
+                line = lineres.data + '\n'
+                tabcount = self.extratabs(line)
+                self.ted.WEKey(ord('\r'), 0)
+                for i in range(tabcount):
+                    self.ted.WEKey(ord('\t'), 0)
+            else:
+                self.ted.WEKey(ord('\r'), 0)
+        elif char in ')]}':
+            self.ted.WEKey(ord(char), modifiers)
+            self.balanceparens(char)
+        else:
+            self.ted.WEKey(ord(char), modifiers)
+        if char not in Wkeys.navigationkeys:
+            self.textchanged()
+        self.selectionchanged()
+        self.updatescrollbars()
+
+    def balanceparens(self, char):
+        if char == ')':
+            target = '('
+        elif char == ']':
+            target = '['
+        elif char == '}':
+            target = '{'
+        recursionlevel = 1
+        selstart, selend = self.ted.WEGetSelection()
+        count = min(selstart, selend) - 2
+        mincount = max(0, count - 2048)
+        lastquote = None
+        while count > mincount:
+            testchar = chr(self.ted.WEGetChar(count))
+            if testchar in "\"'" and chr(self.ted.WEGetChar(count - 1)) <> '\\':
+                if lastquote == testchar:
+                    recursionlevel = recursionlevel - 1
+                    lastquote = None
+                elif not lastquote:
+                    recursionlevel = recursionlevel + 1
+                    lastquote = testchar
+            elif not lastquote and testchar == char:
+                recursionlevel = recursionlevel + 1
+            elif not lastquote and testchar == target:
+                recursionlevel = recursionlevel - 1
+                if recursionlevel == 0:
+                    import time
+                    autoscroll = self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, -1)
+                    if autoscroll:
+                        self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
+                    self.ted.WESetSelection(count, count + 1)
+                    self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)  # needed under OSX
+                    time.sleep(0.2)
+                    self.ted.WESetSelection(selstart, selend)
+                    if autoscroll:
+                        self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
+                    break
+            count = count - 1
+
+    def extratabs(self, line):
+        tabcount = 0
+        for c in line:
+            if c <> '\t':
+                break
+            tabcount = tabcount + 1
+        last = 0
+        cleanline = ''
+        tags = PyFontify.fontify(line)
+        # strip comments and strings
+        for tag, start, end, sublist in tags:
+            if tag in ('string', 'comment'):
+                cleanline = cleanline + line[last:start]
+                last = end
+        cleanline = cleanline + line[last:]
+        cleanline = string.strip(cleanline)
+        if cleanline and cleanline[-1] == ':':
+            tabcount = tabcount + 1
+        else:
+            # extra indent after unbalanced (, [ or {
+            for open, close in (('(', ')'), ('[', ']'), ('{', '}')):
+                count = string.count(cleanline, open)
+                if count and count > string.count(cleanline, close):
+                    tabcount = tabcount + 2
+                    break
+        return tabcount
+
+    def rollover(self, point, onoff):
+        if onoff:
+            if self._debugger and self.pt_in_breaks(point):
+                Wbase.SetCursor("arrow")
+            else:
+                Wbase.SetCursor("iBeam")
+
+    def draw(self, visRgn = None):
+        TextEditor.draw(self, visRgn)
+        if self._debugger:
+            self.drawbreakpoints()
+
+    def showbreakpoints(self, onoff):
+        if (not not self._debugger) <> onoff:
+            if onoff:
+                if not __debug__:
+                    import W
+                    raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)"
+                import PyDebugger
+                self._debugger = PyDebugger.getdebugger()
+                self._debugger.register_editor(self, self.file)
+            elif self._debugger:
+                self._debugger.unregister_editor(self, self.file)
+                self._debugger = None
+            self.adjust(self._bounds)
+
+    def togglebreakpoints(self):
+        self.showbreakpoints(not self._debugger)
+
+    def clearbreakpoints(self):
+        if self.file:
+            self._debugger.clear_all_file_breaks(self.file)
+
+    def editbreakpoints(self):
+        if self._debugger:
+            self._debugger.edit_breaks()
+            self._debugger.breaksviewer.selectfile(self.file)
+
+    def drawbreakpoints(self, eraseall = 0):
+        breakrect = bl, bt, br, bb = self._getbreakrect()
+        br = br - 1
+        self.SetPort()
+        Qd.PenPat(Qd.GetQDGlobalsGray())
+        Qd.PaintRect((br, bt, br + 1, bb))
+        Qd.PenNormal()
+        self._parentwindow.tempcliprect(breakrect)
+        Qd.RGBForeColor((0xffff, 0, 0))
+        try:
+            lasttop = bt
+            self_ted = self.ted
+            Qd_PaintOval = Qd.PaintOval
+            Qd_EraseRect = Qd.EraseRect
+            for lineno in self._debugger.get_file_breaks(self.file):
+                start, end = self_ted.WEGetLineRange(lineno - 1)
+                if lineno <> self_ted.WEOffsetToLine(start) + 1:
+                    # breakpoints beyond our text: erase rest, and back out
+                    Qd_EraseRect((bl, lasttop, br, bb))
+                    break
+                (x, y), h = self_ted.WEGetPoint(start, 0)
+                bottom = y + h
+                #print y, (lasttop, bottom)
+                if bottom > lasttop:
+                    Qd_EraseRect((bl, lasttop, br, y + h * eraseall))
+                    lasttop = bottom
+                redbullet = bl + 2, y + 3, bl + 8, y + 9
+                Qd_PaintOval(redbullet)
+            else:
+                Qd_EraseRect((bl, lasttop, br, bb))
+            Qd.RGBForeColor((0, 0, 0))
+        finally:
+            self._parentwindow.restoreclip()
+
+    def updatescrollbars(self):
+        if self._debugger:
+            self.drawbreakpoints(1)
+        TextEditor.updatescrollbars(self)
+
+    def pt_in_breaks(self, point):
+        return Qd.PtInRect(point, self._getbreakrect())
+
+    def _getbreakrect(self):
+        if self._debugger:
+            l, t, r, b = self._bounds
+            return (l+1, t+1, l + 12, b-1)
+        else:
+            return (0, 0, 0, 0)
+
+    def _getviewrect(self):
+        l, t, r, b = self._bounds
+        if self._debugger:
+            return (l + 17, t + 2, r, b - 2)
+        else:
+            return (l + 5, t + 2, r, b - 2)
+
+    def _calctextbounds(self):
+        viewrect = l, t, r, b = self._getviewrect()
+        if self.ted:
+            dl, dt, dr, db = self.ted.WEGetDestRect()
+            vl, vt, vr, vb = self.ted.WEGetViewRect()
+            xshift = l - vl
+            yshift = t - vt
+            if (db - dt) < (b - t):
+                yshift = t - dt
+            destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
+        else:
+            destrect = (l, t, r + 5000, b)
+        return viewrect, destrect
 
 
 def GetFNum(fontname):
-	"""Same as Fm.GetFNum(), but maps a missing font to Monaco instead of the system font."""
-	if fontname <> Fm.GetFontName(0):
-		fontid = Fm.GetFNum(fontname)
-		if fontid == 0:
-			fontid = Fonts.monaco
-	else:
-		fontid = 0
-	return fontid
+    """Same as Fm.GetFNum(), but maps a missing font to Monaco instead of the system font."""
+    if fontname <> Fm.GetFontName(0):
+        fontid = Fm.GetFNum(fontname)
+        if fontid == 0:
+            fontid = Fonts.monaco
+    else:
+        fontid = 0
+    return fontid
 
 # b/w compat. Anyone using this?
 GetFName = Fm.GetFontName
 
 def GetPortFontSettings(port):
-	return Fm.GetFontName(port.GetPortTextFont()), port.GetPortTextFace(), port.GetPortTextSize()
+    return Fm.GetFontName(port.GetPortTextFont()), port.GetPortTextFace(), port.GetPortTextSize()
 
 def SetPortFontSettings(port, (font, face, size)):
-	saveport = Qd.GetPort()
-	Qd.SetPort(port)
-	Qd.TextFont(GetFNum(font))
-	Qd.TextFace(face)
-	Qd.TextSize(size)
-	Qd.SetPort(saveport)
+    saveport = Qd.GetPort()
+    Qd.SetPort(port)
+    Qd.TextFont(GetFNum(font))
+    Qd.TextFace(face)
+    Qd.TextSize(size)
+    Qd.SetPort(saveport)
diff --git a/Mac/Tools/IDE/Wtraceback.py b/Mac/Tools/IDE/Wtraceback.py
index 90a25fe..e84349d 100644
--- a/Mac/Tools/IDE/Wtraceback.py
+++ b/Mac/Tools/IDE/Wtraceback.py
@@ -7,182 +7,181 @@
 
 
 class TraceBack:
-	
-	def __init__(self, title = "Traceback"):
-		app = W.getapplication()  # checks if W is properly initialized
-		self.title = title
-		self.w = None
-		self.closed = 1
-		self.start = 0
-		self.lastwindowtitle = ""
-		self.bounds = (360, 298)
-	
-	def traceback(self, start = 0, lastwindowtitle = ""):
-		try:
-			self.lastwindowtitle = lastwindowtitle
-			self.start = start
-			self.type, self.value, self.tb = sys.exc_info()
-			if self.type is not SyntaxError:
-				self.show()
-				if type(self.type) == types.ClassType:
-					errortext = self.type.__name__
-				else:
-					errortext = str(self.type)
-				value = str(self.value)
-				if self.value and value:
-					errortext = errortext + ": " + value
-				self.w.text.set(errortext)
-				self.buildtblist()
-				self.w.list.set(self.textlist)
-				self.w.list.setselection([len(self.textlist) - 1])
-				self.w.wid.SelectWindow()
-				self.closed = 0
-			else:
-				self.syntaxerror()
-		except:
-			traceback.print_exc()
-	
-	def syntaxerror(self):
-		try:
-			value, (filename, lineno, charno, line) = self.value
-		except:
-			filename = ""
-			lineno = None
-			value = self.value
-		if not filename and self.lastwindowtitle:
-			filename = self.lastwindowtitle
-		elif not filename:
-			filename = "<unknown>"
-		if filename and os.path.exists(filename):
-			filename = os.path.split(filename)[1]
-		if lineno and charno is not None:
-			charno = charno - 1
-			text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1]
-		else:
-			text = str(value) + '\rFile: "' + str(filename) + '"'
-		self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
-		self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
-		self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
-		self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
-		self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
-		self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
-		self.syntaxdialog.open()
-	
-	def syntaxclose(self):
-		self.syntaxdialog.close()
-		del self.syntaxdialog
-	
-	def syntaxedit(self):
-		try:
-			value, (filename, lineno, charno, line) = self.value
-		except:
-			filename = ""
-			lineno = None
-		if not filename and self.lastwindowtitle:
-			filename = self.lastwindowtitle
-		elif not filename:
-			filename = "<unknown>"
-		self.syntaxclose()
-		if lineno:
-			if charno is None:
-				charno = 1
-			W.getapplication().openscript(filename, lineno, charno - 1)
-		else:
-			W.getapplication().openscript(filename)
-	
-	def show(self):
-		if self.closed:
-			self.setupwidgets()
-			self.w.open()
-		else:
-			self.w.wid.ShowWindow()
-			self.w.wid.SelectWindow()
-	
-	def hide(self):
-		if self.closed:
-			return
-		self.w.close()
-	
-	def close(self):
-		self.bounds = self.w.getbounds()
-		self.closed = 1
-		self.type, self.value, self.tb = None, None, None
-		self.tblist = None
-	
-	def activate(self, onoff):
-		if onoff:
-			if self.closed:
-				self.traceback()
-			self.closed = 0
-			self.checkbuttons()
-	
-	def setupwidgets(self):
-		self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
-		self.w.text = W.TextBox((10, 10, -10, 30))
-		self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
-		self.w.list = W.TwoLineList((10, 60, -10, -40), callback = self.listhit)
-		
-		self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
-		self.w.editbutton.enable(0)
-		
-		self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals\xc9", self.browselocals)
-		self.w.browselocalsbutton.enable(0)
-		
-		self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem\xc9", self.postmortem)
-		
-		self.w.setdefaultbutton(self.w.editbutton)
-		self.w.bind("cmdb", self.w.browselocalsbutton.push)
-		self.w.bind("<close>", self.close)
-		self.w.bind("<activate>", self.activate)
-	
-	def buildtblist(self):
-		tb = self.tb
-		for i in range(self.start):
-			if tb.tb_next is None:
-				break
-			tb = tb.tb_next
-		self.tblist = traceback.extract_tb(tb)
-		self.textlist = []
-		for filename, lineno, func, line in self.tblist:
-			tbline = ""
-			if os.path.exists(filename):
-				filename = os.path.split(filename)[1]
-			tbline = 'File "%s", line %r, in %r' % (filename, lineno, func)
-			if line:
-				tbline = tbline + '\r      ' + line
-			self.textlist.append(tbline[:255])
-	
-	def edit(self):
-		sel = self.w.list.getselection()
-		for i in sel:
-			filename, lineno, func, line = self.tblist[i]
-			W.getapplication().openscript(filename, lineno)
-	
-	def browselocals(self):
-		sel = self.w.list.getselection()
-		for i in sel:
-			tb = self.tb
-			for j in range(i + self.start):
-				tb = tb.tb_next
-			self.browse(tb.tb_frame.f_locals)
-	
-	def browse(self, object):
-		import PyBrowser
-		PyBrowser.Browser(object)
-	
-	def postmortem(self):
-		import PyDebugger
-		PyDebugger.postmortem(self.type, self.value, self.tb)
-	
-	def listhit(self, isdbl):
-		if isdbl:
-			self.w.editbutton.push()
-		else:
-			self.checkbuttons()
-	
-	def checkbuttons(self):
-		havefile = len(self.w.list.getselection()) > 0
-		self.w.editbutton.enable(havefile)
-		self.w.browselocalsbutton.enable(havefile)
-		self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)
 
+    def __init__(self, title = "Traceback"):
+        app = W.getapplication()  # checks if W is properly initialized
+        self.title = title
+        self.w = None
+        self.closed = 1
+        self.start = 0
+        self.lastwindowtitle = ""
+        self.bounds = (360, 298)
+
+    def traceback(self, start = 0, lastwindowtitle = ""):
+        try:
+            self.lastwindowtitle = lastwindowtitle
+            self.start = start
+            self.type, self.value, self.tb = sys.exc_info()
+            if self.type is not SyntaxError:
+                self.show()
+                if type(self.type) == types.ClassType:
+                    errortext = self.type.__name__
+                else:
+                    errortext = str(self.type)
+                value = str(self.value)
+                if self.value and value:
+                    errortext = errortext + ": " + value
+                self.w.text.set(errortext)
+                self.buildtblist()
+                self.w.list.set(self.textlist)
+                self.w.list.setselection([len(self.textlist) - 1])
+                self.w.wid.SelectWindow()
+                self.closed = 0
+            else:
+                self.syntaxerror()
+        except:
+            traceback.print_exc()
+
+    def syntaxerror(self):
+        try:
+            value, (filename, lineno, charno, line) = self.value
+        except:
+            filename = ""
+            lineno = None
+            value = self.value
+        if not filename and self.lastwindowtitle:
+            filename = self.lastwindowtitle
+        elif not filename:
+            filename = "<unknown>"
+        if filename and os.path.exists(filename):
+            filename = os.path.split(filename)[1]
+        if lineno and charno is not None:
+            charno = charno - 1
+            text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1]
+        else:
+            text = str(value) + '\rFile: "' + str(filename) + '"'
+        self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
+        self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
+        self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
+        self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
+        self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
+        self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
+        self.syntaxdialog.open()
+
+    def syntaxclose(self):
+        self.syntaxdialog.close()
+        del self.syntaxdialog
+
+    def syntaxedit(self):
+        try:
+            value, (filename, lineno, charno, line) = self.value
+        except:
+            filename = ""
+            lineno = None
+        if not filename and self.lastwindowtitle:
+            filename = self.lastwindowtitle
+        elif not filename:
+            filename = "<unknown>"
+        self.syntaxclose()
+        if lineno:
+            if charno is None:
+                charno = 1
+            W.getapplication().openscript(filename, lineno, charno - 1)
+        else:
+            W.getapplication().openscript(filename)
+
+    def show(self):
+        if self.closed:
+            self.setupwidgets()
+            self.w.open()
+        else:
+            self.w.wid.ShowWindow()
+            self.w.wid.SelectWindow()
+
+    def hide(self):
+        if self.closed:
+            return
+        self.w.close()
+
+    def close(self):
+        self.bounds = self.w.getbounds()
+        self.closed = 1
+        self.type, self.value, self.tb = None, None, None
+        self.tblist = None
+
+    def activate(self, onoff):
+        if onoff:
+            if self.closed:
+                self.traceback()
+            self.closed = 0
+            self.checkbuttons()
+
+    def setupwidgets(self):
+        self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
+        self.w.text = W.TextBox((10, 10, -10, 30))
+        self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
+        self.w.list = W.TwoLineList((10, 60, -10, -40), callback = self.listhit)
+
+        self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
+        self.w.editbutton.enable(0)
+
+        self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals\xc9", self.browselocals)
+        self.w.browselocalsbutton.enable(0)
+
+        self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem\xc9", self.postmortem)
+
+        self.w.setdefaultbutton(self.w.editbutton)
+        self.w.bind("cmdb", self.w.browselocalsbutton.push)
+        self.w.bind("<close>", self.close)
+        self.w.bind("<activate>", self.activate)
+
+    def buildtblist(self):
+        tb = self.tb
+        for i in range(self.start):
+            if tb.tb_next is None:
+                break
+            tb = tb.tb_next
+        self.tblist = traceback.extract_tb(tb)
+        self.textlist = []
+        for filename, lineno, func, line in self.tblist:
+            tbline = ""
+            if os.path.exists(filename):
+                filename = os.path.split(filename)[1]
+            tbline = 'File "%s", line %r, in %r' % (filename, lineno, func)
+            if line:
+                tbline = tbline + '\r      ' + line
+            self.textlist.append(tbline[:255])
+
+    def edit(self):
+        sel = self.w.list.getselection()
+        for i in sel:
+            filename, lineno, func, line = self.tblist[i]
+            W.getapplication().openscript(filename, lineno)
+
+    def browselocals(self):
+        sel = self.w.list.getselection()
+        for i in sel:
+            tb = self.tb
+            for j in range(i + self.start):
+                tb = tb.tb_next
+            self.browse(tb.tb_frame.f_locals)
+
+    def browse(self, object):
+        import PyBrowser
+        PyBrowser.Browser(object)
+
+    def postmortem(self):
+        import PyDebugger
+        PyDebugger.postmortem(self.type, self.value, self.tb)
+
+    def listhit(self, isdbl):
+        if isdbl:
+            self.w.editbutton.push()
+        else:
+            self.checkbuttons()
+
+    def checkbuttons(self):
+        havefile = len(self.w.list.getselection()) > 0
+        self.w.editbutton.enable(havefile)
+        self.w.browselocalsbutton.enable(havefile)
+        self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)
diff --git a/Mac/Tools/IDE/Wwindows.py b/Mac/Tools/IDE/Wwindows.py
index d646bcf..cb8d855 100644
--- a/Mac/Tools/IDE/Wwindows.py
+++ b/Mac/Tools/IDE/Wwindows.py
@@ -8,629 +8,629 @@
 from types import InstanceType, StringType
 
 if hasattr(Win, "FrontNonFloatingWindow"):
-	MyFrontWindow = Win.FrontNonFloatingWindow
+    MyFrontWindow = Win.FrontNonFloatingWindow
 else:
-	MyFrontWindow = Win.FrontWindow
+    MyFrontWindow = Win.FrontWindow
 
 
 class Window(FrameWork.Window, Wbase.SelectableWidget):
-	
-	windowkind = Windows.documentProc
-	
-	def __init__(self, possize, title="", minsize=None, maxsize=None, 
-			tabbable=1, show=1, fontsettings=None):
-		import W
-		if fontsettings is None:
-			fontsettings = W.getdefaultfont()
-		self._fontsettings = fontsettings
-		W.SelectableWidget.__init__(self, possize)
-		self._globalbounds = l, t, r, b = self.getwindowbounds(possize, minsize)
-		self._bounds = (0, 0, r - l, b - t)
-		self._tabchain = []
-		self._currentwidget = None
-		self.title = title
-		self._parentwindow = self
-		self._tabbable = tabbable
-		self._defaultbutton = None
-		self._drawwidgetbounds = 0
-		self._show = show
-		self._lastrollover = None
-		self.hasclosebox = 1
-		# XXX the following is not really compatible with the
-		#  new (system >= 7.5) window procs. 
-		if minsize:
-			self._hasgrowbox = 1
-			self.windowkind = self.windowkind | 8
-			l, t = minsize
-			if maxsize:
-				r, b = maxsize[0] + 1, maxsize[1] + 1
-			else:
-				r, b = 32000, 32000
-			self.growlimit = (l, t, r, b)
-		else:
-			self._hasgrowbox = 0
-			if (self.windowkind == 0 or self.windowkind >= 8) and self.windowkind < 1000:
-				self.windowkind = self.windowkind | 4
-		FrameWork.Window.__init__(self, W.getapplication())
-	
-	def gettitle(self):
-		return self.title
-	
-	def settitle(self, title):
-		self.title = title
-		if self.wid:
-			self.wid.SetWTitle(title)
-	
-	def getwindowbounds(self, size, minsize = None):
-		return windowbounds(size, minsize)	
-	
-	def getcurrentwidget(self):
-		return self._currentwidget
-	
-	def show(self, onoff):
-		if onoff:
-			self.wid.ShowWindow()
-		else:
-			self.wid.HideWindow()
-	
-	def isvisible(self):
-		return self.wid.IsWindowVisible()
-	
-	def select(self):
-		self.wid.SelectWindow()
-		# not sure if this is the best place, I need it when
-		# an editor gets selected, and immediately scrolled
-		# to a certain line, waste scroll assumes everything 
-		# to be in tact.
-		self.do_rawupdate(self.wid, "DummyEvent")
-	
-	def open(self):
-		self.wid = Win.NewCWindow(self._globalbounds, self.title, self._show,
-			self.windowkind, -1, self.hasclosebox, 0)
-		self.SetPort()
-		fontname, fontstyle, fontsize, fontcolor = self._fontsettings
-		fnum = Fm.GetFNum(fontname)
-		if fnum == 0:
-			fnum = Fm.GetFNum("Geneva")
-		Qd.TextFont(fnum)
-		Qd.TextFace(fontstyle)
-		Qd.TextSize(fontsize)
-		if self._bindings.has_key("<open>"):
-			callback = self._bindings["<open>"]
-			callback()
-		for w in self._widgets:
-			w.forall_frombottom("open")
-		self._maketabchain()
-		if self._tabbable:
-			self.bind('tab', self.nextwidget)
-			self.bind('shifttab', self.previouswidget)
-		else:
-			self._hasselframes = 0
-		if self._tabchain:
-			self._tabchain[0].select(1)
-		self.do_postopen()
-	
-	def close(self):
-		if not self.wid:
-			return	# we are already closed
-		if self._bindings.has_key("<close>"):
-			callback = self._bindings["<close>"]
-			try:
-				rv = callback()
-			except:
-				print 'error in <close> callback'
-				traceback.print_exc()
-			else:
-				if rv:
-					return rv
-		#for key in self._widgetsdict.keys():
-		#	self._removewidget(key)
-		self.forall_butself("close")
-		Wbase.SelectableWidget.close(self)
-		self._tabchain = []
-		self._currentwidget = None
-		self.wid.HideWindow()
-		self.do_postclose()
-	
-	def domenu_close(self, *args):
-		self.close()
-	
-	def getbounds(self):
-		return self._globalbounds
-	
-	def setbounds(self, bounds):
-		l, t, r, b = bounds
-		self.move(l, t)
-		self.resize(r-l, b-t)
-	
-	def move(self, x, y = None):
-		"""absolute move"""
-		if y == None:
-			x, y = x
-		self.wid.MoveWindow(x, y, 0)
-	
-	def resize(self, x, y = None):
-		if not self._hasgrowbox:
-			return  # hands off!
-		if y == None:
-			x, y = x
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(self.getgrowrect())
-		self.wid.SizeWindow(x, y, 1)
-		self._calcbounds()
-	
-	def test(self, point):
-		return 1
-	
-	def draw(self, visRgn = None):
-		if self._hasgrowbox:
-			self.tempcliprect(self.getgrowrect())
-			self.wid.DrawGrowIcon()
-			self.restoreclip()
-	
-	def idle(self, *args):
-		self.SetPort()
-		point = Evt.GetMouse()
-		widget = self.findwidget(point, 0)
-		if self._bindings.has_key("<idle>"):
-			callback = self._bindings["<idle>"]
-			if callback():
-				return
-		if self._currentwidget is not None and hasattr(self._currentwidget, "idle"):
-			if self._currentwidget._bindings.has_key("<idle>"):
-				callback = self._currentwidget._bindings["<idle>"]
-				if callback():
-					return
-			if self._currentwidget.idle():
-				return
-		if widget is not None and hasattr(widget, "rollover"):
-			if 1:	#self._lastrollover <> widget:
-				if self._lastrollover:
-					self._lastrollover.rollover(point, 0)
-				self._lastrollover = widget
-				self._lastrollover.rollover(point, 1)
-		else:
-			if self._lastrollover:
-				self._lastrollover.rollover(point, 0)
-			self._lastrollover = None
-			Wbase.SetCursor("arrow")
 
-	def xxx___select(self, widget):
-		if self._currentwidget == widget:
-			return
-		if self._bindings.has_key("<select>"):
-			callback = self._bindings["<select>"]
-			if callback(widget):
-				return
-		if widget is None:
-			if self._currentwidget is not None:
-				self._currentwidget.select(0)
-		elif type(widget) == InstanceType and widget._selectable:
-			widget.select(1)
-		elif widget == -1 or widget == 1:
-			if len(self._tabchain) <= 1:
-				return
-			temp = self._tabchain[(self._tabchain.index(self._currentwidget) + widget) % len(self._tabchain)]
-			temp.select(1)
-		else:
-			raise TypeError, "Widget is not selectable"
-	
-	def setdefaultbutton(self, newdefaultbutton = None, *keys):
-		if newdefaultbutton == self._defaultbutton:
-			return
-		if self._defaultbutton:
-			self._defaultbutton._setdefault(0)
-		if not newdefaultbutton:
-			self.bind("return", None)
-			self.bind("enter", None)
-			return
-		import Wcontrols
-		if not isinstance(newdefaultbutton, Wcontrols.Button):
-			raise TypeError, "widget is not a button"
-		self._defaultbutton = newdefaultbutton
-		self._defaultbutton._setdefault(1)
-		if not keys:
-			self.bind("return", self._defaultbutton.push)
-			self.bind("enter", self._defaultbutton.push)
-		else:
-			for key in keys:
-				self.bind(key, self._defaultbutton.push)
-	
-	def nextwidget(self):
-		self.xxx___select(1)
-	
-	def previouswidget(self):
-		self.xxx___select(-1)
-	
-	def drawwidgetbounds(self, onoff):
-		self._drawwidgetbounds = onoff
-		self.SetPort()
-		self.GetWindow().InvalWindowRect(self._bounds)
-	
-	def _drawbounds(self):
-		pass
+    windowkind = Windows.documentProc
 
-	def _maketabchain(self):
-		# XXX This has to change, it's no good when we are adding or deleting widgets.
-		# XXX Perhaps we shouldn't keep a "tabchain" at all.
-		self._hasselframes = 0
-		self._collectselectablewidgets(self._widgets)
-		if self._hasselframes and len(self._tabchain) > 1:
-			self._hasselframes = 1
-		else:
-			self._hasselframes = 0
-	
-	def _collectselectablewidgets(self, widgets):
-		import W
-		for w in widgets:
-			if w._selectable:
-				self._tabchain.append(w)
-				if isinstance(w, W.List):
-					self._hasselframes = 1
-			self._collectselectablewidgets(w._widgets)
-	
-	def _calcbounds(self):
-		self._possize = self.wid.GetWindowPort().GetPortBounds()[2:]
-		w, h = self._possize
-		self._bounds = (0, 0, w, h)
-		self.wid.GetWindowContentRgn(scratchRegion)
-		l, t, r, b = GetRgnBounds(scratchRegion)
-		self._globalbounds = l, t, l + w, t + h
-		for w in self._widgets:
-			w._calcbounds()
-	
-	# FrameWork override methods
-	def do_inDrag(self, partcode, window, event):
-		where = event[3]
-		self.wid.GetWindowContentRgn(scratchRegion)
-		was_l, was_t, r, b = GetRgnBounds(scratchRegion)
-		window.DragWindow(where, self.draglimit)
-		self.wid.GetWindowContentRgn(scratchRegion)
-		is_l, is_t, r, b = GetRgnBounds(scratchRegion)
-		self._globalbounds = Qd.OffsetRect(self._globalbounds, 
-					is_l - was_l, is_t - was_t)
-	
-	def do_char(self, char, event):
-		import Wkeys
-		(what, message, when, where, modifiers) = event
-		key = char
-		if Wkeys.keynames.has_key(key):
-			key = Wkeys.keynames[key]
-		if modifiers & Events.shiftKey:
-			key = 'shift' + key
-		if modifiers & Events.cmdKey:
-			key = 'cmd' + key
-		if modifiers & Events.controlKey:
-			key = 'control' + key
-		if self._bindings.has_key("<key>"):
-			callback = self._bindings["<key>"]
-			if Wbase.CallbackCall(callback, 0, char, event):
-				return
-		if self._bindings.has_key(key):
-			callback = self._bindings[key]
-			Wbase.CallbackCall(callback, 0, char, event)
-		elif self._currentwidget is not None:
-			if self._currentwidget._bindings.has_key(key):
-				callback = self._currentwidget._bindings[key]
-				Wbase.CallbackCall(callback, 0, char, event)
-			else:
-				if self._currentwidget._bindings.has_key("<key>"):
-					callback = self._currentwidget._bindings["<key>"]
-					if Wbase.CallbackCall(callback, 0, char, event):
-						return
-				self._currentwidget.key(char, event)
-	
-	def do_contentclick(self, point, modifiers, event):
-		widget = self.findwidget(point)
-		if widget is not None:
-			if self._bindings.has_key("<click>"):
-				callback = self._bindings["<click>"]
-				if Wbase.CallbackCall(callback, 0, point, modifiers):
-					return
-			if widget._bindings.has_key("<click>"):
-				callback = widget._bindings["<click>"]
-				if Wbase.CallbackCall(callback, 0, point, modifiers):
-					return
-			if widget._selectable:
-				widget.select(1, 1)
-			widget.click(point, modifiers)
-	
-	def do_update(self, window, event):
-		Qd.EraseRgn(window.GetWindowPort().visRgn)
-		self.forall_frombottom("draw", window.GetWindowPort().visRgn)
-		if self._drawwidgetbounds:
-			self.forall_frombottom("_drawbounds")
-	
-	def do_activate(self, onoff, event):
-		if not onoff:
-			if self._lastrollover:
-				self._lastrollover.rollover((0, 0), 0)
-				self._lastrollover = None
-		self.SetPort()
-		self.forall("activate", onoff)
-		self.draw()
-	
-	def do_postresize(self, width, height, window):
-		self.GetWindow().InvalWindowRect(self.getgrowrect())
-		self._calcbounds()
-	
-	def do_inGoAway(self, partcode, window, event):
-		where = event[3]
-		closeall = event[4] & Events.optionKey
-		if window.TrackGoAway(where):
-			if not closeall:
-				self.close()
-			else:
-				for window in self.parent._windows.values():
-					rv = window.close()
-					if rv and rv > 0:
-						return
-	
-	# utilities
-	def tempcliprect(self, tempcliprect):
-		tempclip = Qd.NewRgn()
-		Qd.RectRgn(tempclip, tempcliprect)
-		self.tempclip(tempclip)
-		Qd.DisposeRgn(tempclip)
-	
-	def tempclip(self, tempclip):
-		if not hasattr(self, "saveclip"):
-			self.saveclip = []
-		saveclip = Qd.NewRgn()
-		Qd.GetClip(saveclip)
-		self.saveclip.append(saveclip)
-		Qd.SetClip(tempclip)
-	
-	def restoreclip(self):
-		Qd.SetClip(self.saveclip[-1])
-		Qd.DisposeRgn(self.saveclip[-1])
-		del self.saveclip[-1]
-	
-	def getgrowrect(self):
-		l, t, r, b = self.wid.GetWindowPort().GetPortBounds()
-		return (r - 15, b - 15, r, b)
-	
-	def has_key(self, key):
-		return self._widgetsdict.has_key(key)
-	
-	def __getattr__(self, attr):
-		global _successcount, _failcount, _magiccount
-		if self._widgetsdict.has_key(attr):
-			_successcount = _successcount + 1
-			return self._widgetsdict[attr]
-		if self._currentwidget is None or (attr[:7] <> 'domenu_' and 
-				attr[:4] <> 'can_' and attr <> 'insert'):
-			_failcount = _failcount + 1
-			raise AttributeError, attr
-		# special case: if a domenu_xxx, can_xxx or insert method is asked for, 
-		# see if the active widget supports it
-		_magiccount = _magiccount + 1
-		return getattr(self._currentwidget, attr)
+    def __init__(self, possize, title="", minsize=None, maxsize=None,
+                    tabbable=1, show=1, fontsettings=None):
+        import W
+        if fontsettings is None:
+            fontsettings = W.getdefaultfont()
+        self._fontsettings = fontsettings
+        W.SelectableWidget.__init__(self, possize)
+        self._globalbounds = l, t, r, b = self.getwindowbounds(possize, minsize)
+        self._bounds = (0, 0, r - l, b - t)
+        self._tabchain = []
+        self._currentwidget = None
+        self.title = title
+        self._parentwindow = self
+        self._tabbable = tabbable
+        self._defaultbutton = None
+        self._drawwidgetbounds = 0
+        self._show = show
+        self._lastrollover = None
+        self.hasclosebox = 1
+        # XXX the following is not really compatible with the
+        #  new (system >= 7.5) window procs.
+        if minsize:
+            self._hasgrowbox = 1
+            self.windowkind = self.windowkind | 8
+            l, t = minsize
+            if maxsize:
+                r, b = maxsize[0] + 1, maxsize[1] + 1
+            else:
+                r, b = 32000, 32000
+            self.growlimit = (l, t, r, b)
+        else:
+            self._hasgrowbox = 0
+            if (self.windowkind == 0 or self.windowkind >= 8) and self.windowkind < 1000:
+                self.windowkind = self.windowkind | 4
+        FrameWork.Window.__init__(self, W.getapplication())
+
+    def gettitle(self):
+        return self.title
+
+    def settitle(self, title):
+        self.title = title
+        if self.wid:
+            self.wid.SetWTitle(title)
+
+    def getwindowbounds(self, size, minsize = None):
+        return windowbounds(size, minsize)
+
+    def getcurrentwidget(self):
+        return self._currentwidget
+
+    def show(self, onoff):
+        if onoff:
+            self.wid.ShowWindow()
+        else:
+            self.wid.HideWindow()
+
+    def isvisible(self):
+        return self.wid.IsWindowVisible()
+
+    def select(self):
+        self.wid.SelectWindow()
+        # not sure if this is the best place, I need it when
+        # an editor gets selected, and immediately scrolled
+        # to a certain line, waste scroll assumes everything
+        # to be in tact.
+        self.do_rawupdate(self.wid, "DummyEvent")
+
+    def open(self):
+        self.wid = Win.NewCWindow(self._globalbounds, self.title, self._show,
+                self.windowkind, -1, self.hasclosebox, 0)
+        self.SetPort()
+        fontname, fontstyle, fontsize, fontcolor = self._fontsettings
+        fnum = Fm.GetFNum(fontname)
+        if fnum == 0:
+            fnum = Fm.GetFNum("Geneva")
+        Qd.TextFont(fnum)
+        Qd.TextFace(fontstyle)
+        Qd.TextSize(fontsize)
+        if self._bindings.has_key("<open>"):
+            callback = self._bindings["<open>"]
+            callback()
+        for w in self._widgets:
+            w.forall_frombottom("open")
+        self._maketabchain()
+        if self._tabbable:
+            self.bind('tab', self.nextwidget)
+            self.bind('shifttab', self.previouswidget)
+        else:
+            self._hasselframes = 0
+        if self._tabchain:
+            self._tabchain[0].select(1)
+        self.do_postopen()
+
+    def close(self):
+        if not self.wid:
+            return  # we are already closed
+        if self._bindings.has_key("<close>"):
+            callback = self._bindings["<close>"]
+            try:
+                rv = callback()
+            except:
+                print 'error in <close> callback'
+                traceback.print_exc()
+            else:
+                if rv:
+                    return rv
+        #for key in self._widgetsdict.keys():
+        #       self._removewidget(key)
+        self.forall_butself("close")
+        Wbase.SelectableWidget.close(self)
+        self._tabchain = []
+        self._currentwidget = None
+        self.wid.HideWindow()
+        self.do_postclose()
+
+    def domenu_close(self, *args):
+        self.close()
+
+    def getbounds(self):
+        return self._globalbounds
+
+    def setbounds(self, bounds):
+        l, t, r, b = bounds
+        self.move(l, t)
+        self.resize(r-l, b-t)
+
+    def move(self, x, y = None):
+        """absolute move"""
+        if y == None:
+            x, y = x
+        self.wid.MoveWindow(x, y, 0)
+
+    def resize(self, x, y = None):
+        if not self._hasgrowbox:
+            return  # hands off!
+        if y == None:
+            x, y = x
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(self.getgrowrect())
+        self.wid.SizeWindow(x, y, 1)
+        self._calcbounds()
+
+    def test(self, point):
+        return 1
+
+    def draw(self, visRgn = None):
+        if self._hasgrowbox:
+            self.tempcliprect(self.getgrowrect())
+            self.wid.DrawGrowIcon()
+            self.restoreclip()
+
+    def idle(self, *args):
+        self.SetPort()
+        point = Evt.GetMouse()
+        widget = self.findwidget(point, 0)
+        if self._bindings.has_key("<idle>"):
+            callback = self._bindings["<idle>"]
+            if callback():
+                return
+        if self._currentwidget is not None and hasattr(self._currentwidget, "idle"):
+            if self._currentwidget._bindings.has_key("<idle>"):
+                callback = self._currentwidget._bindings["<idle>"]
+                if callback():
+                    return
+            if self._currentwidget.idle():
+                return
+        if widget is not None and hasattr(widget, "rollover"):
+            if 1:   #self._lastrollover <> widget:
+                if self._lastrollover:
+                    self._lastrollover.rollover(point, 0)
+                self._lastrollover = widget
+                self._lastrollover.rollover(point, 1)
+        else:
+            if self._lastrollover:
+                self._lastrollover.rollover(point, 0)
+            self._lastrollover = None
+            Wbase.SetCursor("arrow")
+
+    def xxx___select(self, widget):
+        if self._currentwidget == widget:
+            return
+        if self._bindings.has_key("<select>"):
+            callback = self._bindings["<select>"]
+            if callback(widget):
+                return
+        if widget is None:
+            if self._currentwidget is not None:
+                self._currentwidget.select(0)
+        elif type(widget) == InstanceType and widget._selectable:
+            widget.select(1)
+        elif widget == -1 or widget == 1:
+            if len(self._tabchain) <= 1:
+                return
+            temp = self._tabchain[(self._tabchain.index(self._currentwidget) + widget) % len(self._tabchain)]
+            temp.select(1)
+        else:
+            raise TypeError, "Widget is not selectable"
+
+    def setdefaultbutton(self, newdefaultbutton = None, *keys):
+        if newdefaultbutton == self._defaultbutton:
+            return
+        if self._defaultbutton:
+            self._defaultbutton._setdefault(0)
+        if not newdefaultbutton:
+            self.bind("return", None)
+            self.bind("enter", None)
+            return
+        import Wcontrols
+        if not isinstance(newdefaultbutton, Wcontrols.Button):
+            raise TypeError, "widget is not a button"
+        self._defaultbutton = newdefaultbutton
+        self._defaultbutton._setdefault(1)
+        if not keys:
+            self.bind("return", self._defaultbutton.push)
+            self.bind("enter", self._defaultbutton.push)
+        else:
+            for key in keys:
+                self.bind(key, self._defaultbutton.push)
+
+    def nextwidget(self):
+        self.xxx___select(1)
+
+    def previouswidget(self):
+        self.xxx___select(-1)
+
+    def drawwidgetbounds(self, onoff):
+        self._drawwidgetbounds = onoff
+        self.SetPort()
+        self.GetWindow().InvalWindowRect(self._bounds)
+
+    def _drawbounds(self):
+        pass
+
+    def _maketabchain(self):
+        # XXX This has to change, it's no good when we are adding or deleting widgets.
+        # XXX Perhaps we shouldn't keep a "tabchain" at all.
+        self._hasselframes = 0
+        self._collectselectablewidgets(self._widgets)
+        if self._hasselframes and len(self._tabchain) > 1:
+            self._hasselframes = 1
+        else:
+            self._hasselframes = 0
+
+    def _collectselectablewidgets(self, widgets):
+        import W
+        for w in widgets:
+            if w._selectable:
+                self._tabchain.append(w)
+                if isinstance(w, W.List):
+                    self._hasselframes = 1
+            self._collectselectablewidgets(w._widgets)
+
+    def _calcbounds(self):
+        self._possize = self.wid.GetWindowPort().GetPortBounds()[2:]
+        w, h = self._possize
+        self._bounds = (0, 0, w, h)
+        self.wid.GetWindowContentRgn(scratchRegion)
+        l, t, r, b = GetRgnBounds(scratchRegion)
+        self._globalbounds = l, t, l + w, t + h
+        for w in self._widgets:
+            w._calcbounds()
+
+    # FrameWork override methods
+    def do_inDrag(self, partcode, window, event):
+        where = event[3]
+        self.wid.GetWindowContentRgn(scratchRegion)
+        was_l, was_t, r, b = GetRgnBounds(scratchRegion)
+        window.DragWindow(where, self.draglimit)
+        self.wid.GetWindowContentRgn(scratchRegion)
+        is_l, is_t, r, b = GetRgnBounds(scratchRegion)
+        self._globalbounds = Qd.OffsetRect(self._globalbounds,
+                                is_l - was_l, is_t - was_t)
+
+    def do_char(self, char, event):
+        import Wkeys
+        (what, message, when, where, modifiers) = event
+        key = char
+        if Wkeys.keynames.has_key(key):
+            key = Wkeys.keynames[key]
+        if modifiers & Events.shiftKey:
+            key = 'shift' + key
+        if modifiers & Events.cmdKey:
+            key = 'cmd' + key
+        if modifiers & Events.controlKey:
+            key = 'control' + key
+        if self._bindings.has_key("<key>"):
+            callback = self._bindings["<key>"]
+            if Wbase.CallbackCall(callback, 0, char, event):
+                return
+        if self._bindings.has_key(key):
+            callback = self._bindings[key]
+            Wbase.CallbackCall(callback, 0, char, event)
+        elif self._currentwidget is not None:
+            if self._currentwidget._bindings.has_key(key):
+                callback = self._currentwidget._bindings[key]
+                Wbase.CallbackCall(callback, 0, char, event)
+            else:
+                if self._currentwidget._bindings.has_key("<key>"):
+                    callback = self._currentwidget._bindings["<key>"]
+                    if Wbase.CallbackCall(callback, 0, char, event):
+                        return
+                self._currentwidget.key(char, event)
+
+    def do_contentclick(self, point, modifiers, event):
+        widget = self.findwidget(point)
+        if widget is not None:
+            if self._bindings.has_key("<click>"):
+                callback = self._bindings["<click>"]
+                if Wbase.CallbackCall(callback, 0, point, modifiers):
+                    return
+            if widget._bindings.has_key("<click>"):
+                callback = widget._bindings["<click>"]
+                if Wbase.CallbackCall(callback, 0, point, modifiers):
+                    return
+            if widget._selectable:
+                widget.select(1, 1)
+            widget.click(point, modifiers)
+
+    def do_update(self, window, event):
+        Qd.EraseRgn(window.GetWindowPort().visRgn)
+        self.forall_frombottom("draw", window.GetWindowPort().visRgn)
+        if self._drawwidgetbounds:
+            self.forall_frombottom("_drawbounds")
+
+    def do_activate(self, onoff, event):
+        if not onoff:
+            if self._lastrollover:
+                self._lastrollover.rollover((0, 0), 0)
+                self._lastrollover = None
+        self.SetPort()
+        self.forall("activate", onoff)
+        self.draw()
+
+    def do_postresize(self, width, height, window):
+        self.GetWindow().InvalWindowRect(self.getgrowrect())
+        self._calcbounds()
+
+    def do_inGoAway(self, partcode, window, event):
+        where = event[3]
+        closeall = event[4] & Events.optionKey
+        if window.TrackGoAway(where):
+            if not closeall:
+                self.close()
+            else:
+                for window in self.parent._windows.values():
+                    rv = window.close()
+                    if rv and rv > 0:
+                        return
+
+    # utilities
+    def tempcliprect(self, tempcliprect):
+        tempclip = Qd.NewRgn()
+        Qd.RectRgn(tempclip, tempcliprect)
+        self.tempclip(tempclip)
+        Qd.DisposeRgn(tempclip)
+
+    def tempclip(self, tempclip):
+        if not hasattr(self, "saveclip"):
+            self.saveclip = []
+        saveclip = Qd.NewRgn()
+        Qd.GetClip(saveclip)
+        self.saveclip.append(saveclip)
+        Qd.SetClip(tempclip)
+
+    def restoreclip(self):
+        Qd.SetClip(self.saveclip[-1])
+        Qd.DisposeRgn(self.saveclip[-1])
+        del self.saveclip[-1]
+
+    def getgrowrect(self):
+        l, t, r, b = self.wid.GetWindowPort().GetPortBounds()
+        return (r - 15, b - 15, r, b)
+
+    def has_key(self, key):
+        return self._widgetsdict.has_key(key)
+
+    def __getattr__(self, attr):
+        global _successcount, _failcount, _magiccount
+        if self._widgetsdict.has_key(attr):
+            _successcount = _successcount + 1
+            return self._widgetsdict[attr]
+        if self._currentwidget is None or (attr[:7] <> 'domenu_' and
+                        attr[:4] <> 'can_' and attr <> 'insert'):
+            _failcount = _failcount + 1
+            raise AttributeError, attr
+        # special case: if a domenu_xxx, can_xxx or insert method is asked for,
+        # see if the active widget supports it
+        _magiccount = _magiccount + 1
+        return getattr(self._currentwidget, attr)
 
 _successcount = 0
 _failcount = 0
 _magiccount = 0
 
 class Dialog(Window):
-	
-	windowkind = Windows.movableDBoxProc
-	
-	# this __init__ seems redundant, but it's not: it has less args
-	def __init__(self, possize, title = ""):
-		Window.__init__(self, possize, title)
-	
-	def can_close(self, *args):
-		return 0
-	
-	def getwindowbounds(self, size, minsize = None):
-		screenbounds = sl, st, sr, sb = Qd.GetQDGlobalsScreenBits().bounds
-		w, h = size
-		l = sl + (sr - sl - w) / 2
-		t = st + (sb - st - h) / 3
-		return l, t, l + w, t + h
+
+    windowkind = Windows.movableDBoxProc
+
+    # this __init__ seems redundant, but it's not: it has less args
+    def __init__(self, possize, title = ""):
+        Window.__init__(self, possize, title)
+
+    def can_close(self, *args):
+        return 0
+
+    def getwindowbounds(self, size, minsize = None):
+        screenbounds = sl, st, sr, sb = Qd.GetQDGlobalsScreenBits().bounds
+        w, h = size
+        l = sl + (sr - sl - w) / 2
+        t = st + (sb - st - h) / 3
+        return l, t, l + w, t + h
 
 
 class ModalDialog(Dialog):
-	
-	def __init__(self, possize, title = ""):
-		Dialog.__init__(self, possize, title)
-		if title:
-			self.windowkind = Windows.movableDBoxProc
-		else:
-			self.windowkind = Windows.dBoxProc
-	
-	def open(self):
-		import W
-		Dialog.open(self)
-		self.app = W.getapplication()
-		self.done = 0
-		Menu.HiliteMenu(0)
-		app = self.parent
-		app.enablemenubar(0)
-		try:
-			self.mainloop()
-		finally:
-			app.enablemenubar(1)
-	
-	def close(self):
-		if not self.wid:
-			return	# we are already closed
-		self.done = 1
-		del self.app
-		Dialog.close(self)
-	
-	def mainloop(self):
-		if hasattr(MacOS, 'EnableAppswitch'):
-			saveyield = MacOS.EnableAppswitch(-1)
-		while not self.done:
-			#self.do1event()
-			self.do1event(	Events.keyDownMask + 
-						Events.autoKeyMask + 
-						Events.activMask + 
-						Events.updateMask + 
-						Events.mDownMask +
-						Events.mUpMask, 
-						10)
-		if hasattr(MacOS, 'EnableAppswitch'):
-			MacOS.EnableAppswitch(saveyield)
-	
-	def do1event(self, mask = Events.everyEvent, wait = 0):
-		ok, event = self.app.getevent(mask, wait)
-		if Dlg.IsDialogEvent(event):
-			if self.app.do_dialogevent(event):
-				return
-		if ok:
-			self.dispatch(event)
-		else:
-			self.app.idle(event)
-	
-	def do_keyDown(self, event):
-		self.do_key(event)
-	
-	def do_autoKey(self, event):
-		if not event[-1] & Events.cmdKey:
-			self.do_key(event)
-	
-	def do_key(self, event):
-		(what, message, when, where, modifiers) = event
-		#w = Win.FrontWindow()
-		#if w <> self.wid:
-		#	return
-		c = chr(message & Events.charCodeMask)
-		if modifiers & Events.cmdKey:
-			self.app.checkmenus(self)
-			result = Menu.MenuKey(ord(c))
-			id = (result>>16) & 0xffff	# Hi word
-			item = result & 0xffff		# Lo word
-			if id:
-				self.app.do_rawmenu(id, item, None, event)
-				return
-		self.do_char(c, event)
-	
-	def do_mouseDown(self, event):
-		(what, message, when, where, modifiers) = event
-		partcode, wid = Win.FindWindow(where)
-		#
-		# Find the correct name.
-		#
-		if FrameWork.partname.has_key(partcode):
-			name = "do_" + FrameWork.partname[partcode]
-		else:
-			name = "do_%d" % partcode
-		
-		if name == "do_inDesk":
-			if hasattr(MacOS, "HandleEvent"):
-				MacOS.HandleEvent(event)
-			else:
-				print 'Unexpected inDesk event:', event
-			return
-		if wid == self.wid:
-			try:
-				handler = getattr(self, name)
-			except AttributeError:
-				handler = self.app.do_unknownpartcode
-		else:
-			#MacOS.HandleEvent(event)
-			if name == 'do_inMenuBar':
-				handler = getattr(self.parent, name)
-			else:
-				return		
-		handler(partcode, wid, event)
-	
-	def dispatch(self, event):
-		(what, message, when, where, modifiers) = event
-		if FrameWork.eventname.has_key(what):
-			name = "do_" + FrameWork.eventname[what]
-		else:
-			name = "do_%d" % what
-		try:
-			handler = getattr(self, name)
-		except AttributeError:
-			try:
-				handler = getattr(self.app, name)
-			except AttributeError:
-				handler = self.app.do_unknownevent
-		handler(event)
-	
+
+    def __init__(self, possize, title = ""):
+        Dialog.__init__(self, possize, title)
+        if title:
+            self.windowkind = Windows.movableDBoxProc
+        else:
+            self.windowkind = Windows.dBoxProc
+
+    def open(self):
+        import W
+        Dialog.open(self)
+        self.app = W.getapplication()
+        self.done = 0
+        Menu.HiliteMenu(0)
+        app = self.parent
+        app.enablemenubar(0)
+        try:
+            self.mainloop()
+        finally:
+            app.enablemenubar(1)
+
+    def close(self):
+        if not self.wid:
+            return  # we are already closed
+        self.done = 1
+        del self.app
+        Dialog.close(self)
+
+    def mainloop(self):
+        if hasattr(MacOS, 'EnableAppswitch'):
+            saveyield = MacOS.EnableAppswitch(-1)
+        while not self.done:
+            #self.do1event()
+            self.do1event(  Events.keyDownMask +
+                                    Events.autoKeyMask +
+                                    Events.activMask +
+                                    Events.updateMask +
+                                    Events.mDownMask +
+                                    Events.mUpMask,
+                                    10)
+        if hasattr(MacOS, 'EnableAppswitch'):
+            MacOS.EnableAppswitch(saveyield)
+
+    def do1event(self, mask = Events.everyEvent, wait = 0):
+        ok, event = self.app.getevent(mask, wait)
+        if Dlg.IsDialogEvent(event):
+            if self.app.do_dialogevent(event):
+                return
+        if ok:
+            self.dispatch(event)
+        else:
+            self.app.idle(event)
+
+    def do_keyDown(self, event):
+        self.do_key(event)
+
+    def do_autoKey(self, event):
+        if not event[-1] & Events.cmdKey:
+            self.do_key(event)
+
+    def do_key(self, event):
+        (what, message, when, where, modifiers) = event
+        #w = Win.FrontWindow()
+        #if w <> self.wid:
+        #       return
+        c = chr(message & Events.charCodeMask)
+        if modifiers & Events.cmdKey:
+            self.app.checkmenus(self)
+            result = Menu.MenuKey(ord(c))
+            id = (result>>16) & 0xffff      # Hi word
+            item = result & 0xffff          # Lo word
+            if id:
+                self.app.do_rawmenu(id, item, None, event)
+                return
+        self.do_char(c, event)
+
+    def do_mouseDown(self, event):
+        (what, message, when, where, modifiers) = event
+        partcode, wid = Win.FindWindow(where)
+        #
+        # Find the correct name.
+        #
+        if FrameWork.partname.has_key(partcode):
+            name = "do_" + FrameWork.partname[partcode]
+        else:
+            name = "do_%d" % partcode
+
+        if name == "do_inDesk":
+            if hasattr(MacOS, "HandleEvent"):
+                MacOS.HandleEvent(event)
+            else:
+                print 'Unexpected inDesk event:', event
+            return
+        if wid == self.wid:
+            try:
+                handler = getattr(self, name)
+            except AttributeError:
+                handler = self.app.do_unknownpartcode
+        else:
+            #MacOS.HandleEvent(event)
+            if name == 'do_inMenuBar':
+                handler = getattr(self.parent, name)
+            else:
+                return
+        handler(partcode, wid, event)
+
+    def dispatch(self, event):
+        (what, message, when, where, modifiers) = event
+        if FrameWork.eventname.has_key(what):
+            name = "do_" + FrameWork.eventname[what]
+        else:
+            name = "do_%d" % what
+        try:
+            handler = getattr(self, name)
+        except AttributeError:
+            try:
+                handler = getattr(self.app, name)
+            except AttributeError:
+                handler = self.app.do_unknownevent
+        handler(event)
+
 
 def FrontWindowInsert(stuff):
-	if not stuff:
-		return
-	if type(stuff) <> StringType:
-		raise TypeError, 'string expected'
-	import W
-	app = W.getapplication()
-	wid = MyFrontWindow()
-	if wid and app._windows.has_key(wid):
-		window = app._windows[wid]
-		if hasattr(window, "insert"):
-			try:
-				window.insert(stuff)
-				return
-			except:
-				pass
-	import EasyDialogs
-	if EasyDialogs.AskYesNoCancel(
-			"Can't find window or widget to insert text into; copy to clipboard instead?", 
-			1) == 1:
-		from Carbon import Scrap
-		if hasattr(Scrap, 'PutScrap'):
-			Scrap.ZeroScrap()
-			Scrap.PutScrap('TEXT', stuff)
-		else:
-			Scrap.ClearCurrentScrap()
-			sc = Scrap.GetCurrentScrap()
-			sc.PutScrapFlavor('TEXT', 0, stuff)
+    if not stuff:
+        return
+    if type(stuff) <> StringType:
+        raise TypeError, 'string expected'
+    import W
+    app = W.getapplication()
+    wid = MyFrontWindow()
+    if wid and app._windows.has_key(wid):
+        window = app._windows[wid]
+        if hasattr(window, "insert"):
+            try:
+                window.insert(stuff)
+                return
+            except:
+                pass
+    import EasyDialogs
+    if EasyDialogs.AskYesNoCancel(
+                    "Can't find window or widget to insert text into; copy to clipboard instead?",
+                    1) == 1:
+        from Carbon import Scrap
+        if hasattr(Scrap, 'PutScrap'):
+            Scrap.ZeroScrap()
+            Scrap.PutScrap('TEXT', stuff)
+        else:
+            Scrap.ClearCurrentScrap()
+            sc = Scrap.GetCurrentScrap()
+            sc.PutScrapFlavor('TEXT', 0, stuff)
 
 
-# not quite based on the same function in FrameWork	
+# not quite based on the same function in FrameWork
 _windowcounter = 0
 
 def getnextwindowpos():
-	global _windowcounter
-	rows = 8
-	l = 4 * (rows + 1 - (_windowcounter % rows) + _windowcounter / rows)
-	t = 44 + 20 * (_windowcounter % rows)
-	_windowcounter = _windowcounter + 1
-	return l, t
+    global _windowcounter
+    rows = 8
+    l = 4 * (rows + 1 - (_windowcounter % rows) + _windowcounter / rows)
+    t = 44 + 20 * (_windowcounter % rows)
+    _windowcounter = _windowcounter + 1
+    return l, t
 
 def windowbounds(preferredsize, minsize=None):
-	"Return sensible window bounds"
-	
-	global _windowcounter
-	if len(preferredsize) == 4:
-		bounds = l, t, r, b = preferredsize
-		desktopRgn = Win.GetGrayRgn()
-		tempRgn = Qd.NewRgn()
-		Qd.RectRgn(tempRgn, bounds)
-		union = Qd.UnionRgn(tempRgn, desktopRgn, tempRgn)
-		equal = Qd.EqualRgn(tempRgn, desktopRgn)
-		Qd.DisposeRgn(tempRgn)
-		if equal:
-			return bounds
-		else:
-			preferredsize = r - l, b - t
-	if not minsize:
-		minsize = preferredsize
-	minwidth, minheight = minsize
-	width, height = preferredsize
-	
-	sl, st, sr, sb = screenbounds = Qd.InsetRect(Qd.GetQDGlobalsScreenBits().bounds, 4, 4)
-	l, t = getnextwindowpos()
-	if (l + width) > sr:
-		_windowcounter = 0
-		l, t = getnextwindowpos()
-	r = l + width
-	b = t + height
-	if (t + height) > sb:
-		b = sb
-		if (b - t) < minheight:
-			b = t + minheight
-	return l, t, r, b
+    "Return sensible window bounds"
+
+    global _windowcounter
+    if len(preferredsize) == 4:
+        bounds = l, t, r, b = preferredsize
+        desktopRgn = Win.GetGrayRgn()
+        tempRgn = Qd.NewRgn()
+        Qd.RectRgn(tempRgn, bounds)
+        union = Qd.UnionRgn(tempRgn, desktopRgn, tempRgn)
+        equal = Qd.EqualRgn(tempRgn, desktopRgn)
+        Qd.DisposeRgn(tempRgn)
+        if equal:
+            return bounds
+        else:
+            preferredsize = r - l, b - t
+    if not minsize:
+        minsize = preferredsize
+    minwidth, minheight = minsize
+    width, height = preferredsize
+
+    sl, st, sr, sb = screenbounds = Qd.InsetRect(Qd.GetQDGlobalsScreenBits().bounds, 4, 4)
+    l, t = getnextwindowpos()
+    if (l + width) > sr:
+        _windowcounter = 0
+        l, t = getnextwindowpos()
+    r = l + width
+    b = t + height
+    if (t + height) > sb:
+        b = sb
+        if (b - t) < minheight:
+            b = t + minheight
+    return l, t, r, b
 
 scratchRegion = Qd.NewRgn()
 
 # util -- move somewhere convenient???
 def GetRgnBounds(the_Rgn):
-	(t, l, b, r) = struct.unpack("hhhh", the_Rgn.data[2:10])
-	return (l, t, r, b)
+    (t, l, b, r) = struct.unpack("hhhh", the_Rgn.data[2:10])
+    return (l, t, r, b)
diff --git a/Mac/Tools/macfreeze/directives.py b/Mac/Tools/macfreeze/directives.py
index 3ef9661..7f6142e 100644
--- a/Mac/Tools/macfreeze/directives.py
+++ b/Mac/Tools/macfreeze/directives.py
@@ -17,27 +17,26 @@
 REPROG=re.compile(DIRECTIVE_RE)
 
 def findfreezedirectives(program):
-	extra_modules = []
-	exclude_modules = []
-	optional_modules = []
-	extra_path = []
-	progdir, filename = os.path.split(program)
-	fp = open(program)
-	for line in fp.readlines():
-		match = REPROG.match(line)
-		if match:
-			directive = match.group(1)
-			argument = match.group(2)
-			if directive == 'include':
-				extra_modules.append(argument)
-			elif directive == 'exclude':
-				exclude_modules.append(argument)
-			elif directive == 'optional':
-				optional_modules.append(argument)
-			elif directive == 'path':
-				argument = os.path.join(progdir, argument)
-				extra_path.append(argument)
-			else:
-				print '** Unknown directive', line
-	return extra_modules, exclude_modules, optional_modules, extra_path
-	
+    extra_modules = []
+    exclude_modules = []
+    optional_modules = []
+    extra_path = []
+    progdir, filename = os.path.split(program)
+    fp = open(program)
+    for line in fp.readlines():
+        match = REPROG.match(line)
+        if match:
+            directive = match.group(1)
+            argument = match.group(2)
+            if directive == 'include':
+                extra_modules.append(argument)
+            elif directive == 'exclude':
+                exclude_modules.append(argument)
+            elif directive == 'optional':
+                optional_modules.append(argument)
+            elif directive == 'path':
+                argument = os.path.join(progdir, argument)
+                extra_path.append(argument)
+            else:
+                print '** Unknown directive', line
+    return extra_modules, exclude_modules, optional_modules, extra_path
diff --git a/Mac/Tools/macfreeze/macfreeze.py b/Mac/Tools/macfreeze/macfreeze.py
index 8a2ca76..b2cf72e 100644
--- a/Mac/Tools/macfreeze/macfreeze.py
+++ b/Mac/Tools/macfreeze/macfreeze.py
@@ -26,50 +26,50 @@
 #
 
 def main():
-	if len(sys.argv) < 2:
-		gentype, program, output, debug = macfreezegui.dialog()
-	elif len(sys.argv) == 2:
-		gentype, program, output, debug = macfreezegui.dialog(sys.argv[1])
-	else:
-		EasyDialog.Message(
-		  "Please pass a single script. Additional modules can be specified with directives")
-		sys.exit(0)
-	mustwait = process(gentype, program, output, debug=debug)
-	if mustwait:
-		sys.exit(1)
+    if len(sys.argv) < 2:
+        gentype, program, output, debug = macfreezegui.dialog()
+    elif len(sys.argv) == 2:
+        gentype, program, output, debug = macfreezegui.dialog(sys.argv[1])
+    else:
+        EasyDialog.Message(
+          "Please pass a single script. Additional modules can be specified with directives")
+        sys.exit(0)
+    mustwait = process(gentype, program, output, debug=debug)
+    if mustwait:
+        sys.exit(1)
 
 def process(gentype, program, output, modules=None, module_files=None, debug=0, with_ifdef=0):
-	if modules is None:
-		modules = []
-	if module_files is None:
-		module_files = []
-	module_dict, missing = macmodulefinder.process(program, modules, module_files, debug)
-	if missing:
-		missing.sort()
-		print '** Missing modules:', string.join(missing, ' ')
-		sys.exit(1)
-	#
-	# And generate
-	#
-	if gentype == 'info':
-		import macgen_info
-		macgen_info.generate(output, module_dict)
-		return 1		# So the user can inspect it
-	elif gentype == 'source':
-		import macgen_src
-		warnings = macgen_src.generate(output, module_dict, debug, with_ifdef)
-		return warnings
-	elif gentype == 'resource':
-		import macgen_rsrc
-		macgen_rsrc.generate(output, module_dict, debug)
-		warnings = macgen_rsrc.warnings(module_dict)
-		return warnings
-	elif gentype == 'applet':
-		import macgen_bin
-		architecture = 'fat' # user should choose
-		macgen_bin.generate(program, output, module_dict, architecture, debug)
-	else:
-		raise 'unknown gentype', gentype
+    if modules is None:
+        modules = []
+    if module_files is None:
+        module_files = []
+    module_dict, missing = macmodulefinder.process(program, modules, module_files, debug)
+    if missing:
+        missing.sort()
+        print '** Missing modules:', string.join(missing, ' ')
+        sys.exit(1)
+    #
+    # And generate
+    #
+    if gentype == 'info':
+        import macgen_info
+        macgen_info.generate(output, module_dict)
+        return 1                # So the user can inspect it
+    elif gentype == 'source':
+        import macgen_src
+        warnings = macgen_src.generate(output, module_dict, debug, with_ifdef)
+        return warnings
+    elif gentype == 'resource':
+        import macgen_rsrc
+        macgen_rsrc.generate(output, module_dict, debug)
+        warnings = macgen_rsrc.warnings(module_dict)
+        return warnings
+    elif gentype == 'applet':
+        import macgen_bin
+        architecture = 'fat' # user should choose
+        macgen_bin.generate(program, output, module_dict, architecture, debug)
+    else:
+        raise 'unknown gentype', gentype
 
 if __name__ == '__main__':
-	main()
+    main()
diff --git a/Mac/Tools/macfreeze/macfreezegui.py b/Mac/Tools/macfreeze/macfreezegui.py
index 5dd3435..41d0ec8 100644
--- a/Mac/Tools/macfreeze/macfreezegui.py
+++ b/Mac/Tools/macfreeze/macfreezegui.py
@@ -30,121 +30,121 @@
 ITEM_GENINFO=20
 
 RADIO_GROUPING={
-	ITEM_GENSOURCE: ITEM_GENSOURCE_ITEMS,
-	ITEM_GENRESOURCE: ITEM_GENRESOURCE_ITEMS,
-	ITEM_GENAPPLET: ITEM_GENAPPLET_ITEMS,
-	ITEM_GENINFO: ()
+        ITEM_GENSOURCE: ITEM_GENSOURCE_ITEMS,
+        ITEM_GENRESOURCE: ITEM_GENRESOURCE_ITEMS,
+        ITEM_GENAPPLET: ITEM_GENAPPLET_ITEMS,
+        ITEM_GENINFO: ()
 }
 
 def dialog(script=None):
 
-	# Invent the various names
-	if not script:
-		fss, ok = macfs.PromptGetFile("Script?", "TEXT")
-		if not ok:
-			sys.exit(0)
-		script = fss.as_pathname()
-	basename, ext = os.path.splitext(script)
-	if ext:
-		appletname = basename
-		rsrcname = basename + 'modules.rsrc'
-	else:
-		appletname = script + '.applet'
-		rsrcname = script + 'modules.rsrc'
-	dirname, basebase = os.path.split(basename)
-	dirname = os.path.join(dirname, 'build.'+basebase)
-	
-	# Get the dialog, possibly opening the resource file (if needed)
-	macresource.need('DLOG', ID_MAINDIALOG, 'macfreeze.rsrc')
-	d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
-	if d == None:
-		EasyDialogs.Message("Dialog resource not found or faulty")
-		sys.exit(1)
-	
-	# Fill the dialog
-	d.SetDialogDefaultItem(ITEM_OK)
-	d.SetDialogCancelItem(ITEM_CANCEL)
-	
-	_dialogsetfile(d, ITEM_SCRIPTNAME, script)
-	_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
-	_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
-	_dialogsetfile(d, ITEM_APPLETNAME, appletname)
+    # Invent the various names
+    if not script:
+        fss, ok = macfs.PromptGetFile("Script?", "TEXT")
+        if not ok:
+            sys.exit(0)
+        script = fss.as_pathname()
+    basename, ext = os.path.splitext(script)
+    if ext:
+        appletname = basename
+        rsrcname = basename + 'modules.rsrc'
+    else:
+        appletname = script + '.applet'
+        rsrcname = script + 'modules.rsrc'
+    dirname, basebase = os.path.split(basename)
+    dirname = os.path.join(dirname, 'build.'+basebase)
 
-	gentype = ITEM_GENSOURCE
-	_dialogradiogroup(d, ITEM_GENSOURCE)
+    # Get the dialog, possibly opening the resource file (if needed)
+    macresource.need('DLOG', ID_MAINDIALOG, 'macfreeze.rsrc')
+    d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
+    if d == None:
+        EasyDialogs.Message("Dialog resource not found or faulty")
+        sys.exit(1)
 
-	# Interact
-	d.GetDialogWindow().SetWTitle("Standalone application creation options")
-	d.GetDialogWindow().ShowWindow()
-	d.DrawDialog()
-	while 1:
-		item = Dlg.ModalDialog(None)
-		if item == ITEM_OK:
-			break
-		elif item == ITEM_CANCEL:
-			sys.exit(0)
-		elif item in RADIO_GROUPING.keys():
-			gentype = item
-			_dialogradiogroup(d, item)
-		elif item == ITEM_SCRIPTBROWSE:
-			fss, ok = macfs.PromptGetFile("Script?")
-			if ok:
-				script = fss.as_pathname()
-				_dialogsetfile(d, ITEM_SCRIPTNAME, script)
-		elif item == ITEM_SOURCEDIRBROWSE:
-			fss, ok = macfs.StandardPutFile("Output folder name", os.path.split(dirname)[1])
-			if ok:
-				dirname = fss.as_pathname()
-				_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
-		elif item == ITEM_RESOURCEBROWSE:
-			fss, ok = macfs.StandardPutFile("Resource output file", os.path.split(rsrcname)[1])
-			if ok:
-				rsrcname = fss.as_pathname()
-				_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
-		elif item == ITEM_APPLETBROWSE:
-			fss, ok = macfs.StandardPutFile("Applet output file", os.path.split(appletname)[1])
-			if ok:
-				appletname = fss.as_pathname()
-				_dialogsetfile(d, ITEM_APPLETNAME, appletname)
-		else:
-			pass
-	tp, h, rect = d.GetDialogItem(ITEM_DEBUG)
-	debug = Dlg.GetDialogItemText(h)
-	try:
-		debug = string.atoi(string.strip(debug))
-	except ValueError:
-		EasyDialogs.Message("Illegal debug value %r, set to zero."%(debug,))
-		debug = 0
-	if gentype == ITEM_GENSOURCE:
-		return 'source', script, dirname, debug
-	elif gentype == ITEM_GENRESOURCE:
-		return 'resource', script, rsrcname, debug
-	elif gentype == ITEM_GENAPPLET:
-		return 'applet', script, appletname, debug
-	elif gentype == ITEM_GENINFO:
-		return 'info', script, '', debug
-	raise 'Error in gentype', gentype
+    # Fill the dialog
+    d.SetDialogDefaultItem(ITEM_OK)
+    d.SetDialogCancelItem(ITEM_CANCEL)
+
+    _dialogsetfile(d, ITEM_SCRIPTNAME, script)
+    _dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
+    _dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
+    _dialogsetfile(d, ITEM_APPLETNAME, appletname)
+
+    gentype = ITEM_GENSOURCE
+    _dialogradiogroup(d, ITEM_GENSOURCE)
+
+    # Interact
+    d.GetDialogWindow().SetWTitle("Standalone application creation options")
+    d.GetDialogWindow().ShowWindow()
+    d.DrawDialog()
+    while 1:
+        item = Dlg.ModalDialog(None)
+        if item == ITEM_OK:
+            break
+        elif item == ITEM_CANCEL:
+            sys.exit(0)
+        elif item in RADIO_GROUPING.keys():
+            gentype = item
+            _dialogradiogroup(d, item)
+        elif item == ITEM_SCRIPTBROWSE:
+            fss, ok = macfs.PromptGetFile("Script?")
+            if ok:
+                script = fss.as_pathname()
+                _dialogsetfile(d, ITEM_SCRIPTNAME, script)
+        elif item == ITEM_SOURCEDIRBROWSE:
+            fss, ok = macfs.StandardPutFile("Output folder name", os.path.split(dirname)[1])
+            if ok:
+                dirname = fss.as_pathname()
+                _dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
+        elif item == ITEM_RESOURCEBROWSE:
+            fss, ok = macfs.StandardPutFile("Resource output file", os.path.split(rsrcname)[1])
+            if ok:
+                rsrcname = fss.as_pathname()
+                _dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
+        elif item == ITEM_APPLETBROWSE:
+            fss, ok = macfs.StandardPutFile("Applet output file", os.path.split(appletname)[1])
+            if ok:
+                appletname = fss.as_pathname()
+                _dialogsetfile(d, ITEM_APPLETNAME, appletname)
+        else:
+            pass
+    tp, h, rect = d.GetDialogItem(ITEM_DEBUG)
+    debug = Dlg.GetDialogItemText(h)
+    try:
+        debug = string.atoi(string.strip(debug))
+    except ValueError:
+        EasyDialogs.Message("Illegal debug value %r, set to zero."%(debug,))
+        debug = 0
+    if gentype == ITEM_GENSOURCE:
+        return 'source', script, dirname, debug
+    elif gentype == ITEM_GENRESOURCE:
+        return 'resource', script, rsrcname, debug
+    elif gentype == ITEM_GENAPPLET:
+        return 'applet', script, appletname, debug
+    elif gentype == ITEM_GENINFO:
+        return 'info', script, '', debug
+    raise 'Error in gentype', gentype
 
 def _dialogradiogroup(d, item):
-	for k in RADIO_GROUPING.keys():
-		subitems = RADIO_GROUPING[k]
-		tp, h, rect = d.GetDialogItem(k)
-		if k == item:
-			h.as_Control().SetControlValue(1)
-			for i2 in subitems:
-				d.ShowDialogItem(i2)
-		else:
-			h.as_Control().SetControlValue(0)
-			for i2 in subitems:
-				d.HideDialogItem(i2)
+    for k in RADIO_GROUPING.keys():
+        subitems = RADIO_GROUPING[k]
+        tp, h, rect = d.GetDialogItem(k)
+        if k == item:
+            h.as_Control().SetControlValue(1)
+            for i2 in subitems:
+                d.ShowDialogItem(i2)
+        else:
+            h.as_Control().SetControlValue(0)
+            for i2 in subitems:
+                d.HideDialogItem(i2)
 
 def _dialogsetfile(d, item, file):
-	if len(file) > 32:
-		file = '\311:' + os.path.split(file)[1]
-	tp, h, rect = d.GetDialogItem(item)
-	Dlg.SetDialogItemText(h, file)
-			
+    if len(file) > 32:
+        file = '\311:' + os.path.split(file)[1]
+    tp, h, rect = d.GetDialogItem(item)
+    Dlg.SetDialogItemText(h, file)
+
 if __name__ == '__main__':
-	type, script, file, debug = dialog()
-	print type, script, file, 'debug=%d'%debug
-	sys.exit(1)
+    type, script, file, debug = dialog()
+    print type, script, file, 'debug=%d'%debug
+    sys.exit(1)
diff --git a/Mac/Tools/macfreeze/macgen_bin.py b/Mac/Tools/macfreeze/macgen_bin.py
index 8735e17..bfcdc8b 100644
--- a/Mac/Tools/macfreeze/macgen_bin.py
+++ b/Mac/Tools/macfreeze/macgen_bin.py
@@ -14,208 +14,208 @@
 
 
 def generate(input, output, module_dict=None, architecture='fat', debug=0):
-	# try to remove old file
-	try:
-		os.remove(output)
-	except:
-		pass
-	
-	if module_dict is None:
-		import macmodulefinder
-		print "Searching for modules..."
-		module_dict, missing = macmodulefinder.process(input, [], [], 1)
-		if missing:
-			import EasyDialogs
-			missing.sort()
-			answer = EasyDialogs.AskYesNoCancel("Some modules could not be found; continue anyway?\n(%s)" 
-					% string.join(missing, ", "))
-			if answer <> 1:
-				sys.exit(0)
-	
-	applettemplatepath = buildtools.findtemplate()
-	corepath = findpythoncore()
-	
-	dynamicmodules, dynamicfiles, extraresfiles = findfragments(module_dict, architecture)
-	
-	print 'Adding "__main__"'
-	buildtools.process(applettemplatepath, input, output, 0)
-	
-	outputref = Res.FSpOpenResFile(output, 3)
-	try:
-		Res.UseResFile(outputref)
-		
-		print "Adding Python modules"
-		addpythonmodules(module_dict)
-		
-		print "Adding PythonCore resources"
-		copyres(corepath, outputref, ['cfrg', 'Popt', 'GU\267I'], 1)
-		
-		print "Adding resources from shared libraries"
-		for ppcpath, cfm68kpath in extraresfiles:
-			if os.path.exists(ppcpath):
-				copyres(ppcpath, outputref, ['cfrg'], 1)
-			elif os.path.exists(cfm68kpath):
-				copyres(cfm68kpath, outputref, ['cfrg'], 1)
-		
-		print "Fixing sys.path prefs"
-		Res.UseResFile(outputref)
-		try:
-			res = Res.Get1Resource('STR#', 228) # from PythonCore
-		except Res.Error: pass
-		else:
-			res.RemoveResource()
-		# setting pref file name to empty string
-		res = Res.Get1NamedResource('STR ', "PythonPreferenceFileName")
-		res.data = Pstring("")
-		res.ChangedResource()
-		syspathpref = "$(APPLICATION)"
-		res = Res.Resource("\000\001" + Pstring(syspathpref))
-		res.AddResource("STR#", 229, "sys.path preference")
-		
-		print "Creating 'PYD ' resources"
-		for modname, (ppcfrag, cfm68kfrag) in dynamicmodules.items():
-			res = Res.Resource(Pstring(ppcfrag) + Pstring(cfm68kfrag))
-			id = 0
-			while id < 128:
-				id = Res.Unique1ID('PYD ')
-			res.AddResource('PYD ', id, modname)
-	finally:
-		Res.CloseResFile(outputref)
-	print "Merging code fragments"
-	cfmfile.mergecfmfiles([applettemplatepath, corepath] + dynamicfiles.keys(), 
-			output, architecture)
-	
-	print "done!"
+    # try to remove old file
+    try:
+        os.remove(output)
+    except:
+        pass
+
+    if module_dict is None:
+        import macmodulefinder
+        print "Searching for modules..."
+        module_dict, missing = macmodulefinder.process(input, [], [], 1)
+        if missing:
+            import EasyDialogs
+            missing.sort()
+            answer = EasyDialogs.AskYesNoCancel("Some modules could not be found; continue anyway?\n(%s)"
+                            % string.join(missing, ", "))
+            if answer <> 1:
+                sys.exit(0)
+
+    applettemplatepath = buildtools.findtemplate()
+    corepath = findpythoncore()
+
+    dynamicmodules, dynamicfiles, extraresfiles = findfragments(module_dict, architecture)
+
+    print 'Adding "__main__"'
+    buildtools.process(applettemplatepath, input, output, 0)
+
+    outputref = Res.FSpOpenResFile(output, 3)
+    try:
+        Res.UseResFile(outputref)
+
+        print "Adding Python modules"
+        addpythonmodules(module_dict)
+
+        print "Adding PythonCore resources"
+        copyres(corepath, outputref, ['cfrg', 'Popt', 'GU\267I'], 1)
+
+        print "Adding resources from shared libraries"
+        for ppcpath, cfm68kpath in extraresfiles:
+            if os.path.exists(ppcpath):
+                copyres(ppcpath, outputref, ['cfrg'], 1)
+            elif os.path.exists(cfm68kpath):
+                copyres(cfm68kpath, outputref, ['cfrg'], 1)
+
+        print "Fixing sys.path prefs"
+        Res.UseResFile(outputref)
+        try:
+            res = Res.Get1Resource('STR#', 228) # from PythonCore
+        except Res.Error: pass
+        else:
+            res.RemoveResource()
+        # setting pref file name to empty string
+        res = Res.Get1NamedResource('STR ', "PythonPreferenceFileName")
+        res.data = Pstring("")
+        res.ChangedResource()
+        syspathpref = "$(APPLICATION)"
+        res = Res.Resource("\000\001" + Pstring(syspathpref))
+        res.AddResource("STR#", 229, "sys.path preference")
+
+        print "Creating 'PYD ' resources"
+        for modname, (ppcfrag, cfm68kfrag) in dynamicmodules.items():
+            res = Res.Resource(Pstring(ppcfrag) + Pstring(cfm68kfrag))
+            id = 0
+            while id < 128:
+                id = Res.Unique1ID('PYD ')
+            res.AddResource('PYD ', id, modname)
+    finally:
+        Res.CloseResFile(outputref)
+    print "Merging code fragments"
+    cfmfile.mergecfmfiles([applettemplatepath, corepath] + dynamicfiles.keys(),
+                    output, architecture)
+
+    print "done!"
 
 
 def findfragments(module_dict, architecture):
-	dynamicmodules = {}
-	dynamicfiles = {}
-	extraresfiles = []
-	for name, module in module_dict.items():
-		if module.gettype() <> 'dynamic':
-			continue
-		path = resolvealiasfile(module.__file__)
-		dir, filename = os.path.split(path)
-##		ppcfile, cfm68kfile = makefilenames(filename)
-		ppcfile = filename
-		cfm68kfile = "dummy.cfm68k.slb"
-		
-		# ppc stuff
-		ppcpath = os.path.join(dir, ppcfile)
-		if architecture <> 'm68k':
-			ppcfrag, dynamicfiles = getfragname(ppcpath, dynamicfiles)
-		else:
-			ppcfrag = "_no_fragment_"
-		
-		# 68k stuff
-		cfm68kpath = os.path.join(dir, cfm68kfile)
-		if architecture <> 'pwpc':
-			cfm68kfrag, dynamicfiles = getfragname(cfm68kpath, dynamicfiles)
-		else:
-			cfm68kfrag = "_no_fragment_"
-		
-		dynamicmodules[name] = ppcfrag, cfm68kfrag
-		if (ppcpath, cfm68kpath) not in extraresfiles:
-			extraresfiles.append((ppcpath, cfm68kpath))
-	return dynamicmodules, dynamicfiles, extraresfiles
+    dynamicmodules = {}
+    dynamicfiles = {}
+    extraresfiles = []
+    for name, module in module_dict.items():
+        if module.gettype() <> 'dynamic':
+            continue
+        path = resolvealiasfile(module.__file__)
+        dir, filename = os.path.split(path)
+##              ppcfile, cfm68kfile = makefilenames(filename)
+        ppcfile = filename
+        cfm68kfile = "dummy.cfm68k.slb"
+
+        # ppc stuff
+        ppcpath = os.path.join(dir, ppcfile)
+        if architecture <> 'm68k':
+            ppcfrag, dynamicfiles = getfragname(ppcpath, dynamicfiles)
+        else:
+            ppcfrag = "_no_fragment_"
+
+        # 68k stuff
+        cfm68kpath = os.path.join(dir, cfm68kfile)
+        if architecture <> 'pwpc':
+            cfm68kfrag, dynamicfiles = getfragname(cfm68kpath, dynamicfiles)
+        else:
+            cfm68kfrag = "_no_fragment_"
+
+        dynamicmodules[name] = ppcfrag, cfm68kfrag
+        if (ppcpath, cfm68kpath) not in extraresfiles:
+            extraresfiles.append((ppcpath, cfm68kpath))
+    return dynamicmodules, dynamicfiles, extraresfiles
 
 
 def getfragname(path, dynamicfiles):
-	if not dynamicfiles.has_key(path):
-		if os.path.exists(path):
-			lib = cfmfile.CfrgResource(path)
-			fragname = lib.fragments[0].name
-		else:
-			print "shared lib not found:", path
-			fragname = "_no_fragment_"
-		dynamicfiles[path] = fragname
-	else:
-		fragname = dynamicfiles[path]
-	return fragname, dynamicfiles
+    if not dynamicfiles.has_key(path):
+        if os.path.exists(path):
+            lib = cfmfile.CfrgResource(path)
+            fragname = lib.fragments[0].name
+        else:
+            print "shared lib not found:", path
+            fragname = "_no_fragment_"
+        dynamicfiles[path] = fragname
+    else:
+        fragname = dynamicfiles[path]
+    return fragname, dynamicfiles
 
 
 def addpythonmodules(module_dict):
-	# XXX should really use macgen_rsrc.generate(), this does the same, but skips __main__
-	items = module_dict.items()
-	items.sort()
-	for name, module in items:
-		mtype = module.gettype()
-		if mtype not in ['module', 'package'] or name == "__main__":
-			continue
-		location = module.__file__
-		
-		if location[-4:] == '.pyc':
-			# Attempt corresponding .py
-			location = location[:-1]
-		if location[-3:] != '.py':
-			print '*** skipping', location
-			continue
-		
-		print 'Adding module "%s"' % name
-		id, name = py_resource.frompyfile(location, name, preload=0, 
-				ispackage=mtype=='package')
+    # XXX should really use macgen_rsrc.generate(), this does the same, but skips __main__
+    items = module_dict.items()
+    items.sort()
+    for name, module in items:
+        mtype = module.gettype()
+        if mtype not in ['module', 'package'] or name == "__main__":
+            continue
+        location = module.__file__
+
+        if location[-4:] == '.pyc':
+            # Attempt corresponding .py
+            location = location[:-1]
+        if location[-3:] != '.py':
+            print '*** skipping', location
+            continue
+
+        print 'Adding module "%s"' % name
+        id, name = py_resource.frompyfile(location, name, preload=0,
+                        ispackage=mtype=='package')
 
 def Pstring(str):
-	if len(str) > 255:
-		raise TypeError, "Str255 must be at most 255 chars long"
-	return chr(len(str)) + str
+    if len(str) > 255:
+        raise TypeError, "Str255 must be at most 255 chars long"
+    return chr(len(str)) + str
 
 ##def makefilenames(name):
-##	lname = string.lower(name)
-##	pos = string.find(lname, ".ppc.")
-##	if pos > 0:
-##		return name, name[:pos] + '.CFM68K.' + name[pos+5:]
-##	pos = string.find(lname, ".cfm68k.")
-##	if pos > 0:
-##		return name[:pos] + '.ppc.' + name[pos+8:], name
-##	raise ValueError, "can't make ppc/cfm68k filenames"
+##      lname = string.lower(name)
+##      pos = string.find(lname, ".ppc.")
+##      if pos > 0:
+##              return name, name[:pos] + '.CFM68K.' + name[pos+5:]
+##      pos = string.find(lname, ".cfm68k.")
+##      if pos > 0:
+##              return name[:pos] + '.ppc.' + name[pos+8:], name
+##      raise ValueError, "can't make ppc/cfm68k filenames"
 
 def copyres(input, output, *args, **kwargs):
-	openedin = openedout = 0
-	if type(input) == types.StringType:
-		input = Res.FSpOpenResFile(input, 1)
-		openedin = 1
-	if type(output) == types.StringType:
-		output = Res.FSpOpenResFile(output, 3)
-		openedout = 1
-	try:
-		apply(buildtools.copyres, (input, output) + args, kwargs)
-	finally:
-		if openedin:
-			Res.CloseResFile(input)
-		if openedout:
-			Res.CloseResFile(output)
+    openedin = openedout = 0
+    if type(input) == types.StringType:
+        input = Res.FSpOpenResFile(input, 1)
+        openedin = 1
+    if type(output) == types.StringType:
+        output = Res.FSpOpenResFile(output, 3)
+        openedout = 1
+    try:
+        apply(buildtools.copyres, (input, output) + args, kwargs)
+    finally:
+        if openedin:
+            Res.CloseResFile(input)
+        if openedout:
+            Res.CloseResFile(output)
 
 def findpythoncore():
-	"""find the PythonCore shared library, possibly asking the user if we can't find it"""
-	
-	try:
-		vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kSharedLibrariesFolderType, 0)
-	except macfs.error:
-		extpath = ":"
-	else:
-		extpath = macfs.FSSpec((vRefNum, dirID, "")).as_pathname()
-	version = string.split(sys.version)[0]
-	if MacOS.runtimemodel == 'carbon':
-		corename = "PythonCoreCarbon " + version
-	elif MacOS.runtimemodel == 'ppc':
-		corename = "PythonCore " + version
-	else:
-		raise "Unknown MacOS.runtimemodel", MacOS.runtimemodel
-	corepath = os.path.join(extpath, corename)
-	if not os.path.exists(corepath):
-		corepath = EasyDialogs.AskFileForOpen(message="Please locate PythonCore:", 
-			typeList=("shlb",))
-		if not corepath:
-			raise KeyboardInterrupt, "cancelled"
-	return resolvealiasfile(corepath)
+    """find the PythonCore shared library, possibly asking the user if we can't find it"""
+
+    try:
+        vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kSharedLibrariesFolderType, 0)
+    except macfs.error:
+        extpath = ":"
+    else:
+        extpath = macfs.FSSpec((vRefNum, dirID, "")).as_pathname()
+    version = string.split(sys.version)[0]
+    if MacOS.runtimemodel == 'carbon':
+        corename = "PythonCoreCarbon " + version
+    elif MacOS.runtimemodel == 'ppc':
+        corename = "PythonCore " + version
+    else:
+        raise "Unknown MacOS.runtimemodel", MacOS.runtimemodel
+    corepath = os.path.join(extpath, corename)
+    if not os.path.exists(corepath):
+        corepath = EasyDialogs.AskFileForOpen(message="Please locate PythonCore:",
+                typeList=("shlb",))
+        if not corepath:
+            raise KeyboardInterrupt, "cancelled"
+    return resolvealiasfile(corepath)
 
 def resolvealiasfile(path):
-	try:
-		fss, dummy1, dummy2 = macfs.ResolveAliasFile(path)
-	except macfs.error:
-		pass
-	else:
-		path = fss.as_pathname()
-	return path
+    try:
+        fss, dummy1, dummy2 = macfs.ResolveAliasFile(path)
+    except macfs.error:
+        pass
+    else:
+        path = fss.as_pathname()
+    return path
diff --git a/Mac/Tools/macfreeze/macgen_info.py b/Mac/Tools/macfreeze/macgen_info.py
index 2d984c1..d2edb92 100644
--- a/Mac/Tools/macfreeze/macgen_info.py
+++ b/Mac/Tools/macfreeze/macgen_info.py
@@ -1,8 +1,8 @@
 """macgen_info - Generate informational output"""
 
 def generate(output, module_dict):
-	for name in module_dict.keys():
-		print 'Include %-20s\t'%name,
-		module = module_dict[name]
-		print module.gettype(), '\t', repr(module)
-	return 0
+    for name in module_dict.keys():
+        print 'Include %-20s\t'%name,
+        module = module_dict[name]
+        print module.gettype(), '\t', repr(module)
+    return 0
diff --git a/Mac/Tools/macfreeze/macgen_rsrc.py b/Mac/Tools/macfreeze/macgen_rsrc.py
index 03fc0af..34c17ff 100644
--- a/Mac/Tools/macfreeze/macgen_rsrc.py
+++ b/Mac/Tools/macfreeze/macgen_rsrc.py
@@ -5,33 +5,32 @@
 import sys
 
 def generate(output, module_dict, debug=0, preload=1):
-	fsid = py_resource.create(output)
-	
-	for name, module in module_dict.items():
-		mtype = module.gettype()
-		if mtype not in ['module', 'package']:
-			continue
-		location = module.__file__
-		
-		if location[-4:] == '.pyc':
-			# Attempt corresponding .py
-			location = location[:-1]
-		if location[-3:] != '.py':
-			print '*** skipping', location
-			continue
-			
-		id, name = py_resource.frompyfile(location, name, preload=preload, 
-				ispackage=mtype=='package')
-		if debug > 0:
-			print 'PYC resource %5d\t%s\t%s'%(id, name, location)
-	
-	Res.CloseResFile(fsid)
-	
+    fsid = py_resource.create(output)
+
+    for name, module in module_dict.items():
+        mtype = module.gettype()
+        if mtype not in ['module', 'package']:
+            continue
+        location = module.__file__
+
+        if location[-4:] == '.pyc':
+            # Attempt corresponding .py
+            location = location[:-1]
+        if location[-3:] != '.py':
+            print '*** skipping', location
+            continue
+
+        id, name = py_resource.frompyfile(location, name, preload=preload,
+                        ispackage=mtype=='package')
+        if debug > 0:
+            print 'PYC resource %5d\t%s\t%s'%(id, name, location)
+
+    Res.CloseResFile(fsid)
+
 def warnings(module_dict):
-	problems = 0
-	for name, module in module_dict.items():
-		if module.gettype() not in ('builtin', 'module', 'package'):
-			problems = problems + 1
-			print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
-	return problems
-	
+    problems = 0
+    for name, module in module_dict.items():
+        if module.gettype() not in ('builtin', 'module', 'package'):
+            problems = problems + 1
+            print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
+    return problems
diff --git a/Mac/Tools/macfreeze/macgen_src.py b/Mac/Tools/macfreeze/macgen_src.py
index 089727a..301e85e 100644
--- a/Mac/Tools/macfreeze/macgen_src.py
+++ b/Mac/Tools/macfreeze/macgen_src.py
@@ -16,98 +16,98 @@
 BUNDLE_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozenbundle.rsrc')
 
 def generate(output, module_dict, debug=0, with_ifdef=0):
-	problems = 0
-	output_created=0
-	if not os.path.exists(output):
-		print 'Creating project folder', output
-		os.mkdir(output)
-		output_created = 1
-	# Resolve aliases, if needed
-	try:
-		fss, dummy1, dummy2 = macfs.ResolveAliasFile(output)
-	except macfs.error:
-		pass
-	else:
-		newname = fss.as_pathname()
-		if newname != output:
-			if debug:
-				print 'Alias', output
-				print 'Resolved to', newname
-			output = newname	
-	# Construct the filenames
-	dummy, outfile = os.path.split(output)
-	build, ext = os.path.splitext(outfile)
-	if build == 'build' and ext[0] == '.':
-		# This is probably a good name for the project
-		projname = ext[1:]
-	else:
-		projname = 'frozenapplet.prj'
-	config_name = os.path.join(output, ':macfrozenconfig.c')
-	project_name = os.path.join(output, ':' + projname + '.prj')
-	resource_name = os.path.join(output, ':frozenmodules.rsrc')
-	bundle_name = os.path.join(output, ':frozenbundle.rsrc')
+    problems = 0
+    output_created=0
+    if not os.path.exists(output):
+        print 'Creating project folder', output
+        os.mkdir(output)
+        output_created = 1
+    # Resolve aliases, if needed
+    try:
+        fss, dummy1, dummy2 = macfs.ResolveAliasFile(output)
+    except macfs.error:
+        pass
+    else:
+        newname = fss.as_pathname()
+        if newname != output:
+            if debug:
+                print 'Alias', output
+                print 'Resolved to', newname
+            output = newname
+    # Construct the filenames
+    dummy, outfile = os.path.split(output)
+    build, ext = os.path.splitext(outfile)
+    if build == 'build' and ext[0] == '.':
+        # This is probably a good name for the project
+        projname = ext[1:]
+    else:
+        projname = 'frozenapplet.prj'
+    config_name = os.path.join(output, ':macfrozenconfig.c')
+    project_name = os.path.join(output, ':' + projname + '.prj')
+    resource_name = os.path.join(output, ':frozenmodules.rsrc')
+    bundle_name = os.path.join(output, ':frozenbundle.rsrc')
 
-	# Fill the output folder, if needed.
-	if output_created:
-		# Create the project, if needed
-		if not os.path.exists(project_name):
-			print 'Creating project', project_name
-			if not os.path.exists(PROJECT_TEMPLATE):
-				print '** No template CodeWarrior project found at', PROJECT_TEMPLATE
-				print '   To generate standalone Python applications from source you need'
-				print '   a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
-				print '   for details.'
-				problems = 1
-			else:		
-				macostools.copy(PROJECT_TEMPLATE, project_name)
-				print 'A template CodeWarrior project has been copied to', project_name
-				print 'It is up to you to make the following changes:'
-				print '- Change the output file name'
-				print '- Change the search path, unless the folder is in the python home'
-				print '- Add sourcefiles/libraries for any extension modules used'
-				print '- Remove unused sources, to speed up the build process'
-				print '- Remove unused resource files (like tcl/tk) for a smaller binary'
-				problems = 1
-				macostools.copy(BUNDLE_TEMPLATE, bundle_name)
-				print 'A template bundle file has also been copied to', bundle_name
-				print 'You may want to adapt signature, size resource, etc'
+    # Fill the output folder, if needed.
+    if output_created:
+        # Create the project, if needed
+        if not os.path.exists(project_name):
+            print 'Creating project', project_name
+            if not os.path.exists(PROJECT_TEMPLATE):
+                print '** No template CodeWarrior project found at', PROJECT_TEMPLATE
+                print '   To generate standalone Python applications from source you need'
+                print '   a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
+                print '   for details.'
+                problems = 1
+            else:
+                macostools.copy(PROJECT_TEMPLATE, project_name)
+                print 'A template CodeWarrior project has been copied to', project_name
+                print 'It is up to you to make the following changes:'
+                print '- Change the output file name'
+                print '- Change the search path, unless the folder is in the python home'
+                print '- Add sourcefiles/libraries for any extension modules used'
+                print '- Remove unused sources, to speed up the build process'
+                print '- Remove unused resource files (like tcl/tk) for a smaller binary'
+                problems = 1
+                macostools.copy(BUNDLE_TEMPLATE, bundle_name)
+                print 'A template bundle file has also been copied to', bundle_name
+                print 'You may want to adapt signature, size resource, etc'
 
-	
-	# Create the resource file
-	macgen_rsrc.generate(resource_name, module_dict, debug=debug)
-	
-	# Create the config.c file
-	if not os.path.exists(CONFIG_TEMPLATE):
-		print '** No template config.c found at', PROJECT_TEMPLATE
-		print '   To generate standalone Python applications from source you need'
-		print '   a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
-		print '   for details.'
-		problems = 1
-	else:
-		# Find elegible modules (builtins and dynamically loaded modules)
-		c_modules = []
-		for module in module_dict.keys():
-			if module_dict[module].gettype() in ('builtin', 'dynamic'):
-				# if the module is in a package we have no choice but
-				# to put it at the toplevel in the frozen application.
-				if '.' in module:
-					module = module.split('.')[-1]
-				c_modules.append(module)
-		ifp = open(CONFIG_TEMPLATE)
-		ofp = open(config_name, 'w')
-		makeconfig.makeconfig(ifp, ofp, c_modules, with_ifdef)
-		ifp.close()
-		ofp.close()
-		MacOS.SetCreatorAndType(config_name, 'CWIE', 'TEXT')
-	
-	if warnings(module_dict):
-		problems = 1
-	return problems
-	
+
+    # Create the resource file
+    macgen_rsrc.generate(resource_name, module_dict, debug=debug)
+
+    # Create the config.c file
+    if not os.path.exists(CONFIG_TEMPLATE):
+        print '** No template config.c found at', PROJECT_TEMPLATE
+        print '   To generate standalone Python applications from source you need'
+        print '   a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
+        print '   for details.'
+        problems = 1
+    else:
+        # Find elegible modules (builtins and dynamically loaded modules)
+        c_modules = []
+        for module in module_dict.keys():
+            if module_dict[module].gettype() in ('builtin', 'dynamic'):
+                # if the module is in a package we have no choice but
+                # to put it at the toplevel in the frozen application.
+                if '.' in module:
+                    module = module.split('.')[-1]
+                c_modules.append(module)
+        ifp = open(CONFIG_TEMPLATE)
+        ofp = open(config_name, 'w')
+        makeconfig.makeconfig(ifp, ofp, c_modules, with_ifdef)
+        ifp.close()
+        ofp.close()
+        MacOS.SetCreatorAndType(config_name, 'CWIE', 'TEXT')
+
+    if warnings(module_dict):
+        problems = 1
+    return problems
+
 def warnings(module_dict):
-	problems = 0
-	for name, module in module_dict.items():
-		if module.gettype() not in ('builtin', 'module', 'dynamic', 'package'):
-			problems = problems + 1
-			print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
-	return problems
+    problems = 0
+    for name, module in module_dict.items():
+        if module.gettype() not in ('builtin', 'module', 'dynamic', 'package'):
+            problems = problems + 1
+            print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
+    return problems
diff --git a/Mac/Tools/macfreeze/macgenerate.py b/Mac/Tools/macfreeze/macgenerate.py
index dfa2047..12343c3 100644
--- a/Mac/Tools/macfreeze/macgenerate.py
+++ b/Mac/Tools/macfreeze/macgenerate.py
@@ -1,8 +1,8 @@
 """macgenerate - Generate the out for macfreeze"""
 
 def generate(program, module_dict):
-	for name in module_dict.keys():
-		print 'Include %-20s\t'%name,
-		module = module_dict[name]
-		print module.gettype(), '\t', repr(module)
-	return 0
+    for name in module_dict.keys():
+        print 'Include %-20s\t'%name,
+        module = module_dict[name]
+        print module.gettype(), '\t', repr(module)
+    return 0
diff --git a/Mac/Tools/macfreeze/macmodulefinder.py b/Mac/Tools/macfreeze/macmodulefinder.py
index 285f51f..3f4e0b7 100644
--- a/Mac/Tools/macfreeze/macmodulefinder.py
+++ b/Mac/Tools/macfreeze/macmodulefinder.py
@@ -7,40 +7,40 @@
 import directives
 
 try:
-	# This will work if we are frozen ourselves
-	import modulefinder
+    # This will work if we are frozen ourselves
+    import modulefinder
 except ImportError:
-	# And this will work otherwise
-	_FREEZEDIR=os.path.join(sys.prefix, ':Tools:freeze')
-	sys.path.insert(0, _FREEZEDIR)
-	import modulefinder
+    # And this will work otherwise
+    _FREEZEDIR=os.path.join(sys.prefix, ':Tools:freeze')
+    sys.path.insert(0, _FREEZEDIR)
+    import modulefinder
 
 #
 # Modules that must be included, and modules that need not be included
 # (but are if they are found)
 #
 MAC_INCLUDE_MODULES=['site']
-MAC_MAYMISS_MODULES=['posix', 'os2', 'nt', 'ntpath', 'dos', 'dospath', 
-		'win32api', 'ce', '_winreg',
-		'nturl2path', 'pwd', 'sitecustomize',
-		'org.python.core',
-		'riscos', 'riscosenviron', 'riscospath'
-		]
+MAC_MAYMISS_MODULES=['posix', 'os2', 'nt', 'ntpath', 'dos', 'dospath',
+                'win32api', 'ce', '_winreg',
+                'nturl2path', 'pwd', 'sitecustomize',
+                'org.python.core',
+                'riscos', 'riscosenviron', 'riscospath'
+                ]
 
 # An exception:
 Missing="macmodulefinder.Missing"
 
 class Module(modulefinder.Module):
-	
-	def gettype(self):
-		"""Return type of module"""
-		if self.__path__:
-			return 'package'
-		if self.__code__:
-			return 'module'
-		if self.__file__:
-			return 'dynamic'
-		return 'builtin'
+
+    def gettype(self):
+        """Return type of module"""
+        if self.__path__:
+            return 'package'
+        if self.__code__:
+            return 'module'
+        if self.__file__:
+            return 'dynamic'
+        return 'builtin'
 
 class ModuleFinder(modulefinder.ModuleFinder):
 
@@ -49,64 +49,64 @@
             return self.modules[fqname]
         self.modules[fqname] = m = Module(fqname)
         return m
-        
+
 def process(program, modules=None, module_files=None, debug=0):
-	if modules is None:
-		modules = []
-	if module_files is None:
-		module_files = []
-	missing = []
-	#
-	# Add the standard modules needed for startup
-	#
-	modules = modules + MAC_INCLUDE_MODULES
-	#
-	# search the main source for directives
-	#
-	extra_modules, exclude_modules, optional_modules, extra_path = \
-			directives.findfreezedirectives(program)
-	for m in extra_modules:
-		if os.sep in m:
-			# It is a file
-			module_files.append(m)
-		else:
-			modules.append(m)
+    if modules is None:
+        modules = []
+    if module_files is None:
+        module_files = []
+    missing = []
+    #
+    # Add the standard modules needed for startup
+    #
+    modules = modules + MAC_INCLUDE_MODULES
+    #
+    # search the main source for directives
+    #
+    extra_modules, exclude_modules, optional_modules, extra_path = \
+                    directives.findfreezedirectives(program)
+    for m in extra_modules:
+        if os.sep in m:
+            # It is a file
+            module_files.append(m)
+        else:
+            modules.append(m)
     # collect all modules of the program
-	path = sys.path[:]
-	dir = os.path.dirname(program)
-	path[0] = dir	# "current dir"
-	path = extra_path + path
-	#
-	# Create the module finder and let it do its work
-	#
-	modfinder = ModuleFinder(path, 
-			excludes=exclude_modules, debug=debug)
-	for m in modules:
-		modfinder.import_hook(m)
-	for m in module_files:
-		modfinder.load_file(m)
-	modfinder.run_script(program)
-	module_dict = modfinder.modules
-	#
-	# Tell the user about missing modules
-	#
-	maymiss = exclude_modules + optional_modules + MAC_MAYMISS_MODULES
-	for m in modfinder.badmodules.keys():
-		if not m in maymiss:
-			if debug > 0:
-				print 'Missing', m
-			missing.append(m)
-	#
-	# Warn the user about unused builtins
-	#
-	for m in sys.builtin_module_names:
-		if m in ('__main__', '__builtin__'):
-			pass
-		elif not module_dict.has_key(m):
-			if debug > 0:
-				print 'Unused', m
-		elif module_dict[m].gettype() != 'builtin':
-			# XXXX Can this happen?
-			if debug > 0:
-				print 'Conflict', m
-	return module_dict, missing
+    path = sys.path[:]
+    dir = os.path.dirname(program)
+    path[0] = dir   # "current dir"
+    path = extra_path + path
+    #
+    # Create the module finder and let it do its work
+    #
+    modfinder = ModuleFinder(path,
+                    excludes=exclude_modules, debug=debug)
+    for m in modules:
+        modfinder.import_hook(m)
+    for m in module_files:
+        modfinder.load_file(m)
+    modfinder.run_script(program)
+    module_dict = modfinder.modules
+    #
+    # Tell the user about missing modules
+    #
+    maymiss = exclude_modules + optional_modules + MAC_MAYMISS_MODULES
+    for m in modfinder.badmodules.keys():
+        if not m in maymiss:
+            if debug > 0:
+                print 'Missing', m
+            missing.append(m)
+    #
+    # Warn the user about unused builtins
+    #
+    for m in sys.builtin_module_names:
+        if m in ('__main__', '__builtin__'):
+            pass
+        elif not module_dict.has_key(m):
+            if debug > 0:
+                print 'Unused', m
+        elif module_dict[m].gettype() != 'builtin':
+            # XXXX Can this happen?
+            if debug > 0:
+                print 'Conflict', m
+    return module_dict, missing
