Mercurial > lcfOS
comparison python/hexedit.py @ 140:104037b292cc
Added ui file for hexeditor
author | Windel Bouwman |
---|---|
date | Sun, 27 Jan 2013 12:16:09 +0100 |
parents | 2ec4d4332b7a |
children | 982ddb5f786d |
comparison
equal
deleted
inserted
replaced
139:2ec4d4332b7a | 140:104037b292cc |
---|---|
1 import sys | 1 import sys |
2 from PyQt4.QtCore import * | 2 from PyQt4.QtCore import * |
3 from PyQt4.QtGui import * | 3 from PyQt4.QtGui import * |
4 from PyQt4 import uic | |
4 | 5 |
5 BYTES_PER_LINE, GAP = 8, 12 | 6 BYTES_PER_LINE, GAP = 16, 12 |
6 | 7 |
7 def clamp(minimum, x, maximum): | 8 def clamp(minimum, x, maximum): |
8 return max(minimum, min(x, maximum)) | 9 return max(minimum, min(x, maximum)) |
9 | 10 |
10 def asciiChar(v): | 11 def asciiChar(v): |
16 class BinViewer(QWidget): | 17 class BinViewer(QWidget): |
17 """ The view has an address, hex byte and ascii column """ | 18 """ The view has an address, hex byte and ascii column """ |
18 def __init__(self, scrollArea): | 19 def __init__(self, scrollArea): |
19 super().__init__(scrollArea) | 20 super().__init__(scrollArea) |
20 self.scrollArea = scrollArea | 21 self.scrollArea = scrollArea |
21 self.setFont(QFont('Courier', 18)) | 22 self.setFont(QFont('Courier', 16)) |
22 self.setFocusPolicy(Qt.StrongFocus) | 23 self.setFocusPolicy(Qt.StrongFocus) |
23 self.blinkcursor = False | 24 self.blinkcursor = False |
24 self.cursorX = self.cursorY = 0 | 25 self.cursorX = self.cursorY = 0 |
25 self.scrollArea = scrollArea | 26 self.scrollArea = scrollArea |
26 self.Data = bytearray() | 27 self.Data = bytearray() |
68 yposStart = int(firstIndex / BYTES_PER_LINE) * chh + chh | 69 yposStart = int(firstIndex / BYTES_PER_LINE) * chh + chh |
69 # Draw contents: | 70 # Draw contents: |
70 painter.setPen(Qt.black) | 71 painter.setPen(Qt.black) |
71 ypos = yposStart | 72 ypos = yposStart |
72 for index in range(firstIndex, lastIndex, BYTES_PER_LINE): | 73 for index in range(firstIndex, lastIndex, BYTES_PER_LINE): |
74 painter.setPen(Qt.black) | |
73 painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index + self.Offset)) | 75 painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index + self.Offset)) |
74 xpos = self.xposHex | 76 xpos = self.xposHex |
75 xposAscii = self.xposAscii | 77 xposAscii = self.xposAscii |
76 for colIndex in range(BYTES_PER_LINE): | 78 for colIndex in range(BYTES_PER_LINE): |
77 if index + colIndex < len(self.Data): | 79 if index + colIndex < len(self.Data): |
78 b = self.Data[index + colIndex] | 80 b = self.Data[index + colIndex] |
81 bo = self.originalData[index + colIndex] | |
82 if b == bo: | |
83 painter.setPen(Qt.black) | |
84 else: | |
85 painter.setPen(Qt.red) | |
79 painter.drawText(xpos, ypos, '{0:02X}'.format(b)) | 86 painter.drawText(xpos, ypos, '{0:02X}'.format(b)) |
80 painter.drawText(xposAscii, ypos, asciiChar(b)) | 87 painter.drawText(xposAscii, ypos, asciiChar(b)) |
81 xpos += 3 * chw | 88 xpos += 3 * chw |
82 xposAscii += chw | 89 xposAscii += chw |
83 ypos += chh | 90 ypos += chh |
134 r = 1 if r > 0 else 0 | 141 r = 1 if r > 0 else 0 |
135 self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4) | 142 self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4) |
136 self.scrollArea.setMinimumHeight(self.charHeight * 8) | 143 self.scrollArea.setMinimumHeight(self.charHeight * 8) |
137 self.update() | 144 self.update() |
138 def setData(self, d): | 145 def setData(self, d): |
139 self.data = d | 146 self.data = bytearray(d) |
147 self.originalData = bytearray(d) | |
140 self.adjust() | 148 self.adjust() |
141 self.setCursorPosition(0) | 149 self.setCursorPosition(0) |
142 Data = property(lambda self: self.data, setData) | 150 Data = property(lambda self: self.data, setData) |
143 | 151 |
144 class HexEdit(QScrollArea): | 152 class HexEdit(QScrollArea): |
148 self.setWidget(self.bv) | 156 self.setWidget(self.bv) |
149 self.setWidgetResizable(True) | 157 self.setWidgetResizable(True) |
150 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) | 158 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) |
151 self.setFocusPolicy(Qt.NoFocus) | 159 self.setFocusPolicy(Qt.NoFocus) |
152 | 160 |
161 class HexEditor(QMainWindow): | |
162 def __init__(self): | |
163 super().__init__() | |
164 uic.loadUi('hexeditor.ui', baseinstance=self) | |
165 self.he = HexEdit() | |
166 self.setCentralWidget(self.he) | |
167 self.actionOpen.triggered.connect(self.doOpen) | |
168 self.actionSave.triggered.connect(self.doSave) | |
169 self.actionSaveAs.triggered.connect(self.doSaveAs) | |
170 self.fileName = None | |
171 self.updateControls() | |
172 def updateControls(self): | |
173 s = True if self.fileName else False | |
174 self.actionSave.setEnabled(s) | |
175 self.actionSaveAs.setEnabled(s) | |
176 def doOpen(self): | |
177 filename = QFileDialog.getOpenFileName(self) | |
178 if filename: | |
179 with open(filename, 'rb') as f: | |
180 self.he.bv.Data = f.read() | |
181 self.fileName = filename | |
182 self.updateControls() | |
183 def doSave(self): | |
184 self.updateControls() | |
185 def doSaveAs(self): | |
186 filename = QFileDialog.getSaveFileName(self) | |
187 if filename: | |
188 with open(filename, 'wb') as f: | |
189 f.write(self.he.bv.Data) | |
190 self.fileName = filename | |
191 self.updateControls() | |
192 | |
153 if __name__ == '__main__': | 193 if __name__ == '__main__': |
154 app = QApplication(sys.argv) | 194 app = QApplication(sys.argv) |
155 he = HexEdit() | 195 he = HexEditor() |
156 he.show() | 196 he.show() |
157 he.bv.Data = bytearray(range(100)) * 8 + b'x' | 197 #he.bv.Data = bytearray(range(100)) * 8 + b'x' |
158 app.exec() | 198 app.exec() |
159 | 199 |