from FrameWork import * import Win import Qd import Controls import Ctl import TE import List import os import string import macfs SCROLLBAR=16 MARGIN=2 ICONSIZE=16 TEXTWIDTH=4096 # More-or-less random value PIC_CURRENT=512 PIC_BREAK=513 picture_cache={} class MT_TextWidget: def __init__(self, wid, r): self.wid = wid self.rect = r left, top, right, bottom = r self.terect = left+MARGIN+ICONSIZE, top+MARGIN, \ right-(MARGIN+SCROLLBAR), bottom-(MARGIN+SCROLLBAR) dr = self.terect[0], self.terect[1], TEXTWIDTH, self.terect[3] Qd.SetPort(wid) Qd.TextFont(4) Qd.TextSize(9) self.ted = TE.TENew(dr, self.terect) self.ted.TEAutoView(1) self.activate(1) rect = right-SCROLLBAR, top, right, bottom-SCROLLBAR+1 self.bary = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0) rect = left, bottom-SCROLLBAR, right-SCROLLBAR+1, bottom self.barx = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0) self.have_data = 0 self.line_index = [] def close(self): del self.barx del self.bary del self.ted def scrollbars(self): pass def setcontent(self, file): self.line_index = [] if file == None: data = '' self.have_data = 0 else: try: fp = open(file, 'rb') # NOTE the binary data = fp.read() self.have_data = 1 except IOError, arg: data = 'Cannot open file:\r'+`arg` self.have_data = 0 if len(data) > 32767: self.have_data = 0 data = 'File too big' self.ted.TESetText(data) if self.have_data: cur = 0 while 1: self.line_index.append(cur) try: cur = string.index(data, '\r', cur+1) except ValueError: break self.line_index.append(len(data)) Win.InvalRect(self.rect) self.ted.TESetSelect(0,0) self.ted.TECalText() self.ted.TESelView() self.setscrollbars() def setscrollbars(self): docleft, doctop, docright, docbot = self.ted.destRect winleft, wintop, winright, winbot = self.ted.viewRect docbot = self.ted.nLines*self.ted.lineHeight + doctop self.setbar(self.barx, docleft, docright, winleft, winright) self.setbar(self.bary, doctop, docbot, wintop, winbot) def setbar(self, bar, minmin, maxmax, curmin, curmax): if maxmax-minmin > 32767 or (curmin <= minmin and curmax >= maxmax): bar.SetControlMinimum(0) bar.SetControlMaximum(0) bar.SetControlValue(0) return bar.SetControlMinimum(minmin) bar.SetControlMaximum(maxmax-(curmax-curmin)) bar.SetControlValue(curmin) def update(self, rgn): Qd.EraseRect(self.terect) Qd.FrameRect(self.rect) self.ted.TEUpdate(self.terect) def activate(self, onoff): if onoff: self.ted.TEActivate() else: self.ted.TEDeactivate() def select(self, line): if line == None or line <= 0 or not self.have_data: self.ted.TESetSelect(0,0) else: line = line - 1 if line > len(self.line_index)-1: line = len(self.line_index)-1 if line == 1: self.ted.TESetSelect(0, self.line_index[1]) else: self.ted.TESetSelect(self.line_index[line]+1, self.line_index[line+1]) self.setscrollbars() def click(self, where, modifiers): # First check scrollbars ctltype, control = Ctl.FindControl(where, self.wid) if ctltype and control: partcode = control.TrackControl(where) if partcode: self.controlhit(control, partcode) return None, 0 off = self.ted.TEGetOffset(where) inborder = where[0] < self.terect[0] return self.offsettoline(off), inborder def offsettoline(self, offset): for i in range(len(self.line_index)): if offset < self.line_index[i]: return i # Not i-1: 1-based line numbers in files return None def controlhit(self, control, partcode): if partcode <> Controls.inThumb: if control == self.barx: if partcode == Controls.inUpButton: delta = -10 if partcode == Controls.inDownButton: delta = 10 if partcode == Controls.inPageUp: delta = 10-(self.terect[2]-self.terect[0]) if partcode == Controls.inPageDown: delta = (self.terect[2]-self.terect[0])-10 old = control.GetControlValue() control.SetControlValue(old+delta) if control == self.bary: if partcode == Controls.inUpButton: delta = -self.ted.lineHeight if partcode == Controls.inDownButton: delta = self.ted.lineHeight if partcode == Controls.inPageUp: delta = self.ted.lineHeight-(self.terect[3]-self.terect[1]) if partcode == Controls.inPageDown: delta = (self.terect[3]-self.terect[1])-self.ted.lineHeight old = control.GetControlValue() control.SetControlValue(old+delta) newx = self.barx.GetControlValue() newy = self.bary.GetControlValue() oldx = self.ted.viewRect[0] oldy = self.ted.viewRect[1] self.ted.TEPinScroll(oldx-newx, oldy-newy) self.setscrollbars() # XXXX Bibbert, maar hoe anders? class MT_IconTextWidget(MT_TextWidget): def __init__(self, wid, r): MT_TextWidget.__init__(self, wid, r) self.breakpointlist = [] self.curline = None self.iconrect = (self.rect[0]+1, self.rect[1]+1, self.terect[0]-1, self.terect[3]-1) self.curlinerange = (self.terect[1]+self.ted.lineHeight, self.terect[3]-2*self.ted.lineHeight) def setbreaks(self, list): self.breakpointlist = list[:] Qd.SetPort(self.wid) Win.InvalRect(self.iconrect) def setcurline(self, line): self.curline = line Qd.SetPort(self.wid) self.showline(line) def showline(self, line): if line <= 0: line = 1 if line >= len(self.line_index): line = len(self.line_index)-1 if line < 0: return off = self.line_index[line] x, y = self.ted.TEGetPoint(off) if self.curlinerange[0] <= y <= self.curlinerange[1]: return # It is in view middle = (self.curlinerange[0]+self.curlinerange[1])/2 self.ted.TEPinScroll(0, middle-y) # Of andersom? self.setscrollbars() def setscrollbars(self): MT_TextWidget.setscrollbars(self) Win.InvalRect(self.iconrect) def update(self, rgn): MT_TextWidget.update(self, rgn) self.drawallicons() def drawallicons(self): Qd.EraseRect(self.iconrect) Qd.MoveTo(self.iconrect[2], self.iconrect[1]) Qd.LineTo(self.iconrect[2], self.iconrect[3]) topoffset = self.ted.TEGetOffset((self.terect[0], self.terect[1])) botoffset = self.ted.TEGetOffset((self.terect[0], self.terect[3])) topline = self.offsettoline(topoffset) botline = self.offsettoline(botoffset) if topline == None: topline = 1 # ??? if botline == None: botline = len(self.line_index) for i in self.breakpointlist: if topline <= i <= botline: self.draw1icon(i, PIC_BREAK) if self.curline <> None and topline <= self.curline <= botline: self.draw1icon(self.curline, PIC_CURRENT) def draw1icon(self, line, which): offset = self.line_index[line] botx, boty = self.ted.TEGetPoint(offset) rect = self.rect[0]+2, boty-self.ted.lineHeight, \ self.rect[0]+ICONSIZE-2, boty if not picture_cache.has_key(which): print 'Get picture', which picture_cache[which] = Qd.GetPicture(which) self.drawicon(rect, picture_cache[which]) def drawicon(self, rect, which): Qd.DrawPicture(which, rect) class MT_IndexList: def __init__(self, wid, rect, width): # wid is the window (dialog) where our list is going to be in # rect is it's item rectangle (as in dialog item) self.rect = rect rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1 self.list = List.LNew(rect2, (0, 0, width, 0), (0,0), 0, wid, 0, 1, 0, 1) self.wid = wid self.width = width def setcontent(self, *content): self.list.LDelRow(0, 1) self.list.LSetDrawingMode(0) self.list.LAddRow(len(content[0]), 0) for x in range(len(content)): column = content[x] for y in range(len(column)): self.list.LSetCell(column[y], (x, y)) self.list.LSetDrawingMode(1) Win.InvalRect(self.rect) def deselectall(self): while 1: ok, pt = self.list.LGetSelect(1, (0,0)) if not ok: return self.list.LSetSelect(0, pt) def select(self, num): self.deselectall() if num < 0: return for i in range(self.width): self.list.LSetSelect(1, (i, num)) def click(self, where, modifiers): is_double = self.list.LClick(where, modifiers) ok, (x, y) = self.list.LGetSelect(1, (0, 0)) if ok: return y, is_double else: return None, is_double # draw a frame around the list, List Manager doesn't do that def drawframe(self): Qd.SetPort(self.wid) Qd.FrameRect(self.rect) def update(self, rgn): self.drawframe() self.list.LUpdate(rgn) def activate(self, onoff): self.list.LActivate(onoff) class MT_AnyList(MT_IndexList): def click(self, where, modifiers): is_double = self.list.LClick(where, modifiers) ok, (x, y) = self.list.LGetSelect(1, (0, 0)) if ok: self.select(y) field0 = self.list.LGetCell(1000,(0,y)) else: field0 = None return field0, is_double