5 |
5 |
6 """ |
6 """ |
7 Module implementing an editor for binary data. |
7 Module implementing an editor for binary data. |
8 """ |
8 """ |
9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals, division |
11 try: |
11 try: |
12 chr = unichr # __IGNORE_EXCEPTION__ |
12 chr = unichr # __IGNORE_EXCEPTION__ |
13 except NameError: |
13 except NameError: |
14 pass |
14 pass |
|
15 |
|
16 import math |
15 |
17 |
16 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray, QTimer, QRect, \ |
18 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray, QTimer, QRect, \ |
17 QBuffer, QIODevice |
19 QBuffer, QIODevice |
18 from PyQt5.QtGui import QBrush, QPen, QColor, QFont, QPalette, QKeySequence, \ |
20 from PyQt5.QtGui import QBrush, QPen, QColor, QFont, QPalette, QKeySequence, \ |
19 QPainter |
21 QPainter |
96 # set read only mode on/off |
98 # set read only mode on/off |
97 self.__cursorPosition = 0 |
99 self.__cursorPosition = 0 |
98 # absolute position of cursor, 1 Byte == 2 tics |
100 # absolute position of cursor, 1 Byte == 2 tics |
99 |
101 |
100 self.__addrDigits = 0 |
102 self.__addrDigits = 0 |
|
103 self.__addrSeparators = 0 |
101 self.__blink = True |
104 self.__blink = True |
102 self.__bData = QBuffer() |
105 self.__bData = QBuffer() |
103 self.__cursorRect = QRect() |
106 self.__cursorRect = QRect() |
104 self.__cursorRectAscii = QRect() |
107 self.__cursorRectAscii = QRect() |
105 self.__dataShown = bytearray() |
108 self.__dataShown = bytearray() |
261 self.setCursorPosition(self.__cursorPosition) |
264 self.setCursorPosition(self.__cursorPosition) |
262 self.viewport().update() |
265 self.viewport().update() |
263 |
266 |
264 def addressWidth(self): |
267 def addressWidth(self): |
265 """ |
268 """ |
266 Public method to get the minimum width of the address area in |
269 Public method to get the width of the address area in |
267 characters. |
270 characters. |
|
271 |
|
272 Note: The address area width is always a multiple of four. |
268 |
273 |
269 @return minimum width of the address area |
274 @return minimum width of the address area |
270 @rtype int |
275 @rtype int |
271 """ |
276 """ |
272 size = self.__chunks.size() |
277 size = self.__chunks.size() |
281 n += 2 |
286 n += 2 |
282 size //= 0x100 |
287 size //= 0x100 |
283 if size > 0x10: |
288 if size > 0x10: |
284 n += 1 |
289 n += 1 |
285 size //= 0x10 |
290 size //= 0x10 |
|
291 n = int(math.ceil(n / 4)) * 4 |
286 |
292 |
287 if n > self.__addressWidth: |
293 if n > self.__addressWidth: |
288 return n |
294 return n |
289 else: |
295 else: |
290 return self.__addressWidth |
296 return self.__addressWidth |
291 |
297 |
292 def setAddressWidth(self, width): |
298 def setAddressWidth(self, width): |
293 """ |
299 """ |
294 Public method to set the width of the address area. |
300 Public method to set the width of the address area. |
295 |
301 |
|
302 Note: The address area width is always a multiple of four. |
|
303 The given value will be adjusted as required. |
|
304 |
296 @param width width of the address area in characters |
305 @param width width of the address area in characters |
297 @type int |
306 @type int |
298 """ |
307 """ |
299 self.__addressWidth = width |
308 self.__addressWidth = int(math.ceil(width / 4)) * 4 |
300 self.__adjust() |
309 self.__adjust() |
301 self.setCursorPosition(self.__cursorPosition) |
310 self.setCursorPosition(self.__cursorPosition) |
302 self.viewport().update() |
311 self.viewport().update() |
303 |
312 |
304 def asciiArea(self): |
313 def asciiArea(self): |
1350 self.replace(self.__bPosCurrent, |
1359 self.replace(self.__bPosCurrent, |
1351 self.__fromHex(hexValue)[0]) |
1360 self.__fromHex(hexValue)[0]) |
1352 |
1361 |
1353 self.setCursorPosition(self.__cursorPosition + 1) |
1362 self.setCursorPosition(self.__cursorPosition + 1) |
1354 self.__resetSelection(self.__cursorPosition) |
1363 self.__resetSelection(self.__cursorPosition) |
|
1364 # TODO: handle pressing keyboard modifier only by not calling __referesh |
1355 |
1365 |
1356 self.__refresh() |
1366 self.__refresh() |
1357 |
1367 |
1358 def mouseMoveEvent(self, evt): |
1368 def mouseMoveEvent(self, evt): |
1359 """ |
1369 """ |
1426 pxPosY = self.__pxCharHeight |
1436 pxPosY = self.__pxCharHeight |
1427 while row <= len(self.__dataShown) // self.BYTES_PER_LINE: |
1437 while row <= len(self.__dataShown) // self.BYTES_PER_LINE: |
1428 address = "{0:0{1}x}".format( |
1438 address = "{0:0{1}x}".format( |
1429 self.__bPosFirst + row * self.BYTES_PER_LINE, |
1439 self.__bPosFirst + row * self.BYTES_PER_LINE, |
1430 self.__addrDigits) |
1440 self.__addrDigits) |
|
1441 address = Globals.strGroup(address, ":", 4) |
1431 painter.drawText(self.__pxPosAdrX - pxOfsX, pxPosY, |
1442 painter.drawText(self.__pxPosAdrX - pxOfsX, pxPosY, |
1432 address) |
1443 address) |
1433 # increment loop variables |
1444 # increment loop variables |
1434 row += 1 |
1445 row += 1 |
1435 pxPosY += self.__pxCharHeight |
1446 pxPosY += self.__pxCharHeight |
1700 Private slot to recalculate pixel positions. |
1711 Private slot to recalculate pixel positions. |
1701 """ |
1712 """ |
1702 # recalculate graphics |
1713 # recalculate graphics |
1703 if self.__addressArea: |
1714 if self.__addressArea: |
1704 self.__addrDigits = self.addressWidth() |
1715 self.__addrDigits = self.addressWidth() |
1705 self.__pxPosHexX = self.__pxGapAdr + \ |
1716 self.__addrSeparators = self.__addrDigits // 4 - 1 |
1706 self.__addrDigits * self.__pxCharWidth + self.__pxGapAdrHex |
1717 self.__pxPosHexX = ( |
|
1718 self.__pxGapAdr + |
|
1719 (self.__addrDigits + self.__addrSeparators) * |
|
1720 self.__pxCharWidth + self.__pxGapAdrHex) |
1707 else: |
1721 else: |
1708 self.__pxPosHexX = self.__pxGapAdrHex |
1722 self.__pxPosHexX = self.__pxGapAdrHex |
1709 self.__pxPosAdrX = self.__pxGapAdr |
1723 self.__pxPosAdrX = self.__pxGapAdr |
1710 self.__pxPosAsciiX = self.__pxPosHexX + \ |
1724 self.__pxPosAsciiX = self.__pxPosHexX + \ |
1711 self.HEXCHARS_PER_LINE * self.__pxCharWidth + self.__pxGapHexAscii |
1725 self.HEXCHARS_PER_LINE * self.__pxCharWidth + self.__pxGapHexAscii |