comparison python/ide/hexedit.py @ 333:dcae6574c974

Increment to qt5
author Windel Bouwman
date Sun, 09 Feb 2014 15:27:57 +0100
parents 7b38782ed496
children 11c5a8a70c02
comparison
equal deleted inserted replaced
332:87feb8a23b4d 333:dcae6574c974
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 import sys 3 import sys
4 import os 4 import os
5 from PyQt4.QtCore import * 5 from qtwrapper import QtGui, QtCore, QtWidgets, Qt
6 from PyQt4.QtGui import * 6
7 from PyQt4 import uic
8 7
9 BYTES_PER_LINE, GAP = 8, 12 8 BYTES_PER_LINE, GAP = 8, 12
10 9
11 def clamp(minimum, x, maximum): 10 def clamp(minimum, x, maximum):
12 return max(minimum, min(x, maximum)) 11 return max(minimum, min(x, maximum))
15 if v < 0x20 or v > 0x7e: 14 if v < 0x20 or v > 0x7e:
16 return '.' 15 return '.'
17 else: 16 else:
18 return chr(v) 17 return chr(v)
19 18
20 class BinViewer(QWidget): 19 class BinViewer(QtWidgets.QWidget):
21 """ The view has an address, hex byte and ascii column """ 20 """ The view has an address, hex byte and ascii column """
22 def __init__(self, scrollArea): 21 def __init__(self, scrollArea):
23 super().__init__(scrollArea) 22 super().__init__(scrollArea)
24 self.scrollArea = scrollArea 23 self.scrollArea = scrollArea
25 self.setFont(QFont('Courier', 16)) 24 self.setFont(QtGui.QFont('Courier', 16))
26 self.setFocusPolicy(Qt.StrongFocus) 25 self.setFocusPolicy(Qt.StrongFocus)
27 self.blinkcursor = False 26 self.blinkcursor = False
28 self.cursorX = self.cursorY = 0 27 self.cursorX = self.cursorY = 0
29 self.scrollArea = scrollArea 28 self.scrollArea = scrollArea
30 self.Data = bytearray() 29 self.Data = bytearray()
31 self.Offset = 0 30 self.Offset = 0
32 t = QTimer(self) 31 t = QtCore.QTimer(self)
33 t.timeout.connect(self.updateCursor) 32 t.timeout.connect(self.updateCursor)
34 t.setInterval(500) 33 t.setInterval(500)
35 t.start() 34 t.start()
35
36 def updateCursor(self): 36 def updateCursor(self):
37 self.blinkcursor = not self.blinkcursor 37 self.blinkcursor = not self.blinkcursor
38 self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) 38 self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
39
39 def setCursorPosition(self, position): 40 def setCursorPosition(self, position):
40 position = clamp(0, int(position), len(self.Data) * 2 - 1) 41 position = clamp(0, int(position), len(self.Data) * 2 - 1)
41 self.cursorPosition = position 42 self.cursorPosition = position
42 x = position % (2 * BYTES_PER_LINE) 43 x = position % (2 * BYTES_PER_LINE)
43 x = x + int(x / 2) # Create a gap between hex values 44 x = x + int(x / 2) # Create a gap between hex values
44 self.cursorX = self.xposHex + x * self.charWidth 45 self.cursorX = self.xposHex + x * self.charWidth
45 y = int(position / (2 * BYTES_PER_LINE)) 46 y = int(position / (2 * BYTES_PER_LINE))
46 self.cursorY = y * self.charHeight + 2 47 self.cursorY = y * self.charHeight + 2
47 self.blinkcursor = True 48 self.blinkcursor = True
48 self.update() 49 self.update()
50
49 def getCursorPosition(self): 51 def getCursorPosition(self):
50 return self.cursorPosition 52 return self.cursorPosition
51 CursorPosition = property(getCursorPosition, setCursorPosition) 53 CursorPosition = property(getCursorPosition, setCursorPosition)
52 def setOffset(self, off): 54 def setOffset(self, off):
53 self.offset = off 55 self.offset = off
54 self.update() 56 self.update()
57
55 Offset = property(lambda self: self.offset, setOffset) 58 Offset = property(lambda self: self.offset, setOffset)
56 def paintEvent(self, event): 59 def paintEvent(self, event):
57 # Helper variables: 60 # Helper variables:
58 er = event.rect() 61 er = event.rect()
59 chw, chh = self.charWidth, self.charHeight 62 chw, chh = self.charWidth, self.charHeight
60 painter = QPainter(self) 63 painter = QtGui.QPainter(self)
61 # Background: 64 # Background:
62 painter.fillRect(er, self.palette().color(QPalette.Base)) 65 painter.fillRect(er, self.palette().color(QtGui.QPalette.Base))
63 painter.fillRect(QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray) 66 painter.fillRect(QtCore.QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
64 painter.setPen(Qt.gray) 67 painter.setPen(Qt.gray)
65 x = self.xposAscii - (GAP / 2) 68 x = self.xposAscii - (GAP / 2)
66 painter.drawLine(x, er.top(), x, er.bottom()) 69 painter.drawLine(x, er.top(), x, er.bottom())
67 x = self.xposEnd - (GAP / 2) 70 x = self.xposEnd - (GAP / 2)
68 painter.drawLine(x, er.top(), x, er.bottom()) 71 painter.drawLine(x, er.top(), x, er.bottom())
92 xposAscii += chw 95 xposAscii += chw
93 ypos += chh 96 ypos += chh
94 # cursor 97 # cursor
95 if self.blinkcursor: 98 if self.blinkcursor:
96 painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black) 99 painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black)
100
97 def keyPressEvent(self, event): 101 def keyPressEvent(self, event):
98 if event.matches(QKeySequence.MoveToNextChar): 102 if event.matches(QKeySequence.MoveToNextChar):
99 self.CursorPosition += 1 103 self.CursorPosition += 1
100 if event.matches(QKeySequence.MoveToPreviousChar): 104 if event.matches(QKeySequence.MoveToPreviousChar):
101 self.CursorPosition -= 1 105 self.CursorPosition -= 1
120 else: 124 else:
121 self.data[i] = (self.data[i] & 0xF0) | v 125 self.data[i] = (self.data[i] & 0xF0) | v
122 self.CursorPosition += 1 126 self.CursorPosition += 1
123 self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight / 2, 4, self.charHeight / 2 + 4) 127 self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight / 2, 4, self.charHeight / 2 + 4)
124 self.update() 128 self.update()
129
125 def setCursorPositionAt(self, pos): 130 def setCursorPositionAt(self, pos):
126 """ Calculate cursor position at a certain point """ 131 """ Calculate cursor position at a certain point """
127 if pos.x() > self.xposHex and pos.x() < self.xposAscii: 132 if pos.x() > self.xposHex and pos.x() < self.xposAscii:
128 x = round((2 * (pos.x() - self.xposHex)) / (self.charWidth * 3)) 133 x = round((2 * (pos.x() - self.xposHex)) / (self.charWidth * 3))
129 y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE 134 y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE
130 self.setCursorPosition(x + y) 135 self.setCursorPosition(x + y)
136
131 def mousePressEvent(self, event): 137 def mousePressEvent(self, event):
132 self.setCursorPositionAt(event.pos()) 138 self.setCursorPositionAt(event.pos())
139
133 def adjust(self): 140 def adjust(self):
134 self.charHeight = self.fontMetrics().height() 141 self.charHeight = self.fontMetrics().height()
135 self.charWidth = self.fontMetrics().width('x') 142 self.charWidth = self.fontMetrics().width('x')
136 self.xposAddr = GAP 143 self.xposAddr = GAP
137 self.xposHex = self.xposAddr + 8 * self.charWidth + GAP 144 self.xposHex = self.xposAddr + 8 * self.charWidth + GAP
144 r = len(self.Data) % BYTES_PER_LINE 151 r = len(self.Data) % BYTES_PER_LINE
145 r = 1 if r > 0 else 0 152 r = 1 if r > 0 else 0
146 self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4) 153 self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4)
147 self.scrollArea.setMinimumHeight(self.charHeight * 8) 154 self.scrollArea.setMinimumHeight(self.charHeight * 8)
148 self.update() 155 self.update()
156
149 def showEvent(self, e): 157 def showEvent(self, e):
150 self.adjust() 158 self.adjust()
151 super().showEvent(e) 159 super().showEvent(e)
160
152 def setData(self, d): 161 def setData(self, d):
153 self.data = bytearray(d) 162 self.data = bytearray(d)
154 self.originalData = bytearray(d) 163 self.originalData = bytearray(d)
155 self.adjust() 164 self.adjust()
156 self.setCursorPosition(0) 165 self.setCursorPosition(0)
157 Data = property(lambda self: self.data, setData) 166 Data = property(lambda self: self.data, setData)
158 167
159 class HexEdit(QScrollArea): 168
169 class HexEdit(QtWidgets.QScrollArea):
160 def __init__(self): 170 def __init__(self):
161 super().__init__() 171 super().__init__()
162 self.bv = BinViewer(self) 172 self.bv = BinViewer(self)
163 self.setWidget(self.bv) 173 self.setWidget(self.bv)
164 self.setWidgetResizable(True) 174 self.setWidgetResizable(True)
165 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 175 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
166 self.setFocusPolicy(Qt.NoFocus) 176 self.setFocusPolicy(Qt.NoFocus)
167 177
168 class HexEditor(QMainWindow): 178
179 class HexEditor(QtWidgets.QMainWindow):
169 def __init__(self): 180 def __init__(self):
170 super().__init__() 181 super().__init__()
171 basedir = os.path.dirname(__file__) 182 basedir = os.path.dirname(__file__)
172 uic.loadUi(os.path.join(basedir, 'hexeditor.ui'), baseinstance=self) 183 uic.loadUi(os.path.join(basedir, 'hexeditor.ui'), baseinstance=self)
173 self.he = HexEdit() 184 self.he = HexEdit()
196 with open(filename, 'wb') as f: 207 with open(filename, 'wb') as f:
197 f.write(self.he.bv.Data) 208 f.write(self.he.bv.Data)
198 self.fileName = filename 209 self.fileName = filename
199 self.updateControls() 210 self.updateControls()
200 211
212
201 if __name__ == '__main__': 213 if __name__ == '__main__':
202 app = QApplication(sys.argv) 214 app = QApplication(sys.argv)
203 he = HexEditor() 215 he = HexEditor()
204 he.show() 216 he.show()
205 #he.bv.Data = bytearray(range(100)) * 8 + b'x' 217 #he.bv.Data = bytearray(range(100)) * 8 + b'x'
206 app.exec() 218 app.exec()
207