Whitespace normalization, via reindent.py.
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