コード例 #1
0
class ItemViewDragStartEventListener(QObject):
    dragStarted = Signal(QModelIndex)

    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self._pos = None
        self._index = None

    def eventFilter(self, viewport, event):
        view = viewport.parent()

        if event.type() == QEvent.MouseButtonPress and \
                event.button() == Qt.LeftButton:

            index = view.indexAt(event.pos())

            if index is not None:
                self._pos = event.pos()
                self._index = QPersistentModelIndex(index)

        elif event.type() == QEvent.MouseMove and self._pos is not None and \
                ((self._pos - event.pos()).manhattanLength() >=
                 QApplication.startDragDistance()):

            if self._index.isValid():
                # Map to a QModelIndex in the model.
                index = self._index
                index = index.model().index(index.row(), index.column(),
                                            index.parent())
                self._pos = None
                self._index = None

                self.dragStarted.emit(index)

        return QObject.eventFilter(self, view, event)
コード例 #2
0
    def LayerSelectionChanged(self, new_layer):
        persistent_new_layer = QPersistentModelIndex(new_layer)
        if self.previousActiveLayer is None:
            previous_layer = QPersistentModelIndex(self.layersModel.index(
                0, 0))
        else:
            previous_layer = self.previousActiveLayer
        self.previousActiveLayer = persistent_new_layer

        # remember parameter settings from previous layer when switching to new layer
        # store layer dependent parameters
        if previous_layer.isValid():  # could have been deleted...
            for t in TABS_WITH_PER_LAYER_PARAMS:
                tabidx = t.get_id()
                self.layersModel.itemFromIndex(QModelIndex(previous_layer)).parameters_per_tab[tabidx] = \
                    self.tabhandlers[tabidx].ui_to_model()

        # store overall parameters
        for t in TABS_OVER_ALL_LAYERS:
            tabidx = t.get_id()
            self.properties_over_all_layers_per_tab[tabidx] = self.tabhandlers[
                tabidx].ui_to_model()

        # show parameter settings on newly selected layer if they were stored in a previous visit already
        for t in TABS_WITH_PER_LAYER_PARAMS:
            tabidx = t.get_id()
            self.tabhandlers[tabidx].model_to_ui(
                self.layersModel.itemFromIndex(
                    new_layer).get_parameters_for_tab(tabidx))

        # restore overall parameters
        for t in TABS_OVER_ALL_LAYERS:
            tabidx = t.get_id()
            if tabidx in self.properties_over_all_layers_per_tab:
                self.tabhandlers[tabidx].model_to_ui(
                    self.properties_over_all_layers_per_tab[tabidx])

        # also make last used method the active tab
        last_used_method = self.layersModel.itemFromIndex(
            new_layer).get_last_used_method()
        self.squigglifySetup.setCurrentIndex(TAB_ORDER[last_used_method])
コード例 #3
0
 def set_current_idx(self, set_current: QPersistentModelIndex):
     if set_current:
         assert isinstance(set_current, QPersistentModelIndex)
         assert set_current.isValid()
         self.selectionModel().select(QModelIndex(set_current),
                                      QItemSelectionModel.SelectCurrent)
コード例 #4
0
ファイル: util.py プロジェクト: faircoin/electrumfair
 def set_current_idx(self, set_current: QPersistentModelIndex):
     if set_current:
         assert isinstance(set_current, QPersistentModelIndex)
         assert set_current.isValid()
         self.selectionModel().select(QModelIndex(set_current), QItemSelectionModel.SelectCurrent)
コード例 #5
0
class Tab(QWidget):
    currItemChanged = pyqtSignal(['QModelIndex'])

    def __init__(self, packItem=QModelIndex(), parent: TabWidget = None):
        super(Tab, self).__init__(parent)
        self.tabWidget = parent
        self.icon = QIcon()
        self.initActions()

        self.pathToolBar = ToolBar(self)
        self.pathToolBar.addAction(self.backAct)
        self.pathToolBar.addAction(self.forwardAct)

        self.pathLine: AddressLine = AddressLine(self)
        self.objTypeLine = LineEdit(self, placeholderText="Object Type")
        self.objTypeLine.setFixedWidth(168)
        self.objTypeLine.setReadOnly(True)

        self.descrLabel = QLabel(self)
        self.descrLabel.setWordWrap(True)
        self.descrLabel.setTextInteractionFlags(Qt.TextSelectableByMouse)

        QWebEngineSettings.defaultSettings().setAttribute(
            QWebEngineSettings.PluginsEnabled, True)
        self.mediaWidget = QWebEngineView()
        self.saveMediaAsBtn = QPushButton(
            f"Save media as..",
            self,
            toolTip="Save media file as..",
            clicked=lambda: self.saveMediaAsWithDialog(
                QStandardPaths.writableLocation(QStandardPaths.
                                                DocumentsLocation)))
        self.saveMediaBtn = QPushButton(
            f"Save media on desktop",
            self,
            toolTip="Save media file on desktop",
            clicked=lambda: self.saveMediaAsWithDialog(
                QStandardPaths.writableLocation(QStandardPaths.DesktopLocation)
            ))
        self.mediaViewWidget = QWidget()
        mediaViewWidgetLayout = QVBoxLayout(self.mediaViewWidget)
        mediaViewWidgetLayout.setContentsMargins(0, 0, 0, 0)
        mediaViewWidgetLayout.addWidget(self.mediaWidget)
        mediaViewWidgetLayout.addWidget(self.saveMediaBtn)
        mediaViewWidgetLayout.addWidget(self.saveMediaAsBtn)
        self.mediaViewWidget.hide()

        self.attrsTreeView = AttrsTreeView(self)
        self.attrsTreeView.setFrameShape(QFrame.NoFrame)

        self.toolBar = ToolBar(self)
        self.toolBar.addAction(self.attrsTreeView.zoomInAct)
        self.toolBar.addAction(self.attrsTreeView.zoomOutAct)
        self.toolBar.addAction(self.attrsTreeView.collapseAllAct)
        self.toolBar.addAction(self.attrsTreeView.expandAllAct)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.attrsTreeView.undoAct)
        self.toolBar.addAction(self.attrsTreeView.redoAct)
        self.toolBar.addAction(self.attrsTreeView.copyAct)
        self.toolBar.addAction(self.attrsTreeView.cutAct)
        self.toolBar.addAction(self.attrsTreeView.pasteAct)
        self.toolBar.addAction(self.attrsTreeView.delClearAct)
        self.toolBar.addAction(self.attrsTreeView.editCreateInDialogAct)
        self.toolBar.addAction(self.attrsTreeView.addAct)
        self.searchBar = SearchBar(
            self.attrsTreeView,
            parent=self,
            filterColumns=[ATTRIBUTE_COLUMN, VALUE_COLUMN],
            closable=True)
        self.searchBar.hide()
        self.openSearchBarSC = QShortcut(SC_SEARCH,
                                         self,
                                         activated=self.openSearchBar)

        self.packItem = QPersistentModelIndex(QModelIndex())
        self.prevItems = []
        self.nextItems = []
        if packItem.isValid():
            self.openItem(packItem)
        else:
            self.openEmptyItem()

        self._initLayout()

    # noinspection PyArgumentList
    def initActions(self):
        self.backAct = QAction(BACK_ICON,
                               "Back",
                               self,
                               statusTip=f"Go back one item",
                               toolTip=f"Go back one item",
                               shortcut=SC_BACK,
                               triggered=self.openPrevItem,
                               enabled=False)

        self.forwardAct = QAction(FORWARD_ICON,
                                  "Forward",
                                  self,
                                  statusTip=f"Go forward one item",
                                  toolTip=f"Go forward one item",
                                  shortcut=SC_FORWARD,
                                  triggered=self.openNextItem,
                                  enabled=False)

    def windowTitle(self) -> str:
        return self.packItem.data(NAME_ROLE)

    def windowIcon(self) -> QIcon:
        return self.packItem.data(Qt.DecorationRole)

    def openSearchBar(self):
        self.searchBar.show()
        self.searchBar.searchLine.setFocus()

    def openItem(self, packItem: QModelIndex):
        if not packItem == QModelIndex(self.packItem):
            self.nextItems.clear()
            if self.packItem.isValid():
                self.prevItems.append(self.packItem)
            self._openItem(packItem)

    def openPrevItem(self):
        if self.prevItems:
            prevItem = self.prevItems.pop()
            self.nextItems.append(self.packItem)
            self._openItem(QModelIndex(prevItem))

    def openNextItem(self):
        if self.nextItems:
            nextItem = self.nextItems.pop()
            self.prevItems.append(self.packItem)
            self._openItem(QModelIndex(nextItem))

    def openEmptyItem(self):
        self._openItem(QModelIndex())

    def _openItem(self, packItem: QModelIndex):
        try:
            currTab: Tab = self.tabWidget.currentWidget()
            state = currTab.attrsTreeView.header().saveState()
        except AttributeError:
            # if there is no curr widget, there is no current header state, it
            state = None

        self.packItem = QPersistentModelIndex(packItem.siblingAtColumn(0))
        self.descrLabel.setText("")

        self.packItemObj = self.packItem.data(OBJECT_ROLE)
        self.updateMediaWidget()
        self.pathLine.setText(getTreeItemPath(self.packItem))
        self.objTypeLine.setText(getTypeName(type(self.packItemObj)))

        icon = self.packItem.data(Qt.DecorationRole)
        if icon:
            self.setWindowIcon(icon)
        self.setWindowTitle(self.packItem.data(Qt.DisplayRole))
        self.attrsTreeView.newPackItem(self.packItem)
        self.attrsTreeView.selectionModel().currentChanged.connect(
            self.showDetailInfoItemDoc)
        self.currItemChanged.emit(QModelIndex(self.packItem))

        self.forwardAct.setEnabled(
            True) if self.nextItems else self.forwardAct.setDisabled(True)
        self.backAct.setEnabled(
            True) if self.prevItems else self.backAct.setDisabled(True)
        if state:
            self.attrsTreeView.header().restoreState(state)

    def updateMediaWidget(self):
        if self.packItem.data(IS_MEDIA_ROLE):
            self.mediaWidget.setContent(b"loading...")
            self.mediaViewWidget.show()
            if not self.mediaWidget.width():
                # set equal sizes
                oldSizes = self.splitter.sizes()
                newSizes = [
                    sum(oldSizes) / (len(oldSizes)) for size in oldSizes
                ]
                self.splitter.setSizes(newSizes)

            try:
                mediaContent = self.packItem.data(MEDIA_CONTENT_ROLE)
                if self.packItem.data(IS_URL_MEDIA_ROLE):
                    self.mediaWidget.load(QUrl(mediaContent.value))
                else:
                    self.mediaWidget.setContent(mediaContent.value,
                                                mediaContent.mime_type)
            except Exception as e:
                print(e)
                self.mediaWidget.setContent(
                    b"Error occurred while loading media")
            self.mediaWidget.setZoomFactor(1.0)
        else:
            self.mediaViewWidget.hide()

    def saveMediaAsWithDialog(self, directory="") -> bool:
        mediaContent = self.packItem.data(MEDIA_CONTENT_ROLE)
        file = self.packItem.data(NAME_ROLE)
        saved = False
        while not saved:
            try:
                file = QFileDialog.getSaveFileName(
                    self,
                    'Save media File',
                    directory + "/" + file.strip("/"),
                    options=FILE_DIALOG_OPTIONS)[0]
            except AttributeError as e:
                QMessageBox.critical(self, "Error", f"{e}")
            else:
                if file:
                    saved = self.saveMedia(mediaContent, file)
                else:
                    # cancel pressed
                    return

    def saveMedia(self, media=None, file: str = None) -> bool:
        try:
            with open(file, "wb") as f:
                f.write(media.value)
            return True
        except (TypeError, ValueError) as e:
            QMessageBox.critical(self, "Error",
                                 f"Media couldn't be saved: {file}: {e}")
        except AttributeError as e:
            QMessageBox.critical(self, "Error",
                                 f"No chosen media to save: {e}")
        return False

    def showDetailInfoItemDoc(self, detailInfoItem: QModelIndex):
        self.descrLabel.setText(detailInfoItem.data(Qt.WhatsThisRole))

    def _initLayout(self):
        pathWidget = QWidget()
        pathLayout = QHBoxLayout(pathWidget)
        pathLayout.setContentsMargins(0, 0, 0, 0)
        pathLayout.addWidget(self.pathToolBar)
        pathLayout.addWidget(self.pathLine)
        pathLayout.addWidget(self.objTypeLine)
        pathWidget.setFixedHeight(TOOLBARS_HEIGHT)

        toolBarWidget = QWidget()
        toolBarLayout = QHBoxLayout(toolBarWidget)
        toolBarLayout.setContentsMargins(0, 0, 0, 0)
        toolBarLayout.addWidget(self.toolBar)
        toolBarLayout.addWidget(self.searchBar)
        toolBarWidget.setFixedHeight(TOOLBARS_HEIGHT)

        treeViewWidget = QWidget()
        treeViewLayout = QVBoxLayout(treeViewWidget)
        treeViewLayout.setContentsMargins(0, 0, 0, 0)
        treeViewLayout.addWidget(pathWidget)
        treeViewLayout.addWidget(self.attrsTreeView)
        treeViewLayout.addWidget(self.descrLabel)

        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Horizontal)
        self.splitter.setContentsMargins(0, 0, 0, 0)
        self.splitter.addWidget(treeViewWidget)
        self.splitter.addWidget(self.mediaViewWidget)

        layout = QVBoxLayout(self)
        layout.setObjectName("tabLayout")
        layout.addWidget(pathWidget)
        layout.addWidget(toolBarWidget)
        layout.addWidget(self.splitter)
        layout.setSpacing(2)
        layout.setContentsMargins(0, 2, 0, 2)