| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | from Carbon import Evt, Events, Fm, Fonts | 
					
						
							|  |  |  | from Carbon import Qd, Res, Scrap | 
					
						
							|  |  |  | from Carbon import TE, TextEdit, Win | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | from Carbon import App | 
					
						
							|  |  |  | from Carbon.Appearance import kThemeStateActive, kThemeStateInactive | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | import waste | 
					
						
							|  |  |  | import WASTEconst | 
					
						
							|  |  |  | import Wbase | 
					
						
							|  |  |  | import Wkeys | 
					
						
							|  |  |  | import Wcontrols | 
					
						
							|  |  |  | import PyFontify | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | import string | 
					
						
							|  |  |  | from types import TupleType, StringType | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TextBox(Wbase.Widget): | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	"""A static text widget""" | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 	def __init__(self, possize, text="", align=TextEdit.teJustLeft,  | 
					
						
							|  |  |  | 				fontsettings=None, | 
					
						
							|  |  |  | 				backgroundcolor=(0xffff, 0xffff, 0xffff) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				): | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 		if fontsettings is None: | 
					
						
							|  |  |  | 			import W | 
					
						
							|  |  |  | 			fontsettings = W.getdefaultfont() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 	def getscrollrects(self): | 
					
						
							|  |  |  | 		"""Return (destrect, viewrect).""" | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		return None, None | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# internal method | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	def updatescrollbars(self): | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 		(dl, dt, dr, db), (vl, vt, vr, vb) = self.getscrollrects() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if self._parent._barx: | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			viewwidth = vr - vl | 
					
						
							|  |  |  | 			destwidth = dr - dl | 
					
						
							|  |  |  | 			bar = self._parent._barx | 
					
						
							|  |  |  | 			bar.setmax(destwidth - viewwidth) | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# MacOS 8.1 doesn't automatically disable | 
					
						
							|  |  |  | 			# scrollbars whose max <= min | 
					
						
							|  |  |  | 			bar.enable(destwidth > viewwidth) | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			bar.setviewsize(viewwidth) | 
					
						
							|  |  |  | 			bar.set(vl - dl) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if self._parent._bary: | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			viewheight = vb - vt | 
					
						
							|  |  |  | 			destheight = db - dt | 
					
						
							|  |  |  | 			bar = self._parent._bary | 
					
						
							|  |  |  | 			bar.setmax(destheight - viewheight) | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# MacOS 8.1 doesn't automatically disable | 
					
						
							|  |  |  | 			# scrollbars whose max <= min | 
					
						
							|  |  |  | 			bar.enable(destheight > viewheight) | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			bar.setviewsize(viewheight) | 
					
						
							|  |  |  | 			bar.set(vt - dt) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | UNDOLABELS = [	# Indexed by WEGetUndoInfo() value | 
					
						
							| 
									
										
										
										
											2001-02-21 15:45:55 +00:00
										 |  |  | 	None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style", | 
					
						
							|  |  |  | 	"Ruler", "backspace", "delete", "transform", "resize"] | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EditText(Wbase.SelectableWidget, _ScrollWidget): | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	"""A text edit widget, mainly for simple entry fields.""" | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 	def __init__(self, possize, text="",  | 
					
						
							|  |  |  | 				callback=None, inset=(3, 3),  | 
					
						
							|  |  |  | 				fontsettings=None, | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				tabsettings = (32, 0), | 
					
						
							|  |  |  | 				readonly = 0): | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 		if fontsettings is None: | 
					
						
							|  |  |  | 			import W | 
					
						
							|  |  |  | 			fontsettings = W.getdefaultfont() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		Wbase.SelectableWidget.__init__(self, possize) | 
					
						
							|  |  |  | 		self.temptext = text | 
					
						
							|  |  |  | 		self.ted = None | 
					
						
							|  |  |  | 		self.selection = None | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.oldselection = None | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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) | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 	def textchanged(self, all=0): | 
					
						
							|  |  |  | 		self.changed = 1 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def selectionchanged(self): | 
					
						
							|  |  |  | 		self.selchanged = 1 | 
					
						
							|  |  |  | 		self.oldselection = self.getselection() | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	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): | 
					
						
							| 
									
										
										
										
											2001-08-25 12:15:04 +00:00
										 |  |  | 		from Carbon import Res | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		(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) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		self.updatescrollbars() | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def adjust(self, oldbounds): | 
					
						
							|  |  |  | 		self.SetPort() | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 		# 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. | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if self._selected and self._parentwindow._hasselframes: | 
					
						
							| 
									
										
										
										
											2001-01-23 14:58:20 +00:00
										 |  |  | 			self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3)) | 
					
						
							|  |  |  | 			self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3)) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2001-01-23 14:58:20 +00:00
										 |  |  | 			self.GetWindow().InvalWindowRect(oldbounds) | 
					
						
							|  |  |  | 			self.GetWindow().InvalWindowRect(self._bounds) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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()) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		self.updatescrollbars() | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def getselection(self): | 
					
						
							|  |  |  | 		if self.ted: | 
					
						
							|  |  |  | 			return self.ted.WEGetSelection() | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			return self.selection | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def setselection(self, selstart, selend): | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-06-21 17:51:17 +00:00
										 |  |  | 		newselstart, dummy = self.ted.WEFindLine(selstart, 1) | 
					
						
							|  |  |  | 		dummy, newselend = self.ted.WEFindLine(selend, 1) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if oldselstart <> newselstart or  oldselend <> newselend: | 
					
						
							|  |  |  | 			self.ted.WESetSelection(newselstart, newselend) | 
					
						
							|  |  |  | 			self.updatescrollbars() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def insert(self, text): | 
					
						
							|  |  |  | 		self.ted.WEInsert(text, None, None) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# 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() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 			self.textchanged(1) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	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: | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 				self.textchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 			if char not in Wkeys.scrollkeys: | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 				self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 			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()) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 		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) | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 			if self._selected: | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 				if onoff: | 
					
						
							|  |  |  | 					self.ted.WEActivate() | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					self.ted.WEDeactivate() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				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) | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			# 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 			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: | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			self.vscroll(self._parent._bary.getmin()) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if self._parent._barx and self._parent._barx._enabled: | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			self.hscroll(self._parent._barx.getmin()) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def scrollbottom(self): | 
					
						
							|  |  |  | 		if self._parent._bary and self._parent._bary._enabled: | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			self.vscroll(self._parent._bary.getmax()) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# menu handlers | 
					
						
							|  |  |  | 	def domenu_copy(self, *args): | 
					
						
							|  |  |  | 		selbegin, selend = self.ted.WEGetSelection() | 
					
						
							|  |  |  | 		if selbegin == selend: | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2001-12-31 14:53:05 +00:00
										 |  |  | 		if hasattr(Scrap, 'ZeroScrap'): | 
					
						
							|  |  |  | 			Scrap.ZeroScrap() | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			Scrap.ClearCurrentScrap() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		self.ted.WECopy() | 
					
						
							|  |  |  | 		self.updatescrollbars() | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def domenu_cut(self, *args): | 
					
						
							|  |  |  | 		selbegin, selend = self.ted.WEGetSelection() | 
					
						
							|  |  |  | 		if selbegin == selend: | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2001-12-31 14:53:05 +00:00
										 |  |  | 		if hasattr(Scrap, 'ZeroScrap'): | 
					
						
							|  |  |  | 			Scrap.ZeroScrap() | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			Scrap.ClearCurrentScrap() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		self.ted.WECut() | 
					
						
							|  |  |  | 		self.updatescrollbars() | 
					
						
							|  |  |  | 		self.selview() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		if self._callback: | 
					
						
							|  |  |  | 			Wbase.CallbackCall(self._callback, 0, "", None) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def domenu_clear(self, *args): | 
					
						
							|  |  |  | 		self.ted.WEDelete() | 
					
						
							|  |  |  | 		self.selview() | 
					
						
							|  |  |  | 		self.updatescrollbars() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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() | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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() | 
					
						
							| 
									
										
										
										
											2001-02-21 15:45:55 +00:00
										 |  |  | 		if which < len(UNDOLABELS): | 
					
						
							|  |  |  | 			which = UNDOLABELS[which] | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			which = "" | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 	def getscrollrects(self): | 
					
						
							|  |  |  | 		return self.ted.WEGetDestRect(), self.ted.WEGetViewRect() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def vscroll(self, value): | 
					
						
							|  |  |  | 		lineheight = self.ted.WEGetHeight(0, 1) | 
					
						
							|  |  |  | 		dr = self.ted.WEGetDestRect() | 
					
						
							|  |  |  | 		vr = self.ted.WEGetViewRect() | 
					
						
							|  |  |  | 		viewheight = vr[3] - vr[1] | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 		maxdelta = vr[1] - dr[1] | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			delta = vr[1] - dr[1] - value | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2001-11-18 14:12:43 +00:00
										 |  |  | 			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 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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.""" | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 	def __init__(self, possize, text="", callback=None, wrap=1, inset=(4, 4), | 
					
						
							|  |  |  | 				fontsettings=None, | 
					
						
							|  |  |  | 				tabsettings=(32, 0), | 
					
						
							|  |  |  | 				readonly=0): | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-04 13:30:29 +00:00
										 |  |  | 	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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-21 13:54:31 +00:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2001-06-21 17:51:17 +00:00
										 |  |  | commentPat = re.compile("[ \t]*(#)") | 
					
						
							|  |  |  | indentPat = re.compile("[ \t]*") | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | kStringColor = (0, 0x7fff, 0) | 
					
						
							|  |  |  | kCommentColor = (0, 0, 0xb000) | 
					
						
							| 
									
										
										
										
											2001-06-21 17:51:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PyEditor(TextEditor): | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	"""A specialized Python source edit widget""" | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-09-26 12:21:32 +00:00
										 |  |  | 	def __init__(self, possize, text="", callback=None, inset=(4, 4), | 
					
						
							|  |  |  | 				fontsettings=None, | 
					
						
							|  |  |  | 				tabsettings=(32, 0), | 
					
						
							|  |  |  | 				readonly=0, | 
					
						
							|  |  |  | 				debugger=None, | 
					
						
							|  |  |  | 				file=''): | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		self.bind("cmdshiftd", self.alldirty) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		self.file = file	# only for debugger reference | 
					
						
							|  |  |  | 		self._debugger = debugger | 
					
						
							|  |  |  | 		if debugger: | 
					
						
							|  |  |  | 			debugger.register_editor(self, self.file) | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 		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) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	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)): | 
					
						
							| 
									
										
										
										
											2001-02-21 13:54:31 +00:00
										 |  |  | 			m = commentPat.match(lines[i]) | 
					
						
							|  |  |  | 			if m: | 
					
						
							|  |  |  | 				pos = m.start(1) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				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): | 
					
						
							| 
									
										
										
										
											2001-02-21 13:54:31 +00:00
										 |  |  | 				m = indentPat.match(line) | 
					
						
							|  |  |  | 				if m: | 
					
						
							|  |  |  | 					indent = min(indent, m.regs[0][1]) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				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: | 
					
						
							| 
									
										
										
										
											2001-11-02 19:24:41 +00:00
										 |  |  | 			self.textchanged() | 
					
						
							|  |  |  | 		self.selectionchanged() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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) | 
					
						
							| 
									
										
										
										
											2002-11-30 00:01:29 +00:00
										 |  |  | 					self._parentwindow.wid.GetWindowPort().QDFlushPortBuffer(None)  # needed under OSX | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 					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 | 
					
						
							| 
									
										
										
										
											2001-06-19 21:37:33 +00:00
										 |  |  | 					raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)" | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 				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() | 
					
						
							| 
									
										
										
										
											2002-11-30 00:01:29 +00:00
										 |  |  | 		Qd.PenPat(Qd.GetQDGlobalsGray()) | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 		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): | 
					
						
							| 
									
										
										
										
											2002-11-30 00:01:29 +00:00
										 |  |  | 	return Fm.GetFontName(port.GetPortTextFont()), port.GetPortTextFace(), port.GetPortTextSize() | 
					
						
							| 
									
										
										
										
											1999-01-30 22:39:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) |