Files
Python/Byteswap.py
2025-02-22 16:10:06 +01:00

221 lines
8.7 KiB
Python

import sys, os
from PyQt6 import QtWidgets, QtCore, QtGui
from QHexEdit import QHexEdit
import qhexedit_rc
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, fileName=None):
super(MainWindow, self).__init__()
self.init()
self.setCurrentFile('')
def about(self):
QtWidgets.QMessageBox.about(self, "About ByteSwap",
"ByteSwap is a simple GUI for byteswaping an Amiga Kickstart Rom");
def closeEvent(self, event):
self.writeSettings()
self.close()
def createActions(self):
self.openAct = QtGui.QAction(QtGui.QIcon(':/images/open.png'),
"&Open...", self, shortcut=QtGui.QKeySequence.StandardKey.Open,
statusTip="Open an existing file", triggered=self.open)
self.saveAct = QtGui.QAction(QtGui.QIcon(':/images/save.png'),
"&Save", self, shortcut=QtGui.QKeySequence.StandardKey.Save,
statusTip="Save the document to disk", triggered=self.save)
self.saveAsAct = QtGui.QAction("Save &As...", self,
shortcut=QtGui.QKeySequence.StandardKey.SaveAs,
statusTip="Save the document under a new name", triggered=self.saveAs)
self.saveReadable = QtGui.QAction("Save as &Readable...", self,
statusTip="Save in a readable format", triggered=self.saveToReadableFile)
self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
statusTip="Exit the application", triggered=self.close)
self.undoAct = QtGui.QAction(QtGui.QIcon(':/images/undo.png'),
"&Undo", self, shortcut=QtGui.QKeySequence.StandardKey.Undo, triggered=self.hexEdit.undo)
self.redoAct = QtGui.QAction(QtGui.QIcon(':/images/redo.png'),
"&Redo", self, shortcut=QtGui.QKeySequence.StandardKey.Redo, triggered=self.hexEdit.redo)
self.saveSelectionReadable = QtGui.QAction("Save Selection Readable...", self,
statusTip="Save selection in a readable format",
triggered=self.saveSelectionToReadableFile)
self.aboutAct = QtGui.QAction("&About", self,
statusTip="Show the application's About box", triggered=self.about)
def createMenus(self):
self.fileMenu = self.menuBar().addMenu("&File")
self.fileMenu.addAction(self.openAct)
self.fileMenu.addAction(self.saveAct)
self.fileMenu.addAction(self.saveAsAct)
self.fileMenu.addAction(self.saveReadable)
self.fileMenu.addSeparator()
self.fileMenu.addAction(self.exitAct)
self.editMenu = self.menuBar().addMenu("&Edit")
self.editMenu.addAction(self.undoAct)
self.editMenu.addAction(self.redoAct)
self.editMenu.addAction(self.saveSelectionReadable)
self.helpMenu = self.menuBar().addMenu("&Help")
self.helpMenu.addAction(self.aboutAct)
def createStatusBar(self):
# Address Label
self.lbAddressName = QtWidgets.QLabel()
self.lbAddressName.setText("Address:")
self.statusBar().addPermanentWidget(self.lbAddressName)
self.lbAddress = QtWidgets.QLabel()
self.lbAddress.setFrameShape(QtWidgets.QFrame.Shape.Panel)
self.lbAddress.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.lbAddress.setMinimumWidth(70)
self.statusBar().addPermanentWidget(self.lbAddress)
self.hexEdit.currentAddressChanged.connect(self.setAddress)
# Address Size
self.lbSizeName = QtWidgets.QLabel()
self.lbSizeName.setText("Size:")
self.statusBar().addPermanentWidget(self.lbSizeName)
self.lbSize = QtWidgets.QLabel()
self.lbSize.setFrameShape(QtWidgets.QFrame.Shape.Panel)
self.lbSize.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.lbSize.setMinimumWidth(70)
self.statusBar().addPermanentWidget(self.lbSize)
self.hexEdit.currentSizeChanged.connect(self.setSize)
# Overwrite Mode label
self.lbOverwriteModeName = QtWidgets.QLabel()
self.lbOverwriteModeName.setText("Mode:")
self.statusBar().addPermanentWidget(self.lbOverwriteModeName)
self.lbOverwriteMode = QtWidgets.QLabel()
self.lbOverwriteMode.setFrameShape(QtWidgets.QFrame.Shape.Panel)
self.lbOverwriteMode.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.lbOverwriteMode.setMinimumWidth(70)
self.statusBar().addPermanentWidget(self.lbOverwriteMode)
self.setOverwriteMode(self.hexEdit.overwriteMode())
self.statusBar().showMessage("Ready")
def createToolBars(self):
self.fileToolBar = self.addToolBar("File")
self.fileToolBar.addAction(self.openAct)
self.fileToolBar.addAction(self.saveAct)
self.fileToolBar.addAction(self.undoAct)
self.fileToolBar.addAction(self.redoAct)
def init(self):
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose)
self.isUntitled = True
self.hexEdit = QHexEdit()
self.setCentralWidget(self.hexEdit)
self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode)
self.createActions()
self.createMenus()
self.createToolBars()
self.createStatusBar()
self.readSettings()
def loadFile(self, fileName):
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.WaitCursor)
with open(fileName, 'rb') as f:
self.hexEdit.setData(f.read())
QtWidgets.QApplication.restoreOverrideCursor()
self.setCurrentFile(fileName)
self.statusBar().showMessage("File loaded", 2000)
def open(self):
fileName, _filter = QtWidgets.QFileDialog.getOpenFileName(self)
if fileName:
self.loadFile(fileName)
def readSettings(self):
settings = QtCore.QSettings()
pos = settings.value('pos', QtCore.QPoint(200, 200))
size = settings.value('size', QtCore.QSize(610, 460))
self.move(pos)
self.resize(size)
def save(self):
if self.isUntitled:
self.saveAs()
else:
self.saveFile(self.curFile)
def saveAs(self):
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save As", self.curFile)
if fileName != "":
self.saveFile(fileName)
def setAddress(self, address):
self.lbAddress.setText('%x' % address)
def setOverwriteMode(self, mode):
settings = QtCore.QSettings()
settings.setValue("OverwriteMode", mode)
if mode:
self.lbOverwriteMode.setText("Overwrite")
else:
self.lbOverwriteMode.setText("Insert")
def setSize(self, size):
self.lbSize.setText('%d' % size)
def saveFile(self, fileName):
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.WaitCursor)
with open(fileName, 'wb') as f:
f.write(self.hexEdit.data())
QtWidgets.QApplication.restoreOverrideCursor()
self.setCurrentFile(fileName)
self.statusBar().showMessage("File saved", 2000)
def saveToReadableFile(self):
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save To Readable File")
if fileName != "":
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.WaitCursor)
with open(fileName, "w") as f:
f.write(self.hexEdit.toReadableString())
QtWidgets.QApplication.restoreOverrideCursor()
self.statusBar().showMessage("File saved", 2000);
def saveSelectionToReadableFile(self):
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save To Readable File")
if fileName != "":
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.WaitCursor)
with open(fileName, 'w') as f:
f.write(self.hexEdit.selectionToReadableString())
QtWidgets.QApplication.restoreOverrideCursor()
self.statusBar().showMessage("File saved", 2000);
def setCurrentFile(self, fileName):
self.curFile = fileName
self.isUntitled = (fileName == "")
self.setWindowModified(False)
basename = os.path.basename(self.curFile)
self.setWindowTitle("%s[*] - ByteSwap" % basename)
def writeSettings(self):
settings = QtCore.QSettings()
settings.setValue('pos', self.pos())
settings.setValue('size', self.size())
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName("ByteSwap");
app.setOrganizationName("ByteSwap");
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec())