# HG changeset patch # User Windel Bouwman # Date 1358799156 -3600 # Node ID 01d88140dc03bd4501a703d197dfc9ed4b52a91d # Parent 1a50d6db24ed986336523eca003f8a36d3d0e522 Improve hexedit diff -r 1a50d6db24ed -r 01d88140dc03 python/hexedit.py --- a/python/hexedit.py Mon Jan 21 20:24:40 2013 +0100 +++ b/python/hexedit.py Mon Jan 21 21:12:36 2013 +0100 @@ -8,8 +8,9 @@ class BinViewer(QWidget): """ The view has an address, hex byte and ascii column """ def __init__(self, scrollArea): - super().__init__() - self.setFont(QFont('Courier', 10)) + super().__init__(scrollArea) + self.scrollArea = scrollArea + self.setFont(QFont('Courier', 18)) self.setFocusPolicy(Qt.StrongFocus) self.blinkcursor = False self.cursorX = 0 @@ -24,6 +25,7 @@ self.blinkcursor = not self.blinkcursor self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) def setCursorPosition(self, position): + position = int(position) if position > len(self.Data) * 2 - 1: position = len(self.Data) * 2 - 1 if position < 0: @@ -34,11 +36,17 @@ self.cursorY = int(position / (2 * BYTES_PER_LINE)) * self.charHeight + 4 self.blinkcursor = True self.update() + def getCursorPosition(self): + return self.cursorPosition + CursorPosition = property(getCursorPosition, setCursorPosition) 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.fillRect(QRect(self.xposAddr, event.rect().top(), self.xposHex, self.height()), Qt.gray) + painter.setPen(Qt.gray) + x = self.xposAscii - (GAP / 2) + painter.drawLine(x, event.rect().top(), x, self.height()) painter.setPen(Qt.black) # first and last index @@ -55,43 +63,63 @@ painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index)) xpos = self.xposHex + xposA = self.xposAscii 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) + b = self.Data[index + colIndex] + bhex = '{0:02X}'.format(b) + ba = chr(b) + painter.drawText(xpos, ypos, bhex) + painter.drawText(xposA, ypos, ba) xpos += 2 * self.charWidth + xposA += self.charWidth ypos += self.charHeight # cursor if self.blinkcursor: - painter.fillRect(self.cursorX, self.cursorY + self.charHeight - 2, self.charWidth, 2, Qt.blue) + painter.fillRect(self.cursorX, self.cursorY + self.charHeight - 2, self.charWidth, 2, Qt.black) def keyPressEvent(self, event): if event.matches(QKeySequence.MoveToNextChar): - self.setCursorPosition(self.cursorPosition + 1) + self.CursorPosition += 1 if event.matches(QKeySequence.MoveToPreviousChar): - self.setCursorPosition(self.cursorPosition - 1) + self.CursorPosition -= 1 if event.matches(QKeySequence.MoveToNextLine): - self.setCursorPosition(self.cursorPosition + 2 * BYTES_PER_LINE) + self.CursorPosition += 2 * BYTES_PER_LINE if event.matches(QKeySequence.MoveToPreviousLine): - self.setCursorPosition(self.cursorPosition - 2 * BYTES_PER_LINE) - self.ensureVisible() + self.CursorPosition -= 2 * BYTES_PER_LINE + char = event.text().lower() + if char and char in '0123456789abcdef': + i = int(self.CursorPosition / 2) + hb = self.CursorPosition % 2 + v = int(char, 16) + if hb == 0: + # high half byte + self.data[i] = (self.data[i] & 0xF) | (v << 4) + else: + self.data[i] = (self.data[i] & 0xF0) | v + self.CursorPosition += 1 + self.scrollArea.ensureVisible(self.cursorX, self.cursorY, self.charWidth, self.charHeight + 2) self.update() - def ensureVisible(self): - self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight, 3, self.charHeight / 2 + 2) + def cursorPositionAt(self, pos): + """ Calculate cursor position at a certain point """ + if pos.x() > self.xposHex and pos.x() < self.xposAscii: + x = (pos.x() - self.xposHex) / self.charWidth + y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE + return x + y + return 0 + def mousePressEvent(self, event): + cpos = self.cursorPositionAt(event.pos()) + self.setCursorPosition(cpos) 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.xposAscii = self.xposHex + (BYTES_PER_LINE * 2) * self.charWidth + GAP self.setMinimumWidth(self.xposAscii + self.charWidth * BYTES_PER_LINE) + self.scrollArea.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): @@ -103,15 +131,15 @@ class HexEdit(QScrollArea): def __init__(self): super().__init__() - self.setWidgetResizable(True) self.bv = BinViewer(self) self.setWidget(self.bv) + self.setWidgetResizable(True) self.setFocusPolicy(Qt.NoFocus) if __name__ == '__main__': app = QApplication(sys.argv) he = HexEdit() he.show() - he.bv.Data = bytearray(range(100)) * 8 + he.bv.Data = bytearray(range(100)) * 8 + b'hjkfd' app.exec()