class SerialOut(QWidget): def __init__(self, config): """ Custom widget for serial out frame """ QWidget.__init__(self) self.console = QPlainTextEdit() self.console.setReadOnly(True) doc = self.console.document() f = doc.defaultFont() f.setFamily(get_font(config)) doc.setDefaultFont(f) layout = QVBoxLayout() layout.setMargin(60) layout.addWidget(self.console) self.setLayout(layout) def paintEvent(self, event): """ Override to draw the console frame background image """ painter = QPainter(self) painter.drawPixmap(0, 0, QPixmap("assets/retroterm.png").scaled(self.size())) super().paintEvent(event)
def setPlainTextEditHeight(ptxt: QtWidgets.QPlainTextEdit, nRows: int): """ Sets the height of a plain text edit box to a set number of rows. """ pdoc = ptxt.document() fm = QtGui.QFontMetrics(pdoc.defaultFont()) margins = ptxt.contentsMargins() rowHeight = fm.lineSpacing() height = (rowHeight * nRows + 2 * (pdoc.documentMargin() + ptxt.frameWidth()) + margins.top() + margins.bottom()) ptxt.setFixedHeight(height)
def handlerFilterResult(self, filterResult): result = self.resultMap.get(filterResult.orgTag) if result: print("已存在%s" % filterResult.orgTag) result.setPlainText(filterResult.value) else: print("未存在%s" % filterResult.orgTag) filterResultView = QPlainTextEdit(self) highlighter = LogQSyntaxHighlighter(filterResultView.document()) highlighter.setHighlignterTags(filterResult.tag) filterResultView.setPlainText(filterResult.value) filterResultView.setLineWrapMode(QPlainTextEdit.NoWrap) filterResultView.cursorPositionChanged.connect( self.cursorPositionChanged) self.bottomText.addTab(filterResultView, filterResult.orgTag) self.bottomText.setCurrentIndex(self.bottomText.count() - 1) self.resultMap.setdefault(filterResult.orgTag, filterResultView)
class Snippets(QDialog): def __init__(self, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("Save")) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) self.newFolderButton = QPushButton("New Folder") self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QPlainTextEdit() self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" self.settings = QSettings("Vector35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) self.newFolderButton.clicked.connect(self.newFolder) if self.settings.contains("ui/snippeteditor/selected"): selectedName = self.settings.value("ui/snippeteditor/selected") self.tree.selectionModel().select(self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) if self.tree.selectionModel().hasSelection(): self.selectFile(self.tree.selectionModel().selection(), None) self.edit.setFocus() cursor = self.edit.textCursor() cursor.setPosition(self.edit.document().characterCount()-1) self.edit.setTextCursor(cursor) else: self.readOnly(True) else: self.readOnly(True) @staticmethod def registerAllSnippets(): for action in list(filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())): if action == "Snippets\\Snippet Editor...": continue UIActionHandler.globalActions().unbindAction(action) Menu.mainMenu("Tools").removeAction(action) UIAction.unregisterAction(action) for snippet in includeWalk(snippetPath, ".py"): snippetKeys = None (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet) if not snippetDescription: actionText = "Snippets\\" + os.path.basename(snippet).rstrip(".py") else: actionText = "Snippets\\" + snippetDescription if snippetCode: if snippetKeys == None: UIAction.registerAction(actionText) else: UIAction.registerAction(actionText, snippetKeys) UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode))) Menu.mainMenu("Tools").addAction(actionText, actionText) def clearSelection(self): self.keySequenceEdit.clear() self.currentHotkey = QKeySequence() self.currentHotkeyLabel.setText("") self.currentFileLabel.setText("") self.snippetDescription.setText("") self.edit.setPlainText("") self.currentFile = "" def reject(self): self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry()) if self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?")) if question != QMessageBox.StandardButton.Yes: return self.accept() def newFolder(self): (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: ")) if ok and folderName: index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): QDir(selection).mkdir(folderName) else: QDir(snippetPath).mkdir(folderName) def selectFile(self, new, old): if (self.resetting): self.resetting = False return newSelection = self.files.filePath(new.indexes()[0]) self.settings.setValue("ui/snippeteditor/selected", newSelection) if QFileInfo(newSelection).isDir(): self.readOnly(True) self.tree.clearSelection() self.currentFile = "" return if old and old.length() > 0: oldSelection = self.files.filePath(old.indexes()[0]) if not QFileInfo(oldSelection).isDir() and self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?")) if question != QMessageBox.StandardButton.Yes: self.resetting = True self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) return False self.currentFile = newSelection self.loadSnippet() def loadSnippet(self): self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName()) (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("") self.keySequenceEdit.setKeySequence(snippetKeys) if snippetKeys else self.keySequenceEdit.setKeySequence(QKeySequence("")) self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("") self.readOnly(False) def newFileDialog(self): (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: ")) if ok and snippetName: if not snippetName.endswith(".py"): snippetName += ".py" index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): path = os.path.join(selection, snippetName) else: path = os.path.join(snippetPath, snippetName) self.readOnly(False) open(path, "w").close() self.tree.setCurrentIndex(self.files.index(path)) log_debug("Snippet %s created." % snippetName) def readOnly(self, flag): self.keySequenceEdit.setEnabled(not flag) self.snippetDescription.setReadOnly(flag) self.edit.setReadOnly(flag) if flag: self.snippetDescription.setDisabled(True) self.edit.setDisabled(True) else: self.snippetDescription.setEnabled(True) self.edit.setEnabled(True) def deleteSnippet(self): selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row snippetName = self.files.fileName(selection) question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName) if (question == QMessageBox.StandardButton.Yes): log_debug("Deleting snippet %s." % snippetName) self.clearSelection() self.files.remove(selection) self.registerAllSnippets() def snippetChanged(self): if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()): return False (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) if snippetKeys == None and not self.keySequenceEdit.keySequence().isEmpty(): return True if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence().toString(): return True return self.edit.toPlainText() != snippetCode or \ self.snippetDescription.text() != snippetDescription def save(self): log_debug("Saving snippet %s" % self.currentFile) outputSnippet = open(self.currentFile, "w") outputSnippet.write("#" + self.snippetDescription.text() + "\n") outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n") outputSnippet.write(self.edit.toPlainText()) outputSnippet.close() self.registerAllSnippets() def clearHotkey(self): self.keySequenceEdit.clear()
self.rebuildRules() def appendVarColor(self, var_name, color): reg_ex = self.VAR_PATTERN_PREFIX + var_name + self.VAR_PATTERN_SUFFIX style = self.formatText(color, style="italic") self._var_rules_map[var_name] = (QRegExp(reg_ex), 0, style) self.rebuildRules() def removeVarColor(self, var_name): if var_name in self._var_rules_map: del(self._var_rules_map[var_name]) self.rebuildRules() if __name__ == "__main__": from PySide2.QtWidgets import QApplication, QPlainTextEdit app = QApplication([]) editor = QPlainTextEdit() highlight = QtPythonHighlighter(editor.document()) editor.show() app.exec_()
def _init_widgets(self): layout = QGridLayout() row = 0 header_label = QLabel(self) header_label.setText("Exploration strategy:") layout.addWidget(header_label, row, 0) row += 1 options_container = QGroupBox(self) options = QVBoxLayout() for strategy, cls in sorted( angr.exploration_techniques.__dict__.items()): if hasattr( cls, "mro" ) and angr.exploration_techniques.ExplorationTechnique in type.mro( cls): child = QRadioButton() child.setText(strategy) child.strategy = strategy child.toggled.connect(self.selected) options.addWidget(child) self.strategies[strategy] = cls scroll_area = QScrollArea(self) scroll_area.setWidgetResizable(True) widget = QWidget() scroll_area.setWidget(widget) layout_scroll = QVBoxLayout(widget) layout_scroll.addWidget(options_container) options_container.setLayout(options) layout.addWidget(scroll_area, row, 0) row += 1 constructor_box = QPlainTextEdit(self) highlight = PythonHighlighter(constructor_box.document()) constructor_box.setWordWrapMode(QTextOption.WordWrap) self._constructor_box = constructor_box layout.addWidget(constructor_box, row, 0) row += 1 # buttons ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): constructor_txt = constructor_box.toPlainText() try: strategy = eval(constructor_txt) strategy.project = self.instance.project self.simgr.strategies[strategy.__class__.__name__] = strategy self.close() except NameError as e: # error QMessageBox.about( self, 'Error', f"{str(e)}, \nMake sure to fill in all positional arguments." ) ok_button.clicked.connect(do_ok) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) self.main_layout.addLayout(layout) self.main_layout.addLayout(buttons_layout)
class MainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self._highlighter = Highlighter() self.setup_file_menu() self.setup_editor() self.setCentralWidget(self._editor) self.setWindowTitle(self.tr("Syntax Highlighter")) def new_file(self): self._editor.clear() def open_file(self, path=""): file_name = path if not file_name: file_name, _ = QFileDialog.getOpenFileName( self, self.tr("Open File"), "", "qmake Files (*.pro *.prf *.pri)") if file_name: inFile = QFile(file_name) if inFile.open(QFile.ReadOnly | QFile.Text): stream = QTextStream(inFile) self._editor.setPlainText(stream.readAll()) def setup_editor(self): variable_format = QTextCharFormat() variable_format.setFontWeight(QFont.Bold) variable_format.setForeground(Qt.blue) self._highlighter.add_mapping("\\b[A-Z_]+\\b", variable_format) single_line_comment_format = QTextCharFormat() single_line_comment_format.setBackground(QColor("#77ff77")) self._highlighter.add_mapping("#[^\n]*", single_line_comment_format) quotation_format = QTextCharFormat() quotation_format.setBackground(Qt.cyan) quotation_format.setForeground(Qt.blue) self._highlighter.add_mapping("\".*\"", quotation_format) function_format = QTextCharFormat() function_format.setFontItalic(True) function_format.setForeground(Qt.blue) self._highlighter.add_mapping("\\b[a-z0-9_]+\\(.*\\)", function_format) font = QFont() font.setFamily("Courier") font.setFixedPitch(True) font.setPointSize(10) self._editor = QPlainTextEdit() self._editor.setFont(font) self._highlighter.setDocument(self._editor.document()) def setup_file_menu(self): file_menu = self.menuBar().addMenu(self.tr("&File")) new_file_act = file_menu.addAction(self.tr("&New...")) new_file_act.setShortcut(QKeySequence(QKeySequence.New)) new_file_act.triggered.connect(self.new_file) open_file_act = file_menu.addAction(self.tr("&Open...")) open_file_act.setShortcut(QKeySequence(QKeySequence.Open)) open_file_act.triggered.connect(self.open_file) quit_act = file_menu.addAction(self.tr("E&xit")) quit_act.setShortcut(QKeySequence(QKeySequence.Quit)) quit_act.triggered.connect(self.close) help_menu = self.menuBar().addMenu("&Help") help_menu.addAction("About &Qt", qApp.aboutQt)
class SourceryPane(QWidget, DockContextHandler): def __init__(self, parent, name): global panes panes.append(self) QWidget.__init__(self, parent) DockContextHandler.__init__(self, self, name) self.actionHandler = UIActionHandler() self.actionHandler.setupActionHandler(self) # Top: Headers with line info header_layout = QFormLayout() self.function_info = QLabel("") self.line_info = QLabel("") header_layout.addRow(self.tr("Function:"), self.function_info) header_layout.addRow(self.tr("Line:"), self.line_info) # Middle: main source display pane textbox_layout = QVBoxLayout() self.textbox = QPlainTextEdit() self.textbox.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap) self.textbox.setReadOnly(True) font = getMonospaceFont(self) self.textbox.setFont(font) font = QFontMetrics(font) self.textbox.setMinimumWidth(40 * font.averageCharWidth()) self.textbox.setMinimumHeight(30 * font.lineSpacing()) textbox_layout.addWidget(self.textbox) # Bottom: buttons for stop/start, and substitution paths footer_layout = QVBoxLayout() sync_button_layout = QHBoxLayout() self.sync_button = QPushButton("Turn Source Sync Off") sync_button_layout.addWidget(self.sync_button) path_layout = QFormLayout() self.original_path = QLineEdit() self.substitute_path = QLineEdit() self.substitute_path_button = QPushButton("Do Path Substitution") path_layout.addRow(self.tr("Original Path:"), self.original_path) path_layout.addRow(self.substitute_path_button, self.substitute_path) footer_layout.addLayout(sync_button_layout) footer_layout.addLayout(path_layout) # Putting all the child layouts together layout = QVBoxLayout() layout.addLayout(header_layout) layout.addLayout(textbox_layout) layout.addLayout(footer_layout) self.setLayout(layout) # Set up button signals self.substitute_path_button.clicked.connect(self.do_path_substitution) self.sync_button.clicked.connect(self.toggle_sync) # Actual storage variables self.bv = None self.filename = None self.do_sync = True self.path_substitutions = {} self.failed_substitutions = [] def do_path_substitution(self): original_path = self.original_path.text() new_path = self.substitute_path.text() if isinstance(original_path, bytes): original_path = original_path.decode() new_path = new_path() if original_path == "": log_warn("Path substitution error: Original path can't be blank") elif new_path == "": if original_path in self.path_substitutions: old_sub = self.path_substitutions.pop(original_path) log_info("Removed path substitution: %s -> %s" % (original_path, old_sub)) else: log_warn( "Path substitution error: New substitute path can't be blank" ) else: self.path_substitutions[original_path] = new_path log_info("Added path substitution: %s -> %s" % (original_path, new_path)) self.failed_substitutions = [ ] # clear failures when new path added def toggle_sync(self): if self.do_sync is True: self.do_sync = False self.sync_button.setText("Turn Source Sync On") else: # self.do_sync is False: self.do_sync = True self.sync_button.setText("Turn Source Sync Off") def set_text(self, text): self.textbox.setPlainText(text) def set_line(self, text): self.line_info.setText(text) def set_function(self, text): self.function_info.setText(text) def check_path_substitution(self, path): """Checks for files using path substitutions, going from longest to shortest original path""" sorted_original_paths = sorted(self.path_substitutions.keys(), key=lambda k: len(k), reverse=True) candidate_matches = [] for candidate_path in sorted_original_paths: if candidate_path in path: substitute_pattern = self.path_substitutions[candidate_path] substitute_path = path.replace(candidate_path, substitute_pattern) substitute_path = os.path.expanduser(substitute_path) candidate_matches.append(substitute_path) if os.path.exists(substitute_path): return substitute_path # Only log_warn once per file, and only if the user has tried to add translations if path not in self.failed_substitutions: if len(self.path_substitutions) > 0: log_warn("Failed to find substitution for %s" % path) log_info("Current substitution paths:") for orig_path, sub_path in self.path_substitutions.items(): log_info(" %s => %s" % (orig_path, sub_path)) log_info("Matching patterns' failed substitute paths:") for candidate in candidate_matches: log_info(" %s" % candidate) self.failed_substitutions.append(path) return "" def update_source(self, current_location): source_line = addr2line(self.filename, current_location) line_number_int = -1 text = "" function_name = "" if source_line.startswith("?"): line_text = "No source mapping for address 0x%x" % current_location elif source_line.startswith("ERROR:"): line_text = "%s" % source_line else: filepath, line_number_str, function_name = source_line.split(":") # handle lines like: "16 (discriminator 1)" line_number_int = int(line_number_str.split(' ')[0]) line_text = "%s:%s" % (filepath, line_number_str) # Check for the file, then for subsitutions if not os.path.exists(filepath): new_path = self.check_path_substitution(filepath) if new_path == "": self.textbox.setLineWrapMode( QPlainTextEdit.LineWrapMode.WidgetWidth) text = '[!] Source file "%s" not found\n' % filepath text += '[*] Associated line info: "%s"' % source_line else: filepath = new_path # If we still don't have a good path, the text is set to the correct error if os.path.exists(filepath): self.textbox.setLineWrapMode( QPlainTextEdit.LineWrapMode.NoWrap) with open(filepath, "r") as f: text = f.read() self.set_text(text) self.set_line(line_text) self.set_function(function_name) if line_number_int != -1: self.set_cursor(line_number_int) else: self.reset_cursor() def reset_cursor(self): doc = self.textbox.document() cursor = QTextCursor(doc) cursor.movePosition(QTextCursor.Start) self.textbox.setTextCursor(cursor) def set_cursor(self, line_number): doc = self.textbox.document() cursor = QTextCursor(doc) cursor.movePosition(QTextCursor.Start) for _ in range(line_number - 1): cursor.movePosition(QTextCursor.Down) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) self.textbox.setTextCursor(cursor) self.textbox.centerCursor() def notifyOffsetChanged(self, offset): if self.filename: if self.do_sync: self.update_source(offset) def shouldBeVisible(self, view_frame): if view_frame is None: return False else: return True def notifyViewChanged(self, view_frame): if view_frame is None: pass else: self.bv = view_frame.actionContext().binaryView self.filename = self.bv.file.original_filename def contextMenuEvent(self, event): self.m_contextMenuManager.show(self.m_menu, self.actionHandler) @staticmethod def create_widget(name, parent, data=None): return SourceryPane(parent, name)
class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.textEdit = QPlainTextEdit() self.curFile = "" self.centralWidget = qtw.QWidget() self.mainWindow = self.createMainWindow() self.centralWidget.setLayout(self.mainWindow) self.setCentralWidget(self.centralWidget) #self.setFixedSize(1000, 550) self.createActions() self.createMenus() #self.createToolBars() self.createStatusBar() self.readSettings() self.textEdit.document().contentsChanged.connect(self.documentWasModified) #self.setCurrentFile("") self.setUnifiedTitleAndToolBarOnMac(True) #self.menuBar = qtw.QLayout.menuBar() #self.statusBar = qtw.QMainWindow.statusBar() self.Qsettings = QSettings() #self.connectlist() def createMainWindow(self): self.graphics = GraphicsWindow() self.spreadsheet = self.graphics.scene_class.spreadsheet self.control = self.spreadsheet.control self.controlobj = self.control.controlBox self.control.nextButton.clicked.connect(self.spreadsheet.update_table) self.control.nextButton.clicked.connect(self.graphics.update_view) self.control.prevButton.clicked.connect(self.spreadsheet.prev_table) self.control.prevButton.clicked.connect(self.graphics.prev_view) self.righttop = QVBoxLayout() self.righttop.addLayout(self.controlobj) self.righttop.addWidget(self.spreadsheet.table) self.mainWin = QHBoxLayout() self.mainWin.addWidget(self.graphics) self.mainWin.addLayout(self.righttop) return self.mainWin def closeEvent(self, event): if self.maybeSave: self.writeSettings event.accept() else: event.ignore() def newFile(self): if self.maybeSave: self.textEdit.clear() self.setCurrentFile("") def open(self): if self.maybeSave: fileName = QFileDialog.getOpenFileName(self) if not fileName.isEmpty(): self.loadFile(fileName) def save(self): if self.curFile == "": return self.saveAs else: return self.saveFile(self.curFile) def saveAs(self): fileName = QFileDialog.getSaveFileName(self) if fileName.isEmpty(): return False return self.saveFile(fileName) def about(self): QMessageBox.about(self, "About Application\n", "The <b>Application</b> example demonstrates how to\n" "write modern GUI applications using Qt, With a menu bar\n" "toolbars, and a status bar.") def documentWasModified(self): self.setWindowModified(self.textEdit.document().isModified()) def createActions(self): self.Act = QAction(QIcon(":/images/new.png"), "&New", self) self.Act.setShortcuts(QKeySequence.New) self.Act.setStatusTip("Create a new file") self.Act.triggered.connect(self.newFile) self.openAct = QAction(QIcon(":/images/new.png"), "&Open", self) self.openAct.setShortcuts(QKeySequence.Open) self.openAct.setStatusTip("Open an exsting file") self.openAct.triggered.connect(self.open) self.saveAct = QAction("&Save", self) self.saveAct.setShortcuts(QKeySequence.Save) self.saveAct.setStatusTip("Save a file") self.saveAct.triggered.connect(self.save) self.saveasAct = QAction("&Save as", self) self.saveasAct.setShortcuts(QKeySequence.SaveAs) self.saveasAct.setStatusTip("Save as a file") self.saveasAct.triggered.connect(self.saveAs) self.aboutQtAct = QAction("About &Qt", self) self.aboutQtAct.setStatusTip("Show the Qt library's About box") self.aboutQtAct.triggered.connect(qApp.aboutQt) self.exitAct = QAction("&Exit", self) self.exitAct.setStatusTip("Exit") self.exitAct.triggered.connect(self.exit) #self.cutAct.setEnabled(False) #self.copyAct.setEnabled(False) #self.textEdit.copyAvailable[bool].connect(self.cutAct.setEnabled) #self.textEdit.copyAvailable[bool].connect(self.copyAct.setEnabled) self.findAct = QAction("&Find", self) self.findAct.triggered.connect(self.find) self.gotocellAct = QAction("&GoToCell", self) self.gotocellAct.triggered.connect(self.gotocell) self.sortAct = QAction("&Sort", self) self.sortAct.triggered.connect(self.sort) self.undoAct = QAction("&Undo", self) self.redoAct = QAction("&Redo", self) self.cutAct = QAction("&Cut", self) self.copyAct = QAction("&Copy", self) self.pasteAct = QAction("&Paste", self) self.aboutAct = QAction("&About", self) self.boldAct = QAction("&Bold", self) self.italicAct = QAction("&Italic", self) self.leftAlignAct = QAction("&LeftAlign", self) self.rightAlignAct = QAction("&Alignment", self) self.justifyAct = QAction("&Justify", self) self.centerAct = QAction("&Center", self) self.setLineSpacingAct = QAction("&setLine", self) self.setParagrahSpacingAct = QAction("&setPAragrah", self) def createStatusBar(self): self.statusBar().showMessage("Ready") def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.Act) self.fileMenu.addAction(self.openAct) self.fileMenu.addAction(self.saveAct) 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.addSeparator() self.editMenu.addAction(self.cutAct) self.editMenu.addAction(self.copyAct) self.editMenu.addAction(self.pasteAct) self.editMenu.addSeparator() self.dataMenu = self.menuBar().addMenu("&Data") self.dataMenu.addAction(self.findAct) self.dataMenu.addAction(self.gotocellAct) self.dataMenu.addAction(self.sortAct) self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) self.formatMenu = self.editMenu.addMenu("&Fornat") self.formatMenu.addAction(self.boldAct) self.formatMenu.addAction(self.italicAct) self.formatMenu.addSeparator().setText("Alignment") self.formatMenu.addAction(self.leftAlignAct) self.formatMenu.addAction(self.rightAlignAct) self.formatMenu.addAction(self.justifyAct) self.formatMenu.addAction(self.centerAct) self.formatMenu.addSeparator() self.formatMenu.addAction(self.setLineSpacingAct) self.formatMenu.addAction(self.setParagrahSpacingAct) def readSettings(self): self.settings = QSettings("Trolltrch", "Application Example") self.pos = self.settings.value("pos", QPoint(200, 200))#.toPoint() self.size = self.settings.value("size", QSize(400, 400))#.toSize() self.resize(self.size) self.move(self.pos) def writeSettings(self): self.settings = QSettings("Trolltech", "Application Example") self.settings.setValue("pos", self.pos) self.setting.setValue("size", self.size) def maybeSave(self): if self.textEdit.document().isModified(): ret = QMessageBox.warning(self, "Application", "The document has been modified.\n" "Do you want to save your changes?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.cancel) if ret == QMessageBox.Save: return self.save elif ret == QMessageBox.Cancel: return False return True def loadFile(self, fileName): file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning(self, "Application", "Cannot read file" "{}:\n{}".format(fileName, file.errorString())) return False in_ = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) self.textEdit.setPlainText(in_.readAll()) QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File loaded", 2000) def saveFile(self, fileName): file = QFile(fileName) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Application", "Cannot write file %1:\n%2.".arg(fileName) .arg(file.errorString())) return False self.out = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) self.out = self.textEdit.toPlainText() QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File saved", 2000) return True def setCurrentFile(self, fileName): self.curFile = fileName self.textEdit.document().setModified(False) self.setWindowModified(False) if self.curFile.isEmpty(): shownName = "untitled.txt" else: shownName = strippedName(curFile) setWindowTitle(tr("%1[*] - %2").arg(shownName).arg("Application")) def strippedName(self, fullFileName): return QFileInfo(fullFileName).fileName() def exit(self): pass ''' def connectlist(self): self.copyAct.triggered.connect(self.spreadsheet.copy()) self.pasteAct.triggered.connect(self.spreadsheet.paste()) # self. ''' def find(self): print("findをクリックしました") self.fw = FindDialog() self.fw.show() self.fw.activateWindow() def gotocell(self): self.gw = GoToCell() self.gw.show() self.gw.activateWindow() def sort(self): self.sw = Sort() self.sw.show() self.sw.activateWindow()
class TrackEditor(Observation, QWidget, metaclass=FinalMeta): def __init__(self, subject, powermode=False, allowEditBackend=False, confirmUpdate=True): Observation.__init__(self, subject) QWidget.__init__(self) self._template = None self.deleted = False self.shouldSave = False self.powermode = powermode self.allowEditBackend = allowEditBackend self.confirmUpdate = confirmUpdate self.descriptionMaxLen = 1000 self._code = "" layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) if self.allowEditBackend: self._initForm() self._initCodeEditor() self.setFixedSize(630, 600) self.setAttribute(Qt.WA_StyledBackground) self.setStyleSheet(Theme.templateEditor.style) self.setContextMenuPolicy(Qt.NoContextMenu) self.setWindowModality(Qt.ApplicationModal) self.setWindowFlags(Qt.Tool | Qt.WindowTitleHint | Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowMaximizeButtonHint) self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.codeView.closeShortcut.setEnabled(False) QShortcut(QKeySequence(self.tr("Ctrl+w")), self, self.close) def _initForm(self): layout = QFormLayout() self.runCommand = QLineEdit(self, maxLength=200) self.runCommand.setStyleSheet(Theme.templateEditor.inputStyle) self.runCommand.setFont(Theme.templateEditor.inputCodeFont) self.runCommand.setFixedHeight(Theme.templateEditor.inputHeight) if self.powermode: self.backendName = QLineEdit(self, maxLength=20) self.backendName.setStyleSheet(Theme.templateEditor.inputStyle) self.backendName.setFont(Theme.templateEditor.inputFont) self.backendName.setFixedHeight(Theme.templateEditor.inputHeight) self.editorMode = QComboBox() [self.editorMode.addItem(mode) for mode in self._availableModes()] self.editorMode.currentIndexChanged.connect( self.onEditorModeChanged) self.inputRegex = QLineEdit(self, maxLength=100) self.inputRegex.setToolTip("regex") self.inputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.inputRegex.setFont(Theme.templateEditor.inputCodeFont) self.inputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.inputReplace = QLineEdit(self, maxLength=100) self.inputReplace.setToolTip("substitution string") self.inputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.inputReplace.setFont(Theme.templateEditor.inputCodeFont) self.inputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.outputRegex = QLineEdit(self, maxLength=100) self.outputRegex.setToolTip("regex") self.outputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.outputRegex.setFont(Theme.templateEditor.inputCodeFont) self.outputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.outputReplace = QLineEdit(self, maxLength=100) self.outputReplace.setToolTip("substitution string") self.outputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.outputReplace.setFont(Theme.templateEditor.inputCodeFont) self.outputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.description = QPlainTextEdit(self, minimumHeight=80) self.description.setStyleSheet( Theme.templateEditor.descriptionStyle) self.description.setFont(Theme.templateEditor.descriptionFont) layout.addRow(self.tr("Run Command:"), self.runCommand) if self.powermode: layout.addRow(self.tr("Backend Name:"), self.backendName) layout.addRow(self.tr("Editor Mode:"), self.editorMode) inputMiddlewareLayout = QHBoxLayout() inputMiddlewareLayout.addWidget(self.inputRegex) inputMiddlewareLayout.addWidget(self.inputReplace) layout.addRow(self.tr("Input Middleware:"), inputMiddlewareLayout) outputMiddlewareLayout = QHBoxLayout() outputMiddlewareLayout.addWidget(self.outputRegex) outputMiddlewareLayout.addWidget(self.outputReplace) layout.addRow(self.tr("Output Middleware:"), outputMiddlewareLayout) layout.addRow(self.tr("Description:"), self.description) layout.setSpacing(10) layout.setContentsMargins(10, 10, 10, 10) self.layout().addLayout(layout) def _initCodeEditor(self): self.codeView = CodeView(self.subject, viewTip=False) self.layout().addWidget(QLabel("Setup Code:", margin=10)) self.layout().addWidget(self.codeView) self.codeView.setDelegate(self) def _availableModes(self): return acePropertyNames("mode-", ".js", False) def onEditorModeChanged(self, e): mode = self.editorMode.itemText(e) self.codeView.setMode(mode) if self._template is not None: self._template.editor_mode = mode def onSave(self): self.shouldSave = True if self.allowEditBackend: self._template.run_command = self.runCommand.text().strip() if self.powermode and self.allowEditBackend: self._template.backend_name = self.backendName.text().strip() self._template.editor_mode = self.editorMode.currentText() self._template.backend_middleware.input.regex = \ self.inputRegex.text() self._template.backend_middleware.input.substitution = \ self.inputReplace.text() self._template.backend_middleware.output.regex = \ self.outputRegex.text() self._template.backend_middleware.output.substitution = \ self.outputReplace.text() self._template.description = self.description.toPlainText( )[:self.descriptionMaxLen] self._template.setup_code = self._code def setTemplate(self, delegate): self._template = delegate self.codeView.setDelegate(self) self.deserialize() def setCode(self, code, notify): if self._template is None: return self._code = code if self.shouldSave: self._template.setup_code = code self.onTemplateUpdate() def onTemplateUpdate(self): pass def code(self): if self._template is None: return "" return self._template.setup_code def codeWindowTitle(self): return "Track Template Editor" def deserialize(self): if self._template is None: return if self.allowEditBackend: self.runCommand.setText(self._template.run_command.strip()) if self.powermode and self.allowEditBackend: self.backendName.setText(self._template.backend_name.strip()) self.editorMode.setCurrentText(self._template.editor_mode) self.inputRegex.setText( self._template.backend_middleware.input.regex) self.inputReplace.setText( self._template.backend_middleware.input.substitution) self.outputRegex.setText( self._template.backend_middleware.output.regex) self.outputReplace.setText( self._template.backend_middleware.output.substitution) self.description.document().setPlainText( self._template.description) else: self.codeView.setMode(self._template.editor_mode) self._code = self._template.setup_code self.setWindowTitle("Track Template Editor") def delete(self): self.deleted = True self.codeView.delete() self.unregister() self.setParent(None) self.deleteLater() def template(self): return self._template def showEvent(self, event): self.shouldSave = False self.codeView.show() super().showEvent(event) def closeEvent(self, event): if self._template is not None and not self.deleted: if self.confirmUpdate: question = "Do you want to save changes in " +\ f"{self._template.backend_name} template?" confirmation = ConfirmationDialog("Update Track Template", question) if confirmation.exec_() == ConfirmationDialog.Yes: self.onSave() else: self.onSave() self.codeView.close() super().closeEvent(event)
class PDLEditor(QWidget): def __init__(self): QWidget.__init__(self) self.setLayout(QGridLayout()) split = QSplitter(Qt.Horizontal) split.setChildrenCollapsible(False) self.vis_area = WidgetVisualizationArea() split.addWidget(self.vis_area) edit_pane = QWidget() edit_pane.setLayout(QVBoxLayout()) font = QFont('Courier New', 11) self.editor = QPlainTextEdit() self.editor.document().setDefaultFont(font) edit_pane.layout().addWidget(self.editor) compile_b = QPushButton("Compile") compile_b.clicked.connect(self.compilePDL) edit_pane.layout().addWidget(compile_b) self.messages = QPlainTextEdit() self.messages.setReadOnly(True) self.messages.document().setDefaultFont(font) edit_pane.layout().addWidget(self.messages) split.addWidget(edit_pane) self.layout().addWidget(split) @Slot() def compilePDL(self): self.messages.appendPlainText('------------') pdl_text = self.editor.toPlainText() try: parser = top.Parser([pdl_text], 's') plumb = parser.make_engine() except Exception as e: self.messages.appendPlainText( 'Error encountered in PDL compilation:') self.messages.appendPlainText(str(e)) scrollbar = self.messages.verticalScrollBar() scrollbar.setValue(scrollbar.maximum()) return if not plumb.is_valid(): self.messages.appendPlainText('Plumbing engine is invalid:') error_str = str('\n'.join( [e.error_message for e in plumb.error_set])) self.messages.appendPlainText(error_str) scrollbar = self.messages.verticalScrollBar() scrollbar.setValue(scrollbar.maximum()) return self.messages.appendPlainText('PDL compilation successful') scrollbar = self.messages.verticalScrollBar() scrollbar.setValue(scrollbar.maximum()) self.vis_area.visualizer.uploadEngineInstance(plumb)
class MyTextEditor(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.textEdit = QPlainTextEdit() self.setCentralWidget(self.textEdit) self.createActions() self.readSettings() self.setCurrentFile("") def createActions(self): self.toolBar = self.addToolBar("main tool bar") self.menuBar = self.menuBar() self.fileMenu = self.menuBar.addMenu('File') self.helpMenu = self.menuBar.addMenu('Help') Act = QAction(QIcon(":/icons/new.png"), self.tr("&New"), self) Act.setShortcuts(QKeySequence.New) Act.setStatusTip(self.tr("Create a new file")) Act.triggered.connect(self.newFile) self.fileMenu.addAction(Act) self.toolBar.addAction(Act) openAct = QAction(QIcon(":/icons/openconf.png"), self.tr("&Open..."), self) openAct.setShortcuts(QKeySequence.Open) openAct.setStatusTip(self.tr("Open an existing file")) self.fileMenu.addAction(openAct) self.toolBar.addAction(openAct) openAct.triggered.connect(self.open) saveAct = QAction(QIcon(":/icons/save.png"), self.tr("&Save..."), self) saveAct.setShortcuts(QKeySequence.Save) saveAct.setStatusTip(self.tr("Save a file")) self.fileMenu.addAction(saveAct) self.toolBar.addAction(saveAct) saveAct.triggered.connect(self.save) self.fileMenu.addSeparator() quitAct = QAction(QIcon(":/icons/exit.png"), self.tr("&Exit..."), self) quitAct.setShortcuts(QKeySequence.Close) quitAct.setStatusTip(self.tr("Exit")) self.fileMenu.addAction(quitAct) self.toolBar.addAction(quitAct) quitAct.triggered.connect(self.exit) aboutQtAct = QAction(self.tr("About &Qt"), self) aboutQtAct.setStatusTip(self.tr("Show the Qt library's About box")) aboutQtAct.triggered.connect(self.about) self.helpMenu.addAction(aboutQtAct) def loadFile(self, fileName): file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning(self, self.tr("Application"), self.tr("Cannot read file " "{}:\n{}.".format(fileName, file.errorString()))) return inStream = QTextStream(file) QApplication.setOverrideCursor(QtGui.Qt.WaitCursor) self.textEdit.setPlainText(inStream.readAll()) print(inStream.readAll()) QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage(self.tr("File loaded"), 2000) def newFile(self): if self.maybeSave(): self.fileName = QFileDialog.getOpenFileName(self) if not self.fileName == "": self.loadFile(self.fileName[0]) def open(self): if self.maybeSave(): fileName = QFileDialog.getOpenFileName(self) if not fileName == "" : self.loadFile(fileName[0]) def save(self): if self.curFile == "": return self.saveAs() else: return self.saveFile(self.curFile) def saveAs(self): fileName = QFileDialog.getSaveFileName(self) if fileName == "" : return False return self.saveFile(fileName[0]) def saveFile(self, fileName): file = QFile(fileName) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, self.tr("Application"), self.tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())) return False out = QTextStream(file) QApplication.setOverrideCursor(QtGui.Qt.WaitCursor) print (self.textEdit.toPlainText()) out << self.textEdit.toPlainText() QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage(self.tr("File saved"), 2000) return True def documentWasModified(self): self.setWindowModified(self.textEdit.document().isModified()) def about(self): QMessageBox.about(self, self.tr("About Application"), self.tr("The <b>Application</b> example demonstrates how to " "write modern GUI applications using Qt, with a menu bar, " "toolbars, and a status bar.")) def File(self): if self.maybeSave(): self.textEdit.clear() self.setCurrentFile("") def setCurrentFile(self,fileName): self.curFile = fileName self.textEdit.document().setModified(False) self.setWindowModified(False) if self.curFile == "": shownName = "untitled.txt" else: shownName = self.strippedName(self.curFile) self.setWindowTitle(self.tr("{}[*] - {}").format(shownName,self.tr("Application"))) def strippedName(self, fullFileName): return QFileInfo(fullFileName).fileName() def readSettings(self): settings = QSettings("Trolltech", "Application Example") pos = settings.value("pos", QPoint(200, 200)) size = settings.value("size", QSize(400, 400)) self.resize(size) self.move(pos) def writeSettings(self): settings = QSettings("Trolltech", "Application Example") settings.setValue("pos", self.pos()) settings.setValue("size", self.size()) def closeEvent(self, event): if self.maybeSave(): self.writeSettings() event.accept() else: event.ignore() def exit(self): self.close() #with call to closeEvent #self.deleteLater() #Do not call closeEvent def maybeSave(self): if self.textEdit.document().isModified(): ret = QMessageBox.warning(self, self.tr("Application"), self.tr("The document has been modified.\n" "Do you want to save your changes?"), QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: return self.save() elif ret == QMessageBox.Cancel: return False return True
def _init_widgets(self): layout = QGridLayout() row = 0 # validation_failures = set() addr = hex(self._addr) address_label = QLabel(self) address_label.setText(f"Hook at address {addr}:") layout.addWidget(address_label, row, 0) row += 1 options_container = QGroupBox(self) options = QVBoxLayout() for name, template in sorted(self.templates.items()): child = QRadioButton() child.setText(name) child.template = template child.toggled.connect(self.selected) options.addWidget(child) scroll_area = QScrollArea(self) scroll_area.setWidgetResizable(True) widget = QWidget() scroll_area.setWidget(widget) layout_scroll = QVBoxLayout(widget) header_label = QLabel(self) header_label.setText("Presets:") layout_scroll.addWidget(header_label) layout_scroll.addWidget(options_container) options_container.setLayout(options) layout.addWidget(scroll_area, row, 0) row += 1 function_box = QPlainTextEdit(self) if addr in self.hooks.keys(): function_box.insertPlainText(self.hooks[addr]) highlight = PythonHighlighter(function_box.document()) function_box.setWordWrapMode(QTextOption.WordWrap) self._function_box = function_box layout.addWidget(function_box, row, 0) row += 1 # def add_indent(): # txt = function_box.toPlainText() # if txt.endswith('\n'): # embed() # indent = txt.search() # if txt.endswith(':\n'): # function_box.insertPlainText(' ') # function_box.textChanged.connect(add_indent) # TODO: add python autoindent # buttons ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): hook_code_string = function_box.toPlainText() self.instance.apply_hook(self._addr, hook_code_string) self.hooks[hex(self._addr)] = hook_code_string disasm_view = self.instance.workspace.view_manager.first_view_in_category( "disassembly") # So the hook icon shows up in the disasm view disasm_view.refresh() self.close() ok_button.clicked.connect(do_ok) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) self.main_layout.addLayout(layout) self.main_layout.addLayout(buttons_layout)