import Qd
import TE
import Fm
import waste
import WASTEconst
import Res
import Evt
import Events
import Scrap
import string

import Win
import Wbase
import Wkeys
import Wcontrols
import PyFontify
from types import *
import Fonts
import TextEdit



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()


class _ScrollWidget:
	
	# to be overridden
	def getscrollbarvalues(self):
		return None, None
	
	# internal method
	def updatescrollbars(self):
		vx, vy = self.getscrollbarvalues()
		if self._parent._barx:
			if vx <> None:
				self._parent._barx.enable(1)
				self._parent._barx.set(vx)
			else:
				self._parent._barx.enable(0)
		if self._parent._bary:
			if vy <> None:
				self._parent._bary.enable(1)
				self._parent._bary.set(vy)
			else:
				self._parent._bary.enable(0)
	

UNDOLABELS = [	# Indexed by WEGetUndoInfo() value
	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style",
	"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._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 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):
		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.selchanged = 1
		self.updatescrollbars()
	
	def adjust(self, oldbounds):
		self.SetPort()
		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.selchanged = 1
		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.selchanged = 1
		self.updatescrollbars()
	
	def getselection(self):
		if self.ted:
			return self.ted.WEGetSelection()
		else:
			return self.selection
	
	def setselection(self, selstart, selend):
		self.selchanged = 1
		if self.ted:
			self.ted.WESetSelection(selstart, selend)
			self.ted.WESelView()
			self.updatescrollbars()
		else:
			self.selection = selstart, selend
	
	def offsettoline(self, offset):
		return self.ted.WEOffsetToLine(offset)
	
	def countlines(self):
		return self.ted.WECountLines()
	
	def getselectedtext(self):
		selstart, selend = self.ted.WEGetSelection()
		return self.ted.WEGetText().data[selstart:selend]
	
	def expandselection(self):
		oldselstart, oldselend = self.ted.WEGetSelection()
		selstart, selend = min(oldselstart, oldselend), max(oldselstart, oldselend)
		if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r':
			selend = selend - 1
		newselstart, dummy = self.ted.WEFindLine(selstart, 1)
		dummy, newselend = self.ted.WEFindLine(selend, 1)
		if oldselstart <> newselstart or  oldselend <> newselend:
			self.ted.WESetSelection(newselstart, newselend)
			self.updatescrollbars()
		self.selchanged = 1
	
	def insert(self, text):
		self.ted.WEInsert(text, None, None)
		self.changed = 1
		self.selchanged = 1
	
	# 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.GetWindow().InvalWindowRect(self.ted.WEGetViewRect())
			self.updatescrollbars()
	
	def get(self):
		if not self._parent:
			return self.temptext
		else:
			return self.ted.WEGetText().data
	
	# events
	def key(self, char, event):
		(what, message, when, where, modifiers) = event
		if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
			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 self._callback:
				Wbase.CallbackCall(self._callback, 0, char, modifiers)
	
	def click(self, point, modifiers):
		if not self._enabled:
			return
		self.ted.WEClick(point, modifiers, Evt.TickCount())
		self.selchanged = 1
		self.updatescrollbars()
		return 1
	
	def idle(self):
		self.SetPort()
		self.ted.WEIdle()
	
	def rollover(self, point, onoff):
		if onoff:
			Wbase.SetCursor("iBeam")
	
	def activate(self, onoff):
		self._activated = onoff
		if self._selected and self._visible:
			if onoff:
				self.ted.WEActivate()
			else:
				self.ted.WEDeactivate()
			if self._selected:
				self.drawselframe(onoff)
	
	def select(self, onoff, isclick = 0):
		if Wbase.SelectableWidget.select(self, onoff):
			return
		self.SetPort()
		if onoff:
			self.ted.WEActivate()
			if self._parentwindow._tabbable and not isclick:
				self.selectall()
		else:
			self.ted.WEDeactivate()
		self.drawselframe(onoff)
	
	def draw(self, visRgn = None):
		if self._visible:
			if not visRgn:
				visRgn = self._parentwindow.wid.GetWindowPort().visRgn
			self.ted.WEUpdate(visRgn)
			if self._selected and self._activated:
				self.drawselframe(1)
			Qd.FrameRect(self._bounds)
	
	# scrolling
	def scrollpageup(self):
		if self._parent._bary and self._parent._bary._enabled:
			self.vscroll("++")
	
	def scrollpagedown(self):
		if self._parent._bary and self._parent._bary._enabled:
			self.vscroll("--")
	
	def scrolltop(self):
		if self._parent._bary and self._parent._bary._enabled:
			self.vscroll(0)
		if self._parent._barx and self._parent._barx._enabled:
			self.hscroll(0)
	
	def scrollbottom(self):
		if self._parent._bary and self._parent._bary._enabled:
			self.vscroll(32767)
	
	# menu handlers
	def domenu_copy(self, *args):
		selbegin, selend = self.ted.WEGetSelection()
		if selbegin == selend:
			return
		Scrap.ZeroScrap()
		self.ted.WECopy()
		self.updatescrollbars()
	
	def domenu_cut(self, *args):
		selbegin, selend = self.ted.WEGetSelection()
		if selbegin == selend:
			return
		Scrap.ZeroScrap()
		self.ted.WECut()
		self.updatescrollbars()
		self.selview()
		self.changed = 1
		self.selchanged = 1
		if self._callback:
			Wbase.CallbackCall(self._callback, 0, "", None)
	
	def domenu_paste(self, *args):
		if not self.ted.WECanPaste():
			return
		self.selview()
		self.ted.WEPaste()
		self.updatescrollbars()
		self.changed = 1
		self.selchanged = 1
		if self._callback:
			Wbase.CallbackCall(self._callback, 0, "", None)
	
	def domenu_clear(self, *args):
		self.ted.WEDelete()
		self.selview()
		self.updatescrollbars()
		self.changed = 1
		self.selchanged = 1
		if self._callback:
			Wbase.CallbackCall(self._callback, 0, "", None)
	
	def domenu_undo(self, *args):
		which, redo = self.ted.WEGetUndoInfo()
		if not which: 
			return
		self.ted.WEUndo()
		self.updatescrollbars()
		self.changed = 1
		self.selchanged = 1
		if self._callback:
			Wbase.CallbackCall(self._callback, 0, "", None)
	
	def can_undo(self, menuitem):
		#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 getscrollbarvalues(self):
		dr = self.ted.WEGetDestRect()
		vr = self.ted.WEGetViewRect()
		vx = Wcontrols._scalebarvalue(dr[0], dr[2], vr[0], vr[2])
		vy = Wcontrols._scalebarvalue(dr[1], dr[3], vr[1], vr[3])
		return vx, vy
	
	def vscroll(self, value):
		lineheight = self.ted.WEGetHeight(0, 1)
		dr = self.ted.WEGetDestRect()
		vr = self.ted.WEGetViewRect()
		destheight = dr[3] - dr[1]
		viewheight = vr[3] - vr[1]
		viewoffset = maxdelta = vr[1] - dr[1]
		mindelta = vr[3] - dr[3]
		if value == "+":
			delta = lineheight
		elif value == "-":
			delta = - lineheight
		elif value == "++":
			delta = viewheight - lineheight
		elif value == "--":
			delta = lineheight - viewheight
		else:	# in thumb
			cur = (32767L * viewoffset) / (destheight - viewheight)
			delta = (cur-value)*(destheight - viewheight)/32767
			if abs(delta - viewoffset) <=2:
				# compensate for irritating rounding error
				delta = viewoffset
		delta = min(maxdelta, delta)
		delta = max(mindelta, delta)
		self.ted.WEScroll(0, delta)
		self.updatescrollbars()
	
	def hscroll(self, value):
		dr = self.ted.WEGetDestRect()
		vr = self.ted.WEGetViewRect()
		destwidth = dr[2] - dr[0]
		viewwidth = vr[2] - vr[0]
		viewoffset = maxdelta = vr[0] - dr[0]
		mindelta = vr[2] - dr[2]
		if value == "+":
			delta = 32
		elif value == "-":
			delta = - 32
		elif value == "++":
			delta = 0.5 * (vr[2] - vr[0])
		elif value == "--":
			delta = 0.5 * (vr[0] - vr[2])
		else:	# in thumb
			cur = (32767 * viewoffset) / (destwidth - viewwidth)
			delta = (cur-value)*(destwidth - viewwidth)/32767
			if abs(delta - viewoffset) <=2:
				# compensate for irritating rounding error
				delta = viewoffset
		delta = min(maxdelta, delta)
		delta = max(mindelta, delta)
		self.ted.WEScroll(delta, 0)
		self.updatescrollbars()
	
	# some internals
	def _getflags(self):
		flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoMonoStyled
		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)


import re
commentPat = re.compile("[ \t]*(#)")
indentPat = re.compile("[ \t]*")


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.file = file	# only for debugger reference
		self._debugger = debugger
		if debugger:
			debugger.register_editor(self, self.file)
	
	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.changed = 1
		self.selchanged = 1
		self.updatescrollbars()
	
	def balanceparens(self, char):
		if char == ')':
			target = '('
		elif char == ']':
			target = '['
		elif char == '}':
			target = '{'
		recursionlevel = 1
		selstart, selend = self.ted.WEGetSelection()
		count = min(selstart, selend) - 2
		mincount = max(0, count - 2048)
		lastquote = None
		while count > mincount:
			testchar = chr(self.ted.WEGetChar(count))
			if testchar in "\"'" and chr(self.ted.WEGetChar(count - 1)) <> '\\':
				if lastquote == testchar:
					recursionlevel = recursionlevel - 1
					lastquote = None
				elif not lastquote:
					recursionlevel = recursionlevel + 1
					lastquote = testchar
			elif not lastquote and testchar == char:
				recursionlevel = recursionlevel + 1
			elif not lastquote and testchar == target:
				recursionlevel = recursionlevel - 1
				if recursionlevel == 0:
					import time
					autoscroll = self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, -1)
					if autoscroll:
						self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 0)
					self.ted.WESetSelection(count, count + 1)
					time.sleep(0.2)
					self.ted.WESetSelection(selstart, selend)
					if autoscroll:
						self.ted.WEFeatureFlag(WASTEconst.weFAutoScroll, 1)
					break
			count = count - 1
	
	def extratabs(self, line):
		tabcount = 0
		for c in line:
			if c <> '\t':
				break
			tabcount = tabcount + 1
		last = 0
		cleanline = ''
		tags = PyFontify.fontify(line)
		# strip comments and strings
		for tag, start, end, sublist in tags:
			if tag in ('string', 'comment'):
				cleanline = cleanline + line[last:start]
				last = end
		cleanline = cleanline + line[last:]
		cleanline = string.strip(cleanline)
		if cleanline and cleanline[-1] == ':':
			tabcount = tabcount + 1
		else:
			# 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.qd.gray)
		Qd.PaintRect((br, bt, br + 1, bb))
		Qd.PenNormal()
		self._parentwindow.tempcliprect(breakrect)
		Qd.RGBForeColor((0xffff, 0, 0))
		try:
			lasttop = bt
			self_ted = self.ted
			Qd_PaintOval = Qd.PaintOval
			Qd_EraseRect = Qd.EraseRect
			for lineno in self._debugger.get_file_breaks(self.file):
				start, end = self_ted.WEGetLineRange(lineno - 1)
				if lineno <> self_ted.WEOffsetToLine(start) + 1:
					# breakpoints beyond our text: erase rest, and back out
					Qd_EraseRect((bl, lasttop, br, bb))
					break
				(x, y), h = self_ted.WEGetPoint(start, 0)
				bottom = y + h
				#print y, (lasttop, bottom)
				if bottom > lasttop:
					Qd_EraseRect((bl, lasttop, br, y + h * eraseall))
					lasttop = bottom
				redbullet = bl + 2, y + 3, bl + 8, y + 9
				Qd_PaintOval(redbullet)
			else:
				Qd_EraseRect((bl, lasttop, br, bb))
			Qd.RGBForeColor((0, 0, 0))
		finally:
			self._parentwindow.restoreclip()
	
	def updatescrollbars(self):
		if self._debugger:
			self.drawbreakpoints(1)
		TextEditor.updatescrollbars(self)
	
	def pt_in_breaks(self, point):
		return Qd.PtInRect(point, self._getbreakrect())
	
	def _getbreakrect(self):
		if self._debugger:
			l, t, r, b = self._bounds
			return (l+1, t+1, l + 12, b-1)
		else:
			return (0, 0, 0, 0)
	
	def _getviewrect(self):
		l, t, r, b = self._bounds
		if self._debugger:
			return (l + 17, t + 2, r, b - 2)
		else:
			return (l + 5, t + 2, r, b - 2)
	
	def _calctextbounds(self):
		viewrect = l, t, r, b = self._getviewrect()
		if self.ted:
			dl, dt, dr, db = self.ted.WEGetDestRect()
			vl, vt, vr, vb = self.ted.WEGetViewRect()
			xshift = l - vl
			yshift = t - vt
			if (db - dt) < (b - t):
				yshift = t - dt
			destrect = (dl + xshift, dt + yshift, dr + xshift, db + yshift)
		else:
			destrect = (l, t, r + 5000, b)
		return viewrect, destrect


def GetFNum(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

# b/w compat. Anyone using this?
GetFName = Fm.GetFontName

def GetPortFontSettings(port):
	return Fm.GetFontName(port.txFont), port.txFace, port.txSize

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)
