Mercurial > lcfOS
view python/hexedit.py @ 134:1a50d6db24ed
Changes on hexedit
author | Windel Bouwman |
---|---|
date | Mon, 21 Jan 2013 20:24:40 +0100 |
parents | a816c683c1c0 |
children | 01d88140dc03 |
line wrap: on
line source
import sys from PyQt4.QtCore import * from PyQt4.QtGui import * BYTES_PER_LINE = 8 GAP = 16 class BinViewer(QWidget): """ The view has an address, hex byte and ascii column """ def __init__(self, scrollArea): super().__init__() self.setFont(QFont('Courier', 10)) self.setFocusPolicy(Qt.StrongFocus) self.blinkcursor = False self.cursorX = 0 self.cursorY = 0 self.scrollArea = scrollArea self.Data = bytearray() t = QTimer(self) t.timeout.connect(self.updateCursor) t.setInterval(500) t.start() def updateCursor(self): self.blinkcursor = not self.blinkcursor self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) def setCursorPosition(self, position): if position > len(self.Data) * 2 - 1: position = len(self.Data) * 2 - 1 if position < 0: position = 0 self.cursorPosition = position x = position % (2 * BYTES_PER_LINE) self.cursorX = self.xposHex + x * self.charWidth self.cursorY = int(position / (2 * BYTES_PER_LINE)) * self.charHeight + 4 self.blinkcursor = True self.update() def paintEvent(self, event): painter = QPainter(self) # Background: painter.fillRect(event.rect(), self.palette().color(QPalette.Base)) painter.fillRect(QRect(self.xposAddr, event.rect().top(), self.xposHex, self.height()), Qt.yellow) painter.setPen(Qt.black) # first and last index firstIndex = (int(event.rect().top() / self.charHeight) - self.charHeight) * BYTES_PER_LINE if firstIndex < 0: firstIndex = 0 lastIndex = (int(event.rect().bottom() / self.charHeight) + self.charHeight) * BYTES_PER_LINE if lastIndex < 0: lastIndex = 0 yposStart = int(firstIndex / BYTES_PER_LINE) * self.charHeight + self.charHeight ypos = yposStart for index in range(firstIndex, lastIndex, BYTES_PER_LINE): painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index)) xpos = self.xposHex for colIndex in range(BYTES_PER_LINE): if index + colIndex < len(self.Data): b = '{0:02X}'.format(self.Data[index + colIndex]) painter.drawText(xpos, ypos, b) xpos += 2 * self.charWidth ypos += self.charHeight # cursor if self.blinkcursor: painter.fillRect(self.cursorX, self.cursorY + self.charHeight - 2, self.charWidth, 2, Qt.blue) def keyPressEvent(self, event): if event.matches(QKeySequence.MoveToNextChar): self.setCursorPosition(self.cursorPosition + 1) if event.matches(QKeySequence.MoveToPreviousChar): self.setCursorPosition(self.cursorPosition - 1) if event.matches(QKeySequence.MoveToNextLine): self.setCursorPosition(self.cursorPosition + 2 * BYTES_PER_LINE) if event.matches(QKeySequence.MoveToPreviousLine): self.setCursorPosition(self.cursorPosition - 2 * BYTES_PER_LINE) self.ensureVisible() self.update() def ensureVisible(self): self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight, 3, self.charHeight / 2 + 2) def adjust(self): self.charHeight = self.fontMetrics().height() self.charWidth = self.fontMetrics().width('x') self.xposAddr = 2 self.xposHex = self.xposAddr + 8 * self.charWidth + GAP self.xposAscii = self.xposHex + (BYTES_PER_LINE * 3 - 1) * self.charWidth + GAP self.setMinimumWidth(self.xposAscii + self.charWidth * BYTES_PER_LINE) self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + 1) * self.charHeight) self.update() def getBytes(self, offset): return bytes() def setHexFile(self, hf): self.hexfile = hf self.update() def getData(self): return self.data def setData(self, d): self.data = d self.adjust() self.setCursorPosition(0) Data = property(getData, setData) class HexEdit(QScrollArea): def __init__(self): super().__init__() self.setWidgetResizable(True) self.bv = BinViewer(self) self.setWidget(self.bv) self.setFocusPolicy(Qt.NoFocus) if __name__ == '__main__': app = QApplication(sys.argv) he = HexEdit() he.show() he.bv.Data = bytearray(range(100)) * 8 app.exec()