Exemple #1
0
    def _on_view_context_menu(self, pos):
        widget = self.scene.widget
        if widget is None:
            return
        assert isinstance(widget, HeatmapGridWidget)
        menu = QMenu(self.view.viewport())
        menu.setAttribute(Qt.WA_DeleteOnClose)
        menu.addActions(self.view.actions())
        menu.addSeparator()
        menu.addActions([self.__font_inc, self.__font_dec])
        menu.addSeparator()
        a = QAction("Keep aspect ratio", menu, checkable=True)
        a.setChecked(self.keep_aspect)

        def ontoggled(state):
            self.keep_aspect = state
            self.__aspect_mode_changed()
        a.toggled.connect(ontoggled)
        menu.addAction(a)
        menu.popup(self.view.viewport().mapToGlobal(pos))
Exemple #2
0
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "Variable Definitions")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(
            sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        )

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton(
            "New", toolTip="Create a new variable",
            minimumWidth=120,
            shortcut=QKeySequence.New
        )

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def reserved_names():
            varnames = []
            if self.data is not None:
                varnames = [var.name for var in
                            self.data.domain.variables + self.data.domain.metas]
            varnames += [desc.name for desc in self.featuremodel]
            return set(varnames)

        def generate_newname(fmt):
            return unique_name(fmt, reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("Continuous")
        cont.triggered.connect(
            lambda: self.addFeature(
                ContinuousDescriptor(generate_newname("X{}"), "", 3))
        )
        disc = menu.addAction("Discrete")
        disc.triggered.connect(
            lambda: self.addFeature(
                DiscreteDescriptor(generate_newname("D{}"), "",
                                   ("A", "B"), -1, False))
        )
        string = menu.addAction("String")
        string.triggered.connect(
            lambda: self.addFeature(
                StringDescriptor(generate_newname("S{}"), ""))
        )
        menu.addSeparator()
        self.duplicateaction = menu.addAction("Duplicate Selected Variable")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton(
            "Remove", toolTip="Remove selected variable",
            minimumWidth=120,
            shortcut=QKeySequence.Delete
        )
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        )

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged
        )

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        box = gui.hBox(self.controlArea)
        box.layout().addWidget(self.report_button)
        self.report_button.setMinimumWidth(180)
        gui.rubber(box)
        commit = gui.button(box, self, "Send", callback=self.apply,
                            default=True)
        commit.setMinimumWidth(180)
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "Variable Definitions")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(
            sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        )

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton(
            "New", toolTip="Create a new variable",
            minimumWidth=120,
            shortcut=QKeySequence.New
        )

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def reserved_names():
            varnames = []
            if self.data is not None:
                varnames = [var.name for var in
                            self.data.domain.variables + self.data.domain.metas]
            varnames += [desc.name for desc in self.featuremodel]
            return set(varnames)

        def generate_newname(fmt):
            return unique_name(fmt, reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("Numeric")
        cont.triggered.connect(
            lambda: self.addFeature(
                ContinuousDescriptor(generate_newname("X{}"), "", 3))
        )
        disc = menu.addAction("Categorical")
        disc.triggered.connect(
            lambda: self.addFeature(
                DiscreteDescriptor(generate_newname("D{}"), "",
                                   ("A", "B"), -1, False))
        )
        string = menu.addAction("Text")
        string.triggered.connect(
            lambda: self.addFeature(
                StringDescriptor(generate_newname("S{}"), ""))
        )
        menu.addSeparator()
        self.duplicateaction = menu.addAction("Duplicate Selected Variable")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton(
            "Remove", toolTip="Remove selected variable",
            minimumWidth=120,
            shortcut=QKeySequence.Delete
        )
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        )

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged
        )

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        box = gui.hBox(self.controlArea)
        gui.rubber(box)
        commit = gui.button(box, self, "Send", callback=self.apply,
                            default=True)
        commit.setMinimumWidth(180)
Exemple #4
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon(':/res/box.png'))

        self._tray = QSystemTrayIcon()
        self._tray.setIcon(QIcon(':/res/box.png'))
        self._tray.activated.connect(self.show_tray_menu)
        self._tray.show()
        self._menu = None
        self._action_screen = None
        self._action_clip = None
        self._screenshot_wnd = None
        self.rebuild_menu()

        self._hotkey = hotkeys.initialize()

        if not settings['initialized']:
            settings['initialized'] = True
            settings['hotkey/screenshot'] = 'Print'
            settings['hotkey/clipboard'] = 'Ctrl+Alt+P'
            settings.save()

        self.register_hotkeys()

    def rebuild_menu(self):
        # Terrible way to clear hotkey shortcuts set to actions because Qt can not do that.
        self._menu = QMenu()
        self._action_screen = self._menu.addAction(self.tr('Make Screenshot'))
        self._action_screen.triggered.connect(self.capture_screen)
        self._action_clip = self._menu.addAction(self.tr('Share Clipboard'))
        self._action_clip.triggered.connect(self.share_clipboard)
        self._menu.addSeparator()
        self._menu.addAction(self.tr('Settings')).triggered.connect(self.show_settings)
        self._menu.addSeparator()
        self._menu.addAction(self.tr('Exit')).triggered.connect(lambda: QApplication.exit(0))
        self._tray.setContextMenu(self._menu)

    def __del__(self):
        hotkey = getattr(self, '_hotkey', None)
        if hotkey:
            hotkey.destroy()

    def show_tray_menu(self):
        self._menu.popup(QCursor.pos())

    def capture_screen(self):
        if self._screenshot_wnd:
            return

        self._screenshot_wnd = wnd = Screenshot()
        result = wnd.exec_()
        self._screenshot_wnd = None
        if result == QDialog.Accepted:
            wnd = ShareDialog(self, image=wnd.selected_image)
            wnd.show()
            wnd.exec_()

    def share_clipboard(self):
        mime = QApplication.clipboard().mimeData()
        try:
            wnd = ShareDialog(self, mime=mime)
        except ValueError as e:
            QMessageBox.critical(self, self.tr('Error'), str(e))
            return
        else:
            wnd.show()
            wnd.exec_()

    def register_hotkeys(self):
        if self._hotkey is not None:
            self.rebuild_menu()
            self._hotkey.unregister(winid=self.winId())
            hotkey_bindings = {
                settings['hotkey/clipboard']: (self.share_clipboard, self._action_clip),
                settings['hotkey/screenshot']: (self.capture_screen, self._action_screen)
            }
            for hotkey, (callback, action) in hotkey_bindings.items():
                if hotkey:
                    if self._hotkey.register(hotkey, callback, self.winId()):
                        sequence = QKeySequence(hotkey) if hotkey else QKeySequence()
                        action.setShortcut(sequence)
                    else:
                        QMessageBox.critical(self, 'Error', 'Could not bind {} hotkey!\n'
                                                            'Key combination {} is probably already in use.'
                                             .format(const.APP_NAME, hotkey))
        else:
            qDebug('Hotkeys are not supported on this platform')

    def show_settings(self):
        self._hotkey.unregister(winid=self.winId())
        dlg = SettingsDialog(self)
        dlg.show()
        dlg.exec_()
        # WORKAROUND: On windows calling register_hotkeys() directly often results in a crash.
        QTimer.singleShot(10, self.register_hotkeys)
Exemple #5
0
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "变量定义")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(sizePolicy=QSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding))

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton("新建",
                                     toolTip="Create a new variable",
                                     minimumWidth=120,
                                     shortcut=QKeySequence.New)

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def generate_newname(fmt):
            return unique_name(fmt, self.reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("数值数据")
        cont.triggered.connect(lambda: self.addFeature(
            ContinuousDescriptor(generate_newname("X{}"), "", 3)))
        disc = menu.addAction("分类数据")
        disc.triggered.connect(lambda: self.addFeature(
            DiscreteDescriptor(generate_newname("D{}"), "", (), False)))
        string = menu.addAction("文本")
        string.triggered.connect(lambda: self.addFeature(
            StringDescriptor(generate_newname("S{}"), "")))
        datetime = menu.addAction("日期/时间")
        datetime.triggered.connect(lambda: self.addFeature(
            DateTimeDescriptor(generate_newname("T{}"), "")))

        menu.addSeparator()
        self.duplicateaction = menu.addAction("复制选中变量")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton("删除",
                                        toolTip="删除选中变量",
                                        minimumWidth=120,
                                        shortcut=QKeySequence.Delete)
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(minimumWidth=200,
                                     minimumHeight=50,
                                     sizePolicy=QSizePolicy(
                                         QSizePolicy.Minimum,
                                         QSizePolicy.MinimumExpanding))

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged)

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        self.fix_button = gui.button(self.buttonsArea,
                                     self,
                                     "Upgrade Expressions",
                                     callback=self.fix_expressions)
        self.fix_button.setHidden(True)
        gui.button(self.buttonsArea,
                   self,
                   "Send",
                   callback=self.apply,
                   default=True)
Exemple #6
0
def createStandardContextMenu(item: QGraphicsTextItem,
                              pos: QPointF,
                              parent: Optional[QWidget] = None,
                              acceptRichText=False) -> Optional[QMenu]:
    """
    Like the private QWidgetTextControl::createStandardContextMenu
    """
    def setActionIcon(action: QAction, name: str):
        icon = QIcon.fromTheme(name)
        if not icon.isNull():
            action.setIcon(icon)

    def createMimeDataFromSelection(
            fragment: QTextDocumentFragment) -> QMimeData:
        mime = QMimeData()
        mime.setText(fragment.toPlainText())
        mime.setHtml(fragment.toHtml(b"utf-8"))
        # missing here is odf
        return mime

    def copy():
        cursor = item.textCursor()
        if cursor.hasSelection():
            mime = createMimeDataFromSelection(QTextDocumentFragment(cursor))
            QApplication.clipboard().setMimeData(mime)

    def cut():
        copy()
        item.textCursor().removeSelectedText()

    def copyLinkLocation():
        mime = QMimeData()
        mime.setText(link)
        QApplication.clipboard().setMimeData(mime)

    def canPaste():
        mime = QApplication.clipboard().mimeData()
        return mime.hasFormat("text/plain") or mime.hasFormat("text/html")

    def paste():
        mime = QApplication.clipboard().mimeData()
        if mime is not None:
            insertFromMimeData(mime)

    def insertFromMimeData(mime: QMimeData):
        fragment: Optional[QTextDocumentFragment] = None
        if mime.hasHtml() and acceptRichText:
            fragment = QTextDocumentFragment.fromHtml(mime.html())
        elif mime.hasText():
            fragment = QTextDocumentFragment.fromPlainText(mime.text())
        if fragment is not None:
            item.textCursor().insertFragment(fragment)

    def deleteSelected():
        cursor = item.textCursor()
        cursor.removeSelectedText()

    def selectAll():
        cursor = item.textCursor()
        cursor.select(QTextCursor.Document)
        item.setTextCursor(cursor)

    def addAction(menu: QMenu,
                  text: str,
                  slot: Callable[[], Any],
                  shortcut: Optional[QKeySequence.StandardKey] = None,
                  enabled=True,
                  objectName="",
                  icon="") -> QAction:
        ac = menu.addAction(text)
        ac.triggered.connect(slot)
        ac.setEnabled(enabled)
        if shortcut:
            ac.setShortcut(shortcut)
        if objectName:
            ac.setObjectName(objectName)
        if icon:
            setActionIcon(ac, icon)
        return ac

    flags = item.textInteractionFlags()
    showTextSelectionActions = flags & (Qt.TextEditable
                                        | Qt.TextSelectableByKeyboard
                                        | Qt.TextSelectableByMouse)
    doc = item.document()
    cursor = item.textCursor()
    assert doc is not None
    layout = doc.documentLayout()
    link = layout.anchorAt(pos)
    if not link and not showTextSelectionActions:
        return None
    menu = QMenu(parent)
    menu.setAttribute(Qt.WA_DeleteOnClose)
    if flags & Qt.TextEditable:
        addAction(
            menu,
            "&Undo",
            doc.undo,
            shortcut=QKeySequence.Undo,
            enabled=doc.isUndoAvailable(),
            objectName="edit-undo",
            icon="edit-undo",
        )
        addAction(
            menu,
            "&Redo",
            doc.redo,
            shortcut=QKeySequence.Redo,
            enabled=doc.isRedoAvailable(),
            objectName="edit-redo",
            icon="edit-redo",
        )
        menu.addSeparator()
        addAction(
            menu,
            "Cu&t",
            cut,
            shortcut=QKeySequence.Cut,
            enabled=cursor.hasSelection(),
            objectName="edit-cut",
            icon="edit-cut",
        )

    if showTextSelectionActions:
        addAction(menu,
                  "&Copy",
                  copy,
                  shortcut=QKeySequence.Copy,
                  enabled=cursor.hasSelection(),
                  objectName="edit-copy",
                  icon="edit-copy")

    if flags & (Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard):
        addAction(
            menu,
            "Copy &Link Location",
            copyLinkLocation,
            enabled=bool(link),
            objectName="link-copy",
        )

    if flags & Qt.TextEditable:
        addAction(
            menu,
            "&Paste",
            paste,
            shortcut=QKeySequence.Paste,
            enabled=canPaste(),
            objectName="edit-paste",
            icon="edit-paste",
        )
        addAction(
            menu,
            "Delete",
            deleteSelected,
            enabled=cursor.hasSelection(),
            objectName="edit-delete",
            icon="edit-delete",
        )

    if showTextSelectionActions:
        addAction(
            menu,
            "Select All",
            selectAll,
            shortcut=QKeySequence.SelectAll,
            enabled=not doc.isEmpty(),
            objectName="select-all",
        )
    return menu