コード例 #1
0
class SALErrorCodeWidget(QWidget):
    """Displays errorCode messages."""
    def __init__(self, comm):
        super().__init__()

        layout = QVBoxLayout()

        self.plainText = QPlainTextEdit()
        self.plainText.setReadOnly(True)
        self.plainText.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.plainText.setCenterOnScroll(True)
        font = QFont("Monospace")
        font.setStyleHint(QFont.TypeWriter)
        self.plainText.setFont(font)

        layout.addWidget(self.plainText)
        self.setLayout(layout)

        comm.errorCode.connect(self.errorCode)

    @Slot()
    def errorCode(self, data):
        date = datetime.fromtimestamp(data.private_sndStamp).isoformat(
            sep=" ", timespec="milliseconds")
        self.plainText.appendHtml(
            f"{date} [<b>{data.errorCode:06X}</b>] <span style='color:{'green' if data.errorCode==0 else 'red'}'>{data.errorReport}</span>"
        )
        self.plainText.ensureCursorVisible()
コード例 #2
0
 def _create_raw_widget(self, ) -> QWidget:
     widget = QPlainTextEdit(self)
     font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
     font.setFixedPitch(True)
     metrics = QFontMetrics(font)
     widget.setFont(font)
     widget.setTabStopDistance(2 * metrics.width(' '))
     as_signal_instance(widget.textChanged).connect(self._on_raw_changed, )
     return widget
コード例 #3
0
 def add_new_script(self):
     code_text_edit = QPlainTextEdit()
     code_text_edit.setPlainText('test code')
     code_text_edit.setFont(self.code_font)
     # code_text_edit.setStyleSheet('background: black; color: grey;')
     self.code_text_edits.append(code_text_edit)
     # print('before: ', self.height())
     self.layout().addWidget(code_text_edit)
     # print('after: ', self.height())
     self.parent_node_instance.update_shape()
コード例 #4
0
ファイル: generate_gui.py プロジェクト: zero804/qtbase
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.functionSelector = OptionsSelector(
            parent=self, option_manager=function_describing_options())
        self.layout.addWidget(self.functionSelector)
        self.testcaseSelector = OptionsSelector(
            parent=self, option_manager=testcase_describing_options())
        self.layout.addWidget(self.testcaseSelector)

        self.plainTextEdit = QPlainTextEdit()
        self.plainTextEdit.setReadOnly(True)
        self.layout.addWidget(self.plainTextEdit)
        self.plainTextEdit.setFont(PySide2.QtGui.QFont("Fira Code", 8))

        # temp
        self.functionSelector.optionsSelected.connect(
            lambda o: self._handle_function_change())
        self.testcaseSelector.optionsSelected.connect(
            lambda o: self._handle_testcase_change())

        self._handle_function_change()

    def _handle_function_change(self):
        options = self.functionSelector.get_current_option_set()
        if m := skip_function_description(options):
            self.plainTextEdit.setPlainText(m)
            return

        options_to_disable = disabled_testcase_describing_options(options)
        self.testcaseSelector.set_disabled_options(options_to_disable)

        options.update(self.testcaseSelector.get_current_option_set())
        if m := skip_testcase_description(options):
            self.plainTextEdit.setPlainText(m)
            return
コード例 #5
0
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)
コード例 #6
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        layout = QVBoxLayout()
        self.editor = QPlainTextEdit(
        )  # Could also use a QTextEdit and set self.editor.setAcceptRichText(False)

        # Setup the QTextEdit editor configuration
        fixedfont = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        fixedfont.setPointSize(12)
        self.editor.setFont(fixedfont)

        # self.path holds the path of the currently open file.
        # If none, we haven't got a file open yet (or creating new).
        self.path = None

        layout.addWidget(self.editor)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.status = QStatusBar()
        self.setStatusBar(self.status)

        file_toolbar = QToolBar("File")
        file_toolbar.setIconSize(QSize(14, 14))
        self.addToolBar(file_toolbar)
        file_menu = self.menuBar().addMenu("&File")

        open_file_action = QAction(
            QIcon(os.path.join('images', 'blue-folder-open-document.png')),
            "Open file...", self)
        open_file_action.setStatusTip("Open file")
        open_file_action.triggered.connect(self.file_open)
        file_menu.addAction(open_file_action)
        file_toolbar.addAction(open_file_action)

        save_file_action = QAction(QIcon(os.path.join('images', 'disk.png')),
                                   "Save", self)
        save_file_action.setStatusTip("Save current page")
        save_file_action.triggered.connect(self.file_save)
        file_menu.addAction(save_file_action)
        file_toolbar.addAction(save_file_action)

        saveas_file_action = QAction(
            QIcon(os.path.join('images', 'disk--pencil.png')), "Save As...",
            self)
        saveas_file_action.setStatusTip("Save current page to specified file")
        saveas_file_action.triggered.connect(self.file_saveas)
        file_menu.addAction(saveas_file_action)
        file_toolbar.addAction(saveas_file_action)

        print_action = QAction(QIcon(os.path.join('images', 'printer.png')),
                               "Print...", self)
        print_action.setStatusTip("Print current page")
        print_action.triggered.connect(self.file_print)
        file_menu.addAction(print_action)
        file_toolbar.addAction(print_action)

        edit_toolbar = QToolBar("Edit")
        edit_toolbar.setIconSize(QSize(16, 16))
        self.addToolBar(edit_toolbar)
        edit_menu = self.menuBar().addMenu("&Edit")

        undo_action = QAction(
            QIcon(os.path.join('images', 'arrow-curve-180-left.png')), "Undo",
            self)
        undo_action.setStatusTip("Undo last change")
        undo_action.triggered.connect(self.editor.undo)
        edit_menu.addAction(undo_action)

        redo_action = QAction(QIcon(os.path.join('images', 'arrow-curve.png')),
                              "Redo", self)
        redo_action.setStatusTip("Redo last change")
        redo_action.triggered.connect(self.editor.redo)
        edit_toolbar.addAction(redo_action)
        edit_menu.addAction(redo_action)

        edit_menu.addSeparator()

        cut_action = QAction(QIcon(os.path.join('images', 'scissors.png')),
                             "Cut", self)
        cut_action.setStatusTip("Cut selected text")
        cut_action.triggered.connect(self.editor.cut)
        edit_toolbar.addAction(cut_action)
        edit_menu.addAction(cut_action)

        copy_action = QAction(
            QIcon(os.path.join('images', 'document-copy.png')), "Copy", self)
        copy_action.setStatusTip("Copy selected text")
        copy_action.triggered.connect(self.editor.copy)
        edit_toolbar.addAction(copy_action)
        edit_menu.addAction(copy_action)

        paste_action = QAction(
            QIcon(os.path.join('images', 'clipboard-paste-document-text.png')),
            "Paste", self)
        paste_action.setStatusTip("Paste from clipboard")
        paste_action.triggered.connect(self.editor.paste)
        edit_toolbar.addAction(paste_action)
        edit_menu.addAction(paste_action)

        select_action = QAction(
            QIcon(os.path.join('images', 'selection-input.png')), "Select all",
            self)
        select_action.setStatusTip("Select all text")
        select_action.triggered.connect(self.editor.selectAll)
        edit_menu.addAction(select_action)

        edit_menu.addSeparator()

        wrap_action = QAction(
            QIcon(os.path.join('images', 'arrow-continue.png')),
            "Wrap text to window", self)
        wrap_action.setStatusTip("Toggle wrap text to window")
        wrap_action.setCheckable(True)
        wrap_action.setChecked(True)
        wrap_action.triggered.connect(self.edit_toggle_wrap)
        edit_menu.addAction(wrap_action)

        self.update_title()
        self.show()

    def dialog_critical(self, s):
        dlg = QMessageBox(self)
        dlg.setText(s)
        dlg.setIcon(QMessageBox.Critical)
        dlg.show()

    def file_open(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "Open file", "", "Text documents (*.txt);All files (*.*)")

        if path:
            try:
                with open(path, 'rU') as f:
                    text = f.read()

            except Exception as e:
                self.dialog_critical(str(e))

            else:
                self.path = path
                self.editor.setPlainText(text)
                self.update_title()

    def file_save(self):
        if self.path is None:
            # If we do not have a path, we need to use Save As.
            return self.file_saveas()

        self._save_to_path(self.path)

    def file_saveas(self):
        path, _ = QFileDialog.getSaveFileName(
            self, "Save file", "", "Text documents (*.txt);All files (*.*)")

        if not path:
            # If dialog is cancelled, will return ''
            return

        self._save_to_path(path)

    def _save_to_path(self, path):
        text = self.editor.toPlainText()
        try:
            with open(path, 'w') as f:
                f.write(text)

        except Exception as e:
            self.dialog_critical(str(e))

        else:
            self.path = path
            self.update_title()

    def file_print(self):
        dlg = QPrintDialog()
        if dlg.exec_():
            self.editor.print_(dlg.printer())

    def update_title(self):
        self.setWindowTitle(
            "%s - No2Pads" %
            (os.path.basename(self.path) if self.path else "Untitled"))

    def edit_toggle_wrap(self):
        self.editor.setLineWrapMode(1 if self.editor.lineWrapMode() ==
                                    0 else 0)
コード例 #7
0
ファイル: main.py プロジェクト: mattdoiron/idfplus
    def create_ui(self):
        """Setup main UI elements, dock widgets, UI-related elements, etc.
        """

        log.debug('Loading UI')

        # Undo Stack
        self.undo_stack = QUndoStack(self)
        self.undo_stack.setUndoLimit(100)

        # Object navigation history
        self.obj_history = deque([], config.MAX_OBJ_HISTORY)

        app = QApplication.instance()
        base_font = QFont()
        base_font.fromString(self.prefs['base_font'])
        app.setFont(base_font)

        # Object class table widget
        # classTable = QTableView(self)
        classTable = classtable.TableView(self)
        classTable.setObjectName("classTable")
        classTable.setAlternatingRowColors(True)
        classTable.setFrameShape(QFrame.StyledPanel)
        classTable_font = QFont()
        classTable_font.fromString(self.prefs['class_table_font'])
        classTable.setFont(classTable_font)
        fm = classTable.fontMetrics()
        classTable.setWordWrap(True)
        classTable.setEditTriggers(QAbstractItemView.EditKeyPressed |
                                   QAbstractItemView.DoubleClicked |
                                   QAbstractItemView.AnyKeyPressed |
                                   QAbstractItemView.SelectedClicked)
        # classTable.horizontalHeader().setMovable(True)
        # classTable.verticalHeader().setMovable(False)
        classTable.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
        classTable.verticalHeader().setSectionResizeMode(QHeaderView.Interactive)
        classTable.horizontalHeader().setDefaultSectionSize(self.prefs['default_column_width'])
        classTable.verticalHeader().setDefaultSectionSize(fm.height() + 0)
        classTable.setSelectionMode(QAbstractItemView.ExtendedSelection)
        classTable.setContextMenuPolicy(Qt.CustomContextMenu)
        classTable.customContextMenuRequested.connect(self.custom_table_context_menu)

        # Create table model and proxy layers for transposing and filtering
        self.classTableModel = classtable.IDFObjectTableModel(classTable)
        self.transposeableModel = classtable.TransposeProxyModel(self.classTableModel)
        self.transposeableModel.setSourceModel(self.classTableModel)
        self.sortableModel = classtable.SortFilterProxyModel(self.transposeableModel)
        self.sortableModel.setSourceModel(self.transposeableModel)

        # Assign model to table (enable sorting FIRST)
        # table.setSortingEnabled(True) # Disable for now, CRUD actions won't work!
        classTable.setModel(self.sortableModel)

        # Connect some signals
        selection_model = classTable.selectionModel()
        selection_model.selectionChanged.connect(self.table_selection_changed)
        scroll_bar = classTable.verticalScrollBar()
        scroll_bar.valueChanged.connect(self.scroll_changed)

        # These are currently broken
        # classTable.horizontalHeader().sectionMoved.connect(self.moveObject)
        # classTable.verticalHeader().sectionMoved.connect(self.moveObject)

        # Object class tree widget
        classTreeDockWidget = QDockWidget("Object Classes and Counts", self)
        classTreeDockWidget.setObjectName("classTreeDockWidget")
        classTreeDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)

        classTree = QTreeView(classTreeDockWidget)
        classTree.setUniformRowHeights(True)
        classTree.setAllColumnsShowFocus(True)
        classTree.setRootIsDecorated(False)
        classTree.setExpandsOnDoubleClick(True)
        classTree.setIndentation(15)
        classTree.setAnimated(True)
        classTree_font = QFont()
        classTree_font.fromString(self.prefs['class_tree_font'])
        classTree.setFont(classTree_font)
        classTree.setAlternatingRowColors(True)
        classTree.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        palette = classTree.palette()
        palette.setColor(QPalette.Highlight, Qt.darkCyan)
        classTree.setPalette(palette)

        class_tree_window = QWidget(classTreeDockWidget)
        class_tree_dock_layout_v = QVBoxLayout()
        class_tree_dock_layout_h = QHBoxLayout()
        class_tree_dock_layout_v.setContentsMargins(0, 8, 0, 0)
        class_tree_dock_layout_h.setContentsMargins(0, 0, 0, 0)

        class_tree_filter_edit = QLineEdit(classTreeDockWidget)
        class_tree_filter_edit.setPlaceholderText("Filter Classes")
        class_tree_filter_edit.textChanged.connect(self.treeFilterRegExpChanged)

        class_tree_filter_cancel = QPushButton("Clear", classTreeDockWidget)
        class_tree_filter_cancel.setMaximumWidth(45)
        class_tree_filter_cancel.clicked.connect(self.clearTreeFilterClicked)

        class_tree_dock_layout_h.addWidget(class_tree_filter_edit)
        class_tree_dock_layout_h.addWidget(class_tree_filter_cancel)
        class_tree_dock_layout_v.addLayout(class_tree_dock_layout_h)
        class_tree_dock_layout_v.addWidget(classTree)
        class_tree_window.setLayout(class_tree_dock_layout_v)

        classTreeDockWidget.setWidget(class_tree_window)
        classTreeDockWidget.setContentsMargins(0,0,0,0)

        # Comments widget
        commentDockWidget = QDockWidget("Comments", self)
        commentDockWidget.setObjectName("commentDockWidget")
        commentDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        commentView = UndoRedoTextEdit(commentDockWidget, self)
        commentView.setLineWrapMode(QTextEdit.FixedColumnWidth)
        commentView.setLineWrapColumnOrWidth(499)
        commentView.setFrameShape(QFrame.StyledPanel)
        commentView_font = QFont()
        commentView_font.fromString(self.prefs['comments_font'])
        commentView.setFont(commentView_font)
        commentDockWidget.setWidget(commentView)

        # Info and help widget
        infoDockWidget = QDockWidget("Info", self)
        infoDockWidget.setObjectName("infoDockWidget")
        infoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        infoView = QTextEdit(infoDockWidget)
        infoView.setFrameShape(QFrame.StyledPanel)
        infoView.setReadOnly(True)
        infoDockWidget.setWidget(infoView)

        # Node list and jump menu widget
        refDockWidget = QDockWidget("Field References", self)
        refDockWidget.setObjectName("refDockWidget")
        refDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        ref_model = reftree.ReferenceTreeModel(None, refDockWidget)
        refView = QTreeView(refDockWidget)
        refView.setModel(ref_model)
        refView.setUniformRowHeights(True)
        refView.setRootIsDecorated(False)
        refView.setIndentation(15)
        refView.setColumnWidth(0, 160)
        refView.setFrameShape(QFrame.StyledPanel)
        refDockWidget.setWidget(refView)
        refView.doubleClicked.connect(self.ref_tree_double_clicked)

        # Logging and debugging widget
        logDockWidget = QDockWidget("Log Viewer", self)
        logDockWidget.setObjectName("logDockWidget")
        logDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        logView = QPlainTextEdit(logDockWidget)
        logView.setLineWrapMode(QPlainTextEdit.NoWrap)
        logView.setReadOnly(True)
        logView_font = QFont()
        logView_font.fromString(self.prefs['base_font'])
        logView.setFont(logView_font)
        logView.ensureCursorVisible()
        logDockWidget.setWidget(logView)

        # Undo view widget
        undoDockWidget = QDockWidget("Undo History", self)
        undoDockWidget.setObjectName("undoDockWidget")
        undoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        undoView = QUndoView(self.undo_stack)
        undoDockWidget.setWidget(undoView)

        # Define corner docking behaviour
        self.setDockNestingEnabled(True)
        self.setCorner(Qt.TopLeftCorner,
                       Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner,
                       Qt.RightDockWidgetArea)
        self.setCorner(Qt.BottomLeftCorner,
                       Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner,
                       Qt.RightDockWidgetArea)

        # Assign main widget and dock widgets to QMainWindow
        self.setCentralWidget(classTable)
        self.addDockWidget(Qt.LeftDockWidgetArea, classTreeDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, commentDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, infoDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, refDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, undoDockWidget)

        # Store widgets for access by other objects
        self.classTable = classTable
        self.commentView = commentView
        self.infoView = infoView
        self.classTree = classTree
        self.logView = logView
        self.undoView = undoView
        self.refView = refView
        self.filterTreeBox = class_tree_filter_edit

        # Store docks for access by other objects
        self.commentDockWidget = commentDockWidget
        self.infoDockWidget = infoDockWidget
        self.classTreeDockWidget = classTreeDockWidget
        self.logDockWidget = logDockWidget
        self.undoDockWidget = undoDockWidget
        self.refDockWidget = refDockWidget

        # Perform other UI-related initialization tasks
        self.center()
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.setWindowIcon(QIcon(':/images/logo.png'))

        # Status bar setup
        self.statusBar().showMessage('Status: Ready')
        self.unitsLabel = QLabel()
        self.unitsLabel.setAlignment(Qt.AlignCenter)
        self.unitsLabel.setMinimumSize(self.unitsLabel.sizeHint())
        self.unitsLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.unitsLabel)
        self.pathLabel = QLabel()
        self.pathLabel.setAlignment(Qt.AlignCenter)
        self.pathLabel.setMinimumSize(self.pathLabel.sizeHint())
        self.pathLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.pathLabel)
        self.versionLabel = QLabel()
        self.versionLabel.setAlignment(Qt.AlignCenter)
        self.versionLabel.setMinimumSize(self.versionLabel.sizeHint())
        self.versionLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.versionLabel)
        self.progressBarIDF = QProgressBar()
        self.progressBarIDF.setAlignment(Qt.AlignCenter)
        self.progressBarIDF.setMaximumWidth(200)
        self.statusBar().addPermanentWidget(self.progressBarIDF)

        self.clipboard = QApplication.instance().clipboard()
        self.obj_clipboard = []

        self.setStyleSheet("""
            QToolTip {
               background-color: gray;
               color: white;
               border: black solid 1px
            } 
            # QMenu {
            #     background-color: rgbf(0.949020, 0.945098, 0.941176);
            #     color: rgb(255,255,255);
            # }
            # QMenu::item::selected {
            #     background-color: rgbf(0.949020, 0.945098, 0.941176);
            # }
            """)
コード例 #8
0
ファイル: __init__.py プロジェクト: redNixon/sourcery_pane
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)
コード例 #9
0
class SummaryWidget(QWidget):

    def __init__(self, plugin_manager):
        super(SummaryWidget, self).__init__()
        self.plugin_manager = plugin_manager

        icon_path = os.path.join(c.ICON_PATH, "neutral", "quote.png")
        self.setWindowIcon(QIcon(icon_path))
        self.setWindowTitle("Summary")

        self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat)
        self.font = QFont(self.settings.value(c.FONT, defaultValue="Arial", type=str))
        self.font.setPointSize(12)

        self.summary_text = QPlainTextEdit()
        self.summary_text.setReadOnly(True)
        self.summary_text.setFont(self.font)


        self.refresh_btn = QPushButton("Refresh")
        self.refresh_btn.clicked.connect(self.get_summary)

        self.threshold_value = 1.2
        self.threshold = QLineEdit(str(self.threshold_value))
        self.threshold.setFixedSize(40, 25)
        self.validator = QDoubleValidator()
        self.validator.setLocale(QLocale.English)
        self.threshold.setValidator(self.validator)
        self.threshold.textChanged.connect(self.threshold_changed)

        self.h_box = QHBoxLayout()
        self.h_box.addWidget(self.refresh_btn)
        self.h_box.addWidget(self.threshold)

        self.v_box = QVBoxLayout()
        self.v_box.addWidget(self.summary_text)
        self.v_box.addLayout(self.h_box)
        self.setLayout(self.v_box)
        self.resize(500, 500)

    def get_summary(self):
        if "de" in self.plugin_manager.get_language():
            language = "german"
        elif "en" in self.plugin_manager.get_language():
            language = "english"
        else:
            return

        text = self.plugin_manager.get_text()
        stop_words = set(stopwords.words(language))
        words = word_tokenize(text=text, language=language)

        # count word frequency
        freq = dict()
        for word in words:
            word = word.lower()
            if word in stop_words:
                continue
            if word in freq:
                freq[word] += 1
            else:
                freq[word] = 1

        sentences = sent_tokenize(text, language)
        sentence_freq = dict()

        # sum frequency of words in each sentence
        for word, freq in freq.items():
            for sentence in sentences:
                if word in sentence.lower():
                    if sentence in sentence_freq:
                        sentence_freq[sentence] += freq
                    else:
                        sentence_freq[sentence] = freq

        # calculate avg freq per word in sentence so long sentences dont have an advantage
        for sentence in sentences:
            sentence_freq[sentence] = sentence_freq[sentence] / len(sentence.split())

        # calc average word-frequency per sentence
        sum_sentece_freq = 0
        for sentence in sentence_freq:
            sum_sentece_freq += sentence_freq[sentence]

        avg = int(sum_sentece_freq / len(sentence_freq))

        # filter sentences that doesn't reach the threshold
        summary = ""
        for sentence in sentence_freq:
            if sentence_freq[sentence] > (self.threshold_value * avg):
                summary += " " + sentence

        self.summary_text.setPlainText(summary.strip())

    def threshold_changed(self):
        validator = self.threshold.validator()
        validator_state = validator.validate(self.threshold.text(), 0)[0]

        if validator_state == QValidator.Acceptable:
            color = '#006600'
            self.threshold_value = float(self.threshold.text())
        else:
            color = '#800000'

        self.threshold.setStyleSheet('QLineEdit { background-color: %s }' % color)

    def show(self):
        super(SummaryWidget, self).show()
        self.get_summary()
コード例 #10
0
class Notepad(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(Notepad, self).__init__(*args, **kwargs)

        self.setWindowIcon(QIcon('arti.PNG'))
        self.setGeometry(200, 100, 700, 400)

        layout = QVBoxLayout()
        self.editor = QPlainTextEdit()
        self.editor.setFont(QFont('Roboto', 12))

        # self.path holds the path of the currently open file.
        # If none, we haven't got a file open yet (or creating new).
        self.path = None

        layout.addWidget(self.editor)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.status = QStatusBar()
        self.setStatusBar(self.status)

        file_toolbar = QToolBar("File")
        file_toolbar.setIconSize(QSize(14, 14))
        self.addToolBar(file_toolbar)
        file_menu = self.menuBar().addMenu("&File")

        open_file_action = QAction(QIcon(), "Open file...", self)
        open_file_action.setStatusTip("Open file")
        open_file_action.triggered.connect(self.file_open)
        file_menu.addAction(open_file_action)
        file_toolbar.addAction(open_file_action)
        open_file_action.setShortcut(QKeySequence('Ctrl+O'))

        save_file_action = QAction(QIcon(), "Save", self)
        save_file_action.setStatusTip("Save current page")
        save_file_action.triggered.connect(self.file_save)
        file_menu.addAction(save_file_action)
        file_toolbar.addAction(save_file_action)
        save_file_action.setShortcut(QKeySequence('Ctrl+S'))

        saveas_file_action = QAction(QIcon(), "Save As...", self)
        saveas_file_action.setStatusTip("Save current page to specified file")
        saveas_file_action.triggered.connect(self.file_saveas)
        file_menu.addAction(saveas_file_action)
        file_toolbar.addAction(saveas_file_action)
        saveas_file_action.setShortcut(QKeySequence('Ctrl+Shift+S'))

        print_action = QAction(QIcon(), "Print...", self)
        print_action.setStatusTip("Print current page")
        print_action.triggered.connect(self.file_print)
        file_menu.addAction(print_action)
        file_toolbar.addAction(print_action)
        print_action.setShortcut(QKeySequence('Ctrl+P'))

        edit_toolbar = QToolBar("Edit")
        edit_toolbar.setIconSize(QSize(16, 16))
        self.addToolBar(edit_toolbar)
        edit_menu = self.menuBar().addMenu("&Edit")

        undo_action = QAction(QIcon(), "Undo", self)
        undo_action.setStatusTip("Undo last change")
        undo_action.triggered.connect(self.editor.undo)
        edit_menu.addAction(undo_action)
        undo_action.setShortcut(QKeySequence('Ctrl+Z'))

        redo_action = QAction(QIcon(), "Redo", self)
        redo_action.setStatusTip("Redo last change")
        redo_action.triggered.connect(self.editor.redo)
        edit_toolbar.addAction(redo_action)
        edit_menu.addAction(redo_action)
        redo_action.setShortcut(QKeySequence('Ctrl+Y'))

        edit_menu.addSeparator()

        cut_action = QAction(QIcon(), "Cut", self)
        cut_action.setStatusTip("Cut selected text")
        cut_action.triggered.connect(self.editor.cut)
        edit_toolbar.addAction(cut_action)
        edit_menu.addAction(cut_action)
        cut_action.setShortcut(QKeySequence('Ctrl+X'))

        copy_action = QAction(QIcon(), "Copy", self)
        copy_action.setStatusTip("Copy selected text")
        copy_action.triggered.connect(self.editor.copy)
        edit_toolbar.addAction(copy_action)
        edit_menu.addAction(copy_action)
        copy_action.setShortcut(QKeySequence('Ctrl+C'))

        paste_action = QAction(QIcon(), "Paste", self)
        paste_action.setStatusTip("Paste from clipboard")
        paste_action.triggered.connect(self.editor.paste)
        edit_toolbar.addAction(paste_action)
        edit_menu.addAction(paste_action)
        paste_action.setShortcut(QKeySequence('Ctrl+V'))

        select_action = QAction(QIcon(), "Select all", self)
        select_action.setStatusTip("Select all text")
        select_action.triggered.connect(self.editor.selectAll)
        edit_menu.addAction(select_action)
        select_action.setShortcut(QKeySequence('Ctrl+A'))

        edit_menu.addSeparator()

        wrap_action = QAction(QIcon(), "Wrap text to window", self)
        wrap_action.setStatusTip("Toggle wrap text to window")
        wrap_action.setCheckable(True)
        wrap_action.setChecked(True)
        wrap_action.triggered.connect(self.edit_toggle_wrap)
        edit_menu.addAction(wrap_action)

        self.update_title()
        self.show()

    def dialog_critical(self, s):
        dlg = QMessageBox(self)
        dlg.setText(s)
        dlg.setIcon(QMessageBox.Critical)
        dlg.show()

    def file_open(self):
        path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Text documents (*.txt)")

        if path:
            try:
                with open(path, 'rU') as f:
                    text = f.read()

            except Exception as e:
                self.dialog_critical(str(e))

            else:
                self.path = path
                self.editor.setPlainText(text)
                self.update_title()

    def file_save(self):
        if self.path is None:
            return self.file_saveas()

        self._save_to_path(self.path)

    def file_saveas(self):
        path, _ = QFileDialog.getSaveFileName(self, "Save file", "", "Text documents (*.txt)")

        if not path:
            return

        self._save_to_path(path)

    def _save_to_path(self, path):
        text = self.editor.toPlainText()
        try:
            with open(path, 'w') as f:
                f.write(text)

        except Exception as e:
            self.dialog_critical(str(e))

        else:
            self.path = path
            self.update_title()

    def file_print(self):
        dlg = QPrintDialog()
        if dlg.exec_():
            self.editor.print_(dlg.printer())

    def update_title(self):
        self.setWindowTitle("%s - Notepad" % (os.path.basename(self.path) if self.path else "Untitled"))

    def edit_toggle_wrap(self):
        self.editor.setLineWrapMode(1 if self.editor.lineWrapMode() == 0 else 0)
コード例 #11
0
class GridTransformerDialog(QDialog):
    def __init__(self, parent=None):
        super(GridTransformerDialog, self).__init__(
            parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint
            | QtCore.Qt.WindowCloseButtonHint)
        self.setWindowTitle("Grid Transformer")

        self.setWindowIcon(qta.icon('fa.th'))

        # dict to store inputs that will get passed to the grid transformer
        # this gets validated to ensure all the bits of info are in it before
        # the run button gets enabled
        self.grid_transformer_inputs = {}

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self._add_inputs()
        self._add_output()
        self._add_process()

        close_layout = QHBoxLayout()
        close_layout.addStretch()
        button_close = QPushButton("Close")
        button_close.clicked.connect(self.close_dialog)
        close_layout.addWidget(button_close)
        self.layout.addLayout(close_layout)

    def _add_inputs(self):
        inputs_groupbox = QGroupBox("Inputs")
        inputs_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        inputs_layout = QVBoxLayout()
        inputs_layout.setSpacing(0)
        inputs_groupbox.setLayout(inputs_layout)

        for input_band_name in input_band_names:
            inputband = GridTransformerInputBand(input_band_name)
            inputs_layout.addWidget(inputband)
            inputband.band_selected.connect(self._band_selected)
            inputband.log_message.connect(self._log_message)

        self.layout.addWidget(inputs_groupbox)

    def _band_selected(self, band_details):
        band_name, filename, band_index = band_details
        self.grid_transformer_inputs[band_name] = (filename, band_index)
        self.validate()

    def validate(self):
        self.run_button.setEnabled(self._is_valid())

    def _is_valid(self) -> bool:
        '''Is this ready to run, as in has the user specified all inputs needed
        for the grid transformer'''
        for band_name in input_band_names:
            if band_name not in self.grid_transformer_inputs:
                return False
            if self.grid_transformer_inputs[band_name] is None:
                return False
        if 'output' not in self.grid_transformer_inputs:
            return False

        return True

    def _log_message(self, message):
        self.log_messages.appendPlainText(message)

    def _add_output(self):
        output_groupbox = QGroupBox("Output")
        output_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        output_layout = QVBoxLayout()
        output_layout.setSpacing(0)
        output_groupbox.setLayout(output_layout)

        output_file_layout = QHBoxLayout()
        output_file_layout.setSpacing(4)
        self.output_file_input = QLineEdit()
        self.output_file_input.textChanged.connect(
            self._on_output_filename_changed)
        self.output_file_input.setMinimumWidth(400)
        self.output_file_input.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)
        output_file_layout.addWidget(self.output_file_input)
        output_layout.addLayout(output_file_layout)

        self.open_output_file_button = QPushButton()
        output_file_layout.addWidget(self.open_output_file_button)
        self.open_output_file_button.setIcon(qta.icon('fa.folder-open'))
        self.open_output_file_button.setToolTip("Select output file location")
        self.open_output_file_button.clicked.connect(self._click_open_output)

        self.layout.addWidget(output_groupbox)

    def _on_output_filename_changed(self, filename):
        self.grid_transformer_inputs['output'] = filename
        self.validate()

    def _set_output_filename(self, filename):
        self.output_file_input.setText(filename)
        self.grid_transformer_inputs['output'] = filename
        self.validate()

    def _click_open_output(self):
        filters = ("GeoTIFF (*.tif *.tiff)")
        filename, _ = QFileDialog.getSaveFileName(
            self, f"Select output file",
            GuiSettings.settings().value(output_folder_settings), filters)
        if filename is None:
            return
        last_open_folder = os.path.dirname(filename)
        if os.path.exists(last_open_folder):
            GuiSettings.settings().setValue(output_folder_settings,
                                            last_open_folder)

        self._set_output_filename(filename)

    def _add_process(self):
        process_groupbox = QGroupBox("Process")
        process_groupbox.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        process_layout = QVBoxLayout()
        process_layout.setSpacing(0)
        process_groupbox.setLayout(process_layout)

        pbar_frame = QFrame()
        pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        pbar_hbox = QHBoxLayout()
        pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        pbar_hbox.setSpacing(16)

        # Run and stop buttons
        hbox = QHBoxLayout()
        hbox.setSpacing(8)
        self.run_button = QPushButton()
        # is only enabled when validation passes
        self.run_button.setEnabled(False)
        self.run_button.setText("Run")
        self.run_button.setFixedWidth(100)
        run_icon = qta.icon('fa.play', color='green')
        self.run_button.setIcon(run_icon)
        self.run_button.clicked.connect(self._click_run)
        hbox.addWidget(self.run_button)

        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setText("Stop")
        self.stop_button.setFixedWidth(100)
        stop_icon = qta.icon('fa.stop', color='red')
        self.stop_button.setIcon(stop_icon)
        self.stop_button.clicked.connect(self._click_stop)
        hbox.addWidget(self.stop_button)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.progress_bar.setValue(0)
        self.progress_bar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)

        pbar_hbox.addLayout(hbox)
        pbar_hbox.addWidget(self.progress_bar)
        pbar_frame.setLayout(pbar_hbox)
        process_layout.addWidget(pbar_frame)

        self.warning_frame = QFrame()
        self.warning_frame.setVisible(False)
        self.warning_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        warning_icon_widget = qta.IconWidget('fa.warning', color='red')
        warning_icon_widget.setIconSize(QtCore.QSize(48, 48))
        warning_icon_widget.update()
        hbox.addWidget(warning_icon_widget)
        warning_label = QLabel(
            "Grid Transformer did not complete successfully. Please refer to "
            "log output.")
        warning_label.setStyleSheet("QLabel { color: red; }")
        warning_label.setWordWrap(True)
        warning_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(warning_label)
        self.warning_frame.setLayout(hbox)
        process_layout.addWidget(self.warning_frame)

        self.success_frame = QFrame()
        self.success_frame.setVisible(False)
        self.success_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        success_icon_widget = qta.IconWidget('fa.check', color='green')
        success_icon_widget.setIconSize(QtCore.QSize(48, 48))
        success_icon_widget.update()
        hbox.addWidget(success_icon_widget)
        success_label = QLabel("Grid Transformer completed successfully.")
        success_label.setStyleSheet("QLabel { color: green; }")
        success_label.setWordWrap(True)
        success_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(success_label)
        self.success_frame.setLayout(hbox)
        process_layout.addWidget(self.success_frame)

        log_layout = QVBoxLayout()
        log_layout.setSpacing(4)
        log_label = QLabel("Log messages")
        log_label.setStyleSheet("QLabel { color: grey; }")
        log_layout.addWidget(log_label)

        self.log_messages = QPlainTextEdit()
        log_font = QFont("monospace")
        log_font.setStyleHint(QFont.TypeWriter)
        self.log_messages.setFont(log_font)
        self.log_messages.setReadOnly(True)
        self.log_messages.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        # self.log_messages.sizePolicy.setVerticalStretch(1)
        log_layout.addWidget(self.log_messages)
        process_layout.addLayout(log_layout)

        self.layout.addWidget(process_groupbox)

    def _on_progress(self, progress):
        self.progress_bar.setValue(int(progress * 100))

    def _on_complete(self, successful: bool):
        self.warning_frame.setVisible(not successful)
        self.success_frame.setVisible(successful)
        self.stop_button.setEnabled(False)
        self.run_button.setEnabled(True)

        run_time = time.perf_counter() - self.start_time
        self._log_message(
            f"Total grid transformation time = {run_time:.2f} sec")
        self._log_message("\n\n")

    def _click_run(self):
        self.warning_frame.setVisible(False)
        self.success_frame.setVisible(False)
        self.stop_button.setEnabled(True)
        self.run_button.setEnabled(False)

        self.gt_executor = QtGridTransformerThread(
            self.grid_transformer_inputs)

        self.gt_executor.progress.connect(self._on_progress)
        self.gt_executor.message.connect(self._log_message)
        self.gt_executor.complete.connect(self._on_complete)

        self.start_time = time.perf_counter()
        self._log_message("\n\nStarting Grid Transformer process")
        self.gt_executor.start()

    def _click_stop(self):
        if self.gt_executor is not None:
            self.gt_executor.stop()

    def close_dialog(self):
        self.close()
コード例 #12
0
class MainWindow(QMainWindow):
    font: QFont
    vertical_layout: QVBoxLayout
    central_widget: QWidget
    text_box: QPlainTextEdit
    recognize_button: QPushButton

    assistant: AssistantInterface

    def __init__(self, assistant: AssistantInterface):
        super().__init__()

        qInitResources()

        self.assistant = assistant

        self.build_layout()
        self.init_handlers()

    def build_layout(self):
        self.setup_window()
        self.setup_styles()
        self.setup_font()

        self.build_central_widget()
        self.build_vertical_layout()
        self.build_text_box()
        self.build_recognize_button()

        QMetaObject.connectSlotsByName(self)

    def setup_window(self):
        window_size = QSize(420, 700)

        self.setObjectName("window")
        self.resize(window_size)
        self.setMinimumSize(window_size)
        self.setMaximumSize(window_size)
        self.setWindowTitle(u"Voice Assistant")
        self.setAutoFillBackground(False)

    def setup_styles(self):
        file = QFile(":/styles/style.css")
        file.open(QFile.ReadOnly)

        byte_array = file.readAll()

        file.close()

        self.setStyleSheet(byte_array.data().decode())

    def setup_font(self):
        self.font = QFont()
        self.font.setFamily(u"Helvetica")
        self.font.setPointSize(18)

    def build_central_widget(self):
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)

        self.central_widget = QWidget(self)
        self.central_widget.setObjectName(u"central_widget")
        self.central_widget.setSizePolicy(size_policy)

        self.setCentralWidget(self.central_widget)

    def build_vertical_layout(self):
        self.vertical_layout = QVBoxLayout(self.central_widget)
        self.vertical_layout.setObjectName(u"vertical_layout")

    def build_text_box(self):
        text_box_size = QSize(420, 600)

        self.text_box = QPlainTextEdit(self.central_widget)
        self.text_box.setObjectName(u"text_box")
        self.text_box.setMaximumSize(text_box_size)
        self.text_box.setFont(self.font)
        self.text_box.setContextMenuPolicy(Qt.NoContextMenu)
        self.text_box.setUndoRedoEnabled(False)
        self.text_box.setReadOnly(True)
        self.text_box.setPlaceholderText("Waiting for your question...")

        self.vertical_layout.addWidget(self.text_box)

    def build_recognize_button(self):
        button_size = QSize(140, 40)

        self.recognize_button = QPushButton(self.central_widget)
        self.recognize_button.setObjectName(u"recognize_button")
        self.recognize_button.setEnabled(True)
        self.recognize_button.setMinimumSize(button_size)
        self.recognize_button.setMaximumSize(button_size)
        self.recognize_button.setFont(self.font)
        self.recognize_button.setAutoFillBackground(False)
        self.recognize_button.setText("Recognize")
        self.recognize_button.setShortcut("Return")

        self.vertical_layout.addWidget(self.recognize_button, 0,
                                       Qt.AlignHCenter)

    def init_handlers(self):
        self.recognize_button.pressed.connect(self.start_recognition)
        self.assistant.on_wake = self.on_assistant_started
        self.assistant.on_sleep = self.on_assistant_finished
        self.assistant.on_assistant_listen = self.on_recognize_started
        self.assistant.on_user_message = self.on_user_text
        self.assistant.on_assistant_message = self.on_assistant_text

    def on_assistant_started(self):
        self.recognize_button.setEnabled(False)

    def on_assistant_finished(self):
        self.recognize_button.setEnabled(True)
        self.recognize_button.setText("Recognize")

    def on_recognize_started(self):
        self.async_play_sound()
        self.recognize_button.setText("Listening...")

    def on_user_text(self, user_text: str):
        self.recognize_button.setText("Processing...")
        self.append_message(f"[You] {user_text}")

    def on_assistant_text(self, assistant_answer: str):
        signed_text = f"[{self.assistant.get_name()}] {assistant_answer}"
        self.append_message(signed_text)

    def append_message(self, message: str):
        self.text_box.appendPlainText(f"{message}\n")

    def start_recognition(self):
        coroutine = self.assistant.handle()
        asyncio.create_task(coroutine)

    @async_function
    def async_play_sound(self):
        file = QFile(":/sounds/click.mp3")
        file.open(QFile.ReadOnly)

        byte_array = file.readAll()

        file.close()

        with tempfile.NamedTemporaryFile("wb", delete=True) as temp:
            temp.write(byte_array.data())
            playsound(temp.name)

    def closeEvent(self, event: QCloseEvent):
        for task in asyncio.all_tasks():
            task.cancel()

        asyncio.get_running_loop().stop()

    async def start(self):
        self.show()
コード例 #13
0
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)
コード例 #14
0
ファイル: run_tab.py プロジェクト: ausseabed/hyo2_qax
class RunTab(QtWidgets.QWidget):

    run_checks = QtCore.Signal()

    def __init__(self, prj: QAXProject):
        super(RunTab, self).__init__()
        self.prj = prj
        self.check_executor = None

        self.vbox = QtWidgets.QVBoxLayout()
        self.setLayout(self.vbox)

        self._add_check_outputs()
        self._add_process()

        # final setup
        self.set_run_stop_buttons_enabled(False)

    def _add_check_outputs(self):
        co_groupbox = QGroupBox("Check outputs")
        co_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        co_layout = QVBoxLayout()
        co_layout.setSpacing(16)
        co_groupbox.setLayout(co_layout)

        self.qajson_spatial_checkbox = QCheckBox(
            "Include summary spatial output in QAJSON. "
            "Supports QAX visualisation.")
        self.qajson_spatial_checkbox.setCheckState(
            QtCore.Qt.CheckState.Checked)
        co_layout.addWidget(self.qajson_spatial_checkbox)

        export_layout = QVBoxLayout()
        export_layout.setSpacing(4)
        self.export_spatial_checkbox = QCheckBox(
            "Export detailed spatial outputs to file. "
            "Supports visualisation in other geospatial applications.")
        self.export_spatial_checkbox.stateChanged.connect(
            self._on_export_spatial_changed)
        export_layout.addWidget(self.export_spatial_checkbox)

        output_folder_layout = QHBoxLayout()
        output_folder_layout.setSpacing(4)
        output_folder_layout.addSpacerItem(QtWidgets.QSpacerItem(37, 20))
        self.output_folder_label = QLabel(
            "Detailed spatial output folder location:")
        output_folder_layout.addWidget(self.output_folder_label)
        self.output_folder_input = QLineEdit()
        self.output_folder_input.setText(
            GuiSettings.settings().value("spatial_outputs"))
        self.output_folder_input.setMinimumWidth(300)
        self.output_folder_input.setSizePolicy(QSizePolicy.Expanding,
                                               QSizePolicy.Expanding)
        output_folder_layout.addWidget(self.output_folder_input)

        self.open_output_folder_button = QPushButton()
        output_folder_layout.addWidget(self.open_output_folder_button)
        self.open_output_folder_button.setIcon(qta.icon('fa.folder-open'))
        self.open_output_folder_button.setToolTip(
            f"Select file containing data")
        self.open_output_folder_button.clicked.connect(
            self._click_open_spatial_export_folder)
        export_layout.addLayout(output_folder_layout)

        co_layout.addLayout(export_layout)

        self._on_export_spatial_changed()
        self.vbox.addWidget(co_groupbox)

    def _click_open_spatial_export_folder(self):
        output_folder = QFileDialog.getExistingDirectory(
            self, f"Select folder for spatial outputs",
            GuiSettings.settings().value("spatial_outputs"),
            QFileDialog.ShowDirsOnly)

        if os.path.exists(output_folder):
            GuiSettings.settings().setValue("spatial_outputs", output_folder)

        self.output_folder_input.setText(output_folder)

    def _on_export_spatial_changed(self):
        is_export = self.export_spatial_checkbox.isChecked()
        self.output_folder_label.setEnabled(is_export)
        self.output_folder_input.setEnabled(is_export)
        self.open_output_folder_button.setEnabled(is_export)

    def _add_process(self):
        process_groupbox = QGroupBox("Process")
        process_groupbox.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        process_layout = QVBoxLayout()
        process_layout.setSpacing(0)
        process_groupbox.setLayout(process_layout)

        pbar_frame = QFrame()
        pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        pbar_hbox = QHBoxLayout()
        pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        pbar_hbox.setSpacing(16)

        # Run and stop buttons
        hbox = QHBoxLayout()
        hbox.setSpacing(8)
        self.run_button = QPushButton()
        # is only enabled when validation passes
        self.run_button.setEnabled(False)
        self.run_button.setText("Run")
        self.run_button.setToolTip("Start check execution")
        self.run_button.setFixedWidth(100)
        run_icon = qta.icon('fa.play', color='green')
        self.run_button.setIcon(run_icon)
        self.run_button.clicked.connect(self._click_run)
        hbox.addWidget(self.run_button)

        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setText("Stop")
        self.stop_button.setToolTip("Stop check execution")
        self.stop_button.setFixedWidth(100)
        stop_icon = qta.icon('fa.stop', color='red')
        self.stop_button.setIcon(stop_icon)
        self.stop_button.clicked.connect(self._click_stop)
        hbox.addWidget(self.stop_button)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.progress_bar.setValue(0)
        self.progress_bar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)

        pbar_hbox.addLayout(hbox)
        pbar_hbox.addWidget(self.progress_bar)
        pbar_frame.setLayout(pbar_hbox)
        process_layout.addWidget(pbar_frame)

        vbox = QVBoxLayout()
        vbox.setSpacing(8)
        vbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        process_layout.addLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        check_name_label = QLabel("Check:")
        check_name_label.setFixedWidth(80)
        hbox.addWidget(check_name_label)
        self.check_name_text_label = QLabel("n/a")
        hbox.addWidget(self.check_name_text_label)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        status_name_label = QLabel("Status:")
        status_name_label.setFixedWidth(80)
        hbox.addWidget(status_name_label)
        self.status_name_text_label = QLabel("Not started")
        hbox.addWidget(self.status_name_text_label)

        self.warning_frame = QFrame()
        self.warning_frame.setVisible(False)
        self.warning_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        warning_icon_widget = qta.IconWidget('fa.warning', color='red')
        warning_icon_widget.setIconSize(QtCore.QSize(48, 48))
        warning_icon_widget.update()
        hbox.addWidget(warning_icon_widget)
        warning_label = QLabel(
            "Grid Transformer did not complete successfully. Please refer to "
            "log output.")
        warning_label.setStyleSheet("QLabel { color: red; }")
        warning_label.setWordWrap(True)
        warning_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(warning_label)
        self.warning_frame.setLayout(hbox)
        process_layout.addWidget(self.warning_frame)

        self.success_frame = QFrame()
        self.success_frame.setVisible(False)
        self.success_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        success_icon_widget = qta.IconWidget('fa.check', color='green')
        success_icon_widget.setIconSize(QtCore.QSize(48, 48))
        success_icon_widget.update()
        hbox.addWidget(success_icon_widget)
        success_label = QLabel("All checks completed successfully.")
        success_label.setStyleSheet("QLabel { color: green; }")
        success_label.setWordWrap(True)
        success_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(success_label)
        self.success_frame.setLayout(hbox)
        process_layout.addWidget(self.success_frame)

        log_layout = QVBoxLayout()
        log_layout.setSpacing(4)
        log_label = QLabel("Log messages")
        log_label.setStyleSheet("QLabel { color: grey; }")
        log_layout.addWidget(log_label)

        self.log_messages = QPlainTextEdit()
        log_font = QFont("monospace")
        log_font.setStyleHint(QFont.TypeWriter)
        self.log_messages.setFont(log_font)
        self.log_messages.setReadOnly(True)
        self.log_messages.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        log_layout.addWidget(self.log_messages)
        process_layout.addLayout(log_layout)

        self.vbox.addWidget(process_groupbox)

    def set_run_stop_buttons_enabled(self, is_running: bool) -> NoReturn:
        if is_running:
            self.run_button.setEnabled(False)
            self.stop_button.setEnabled(True)
        else:
            self.run_button.setEnabled(True)
            self.stop_button.setEnabled(False)

    def _log_message(self, message):
        self.log_messages.appendPlainText(message)

    def run_executor(self, check_executor: QtCheckExecutorThread):
        # we pass the check_executor into the run tab as this is where the UI
        # components are that will display the execution status.
        self.set_run_stop_buttons_enabled(True)

        self._log_message("Check execution started")
        self.start_time = time.perf_counter()

        self.check_executor = check_executor
        self.check_executor.options = self.get_options()
        self.check_executor.check_tool_started.connect(
            self._on_check_tool_started)
        self.check_executor.progress.connect(self._on_progress)
        self.check_executor.qajson_updated.connect(self._on_qajson_update)
        self.check_executor.checks_complete.connect(self._on_checks_complete)
        self.check_executor.status_changed.connect(self._on_status_change)
        self.check_executor.start()

    def get_options(self) -> Dict:
        ''' Gets a list of options based on user entered data. eg; the spatial
        output specifications.
        '''
        return {
            CheckOption.spatial_output_qajson:
            self.qajson_spatial_checkbox.isChecked(),
            CheckOption.spatial_output_export:
            self.export_spatial_checkbox.isChecked(),
            CheckOption.spatial_output_export_location:
            self.output_folder_input.text()
        }

    def _click_run(self):
        self.run_checks.emit()

    def _click_stop(self):
        if self.check_executor is None:
            logger.warn("Check executor does not exist, cannot stop")
            return
        self._log_message("Stopping check execution")
        self.check_executor.stop()

    @QtCore.Slot(float)
    def _on_progress(self, progress):
        self.progress_bar.setValue(int(progress * 100))

    @QtCore.Slot()
    def _on_qajson_update(self):
        self.prj.qa_json = self.check_executor.qa_json

    @QtCore.Slot(object)
    def _on_check_tool_started(self, tpl):
        check_tool_name, check_number, total_check_count = tpl
        self.check_name_text_label.setText("{} ({}/{})".format(
            check_tool_name, check_number, total_check_count))

    @QtCore.Slot()
    def _on_checks_complete(self):
        run_time = time.perf_counter() - self.start_time
        self._log_message(
            f"Execution time for all checks = {run_time:.2f} sec")
        self._log_message("\n\n")

        self.set_run_stop_buttons_enabled(False)
        self.prj.qa_json = self.check_executor.qa_json

    @QtCore.Slot(str)
    def _on_status_change(self, status):
        self.status_name_text_label.setText(status)
コード例 #15
0
class MyWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.thread = SerialMonitorThread()
        self.thread.dataReady.connect(self.get_data, Qt.QueuedConnection)
        self.thread.setTerminationEnabled(True)

        #Menu
        self.setPalette(get_verifone_color())

        collapsible = CollapsibleWidget()
        self.init_logging(collapsible)

        self.init_download(collapsible)

        self.init_analyser(collapsible)

        collapsible.add_sections()
        # Scroll Area
        self.createLoggingDisplayLabel()
        self.scrollArea = QScrollArea()
        self.scrollArea.setBackgroundRole(QPalette.Dark)
        self.scrollArea.setWidget(self.text)
        self.scrollArea.setWidgetResizable(True)

        hLayout = QHBoxLayout()
        #hLayout.addLayout(vLayout)
        hLayout.addWidget(collapsible)
        hLayout.addWidget(self.scrollArea)

        self.setLayout(hLayout)

    def init_logging(self, collapsible):

        self.logger = QPushButton("Start Logging", self)
        self.logger.setFont(QFont("Times", 14, QFont.Bold))
        self.logger.clicked.connect(lambda: self.display_log_data())
        self.logger.setStyleSheet("background-color: white")

        #self.filterLayout = QtWidgets.QHBoxLayout()
        self.logFilterLabel = QLabel('Filter', self)
        self.logFilterLabel.setFont(QFont("Times", 14, QFont.Bold))
        self.logFilterLabel.setPalette(get_white_color_text())
        self.logFilterLabel.setFixedWidth(60)
        self.logFilter = QLineEdit(self)
        self.logFilter.setPalette(get_white_color())
        self.logFilter.setStyleSheet("background-color: white")
        self.logFilter.setFixedWidth(200)
        #self.filterLayout.addWidget(self.logFilterLabel, QtCore.Qt.AlignLeft)
        #self.filterLayout.addWidget(self.logFilter, QtCore.Qt.AlignLeft)

        self.serialList = QComboBox()
        ports = get_available_serial_ports()
        if (len(ports) == 1):
            self.serialList.addItem(ports[0])
            self.thread.set_comport(self.serialList.currentText())
        else:
            self.serialList.addItem("Select")
            for port in ports:
                self.serialList.addItem(port)

        self.serialList.currentIndexChanged.connect(
            lambda: self.set_serial_port())
        self.serialList.setStyleSheet("background-color: white")
        self.clear = QPushButton("Clear Log File", self)
        self.clear.setStyleSheet("background-color: white")
        self.clear.setFont(QFont("Times", 14, QFont.Bold))
        self.clear.clicked.connect(lambda: self.clear_data())

        widget = QFrame(collapsible.get_tree())
        widget.setPalette(get_verifone_color())
        title = "Logging"
        self.loggerGrid = QGridLayout(widget)
        self.loggerGrid.addWidget(self.logger, 0, 0, 1, 2)
        self.loggerGrid.addWidget(self.logFilterLabel, 1, 0, 1, 1)
        self.loggerGrid.addWidget(self.logFilter, 1, 1, 1, 1)
        self.loggerGrid.addWidget(self.serialList, 2, 0, 1, 2)
        self.loggerGrid.addWidget(self.clear, 3, 0, 1, 2)

        collapsible.include_section(title, widget)

    def init_download(self, collapsible):
        self.download = QPushButton("Download Package", self)
        self.download.setFont(QFont("Times", 14, QFont.Bold))
        self.download.clicked.connect(lambda: self.send_file())
        self.download.setStyleSheet("background-color: white")

        self.loadDownloadFile = QPushButton("Load File", self)
        self.loadDownloadFile.setFont(QFont("Times", 14, QFont.Bold))
        self.loadDownloadFile.clicked.connect(self.loadFromFile)
        self.loadDownloadFile.setStyleSheet("background-color: white")

        self.downloadFileName = QLineEdit("File name", self)
        self.downloadFileName.setStyleSheet("background-color: white")
        self.downloadFileName.setFixedWidth(300)

        self.downloadAddress = QLineEdit("IP Address", self)
        self.downloadAddress.setStyleSheet("background-color: white")
        self.downloadAddress.setFixedWidth(300)

        self.downloadStatus = QLabel("Download Status", self)
        self.downloadStatus.setStyleSheet(
            "background-color: rgba(3, 169, 229, 0); color : white")
        self.downloadStatus.setFixedWidth(300)
        widget = QFrame(collapsible.get_tree())
        title = "Download"

        self.downloadGrid = QGridLayout(widget)
        self.downloadGrid.addWidget(self.download, 0, 0, 1, 2)
        self.downloadGrid.addWidget(self.loadDownloadFile, 1, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadFileName, 2, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadAddress, 3, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadStatus, 4, 0, 1, 2)
        collapsible.include_section(title, widget)

    def init_analyser(self, collapsible):
        self.performanceData = QPushButton("View Performance Data", self)
        self.performanceData.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceData.clicked.connect(
            lambda: self.display_performance_data())
        self.performanceData.setStyleSheet("background-color: white")

        self.performanceChart = QPushButton("View Performance Chart", self)
        self.performanceChart.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceChart.clicked.connect(
            lambda: self.display_performance_chart())
        self.performanceChart.setStyleSheet("background-color: white")

        widget = QFrame(collapsible.get_tree())
        title = "Analyser"
        self.analyserGrid = QGridLayout(widget)
        self.analyserGrid.addWidget(self.performanceData, 0, 0, 1, 2)
        self.analyserGrid.addWidget(self.performanceChart, 1, 0, 1, 2)
        collapsible.include_section(title, widget)

    def loadFromFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Load Package", '', "Download Files (*.tgz);;All Files (*)")

        if not fileName:
            return

        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()
        self.downloadFileName.setText(fileName)

    def createLoggingDisplayLabel(self):
        # Display Area
        self.text = QPlainTextEdit(self)
        self.text.setReadOnly(True)
        self.text.setFont(QFont("Times", 12, QFont.Bold))
        self.text.setTextInteractionFlags(Qt.TextSelectableByMouse
                                          | Qt.TextSelectableByKeyboard)

    def clear_data(self):
        self.text.clear()
        os.remove(logfile_path, dir_fd=None)

    def display_log_data(self):
        #send_file()

        if ('COM' in self.serialList.currentText()):
            self.createLoggingDisplayLabel()
            self.scrollArea.setWidget(self.text)
            self.thread.stop()
            self.thread.start()

            data = get_data_from_file(logfile_path)
            if (len(data) > 0 and data != None):
                self.text.appendPlainText(data)
            self.logger.setDisabled(True)

    def get_data(self, data):
        if (len(data) > 0):
            logFile = open(logfile_path, "a")
            logFile.write(data)
            logFile.close()
            filterText = self.logFilter.text()
            if filterText in data.rstrip():
                self.text.appendPlainText(data.rstrip())
                vbar = self.scrollArea.verticalScrollBar()
                vbar.setValue(vbar.maximum())

    def display_performance_data(self):
        self.thread.stop()
        data = get_data_from_file(logfile_path)
        jsonData = translate_data_to_json(data)
        self.performanceData = DisplayPerformanceData()
        self.performanceData.loadCsv(
            os.path.join(base_log_path, "performance_data.csv"))
        self.scrollArea.setWidget(self.performanceData)
        self.logger.setDisabled(False)

    def display_performance_chart(self):
        self.thread.stop()
        self.scrollArea.setWidget(get_performace_chart())
        self.logger.setDisabled(False)

    def set_serial_port(self):
        self.thread.set_comport(self.serialList.currentText())

    def send_file(self):
        base_path = os.path.join("c:/", "VFI", 'wks',
                                 'global-payment-application', 'GPA', 'output',
                                 'vos2', 'gpa', 'dl.gpa-1.0.0.0-000.tgz')
        fileName = self.downloadFileName.text()
        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()

        load_vos_package_ip('192.168.0.104', fileName, self.downloadStatus)
コード例 #16
0
class QFileBrowse(QWidget):
    def __init__(self, subfolder_name='QR Codes', *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.layout = QGridLayout()
        self.button = QPushButton("Change save location")
        self.subfolder = QCheckBox("Create subfolder")
        self.subfolder.stateChanged.connect(self.update_display)
        self.button.clicked.connect(self.browse)
        self.subfolder_name = subfolder_name
        self.dialog = QFileDialog()
        self._base_path = pathlib.Path(".").expanduser().resolve()

        # output path display
        self.path_display = QPlainTextEdit()
        # make bold
        font = self.path_display.font()
        font.setWeight(QFont.Bold)
        self.path_display.setFont(font)
        # configure height
        self.path_display.setFixedHeight(QFontMetrics(font).height() * 2)
        self.path_display.setLineWrapMode(QPlainTextEdit.NoWrap)
        # styles
        self.path_display.setReadOnly(True)
        self.path_display.setFrameStyle(QFrame.Box | QFrame.Sunken)
        self.path_display.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.path_display.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.path_display.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.path_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # add widgets to layout
        self.layout.addWidget(self.button, 0, 0)
        self.layout.addWidget(self.subfolder, 0, 1)
        self.layout.addWidget(self.path_display, 1, 0, 1, 2)
        self.layout.setMargin(0)

        self.setLayout(self.layout)
        self.update_display()

    @property
    def save_path(self):
        if self.subfolder.isChecked():
            return self._base_path / self.subfolder_name
        return self._base_path

    def browse(self):
        path = self.dialog.getExistingDirectory()
        if path != '':
            self._base_path = pathlib.Path(path).expanduser().resolve()
        self.update_display()

    def update_display(self):
        scrollbar = self.path_display.horizontalScrollBar()
        old_scroll = scrollbar.value()
        scrolled_to_end = old_scroll == scrollbar.maximum()

        self.path_display.setPlainText(str(self.save_path))

        if scrolled_to_end:
            scrollbar.setValue(scrollbar.maximum())
        else:
            scrollbar.setValue(old_scroll)
コード例 #17
0
ファイル: __init__.py プロジェクト: xwlan/binaryninja-api
class Snippets(QDialog):

    def __init__(self, parent=None):
        super(Snippets, self).__init__(parent)
        # Create widgets
        self.setWindowModality(Qt.NonModal)
        self.title = QLabel(self.tr("Snippet Editor"))
        self.saveButton = QPushButton(self.tr("Save"))
        self.revertButton = QPushButton(self.tr("Revert"))
        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.resetting = False
        self.columns = 3

        self.keySequenceEdit = QKeySequenceEdit(self)
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel = QLabel("")
        self.currentFileLabel = QLabel()
        self.currentFile = ""
        self.snippetDescription = QLineEdit()
        self.snippetEditsPending = False

        self.clearSelection()

        #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.revertButton)
        buttons.addWidget(self.saveButton)

        description = QHBoxLayout()
        description.addWidget(QLabel(self.tr("Description: ")))
        description.addWidget(self.snippetDescription)

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addWidget(self.currentFileLabel)
        vlayout.addWidget(self.edit)
        vlayout.addLayout(description)
        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("Vector 35", "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.revertButton.clicked.connect(self.loadSnippet)
        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)

    def registerAllSnippets(self):
        for action in list(filter(lambda x: x.startswith("Snippet\\"), UIAction.getAllRegisteredActions())):
            UIActionHandler.globalActions().unbindAction(action)
            UIAction.unregisterAction(action)

        for snippet in includeWalk(snippetPath, ".py"):
            (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(snippet)
            if not snippetDescription:
                actionText = "Snippet\\" + snippet
            else:
                actionText = "Snippet\\" + snippetDescription
            UIAction.registerAction(actionText, snippetKey)
            UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode)))

    def clearSelection(self):
        self.keySequenceEdit.clear()
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel.setText("")
        self.currentFileLabel.setText("")
        self.snippetDescription.setText("")
        self.edit.setPlainText("")

    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])
        if QFileInfo(newSelection).isDir():
            self.clearSelection()
            return

        if 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())
        log_debug("Loading %s as a snippet." % self.currentFile)
        (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile)
        self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("")
        self.keySequenceEdit.setKeySequence(snippetKey[0]) if len(snippetKey) != 0 else self.keySequenceEdit.setKeySequence(QKeySequence(""))
        self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("")

    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():
                open(os.path.join(selection, snippetName), "w").close()
            else:
                open(os.path.join(snippetPath, snippetName), "w").close()
            log_debug("Snippet %s created." % snippetName)

    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)

    def snippetChanged(self):
        if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()):
            return False
        (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile)
        if (not snippetCode):
            return False
        if len(snippetKey) == 0 and not self.keySequenceEdit.keySequence().isEmpty():
            return True
        if len(snippetKey) != 0 and snippetKey[0] != self.keySequenceEdit.keySequence():
            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()
コード例 #18
0
class BibTeXWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self._source = None
        self._table = None
        self._id = -1
        self._inspire_id = None
        self._doi = None
        self._bibtex_string = ""

        self._fetcher = Fetcher()
        self._fetcher.BatchReady.connect(self._HandleBatchReady)
        self._fetcher.FetchingFinished.connect(self._HandleFetchingCompleted)

        self._text_edit = QPlainTextEdit()
        font = QFont("Monospace")
        self._text_edit.setFont(font)
        self._text_edit.setTextInteractionFlags(
            Qt.TextInteractionFlag.TextSelectableByKeyboard
            | Qt.TextInteractionFlag.TextSelectableByMouse)
        self._text_edit.setEnabled(False)

        self._dowload_inspire = QToolButton()
        self._dowload_inspire.setIcon(QIcon(icons.INSPIRE))
        self._dowload_inspire.clicked.connect(self._FetchINSPIRE)
        self._dowload_inspire.setEnabled(False)

        self._dowload_doi = QToolButton()
        self._dowload_doi.setIcon(QIcon(icons.DOI))
        self._dowload_doi.clicked.connect(self._FetchDOI)
        self._dowload_doi.setEnabled(False)

        self._SetupUI()

    def _SetupUI(self):
        tool_widget = QWidget()
        tool_layout = QHBoxLayout()
        tool_layout.setContentsMargins(0, 0, 0, 0)
        tool_layout.addWidget(self._dowload_inspire)
        tool_layout.addWidget(self._dowload_doi)
        tool_layout.addStretch(1)
        tool_widget.setLayout(tool_layout)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._text_edit)
        layout.addWidget(tool_widget)
        self.setLayout(layout)

    def SetTable(self, database_table):
        if self._table == database_table:
            return

        if self._table is not None:
            self._table.Cleared.disconnect(self.Clear)

        self._table = database_table
        self._table.Cleared.connect(self.Clear)

    def Clear(self):
        self._text_edit.clear()
        self._text_edit.setEnabled(False)
        self._dowload_inspire.setEnabled(False)
        self._dowload_doi.setEnabled(False)

    def DisplayItem(self, id_):
        # NOTE: What if the item gets updated?

        if self._id == id_:
            return

        self._id = id_
        self._fetcher.Stop()
        self.Clear()

        if self._id == -1:
            return

        record = self._table.GetRow(self._id, ("inspire_id", "dois"))
        self._inspire_id = record["inspire_id"]
        self._doi = None if record["dois"] == [] else record["dois"][0]
        has_inspire_id = self._inspire_id is not None
        has_doi = self._doi is not None

        self._text_edit.setEnabled(has_inspire_id | has_doi)
        self._dowload_inspire.setEnabled(has_inspire_id)
        self._dowload_doi.setEnabled(has_doi)

    def _FetchINSPIRE(self):
        self._fetcher.Fetch(InspireBibTeXPlugin,
                            "recid:" + str(self._inspire_id),
                            batch_size=2)

    def _FetchDOI(self):
        self._fetcher.Fetch(DOIBibTeXPlugin, self._doi)

    def _HandleBatchReady(self, batch):
        self._bibtex_string = batch[0]

    def _HandleFetchingCompleted(self, records_number):
        self._text_edit.setPlainText(self._bibtex_string)