eric6/HexEdit/HexEditWidget.py

changeset 7254
f00d825fbdb3
parent 7229
53054eb5b15a
child 7360
9190402e4505
equal deleted inserted replaced
7253:50dbe65a1334 7254:f00d825fbdb3
7 Module implementing an editor for binary data. 7 Module implementing an editor for binary data.
8 """ 8 """
9 9
10 import math 10 import math
11 11
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray, QTimer, QRect, \ 12 from PyQt5.QtCore import (
13 QBuffer, QIODevice 13 pyqtSignal, pyqtSlot, Qt, QByteArray, QTimer, QRect, QBuffer, QIODevice
14 from PyQt5.QtGui import QBrush, QPen, QColor, QFont, QPalette, QKeySequence, \ 14 )
15 QPainter 15 from PyQt5.QtGui import (
16 QBrush, QPen, QColor, QFont, QPalette, QKeySequence, QPainter
17 )
16 from PyQt5.QtWidgets import QAbstractScrollArea, QApplication 18 from PyQt5.QtWidgets import QAbstractScrollArea, QApplication
17 19
18 from .HexEditChunks import HexEditChunks 20 from .HexEditChunks import HexEditChunks
19 from .HexEditUndoStack import HexEditUndoStack 21 from .HexEditUndoStack import HexEditUndoStack
20 22
725 """ 727 """
726 result = -1 728 result = -1
727 if (point.x() >= self.__pxPosHexX) and ( 729 if (point.x() >= self.__pxPosHexX) and (
728 point.x() < (self.__pxPosHexX + (1 + self.HEXCHARS_PER_LINE) * 730 point.x() < (self.__pxPosHexX + (1 + self.HEXCHARS_PER_LINE) *
729 self.__pxCharWidth)): 731 self.__pxCharWidth)):
730 x = (point.x() - self.__pxPosHexX - self.__pxCharWidth // 2) // \ 732 x = (
733 (point.x() - self.__pxPosHexX - self.__pxCharWidth // 2) //
731 self.__pxCharWidth 734 self.__pxCharWidth
735 )
732 x = (x // 3) * 2 + x % 3 736 x = (x // 3) * 2 + x % 3
733 y = ((point.y() - 3) // self.__pxCharHeight) * 2 * \ 737 y = (
738 ((point.y() - 3) // self.__pxCharHeight) * 2 *
734 self.BYTES_PER_LINE 739 self.BYTES_PER_LINE
740 )
735 result = self.__bPosFirst * 2 + x + y 741 result = self.__bPosFirst * 2 + x + y
736 return result 742 return result
737 743
738 def ensureVisible(self): 744 def ensureVisible(self):
739 """ 745 """
995 1001
996 def selectToEndOfLine(self): 1002 def selectToEndOfLine(self):
997 """ 1003 """
998 Public method to extend the selection to the end of line. 1004 Public method to extend the selection to the end of line.
999 """ 1005 """
1000 pos = self.__cursorPosition - \ 1006 pos = (
1001 (self.__cursorPosition % (2 * self.BYTES_PER_LINE)) + \ 1007 self.__cursorPosition -
1008 (self.__cursorPosition % (2 * self.BYTES_PER_LINE)) +
1002 2 * self.BYTES_PER_LINE 1009 2 * self.BYTES_PER_LINE
1010 )
1003 self.setCursorPosition(pos) 1011 self.setCursorPosition(pos)
1004 self.__setSelection(pos) 1012 self.__setSelection(pos)
1005 1013
1006 def selectToStartOfLine(self): 1014 def selectToStartOfLine(self):
1007 """ 1015 """
1008 Public method to extend the selection to the start of line. 1016 Public method to extend the selection to the start of line.
1009 """ 1017 """
1010 pos = self.__cursorPosition - \ 1018 pos = (
1019 self.__cursorPosition -
1011 (self.__cursorPosition % (2 * self.BYTES_PER_LINE)) 1020 (self.__cursorPosition % (2 * self.BYTES_PER_LINE))
1021 )
1012 self.setCursorPosition(pos) 1022 self.setCursorPosition(pos)
1013 self.__setSelection(pos) 1023 self.__setSelection(pos)
1014 1024
1015 def selectPreviousLine(self): 1025 def selectPreviousLine(self):
1016 """ 1026 """
1030 1040
1031 def selectNextPage(self): 1041 def selectNextPage(self):
1032 """ 1042 """
1033 Public method to extend the selection one page down. 1043 Public method to extend the selection one page down.
1034 """ 1044 """
1035 pos = self.__cursorPosition + \ 1045 pos = (
1036 ((self.viewport().height() // self.__pxCharHeight) - 1) * \ 1046 self.__cursorPosition +
1047 ((self.viewport().height() // self.__pxCharHeight) - 1) *
1037 2 * self.BYTES_PER_LINE 1048 2 * self.BYTES_PER_LINE
1049 )
1038 self.setCursorPosition(pos) 1050 self.setCursorPosition(pos)
1039 self.__setSelection(pos) 1051 self.__setSelection(pos)
1040 1052
1041 def selectPreviousPage(self): 1053 def selectPreviousPage(self):
1042 """ 1054 """
1043 Public method to extend the selection one page up. 1055 Public method to extend the selection one page up.
1044 """ 1056 """
1045 pos = self.__cursorPosition - \ 1057 pos = (
1046 ((self.viewport().height() // self.__pxCharHeight) - 1) * \ 1058 self.__cursorPosition -
1059 ((self.viewport().height() // self.__pxCharHeight) - 1) *
1047 2 * self.BYTES_PER_LINE 1060 2 * self.BYTES_PER_LINE
1061 )
1048 self.setCursorPosition(pos) 1062 self.setCursorPosition(pos)
1049 self.__setSelection(pos) 1063 self.__setSelection(pos)
1050 1064
1051 def selectEndOfDocument(self): 1065 def selectEndOfDocument(self):
1052 """ 1066 """
1224 self.selectStartOfDocument() 1238 self.selectStartOfDocument()
1225 1239
1226 # Edit commands 1240 # Edit commands
1227 elif evt.matches(QKeySequence.Copy): 1241 elif evt.matches(QKeySequence.Copy):
1228 self.copy() 1242 self.copy()
1229 elif evt.key() == Qt.Key_Insert and \ 1243 elif (
1230 evt.modifiers() == Qt.NoModifier: 1244 evt.key() == Qt.Key_Insert and
1245 evt.modifiers() == Qt.NoModifier
1246 ):
1231 self.setOverwriteMode(not self.overwriteMode()) 1247 self.setOverwriteMode(not self.overwriteMode())
1232 self.setCursorPosition(self.__cursorPosition) 1248 self.setCursorPosition(self.__cursorPosition)
1233 1249
1234 elif not self.__readOnly: 1250 elif not self.__readOnly:
1235 if evt.matches(QKeySequence.Cut): 1251 if evt.matches(QKeySequence.Cut):
1236 self.cut() 1252 self.cut()
1237 elif evt.matches(QKeySequence.Paste): 1253 elif evt.matches(QKeySequence.Paste):
1238 self.paste() 1254 self.paste()
1239 elif evt.matches(QKeySequence.Delete): 1255 elif evt.matches(QKeySequence.Delete):
1240 self.deleteByte() 1256 self.deleteByte()
1241 elif evt.key() == Qt.Key_Backspace and \ 1257 elif (
1242 evt.modifiers() == Qt.NoModifier: 1258 evt.key() == Qt.Key_Backspace and
1259 evt.modifiers() == Qt.NoModifier
1260 ):
1243 self.deleteByteBack() 1261 self.deleteByteBack()
1244 elif evt.matches(QKeySequence.Undo): 1262 elif evt.matches(QKeySequence.Undo):
1245 self.undo() 1263 self.undo()
1246 elif evt.matches(QKeySequence.Redo): 1264 elif evt.matches(QKeySequence.Redo):
1247 self.redo() 1265 self.redo()
1331 @param evt reference to the paint event 1349 @param evt reference to the paint event
1332 @type QPaintEvent 1350 @type QPaintEvent
1333 """ 1351 """
1334 painter = QPainter(self.viewport()) 1352 painter = QPainter(self.viewport())
1335 1353
1336 if evt.rect() != self.__cursorRect and \ 1354 if (
1337 evt.rect() != self.__cursorRectAscii: 1355 evt.rect() != self.__cursorRect and
1356 evt.rect() != self.__cursorRectAscii
1357 ):
1338 pxOfsX = self.horizontalScrollBar().value() 1358 pxOfsX = self.horizontalScrollBar().value()
1339 pxPosStartY = self.__pxCharHeight 1359 pxPosStartY = self.__pxCharHeight
1340 1360
1341 # draw some patterns if needed 1361 # draw some patterns if needed
1342 painter.fillRect( 1362 painter.fillRect(
1385 pxPosX = self.__pxPosHexX - pxOfsX 1405 pxPosX = self.__pxPosHexX - pxOfsX
1386 pxPosAsciiX2 = self.__pxPosAsciiX - pxOfsX 1406 pxPosAsciiX2 = self.__pxPosAsciiX - pxOfsX
1387 bPosLine = row * self.BYTES_PER_LINE 1407 bPosLine = row * self.BYTES_PER_LINE
1388 1408
1389 colIdx = 0 1409 colIdx = 0
1390 while bPosLine + colIdx < len(self.__dataShown) and \ 1410 while (
1391 colIdx < self.BYTES_PER_LINE: 1411 bPosLine + colIdx < len(self.__dataShown) and
1412 colIdx < self.BYTES_PER_LINE
1413 ):
1392 c = self.viewport().palette().color(QPalette.Base) 1414 c = self.viewport().palette().color(QPalette.Base)
1393 painter.setPen(colStandard) 1415 painter.setPen(colStandard)
1394 1416
1395 posBa = self.__bPosFirst + bPosLine + colIdx 1417 posBa = self.__bPosFirst + bPosLine + colIdx
1396 if self.getSelectionBegin() <= posBa and \ 1418 if (
1397 self.getSelectionEnd() > posBa: 1419 self.getSelectionBegin() <= posBa and
1420 self.getSelectionEnd() > posBa
1421 ):
1398 c = self.__selectionBrush.color() 1422 c = self.__selectionBrush.color()
1399 painter.setPen(self.__selectionPen) 1423 painter.setPen(self.__selectionPen)
1400 elif self.__highlighting: 1424 elif self.__highlighting:
1401 if self.__markedShown and self.__markedShown[ 1425 if self.__markedShown and self.__markedShown[
1402 posBa - self.__bPosFirst]: 1426 posBa - self.__bPosFirst]:
1418 pxPosY - self.__pxCharHeight + 1442 pxPosY - self.__pxCharHeight +
1419 self.__pxSelectionSub, 1443 self.__pxSelectionSub,
1420 3 * self.__pxCharWidth, 1444 3 * self.__pxCharWidth,
1421 self.__pxCharHeight) 1445 self.__pxCharHeight)
1422 painter.fillRect(r, c) 1446 painter.fillRect(r, c)
1423 hexStr = \ 1447 hexStr = (
1424 chr(self.__hexDataShown[(bPosLine + colIdx) * 2]) + \ 1448 chr(self.__hexDataShown[(bPosLine + colIdx) * 2]) +
1425 chr(self.__hexDataShown[(bPosLine + colIdx) * 2 + 1]) 1449 chr(self.__hexDataShown[(bPosLine + colIdx) * 2 + 1])
1450 )
1426 painter.drawText(pxPosX, pxPosY, hexStr) 1451 painter.drawText(pxPosX, pxPosY, hexStr)
1427 pxPosX += 3 * self.__pxCharWidth 1452 pxPosX += 3 * self.__pxCharWidth
1428 1453
1429 # render ascii value 1454 # render ascii value
1430 if self.__asciiArea: 1455 if self.__asciiArea:
1648 (self.__addrDigits + self.__addrSeparators) * 1673 (self.__addrDigits + self.__addrSeparators) *
1649 self.__pxCharWidth + self.__pxGapAdrHex) 1674 self.__pxCharWidth + self.__pxGapAdrHex)
1650 else: 1675 else:
1651 self.__pxPosHexX = self.__pxGapAdrHex 1676 self.__pxPosHexX = self.__pxGapAdrHex
1652 self.__pxPosAdrX = self.__pxGapAdr 1677 self.__pxPosAdrX = self.__pxGapAdr
1653 self.__pxPosAsciiX = self.__pxPosHexX + \ 1678 self.__pxPosAsciiX = (
1654 self.HEXCHARS_PER_LINE * self.__pxCharWidth + self.__pxGapHexAscii 1679 self.__pxPosHexX +
1680 self.HEXCHARS_PER_LINE * self.__pxCharWidth +
1681 self.__pxGapHexAscii
1682 )
1655 1683
1656 # set horizontal scrollbar 1684 # set horizontal scrollbar
1657 pxWidth = self.__pxPosAsciiX 1685 pxWidth = self.__pxPosAsciiX
1658 if self.__asciiArea: 1686 if self.__asciiArea:
1659 pxWidth += self.BYTES_PER_LINE * self.__pxCharWidth 1687 pxWidth += self.BYTES_PER_LINE * self.__pxCharWidth
1660 self.horizontalScrollBar().setRange( 1688 self.horizontalScrollBar().setRange(
1661 0, pxWidth - self.viewport().width()) 1689 0, pxWidth - self.viewport().width())
1662 self.horizontalScrollBar().setPageStep(self.viewport().width()) 1690 self.horizontalScrollBar().setPageStep(self.viewport().width())
1663 1691
1664 # set vertical scrollbar 1692 # set vertical scrollbar
1665 self.__rowsShown = \ 1693 self.__rowsShown = (
1666 (self.viewport().height() - 4) // self.__pxCharHeight 1694 (self.viewport().height() - 4) // self.__pxCharHeight
1695 )
1667 lineCount = (self.__chunks.size() // self.BYTES_PER_LINE) + 1 1696 lineCount = (self.__chunks.size() // self.BYTES_PER_LINE) + 1
1668 self.verticalScrollBar().setRange(0, lineCount - self.__rowsShown) 1697 self.verticalScrollBar().setRange(0, lineCount - self.__rowsShown)
1669 self.verticalScrollBar().setPageStep(self.__rowsShown) 1698 self.verticalScrollBar().setPageStep(self.__rowsShown)
1670 1699
1671 # do the rest 1700 # do the rest
1672 value = self.verticalScrollBar().value() 1701 value = self.verticalScrollBar().value()
1673 self.__bPosFirst = value * self.BYTES_PER_LINE 1702 self.__bPosFirst = value * self.BYTES_PER_LINE
1674 self.__bPosLast = \ 1703 self.__bPosLast = (
1675 self.__bPosFirst + self.__rowsShown * self.BYTES_PER_LINE - 1 1704 self.__bPosFirst + self.__rowsShown * self.BYTES_PER_LINE - 1
1705 )
1676 if self.__bPosLast >= self.__chunks.size(): 1706 if self.__bPosLast >= self.__chunks.size():
1677 self.__bPosLast = self.__chunks.size() - 1 1707 self.__bPosLast = self.__chunks.size() - 1
1678 self.__readBuffers() 1708 self.__readBuffers()
1679 self.setCursorPosition(self.__cursorPosition) 1709 self.setCursorPosition(self.__cursorPosition)
1680 1710

eric ide

mercurial