def gotoHexView(self, offset, lenData): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.toOffset(offset, lenData) self.focusWidgetInTab(self.hexView)
def __init__(self, window): self.window = window self.colours = {'white' : (255, 255, 255, 0), 'outerspace': (65, 74, 76, 0) } pyglet.gl.glClearColor(*self.colours['outerspace']) #Load images, create batch-groups, a batch pyglet.resource.path = ['tiles'] pyglet.resource.reindex() #self.explosion_stream = open('explosion2strip.png', 'rb') #self.explosion = pyglet.image.load('explosion1strip.png') self.hexWater = pyglet.resource.image('hex.png') self.hexMud = pyglet.resource.image('hexDirt.png') self.hexUnwalkable = pyglet.resource.image('hexUnwalkable.png') self.ship = pyglet.resource.image('ship.png') self.background = pyglet.graphics.OrderedGroup(0) self.foreground = pyglet.graphics.OrderedGroup(1) self.effectslayer = pyglet.graphics.OrderedGroup(2) self.cellbatch = pyglet.graphics.Batch() self.grid = Grid(12, 8) self.hexView = HexView(self.grid, 64, 55, 17, 0, 0) #todo: something to get this centered in the screen automatically self.screenCoordinates = self.hexView.screenCoordinates() self.selectedCell = None self.phase = 1 self.movingUnit = False #True if a unit is being moved self.currentFaction = "Viper"
def __init__(self): super(HMainWindow, self).__init__( ) # does something magical about inheritance and preventing infinite recursion? self.files = [] self.current_file = None # self.last_selected = 0 # QtCore.QCoreApplication.setOrganizationName("L-3Com") # QtCore.QCoreApplication.setOrganizationName("l-3com.com") # QtCore.QCoreApplication.setApplicationName("Hexotomy") self.setWindowTitle("Hexotomy") QtCore.QSettings.setPath(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, ".") self.read_settings() self.show() # self.showMaximized() self.setAcceptDrops(True) # self.file_watcher = QtCore.QFileSystemWatcher() # self.file_watcher.fileChanged.connect(self.file_changed) self.file_watch = HexFileWatch(self) self.hex_view = HexView(self) self.setCentralWidget(self.hex_view) self.create_actions() self.create_menus() self.create_toolbars() self.create_statusbar() self.create_dock_windows() self.load_project(self.project_file) self.save_timer = QtCore.QTimer() self.save_timer.timeout.connect(self.save_project) self.save_timer.start(30000)
def openHexView(self): if self.hexView is not None: self.focusWidgetInTab(self.hexView) else: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View")
def changeData(self, offset, data): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.changeData(offset, data)
class Window(QMainWindow): def __init__(self): super(Window, self).__init__() screenShape = QDesktopWidget().screenGeometry() SCREEN_WIDTH = screenShape.width() SCREEN_HIGHT = screenShape.height() self.setWindowTitle(APPNAME) self.setWindowIcon(QIcon(ICON)) self.setMinimumWidth(SCREEN_WIDTH // 3) self.setMinimumHeight(SCREEN_HIGHT // 3) self.statusBar = self.statusBar() self.mainMenu = self.menuBar() QApplication.setStyle(QStyleFactory.create(STYLE)) self.iraChache = {} self.mainTab = None self.stringView = None self.asmLinear = None self.hexView = None self.initMenu() self.initToolBar() self.showMaximized() def initMenu(self): names = ['File', 'View', 'Tool'] items = { 'File': [ ('Open', 'Ctrl+O', 'Open file', self.openFile), ('Save', 'Ctrl+S', 'Save file', self.saveFile), ('Save As', 'Ctrl+Shift+S', 'Save file as', self.saveFileAs), ('Quit', 'Ctrl+Q', 'Quit the program', self.closeApp), ], 'View': [ ('Linear Diassembly', 'Ctrl+L', 'Linear Dissembly View', self.openAsmLinearView), ('Asm Graph', 'Ctrl+G', 'Graph View', self.openAsmCFGView), ('IR Linear', 'Ctrl+G', 'IR Linear View', self.openIRLinearView), ('IR Graph', 'Ctrl+G', 'IR Graph View', self.openIRCFGView), ('Hex', 'Ctrl+H', 'Hex View', self.openHexView), ('String', 'Ctrl+L', 'String View', self.openStringView), ], 'Tool': [('Basic Deobfuscate', 'Ctrl+R', "Basic Deobfuscate", self.recoverAlgorithm)] } for name in names: menu = self.mainMenu.addMenu('&' + name) for item, shortcut, status, func in items[name]: menu.addAction( self.createActionWithShortcut(item, shortcut, status, func)) def initToolBar(self): names = ['File Utils', 'View'] items = { 'File Utils': [ ('imgs/open.png', 'Open', 'Open file', self.openFile), ('imgs/save.png', 'Save', 'Save file', self.saveFile), ('imgs/saveas.png', 'Save as', 'Save file as', self.saveFileAs), ], 'View': [ ('imgs/hex.png', 'Hex', 'Hex View', self.openHexView), ('imgs/graph.png', 'Graph', 'Graph View', self.openAsmCFGView), ('imgs/linear.png', 'Linear Disassembly', 'Linear Disassembly View', self.openAsmLinearView), ], } for name in names: toolBar = self.addToolBar(name) for img, desc, status, func in items[name]: toolBar.addAction( self.createActionWithIcon(img, desc, status, func)) def createActionWithShortcut(self, name, shortcut, status, func): """ Tao action gan voi shortcut key. VD: createActionWithShortcut('Quit', 'Ctrl+Q', closeApp) :param name: ten action :param shortcut: phim shortcut gan voi action :param func: ham se chay khi bi click :return: QAction """ action = QAction(name, self) action.setShortcut(shortcut) action.setStatusTip(status) action.triggered.connect(func) return action def createActionWithIcon(self, icon, description, status, func): """ Tao action bieu tuong icon. VD: createActionWithIcon('ifa.png', 'Quit', closeApp) :param icon: ten file icon :param description: text hien thi khi de chuot vao :param func: ham se chay neu icon duoc click :return: QAction """ action = QAction(QIcon(icon), description, self) action.setStatusTip(status) action.triggered.connect(func) return action # ============================================================== def closeApp(self): """ Quit App :return: """ sys.exit() def openFile(self): """" Open File, Load Function to ListFunction and Info :return: """ try: f = open('cache', 'r') dir = f.read() except FileNotFoundError: dir = '' file, _ = QFileDialog.getOpenFileName( self, "Open File", dir, "All File (*);;Python File (*.elf);;PE File (*.exe", options=QFileDialog.DontUseNativeDialog) if file: dir = os.path.dirname(file) open('cache', 'w').write(dir) self.centralWidget = QWidget(self) self.setCentralWidget(self.centralWidget) QVBoxLayout(self.centralWidget) allLayout = self.centralWidget.layout() BinaryAnalysis.init(file) self.outputLog = QTextEdit() self.binInfo = QTextEdit() self.binInfo.setReadOnly(True) self.binInfo.setText(BinaryAnalysis.binaryInfo.info()) self.listFunctions = ListFuncs(BinaryAnalysis.funcs) self.listFunctions.gotoFunc.connect(self.gotoAddress) leftTopBottomSplitter = QSplitter(Qt.Vertical) leftTopBottomSplitter.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) leftTopBottomSplitter.addWidget(self.binInfo) leftTopBottomSplitter.addWidget(self.listFunctions) leftTopBottomSplitter.setStretchFactor(0, 1) leftTopBottomSplitter.setStretchFactor(1, 9) leftRightSplitter = QSplitter() self.mainTab = QTabWidget() self.mainTab.setTabsClosable(True) self.mainTab.tabCloseRequested.connect(self.closeTab) self.mainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.asmLinear = AsmLinear() self.mainTab.addTab(self.asmLinear, "Disassembly") self.asmLinear.focusAddress(BinaryAnalysis.binaryInfo.entryPoint) self.bindAsmLinear() self.hexView = HexView(BinaryAnalysis.rawData) self.mainTab.addTab(self.hexView, "Hex View") self.stringView = StringView(BinaryAnalysis.binaryInfo.strings) self.stringView.clicked.connect(self.gotoAddress) self.mainTab.addTab(self.stringView, "String List") self.importView = ImportView(BinaryAnalysis.binaryInfo.imports) self.importView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.importView, "Imports") self.exportView = ExportView(BinaryAnalysis.binaryInfo.exports) self.exportView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.exportView, "Exports") leftRightSplitter.addWidget(leftTopBottomSplitter) leftRightSplitter.addWidget(self.mainTab) leftRightSplitter.setStretchFactor(0, 2) leftRightSplitter.setStretchFactor(1, 8) topBottomSplitter = QSplitter(Qt.Vertical) topBottomSplitter.addWidget(leftRightSplitter) topBottomSplitter.addWidget(self.outputLog) topBottomSplitter.setStretchFactor(0, 8) topBottomSplitter.setStretchFactor(1, 2) allLayout.addWidget(topBottomSplitter) self.asmLinear.setFocus() def gotoLibFunc(self, name): for func in BinaryAnalysis.funcs: if func.name.endswith(name): self.gotoAsmLinear(func.address) break def bindAsmLinear(self): self.asmLinear.addCFG.connect(self.addAsmCFGView) self.asmLinear.gotoHexView.connect(self.gotoHexView) self.asmLinear.log.connect(self.outputLog.append) self.asmLinear.changedData.connect(self.changeData) self.asmLinear.addIRLinear.connect(self.addIRLinearView) def changeData(self, offset, data): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.changeData(offset, data) def addIRLinearView(self, func): from IRAnalysis import IRAnalysis from IRView import IRWidget if func in self.iraChache: if not func.changed: ira = self.iraChache[func] else: func.changed = False ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira else: ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira irLinearView = IRWidget(ira, 0) self.addNewTab(irLinearView, "IR Linear %s" % func.name) def addIRCFGView(self, func): from IRAnalysis import IRAnalysis from IRView import IRWidget if func in self.iraChache: if not func.changed: ira = self.iraChache[func] else: func.changed = False func.ircfg = None func.defUse = None func.ira = None ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira else: ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira irLinearView = IRWidget(ira, 2) self.addNewTab(irLinearView, "IR CFG %s" % func.name) def addAsmCFGView(self, line): for i in range(self.mainTab.count()): widget = self.mainTab.widget(i) if isinstance(widget, AsmCFGView): if line.func == widget.func: if not line.func.changed: self.mainTab.setCurrentIndex(i) return else: self.mainTab.removeTab(i) line.func.changed = False line.func.ircfg = None line.func.ira = None line.func.defUse = None if line.func in self.iraChache: del self.iraChache[line.func] break asmCFGView = AsmCFGView(line.func) asmCFGView.gotoAsmLinear.connect(self.gotoAsmLinear) asmCFGView.changeCFG.connect(self.replaceAsmCFG) asmCFGView.gotoHexView.connect(self.gotoHexView) asmCFGView.gotoIRCFG.connect(self.addIRCFGView) asmCFGView.gotoAddress.connect(self.gotoAsmLinear) asmCFGView.log.connect(self.outputLog.append) indexes = self.asmLinear.selectedIndexes() for index in indexes: item = self.asmLinear.getItemFormIndex(index) if hasattr(item, 'instr'): asmCFGView.selectAddress(item.instr.offset, False, False) asmCFGView.selectAddress(line.address, True, False) self.addNewTab(asmCFGView, "AsmCFG") def gotoAsmLinear(self, address): index = self.mainTab.indexOf(self.asmLinear) if index == -1: self.asmLinear = AsmLinear() self.bindAsmLinear() self.addNewTab(self.asmLinear, "Disassmbly") if address in self.asmLinear.addressMap: self.focusWidgetInTab(self.asmLinear) self.asmLinear.focusAddress(address) self.asmLinear.setFocus() def gotoHexView(self, offset, lenData): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.toOffset(offset, lenData) self.focusWidgetInTab(self.hexView) def addNewTab(self, widget, name): index = self.mainTab.currentIndex() self.mainTab.insertTab(index + 1, widget, name) self.mainTab.setCurrentIndex(index + 1) widget.setFocus() def gotoAddress(self, address): from IRView import IRWidget widget = self.getCurrentWidget() if isinstance(widget, AsmCFGView): self.replaceAsmCFG(address) elif isinstance(widget, IRWidget): for func in BinaryAnalysis.funcs: if func.address == address: if widget.viewType == 0: self.addIRLinearView(func) else: self.addIRCFGView(func) self.mainTab.removeTab(self.mainTab.currentIndex() - 1) break elif address in self.asmLinear.addressMap: linearIndex = self.mainTab.indexOf(self.asmLinear) self.mainTab.setCurrentIndex(linearIndex) self.asmLinear.focusAddress(address) self.asmLinear.setFocus() else: hexIndex = self.mainTab.indexOf(self.hexView) self.mainTab.setCurrentIndex(hexIndex) offset = BinaryAnalysis.binaryInfo.getOffsetAtAddress(address) self.hexView.toOffset(offset) self.hexView.setFocus() def replaceAsmCFG(self, address): newFunc = None index = self.mainTab.currentIndex() for func in BinaryAnalysis.funcs: if address == func.address: newFunc = func break if newFunc is not None: asmCFGView = AsmCFGView(newFunc) self.addNewTab(asmCFGView, "AsmCFG") asmCFGView.changeCFG.connect(self.replaceAsmCFG) self.mainTab.removeTab(index) asmCFGView.setFocus() def getCurrentWidget(self): return self.mainTab.currentWidget() def closeTab(self, index): self.mainTab.removeTab(index) self.mainTab.setCurrentIndex(index - 1) self.mainTab.widget(index - 1).setFocus() def focusWidgetInTab(self, widget): index = self.mainTab.indexOf(widget) self.mainTab.setCurrentIndex(index) widget.setFocus() def saveFile(self): if BinaryAnalysis.path is not None: button_pressed = QMessageBox.question( self, 'Save File', "Do you want to save?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if button_pressed == QMessageBox.Yes: f = open(BinaryAnalysis.path, 'wb') f.write(bytearray(BinaryAnalysis.rawData)) f.close() def saveFileAs(self): if BinaryAnalysis.path is not None: name, _ = QFileDialog.getSaveFileName(self, "Save File as") if name: f = open(name, 'wb') f.write(bytearray(BinaryAnalysis.rawData)) f.close() def openAsmLinearView(self): if BinaryAnalysis.path is not None: self.gotoAsmLinear(BinaryAnalysis.binaryInfo.entryPoint) def openAsmCFGView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addAsmCFGView(line) def openIRLinearView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addIRLinearView(line.func) elif isinstance(self.mainTab.currentWidget(), AsmCFGView): self.addIRLinearView(self.mainTab.currentWidget().func) def openIRCFGView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addIRCFGView(line.func) elif isinstance(self.mainTab.currentWidget(), AsmCFGView): self.addIRCFGView(self.mainTab.currentWidget().func) def openHexView(self): if self.hexView is not None: self.focusWidgetInTab(self.hexView) else: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") def openStringView(self): if self.stringView is not None: self.focusWidgetInTab(self.stringView) else: self.stringView = StringView(BinaryAnalysis.binaryInfo.strings) self.addNewTab(self.stringView, "Strings") def recoverAlgorithm(self): from IRAnalysis import IRAnalysis from IRView import IRCFGRecover, IRWidget widget = self.mainTab.currentWidget() func = None if isinstance(widget, AsmLinear): indexes = widget.selectedIndexes() if len(indexes) > 0: line = widget.getItemFormIndex(indexes[0]) func = line.func elif isinstance(widget, AsmCFGView): func = widget.func elif isinstance(widget, IRWidget): address = widget.ira.address for f in BinaryAnalysis.funcs: if f.address == address: func = f break if func is not None: if func in self.iraChache: ira = self.iraChache[func] else: ira = IRAnalysis(func.address, func.cfg) newLocDB, newIRCFG = ira.recoverAlgorithm() recoverIRCFG = IRCFGRecover(newIRCFG) for block in recoverIRCFG.mapItems: line = block.model.item(0, 0) line.setText(newLocDB.pretty_str(line.lockey)) self.addNewTab(recoverIRCFG, "Recovered IRCFG")
def openFile(self): """" Open File, Load Function to ListFunction and Info :return: """ try: f = open('cache', 'r') dir = f.read() except FileNotFoundError: dir = '' file, _ = QFileDialog.getOpenFileName( self, "Open File", dir, "All File (*);;Python File (*.elf);;PE File (*.exe", options=QFileDialog.DontUseNativeDialog) if file: dir = os.path.dirname(file) open('cache', 'w').write(dir) self.centralWidget = QWidget(self) self.setCentralWidget(self.centralWidget) QVBoxLayout(self.centralWidget) allLayout = self.centralWidget.layout() BinaryAnalysis.init(file) self.outputLog = QTextEdit() self.binInfo = QTextEdit() self.binInfo.setReadOnly(True) self.binInfo.setText(BinaryAnalysis.binaryInfo.info()) self.listFunctions = ListFuncs(BinaryAnalysis.funcs) self.listFunctions.gotoFunc.connect(self.gotoAddress) leftTopBottomSplitter = QSplitter(Qt.Vertical) leftTopBottomSplitter.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) leftTopBottomSplitter.addWidget(self.binInfo) leftTopBottomSplitter.addWidget(self.listFunctions) leftTopBottomSplitter.setStretchFactor(0, 1) leftTopBottomSplitter.setStretchFactor(1, 9) leftRightSplitter = QSplitter() self.mainTab = QTabWidget() self.mainTab.setTabsClosable(True) self.mainTab.tabCloseRequested.connect(self.closeTab) self.mainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.asmLinear = AsmLinear() self.mainTab.addTab(self.asmLinear, "Disassembly") self.asmLinear.focusAddress(BinaryAnalysis.binaryInfo.entryPoint) self.bindAsmLinear() self.hexView = HexView(BinaryAnalysis.rawData) self.mainTab.addTab(self.hexView, "Hex View") self.stringView = StringView(BinaryAnalysis.binaryInfo.strings) self.stringView.clicked.connect(self.gotoAddress) self.mainTab.addTab(self.stringView, "String List") self.importView = ImportView(BinaryAnalysis.binaryInfo.imports) self.importView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.importView, "Imports") self.exportView = ExportView(BinaryAnalysis.binaryInfo.exports) self.exportView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.exportView, "Exports") leftRightSplitter.addWidget(leftTopBottomSplitter) leftRightSplitter.addWidget(self.mainTab) leftRightSplitter.setStretchFactor(0, 2) leftRightSplitter.setStretchFactor(1, 8) topBottomSplitter = QSplitter(Qt.Vertical) topBottomSplitter.addWidget(leftRightSplitter) topBottomSplitter.addWidget(self.outputLog) topBottomSplitter.setStretchFactor(0, 8) topBottomSplitter.setStretchFactor(1, 2) allLayout.addWidget(topBottomSplitter) self.asmLinear.setFocus()
class HMainWindow(QtGui.QMainWindow): def __init__(self): super(HMainWindow, self).__init__( ) # does something magical about inheritance and preventing infinite recursion? self.files = [] self.current_file = None # self.last_selected = 0 # QtCore.QCoreApplication.setOrganizationName("L-3Com") # QtCore.QCoreApplication.setOrganizationName("l-3com.com") # QtCore.QCoreApplication.setApplicationName("Hexotomy") self.setWindowTitle("Hexotomy") QtCore.QSettings.setPath(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, ".") self.read_settings() self.show() # self.showMaximized() self.setAcceptDrops(True) # self.file_watcher = QtCore.QFileSystemWatcher() # self.file_watcher.fileChanged.connect(self.file_changed) self.file_watch = HexFileWatch(self) self.hex_view = HexView(self) self.setCentralWidget(self.hex_view) self.create_actions() self.create_menus() self.create_toolbars() self.create_statusbar() self.create_dock_windows() self.load_project(self.project_file) self.save_timer = QtCore.QTimer() self.save_timer.timeout.connect(self.save_project) self.save_timer.start(30000) # Create: def create_actions(self): self.openAction = QtGui.QAction(QtGui.QIcon('document-open.png'), "&Open...", self, shortcut=QtGui.QKeySequence.Open, statusTip="Open an existing file", triggered=self.open_file) self.projectAction = QtGui.QAction( QtGui.QIcon('system-file-manager.png'), "&Load Project File...", self, shortcut=QtGui.QKeySequence.Open, statusTip="Load a Project file where all work will be saved", triggered=self.choose_project) self.exitAction = QtGui.QAction("E&xit", self, shortcut="Ctrl-Q", statusTip="Exit Hexotomy", triggered=self.close) self.aboutAction = QtGui.QAction( "&About", self, statusTip="Show the application's About box", triggered=self.about) def create_menus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.projectAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.openAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAction) def create_toolbars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.setObjectName("fileToolBar") self.fileToolBar.addAction(self.projectAction) self.fileToolBar.addSeparator() self.fileToolBar.addAction(self.openAction) def create_statusbar(self): self.statusBar().showMessage("") def create_dock_windows(self): self.revision_dock = QtGui.QDockWidget("Files/Revisions", self) self.revision_dock.setObjectName("revision_dock") # self.self().self.selfie.self() = self.selfy.self%self().selfself self.revision_dock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable) self.revision_tree = HexRevisionTree(self) self.revision_dock.setWidget(self.revision_tree) # self.revision_dock.setGeometry(0, 0, 400, 600) self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.revision_dock) self.inspector_dock = QtGui.QDockWidget("Inspector Gadget", self) self.inspector_dock.setObjectName("inspector_dock") self.inspector_dock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable) # self.inspector_table = QtGui.QTableWidget(self.inspector_dock) self.inspector_table = HexInspectorTable(self) self.inspector_dock.setWidget(self.inspector_table) # self.inspector_dock.setGeometry(0, 0, 400, 600) # useless self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.inspector_dock) self.interpreter_dock = QtGui.QDockWidget("Interpreter", self) self.interpreter_dock.setObjectName("interpreter_dock") self.interpreter_dock.setFeatures( QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable) self.interpreter_table = HexInterpreterTable(self) self.interpreter_dock.setWidget(self.interpreter_table) # self.inspector_dock.setGeometry(0, 0, 400, 600) # useless self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interpreter_dock) self.interpreter_detail_dock = QtGui.QDockWidget( "Interpret Detail", self) self.interpreter_detail_dock.setObjectName("interpreter_detail_dock") self.interpreter_detail_dock.setFeatures( QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable) self.interpreter_table.detail = HexInterpreterDetail( self.interpreter_table) self.interpreter_detail_dock.setWidget(self.interpreter_table.detail) # self.inspector_dock.setGeometry(0, 0, 400, 600) # useless self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interpreter_detail_dock) # Do stuff: def about(self): QtGui.QMessageBox.about( self, "About Hexotomy", "Hexotomy is a tool to help understand small binary files.<p>" "Uses PySide (LGPL) and Tango Icons (Public Domain)") def read_settings(self): settings = QtCore.QSettings(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, "L-3com", "Hexotomy") self.project_file = settings.value("project", "default.hxt") print "project_file: " + self.project_file #print "GRRR: isfile-%s getsize-%d" % (str(os.path.isfile(self.project_file)), os.path.getsize(self.project_file)) if not os.path.isfile( self.project_file) or os.path.getsize(self.project_file) < 20: print "read_settings: '%s' is not a real project file. Defaulting to default.hxt" % ( self.project_file) self.project_file = "default.hxt" self.restoreGeometry(settings.value("geometry")) #if not self.restoreState(settings.value("windowState")): #self.showMaximized() def write_settings(self): settings = QtCore.QSettings(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, "L-3com", "Hexotomy") settings.setValue("project", self.project_file) settings.setValue("geometry", self.saveGeometry()) settings.setValue("windowState", self.saveState()) def choose_project(self): filename, _ = QtGui.QFileDialog.getSaveFileName( self, caption="Load Project File", filter="Hexotomy Project (*.hxt);;All Files (*)", options="QFileDialog.DontConfirmOverwrite") if filename: self.save_project() self.load_project(filename) def load_project(self, filename): if not filename: print "empty db filename" return if os.path.isfile(filename) and os.path.getsize(filename) > 0: try: project_file = open(str(filename), "rb") self.files = cPickle.load(project_file) self.interpreter_table.interprets = cPickle.load(project_file) except IOError as err: # TODO: I should really use some variable with the app name here QtGui.QMessageBox.warning( self, "Hexotomy", "Cannot load project %s:\n%s." % (filename, err.strerror)) return except EOFError as err: QtGui.QMessageBox.warning( self, "Hexotomy", "Corrupted project file %s." % (filename)) finally: project_file.close() self.project_file = os.path.abspath(filename) self.revision_tree.update() self.select_file(0) self.interpreter_table.update_interpreter() for i in range(0, len(self.files)): self.file_watch.add(self.files[i]["fullfilename"]) print "really loaded db!" self.setWindowTitle("Hexotomy (%s)" % os.path.basename(filename)) print "loaded db! " + str(self.project_file) def save_project(self): # print "trying to save project: " + self.project_file if self.project_file: try: project_file = open(str(self.project_file), "w+b") cPickle.dump(self.files, project_file) cPickle.dump(self.interpreter_table.interprets, project_file) project_file.close() except IOError as err: QtGui.QMessageBox.warning( self, "Application?", "Cannot save project %s:\n%s." % (self.project_file, err.strerror)) return False # print "saved db!" return True def open_file(self): filename, _ = QtGui.QFileDialog.getOpenFileName(self) if filename: self.load_file(filename) def load_file(self, filename): rawfile = QtCore.QFile(filename) rawfileinfo = QtCore.QFileInfo(rawfile) if not rawfile.open(QtCore.QFile.ReadOnly): QtGui.QMessageBox.warning( self, "Application?", "Cannot read file %s:\n%s." % (filename, rawfile.errorString())) return QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) rawbinary = rawfile.readAll().data() self.files.append({ "filename": rawfileinfo.fileName(), "timestamp": rawfileinfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"), "comment": "", "fullfilename": rawfileinfo.canonicalFilePath(), "rawfile": rawbinary, "diff": "true" }) file_index = len(self.files) - 1 self.statusBar().showMessage("File Loaded", 2000) self.revision_tree.update() self.select_file(file_index) QtGui.QApplication.restoreOverrideCursor() self.file_watch.add(rawfileinfo.canonicalFilePath()) # print "Currently watched files: " # self.file_watch.list() def remove_file_rightclick(self): # find file in files selected = self.revision_tree.selectedIndexes()[0] row = self.revision_tree.model.itemFromIndex(selected).row() self.remove_file(row) def remove_file(self, index): # remove filewatch self.file_watch.remove(self.files[index]["fullfilename"], 1) # statusbar message self.statusBar().showMessage( "Removed file '%s'" % self.files[index]["fullfilename"], 5000) # delete from files del self.files[index] # select a different file if necessary if self.current_file == index: if index < len(self.files): self.select_file(index) elif index != 0: self.select_file(index - 1) else: # I don't want to handle empty :( pass else: # current_file needs to be relocated! if self.current_file > index: self.select_file(index) # remove from HexRevisionTree self.revision_tree.update() # print "Currently watched files: " # self.file_watch.list() def stop_file_watch_rightclick(self): # find file in files selected = self.revision_tree.selectedIndexes()[0] row = self.revision_tree.model.itemFromIndex(selected).row() self.stop_file_watch(row) def stop_file_watch(self, index): # remove filewatch # print "removing file watch for %d %s" % (index, self.files[index]["fullfilename"]) self.file_watch.remove(self.files[index]["fullfilename"], 99999) # print "Currently watched files: " # self.file_watch.list() def select_file(self, index): if index < len(self.files): self.current_file = index # start = time.time() self.hex_view.set_binary(self.current_file) # print "hex_view.set_binary(%d): %f" % (index, time.time() - start) #start = time.time() self.inspector_table.update_inspector( ) # Inspector Gadget will show info at loc #print "inspector_table.update_inspector: %f" % (time.time() - start) #start = time.time() self.interpreter_table.update_interpreter() #print "interpreter_table.update_interpreter: %f" % (time.time() - start) self.statusBar().showMessage( "selected file %s" % self.files[self.current_file]["fullfilename"]) else: print "somebody tried to call select_file(%d), but there are only %d files loaded (ok on init)" \ % (index, len(self.files)) # Handle stuff def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.acceptProposedAction() def dragMoveEvent(self, event): event.acceptProposedAction() def dropEvent(self, event): # print "got a dropEvent!" event.acceptProposedAction() # print "mime: " + str(event.mimeData().formats()) # print "text: " + str(event.mimeData().text()) # print "urls: " + str(event.mimeData().urls()) # print "name: " + str(event.mimeData().data("FileName")) if event.mimeData().hasUrls(): for url in event.mimeData().urls(): # print "attempting to load: " + str(url) self.load_file(url.toLocalFile()) def dragLeaveEvent(self, event): event.acceptProposedAction() def closeEvent(self, event): self.write_settings() if self.save_project(): event.accept()
class Game(): def __init__(self, window): self.window = window self.colours = {'white' : (255, 255, 255, 0), 'outerspace': (65, 74, 76, 0) } pyglet.gl.glClearColor(*self.colours['outerspace']) #Load images, create batch-groups, a batch pyglet.resource.path = ['tiles'] pyglet.resource.reindex() #self.explosion_stream = open('explosion2strip.png', 'rb') #self.explosion = pyglet.image.load('explosion1strip.png') self.hexWater = pyglet.resource.image('hex.png') self.hexMud = pyglet.resource.image('hexDirt.png') self.hexUnwalkable = pyglet.resource.image('hexUnwalkable.png') self.ship = pyglet.resource.image('ship.png') self.background = pyglet.graphics.OrderedGroup(0) self.foreground = pyglet.graphics.OrderedGroup(1) self.effectslayer = pyglet.graphics.OrderedGroup(2) self.cellbatch = pyglet.graphics.Batch() self.grid = Grid(12, 8) self.hexView = HexView(self.grid, 64, 55, 17, 0, 0) #todo: something to get this centered in the screen automatically self.screenCoordinates = self.hexView.screenCoordinates() self.selectedCell = None self.phase = 1 self.movingUnit = False #True if a unit is being moved self.currentFaction = "Viper" #self.exp_seq = pyglet.image.ImageGrid(self.explosion, 1, 32) #self.boom = pyglet.image.Animation.from_image_sequence(self.exp_seq, 0.09) #self.boomsprite = pyglet.sprite.Sprite(self.boom, x=10, y=10, batch=self.cellbatch, group=self.foreground) def initializeCellSprites(self): # use iteritems and refactor this nonsense for cell in self.grid.CellDict.iterkeys(): if not self.grid.CellDict[cell].walkable: self.grid.CellDict[cell].baseImg = pyglet.sprite.Sprite(self.hexUnwalkable, x=self.grid.CellDict[cell].screenCoordinates[0], y=self.grid.CellDict[cell].screenCoordinates[1], batch=self.cellbatch, group=self.background) else: self.grid.CellDict[cell].baseImg = pyglet.sprite.Sprite(self.hexWater, x=self.grid.CellDict[cell].screenCoordinates[0], y=self.grid.CellDict[cell].screenCoordinates[1], batch=self.cellbatch, group=self.background) def initializeUnits(self): self.grid.addUnit((3,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Viper") self.grid.addUnit((3,4), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Viper") self.grid.addUnit((5,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Raider") self.grid.addUnit((2,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Raider") def on_draw(self): glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.window.clear() self.cellbatch.draw() #self.boomsprite.draw() #pyglet.clock.ClockDisplay().draw() def validCell(self, coords): return coords in self.grid.CellDict #Should this be here? def on_mouse_motion(self,x, y, dx, dy): pass def moveUnit(self, startCell, endCell): path = self.grid.findPath(startCell, endCell) startCell.unit.path = path for cell in path: print cell self.movingUnit = False def resolveMove(self): for unit in self.grid.units: print unit def on_mouse_press(self, x, y, button, modifiers): coords = self.hexView.getClickedCell(x,y) if self.validCell(coords): cell = self.grid.CellDict[coords] if not self.movingUnit and cell.unit != None: if cell.unit.faction == self.currentFaction: self.movingUnit = True self.currentCell = cell print cell.unit return if self.movingUnit and cell != None: self.moveUnit(self.currentCell, cell) if button == mouse.RIGHT: self.resolveMove() def startGame(self): self.initializeCellSprites() self.initializeUnits() self.window.on_draw = self.on_draw self.window.on_mouse_press = self.on_mouse_press self.window.on_mouse_motion = self.on_mouse_motion #self.window.event(self.on_draw) #self.window.event(self.on_mouse_press) pyglet.app.run()