Like other things posted here without notices to the contrary, this code is in the public domain.
This is a relatively responsive pager program for text files, much like 'more' or 'less', but in a GUI, so it zooms in and out with the + and - keys. It's written in Python with PyQt. #!/usr/bin/python import qt, sys, time, qd class mailviewer(qt.QWidget): def __init__(self, filename, parent=None): qt.QWidget.__init__(self, parent, None, qt.Qt.WStaticContents | qt.Qt.WRepaintNoErase) self.fontSize = 10 self.setFont() self.setEraseColor(self.white) self.setFocusPolicy(qt.QWidget.StrongFocus) self.file = file(filename) self.filePos = 0 self.prevPoses = [] self.startTime = time.time() def setFont(self): # to get this font name, I used this to select from the dialog box: # self.font, ok = qt.QFontDialog.getFont(self.font) # It's Palatino. self.font = qt.QFont('Urw Palladio l', self.fontSize) def adjustFontSize(self, delta): self.fontSize += delta self.setFont() self.update() def pageUp(self): if self.prevPoses: self.filePos = self.prevPoses.pop() self.update() def pageDown(self): self.prevPoses.append(self.filePos) self.filePos = self.newPos self.update() def keyPressEvent(self, ev): self.startTime = time.time() key = ev.key() if key in [qt.Qt.Key_Plus, qt.Qt.Key_Equal]: self.adjustFontSize(delta = +2) elif key in [qt.Qt.Key_Minus]: self.adjustFontSize(delta = -2) elif key in [qt.Qt.Key_Next, qt.Qt.Key_Space]: self.pageDown() elif key in [qt.Qt.Key_Prior, qt.Qt.Key_Backspace]: self.pageUp() else: self.startTime = None ev.ignore() return ev.accept() def lineReader(self): self.file.seek(self.filePos) return iter(self.file) def paintEvent(self, ev): if self.startTime is None: self.startTime = time.time() pix = qt.QPixmap(self.size()) pix.fill(self, 0, 0) pa = qt.QPainter(pix) pa.setFont(self.font) linespacing = pa.fontMetrics().lineSpacing() y = linespacing lines = self.lineReader() height = self.height() try: self.newPos = self.filePos while y < height + linespacing: rawline = lines.next() self.newPos += len(rawline) pa.drawText(10, y, qd.chomp(qd.untabify(rawline))) y += linespacing except StopIteration: pass # ran out of lines! pa.end() npa = qt.QPainter(self) npa.drawPixmap(0, 0, pix) npa.setFont(qt.QFont('Helvetica', 10)) npa.setPen(self.darkGray) npa.drawText(self.width() - 40, npa.fontMetrics().lineSpacing(), str(time.time() - self.startTime)) if __name__ == '__main__': a = qt.QApplication(sys.argv) w = mailviewer(sys.argv[1]) a.setMainWidget (w) w.show() w.setFocus() a.exec_loop() Here's qd.py, which it depends on: def chomp(text): while text[-1:] in ['\r', '\n']: text = text[:-1] return text assert chomp('a\n') == 'a' assert chomp('\n') == '' assert chomp('') == '' def untabify(text): def dumb_tab_exp(char): if char != '\t': return char return ' ' return ''.join(map(dumb_tab_exp, text))