示例#1
0
class LabelConfigurator(QDialog):
    def __init__(self, boxManager, spawnPos):
        super().__init__()
        # Variables
        self.spawnPos = spawnPos

        # Objects
        self.boxManager = boxManager
        self.layout = QVBoxLayout(self)
        self.contentLayout = QHBoxLayout()
        self.settingsLayout = QVBoxLayout()
        self.isOccludedButton = Check('Occluded',
                                      boxManager.getRecentIsOccluded())
        self.isTruncatedButton = Check('Truncated',
                                       boxManager.getRecentIsTruncated())
        self.isGroupOfButton = Check('Group Of',
                                     boxManager.getRecentIsGroupOf())
        self.isDepictionButton = Check('Depiction',
                                       boxManager.getRecentIsDepiction())
        self.isInsideButton = Check('Inside', boxManager.getRecentIsInside())
        self.acceptButton = QPushButton('Accept')
        self.cancelButton = QPushButton('Cancel')
        self.labelsModel = QStringListModel()
        self.labelsView = QListView()

        # Layout
        self.setWindowFlags(Qt.Popup)
        self.settingsLayout.setAlignment(Qt.AlignTop | Qt.AlignCenter)
        self.settingsLayout.setMargin(0)
        self.settingsLayout.addWidget(self.isOccludedButton)
        self.settingsLayout.addWidget(self.isTruncatedButton)
        self.settingsLayout.addWidget(self.isGroupOfButton)
        self.settingsLayout.addWidget(self.isDepictionButton)
        self.settingsLayout.addWidget(self.isInsideButton)
        self.settingsLayout.addStretch(1)
        self.settingsLayout.addWidget(self.acceptButton)
        self.settingsLayout.addWidget(self.cancelButton)
        self.contentLayout.addWidget(self.labelsView)
        self.contentLayout.addLayout(self.settingsLayout)
        self.layout.addLayout(self.contentLayout)

        # Styling
        self.setStyleSheet('LabelConfigurator { '
                           'background-color: ' + ThemeManager.BG_L1 + ';'
                           'border-top-left-radius:     ' +
                           str(ThemeManager.CURVE) + 'px;'
                           'border-bottom-left-radius:  ' +
                           str(ThemeManager.CURVE) + 'px;'
                           'border-top-right-radius:    ' +
                           str(ThemeManager.CURVE) + 'px;'
                           'border-bottom-right-radius: ' +
                           str(ThemeManager.CURVE) + 'px;'
                           'border-width: 0px;'
                           'border-style: solid;'
                           '}'
                           'QPushButton {'
                           'background-color: ' + ThemeManager.BG_L2 + ';'
                           'border-radius: 10px;'
                           'color: ' + ThemeManager.LABEL + ';'
                           'font-size: 14px;'
                           '}'
                           'QPushButton:hover {'
                           'background-color: ' + ThemeManager.BG_L3 + ';'
                           '}'
                           'QListView { '
                           'background-color: ' + ThemeManager.BG_L2 + ';'
                           '}')
        self.layout.setMargin(20)
        self.layout.setSpacing(10)
        self.contentLayout.setMargin(0)
        self.labelsModel.setStringList(boxManager.loadLabels())
        self.labelsView.setFixedWidth(80)
        self.labelsView.setFrameStyle(QFrame.NoFrame)
        self.labelsView.setModel(self.labelsModel)
        self.labelsView.setItemDelegate(ListDelegate.ListDelegate())

        index = None
        try:
            row = self.labelsModel.stringList().index(
                boxManager.getRecentLabelName())
            index = self.labelsModel.index(row)
        except ValueError:
            index = self.labelsModel.index(0)
        if index is not None:
            self.labelsView.setCurrentIndex(index)

        # Connections
        self.acceptButton.clicked.connect(self.close)
        self.cancelButton.clicked.connect(self.reject)

    def showEvent(self, event):
        super().showEvent(event)
        self.move(self.spawnPos)

    def closeEvent(self, event):
        labelConfig = (self.labelsView.selectedIndexes()[0].data(
            role=Qt.DisplayRole), self.isOccludedButton.getEnabled(),
                       self.isTruncatedButton.getEnabled(),
                       self.isGroupOfButton.getEnabled(),
                       self.isDepictionButton.getEnabled(),
                       self.isInsideButton.getEnabled())
        self.labelAccepted.emit(labelConfig)
        super().closeEvent(event)

    def getLabelConfig(self):
        return

    labelAccepted = Signal(object)
示例#2
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.player = QMediaPlayer()

        self.player.error.connect(self.erroralert)
        self.player.play()

        # Setup the playlist.
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        # Add viewer for video playback, separate floating window.
        self.viewer = ViewerWindow(self)
        self.viewer.setWindowFlags(self.viewer.windowFlags()
                                   | Qt.WindowStaysOnTopHint)
        self.viewer.setMinimumSize(QSize(480, 360))

        videoWidget = QVideoWidget()
        self.viewer.setCentralWidget(videoWidget)
        self.player.setVideoOutput(videoWidget)

        # Connect control buttons/slides for media player.
        self.playButton.pressed.connect(self.player.play)
        self.pauseButton.pressed.connect(self.player.pause)
        self.stopButton.pressed.connect(self.player.stop)
        self.volumeSlider.valueChanged.connect(self.player.setVolume)

        self.viewButton.toggled.connect(self.toggle_viewer)
        self.viewer.state.connect(self.viewButton.setChecked)

        self.previousButton.pressed.connect(self.playlist.previous)
        self.nextButton.pressed.connect(self.playlist.next)

        self.model = PlaylistModel(self.playlist)
        self.playlistView.setModel(self.model)
        self.playlist.currentIndexChanged.connect(
            self.playlist_position_changed)
        selection_model = self.playlistView.selectionModel()
        selection_model.selectionChanged.connect(
            self.playlist_selection_changed)

        self.player.durationChanged.connect(self.update_duration)
        self.player.positionChanged.connect(self.update_position)
        self.timeSlider.valueChanged.connect(self.player.setPosition)

        self.open_file_action.triggered.connect(self.open_file)

        self.setAcceptDrops(True)

        self.show()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(484, 371)
        self.centralWidget = QWidget(MainWindow)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.centralWidget.sizePolicy().hasHeightForWidth())
        self.centralWidget.setSizePolicy(sizePolicy)
        self.centralWidget.setObjectName("centralWidget")
        self.horizontalLayout = QHBoxLayout(self.centralWidget)
        self.horizontalLayout.setContentsMargins(11, 11, 11, 11)
        self.horizontalLayout.setSpacing(6)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")
        self.playlistView = QListView(self.centralWidget)
        self.playlistView.setAcceptDrops(True)
        self.playlistView.setProperty("showDropIndicator", True)
        self.playlistView.setDragDropMode(QAbstractItemView.DropOnly)
        self.playlistView.setAlternatingRowColors(True)
        self.playlistView.setUniformItemSizes(True)
        self.playlistView.setObjectName("playlistView")
        self.verticalLayout.addWidget(self.playlistView)
        self.horizontalLayout_4 = QHBoxLayout()
        self.horizontalLayout_4.setSpacing(6)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.currentTimeLabel = QLabel(self.centralWidget)
        self.currentTimeLabel.setMinimumSize(QSize(80, 0))
        self.currentTimeLabel.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                           | Qt.AlignVCenter)
        self.currentTimeLabel.setObjectName("currentTimeLabel")
        self.horizontalLayout_4.addWidget(self.currentTimeLabel)
        self.timeSlider = QSlider(self.centralWidget)
        self.timeSlider.setOrientation(Qt.Horizontal)
        self.timeSlider.setObjectName("timeSlider")
        self.horizontalLayout_4.addWidget(self.timeSlider)
        self.totalTimeLabel = QLabel(self.centralWidget)
        self.totalTimeLabel.setMinimumSize(QSize(80, 0))
        self.totalTimeLabel.setAlignment(Qt.AlignLeading | Qt.AlignLeft
                                         | Qt.AlignVCenter)
        self.totalTimeLabel.setObjectName("totalTimeLabel")
        self.horizontalLayout_4.addWidget(self.totalTimeLabel)
        self.verticalLayout.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_5 = QHBoxLayout()
        self.horizontalLayout_5.setSpacing(6)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.previousButton = QPushButton(self.centralWidget)
        self.previousButton.setText("")
        icon = QIcon()
        icon.addPixmap(QPixmap("images/control-skip-180.png"), QIcon.Normal,
                       QIcon.Off)
        self.previousButton.setIcon(icon)
        self.previousButton.setObjectName("previousButton")
        self.horizontalLayout_5.addWidget(self.previousButton)
        self.playButton = QPushButton(self.centralWidget)
        self.playButton.setText("")
        icon1 = QIcon()
        icon1.addPixmap(QPixmap("images/control.png"), QIcon.Normal, QIcon.Off)
        self.playButton.setIcon(icon1)
        self.playButton.setObjectName("playButton")
        self.horizontalLayout_5.addWidget(self.playButton)
        self.pauseButton = QPushButton(self.centralWidget)
        self.pauseButton.setText("")
        icon2 = QIcon()
        icon2.addPixmap(QPixmap("images/control-pause.png"), QIcon.Normal,
                        QIcon.Off)
        self.pauseButton.setIcon(icon2)
        self.pauseButton.setObjectName("pauseButton")
        self.horizontalLayout_5.addWidget(self.pauseButton)
        self.stopButton = QPushButton(self.centralWidget)
        self.stopButton.setText("")
        icon3 = QIcon()
        icon3.addPixmap(QPixmap("images/control-stop-square.png"),
                        QIcon.Normal, QIcon.Off)
        self.stopButton.setIcon(icon3)
        self.stopButton.setObjectName("stopButton")
        self.horizontalLayout_5.addWidget(self.stopButton)
        self.nextButton = QPushButton(self.centralWidget)
        self.nextButton.setText("")
        icon4 = QIcon()
        icon4.addPixmap(QPixmap("images/control-skip.png"), QIcon.Normal,
                        QIcon.Off)
        self.nextButton.setIcon(icon4)
        self.nextButton.setObjectName("nextButton")
        self.horizontalLayout_5.addWidget(self.nextButton)
        self.viewButton = QPushButton(self.centralWidget)
        self.viewButton.setText("")
        icon5 = QIcon()
        icon5.addPixmap(QPixmap("images/application-image.png"), QIcon.Normal,
                        QIcon.Off)
        self.viewButton.setIcon(icon5)
        self.viewButton.setCheckable(True)
        self.viewButton.setObjectName("viewButton")
        self.horizontalLayout_5.addWidget(self.viewButton)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout_5.addItem(spacerItem)
        self.label = QLabel(self.centralWidget)
        self.label.setText("")
        self.label.setPixmap(QPixmap("images/speaker-volume.png"))
        self.label.setObjectName("label")
        self.horizontalLayout_5.addWidget(self.label)
        self.volumeSlider = QSlider(self.centralWidget)
        self.volumeSlider.setMaximum(100)
        self.volumeSlider.setProperty("value", 100)
        self.volumeSlider.setOrientation(Qt.Horizontal)
        self.volumeSlider.setObjectName("volumeSlider")
        self.horizontalLayout_5.addWidget(self.volumeSlider)
        self.verticalLayout.addLayout(self.horizontalLayout_5)
        self.horizontalLayout.addLayout(self.verticalLayout)
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QMenuBar(MainWindow)
        self.menuBar.setGeometry(QRect(0, 0, 484, 22))
        self.menuBar.setObjectName("menuBar")
        self.menuFIle = QMenu(self.menuBar)
        self.menuFIle.setObjectName("menuFIle")
        MainWindow.setMenuBar(self.menuBar)
        self.statusBar = QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.open_file_action = QAction(MainWindow)
        self.open_file_action.setObjectName("open_file_action")
        self.menuFIle.addAction(self.open_file_action)
        self.menuBar.addAction(self.menuFIle.menuAction())

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Failamp"))
        self.currentTimeLabel.setText(_translate("MainWindow", "0:00"))
        self.totalTimeLabel.setText(_translate("MainWindow", "0:00"))
        self.menuFIle.setTitle(_translate("MainWindow", "FIle"))
        self.open_file_action.setText(_translate("MainWindow", "Open file..."))

    def dragEnterEvent(self, e):
        if e.mimeData().hasUrls():
            e.acceptProposedAction()

    def dropEvent(self, e):
        for url in e.mimeData().urls():
            self.playlist.addMedia(QMediaContent(url))

        self.model.layoutChanged.emit()

        # If not playing, seeking to first of newly added + play.
        if self.player.state() != QMediaPlayer.PlayingState:
            i = self.playlist.mediaCount() - len(e.mimeData().urls())
            self.playlist.setCurrentIndex(i)
            self.player.play()

    def open_file(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "Open file", "",
            "mp3 Audio (*.mp3);mp4 Video (*.mp4);Movie files (*.mov);All files (*.*)"
        )

        if path:
            self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path)))

        self.model.layoutChanged.emit()

    def update_duration(self, duration):
        print("!", duration)
        print("?", self.player.duration())

        self.timeSlider.setMaximum(duration)

        if duration >= 0:
            self.totalTimeLabel.setText(hhmmss(duration))

    def update_position(self, position):
        if position >= 0:
            self.currentTimeLabel.setText(hhmmss(position))

        # Disable the events to prevent updating triggering a setPosition event (can cause stuttering).
        self.timeSlider.blockSignals(True)
        self.timeSlider.setValue(position)
        self.timeSlider.blockSignals(False)

    def playlist_selection_changed(self, ix):
        # We receive a QItemSelection from selectionChanged.
        i = ix.indexes()[0].row()
        self.playlist.setCurrentIndex(i)

    def playlist_position_changed(self, i):
        if i > -1:
            ix = self.model.index(i)
            self.playlistView.setCurrentIndex(ix)

    def toggle_viewer(self, state):
        if state:
            self.viewer.show()
        else:
            self.viewer.hide()

    def erroralert(self, *args):
        print(args)
示例#3
0
class IconColorEditor(QDialog):
    """An editor to let the user select an icon and a color for an object_class.
    """
    def __init__(self, parent):
        """Init class."""
        super().__init__(parent)  # , Qt.Popup)
        icon_size = QSize(32, 32)
        self.icon_mngr = IconListManager(icon_size)
        self.setWindowTitle("Select icon and color")
        self.icon_widget = QWidget(self)
        self.icon_list = QListView(self.icon_widget)
        self.icon_list.setViewMode(QListView.IconMode)
        self.icon_list.setIconSize(icon_size)
        self.icon_list.setResizeMode(QListView.Adjust)
        self.icon_list.setItemDelegate(_IconPainterDelegate(self))
        self.icon_list.setMovement(QListView.Static)
        self.icon_list.setMinimumHeight(400)
        icon_widget_layout = QVBoxLayout(self.icon_widget)
        icon_widget_layout.addWidget(QLabel("Font Awesome icons"))
        self.line_edit = QLineEdit()
        self.line_edit.setPlaceholderText("Search icons for...")
        icon_widget_layout.addWidget(self.line_edit)
        icon_widget_layout.addWidget(self.icon_list)
        self.color_dialog = QColorDialog(self)
        self.color_dialog.setWindowFlags(Qt.Widget)
        self.color_dialog.setOption(QColorDialog.NoButtons, True)
        self.color_dialog.setOption(QColorDialog.DontUseNativeDialog, True)
        self.button_box = QDialogButtonBox(self)
        self.button_box.setStandardButtons(QDialogButtonBox.Cancel
                                           | QDialogButtonBox.Ok)
        top_widget = QWidget(self)
        top_layout = QHBoxLayout(top_widget)
        top_layout.addWidget(self.icon_widget)
        top_layout.addWidget(self.color_dialog)
        layout = QVBoxLayout(self)
        layout.addWidget(top_widget)
        layout.addWidget(self.button_box)
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.icon_mngr.model)
        self.proxy_model.filterAcceptsRow = self._proxy_model_filter_accepts_row
        self.icon_list.setModel(self.proxy_model)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.connect_signals()

    def _proxy_model_filter_accepts_row(self, source_row, source_parent):
        """Overridden method to filter icons according to search terms.
        """
        text = self.line_edit.text()
        if not text:
            return QSortFilterProxyModel.filterAcceptsRow(
                self.proxy_model, source_row, source_parent)
        searchterms = self.icon_mngr.model.index(
            source_row, 0, source_parent).data(Qt.UserRole + 1)
        return any([text in term for term in searchterms])

    def connect_signals(self):
        """Connect signals to slots."""
        self.line_edit.textEdited.connect(self.proxy_model.invalidateFilter)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

    def set_data(self, data):
        icon_code, color_code = interpret_icon_id(data)
        self.icon_mngr.init_model()
        for i in range(self.proxy_model.rowCount()):
            index = self.proxy_model.index(i, 0)
            if index.data(Qt.UserRole) == icon_code:
                self.icon_list.setCurrentIndex(index)
                break
        self.color_dialog.setCurrentColor(QColor(color_code))

    def data(self):
        icon_code = self.icon_list.currentIndex().data(Qt.UserRole)
        color_code = self.color_dialog.currentColor().rgb()
        return make_icon_id(icon_code, color_code)
示例#4
0
class AuswahlDialog(QDialog):
    def __init__(self, title=None, parent=None):
        QDialog.__init__(self, parent)
        self.title = title
        self.listView = QListView()
        self.font = QFont("Arial", 14)
        self.okButton = QPushButton("OK")
        self.cancelButton = QPushButton("Abbrechen")
        self.model = QStandardItemModel()
        self.listView.setModel(self.model)
        self._selectedIndexes = ""
        self._createGui()

    def _createGui(self):
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(self.okButton)
        hbox.addWidget(self.cancelButton)

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.listView, stretch=1)
        # vbox.addStretch(1)
        vbox.addLayout(hbox)

        self.okButton.setDefault(True)

        if self.title:
            self.setWindowTitle(self.title)
        else:
            self.setWindowTitle("Auswahl")

        self.okButton.clicked.connect(self.onAccepted)
        self.cancelButton.clicked.connect(self.reject)

    def appendItemList(self, itemlist: List[str]):
        for i in itemlist:
            self.appendItem(i, None)

    def appendItem(self, text: str, userdata: Any = None):
        item = CustomItem(text)
        if userdata:
            item.userdata = userdata
        item.setFont(self.font)
        self.model.appendRow(item)
        if self.model.rowCount() == 1:
            self.listView.setCurrentIndex(self.model.index(0, 0))

    def onAccepted(self):
        self._selectedIndexes = self.listView.selectedIndexes()
        self.accept()

    def getSelectedIndexes(self):
        return self._selectedIndexes

    def getSelection(self) -> List[Tuple]:
        sel = self.getSelectedIndexes()
        l = list()
        for idx in sel:
            item: CustomItem = self.model.item(idx.row(), idx.column())
            t = (item.text(), item.userdata)
            l.append(t)

        return l
示例#5
0
class PipelineEditor(QGroupBox):
    def __init__(self, file_picker):
        super().__init__("Pipeline Editor")

        self.setLayout(QVBoxLayout())

        self.file_picker = file_picker

        self.pipeline = Pipeline()
        self.pipelineView = QListView()
        self.pipelineView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.pipelineView.setModel(QStandardItemModel())

        self.layout().addWidget(self.pipelineView)

        # === BUTTON CONTAINER ===
        button_rows = QWidget()
        self.layout().addWidget(button_rows)
        button_rows_layout = QVBoxLayout(button_rows)
        button_rows_layout.setContentsMargins(0, 0, 0, 0)

        # === ROW 1 ===
        row_1 = QWidget()
        button_rows_layout.addWidget(row_1)
        row_1_layout = QHBoxLayout(row_1)
        row_1_layout.setContentsMargins(0, 0, 0, 0)

        self.moveUpButton = QPushButton("Move Up")
        row_1_layout.addWidget(self.moveUpButton)
        self.moveUpButton.clicked.connect(self._move_up_listener)

        self.moveDownButton = QPushButton("Move Down")
        row_1_layout.addWidget(self.moveDownButton)
        self.moveDownButton.clicked.connect(self._move_down_listener)

        self.deleteButton = QPushButton("Delete")
        row_1_layout.addWidget(self.deleteButton)
        self.deleteButton.clicked.connect(self._delete_listener)

        # === ROW 2 ===
        row_2 = QWidget()
        button_rows_layout.addWidget(row_2)
        row_2_layout = QHBoxLayout(row_2)
        row_2_layout.setContentsMargins(0, 0, 0, 0)

        self.applyButton = QPushButton("Apply Pipeline")
        row_2_layout.addWidget(self.applyButton)
        self.applyButton.clicked.connect(self._apply_pipeline_listener)

        self.update_pipeline_view()

    def update_pipeline_view(self):
        logging.debug(self.pipeline)
        model = self.pipelineView.model()
        model.clear()

        for t in range(self.pipeline.rowCount()):
            item = QStandardItem()
            item.setText(repr(self.pipeline.data(t)))
            model.appendRow(item)

    def _modify_transformation_listener(self):
        # TODO
        raise NotImplementedError

    def _move_up_listener(self):
        try:
            to_move = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            if to_move < 1:
                return
            self.pipeline.move_transformation_up(to_move)
            self.update_pipeline_view()
            self.pipelineView.setCurrentIndex(self.pipelineView.model().index(
                to_move - 1, 0))
        except IndexError:
            return

    def _move_down_listener(self):
        try:
            to_move = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            if to_move > self.pipelineView.model().rowCount() - 2:
                return
            self.pipeline.move_transformation_down(to_move)
            self.update_pipeline_view()
            self.pipelineView.setCurrentIndex(self.pipelineView.model().index(
                to_move + 1, 0))
        except IndexError:
            return

    def _delete_listener(self):
        try:
            to_delete = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            self.pipeline.remove_transformation(to_delete)
            self.update_pipeline_view()
            if to_delete > self.pipelineView.model().rowCount() - 1:
                self.pipelineView.setCurrentIndex(
                    self.pipelineView.model().index(to_delete - 1, 0))
            else:
                self.pipelineView.setCurrentIndex(
                    self.pipelineView.model().index(to_delete, 0))
        except IndexError:
            return

    def _apply_pipeline_listener(self):
        # Check that at least one transformation has been added to the pipeline
        if self.pipeline.rowCount() == 0:
            no_transformations_messagebox = QMessageBox(self)
            no_transformations_messagebox.setText(
                "ERROR: No transformations selected")
            no_transformations_messagebox.exec_()
            return

        file_sequence = self.file_picker.file_sequence.files

        # Check that at least one file has been added to the file sequence
        if len(file_sequence) == 0:
            no_files_messagebox = QMessageBox(self)
            no_files_messagebox.setText("ERROR: No files selected")
            no_files_messagebox.exec_()
            return

        transformed_sequence = self.pipeline.resolve(file_sequence)

        before_after = list(zip(file_sequence, transformed_sequence))

        preview_text_lines = []
        for rename in before_after:
            preview_text_lines.append(f"{rename[0].name} -> {rename[1].name}")
        preview_text = "\n".join(preview_text_lines)

        confirmation = QMessageBox(self)
        confirmation.setText("Are you sure you want to apply the pipeline?")
        confirmation.setDetailedText(preview_text)
        confirmation.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        confirmation.setDefaultButton(QMessageBox.No)
        ret = confirmation.exec_()

        if ret == int(QMessageBox.Yes):
            for rename in before_after:
                from_path = rename[0]
                to_path = rename[1]

                shutil.move(str(from_path), str(to_path))
            self.file_picker.clear_file_list()
示例#6
0
class Completer(QWidget):
    """docstring for ClassName

    Attributes:
        delegate (CompleterDelegate): the delegate use by the view
        model (CompleterModel): the model
        proxy_model (QSortFilterProxyModel ): the proxy model used to filter model
        panel (QLabel): The description widget
        view (QListView): the view 
    
    Signals:
        activated (str): return the keyword selected 
    """

    activated = Signal(str)

    def __init__(self, parent=None):
        super().__init__(parent)

        self._target = None
        self._completion_prefix = ""

        self.setWindowFlag(Qt.Popup)
        self.setFocusPolicy(Qt.NoFocus)

        #  create model
        self.model = CompleterModel()
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)

        #  create delegate
        self.delegate = CompleterDelegate()
        # create view
        self.view = QListView()
        self.view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.view.setFocusPolicy(Qt.NoFocus)
        self.view.installEventFilter(self)
        self.view.setModel(self.proxy_model)
        self.view.setItemDelegate(self.delegate)
        self.view.setMinimumWidth(200)
        self.view.setUniformItemSizes(True)
        self.view.setSpacing(0)

        self.view.selectionModel().currentRowChanged.connect(
            self._on_row_changed)
        self.setFocusProxy(self.view)

        #  create panel info
        self.panel = QLabel()
        self.panel.setAlignment(Qt.AlignTop)
        self.panel.setMinimumWidth(300)
        self.panel.setWordWrap(True)
        self.panel.setFrameShape(QFrame.StyledPanel)

        # Create layout
        vlayout = QHBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        vlayout.setSpacing(0)
        vlayout.addWidget(self.view)
        vlayout.addWidget(self.panel)
        self.setLayout(vlayout)

    def set_target(self, target):
        """Set CodeEdit  
        
        Args:
            target (CodeEdit): The CodeEdit 
        """
        self._target = target
        self.installEventFilter(self._target)

    def eventFilter(self, obj: QObject, event: QEvent) -> bool:
        """Filter event from CodeEdit and QListView
        
        Args:
            obj (QObject): Description
            event (QEvent): Description
        
        Returns:
            bool
        """

        #  Intercept CodeEdit event
        if obj == self._target:
            if event.type() == QEvent.FocusOut:
                # Ignore lost focus!
                return True
            else:
                obj.event(event)
                return True

        # Intercept QListView event
        if obj == self.view:
            #  Redirect event to QTextExit

            if event.type() == QEvent.KeyPress and self._target:

                current = self.view.selectionModel().currentIndex()

                # emit signal when user press return
                if event.key() == Qt.Key_Return:
                    word = current.data()
                    self.activated.emit(word)
                    self.hide()
                    event.ignore()
                    return True

                # use tab to move down/up in the list
                if event.key() == Qt.Key_Tab:
                    if current.row() < self.proxy_model.rowCount() - 1:
                        self.view.setCurrentIndex(
                            self.proxy_model.index(current.row() + 1, 0))
                if event.key() == Qt.Key_Backtab:
                    if current.row() > 0:
                        self.view.setCurrentIndex(
                            self.proxy_model.index(current.row() - 1, 0))

                # Route other key event to the target ! This make possible to write text when completer is visible
                self._target.event(event)

        return super().eventFilter(obj, event)

    def complete(self, rect: QRect):
        """Show completer as popup
        
        Args:
            rect (QRect): the area where to display the completer
        
        """
        if self.proxy_model.rowCount() == 0:
            self.hide()
            return

        if self._target:
            pos = self._target.mapToGlobal(rect.bottomRight())
            self.move(pos)
            self.setFocus()
            if not self.isVisible():
                width = 400
                #height = self.view.sizeHintForRow(0) * self.proxy_model.rowCount() + 3
                #  HACK.. TODO better !
                #height = min(self._target.height() / 2, height)

                #self.resize(width, height)
                self.adjustSize()
                self.show()

    def set_completion_prefix(self, prefix: str):
        """Set prefix and filter model 
        
        Args:
            prefix (str): A prefix keyword used to filter model
        """
        self.view.clearSelection()
        self._completion_prefix = prefix
        self.proxy_model.setFilterRegularExpression(
            QRegularExpression(f"^{prefix}.*",
                               QRegularExpression.CaseInsensitiveOption))
        if self.proxy_model.rowCount() > 0:
            self.select_row(0)

    def select_row(self, row: int):
        """Select a row in the model
        
        Args:
            row (int): a row number
        """
        index = self.proxy_model.index(row, 0)
        self.view.selectionModel().setCurrentIndex(index,
                                                   QItemSelectionModel.Select)

    def completion_prefix(self) -> str:
        """getter of completion_prefix
        
        TODO: use getter / setter 
        
        Returns:
            str: Return the completion_prefix
        """
        return self._completion_prefix

    def hide(self):
        """Override from QWidget

        Hide the completer 
        """
        self.set_completion_prefix("")
        super().hide()

    def _on_row_changed(self, current: QModelIndex, previous: QModelIndex):
        """Slot received when user select a new item in the list.
        This is used to update the panel
        
        Args:
            current (QModelIndex): the selection index
            previous (QModelIndex): UNUSED
        """
        description = current.data(Qt.ToolTipRole)
        self.panel.setText(description)