Ejemplo n.º 1
0
    def add_vertical_splitter(self, layout):
        splitter = QSplitter()
        layout.addWidget(splitter)

        # ADD LEFT
        left_widget = QWidget(splitter)
        left = QVBoxLayout(left_widget)

        # NORMAL
        let = QLineEdit('Line Edit With Text')
        left.layout().addWidget(let)

        #PLACEHOLDER
        let = QLineEdit()
        let.setPlaceholderText('This is placeholder text...')
        left.layout().addWidget(let)

        # DISABLED
        let = QLineEdit('Line Edit Disabled')
        let.setEnabled(False)
        left.layout().addWidget(let)

        # ADD RIGHT
        right_widget = QWidget(splitter)
        right = QGridLayout(right_widget)

        # GROUP BOX
        grp = QGroupBox("Group Box")
        right.layout().addWidget(grp)

        grp_layout = QGridLayout(grp)

        btn = QPushButton('Set Style')
        btn.pressed.connect(self.set_style)
        grp_layout.addWidget(btn)
def SaveZeroPoint(offset: float, zeroPointManager: ZeroPointManager):
    dialog = QDialog()
    dialog.setWindowTitle("Save Zero Position")

    zeroPositionNameLineEdit = QLineEdit("Default Name: ")
    zeroPositionOffsetLineEdit = QLineEdit(str(offset))
    zeroPositionOffsetLineEdit.setEnabled(False)

    buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

    def createNewZeroPoint():
        zeroPointManager.createZeroPoint(
            zeroPositionNameLineEdit.text(),
            float(zeroPositionOffsetLineEdit.text()))
        dialog.close()

    buttonBox.accepted.connect(createNewZeroPoint)
    buttonBox.rejected.connect(dialog.reject)

    layout = QFormLayout()
    layout.addRow(QLabel("Name: "), zeroPositionNameLineEdit)
    layout.addRow(QLabel("Offset: "), zeroPositionOffsetLineEdit)
    layout.addRow(buttonBox)

    dialog.setLayout(layout)
    return dialog
Ejemplo n.º 3
0
class NodesList_NodeWidget(QWidget):

    mouse_pressed = Signal()
    del_node_triggered = Signal()

    def __init__(self, node):
        super(NodesList_NodeWidget, self).__init__()

        self.node = node

        # UI
        layout = QHBoxLayout()

        self.name_line_edit = QLineEdit(node.title)
        self.name_line_edit.setEnabled(False)

        layout.addWidget(self.name_line_edit)

        self.setLayout(layout)

    def set_name(self, name):
        self.name_line_edit.setText(name)

    def set_selected(self, selected):
        if selected:
            self.name_line_edit.setStyleSheet(
                'background: rgba(84, 169, 222, 200);')
        else:
            self.name_line_edit.setStyleSheet('')

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed.emit()
        return

    def event(self, event):
        if event.type() == QEvent.ToolTip:
            self.setToolTip(self.node.content_widget.get_node_description())

        return QWidget.event(self, event)

    def contextMenuEvent(self, event):
        menu: QMenu = QMenu(self)

        delete_action = QAction('delete')
        delete_action.triggered.connect(self.action_delete_triggered)

        actions = [delete_action]
        for a in actions:
            menu.addAction(a)

        menu.exec_(event.globalPos())

    def action_delete_triggered(self):
        self.del_node_triggered.emit()
Ejemplo n.º 4
0
class SearchBar(QWidget):
    QueryLaunched = Signal(str)
    StopPressed = Signal()

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

        self._query_edit = QLineEdit()
        self._query_edit.setClearButtonEnabled(True)
        self._query_edit.setPlaceholderText("Type you query here")
        self._query_edit.returnPressed.connect(self._HandleReturnPressed)
        self._query_edit.addAction(QIcon(icons.SEARCH),
                                   QLineEdit.LeadingPosition)

        self._kill_button = QToolButton()
        self._kill_button.setIcon(QIcon(icons.STOP))
        self._kill_button.setAutoRaise(True)
        self._kill_button.setMinimumSize(31, 31)
        self._kill_button.setEnabled(False)
        self._kill_button.clicked.connect(self.StopPressed)

        layout = QHBoxLayout()
        layout.addWidget(self._kill_button)
        layout.addWidget(self._query_edit)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout)

        self.setFocusProxy(self._query_edit)

    def Clear(self):
        self._query_edit.clear()

    def SetStopEnabled(self, bool_):
        self._kill_button.setEnabled(bool_)

    def SetQueryEditEnabled(self, bool_):
        self._query_edit.setEnabled(bool_)

    def SetQuery(self, query):
        self._query_edit.setText(query)

    def LaunchQuery(self, query):
        self._query_edit.setText(query)
        self._HandleReturnPressed()

    def _HandleReturnPressed(self):
        query = " ".join(self._query_edit.text().split())

        if query == "":
            return

        self.QueryLaunched.emit(query)
Ejemplo n.º 5
0
class PlotControls(QWidget):
    erasePlot = Signal(bool)

    def __init__(self):
        super().__init__()

        types_of_axes = ['Cartesiano', 'Logarítmico']
        types_of_traces = ['Scatter', "Boxplot"]

        self.modify_title = QLineEdit()
        self.modify_x_axis_type = Dropdown(types_of_axes)
        self.modify_y_axis_type = Dropdown(types_of_axes)
        self.modify_x_axis_label = QLineEdit()
        self.modify_y_axis_label = QLineEdit()
        self.modify_lower_x_range = QLineEdit()
        self.modify_upper_x_range = QLineEdit()
        self.modify_lower_y_range = QLineEdit()
        self.modify_upper_y_range = QLineEdit()
        self.type_of_trace = Dropdown(types_of_traces)
        self.add_x_trace = QLineEdit()
        self.add_y_trace = QLineEdit()
        self.trace_name = QLineEdit()
        self.run_button = QPushButton('Confirmar alterações')
        self.erase_button = QPushButton('Apagar gráfico')

        self.erase_button.clicked.connect(lambda: self.erasePlot.emit(True))
        self.type_of_trace.currentIndexChanged.connect(self.typeChanged)

        self.buildLayout()
        self.setStyleSheet('color:white; font-family: Bahnschrift SemiLight Condensed; font-size: 14px;')

        self.modify_title.setStyleSheet('background-color: white; color: black')
        self.modify_x_axis_type.setStyleSheet('background-color: white; color: black')
        self.modify_y_axis_type.setStyleSheet('background-color: white; color: black')
        self.modify_x_axis_label.setStyleSheet('background-color: white; color: black')
        self.modify_y_axis_label.setStyleSheet('background-color: white; color: black')
        self.modify_lower_x_range.setStyleSheet('background-color: white; color: black')
        self.modify_upper_x_range.setStyleSheet('background-color: white; color: black')
        self.modify_lower_y_range.setStyleSheet('background-color: white; color: black')
        self.modify_upper_y_range.setStyleSheet('background-color: white; color: black')
        self.type_of_trace.setStyleSheet('background-color: white; color: black')
        self.add_x_trace.setStyleSheet('background-color: white; color: black')
        self.add_y_trace.setStyleSheet('background-color: white; color: black')
        self.trace_name.setStyleSheet('background-color: white; color: black')
        self.run_button.setStyleSheet('background-color: white; color: black')
        self.erase_button.setStyleSheet('background-color: white; color: black')

    def buildLayout(self):
        layout = QFormLayout()
        layout.addRow('Título', self.modify_title)
        layout.addRow('Escala do eixo X', self.modify_x_axis_type)
        layout.addRow('Escala do eixo Y', self.modify_y_axis_type)
        layout.addRow('Rótulo do eixo X', self.modify_x_axis_label)
        layout.addRow('Rótulo do eixo Y', self.modify_y_axis_label)
        layout.addRow('Limite inferior do eixo X', self.modify_lower_x_range)
        layout.addRow('Limite superior do eixo X', self.modify_upper_x_range)
        layout.addRow('Limite inferior do eixo Y', self.modify_lower_y_range)
        layout.addRow('Limite superior do eixo Y', self.modify_upper_y_range)
        layout.addRow('Tipo de série', self.type_of_trace)
        layout.addRow('Adicionar série/box no gráfico (eixo x)', self.add_x_trace)
        layout.addRow('Adicionar série/box no gráfico (eixo y)', self.add_y_trace)
        layout.addRow('Nome da série', self.trace_name)
        layout.addWidget(self.run_button)
        layout.addWidget(self.erase_button)
        self.setLayout(layout)

    def fillFromJson(self, _json):
        # json is the standard json export from the plotly library
        assert (isinstance(_json, str))

        j_obj = j.loads(_json)
        
        try:
            if 'title' in list(j_obj['layout'].keys()):
                self.modify_title.setText(str(j_obj['layout']['title']['text']))
    
            if 'type' in list(j_obj['layout']['xaxis'].keys()):
                if j_obj['layout']['xaxis']['type'].lower() == 'log':
                    self.modify_x_axis_type.setCurrentIndex(1)
                else:
                    self.modify_y_axis_type.setCurrentIndex(0)
                    
            if 'type' in list(j_obj['layout']['yaxis'].keys()):
                if j_obj['layout']['yaxis']['type'].lower() == 'log':
                    self.modify_y_axis_type.setCurrentIndex(1)
                else:
                    self.modify_y_axis_type.setCurrentIndex(0)
    
            if 'title' in list(j_obj['layout']['xaxis'].keys()):
                self.modify_x_axis_label.setText(str(j_obj['layout']['xaxis']['title']['text']))
            if 'title' in list(j_obj['layout']['yaxis'].keys()):
                self.modify_y_axis_label.setText(str(j_obj['layout']['yaxis']['title']['text']))
            if 'range' in list(j_obj['layout']['xaxis'].keys()):
                self.modify_lower_x_range.setText(str(j_obj['layout']['xaxis']['range'][0]))
                self.modify_upper_x_range.setText(str(j_obj['layout']['xaxis']['range'][1]))
            if 'range' in list(j_obj['layout']['yaxis'].keys()):
                self.modify_lower_y_range.setText(str(j_obj['layout']['yaxis']['range'][0]))
                self.modify_upper_y_range.setText(str(j_obj['layout']['yaxis']['range'][1]))
        except KeyError:
            if 'title' in list(j_obj['layout']['template']['layout'].keys()):
                self.modify_title.setText(str(j_obj['layout']['template']['layout']['title']['text']))

            if 'type' in list(j_obj['layout']['template']['layout']['xaxis'].keys()):
                if j_obj['layout']['template']['layout']['xaxis']['type'].lower() == 'log':
                    self.modify_x_axis_type.setCurrentIndex(1)
                else:
                    self.modify_y_axis_type.setCurrentIndex(0)

            if 'type' in list(j_obj['layout']['template']['layout']['yaxis'].keys()):
                if j_obj['layout']['template']['layout']['yaxis']['type'].lower() == 'log':
                    self.modify_y_axis_type.setCurrentIndex(1)
                else:
                    self.modify_y_axis_type.setCurrentIndex(0)

            if 'title' in list(j_obj['layout']['template']['layout']['xaxis'].keys()):
                self.modify_x_axis_label.setText(str(j_obj['layout']['template']['layout']['xaxis']['title']['text']))
            if 'title' in list(j_obj['layout']['template']['layout']['yaxis'].keys()):
                self.modify_y_axis_label.setText(str(j_obj['layout']['template']['layout']['yaxis']['title']['text']))
            if 'range' in list(j_obj['layout']['template']['layout']['xaxis'].keys()):
                self.modify_lower_x_range.setText(str(j_obj['layout']['template']['layout']['xaxis']['range'][0]))
                self.modify_upper_x_range.setText(str(j_obj['layout']['template']['layout']['xaxis']['range'][1]))
            if 'range' in list(j_obj['layout']['template']['layout']['yaxis'].keys()):
                self.modify_lower_y_range.setText(str(j_obj['layout']['template']['layout']['yaxis']['range'][0]))
                self.modify_upper_y_range.setText(str(j_obj['layout']['template']['layout']['yaxis']['range'][1]))

        return

    def typeChanged(self, ind):
        currentType = self.type_of_trace.currentText()
        if currentType == "Boxplot":
            self.add_y_trace.setDisabled(True)
            self.add_y_trace.setStyleSheet('background-color: grey; color: black')
        else:
            self.add_y_trace.setEnabled(True)
            self.add_y_trace.setStyleSheet('background-color: white; color: black')
Ejemplo n.º 6
0
class Snippets(QDialog):

    def __init__(self, parent=None):
        super(Snippets, self).__init__(parent)
        # Create widgets
        self.setWindowModality(Qt.ApplicationModal)
        self.title = QLabel(self.tr("Snippet Editor"))
        self.saveButton = QPushButton(self.tr("Save"))
        self.closeButton = QPushButton(self.tr("Close"))
        self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey"))
        self.setWindowTitle(self.title.text())
        self.newFolderButton = QPushButton("New Folder")
        self.deleteSnippetButton = QPushButton("Delete")
        self.newSnippetButton = QPushButton("New Snippet")
        self.edit = QPlainTextEdit()
        self.edit.setPlaceholderText("python code")
        self.resetting = False
        self.columns = 3

        self.keySequenceEdit = QKeySequenceEdit(self)
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel = QLabel("")
        self.currentFileLabel = QLabel()
        self.currentFile = ""
        self.snippetDescription = QLineEdit()
        self.snippetDescription.setPlaceholderText("optional description")

        #Set Editbox Size
        font = getMonospaceFont(self)
        self.edit.setFont(font)
        font = QFontMetrics(font)
        self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API

        #Files
        self.files = QFileSystemModel()
        self.files.setRootPath(snippetPath)
        self.files.setNameFilters(["*.py"])

        #Tree
        self.tree = QTreeView()
        self.tree.setModel(self.files)
        self.tree.setSortingEnabled(True)
        self.tree.hideColumn(2)
        self.tree.sortByColumn(0, Qt.AscendingOrder)
        self.tree.setRootIndex(self.files.index(snippetPath))
        for x in range(self.columns):
            #self.tree.resizeColumnToContents(x)
            self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) 
        treeLayout = QVBoxLayout()
        treeLayout.addWidget(self.tree)
        treeButtons = QHBoxLayout()
        treeButtons.addWidget(self.newFolderButton)
        treeButtons.addWidget(self.newSnippetButton)
        treeButtons.addWidget(self.deleteSnippetButton)
        treeLayout.addLayout(treeButtons)
        treeWidget = QWidget()
        treeWidget.setLayout(treeLayout)

        # Create layout and add widgets
        buttons = QHBoxLayout()
        buttons.addWidget(self.clearHotkeyButton)
        buttons.addWidget(self.keySequenceEdit)
        buttons.addWidget(self.currentHotkeyLabel)
        buttons.addWidget(self.closeButton)
        buttons.addWidget(self.saveButton)

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

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addLayout(description)
        vlayout.addWidget(self.edit)
        vlayout.addLayout(buttons)
        vlayoutWidget.setLayout(vlayout)

        hsplitter = QSplitter()
        hsplitter.addWidget(treeWidget)
        hsplitter.addWidget(vlayoutWidget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(hsplitter)

        self.showNormal() #Fixes bug that maximized windows are "stuck"
        self.settings = QSettings("Vector35", "Snippet Editor")
        if self.settings.contains("ui/snippeteditor/geometry"):
            self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry"))
        else:
            self.edit.setMinimumWidth(80 * font.averageCharWidth())
            self.edit.setMinimumHeight(30 * font.lineSpacing())

        # Set dialog layout
        self.setLayout(hlayout)

        # Add signals
        self.saveButton.clicked.connect(self.save)
        self.closeButton.clicked.connect(self.close)
        self.clearHotkeyButton.clicked.connect(self.clearHotkey)
        self.tree.selectionModel().selectionChanged.connect(self.selectFile)
        self.newSnippetButton.clicked.connect(self.newFileDialog)
        self.deleteSnippetButton.clicked.connect(self.deleteSnippet)
        self.newFolderButton.clicked.connect(self.newFolder)

        if self.settings.contains("ui/snippeteditor/selected"):
            selectedName = self.settings.value("ui/snippeteditor/selected")
            self.tree.selectionModel().select(self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
            if self.tree.selectionModel().hasSelection():
                self.selectFile(self.tree.selectionModel().selection(), None)
                self.edit.setFocus()
                cursor = self.edit.textCursor()
                cursor.setPosition(self.edit.document().characterCount()-1)
                self.edit.setTextCursor(cursor)
            else:
                self.readOnly(True)
        else:
            self.readOnly(True)


    @staticmethod
    def registerAllSnippets():
        for action in list(filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())):
            if action == "Snippets\\Snippet Editor...":
                continue
            UIActionHandler.globalActions().unbindAction(action)
            Menu.mainMenu("Tools").removeAction(action)
            UIAction.unregisterAction(action)

        for snippet in includeWalk(snippetPath, ".py"):
            snippetKeys = None
            (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet)
            if not snippetDescription:
                actionText = "Snippets\\" + os.path.basename(snippet).rstrip(".py")
            else:
                actionText = "Snippets\\" + snippetDescription
            if snippetCode:
                if snippetKeys == None:
                    UIAction.registerAction(actionText)
                else:
                    UIAction.registerAction(actionText, snippetKeys)
                UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode)))
                Menu.mainMenu("Tools").addAction(actionText, actionText)

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

    def reject(self):
        self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry())

        if self.snippetChanged():
            question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?"))
            if question != QMessageBox.StandardButton.Yes:
                return
        self.accept()

    def newFolder(self):
        (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: "))
        if ok and folderName:
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                QDir(selection).mkdir(folderName)
            else:
                QDir(snippetPath).mkdir(folderName)    

    def selectFile(self, new, old):
        if (self.resetting):
            self.resetting = False
            return
        newSelection = self.files.filePath(new.indexes()[0])
        self.settings.setValue("ui/snippeteditor/selected", newSelection)
        if QFileInfo(newSelection).isDir():
            self.readOnly(True)
            self.tree.clearSelection()
            self.currentFile = ""
            return

        if old and old.length() > 0:
            oldSelection = self.files.filePath(old.indexes()[0])
            if not QFileInfo(oldSelection).isDir() and self.snippetChanged():
                question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?"))
                if question != QMessageBox.StandardButton.Yes:
                    self.resetting = True
                    self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
                    return False

        self.currentFile = newSelection
        self.loadSnippet()

    def loadSnippet(self):
        self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName())
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("")
        self.keySequenceEdit.setKeySequence(snippetKeys) if snippetKeys else self.keySequenceEdit.setKeySequence(QKeySequence(""))
        self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("")
        self.readOnly(False)

    def newFileDialog(self):
        (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: "))
        if ok and snippetName:
            if not snippetName.endswith(".py"):
                snippetName += ".py"
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                path = os.path.join(selection, snippetName)
            else:
                path = os.path.join(snippetPath, snippetName)
                self.readOnly(False)
            open(path, "w").close()
            self.tree.setCurrentIndex(self.files.index(path))
            log_debug("Snippet %s created." % snippetName)

    def readOnly(self, flag):
        self.keySequenceEdit.setEnabled(not flag)
        self.snippetDescription.setReadOnly(flag)
        self.edit.setReadOnly(flag)
        if flag:
            self.snippetDescription.setDisabled(True)
            self.edit.setDisabled(True)
        else:
            self.snippetDescription.setEnabled(True)
            self.edit.setEnabled(True)

    def deleteSnippet(self):
        selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row
        snippetName = self.files.fileName(selection)
        question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName)
        if (question == QMessageBox.StandardButton.Yes):
            log_debug("Deleting snippet %s." % snippetName)
            self.clearSelection()
            self.files.remove(selection)
            self.registerAllSnippets()

    def snippetChanged(self):
        if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()):
            return False
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        if snippetKeys == None and not self.keySequenceEdit.keySequence().isEmpty():
            return True
        if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence().toString():
            return True
        return self.edit.toPlainText() != snippetCode or \
               self.snippetDescription.text() != snippetDescription

    def save(self):
        log_debug("Saving snippet %s" % self.currentFile)
        outputSnippet = open(self.currentFile, "w")
        outputSnippet.write("#" + self.snippetDescription.text() + "\n")
        outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n")
        outputSnippet.write(self.edit.toPlainText())
        outputSnippet.close()
        self.registerAllSnippets()

    def clearHotkey(self):
        self.keySequenceEdit.clear()
Ejemplo n.º 7
0
class Separate(QDialog):
    videoPath = ''
    duration = 60000
    processToken = False
    voiceList = Signal(list)
    avgList = Signal(list)
    clrSep = Signal()
    tablePreset = Signal(list)
    autoFillToken = True
    autoSpanToken = True
    multipleThread = True

    def __init__(self):
        super().__init__()
        self.resize(800, 150)
        self.setWindowTitle('AI智能打轴 (测试版)')
        layout = QGridLayout()
        self.setLayout(layout)
        layout.addWidget(QLabel('前侧留白(ms)'), 0, 0, 1, 1)
        self.beforeEdit = QLineEdit('20')
        validator = QIntValidator()
        validator.setRange(0, 5000)
        self.beforeEdit.setValidator(validator)
        self.beforeEdit.setFixedWidth(50)
        layout.addWidget(self.beforeEdit, 0, 1, 1, 1)
        layout.addWidget(QLabel(''), 0, 2, 1, 1)
        layout.addWidget(QLabel('后侧留白(ms)'), 0, 3, 1, 1)
        self.afterEdit = QLineEdit('300')
        self.afterEdit.setValidator(validator)
        self.afterEdit.setFixedWidth(50)
        layout.addWidget(self.afterEdit, 0, 4, 1, 1)
        layout.addWidget(QLabel(''), 0, 5, 1, 1)
        self.autoFill = QPushButton('填充字符')
        self.autoFill.setStyleSheet('background-color:#3daee9')
        self.autoFill.clicked.connect(self.setAutoFill)
        layout.addWidget(self.autoFill, 0, 6, 1, 1)
        self.fillWord = QLineEdit('#AI自动识别#')
        layout.addWidget(self.fillWord, 0, 7, 1, 1)
        layout.addWidget(QLabel(''), 0, 8, 1, 1)
        self.autoSpan = QPushButton('自动合并')
        self.autoSpan.setStyleSheet('background-color:#3daee9')
        self.autoSpan.clicked.connect(self.setAutoSpan)
        layout.addWidget(self.autoSpan, 0, 9, 1, 1)
        self.multiCheck = QPushButton('启用多进程')
        self.multiCheck.setStyleSheet('background-color:#3daee9')
        self.multiCheck.clicked.connect(self.setMultipleThread)
        layout.addWidget(self.multiCheck, 0, 10, 1, 1)
        self.processBar = QProgressBar()
        layout.addWidget(self.processBar, 1, 0, 1, 10)
        self.checkButton = QPushButton('开始')
        self.checkButton.setFixedWidth(100)
        self.checkButton.clicked.connect(self.separateProcess)
        layout.addWidget(self.checkButton, 1, 10, 1, 1)

    def setDefault(self, videoPath, duration):
        self.videoPath = videoPath
        self.duration = duration

    def separateProcess(self):
        self.processToken = not self.processToken
        if self.videoPath:
            if self.processToken:
                self.processBar.setValue(0)
                self.checkButton.setText('初始化中')
                if not self.beforeEdit.text():
                    self.beforeEdit.setText('0')
                before = self.beforeEdit.text()
                if not self.afterEdit.text():
                    self.afterEdit.setText('0')
                after = self.afterEdit.text()
                if self.autoFillToken:
                    try:
                        fillWord = self.fillWord.text()
                    except:
                        fillWord = ''
                else:
                    fillWord = ''
                self.sepProc = separateQThread(self.videoPath, self.duration,
                                               before, after,
                                               self.multipleThread)
                self.clrSep.emit()  # 清空第一条字幕轴
                self.sepProc.position.connect(self.setTitle)  # 设置标题分析至第几分钟
                self.sepProc.percent.connect(self.setProgressBar)  # 设置滚动条进度
                self.sepProc.voiceList.connect(
                    self.sendVoiceList)  # 二次传球给主界面标记表格
                self.sepProc.avgList.connect(
                    self.sendAvgList)  # 平均音频响度 预留给后面画音频图
                self.tablePreset.emit([fillWord,
                                       self.autoSpanToken])  # 自动填充 填充文本 自动合并
                self.sepProc.finish.connect(self.sepFinished)
                self.sepProc.start()
            else:
                self.setWindowTitle('AI智能打轴 (测试版)')
                self.processBar.setValue(0)
                self.checkButton.setText('开始')
                self.checkButton.setStyleSheet('background-color:#31363b')
                #                 self.sepProc.separate._pool.terminate()
                #                 try:
                #                     p = psutil.Process(self.sepProc.p.pid)
                #                     for proc in p.children(True):
                #                         proc.kill()
                #                 except:
                #                     pass
                self.sepProc.terminate()
                self.sepProc.quit()
                self.sepProc.wait()

    def setTitle(self, pos):
        self.setWindowTitle('AI智能打轴 (已分析至第%s分钟)' % pos)

    def setProgressBar(self, percent):
        self.checkButton.setText('停止')
        self.checkButton.setStyleSheet('background-color:#3daee9')
        self.processBar.setValue(percent)

    def sendVoiceList(self, voiceList):
        self.voiceList.emit(voiceList)

    def sendAvgList(self, avgList):
        self.avgList.emit(avgList)

    def sepFinished(self, result):
        if result:
            self.processToken = not self.processToken
            self.setWindowTitle('AI智能打轴 (测试版)')
            self.processBar.setValue(100)
            self.checkButton.setText('开始')
            self.checkButton.setStyleSheet('background-color:#31363b')
            #             self.sepProc.separate._pool.terminate()
            #             try:
            #                 p = psutil.Process(self.sepProc.p.pid)
            #                 for proc in p.children(True):
            #                     proc.kill()
            #             except:
            #                 pass
            self.sepProc.terminate()
            self.sepProc.quit()
            self.sepProc.wait()

    def setAutoFill(self):
        self.autoFillToken = not self.autoFillToken
        if self.autoFillToken:
            self.autoFill.setStyleSheet('background-color:#3daee9')
            self.fillWord.setEnabled(True)
        else:
            self.autoFill.setStyleSheet('background-color:#31363b')
            self.fillWord.setEnabled(False)

    def setAutoSpan(self):
        self.autoSpanToken = not self.autoSpanToken
        if self.autoSpanToken:
            self.autoSpan.setStyleSheet('background-color:#3daee9')
        else:
            self.autoSpan.setStyleSheet('background-color:#31363b')

    def setMultipleThread(self):
        self.multipleThread = not self.multipleThread
        if self.multipleThread:
            self.multiCheck.setStyleSheet('background-color:#3daee9')
        else:
            self.multiCheck.setStyleSheet('background-color:#31363b')
Ejemplo n.º 8
0
class SettingsEditionDialog(QDialog):

    languages = {"Français": "fr", "English": "en"}

    def __init__(self):
        QDialog.__init__(self)

        self.setWindowTitle(tr("btn_config"))
        self.setFixedSize(QSize(700, 670))

        # Retrieve current settings
        self.settings = AssetManager.getInstance().config_to_dico(
            AssetManager.getInstance().get_config_parser())
        self.__restart_needed = False
        self.__restore_required = False

        # Version
        self.lab_version = QLabel(self.settings['main']['version'])

        # Language
        self.combo_language = QComboBox()
        self.combo_language.addItems(list(self.languages.keys()))
        for lang in self.languages:  # Look for the current language to select it
            if self.languages[lang] == self.settings['main']['language']:
                self.combo_language.setCurrentText(lang)
                break

        # CSV separator
        self.csv_sep_edit = QLineEdit()
        self.csv_sep_edit.setMaxLength(2)
        self.csv_sep_edit.setFixedWidth(25)
        self.csv_sep_edit.setAlignment(Qt.AlignCenter)
        self.csv_sep_edit.setText(self.settings['main']['csv_separator'])

        # BDD path
        self.btn_bdd_path = QPushButton(self.settings['main']['bdd_path'])
        self.btn_bdd_path.clicked.connect(self.choose_bdd_path)

        # Port
        self.wepapp_port = QSpinBox()
        self.wepapp_port.setMinimum(1024)
        self.wepapp_port.setMaximum(65535)
        self.wepapp_port.setValue(int(self.settings['webapp']['port']))

        # Colors
        self.tile_color = ColorChooser(self.settings['colors']['tile'])
        self.hovered_tile_color = ColorChooser(
            self.settings['colors']['hovered_tile'])
        self.hovered_empty_tile_color = ColorChooser(
            self.settings['colors']['hovered_empty_tile'])
        self.dragged_tile_color = ColorChooser(
            self.settings['colors']['dragged_tile'])
        self.drag_selected_tile_color = ColorChooser(
            self.settings['colors']['drag_selected_tile'])
        self.selected_tile_color = ColorChooser(
            self.settings['colors']['selected_tile'])
        self.tile_text_color = ColorChooser(
            self.settings['colors']['tile_text'])
        self.room_bg_color = ColorChooser(self.settings['colors']['room_bg'])
        self.room_grid_color = ColorChooser(
            self.settings['colors']['room_grid'])
        self.main_bg_color = ColorChooser(self.settings['colors']['main_bg'])
        self.board_bg_color = ColorChooser(self.settings['colors']['board_bg'])

        self.attr_colors = ""  # Chosen colors
        self.attributes_colors_chooser = AttrColorsChooser(
            self.settings['colors']['attr_colors'].split())

        # Sizes (unmodifiable)
        self.unmodifiable = QLabel(tr("unmodifiable_data"))
        self.unmodifiable.setAlignment(Qt.AlignCenter)
        self.desk_size = QLineEdit(self.settings['size']['desk'])
        self.desk_size.setEnabled(False)
        self.desk_size.setFixedWidth(50)
        self.grid_rows = QLineEdit(self.settings['size']['default_room_rows'])
        self.grid_rows.setEnabled(False)
        self.grid_rows.setFixedWidth(50)
        self.grid_cols = QLineEdit(
            self.settings['size']['default_room_columns'])
        self.grid_cols.setEnabled(False)
        self.grid_cols.setFixedWidth(50)

        # --- Buttons ---

        # Confirm button
        self.ok_btn = QPushButton(tr("btn_save"))
        self.ok_btn.clicked.connect(self.accept)
        self.ok_btn.setFocus()

        # Cancel button
        self.cancel_btn = QPushButton(tr("btn_cancel"))
        self.cancel_btn.clicked.connect(self.reject)

        # Restore defaults button
        self.restore_btn = QPushButton(tr("btn_restore"))
        self.restore_btn.clicked.connect(self.__restore)

        self.__set_layout()

    def __set_layout(self) -> None:
        """
        Sets the dialog layout
        """
        # Main layout
        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.addSpacing(5)

        # Main section
        main_layout = QFormLayout()
        main_layout.addRow(tr("app_version"), self.lab_version)
        main_layout.addRow(tr("language"), self.combo_language)
        main_layout.addRow(tr("csv_sep"), self.csv_sep_edit)
        main_layout.addRow(tr("bdd_path"), self.btn_bdd_path)

        # Web app
        widget_port = QWidget()
        layout_port = QHBoxLayout()
        layout_port.setMargin(0)
        layout_port.addWidget(self.wepapp_port)
        layout_port.addWidget(ShutDownToolTip())
        widget_port.setLayout(layout_port)
        main_layout.addRow(tr("web_port"), widget_port)

        layout.addLayout(main_layout)
        Separator(self.width(), layout)

        # Colors
        colors_layout1 = QFormLayout()
        colors_layout1.addRow(tr("tile"), self.tile_color)
        colors_layout1.addRow(tr("hovered_tile"), self.hovered_tile_color)
        colors_layout1.addRow(tr("hovered_empty_tile"),
                              self.hovered_empty_tile_color)
        colors_layout1.addRow(tr("dragged_tile"), self.dragged_tile_color)
        colors_layout1.addRow(tr("drag_selected_tile"),
                              self.drag_selected_tile_color)
        colors_layout1.addRow(tr("selected_tile"), self.selected_tile_color)

        colors_layout2 = QFormLayout()
        colors_layout2.addRow(tr("tile_text"), self.tile_text_color)
        colors_layout2.addRow(tr("room_bg"), self.room_bg_color)
        colors_layout2.addRow(tr("room_grid"), self.room_grid_color)
        colors_layout2.addRow(tr("main_bg"), self.main_bg_color)
        colors_layout2.addRow(tr("board_bg"), self.board_bg_color)

        colors_layout = QHBoxLayout()
        colors_layout.setMargin(0)
        colors_layout.addLayout(colors_layout1)
        colors_layout.addLayout(colors_layout2)

        layout.addLayout(colors_layout)
        layout.addSpacing(15)

        colors_layout3 = QFormLayout()
        colors_layout3.setMargin(0)
        colors_layout3.addRow(tr("attr_colors"),
                              self.attributes_colors_chooser)
        layout.addLayout(colors_layout3)

        Separator(self.width(), layout)

        # Unmodifiable data
        sizes_layout = QFormLayout()
        sizes_layout.setMargin(0)
        sizes_layout.addRow(tr("desk_size"), self.desk_size)
        sizes_layout.addRow(tr("grid_rows"), self.grid_rows)
        sizes_layout.addRow(tr("grid_cols"), self.grid_cols)

        layout.addWidget(self.unmodifiable, alignment=Qt.AlignCenter)
        layout.addSpacing(5)
        layout.addLayout(sizes_layout)

        Separator(self.width(), layout)

        # Buttons
        layout_buttons = QHBoxLayout()
        layout_buttons.addWidget(self.ok_btn)
        layout_buttons.addWidget(self.restore_btn)
        layout_buttons.addWidget(self.cancel_btn)

        layout.addLayout(layout_buttons)
        self.setLayout(layout)

        self.setStyleSheet(get_stylesheet("dialog2"))

    def __restore(self) -> None:
        """
        Restore default parameters before closing dialog
        """
        self.__restart_needed = True
        self.__restore_required = True
        self.accept()

    def __new_settings(self) -> dict:
        """
        Retrieves the new settings to use
        """
        settings = self.settings

        # Language
        language = self.languages[self.combo_language.currentText()]
        if language != settings['main']['language']:
            settings['main']['language'] = language
            self.__restart_needed = True

        # CSV separator
        settings['main']['csv_separator'] = self.csv_sep_edit.text()

        # BDD path
        if self.btn_bdd_path.text() != settings['main']['bdd_path']:
            if self.btn_bdd_path.text().endswith("sdc_db"):
                settings['main']['bdd_path'] = self.btn_bdd_path.text()
            else:
                settings['main']['bdd_path'] = ""
            self.__restart_needed = True

        # Port
        if str(self.wepapp_port.value()) != settings['webapp']['port']:
            settings['webapp']['port'] = str(self.wepapp_port.value())

        # Colors
        settings['colors']['tile'] = self.tile_color.get_color()
        settings['colors']['hovered_tile'] = self.hovered_tile_color.get_color(
        )
        settings['colors'][
            'hovered_empty_tile'] = self.hovered_empty_tile_color.get_color()
        settings['colors']['dragged_tile'] = self.dragged_tile_color.get_color(
        )
        settings['colors'][
            'drag_selected_tile'] = self.drag_selected_tile_color.get_color()
        settings['colors'][
            'selected_tile'] = self.selected_tile_color.get_color()
        settings['colors']['tile_text'] = self.tile_text_color.get_color()
        settings['colors']['room_grid'] = self.room_grid_color.get_color()

        if self.room_bg_color.get_color() != settings['colors']['room_bg']:
            settings['colors']['room_bg'] = self.room_bg_color.get_color()
            self.__restart_needed = True

        if self.main_bg_color.get_color() != settings['colors']['main_bg']:
            settings['colors']['main_bg'] = self.main_bg_color.get_color()
            self.__restart_needed = True

        if self.board_bg_color.get_color() != settings['colors']['board_bg']:
            settings['colors']['board_bg'] = self.board_bg_color.get_color()
            self.__restart_needed = True

        settings['colors']['attr_colors'] = self.attr_colors

        return settings

    def new_config(self) -> ConfigParser:
        """
        Retrieves the new config parser object
        """
        conf = ConfigParser()
        conf.read_dict(self.__new_settings())

        return conf

    def need_restart(self):
        return self.__restart_needed

    def restore_default(self) -> bool:
        return self.__restore_required

    def accept(self) -> None:
        """
        Performs actions before calling parent's accept method
        """
        self.attr_colors = self.attributes_colors_chooser.get_colors_to_str()
        super().accept()

    def choose_bdd_path(self) -> None:
        """
        Opens a file chooser to select the bdd path. Then sets the name as button text.
        """
        bdd_path = QFileDialog.getOpenFileName(self, tr("bdd_path"),
                                               self.btn_bdd_path.text())[0]

        if bdd_path:
            self.btn_bdd_path.setText(bdd_path)
Ejemplo n.º 9
0
class SearchBar(QWidget):
    def __init__(self):
        super(SearchBar, self).__init__()
        self.layout = QVBoxLayout()
        self.layout.setMargin(0)
        self.setStyleSheet(
            css('border: 1px solid {{color}};', color=colors.SECONDARY_COLOR))

        self.searchbar = QLineEdit()
        self.searchbar.setPlaceholderText(
            'Try searching for an artist or album')
        self.searchbar.textChanged.connect(self.set_keywords)
        self.searchbar.returnPressed.connect(self.search)
        self.searchbar.setStyleSheet(
            css('''
            QLineEdit {
                padding: 10px;
                border-radius: 8px;
                background: {{backgroundColor}};
            }
            ''',
                backgroundColor=colors.PLACEHOLDER_COLOR))

        self.layout.addWidget(self.searchbar)
        self.setLayout(self.layout)

    def set_keywords(self, keywords):
        self.keywords = keywords

    def search(self):
        if self.searchbar.completer() and self.searchbar.completer().popup(
        ).isVisible():
            # User did select an option from the dropdown menu.
            selected_suggestion = [
                s for s in self.suggestions if s['label'] == self.keywords
            ]
            if len(selected_suggestion) > 0:
                self.searchbar.setCompleter(None)
                PageSignal.changed.emit(
                    SongDetailPage(url=selected_suggestion[0]['url']))
        else:
            # User did type something and then hit ENTER to search.
            self.thread = RunThread(self.get_search_suggestions,
                                    self.on_search_suggestions)

    def get_search_suggestions(self):
        if self.keywords:
            self.searchbar.setEnabled(False)
            logging.info(
                'Getting search suggestions for keywords: "{}"'.format(
                    self.keywords))
            spider = CoreRadioSpider()
            self.suggestions = spider.get_search_suggestions(self.keywords)

    def on_search_suggestions(self):
        logging.info('Received search suggestions for keywords: "{}"'.format(
            self.keywords))
        self.searchbar.setEnabled(True)
        self.searchbar.setFocus()
        if self.suggestions:
            suggestions = [
                suggestion['label'] for suggestion in self.suggestions
            ]
            completer = QCompleter(suggestions)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            self.searchbar.setCompleter(completer)
            self.searchbar.completer().complete()
            self.searchbar.completer().popup().setStyleSheet(
                css(
                    """
                QListView {
                    border: 1px solid {{borderColor}};
                    padding: 10px;
                    background: {{backgroundColor}};
                }
                QItemSelection {
                    padding: 10px;
                }
                """,
                    borderColor=colors.SECONDARY_COLOR,
                    backgroundColor=colors.PLACEHOLDER_COLOR,
                ))
Ejemplo n.º 10
0
class VODCutter(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.twitch_client_id = config.TWITCH_API_CLIENT_ID
        self.twitch_oauth_token = config.TWITCH_API_OAUTH_TOKEN

        self.twitch_interface = TwitchInterface(
            api_client_id=config.TWITCH_API_CLIENT_ID,
            api_oauth_token=config.TWITCH_API_OAUTH_TOKEN,
            browser_client_id=config.TWITCH_BROWSER_OAUTH_TOKEN,
            browser_oauth_token=config.TWITCH_BROWSER_OAUTH_TOKEN)

        self.vlc_interface = VLCInterface(config.VLC_PATH)

        self.loaded_video = None

        self.main_layout = QVBoxLayout()

        self.launch_vlc_btn = QPushButton("Launch VLC")

        self.info_layout = QGridLayout()

        self.file_picker_layout = QHBoxLayout()

        self.file_path_field = QLineEdit()
        self.file_browser_btn = QPushButton(text="...")

        self.file_picker_layout.addWidget(self.file_path_field)
        self.file_picker_layout.addWidget(self.file_browser_btn)

        vod_filepath_label = QLabel("VOD Filepath")
        id_twitch_label = QLabel("ID Twitch")
        created_at_label = QLabel("Created at")
        duration_label = QLabel("Duration")
        title_label = QLabel("Title")
        streamer_label = QLabel("Streamer")

        self.id_twitch_field = QLineEdit()
        self.created_at_field = QLineEdit()
        self.duration_field = QLineEdit()
        self.title_field = QLineEdit()
        self.streamer_field = QLineEdit()

        self.id_twitch_field.setEnabled(False)
        self.created_at_field.setEnabled(False)
        self.duration_field.setEnabled(False)
        self.title_field.setEnabled(False)
        self.streamer_field.setEnabled(False)

        self.info_layout.addWidget(vod_filepath_label, 0, 0)
        self.info_layout.addWidget(id_twitch_label, 1, 0)
        self.info_layout.addWidget(created_at_label, 2, 0)
        self.info_layout.addWidget(duration_label, 3, 0)
        self.info_layout.addWidget(title_label, 4, 0)
        self.info_layout.addWidget(streamer_label, 5, 0)

        self.info_layout.addLayout(self.file_picker_layout, 0, 1)
        self.info_layout.addWidget(self.id_twitch_field, 1, 1)
        self.info_layout.addWidget(self.created_at_field, 2, 1)
        self.info_layout.addWidget(self.duration_field, 3, 1)
        self.info_layout.addWidget(self.title_field, 4, 1)
        self.info_layout.addWidget(self.streamer_field, 5, 1)

        self.segments_create_btn = QPushButton("Import Chapters")
        self.download_thumbnails_btn = QPushButton("Download Thumbnails")
        self.download_chatlog_btn = QPushButton("Download Chat Log")

        self.segments_list = QListWidget()

        self.segments_add_btn = QPushButton(text="+")
        self.segments_delete_btn = QPushButton(text="-")

        self.jump_start_btn = QPushButton(text="Jump To Start")
        self.jump_end_btn = QPushButton(text="Jump To End")

        self.set_start_btn = QPushButton(text="Set Start")
        self.set_end_btn = QPushButton(text="Set End")

        self.split_btn = QPushButton(text="Split")

        self.process_selected_btn = QPushButton(
            text="Process Selected Segment")
        self.process_all_btn = QPushButton(text="Process All Segments")

        self.jump_layout = QHBoxLayout()

        self.jump_layout.addWidget(self.jump_start_btn)
        self.jump_layout.addWidget(self.jump_end_btn)

        self.set_layout = QHBoxLayout()

        self.set_layout.addWidget(self.set_start_btn)
        self.set_layout.addWidget(self.set_end_btn)

        self.main_layout.addWidget(self.launch_vlc_btn)
        self.main_layout.addLayout(self.file_picker_layout)
        self.main_layout.addLayout(self.info_layout)
        self.main_layout.addWidget(self.segments_create_btn)
        self.main_layout.addWidget(self.download_thumbnails_btn)
        self.main_layout.addWidget(self.download_chatlog_btn)
        self.main_layout.addWidget(self.segments_list)
        self.main_layout.addWidget(self.segments_add_btn)
        self.main_layout.addWidget(self.segments_delete_btn)
        self.main_layout.addLayout(self.jump_layout)
        self.main_layout.addLayout(self.set_layout)
        self.main_layout.addWidget(self.split_btn)
        self.main_layout.addWidget(self.process_selected_btn)
        self.main_layout.addWidget(self.process_all_btn)

        self.main_widget = QWidget()
        self.main_widget.setLayout(self.main_layout)

        self.setCentralWidget(self.main_widget)

        self.segments_list.itemDoubleClicked.connect(
            self.on_segments_list_doubleclick)

        self.jump_start_btn.clicked.connect(self.jump_to_segment_start)
        self.jump_end_btn.clicked.connect(self.jump_to_segment_end)
        self.set_start_btn.clicked.connect(self.set_segment_start)
        self.set_end_btn.clicked.connect(self.set_segment_end)

        self.download_thumbnails_btn.clicked.connect(self.download_thumbnails)
        self.segments_add_btn.clicked.connect(self.create_segment)
        self.segments_delete_btn.clicked.connect(self.delete_segment)
        self.split_btn.clicked.connect(self.split_selected_segment)
        self.launch_vlc_btn.clicked.connect(self.on_launch_vlc)
        self.file_path_field.returnPressed.connect(self.on_video_url_changed)
        self.file_browser_btn.clicked.connect(self.on_filebrowse_btn_click)
        self.process_selected_btn.clicked.connect(
            self.process_selected_segment)
        self.process_all_btn.clicked.connect(self.process_all_segments)

    def on_launch_vlc(self):
        self.vlc_interface.launch()

    def on_filebrowse_btn_click(self):
        filename = QFileDialog.getOpenFileName(self, "Select a video file")
        if filename[0]:
            self.set_video_file(filename[0])

    def on_video_url_changed(self):
        self.set_video_file(self.file_path_field.text())

    def on_segments_list_doubleclick(self, item):
        current_segment = item.get_segment()
        if current_segment:
            self.vlc_interface.set_current_time(int(
                current_segment.start_time))

    def set_video_file(self, filepath=None):
        self.file_path_field.setText("" if filepath is None else filepath)

        if filepath:
            self.loaded_video = InputVideo()

            if re.search(r"^(?:/|[a-z]:[\\/])", filepath, re.I):
                file_url = "file://" + filepath
                self.loaded_video.is_local = True
            else:
                file_url = filepath

            if not self.loaded_video.is_local:
                streams = streamlink.streams(file_url)
                if streams:
                    self.loaded_video.filepath = streams["best"].url
                else:
                    self.loaded_video.filepath = file_url
            else:
                self.loaded_video.filepath = file_url

            try:
                self.update_twitch_metadatas()
            except requests.exceptions.ConnectionError:
                print("<!!> Can't connect to Twitch API.")

            try:
                self.vlc_interface.open_url(self.loaded_video.filepath)
            except requests.exceptions.ConnectionError:
                print("<!!> Can't connect to local VLC instance.")

    def get_twitch_id_from_filepath(self):
        filename = self.file_path_field.text()

        parsed_filename = re.search("([0-9]+)\.mp4$", filename, re.I)

        if parsed_filename:
            video_id = parsed_filename.group(1)
            return int(video_id)
        else:
            parsed_url = re.search("videos/([0-9]+)", filename, re.I)
            if parsed_url:
                video_id = parsed_url.group(1)
                return int(video_id)
            else:
                raise Exception(
                    f"<!!> Can't find video Twitch id in video filename ({filename})"
                )

    def create_segment_before(self, segment_obj):
        pass

    def create_segment_after(self, segment_obj):
        pass

    def update_twitch_metadatas(self):
        twitch_video_id = self.get_twitch_id_from_filepath()
        metadatas = self.twitch_interface.get_twitch_metadatas(twitch_video_id)

        self.loaded_video.metadatas = metadatas

        duration = parse_duration(metadatas["duration"])

        self.id_twitch_field.setText(metadatas["id"])
        self.created_at_field.setText(str(metadatas["created_at"]))
        self.duration_field.setText(format_time(duration.seconds))
        self.title_field.setText(metadatas["title"])
        self.streamer_field.setText(metadatas["user_login"])

        for moment in self.twitch_interface.get_video_games_list(
                metadatas["id"]):
            s = Segment()

            s.name = f"{moment['description']} ({moment['type']})"
            s.start_time = moment['positionMilliseconds'] / 1000
            s.end_time = (moment['positionMilliseconds'] +
                          moment['durationMilliseconds']) / 1000

            self.segments_list.addItem(SegmentListItem(s))

    def create_segment(self):
        s = Segment()

        s.name = f"Segment {self.segments_list.count()}"
        s.start_time = 0
        s.end_time = self.vlc_interface.get_duration()

        self.segments_list.addItem(SegmentListItem(s))

    def delete_segment(self):
        for item in self.segments_list.selectedItems():
            idx = self.segments_list.indexFromItem(item)
            item = self.segments_list.takeItem(idx.row())
            del item

    def split_selected_segment(self):
        current_time = self.vlc_interface.get_current_time()

        for segment_item in self.segments_list.selectedItems():
            current_segment = segment_item.get_segment()
            if current_segment:
                new_segment = segment_item.split(
                    current_time,
                    name="Splitted " + current_segment.name,
                    split_mode=SPLIT_MODE.ABSOLUTE)
                self.segments_list.addItem(SegmentListItem(new_segment))

    def get_selected_segments(self):
        return list(
            map(lambda item: item.get_segment(),
                self.segments_list.selectedItems()))

    def jump_to_segment_start(self):
        selected_segments = self.get_selected_segments()
        if selected_segments:
            self.vlc_interface.set_current_time(
                math.floor(selected_segments[0].start_time))

    def jump_to_segment_end(self):
        selected_segments = self.get_selected_segments()
        if selected_segments:
            self.vlc_interface.set_current_time(
                math.floor(selected_segments[0].end_time))

    def set_segment_start(self):
        current_time = self.vlc_interface.get_current_time()
        selected_segments = self.segments_list.selectedItems()
        if selected_segments:
            selected_segments[0].get_segment().start_time = current_time
            selected_segments[0].update()

    def set_segment_end(self):
        current_time = self.vlc_interface.get_current_time()
        selected_segments = self.segments_list.selectedItems()
        if selected_segments:
            selected_segments[0].get_segment().end_time = current_time
            selected_segments[0].update()

    def process_selected_segment(self):
        for segment in self.get_selected_segments():
            self.process_segment(segment)

    def process_all_segments(self):
        for idx in range(self.segments_list.count()):
            segment_item = self.segments_list.item(idx)
            self.process_segment(segment_item.get_segment())

    def process_segment(self, segment_obj):
        if not self.loaded_video:
            raise Exception("<!!> No video loaded")

        video_id = self.loaded_video.metadatas.get("id", None)
        created_at = self.loaded_video.metadatas.get("created_at", None)
        user_login = self.loaded_video.metadatas.get("user_login", None)

        if not (video_id and created_at and user_login):
            raise Exception("<!!> Missing video metadatas")

        created_at_timestamp = int(datetime.datetime.timestamp(created_at))

        if self.loaded_video.is_local:
            cmd = f'ffmpeg -i "{self.loaded_video.filepath}" -ss {segment_obj.start_time} -to {segment_obj.end_time} -c:v copy -c:a copy "{user_login}_{created_at_timestamp}_{video_id}.mp4"'
        else:
            cmd = f'streamlink -f --hls-start-offset {format_time(segment_obj.start_time)} --hls-duration {format_time(segment_obj.end_time - segment_obj.start_time)} --player-passthrough hls "{self.loaded_video.filepath}" best -o "{user_login}_{created_at_timestamp}_{video_id}.mp4"'

        print(cmd)

        os.system(cmd)

    def download_thumbnails(self):
        twitch_video_id_str = self.id_twitch_field.text()
        if twitch_video_id_str:
            thumbnails_manifest_url = self.twitch_interface.get_video_thumbnails_manifest_url(
                int(twitch_video_id_str))
            thumbnails_manifest, images_url_list = self.twitch_interface.get_thumbnails_url_from_manifest(
                thumbnails_manifest_url)

            for img in images_url_list:
                r = requests.get(images_url_list[img])
                fp = open(img, "wb")
                fp.write(r.content)
                fp.close()
Ejemplo n.º 11
0
class PreparationWidget(QtWidgets.QWidget):
  def __init__(self):
    QtWidgets.QWidget.__init__(self)
    self.min_questions = 0
    self.min_answers = 0
    layout = QVBoxLayout()
    self.setLayout(layout)

    layout.addWidget(QLabel("Questions"))
    self.questions = QtWidgets.QListWidget()
    layout.addWidget(self.questions)
    self.question_textbox = QLineEdit()
    layout.addWidget(self.question_textbox)

    buttons_layout = QtWidgets.QHBoxLayout()
    icon = QtGui.QIcon.fromTheme('list-add')
    button = QPushButton(icon, "Add")
    button.clicked.connect(self.add_question)
    buttons_layout.addWidget(button)
    icon = QtGui.QIcon.fromTheme('list-remove')
    button = QPushButton(icon, 'Remove')
    button.clicked.connect(self.remove_question)
    buttons_layout.addWidget(button)
    layout.addLayout(buttons_layout)

    layout.addWidget(QLabel("Answers"))
    self.answers = QtWidgets.QListWidget()
    layout.addWidget(self.answers)
    self.answer_textbox = QLineEdit()
    layout.addWidget(self.answer_textbox)

    buttons_layout = QtWidgets.QHBoxLayout()
    icon = QtGui.QIcon.fromTheme('list-add')
    button = QPushButton(icon, "Add")
    button.clicked.connect(self.add_answer)
    buttons_layout.addWidget(button)
    icon = QtGui.QIcon.fromTheme('list-remove')
    button = QPushButton(icon, 'Remove')
    button.clicked.connect(self.remove_answer)
    buttons_layout.addWidget(button)
    icon = QtGui.QIcon.fromTheme('go-next')
    self.send_button = QPushButton(icon, "Send")
    self.send_button.clicked.connect(self.send_questions)
    buttons_layout.addWidget(self.send_button)
    layout.addLayout(buttons_layout)

  def set_num_players(self, num_players):
    self.min_questions = 3
    self.min_answers = 3  * (num_players - 1)

  @QtCore.Slot()
  def add_question(self):
    text: str = self.question_textbox.text()
    if text:
      if not text.endswith('?'):
        text += '?'
      self.questions.addItem(text)
      self.question_textbox.clear()

  @QtCore.Slot()
  def remove_question(self):
    self.questions.takeItem(self.questions.currentRow())

  @QtCore.Slot()
  def add_answer(self):
    text: str = self.answer_textbox.text()
    if text:
      self.answers.addItem(text)
      self.answer_textbox.clear()

  @QtCore.Slot()
  def remove_answer(self):
    self.answers.takeItem(self.questions.currentRow())

  @QtCore.Slot()
  def send_questions(self):
    def callback(data):
      if data['status'] != 'ok':
        print(data)
      else:
        self.answer_textbox.setEnabled(False)
        self.question_textbox.setEnabled(False)
        self.send_button.setEnabled(False)

    questions = [self.questions.item(i).text()
                 for i in range(self.questions.count())]
    answers = [self.answers.item(i). text()
               for i in range(self.answers.count())]
    if (len(questions) >= self.min_questions and
        len(answers) >= self.min_answers):
      sio.emit(
        "add-questions",
        (room_code, questions, answers),
        callback=callback
      )
Ejemplo n.º 12
0
class BlockView(QWidget):
    """Config widget for a single experiment block.  
    In a model-view paradigm, this is a view, and block is a model. A new block can be set using setModel.
    """
    statistics_type_to_name = {
        "max": "Min/Max",
        "meanstd": "Standardise"
    }
    statistics_name_to_type = {v: k for k, v in statistics_type_to_name.items()}

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

        self._model = None

        # Block properties ---------------------------------------------------------------------------------------------
        self.duration = QWidget()
        self.duration.setContentsMargins(0, 0, 0, 0)
        ly = QHBoxLayout()
        ly.setContentsMargins(0, 0, 0, 0)
        self.duration.setLayout(ly)

        self.duration_base = QDoubleSpinBox()
        self.duration_base.setRange(0, 1000)
        self.duration_base.setValue(10)

        self.duration_deviation = QDoubleSpinBox()
        self.duration_deviation.setRange(0, 10)
        self.duration_deviation.setValue(0)
        self.duration_deviation.setSingleStep(0.1)
        self.duration_deviation.setSuffix(" s")
        self.duration_base.valueChanged.connect(self.duration_deviation.setMaximum)

        ly.addWidget(self.duration_base)
        ly.addWidget(QLabel("±"))
        ly.addWidget(self.duration_deviation)

        self.feedback_source = QLineEdit("All")

        self.feedback_type = QComboBox()
        self.feedback_type.addItem("Baseline")
        self.feedback_type.addItem("Feedback")

        self.mock_signal_path = QLineEdit()
        self.mock_signal_dataset = QLineEdit()
        self.mock_previous = QSpinBox()
        self.mock_previous_reverse = QCheckBox()
        self.mock_previous_random = QCheckBox()
        self.pause = QCheckBox()
        self.beep = QCheckBox()
        self.start_data_driven_filter_designer = QCheckBox()
        self.update_statistics = QCheckBox()
        self.update_statistics.stateChanged.connect(lambda state: self.statistics_type.setEnabled(bool(state)))
        self.statistics_type = QComboBox()
        self.statistics_type.setEnabled(False)
        for name in self.statistics_name_to_type:
            self.statistics_type.addItem(name)
        self.statistics_type.setCurrentText("Standardise")

        self.random_bound = QComboBox()
        self.random_bound.addItem("SimCircle")
        self.random_bound.addItem("RandomCircle")
        self.random_bound.addItem("Bar")

        self.video_path = QLineEdit()
        
        self.message = QLineEdit()
        self.feedback_type.currentTextChanged.connect(lambda ftype: self.message.setEnabled(ftype == "Baseline"))

        self.voiceover = QCheckBox()

        # Grouped properties -------------------------------------------------------------------------------------------
        # Mock signal
        mock_signal_groupbox = QGroupBox("Mock signal")
        mock_signal_gblayout = QFormLayout()
        mock_signal_groupbox.setLayout(mock_signal_gblayout)
        mock_signal_gblayout.addRow("Mock signal file path", self.mock_signal_path)
        mock_signal_gblayout.addRow("Mock signal file dataset", self.mock_signal_dataset)
        mock_signal_gblayout.addRow("Mock previous", self.mock_previous)
        mock_signal_gblayout.addRow("Reverse mock previous", self.mock_previous_reverse)
        mock_signal_gblayout.addRow("Random mock previous", self.mock_previous_random)

        # After block actions
        after_block_groupbox = QGroupBox("After block actions")
        after_block_gblayout = QFormLayout()
        after_block_groupbox.setLayout(after_block_gblayout)
        after_block_gblayout.addRow("Start data driven filter designer", self.start_data_driven_filter_designer)
        after_block_gblayout.addRow("Pause", self.pause)
        after_block_gblayout.addRow("Beep", self.beep)
        after_block_gblayout.addRow("Update statistics", self.update_statistics)
        after_block_gblayout.addRow("Statistics type", self.statistics_type)

        # Adding properties to the widget ------------------------------------------------------------------------------
        layout.addRow("Duration", self.duration)
        layout.addRow("Source", self.feedback_source)
        layout.addRow("FB Type", self.feedback_type)
        layout.addRow("Random bound", self.random_bound)
        layout.addRow("Video path", self.video_path)
        layout.addRow("Message for test subject", self.message)
        layout.addRow("Voiceover for message", self.voiceover)
        layout.addRow(mock_signal_groupbox)
        layout.addRow(after_block_groupbox)

    def model(self):
        return self._model

    def setModel(self, block, /):
        """Set the model block for this view.
        Data in the view will be updated to reflect the new block.
        """
        self._model = block
        self.updateView()
    
    def updateModel(self):
        """Copy data from this view to the block model.
        A similarly named function in the block copies data the opposite way. Use one or the other depending on where
        data was changed.
        """
        model = self.model()
        if model is None:
            return
        
        model.duration = self.duration_base.value()
        model.duration_deviation = self.duration_deviation.value()
        model.feedback_source = self.feedback_source.text()
        model.feedback_type = self.feedback_type.currentText()
        model.random_bound = self.random_bound.currentText()
        model.video_path = self.video_path.text()
        model.message = self.message.text()
        model.voiceover = self.voiceover.isChecked()
        model.mock_signal_path = self.mock_signal_path.text()
        model.mock_signal_dataset = self.mock_signal_dataset.text()
        model.mock_previous = self.mock_previous.value()
        model.mock_previous_reverse = self.mock_previous_reverse.isChecked()
        model.mock_previous_random = self.mock_previous_random.isChecked()
        model.start_data_driven_filter_designer = self.start_data_driven_filter_designer.isChecked()
        model.pause = self.pause.isChecked()
        model.beep = self.beep.isChecked()
        model.update_statistics = self.update_statistics.isChecked()
        model.statistics_type = self.statistics_name_to_type[self.statistics_type.currentText()]

    def updateView(self):
        model = self.model()
        if model is None:
            return
        
        self.duration_base.setValue(model.duration)
        self.duration_deviation.setValue(model.duration_deviation)
        self.feedback_source.setText(model.feedback_source)
        self.feedback_type.setCurrentText(model.feedback_type)
        self.mock_signal_path.setText(model.mock_signal_path)
        self.mock_signal_dataset.setText(model.mock_signal_dataset)
        self.mock_previous.setValue(model.mock_previous)
        self.mock_previous_reverse.setChecked(model.mock_previous_reverse)
        self.mock_previous_random.setChecked(model.mock_previous_random)
        self.pause.setChecked(model.pause)
        self.beep.setChecked(model.beep)
        self.start_data_driven_filter_designer.setChecked(model.start_data_driven_filter_designer)
        self.update_statistics.setChecked(model.update_statistics)
        self.statistics_type.setCurrentText(self.statistics_type_to_name[model.statistics_type])
        self.random_bound.setCurrentText(model.random_bound)
        self.video_path.setText(model.video_path)
        self.message.setText(model.message)
        self.voiceover.setChecked(model.voiceover)
Ejemplo n.º 13
0
class MainWindow(QMainWindow):
    def __init__(self, vehicle_ctl: VehicleCtl,
                 image_stream_server: ImageStreamServer):
        QMainWindow.__init__(self)

        self._vehicle_ctl = vehicle_ctl
        self._image_stream_server = image_stream_server

        # Our popup window for setting trim
        self._trim_window = None

        self.setMinimumSize(QSize(1000, 500))
        self.setWindowTitle("Rotor Client")

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Need to allow the central widget to get focus so the key presses are caught correctly
        central_widget.setFocusPolicy(QtCore.Qt.ClickFocus)

        # Create all the buttons and widgets
        self.create_gui()

        # Create the image viewer
        self._image_viewer = ImageViewer(self._image_stream_server)

        # Connect all the push button signals
        self.add_gui_listeners()

        # Set the widgets in the grid layout
        self.add_widgets_to_screen(central_widget)

        # Give the central widget focus so the key presses work
        central_widget.setFocus()

    def game_controller_calibration_dialog(self):
        self._game_controller_config_window = GameControllerCalibrationDialog()
        self._game_controller_config_window.show()
        self._game_controller_config_window.calibration_complete_response = lambda calibration_data: self.game_controller_calibrated_from_window(
            calibration_data)

    def game_controller_calibrated_from_window(self, calibration_data):
        self._game_controller_config_window.close()

        config_handler = ConfigHandler.get_instance()
        config_handler.set_config_value('game_controller_calibration',
                                        calibration_data.to_json())

        self.game_controller_calibrated(calibration_data)

    def game_controller_calibrated(self, calibration_data):
        logging.info("CONTROLLER WAS CALIBRATED!  " +
                     str(calibration_data.to_json()))
        self._game_controller = GameController(inputs.devices.gamepads[0],
                                               calibration_data)
        self._game_controller.add_event_response(
            'ABS_HAT0X', self.game_controller_direction_pad_response)
        self._game_controller.add_event_response(
            'ABS_RZ', self.game_controller_right_trigger_response)
        self._game_controller.add_event_response(
            'ABS_Z', self.game_controller_left_trigger_response)
        self._game_controller.add_event_response(
            'ABS_X', self.game_controller_left_stick_x)
        self._game_controller.add_event_response(
            'BTN_EAST', self.game_controller_b_button_response)
        self._game_controller.add_event_response(
            'BTN_TR', self.game_controller_right_bumper_response)
        self._game_controller.start()

    def game_controller_left_stick_x(self, state):
        self._vehicle_ctl.set_steering(
            state / self._game_controller.get_calibration().joystick_boundary)

    def game_controller_direction_pad_response(self, state):
        if state == -1:
            self.left_pressed()
        elif state == 1:
            self.right_pressed()
        else:
            self._vehicle_ctl.set_steering(0.0)

    def game_controller_b_button_response(self, state):
        if state == 1:
            self.backward_pressed()
        else:
            self.backward_released()

    def game_controller_right_bumper_response(self, state):
        if state == 0:
            self.change_gear()

    def game_controller_right_trigger_response(self, state):
        acc_value = state / self._game_controller.get_calibration(
        ).right_trigger_max
        if self._vehicle_ctl.get_gear() == Gear.DRIVE:
            self._vehicle_ctl.set_accelerator(acc_value)
        elif self._vehicle_ctl.get_gear() == Gear.REVERSE:
            acc_value *= -1
            self._vehicle_ctl.set_accelerator(acc_value)

    def game_controller_left_trigger_response(self, state):
        acc_value = state / self._game_controller.get_calibration(
        ).right_trigger_max
        acc_value *= -1
        if self._vehicle_ctl.get_gear() == Gear.DRIVE:
            self._vehicle_ctl.set_accelerator(acc_value)
        elif self._vehicle_ctl.get_gear() == Gear.REVERSE:
            acc_value *= -1
            self._vehicle_ctl.set_accelerator(acc_value)

    def forward_pressed(self):
        if self._vehicle_ctl.get_gear() is Gear.REVERSE:
            self._vehicle_ctl.set_accelerator(-1.0)
        elif self._vehicle_ctl.get_gear() is Gear.DRIVE:
            self._vehicle_ctl.set_accelerator(1.0)

    def forward_released(self):
        self._vehicle_ctl.set_accelerator(0.0)

    def backward_pressed(self):
        if self._vehicle_ctl.get_gear() is Gear.REVERSE:
            self._vehicle_ctl.set_accelerator(1.0)
        elif self._vehicle_ctl.get_gear() is Gear.DRIVE:
            self._vehicle_ctl.set_accelerator(-1.0)

    def backward_released(self):
        self._vehicle_ctl.set_accelerator(0.0)

    def right_pressed(self):
        self._vehicle_ctl.set_steering(1.0)

    def right_released(self):
        self._vehicle_ctl.set_steering(0.0)

    def left_pressed(self):
        self._vehicle_ctl.set_steering(-1.0)

    def left_released(self):
        self._vehicle_ctl.set_steering(0.0)

    def show_trim_window(self):

        # Pull in the trim from the vehicle to populate the trim window
        trim = self._vehicle_ctl.get_trim()
        self._trim_window = TrimDialog(trim)
        self._trim_window.setGeometry(QtCore.QRect(100, 100, 400, 200))
        self._trim_window.show()

        # After things have been trimmed, update our command so we can send updated trim values
        self._trim_window.trim_changed.connect(self.update_trim_from_dialog)

    def update_trim_from_dialog(self):
        trim = self._trim_window.get_trim()
        self._vehicle_ctl.send_trim(trim)

    def ip_changed(self, ip):

        port = self._sb_port.value()
        self._vehicle_ctl.set_endpoint(ip, port)

    def proxy_address_changed(self, address):
        self._vehicle_ctl.set_proxy(address,
                                    self._vehicle_ctl.vehicle_proxy_port())

    def proxy_port_changed(self, port):
        self._vehicle_ctl.set_proxy(self._vehicle_ctl.vehicle_proxy_address(),
                                    port)

    def use_proxy_toggled(self, state):
        self._le_proxy_address.setEnabled(state)
        self._sb_proxy_port.setEnabled(state)
        if state:
            self._vehicle_ctl.enable_proxy()
        else:
            self._vehicle_ctl.disable_proxy()

    def port_changed(self, port):
        ip = self._le_ip.text()
        self._vehicle_ctl.set_endpoint(ip, port)

    def mode_changed(self, index):
        mode_int = self._cbo_mode.currentData()
        mode = Mode()
        mode.set_mode(mode_int)

        self._vehicle_ctl.set_mode(mode)

    def restart_stream(self):

        self._vehicle_ctl.restart_stream()

    def change_gear(self):
        self._vehicle_ctl.toggle_fw_bw()
        self._lbl_gear.setText('<b style="color: black;">' +
                               self._vehicle_ctl.get_gear().value + "</b>")

    def keyPressEvent(self, e):
        if e.isAutoRepeat():
            return super().keyReleaseEvent(e)

        if e.key() == QtCore.Qt.Key_Up or e.key() == QtCore.Qt.Key_W:
            self.forward_pressed()
        if e.key() == QtCore.Qt.Key_Left or e.key() == QtCore.Qt.Key_A:
            self.left_pressed()
        if e.key() == QtCore.Qt.Key_Down or e.key() == QtCore.Qt.Key_S:
            self.backward_pressed()
        if e.key() == QtCore.Qt.Key_Right or e.key() == QtCore.Qt.Key_D:
            self.right_pressed()

        return super().keyPressEvent(e)

    def keyReleaseEvent(self, e):
        if e.isAutoRepeat():
            return super().keyReleaseEvent(e)

        if e.key() == QtCore.Qt.Key_Up or e.key() == QtCore.Qt.Key_W:
            self.forward_released()
        elif e.key() == QtCore.Qt.Key_Left or e.key() == QtCore.Qt.Key_A:
            self.left_released()
        elif e.key() == QtCore.Qt.Key_Down or e.key() == QtCore.Qt.Key_S:
            self.backward_released()
        elif e.key() == QtCore.Qt.Key_Right or e.key() == QtCore.Qt.Key_D:
            self.right_released()
        elif e.key() == QtCore.Qt.Key_R:
            self.change_gear()

        return super().keyReleaseEvent(e)

    def send_trim(self):
        self._vehicle_ctl.send_trim(self.trim)

    def create_gui(self):
        buttonHeight = 100
        self._forward_btn = QPushButton("ACC", self)
        self._brake_btn = QPushButton("BRAKE", self)
        self._left_btn = QPushButton("LEFT", self)
        self._right_btn = QPushButton("RIGHT", self)

        self._forward_btn.setFixedHeight(buttonHeight)
        self._brake_btn.setFixedHeight(buttonHeight)
        self._left_btn.setFixedHeight(buttonHeight)
        self._right_btn.setFixedHeight(buttonHeight)

        self._trim_btn = QPushButton("Set Trim", self)
        self._trim_btn.clicked.connect(self.show_trim_window)
        self._le_ip = QLineEdit(self._vehicle_ctl.vehicle_ip(), self)
        self._le_ip.textChanged.connect(self.ip_changed)
        self._lbl_ip = QLabel("Ip:")
        self._sb_port = QSpinBox(self)
        self._sb_port.setMaximum(99999)
        self._sb_port.setValue(self._vehicle_ctl.vehicle_port())
        self._sb_port.valueChanged.connect(self.port_changed)
        self._lbl_port = QLabel("Port:")
        self._lbl_mode = QLabel("Mode:")
        self._cbo_mode = QComboBox(self)
        self._lbl_proxy_address = QLabel("Proxy:")
        self._le_proxy_address = QLineEdit(
            self._vehicle_ctl.vehicle_proxy_address(), self)
        self._lbl_proxy_port = QLabel("Proxy Port:")

        self._lbl_gear = QLabel('<b style="color: black;">' +
                                self._vehicle_ctl.get_gear().value + "</b>")
        f = self._lbl_gear.font()
        f.setPointSizeF(100)
        self._lbl_gear.setFont(f)
        self._lbl_gear.setAlignment(Qt.AlignCenter)

        self._btn_change_gear = QPushButton("Shift Gear")

        self._sb_proxy_port = QSpinBox(self)
        self._sb_proxy_port.setMaximum(99999)
        self._sb_proxy_port.setValue(self._vehicle_ctl.vehicle_proxy_port())

        self._cbo_mode.addItem("NORMAL", int(ModeType.NORMAL))
        self._cbo_mode.addItem("TRAIN", int(ModeType.TRAIN))
        self._cbo_mode.addItem("AUTO", int(ModeType.AUTO))
        self._btn_restart = QPushButton("Restart Stream")
        self._cb_proxy = QCheckBox()
        self._lbl_use_proxy = QLabel("Use Proxy")
        self._cb_proxy.setChecked(self._vehicle_ctl.is_using_proxy())
        self._le_proxy_address.setEnabled(self._vehicle_ctl.is_using_proxy())
        self._sb_proxy_port.setEnabled(self._vehicle_ctl.is_using_proxy())

    def add_gui_listeners(self):
        self._forward_btn.pressed.connect(self.forward_pressed)
        self._forward_btn.released.connect(self.forward_released)
        self._brake_btn.pressed.connect(self.backward_pressed)
        self._brake_btn.released.connect(self.backward_released)
        self._right_btn.pressed.connect(self.right_pressed)
        self._right_btn.released.connect(self.right_released)
        self._left_btn.pressed.connect(self.left_pressed)
        self._left_btn.released.connect(self.left_released)
        self._cbo_mode.activated.connect(self.mode_changed)
        self._btn_restart.pressed.connect(self.restart_stream)
        self._cb_proxy.toggled.connect(self.use_proxy_toggled)
        self._le_proxy_address.textChanged.connect(self.proxy_address_changed)
        self._sb_proxy_port.valueChanged.connect(self.proxy_port_changed)
        self._btn_change_gear.released.connect(self.change_gear)

    def add_widgets_to_screen(self, cw):
        grid_layout = QGridLayout(cw)

        controls_layout = QGridLayout()
        controls_layout.setAlignment(Qt.AlignVCenter)
        grid_layout.addLayout(controls_layout, 0, 0, 2, 3)

        controls_layout.addWidget(self._forward_btn, 0, 1)
        controls_layout.addWidget(self._left_btn, 1, 0)
        controls_layout.addWidget(self._brake_btn, 1, 1)
        controls_layout.addWidget(self._right_btn, 1, 2)

        grid_layout.addWidget(self._lbl_ip, 2, 0)
        grid_layout.addWidget(self._le_ip, 2, 1, 1,
                              2)  # Stretch the line edit into two cells
        grid_layout.addWidget(self._lbl_port, 3, 0)
        grid_layout.addWidget(self._sb_port, 3, 1, 1,
                              2)  # Stretch the spinbox into two cells
        grid_layout.addWidget(self._lbl_use_proxy, 4, 0)
        grid_layout.addWidget(self._cb_proxy, 4, 1)
        grid_layout.addWidget(self._lbl_proxy_address, 5, 0)
        grid_layout.addWidget(self._le_proxy_address, 5, 1, 1, 2)
        grid_layout.addWidget(self._lbl_proxy_port, 6, 0)
        grid_layout.addWidget(self._sb_proxy_port, 6, 1, 1, 2)
        grid_layout.addWidget(self._lbl_mode, 7, 0)
        grid_layout.addWidget(self._cbo_mode, 7, 1, 1, 2)
        grid_layout.addWidget(self._image_viewer, 0, 3, 5, 1)
        grid_layout.addWidget(self._btn_restart, 5, 3)

        vehicle_layout = QVBoxLayout()
        grid_layout.addLayout(vehicle_layout, 0, 4)
        vehicle_layout.addWidget(self._lbl_gear)
        vehicle_layout.addWidget(self._btn_change_gear)
        vehicle_layout.addWidget(self._trim_btn)
Ejemplo n.º 14
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__()
        self.path = None
        self.settings()
        self.create_widgets()
        self.create_layout()

    def settings(self):
        self.resize(300, 120)
        self.setWindowTitle('Mp3 Downloader')

    def create_widgets(self):
        self.edit_url = QLineEdit()
        self.edit_name = QLineEdit()
        self.btn_select_path = QPushButton('Select path', self)
        self.btn_select_path.clicked.connect(self.select_path)
        self.btn_download = QPushButton('Download mp3', self)
        self.btn_download.clicked.connect(self.download)

    def create_layout(self):
        self.layout = QFormLayout()
        self.layout.addRow('Nome:', self.edit_name)
        self.layout.addRow('Url:', self.edit_url)
        self.layout.addRow('Selecionar destino:', self.btn_select_path)
        self.layout.addRow(self.btn_download)
        self.setLayout(self.layout)

    def select_path(self):
        self.path = QFileDialog.getExistingDirectory(self, 'Selecionar Pasta')

    def download(self):
        if self.verify_fields():
            self.manage_interface(False)
            self.thread_qt()

    def verify_fields(self):
        if self.path is None:
            return False
        else:
            strings = [self.edit_url, self.edit_name.text(), self.path]
            regex_validate = QRegExp('*.mp3')
            regex_validate.setPatternSyntax(QRegExp.Wildcard)
            emptys = 0
            for string in strings:
                if len(string.split()) == 0:
                    emptys += 1
                if emptys == 0 and regex_validate.exactMatch(
                        self.edit_url.text()):
                    return True

    def thread_qt(self):
        url = self.edit_url.text()
        name = self.edit_name.text()
        path = self.edit_path.text()
        self.thre = DownloaderMusic()
        self.thre.finished.connect(self.downfin)
        self.thre.start()

    def manage_interface(self, state):
        self.btn_download.setEnabled(state)
        self.edit_name.setEnabled(state)
        self.edit_url.setEnabled(state)
        self.btn_select_path

    def downfin(self):
        self.notify_icon = QSystemTrayIcon()
        self.notify_icon.setVisible(True)
        self.notify_icon.showMessage(
            'Download Finalizado',
            u'O download da sua música foi realizado com sucesso.',
            QSystemTrayIcon.Information, 3000)
        self.manage_interface(True)
Ejemplo n.º 15
0
class NodeInput(QWidget):
    def __init__(self, content_widget):
        super(NodeInput, self).__init__()

        self.content_widget = content_widget
        self.widget_type = ''  # gets specified automatically when creating ui below (see self.widget_combo_box_changed)

        # create UI

        # create all layouts
        self.grid_layout = QGridLayout(self)

        # move buttons
        self.up_button = QPushButton('   <   ')
        self.down_button = QPushButton('   >   ')

        # type and label
        self.type_combo_box = QComboBox(self)
        self.type_combo_box.addItem('exec')
        self.type_combo_box.addItem('data')
        self.type_combo_box.currentTextChanged.connect(
            self.type_combo_box_changed)
        self.label_text_edit = QPlainTextEdit(self)
        self.label_text_edit.setPlaceholderText('Label')
        self.label_text_edit.setFixedWidth(self.type_combo_box.width())
        # self.label_text_edit.setMinimumHeight(20)
        self.label_text_edit.setMaximumHeight(56)

        # widget
        self.widget_grid_layout = QGridLayout()
        self.widget_yes_no_group_box = QGroupBox(self)
        self.widget_yes_no_group_box.setLayout(QVBoxLayout())
        self.widget_yes_radio_button = QRadioButton('Yes', self)
        self.widget_yes_radio_button.setChecked(True)
        self.widget_yes_radio_button.toggled.connect(self.widget_yes_set)
        self.widget_no_radio_button = QRadioButton('No', self)
        self.widget_yes_no_group_box.layout().addWidget(
            self.widget_yes_radio_button)
        self.widget_yes_no_group_box.layout().addWidget(
            self.widget_no_radio_button)
        self.widget_grid_layout.addWidget(self.widget_yes_no_group_box, 0, 0,
                                          4, 1)

        self.widget_group_box = QGroupBox(self)
        self.widget_group_box.setLayout(QVBoxLayout())
        self.widget_type_combo_box = QComboBox(self)
        self.widget_type_combo_box.addItem('std line edit')
        self.widget_type_combo_box.addItem('std spin box')
        self.widget_type_combo_box.addItem('custom widget')
        self.widget_type_combo_box.currentTextChanged.connect(
            self.widget_type_combo_box_changed)
        self.custom_widget_line_edit = QLineEdit()
        self.custom_widget_line_edit.setPlaceholderText('input widget name')
        self.custom_widget_line_edit.editingFinished.connect(
            self.widget_name_line_edit_edited)
        self.custom_widget_line_edit.setEnabled(False)

        self.widget_under_label_radio_button = QRadioButton(
            'widget under label')
        self.widget_under_label_radio_button.setChecked(True)
        self.widget_besides_label_radio_button = QRadioButton(
            'widget besides label')

        self.widget_group_box.layout().addWidget(self.widget_type_combo_box)
        self.widget_group_box.layout().addWidget(self.custom_widget_line_edit)
        self.widget_group_box.layout().addWidget(
            self.widget_under_label_radio_button)
        self.widget_group_box.layout().addWidget(
            self.widget_besides_label_radio_button)

        self.widget_grid_layout.addWidget(self.widget_group_box, 0, 3, 4, 1)

        # del button
        self.del_button = QPushButton(self)
        self.del_button.setText(' Del ')
        self.del_button.clicked.connect(self.delete_clicked)

        # create layout
        self.grid_layout.addWidget(self.up_button, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.down_button, 3, 0, 1, 1)
        self.grid_layout.addWidget(self.type_combo_box, 0, 1)
        self.grid_layout.addWidget(self.label_text_edit, 1, 1, 3, 1)
        self.grid_layout.addLayout(self.widget_grid_layout, 0, 2, 4, 1)
        self.grid_layout.addWidget(self.del_button, 0, 4, 4, 1)

    def get_type(self):
        return self.type_combo_box.currentText()

    def get_label(self):
        return self.label_text_edit.toPlainText()

    def has_widget(self):
        return self.widget_yes_radio_button.isChecked()

    def set_has_widget(self, has_widget):
        if has_widget:
            self.widget_yes_radio_button.setChecked(True)
            self.widget_no_radio_button.setChecked(False)
        else:
            self.widget_yes_radio_button.setChecked(False)
            self.widget_no_radio_button.setChecked(True)

    def get_widget_type(self):
        return self.widget_type_combo_box.currentText()

    def set_widget_type(self, new_widget_type):
        self.widget_type_combo_box.setCurrentText(new_widget_type)

    def get_widget_name(self):
        return self.content_widget.prepare_class_name(
            self.custom_widget_line_edit.text())

    def set_widget_name(self, name):
        self.custom_widget_line_edit.setText(name)

    def get_widget_pos(self):
        under = self.widget_under_label_radio_button
        # besides = self.widget_besides_label_radio_button
        return 'under' if under.isChecked() else 'besides'

    def set_widget_pos(self, pos):
        if pos == 'under':
            self.widget_under_label_radio_button.setChecked(True)
            self.widget_besides_label_radio_button.setChecked(False)
        elif pos == 'besides':
            self.widget_under_label_radio_button.setChecked(False)
            self.widget_besides_label_radio_button.setChecked(True)

    def widget_yes_set(self):
        if self.widget_yes_radio_button.isChecked():
            self.widget_group_box.setEnabled(True)
        else:
            self.widget_group_box.setEnabled(False)

    def widget_name_line_edit_edited(self):
        self.custom_widget_line_edit.setText(
            self.content_widget.prepare_class_name(
                self.custom_widget_line_edit.text()))

    def widget_type_combo_box_changed(self, new_text):
        self.widget_type = new_text
        if new_text == 'custom widget':
            self.custom_widget_line_edit.setEnabled(True)
        else:
            self.custom_widget_line_edit.setEnabled(False)

    def set_type(self, new_type):
        self.type_combo_box.setCurrentText(new_type)

    def type_combo_box_changed(self, new_type):
        if new_type == 'data':
            self.widget_grid_layout.setEnabled(True)
        elif new_type == 'exec':
            self.widget_grid_layout.setEnabled(False)

    def set_label(self, new_label):
        self.label_text_edit.setPlainText(new_label)

    def delete_clicked(self):
        ret = QMessageBox.warning(
            self, 'Input',
            'Do you really want to delete this input? All changes'
            'will be lost.', QMessageBox.Yes, QMessageBox.No)
        if ret == QMessageBox.Yes:
            self.content_widget.delete_input(self)
Ejemplo n.º 16
0
class ButtonBox(QGroupBox):
    """ This code is to contain the overall controls which govern running experiments. """
    def __init__(self, parent, size: QSize, log_handlers: [StreamHandler],
                 lang: LangEnum):
        self.logger = getLogger(__name__)
        for h in log_handlers:
            self.logger.addHandler(h)
        self.logger.debug("Initializing")
        super().__init__(parent)
        self.setLayout(QVBoxLayout())
        self.setMaximumSize(size)
        self._button_layout = QHBoxLayout()

        self._create_button = ClickAnimationButton()
        self._create_button.setFixedSize(60, 40)
        self._start_button = ClickAnimationButton()
        self._start_button.setFixedSize(120, 40)
        self._button_layout.addWidget(self._create_button)
        self._button_layout.addWidget(self._start_button)
        self._text_entry = QLineEdit()
        self.layout().addLayout(self._button_layout)
        self.layout().addWidget(self._text_entry)

        self._play_icon = QIcon(button_box_start_image_filepath)
        self._pause_icon = QIcon(button_box_pause_image_filepath)

        # self.prog_bar_label = QLabel()
        # self.prog_bar = QProgressBar()
        # self.prog_bar.setTextVisible(True)
        # self.prog_bar.setAlignment(Qt.AlignHCenter)
        # self.prog_bar.setMaximumHeight(12)
        # self.layout().addWidget(self.prog_bar_label)
        # self.layout().addWidget(self.prog_bar)

        self._start_button_state = 0
        self._create_button_state = 0
        self._set_button_states()
        self._strings = dict()
        self.set_lang(lang)
        # self.toggle_show_prog_bar(False)
        self.logger.debug("Initialized")

    def set_lang(self, lang: LangEnum) -> None:
        """
        Set the language for this view object.
        :param lang: The enum for the language.
        :return None:
        """
        self._strings = strings[lang]
        self._set_texts()
        self._set_tooltips()

    def get_condition_name(self) -> str:
        """
        Return the text from the condition name text entry
        :return: The text from the text entry.
        """
        return self._text_entry.text()

    def add_create_button_handler(self, func: classmethod) -> None:
        """
        Add handler for the create button click event.
        :param func: The handler.
        :return: None.
        """
        self.logger.debug("running")
        self._create_button.clicked.connect(func)
        self.logger.debug("done")

    def add_start_button_handler(self, func: classmethod) -> None:
        """
        Add handler for the start button click event.
        :param func: The handler
        :return: None.
        """
        self.logger.debug("running")
        self._start_button.clicked.connect(func)
        self.logger.debug("done")

    def set_condition_name_box_enabled(self, is_active: bool) -> None:
        """
        Set whether this text entry is enabled.
        :param is_active: Whether this button is active.
        :return: None
        """
        self.logger.debug("running")
        self._text_entry.setEnabled(is_active)
        self.logger.debug("done")

    def set_create_button_enabled(self, is_active: bool) -> None:
        """
        Toggle whether this button is active.
        :param is_active: Whether this button is active.
        :return None:
        """
        self._create_button.setEnabled(is_active)

    def set_create_button_state(self, button_state: int) -> None:
        """
        Set create button state to given state. 0: Create. 1: End.
        :param button_state: The state to show on this button.
        :return: None.
        """
        self.logger.debug("running")
        if button_state == 0:
            self._create_button.setText(self._strings[StringsEnum.CREATE])
            self._create_button.setToolTip(
                self._strings[StringsEnum.CREATE_TT])
        elif button_state == 1:
            self._create_button.setText(self._strings[StringsEnum.END])
            self._create_button.setToolTip(self._strings[StringsEnum.END_TT])
        self.logger.debug("done")

    def set_start_button_enabled(self, is_active: bool) -> None:
        """
        Toggle whether this button is active.
        :param is_active: Whether this button is active.
        :return None:
        """
        self._start_button.setEnabled(is_active)

    def set_start_button_state(self, button_state: int = 0) -> None:
        """
        Set start button state to given state. 0: Start. 1: Pause. 2: Resume.
        :param button_state: The state to show on this button.
        :return: None.
        """
        self.logger.debug("running")
        if button_state == 0:
            self._start_button.setIcon(self._play_icon)
            self._start_button.setIconSize(QSize(26, 26))
            self._start_button.setToolTip(self._strings[StringsEnum.START_TT])
        elif button_state == 1:
            self._start_button.setIcon(self._pause_icon)
            self._start_button.setIconSize(QSize(36, 36))
            self._start_button.setToolTip(self._strings[StringsEnum.PAUSE_TT])
        elif button_state == 2:
            self._start_button.setIcon(self._play_icon)
            self._start_button.setIconSize(QSize(26, 26))
            self._start_button.setToolTip(self._strings[StringsEnum.RESUME_TT])
        self.logger.debug("done")

    def toggle_show_prog_bar(self, is_visible: bool) -> None:
        """
        Toggle showing the progress bar.
        :param is_visible: Whether or not to show the progress bar.
        :return: None.
        """
        pass
        # if is_visible:
        #     self.prog_bar.show()
        #     self.prog_bar_label.show()
        # else:
        #     self.prog_bar.hide()
        #     self.prog_bar_label.hide()

    def update_prog_bar_value(self, value: int) -> None:
        """
        Update the progress bar to the given value
        :param value: The value to use when updating the progress bar.
        :return: None.
        """
        pass
        # self.prog_bar.setValue(value)

    def _set_texts(self) -> None:
        """
        Set the texts of this view item.
        :return: None.
        """
        self.logger.debug("running")
        self.setTitle(self._strings[StringsEnum.TITLE])
        self._text_entry.setPlaceholderText(
            self._strings[StringsEnum.COND_NAME_SHADOW])
        if self._create_button_state == 0:
            self._create_button.setText(self._strings[StringsEnum.CREATE])
        elif self._create_button_state == 1:
            self._create_button.setText(self._strings[StringsEnum.END])
        if self._start_button_state == 0 or self._start_button_state == 2:
            self._start_button.setIcon(self._play_icon)
            self._start_button.setIconSize(QSize(32, 32))
        elif self._start_button_state == 1:
            self._start_button.setIcon(self._pause_icon)
            self._start_button.setIconSize(QSize(36, 36))
        # self.prog_bar_label.setText(button_box_prog_bar_label)
        # self.prog_bar.setValue(0)
        self.logger.debug("done")

    def _set_button_states(self) -> None:
        """
        Set default button states.
        :return: None.
        """
        self.logger.debug("running")
        self._start_button.setEnabled(False)
        self.logger.debug("done")

    def _set_tooltips(self) -> None:
        """
        Set the text for the tooltips in this view item.
        :return: None.
        """
        self.logger.debug("running")
        if self._create_button_state == 0:
            self._create_button.setToolTip(
                self._strings[StringsEnum.CREATE_TT])
        if self._create_button_state == 1:
            self._create_button.setToolTip(self._strings[StringsEnum.END_TT])
        if self._start_button_state == 0:
            self._start_button.setToolTip(self._strings[StringsEnum.START_TT])
        elif self._start_button_state == 1:
            self._start_button.setToolTip(self._strings[StringsEnum.PAUSE_TT])
        elif self._start_button_state == 2:
            self._start_button.setToolTip(self._strings[StringsEnum.RESUME_TT])
        self.logger.debug("done")
Ejemplo n.º 17
0
class ContinuousCriteriaPage(EnableNextOnBackMixin, QWizardPage):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent_wizard = weakref.proxy(parent)

        self.setTitle('Continuous criteria')
        # Radio button, if yes then ask for inputs
        self.yes = QRadioButton(
            '&Yes, there are criteria that needs to be calculated')
        no = QRadioButton(
            'N&o, I will manually give a rating for every choice and criteria')
        no.setChecked(True)

        self.registerField('yes', self.yes)
        self.yes.toggled.connect(self.toggled)

        group = QButtonGroup(self)
        group.addButton(self.yes)
        group.addButton(no)

        # Duplicated from AbstractMultiInputPage
        self.line_edit = QLineEdit()
        self.list_widget = QListWidget()
        self.add_button = QPushButton('&Add criterion')
        self.delete_button = QPushButton('&Delete')

        self.line_edit.setDisabled(True)
        self.list_widget.setDisabled(True)
        self.add_button.setDisabled(True)
        self.delete_button.setDisabled(True)

        self.line_edit.returnPressed.connect(self.add_item)
        self.add_button.clicked.connect(self.add_item)
        self.delete_button.clicked.connect(self.delete_item)

        grid = QGridLayout(self)
        grid.addWidget(self.yes, 0, 0)
        grid.addWidget(no, 1, 0)
        grid.addWidget(self.line_edit, 2, 0)
        grid.addWidget(self.add_button, 2, 1)
        grid.addWidget(self.list_widget, 3, 0)
        grid.addWidget(self.delete_button, 3, 1, Qt.AlignTop)
        self.setLayout(grid)

    def initializePage(self):
        for criterion in self.parent_wizard.main_parent.matrix.continuous_criteria:
            self.list_widget.addItem(QListWidgetItem(criterion))

        if self.list_widget.count() != 0:
            self.yes.setChecked(True)
            self.parent_wizard.next_button.setEnabled(True)

    def toggled(self, checked: bool):
        if checked:
            self.line_edit.setEnabled(True)
            self.list_widget.setEnabled(True)
            self.add_button.setEnabled(True)
            self.parent_wizard.next_button.setDisabled(True)
        else:
            self.line_edit.setDisabled(True)
            self.list_widget.setDisabled(True)
            self.parent_wizard.next_button.setEnabled(True)

    def add_item(self):
        # Duplicated
        if not (name := self.line_edit.text()):
            return
        item = QListWidgetItem(name)
        self.list_widget.addItem(item)
        self.line_edit.clear()
        self.line_edit.setFocus()
        self.parent_wizard.next_button.setEnabled(True)
        self.delete_button.setEnabled(True)

        self.parent_wizard.main_parent.line_edit_cc_tab.setText(name)
        self.parent_wizard.main_parent.matrix.add_continuous_criterion(
            name, weight=float('nan'))
        self.parent_wizard.main_parent.add_continuous_criteria()
Ejemplo n.º 18
0
class App(QWidget):
    def __init__(self, bk, prefs):
        super().__init__()

        self.bk = bk
        self.prefs = prefs
        self.update = False

        # Install translator for the DOCXImport plugin dialog.
        # Use the Sigil language setting unless manually overridden.
        plugin_translator = QTranslator()
        if prefs['language_override'] is not None:
            print('Plugin preferences language override in effect')
            qmf = '{}_{}'.format(bk._w.plugin_name.lower(),
                                 prefs['language_override'])
        else:
            qmf = '{}_{}'.format(bk._w.plugin_name.lower(), bk.sigil_ui_lang)
        print(
            qmf,
            os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations'))
        plugin_translator.load(
            qmf,
            os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations'))
        print(QCoreApplication.instance().installTranslator(plugin_translator))

        self._ok_to_close = False

        self.FTYPE_MAP = {
            'smap': {
                'title': _translate('App', 'Select custom style-map file'),
                'defaultextension': '.txt',
                'filetypes': 'Text Files (*.txt);;All files (*.*)',
            },
            'css': {
                'title': _translate('App', 'Select custom CSS file'),
                'defaultextension': '.css',
                'filetypes': 'CSS Files (*.css)',
            },
            'docx': {
                'title': _translate('App', 'Select DOCX file'),
                'defaultextension': '.docx',
                'filetypes': 'DOCX Files (*.docx)',
            },
        }

        # Check online github files for newer version
        if self.prefs['check_for_updates']:
            self.update, self.newversion = self.check_for_update()
        self.initUI()

    def initUI(self):
        main_layout = QVBoxLayout(self)

        self.setWindowTitle('DOCXImport')
        self.upd_layout = QVBoxLayout()
        self.update_label = QLabel()
        self.update_label.setAlignment(Qt.AlignCenter)
        self.upd_layout.addWidget(self.update_label)
        self.get_update_button = QPushButton()
        self.get_update_button.clicked.connect(self.get_update)
        self.upd_layout.addWidget(self.get_update_button)
        main_layout.addLayout(self.upd_layout)
        if not self.update:
            self.update_label.hide()
            self.get_update_button.hide()

        self.details_grid = QGridLayout()
        self.epub2_select = QRadioButton()
        self.epub2_select.setText('EPUB2')
        self.epubType = QButtonGroup()
        self.epubType.addButton(self.epub2_select)
        self.details_grid.addWidget(self.epub2_select, 0, 0, 1, 1)
        self.checkbox_get_updates = QCheckBox()
        self.details_grid.addWidget(self.checkbox_get_updates, 0, 1, 1, 1)
        self.epub3_select = QRadioButton()
        self.epub3_select.setText('EPUB3')
        self.epubType.addButton(self.epub3_select)
        self.details_grid.addWidget(self.epub3_select, 1, 0, 1, 1)
        main_layout.addLayout(self.details_grid)
        self.checkbox_get_updates.setChecked(self.prefs['check_for_updates'])
        if self.prefs['epub_version'] == '2.0':
            self.epub2_select.setChecked(True)
        elif self.prefs['epub_version'] == '3.0':
            self.epub3_select.setChecked(True)
        else:
            self.epub2_select.setChecked(True)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle('')
        self.verticalLayout_2 = QVBoxLayout(self.groupBox)
        self.docx_grid = QGridLayout()
        self.docx_label = QLabel()
        self.docx_grid.addWidget(self.docx_label, 0, 0, 1, 1)
        self.docx_path = QLineEdit()
        self.docx_grid.addWidget(self.docx_path, 1, 0, 1, 1)
        self.choose_docx_button = QPushButton()
        self.choose_docx_button.setText('...')
        self.docx_grid.addWidget(self.choose_docx_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.docx_grid)
        self.choose_docx_button.clicked.connect(
            lambda: self.fileChooser('docx', self.docx_path))
        if len(self.prefs['lastDocxPath']):
            self.docx_path.setText(self.prefs['lastDocxPath'])
        self.docx_path.setEnabled(False)

        self.smap_grid = QGridLayout()
        self.checkbox_smap = QCheckBox(self.groupBox)
        self.smap_grid.addWidget(self.checkbox_smap, 0, 0, 1, 1)
        self.cust_smap_path = QLineEdit(self.groupBox)
        self.smap_grid.addWidget(self.cust_smap_path, 1, 0, 1, 1)
        self.choose_smap_button = QPushButton(self.groupBox)
        self.choose_smap_button.setText('...')
        self.smap_grid.addWidget(self.choose_smap_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.smap_grid)
        self.checkbox_smap.setChecked(self.prefs['useSmap'])
        self.checkbox_smap.stateChanged.connect(lambda: self.chkBoxActions(
            self.checkbox_smap, self.choose_smap_button))
        self.choose_smap_button.clicked.connect(
            lambda: self.fileChooser('smap', self.cust_smap_path, self.
                                     checkbox_smap, self.choose_smap_button))
        if len(self.prefs['useSmapPath']):
            self.cust_smap_path.setText(self.prefs['useSmapPath'])
        self.cust_smap_path.setEnabled(False)
        self.chkBoxActions(self.checkbox_smap, self.choose_smap_button)

        self.css_grid = QGridLayout()
        self.checkbox_css = QCheckBox(self.groupBox)
        self.css_grid.addWidget(self.checkbox_css, 0, 0, 1, 1)
        self.cust_css_path = QLineEdit(self.groupBox)
        self.css_grid.addWidget(self.cust_css_path, 1, 0, 1, 1)
        self.choose_css_button = QPushButton(self.groupBox)
        self.choose_css_button.setText('...')
        self.css_grid.addWidget(self.choose_css_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.css_grid)
        self.checkbox_css.setChecked(self.prefs['useCss'])
        self.checkbox_css.stateChanged.connect(lambda: self.chkBoxActions(
            self.checkbox_css, self.choose_css_button))
        self.choose_css_button.clicked.connect(
            lambda: self.fileChooser('css', self.cust_css_path, self.
                                     checkbox_css, self.choose_css_button))
        if len(self.prefs['useCssPath']):
            self.cust_css_path.setText(self.prefs['useCssPath'])
        self.cust_css_path.setEnabled(False)
        self.chkBoxActions(self.checkbox_css, self.choose_css_button)

        main_layout.addWidget(self.groupBox)
        self.checkbox_debug = QCheckBox()
        main_layout.addWidget(self.checkbox_debug)
        self.checkbox_debug.setChecked(self.prefs['debug'])

        spacerItem = QSpacerItem(20, 15, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        main_layout.addItem(spacerItem)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self._ok_clicked)
        button_box.rejected.connect(self._cancel_clicked)
        main_layout.addWidget(button_box)
        self.retranslateUi(self)
        if self.prefs['qt_geometry'] is not None:
            try:
                self.restoreGeometry(
                    QByteArray.fromHex(
                        self.prefs['qt_geometry'].encode('ascii')))
            except:
                pass
        self.show()

    def retranslateUi(self, App):
        self.update_label.setText(_translate('App', 'Plugin Update Available'))
        self.get_update_button.setText(_translate('App',
                                                  'Go to download page'))
        self.checkbox_get_updates.setText(
            _translate('App', 'Check for plugin updates'))
        self.docx_label.setText(_translate('App', 'DOCX File to import'))
        self.checkbox_smap.setText(_translate('App', 'Use Custom Style Map'))
        self.checkbox_css.setText(_translate('App', 'Use Custom CSS'))
        self.checkbox_debug.setText(
            _translate('App',
                       'Debug Mode (change takes effect next plugin run)'))

    def fileChooser(self, ftype, qlineedit, qcheck=None, qbutton=None):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        title = self.FTYPE_MAP[ftype]['title']
        startfolder = self.prefs['lastDir'][ftype]
        ffilter = self.FTYPE_MAP[ftype]['filetypes']
        inpath, _ = QFileDialog.getOpenFileName(self,
                                                title,
                                                startfolder,
                                                ffilter,
                                                options=options)
        if len(inpath):
            qlineedit.setEnabled(True)
            qlineedit.setText(os.path.normpath(inpath))
            self.prefs['lastDir'][ftype] = os.path.dirname(inpath)
            qlineedit.setEnabled(False)
        else:
            if qcheck is not None:
                qcheck.setChecked(False)
            if qbutton is not None:
                qbutton.setEnabled(False)

    def chkBoxActions(self, chk, btn):
        btn.setEnabled(chk.isChecked())

    def cmdDo(self):
        global _DETAILS
        self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode(
            'ascii')
        self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked()
        self.prefs['epub_version'] = self.epubType.checkedButton().text(
        )[-1] + '.0'
        self.prefs['debug'] = self.checkbox_debug.isChecked()
        _DETAILS['vers'] = self.epubType.checkedButton().text()[-1] + '.0'
        self.prefs['useSmap'] = self.checkbox_smap.isChecked()
        if self.checkbox_smap.isChecked():
            if len(self.cust_smap_path.text()):
                self.prefs['useSmapPath'] = self.cust_smap_path.text()
                _DETAILS['smap'] = (self.checkbox_smap.isChecked(),
                                    self.cust_smap_path.text())
            else:
                # Message box that no file is selected
                return
        self.prefs['useCss'] = self.checkbox_css.isChecked()
        if self.checkbox_css.isChecked():
            if len(self.cust_css_path.text()):
                self.prefs['useCssPath'] = self.cust_css_path.text()
                _DETAILS['css'] = (self.checkbox_css.isChecked(),
                                   self.cust_css_path.text())
            else:
                # Message box that no file is selected
                return
        if len(self.docx_path.text()):
            self.prefs['lastDocxPath'] = self.docx_path.text()
            _DETAILS['docx'] = self.docx_path.text()
        else:
            # Message box that no file is selected
            return

    def check_for_update(self):
        '''Use updatecheck.py to check for newer versions of the plugin'''
        chk = UpdateChecker(self.prefs['last_time_checked'], self.bk._w)
        update_available, online_version, time = chk.update_info()
        # update preferences with latest date/time/version
        self.prefs['last_time_checked'] = time
        if online_version is not None:
            self.prefs['last_online_version'] = online_version
        if update_available:
            return (True, online_version)
        return (False, online_version)

    def get_update(self):
        url = DOWNLOAD_PAGE
        if self.update:
            latest = '/tag/v{}'.format(self.newversion)
            url = url + latest
        webbrowser.open_new_tab(url)

    def _ok_clicked(self):
        self._ok_to_close = True
        self.cmdDo()
        self.bk.savePrefs(self.prefs)
        QCoreApplication.instance().quit()

    def _cancel_clicked(self):
        self._ok_to_close = True
        '''Close aborting any changes'''
        self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode(
            'ascii')
        self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked()
        self.prefs['debug'] = self.checkbox_debug.isChecked()
        self.bk.savePrefs(self.prefs)
        QCoreApplication.instance().quit()

    def closeEvent(self, event):
        if self._ok_to_close:
            event.accept()  # let the window close
        else:
            self._cancel_clicked()
Ejemplo n.º 19
0
class RightSide:
    def __init__(self, font):
        self._font = font

        self.layout = QVBoxLayout()

        self.stdout_info = QTextEdit()
        self.stdout_info.setFixedWidth(800)
        self.stdout_info.moveCursor(QtGui.QTextCursor.Start)
        self.stdout_info.ensureCursorVisible()
        self.stdout_info.setLineWrapColumnOrWidth(500)
        self.stdout_info.setLineWrapMode(QTextEdit.FixedPixelWidth)

        self.layout.addWidget(self.stdout_info)

        self._set_media_player()

        self._midi_path = os.path.abspath(
            os.path.join(str(Path(__file__).parent.parent.parent), 'results'))
        self._midi_file = None
        self.midi_player = MidiPlayer()
        self._toggle_pause = True
        self._already_playing = False

        self._play_default_stylesheet = None
        self._pause_default_stylesheet = None
        self._stop_default_stylesheet = None

        self.end_signal = 'NO END.'
        self.player_timer_thread = threading.Thread(
            target=self._update_media_player_timer)
        self.player_timer_thread.start()

    def update_stdout_text_window(self, msg):
        cursor = self.stdout_info.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(msg)
        self.stdout_info.setTextCursor(cursor)
        self.stdout_info.ensureCursorVisible()

    def _set_media_player(self):
        self._resources_path = os.path.abspath(
            os.path.join(str(Path(__file__).parent.parent.parent), 'resources',
                         'gui'))

        self._media_box = QHBoxLayout()

        self._play_button = QPushButton('PLAY')
        self._play_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'play.png'))
        self._play_button.setIcon(self._play_icon)
        self._play_default_stylesheet = self._play_button.styleSheet()
        self._play_button.setEnabled(False)
        self._play_button.clicked.connect(lambda c: self._play_midi())

        self._pause_button = QPushButton('PAUSE')
        self._pause_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'pause.png'))
        self._pause_button.setIcon(self._pause_icon)
        self._pause_default_stylesheet = self._pause_button.styleSheet()
        self._pause_button.setEnabled(False)
        self._pause_button.clicked.connect(lambda c: self._pause())

        self._stop_button = QPushButton('STOP')
        self._stop_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'stop.png'))
        self._stop_button.setIcon(self._stop_icon)
        self._stop_button.setEnabled(False)
        self._stop_button.clicked.connect(lambda c: self._stop())
        self._stop_button.setStyleSheet(
            "QPushButton:pressed { background-color: red }")

        self._player_timer = QLineEdit('--/-- sec.')
        self._player_timer.setFixedWidth(200)
        self._player_timer.setEnabled(False)

        self._media_box.addWidget(self._play_button)
        self._media_box.addWidget(self._pause_button)
        self._media_box.addWidget(self._stop_button)
        self._media_box.addWidget(self._player_timer)
        self.layout.addLayout(self._media_box)

    def update_media_player(self, msg):
        self._midi_file = os.path.join(self._midi_path, msg[:-4] + '.mid')
        self.midi_player.load(self._midi_file)
        self._play_button.setEnabled(True)
        self._pause_button.setEnabled(True)
        self._stop_button.setEnabled(True)

    def _play_midi(self):
        self._play_button.setStyleSheet("background-color: green")
        self._pause_button.setStyleSheet(self._pause_default_stylesheet)

        self._toggle_pause = True
        if self._already_playing is False:
            self.midi_player.play()
            self._already_playing = True

    def _pause(self):
        self._play_button.setStyleSheet(self._play_default_stylesheet)
        self._pause_button.setStyleSheet("background-color: green")

        if self._toggle_pause is True:
            self.midi_player.pause()
            self._already_playing = False
        else:
            self.midi_player.unpause()
            self._already_playing = True

        self._toggle_pause = not self._toggle_pause

    def _stop(self):
        self._play_button.setStyleSheet(self._play_default_stylesheet)
        self._pause_button.setStyleSheet(self._pause_default_stylesheet)
        self._toggle_pause = True
        self.midi_player.stop()
        self._already_playing = False

    def _update_media_player_timer(self):
        while True:
            if self.end_signal == 'End.':
                break

            total = self.midi_player.song_duration
            if total != 0:
                current = self.midi_player.current_runtime
                if int(current) > math.floor(total):
                    current = total
                output = f'{current}/{total} sec.'
            else:
                output = '--/-- sec.'
            self._player_timer.setText(output)
Ejemplo n.º 20
0
class VOGTab(QWidget):
    """ This code is for helping the user interact with the configurations of the VOG device. """
    def __init__(self, device, ch):
        self.logger = logging.getLogger(__name__)
        self.logger.addHandler(ch)
        self.logger.debug("Initializing")
        try:
            super().__init__()
        except Exception as e:
            self.logger.exception(
                "Error making VOGTab, passed parent is invalid")
            return
        self.setLayout(QVBoxLayout(self))
        self.setGeometry(QRect(0, 0, 200, 500))
        self.setMaximumHeight(500)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set configuration value display area"""
        self.__config_frame = EasyFrame()
        self.__config_horiz_layout = QHBoxLayout(self.__config_frame)
        self.__config_label = QLabel(self.__config_frame)
        self.__config_label.setAlignment(Qt.AlignCenter)
        self.__config_horiz_layout.addWidget(self.__config_label)
        self.__config_val_line_edit = QLineEdit(self.__config_frame)
        self.__config_val_line_edit.setAlignment(Qt.AlignCenter)
        self.__config_horiz_layout.addWidget(self.__config_val_line_edit)
        self.layout().addWidget(self.__config_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set preset button selection area. """
        self.__presets_frame = EasyFrame()
        self.__presets_vert_layout = QVBoxLayout(self.__presets_frame)
        self.__nhtsa_button = ClickAnimationButton(self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__nhtsa_button)
        self.__eblindfold_button = ClickAnimationButton(self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__eblindfold_button)
        self.__direct_control_button = ClickAnimationButton(
            self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__direct_control_button)
        self.layout().addWidget(self.__presets_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set open duration, close duration, and debounce time settings display area. """
        self.__input_box_frame = EasyFrame()
        self.__input_box_grid_layout = QGridLayout(self.__input_box_frame)
        self.__input_box_grid_layout.setContentsMargins(0, 6, 0, 6)
        self.__open_dur_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__open_dur_label, 0, 0, 1,
                                               1)
        self.__open_dur_line_edit = QLineEdit(self.__input_box_frame)
        self.__open_dur_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__open_dur_line_edit, 0, 1,
                                               1, 1)
        self.__open_inf_check_box = QCheckBox(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__open_inf_check_box, 0, 2,
                                               1, 1)
        self.__close_dur_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__close_dur_label, 1, 0, 1,
                                               1)
        self.__close_dur_line_edit = QLineEdit(self.__input_box_frame)
        self.__close_dur_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__close_dur_line_edit, 1,
                                               1, 1, 1)
        self.__close_inf_check_box = QCheckBox(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__close_inf_check_box, 1,
                                               2, 1, 1)
        self.__debounce_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__debounce_label, 2, 0, 1,
                                               1)
        self.__debounce_time_line_edit = QLineEdit(self.__input_box_frame)
        self.__debounce_time_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__debounce_time_line_edit,
                                               2, 1, 1, 1)
        self.layout().addWidget(self.__input_box_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set button mode setting display area. """
        self.__button_mode_frame = EasyFrame()
        self.__button_mode_horiz_layout = QHBoxLayout(self.__button_mode_frame)
        self.__button_mode_label = QLabel(self.__button_mode_frame)
        self.__button_mode_horiz_layout.addWidget(self.__button_mode_label)
        self.__button_mode_selector = QComboBox(self.__button_mode_frame)
        self.__button_mode_selector.addItem("")
        self.__button_mode_selector.addItem("")
        self.__button_mode_horiz_layout.addWidget(self.__button_mode_selector)
        self.layout().addWidget(self.__button_mode_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set upload button selection area. """
        self.__upload_settings_button = ClickAnimationButton()
        self.layout().addWidget(self.__upload_settings_button)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set manual control selection area. """
        self.__manual_control_button = ClickAnimationButton()
        self.layout().addWidget(self.__manual_control_button)

        self.layout().addWidget(EasyFrame(line=True))

        self.__graph_buttons = []
        self.device_info = device
        self.__index = 0
        self.__set_texts()
        self.__set_tooltips()
        self.logger.debug("Initialized")

    def add_manual_control_handler(self, func):
        self.logger.debug("running")
        self.__manual_control_button.clicked.connect(func)
        self.logger.debug("done")

    def add_nhtsa_button_handler(self, func):
        self.logger.debug("running")
        self.__nhtsa_button.clicked.connect(func)
        self.logger.debug("done")

    def add_eblind_button_handler(self, func):
        self.logger.debug("running")
        self.__eblindfold_button.clicked.connect(func)
        self.logger.debug("done")

    def add_direct_control_button_handler(self, func):
        self.logger.debug("running")
        self.__direct_control_button.clicked.connect(func)
        self.logger.debug("done")

    def add_upload_button_handler(self, func):
        self.logger.debug("running")
        self.__upload_settings_button.clicked.connect(func)
        self.logger.debug("done")

    def add_open_inf_handler(self, func):
        self.logger.debug("running")
        self.__open_inf_check_box.toggled.connect(func)
        self.logger.debug("done")

    def add_close_inf_handler(self, func):
        self.logger.debug("running")
        self.__close_inf_check_box.toggled.connect(func)
        self.logger.debug("done")

    def add_open_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__open_dur_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_close_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__close_dur_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_debounce_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__debounce_time_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_button_mode_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__button_mode_selector.currentIndexChanged.connect(func)
        self.logger.debug("done")

    def add_config_val_changed_handler(self, func):
        self.logger.debug("running")
        self.__config_val_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def set_upload_button_activity(self, is_active):
        """ Set upload button to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__upload_settings_button.setEnabled(is_active)
        self.logger.debug("done")

    def set_config_value(self, value):
        """ Set display value of config.txt. """
        self.logger.debug("running")
        self.__config_val_line_edit.setText(value)
        self.logger.debug("done")

    def get_config_value(self):
        return self.__config_val_line_edit.text()

    def get_open_val(self):
        return self.__open_dur_line_edit.text()

    def set_open_val(self, val):
        """ Set display value of open duration. """
        self.logger.debug("running")
        self.__open_dur_line_edit.setText(str(val))
        self.logger.debug("done")

    def set_open_val_error(self, is_error):
        """ Set display of error in open duration line edit. """
        self.logger.debug("running")
        if is_error:
            self.__open_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self.__open_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_close_val_error(self, is_error):
        """ Set display of error in close duration line edit. """
        self.logger.debug("running")
        if is_error:
            self.__close_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self.__close_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_debounce_val_error(self, is_error):
        """ Set display of error in debounce line edit. """
        self.logger.debug("running")
        if is_error:
            self.__debounce_time_line_edit.setStyleSheet(
                tab_line_edit_error_style)
        else:
            self.__debounce_time_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_open_val_entry_activity(self, is_active):
        """ Set open value line edit to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__open_dur_line_edit.setEnabled(is_active)
        self.logger.debug("done")

    def get_open_inf(self):
        return self.__open_inf_check_box.isChecked()

    def set_open_inf(self, is_checked):
        """ Set open infinity checkbox state to is_checked. """
        self.logger.debug("running")
        self.__open_inf_check_box.setChecked(is_checked)
        self.logger.debug("done")

    def get_close_val(self):
        return self.__close_dur_line_edit.text()

    def set_close_val(self, val):
        """ Set display value of close duration. """
        self.logger.debug("running")
        self.__close_dur_line_edit.setText(str(val))
        self.logger.debug("done")

    def set_close_val_entry_activity(self, is_active):
        """ Set close value line edit to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__close_dur_line_edit.setEnabled(is_active)
        self.logger.debug("done")

    def get_close_inf(self):
        return self.__close_inf_check_box.isChecked()

    def set_close_inf(self, is_checked):
        """ Set close infinity checkbox state to is_checked. """
        self.logger.debug("running")
        self.__close_inf_check_box.setChecked(is_checked)
        self.logger.debug("done")

    def get_debounce_val(self):
        return self.__debounce_time_line_edit.text()

    def set_debounce_val(self, val):
        """ Set debounce display value. """
        self.logger.debug("running")
        self.__debounce_time_line_edit.setText(str(val))
        self.logger.debug("done")

    def get_button_mode(self):
        return self.__button_mode_selector.currentIndex()

    def set_button_mode(self, val):
        """ Set display value of button mode. """
        self.logger.debug("running")
        self.__button_mode_selector.setCurrentIndex(int(val))
        self.logger.debug("done")

    def get_name(self):
        return self.device_info

    def __set_texts(self):
        self.logger.debug("running")
        self.__config_label.setText("Current configuration:")
        self.__config_val_line_edit.setText("DIRECT CONTROL")
        self.__nhtsa_button.setText("NHTSA")
        self.__eblindfold_button.setText("eBlindfold")
        self.__direct_control_button.setText("Direct Control")
        self.__open_dur_label.setText("Open Duration")
        self.__open_inf_check_box.setText("INF")
        self.__close_dur_label.setText("Close Duration")
        self.__close_inf_check_box.setText("INF")
        self.__debounce_label.setText("Debounce Time")
        self.__button_mode_label.setText("Button Mode")
        self.__button_mode_selector.setItemText(0, "Hold")
        self.__button_mode_selector.setItemText(1, "Click")
        self.__upload_settings_button.setText("Upload settings")
        self.__manual_control_button.setText("Toggle Lens")
        self.logger.debug("done")

    def __set_tooltips(self):
        self.logger.debug("running")
        self.__config_label.setToolTip("Current device configuration")
        self.__config_val_line_edit.setToolTip("Enter custom config name here")
        self.__config_val_line_edit.setPlaceholderText("Custom config name")
        self.__nhtsa_button.setToolTip("Set Device to NHTSA standard")
        self.__eblindfold_button.setToolTip("Set Device to eBlindfold mode")
        self.__direct_control_button.setToolTip(
            "Set Device to Direct Control mode")
        self.__button_mode_label.setToolTip("CHANGEME")
        self.__open_dur_label.setToolTip("Range: " + str(vog_min_open_close) +
                                         "-" + str(vog_max_open_close))
        self.__close_dur_label.setToolTip("Range: " + str(vog_min_open_close) +
                                          "-" + str(vog_max_open_close))
        self.__debounce_label.setToolTip("Range: " + str(vog_debounce_min) +
                                         "-" + str(vog_debounce_max))
        self.__open_inf_check_box.setToolTip("Set to manual switching")
        self.__close_inf_check_box.setToolTip("Set to manual switching")
        self.__upload_settings_button.setToolTip(
            "Upload current configuration to device")
        self.__manual_control_button.setToolTip(
            "Manually open or close the lens")
        self.logger.debug("done")
Ejemplo n.º 21
0
class WidgetConfig(QGroupBox):
    def __init__(self):
        super(WidgetConfig, self).__init__()

        HEIGHT = 40

        grid = QGridLayout()

        # 使用默认摄像头复选框
        self.check_camera = QCheckBox('Use default camera')
        self.check_camera.setChecked(False)
        self.check_camera.stateChanged.connect(self.slot_check_camera)

        grid.addWidget(self.check_camera, 0, 0, 1, 3)  # 一行三列

        # 选择视频文件
        label_video = QLabel('Detect File')
        self.line_video = QLineEdit()
        if 'video' in GLOBAL.config:
            self.line_video.setText(GLOBAL.config['video'])
        self.line_video.setFixedHeight(HEIGHT)
        self.line_video.setEnabled(False)
        self.line_video.editingFinished.connect(
            lambda: GLOBAL.record_config({'video': self.line_video.text()}))

        self.btn_video = QPushButton('Choose')
        self.btn_video.setFixedHeight(HEIGHT)
        self.btn_video.setEnabled(False)
        self.btn_video.clicked.connect(self.choose_video_file)

        self.slot_check_camera()

        grid.addWidget(label_video, 1, 0)
        grid.addWidget(self.line_video, 1, 1)
        grid.addWidget(self.btn_video, 1, 2)

        # 选择权重文件
        label_weights = QLabel('Weights File')
        self.line_weights = QLineEdit()
        if 'weights' in GLOBAL.config:
            self.line_weights.setText(GLOBAL.config['weights'])
        self.line_weights.setFixedHeight(HEIGHT)
        self.line_weights.editingFinished.connect(lambda: GLOBAL.record_config(
            {'weights': self.line_weights.text()}))

        self.btn_weights = QPushButton('Choose')
        self.btn_weights.setFixedHeight(HEIGHT)
        self.btn_weights.clicked.connect(self.choose_weights_file)

        grid.addWidget(label_weights, 2, 0)
        grid.addWidget(self.line_weights, 2, 1)
        grid.addWidget(self.btn_weights, 2, 2)

        # 是否使用GPU
        label_device = QLabel('CUDA device')
        self.line_device = QLineEdit('gpu')
        if 'device' in GLOBAL.config:
            self.line_device.setText(GLOBAL.config['device'])
        else:
            self.line_device.setText('cpu')
        self.line_device.setPlaceholderText('cpu or 0 or 0,1,2,3')
        self.line_device.setFixedHeight(HEIGHT)
        self.line_device.editingFinished.connect(
            lambda: GLOBAL.record_config({'device': self.line_device.text()}))

        grid.addWidget(label_device, 3, 0)
        grid.addWidget(self.line_device, 3, 1, 1, 2)

        # 设置图像大小
        label_size = QLabel('Img Size')
        self.combo_size = QComboBox()
        self.combo_size.setFixedHeight(HEIGHT)
        self.combo_size.setStyleSheet(
            'QAbstractItemView::item {height: 40px;}')
        self.combo_size.setView(QListView())
        self.combo_size.addItem('320', 320)
        self.combo_size.addItem('416', 416)
        self.combo_size.addItem('480', 480)
        self.combo_size.addItem('544', 544)
        self.combo_size.addItem('640', 640)
        self.combo_size.setCurrentIndex(2)
        self.combo_size.currentIndexChanged.connect(
            lambda: GLOBAL.record_config(
                {'img_size': self.combo_size.currentData()}))

        grid.addWidget(label_size, 4, 0)
        grid.addWidget(self.combo_size, 4, 1, 1, 2)

        #choose net camera
        label_stream = QLabel('NetVedioStream')
        self.combo_stream = QComboBox()
        self.combo_stream.setFixedHeight(HEIGHT)
        self.combo_stream.setStyleSheet(
            'QAbstractItemView::item {height: 40px;}')
        self.combo_stream.setView(QListView())
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.65/',
                                  'rtsp://*****:*****@192.168.0.65/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.66/',
                                  'rtsp://*****:*****@192.168.0.66/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.67/',
                                  'rtsp://*****:*****@192.168.0.67/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.68/',
                                  'rtsp://*****:*****@192.168.0.68/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.65/',
                                  'rtsp://*****:*****@192.168.0.65/')
        self.combo_stream.setCurrentIndex(0)
        self.combo_stream.currentIndexChanged.connect(
            lambda: GLOBAL.record_config(
                {'netstreamvedio': self.combo_stream.currentData()}))

        grid.addWidget(label_stream, 5, 0)
        grid.addWidget(self.combo_stream, 5, 1, 1, 2)

        # 设置置信度阈值
        label_conf = QLabel('Confidence')
        self.spin_conf = QDoubleSpinBox()
        self.spin_conf.setFixedHeight(HEIGHT)
        self.spin_conf.setDecimals(1)
        self.spin_conf.setRange(0.1, 0.9)
        self.spin_conf.setSingleStep(0.1)
        if 'conf_thresh' in GLOBAL.config:
            self.spin_conf.setValue(GLOBAL.config['conf_thresh'])
        else:
            self.spin_conf.setValue(0.4)  # 默认值
            GLOBAL.record_config({'conf_thresh': 0.4})
        self.spin_conf.valueChanged.connect(lambda: GLOBAL.record_config(
            {'conf_thresh': round(self.spin_conf.value(), 1)}))

        grid.addWidget(label_conf, 6, 0)
        grid.addWidget(self.spin_conf, 6, 1, 1, 2)

        # 设置IOU阈值
        label_iou = QLabel('IOU')
        self.spin_iou = QDoubleSpinBox()
        self.spin_iou.setFixedHeight(HEIGHT)
        self.spin_iou.setDecimals(1)
        self.spin_iou.setRange(0.1, 0.9)
        self.spin_iou.setSingleStep(0.1)
        if 'iou_thresh' in GLOBAL.config:
            self.spin_iou.setValue(GLOBAL.config['iou_thresh'])
        else:
            self.spin_iou.setValue(0.5)  # 默认值
            GLOBAL.record_config({'iou_thresh': 0.5})
        self.spin_iou.valueChanged.connect(lambda: GLOBAL.record_config(
            {'iou_thresh': round(self.spin_iou.value(), 1)}))

        grid.addWidget(label_iou, 7, 0)
        grid.addWidget(self.spin_iou, 7, 1, 1, 2)

        # class-agnostic NMS
        self.check_agnostic = QCheckBox('Agnostic')
        if 'agnostic' in GLOBAL.config:
            self.check_agnostic.setChecked(GLOBAL.config['agnostic'])
        else:
            self.check_agnostic.setChecked(True)
        self.check_agnostic.stateChanged.connect(lambda: GLOBAL.record_config(
            {'agnostic': self.check_agnostic.isChecked()}))

        grid.addWidget(self.check_agnostic, 8, 0, 1, 3)  # 一行三列

        # augmented inference
        self.check_augment = QCheckBox('Augment')
        if 'augment' in GLOBAL.config:
            self.check_augment.setChecked(GLOBAL.config['augment'])
        else:
            self.check_augment.setChecked(True)
        self.check_augment.stateChanged.connect(lambda: GLOBAL.record_config(
            {'augment': self.check_augment.isChecked()}))

        grid.addWidget(self.check_augment, 9, 0, 1, 3)  # 一行三列

        self.setLayout(grid)  # 设置布局

    def slot_check_camera(self):
        check = self.check_camera.isChecked()
        GLOBAL.record_config({'use_camera': check})  # 保存配置
        if check:
            self.line_video.setEnabled(False)
            self.btn_video.setEnabled(False)
        else:
            self.line_video.setEnabled(True)
            self.btn_video.setEnabled(True)

    def choose_weights_file(self):
        """从系统中选择权重文件"""
        file = QFileDialog.getOpenFileName(
            self, "Pre-trained YOLOv5 Weights", "./",
            "Weights Files (*.pt);;All Files (*)")
        if file[0] != '':
            self.line_weights.setText(file[0])
            GLOBAL.record_config({'weights': file[0]})

    def choose_video_file(self):
        """从系统中选择视频文件"""
        file = QFileDialog.getOpenFileName(self, "Video Files", "./",
                                           "Video Files (*)")
        if file[0] != '':
            self.line_video.setText(file[0])
            GLOBAL.record_config({'video': file[0]})

    def save_config(self):
        """保存当前的配置到配置文件"""
        config = {
            'use_camera': self.check_camera.isChecked(),
            'video': self.line_video.text(),
            'weights': self.line_weights.text(),
            'device': self.line_device.text(),
            'img_size': self.combo_size.currentData(),
            'conf_thresh': round(self.spin_conf.value(), 1),
            'iou_thresh': round(self.spin_iou.value(), 1),
            'agnostic': self.check_agnostic.isChecked(),
            'augment': self.check_augment.isChecked(),
            'netstreamvedio': self.combo_stream.currentData()
        }
        GLOBAL.record_config(config)
Ejemplo n.º 22
0
class LimitOptionsView(QWidget):
    """View which displays options for limiting they type of files to work with.

    Attributes:
        layout (QVBoxLayout): Main layout for view.
        frame (QFrame): Frame around limit options.
        frame_layout (QHBoxLayout): Layout associated with frame.
        title (QLabel): Title associated with view.
        limit_type_cb (QCheckBox): CheckBox which controls if view should be limited by file type.
        limit_type (QLineEdit): File type to limit to.
        search_cb (QCheckBox): CheckBox which controls if the view should limit by a search word.
        search (QLineEdit): Word to search for when renaming.
    """
    def __init__(self):
        super(LimitOptionsView, self).__init__()
        self.layout = QVBoxLayout()
        self.title = QLabel(prefs.TITLE)
        self.frame_layout = QHBoxLayout()
        self.frame = QFrame()
        self.limit_type_cb = QCheckBox(prefs.LIMIT)
        self.limit_type = QLineEdit(prefs.LIMIT_DEFAULT)
        self.search_cb = QCheckBox(prefs.SEARCH)
        self.search = QLineEdit(prefs.SEARCH_DEFAULT)

        self._configure()

    def _configure(self) -> None:
        """Configure LimitOptionsView."""
        self.frame.setLayout(self.frame_layout)
        self.layout.setAlignment(Qt.AlignLeft)
        self.limit_type_cb.setToolTip(prefs.LIMIT_TOOLTIP)
        self.search_cb.setToolTip(prefs.SEARCH_TOOLTIP)

        self.frame_layout.addWidget(self.limit_type_cb)
        self.frame_layout.addWidget(self.limit_type)
        self.frame_layout.addSpacerItem(QSpacerItem(*prefs.ITEM_SPACING))
        self.frame_layout.addWidget(self.search_cb)
        self.frame_layout.addWidget(self.search)
        self.layout.addWidget(self.title)
        self.layout.addWidget(self.frame)
        self.setLayout(self.layout)

    def disable_limit_type(self) -> None:
        """Disable limit type functionality."""
        self.limit_type.setDisabled(True)

    def disable_search(self) -> None:
        """Disable search functionality."""
        self.search.setDisabled(True)

    def enable_limit_type(self) -> None:
        """Enable limit type functionality."""
        self.limit_type.setEnabled(True)

    def enable_search(self) -> None:
        """Enable limit type functionality."""
        self.limit_type.setEnabled(True)

    def get_limit_type(self) -> str:
        """Return the limit type."""
        return str(self.limit_type.text())

    def get_do_limit_type(self) -> bool:
        """Return if end user wants to limit the file type."""
        return self.limit_type_cb.isChecked()

    def get_search(self) -> str:
        """Return the search value."""
        return str(self.search.text())

    def get_do_search(self) -> bool:
        """Return if the end user wants to limit files by a search."""
        return self.search_cb.isChecked()

    def set_disabled(self) -> None:
        """Disable View."""
        self.setDisabled(True)

    def set_enable(self) -> None:
        """Enable View."""
        self.setEnabled(True)

    def set_limit_type(self, value: str) -> None:
        """Set the value in the limit type."""
        self.limit_type.setText(value)

    def set_limit_type_style(self, style: str) -> None:
        """Set the style applied to limit type."""
        self.limit_type.setStyleSheet(style)

    def set_search(self, value: str) -> None:
        """Set the value in the search."""
        self.search.setText(value)

    def set_search_style(self, style: str) -> None:
        """Set the style applied to search."""
        self.search.setStyleSheet(style)
Ejemplo n.º 23
0
class MuxSettingTab(QWidget):
    tab_clicked_signal = Signal()
    start_muxing_signal = Signal()
    update_task_bar_progress_signal = Signal(int)
    update_task_bar_paused_signal = Signal()
    update_task_bar_clear_signal = Signal()

    def __init__(self):
        super().__init__()
        self.create_widgets()
        self.setup_widgets()
        self.connect_signals()

    def connect_signals(self):
        self.tab_clicked_signal.connect(self.tab_clicked)

        self.destination_path_button.clicked.connect(self.open_select_destination_folder_dialog)

        self.only_keep_those_audios_checkBox.stateChanged.connect(
            self.only_keep_those_audios_multi_choose_comboBox.check_box_state_changed)

        self.only_keep_those_subtitles_checkBox.stateChanged.connect(
            self.only_keep_those_subtitles_multi_choose_comboBox.check_box_state_changed)

        self.make_this_audio_default_checkBox.disable_combo_box.connect(self.disable_make_this_audio_default_comboBox)

        self.make_this_subtitle_default_checkBox.disable_combo_box.connect(
            self.disable_make_this_subtitle_default_comboBox)

        self.control_queue_button.add_to_queue_clicked_signal.connect(self.add_to_queue_button_clicked)
        self.control_queue_button.start_multiplexing_clicked_signal.connect(self.start_multiplexing_button_clicked)
        self.control_queue_button.pause_multiplexing_clicked_signal.connect(self.pause_multiplexing_button_clicked)

        self.clear_job_queue_button.clicked.connect(self.clear_job_queue_button_clicked)

        self.only_keep_those_audios_multi_choose_comboBox.closeList.connect(self.only_keep_those_audios_close_list)

        self.only_keep_those_subtitles_multi_choose_comboBox.closeList.connect(
            self.only_keep_those_subtitles_close_list)

        self.make_this_audio_default_comboBox.currentTextChanged.connect(
            self.make_this_audio_default_comboBox_text_changed)

        self.make_this_subtitle_default_comboBox.currentTextChanged.connect(
            self.make_this_subtitle_default_comboBox_text_changed)

        self.abort_on_errors_checkBox.stateChanged.connect(self.abort_on_errors_state_changed)

        self.keep_log_file_checkBox.stateChanged.connect(self.keep_log_file_state_changed)
        self.job_queue_layout.update_task_bar_progress_signal.connect(self.update_task_bar_progress)
        self.job_queue_layout.paused_done_signal.connect(self.paused_done)
        self.job_queue_layout.cancel_done_signal.connect(self.cancel_done)
        self.job_queue_layout.finished_all_jobs_signal.connect(self.finished_all_jobs)
        self.job_queue_layout.pause_from_error_occurred_signal.connect(self.pause_multiplexing_button_clicked)

    def setup_widgets(self):
        self.setup_mux_setting_groupBox()
        self.setup_job_queue_groupBox()
        self.setup_destination_path_label()
        self.setup_destination_path_lineEdit()
        self.setup_destination_path_button()
        self.setup_abort_on_errors_checkBox()
        self.setup_discard_old_attachments_checkBox()
        self.setup_keep_log_file_checkBox()
        self.setup_clear_job_queue_button()
        self.setup_tool_tip_hint()
        self.setup_layouts()

    def setup_layouts(self):
        self.setup_MainLayout()
        self.mux_setting_groupBox.setLayout(self.mux_setting_layout)
        self.job_queue_groupBox.setLayout(self.job_queue_layout)
        self.setup_mux_tools_layout_first_row()
        self.setup_mux_tools_layout_second_row()
        self.setup_mux_setting_layout()
        self.setLayout(self.MainLayout)

    # noinspection PyAttributeOutsideInit
    def create_widgets(self):
        self.MainLayout = QVBoxLayout()
        self.mux_setting_groupBox = QGroupBox(self)
        self.job_queue_groupBox = QGroupBox(self)
        self.mux_setting_layout = QGridLayout()
        self.job_queue_layout = JobQueueLayout()
        self.destination_path_label = QLabel()
        self.destination_path_lineEdit = QLineEdit()
        self.destination_path_button = QPushButton()
        self.only_keep_those_audios_checkBox = OnlyKeepThoseAudiosCheckBox()
        self.only_keep_those_subtitles_checkBox = OnlyKeepThoseSubtitlesCheckBox()
        self.only_keep_those_audios_multi_choose_comboBox = AudioTracksCheckableComboBox()
        self.only_keep_those_subtitles_multi_choose_comboBox = SubtitleTracksCheckableComboBox()
        self.make_this_audio_default_checkBox = MakeThisAudioDefaultCheckBox()
        self.make_this_subtitle_default_checkBox = MakeThisSubtitleDefaultCheckBox()
        self.make_this_audio_default_comboBox = MakeThisTrackDefaultComboBox()
        self.make_this_subtitle_default_comboBox = MakeThisTrackDefaultComboBox()
        self.abort_on_errors_checkBox = QCheckBox()
        self.discard_old_attachments_checkBox = QCheckBox()
        self.keep_log_file_checkBox = QCheckBox()
        self.control_queue_button = ControlQueueButton()
        self.clear_job_queue_button = QPushButton()
        self.mux_tools_layout_first_row = QHBoxLayout()
        self.mux_tools_layout_second_row = QHBoxLayout()
        self.job_queue_tools_layout = QHBoxLayout()

    def setup_mux_setting_layout(self):
        self.mux_setting_layout.addWidget(self.destination_path_label, 0, 0)
        self.mux_setting_layout.addWidget(self.destination_path_lineEdit, 0, 1)
        self.mux_setting_layout.addWidget(self.destination_path_button, 0, 2)
        self.mux_setting_layout.addWidget(self.only_keep_those_audios_checkBox, 1, 0)
        self.mux_setting_layout.addWidget(self.only_keep_those_subtitles_checkBox, 2, 0)
        self.mux_setting_layout.addLayout(self.mux_tools_layout_first_row, 1, 1)
        self.mux_setting_layout.addLayout(self.mux_tools_layout_second_row, 2, 1)

    def setup_mux_tools_layout_first_row(self):
        self.mux_tools_layout_first_row.addWidget(self.only_keep_those_audios_multi_choose_comboBox, 2)
        self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_checkBox, 1)
        self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_comboBox, 2)
        self.mux_tools_layout_first_row.addWidget(self.abort_on_errors_checkBox, 1)
        self.mux_tools_layout_first_row.addWidget(self.keep_log_file_checkBox)

    def setup_mux_tools_layout_second_row(self):
        self.mux_tools_layout_second_row.addWidget(self.only_keep_those_subtitles_multi_choose_comboBox, 2)
        self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_checkBox, 1)
        self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_comboBox, 2)
        self.mux_tools_layout_second_row.addWidget(self.control_queue_button, 1)
        self.mux_tools_layout_second_row.addWidget(self.clear_job_queue_button, 1)

    def setup_clear_job_queue_button(self):
        self.clear_job_queue_button.setText("Clear All")
        self.clear_job_queue_button.setIcon(GlobalFiles.CleanIcon)
        self.clear_job_queue_button.setDisabled(True)

    def setup_keep_log_file_checkBox(self):
        self.keep_log_file_checkBox.setText("Keep Log File")
        self.keep_log_file_checkBox.setToolTip("log file will located in the source folder after finished muxing")

    def setup_discard_old_attachments_checkBox(self):
        self.discard_old_attachments_checkBox.setText("Discard Old Attachments ")

    def setup_abort_on_errors_checkBox(self):
        self.abort_on_errors_checkBox.setText("Abort On Errors")
        self.abort_on_errors_checkBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)

    def setup_destination_path_button(self):
        self.destination_path_button.setIcon(GlobalFiles.SelectFolderIcon)

    def setup_destination_path_lineEdit(self):
        self.destination_path_lineEdit.setPlaceholderText("Enter Destination Folder Path")
        self.destination_path_lineEdit.setClearButtonEnabled(True)

    def setup_destination_path_label(self):
        self.destination_path_label.setText("Videos Destination Folder :")

    def setup_MainLayout(self):
        self.MainLayout.addWidget(self.mux_setting_groupBox)
        self.MainLayout.addWidget(self.job_queue_groupBox)

    def setup_job_queue_groupBox(self):
        self.job_queue_groupBox.setTitle("Job Queue")

    def setup_mux_setting_groupBox(self):
        self.mux_setting_groupBox.setTitle("Mux Setting")

    def paintEvent(self, event: QPaintEvent):
        self.update_widgets_size()
        super().paintEvent(event)

    def resizeEvent(self, event: QResizeEvent):
        self.job_queue_layout.update_layout()
        super().resizeEvent(event)

    def update_widgets_size(self):
        self.only_keep_those_subtitles_multi_choose_comboBox.resize(
            self.only_keep_those_audios_multi_choose_comboBox.width(),
            self.only_keep_those_audios_multi_choose_comboBox.height(),
        )

        self.make_this_subtitle_default_checkBox.resize(
            self.make_this_audio_default_checkBox.width(),
            self.make_this_audio_default_checkBox.height(),
        )
        self.make_this_subtitle_default_checkBox.move(
            self.make_this_audio_default_checkBox.x(),
            self.make_this_subtitle_default_checkBox.y(),
        )

        self.make_this_subtitle_default_comboBox.resize(
            self.make_this_audio_default_comboBox.width(),
            self.make_this_audio_default_comboBox.height(),
        )
        self.make_this_subtitle_default_comboBox.move(
            self.make_this_audio_default_comboBox.x(),
            self.make_this_subtitle_default_comboBox.y(),
        )

        self.control_queue_button.move(
            self.abort_on_errors_checkBox.x(),
            self.control_queue_button.y(),
        )

        self.clear_job_queue_button.move(
            self.control_queue_button.x() + self.control_queue_button.width() + 5,
            self.clear_job_queue_button.y(),
        )

    def open_select_destination_folder_dialog(self):
        temp_folder_path = QFileDialog.getExistingDirectory(self, caption="Choose Destination Folder",
                                                            dir=GlobalSetting.LAST_DIRECTORY_PATH, )
        if temp_folder_path == "" or temp_folder_path.isspace():
            return
        elif Path(temp_folder_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH):
            invalid_dialog = InvalidPathDialog(
                error_message="Source and destination videos can't be in the same folder")
            invalid_dialog.execute()
            return
        else:
            self.destination_path_lineEdit.setText(str(Path(temp_folder_path)))
            GlobalSetting.LAST_DIRECTORY_PATH = self.destination_path_lineEdit.text()
            GlobalSetting.DESTINATION_FOLDER_PATH = self.destination_path_lineEdit.text()

    def check_destination_path(self):
        temp_destination_path = self.destination_path_lineEdit.text()
        try:
            if temp_destination_path == "" or temp_destination_path.isspace():
                temp_destination_path = "[Empty Path]"
                raise Exception(
                    "[WinError 998] Empty path is Not a valid path : " + temp_destination_path)
            # check if system is windows so path must have # SOME_LETTER:\
            if os.name == 'nt':
                if temp_destination_path[1:3] != ":\\" and self.destination_path_lineEdit.text()[
                                                           1:3] != ":/":
                    raise Exception("[WinError 999] Not a valid path : " + temp_destination_path)
            makedirs(temp_destination_path, exist_ok=True)
            ## test if i can write into this path:
            test_file_name = str(time.time()) + ".txt"
            test_file_name_absolute = os.path.join(Path(temp_destination_path), Path(test_file_name))
            try:
                with open(test_file_name_absolute, 'w+') as test_file:
                    test_file.write("Test")
                os.remove(test_file_name_absolute)
            except Exception as e:
                write_to_log_file(e)
                invaild_dialog = InvalidPathDialog(window_title="Permission Denied",
                                                   error_message="MKV Muxing Batch GUI lacks write "
                                                                 "permissions on Destination folder")
                invaild_dialog.execute()
                self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
                return False
        except Exception as e:
            write_to_log_file(e)
            error_message = ""
            if temp_destination_path == "[Empty Path]":
                error_message = "Enter a valid destination path"
            else:
                error_message = temp_destination_path + "\nisn't a valid path!"
            invalid_dialog = InvalidPathDialog(error_message=error_message)
            invalid_dialog.execute()
            self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
            return False
        if Path(temp_destination_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH):
            invalid_dialog = InvalidPathDialog(
                error_message="Source and destination videos can't be in the same folder")
            invalid_dialog.execute()
            self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
            return False
        GlobalSetting.DESTINATION_FOLDER_PATH = temp_destination_path
        return True

    def setup_tool_tip_hint(self):
        self.only_keep_those_subtitles_multi_choose_comboBox.set_tool_tip_hint()
        self.only_keep_those_audios_multi_choose_comboBox.set_tool_tip_hint()
        self.make_this_subtitle_default_checkBox.set_tool_tip_hint_no_check()
        self.make_this_audio_default_checkBox.set_tool_tip_hint_no_check()

    def add_to_queue_button_clicked(self):
        self.job_queue_layout.setup_queue()
        self.enable_muxing_setting()
        if not GlobalSetting.JOB_QUEUE_EMPTY:
            self.disable_editable_widgets()
            self.control_queue_button.set_state_start_multiplexing()
            self.clear_job_queue_button.setDisabled(False)
            change_global_LogFilePath()
        else:
            self.enable_editable_widgets()
            self.setup_enable_options_for_mkv_only_options()

    def tab_clicked(self):
        self.job_queue_layout.show_necessary_table_columns()
        self.setup_enable_options_for_mkv_only_options()

    def setup_enable_options_for_mkv_only_options(self):
        if GlobalSetting.JOB_QUEUE_EMPTY:
            if GlobalSetting.VIDEO_SOURCE_MKV_ONLY:
                self.only_keep_those_audios_checkBox.setEnabled(True)
                self.only_keep_those_subtitles_checkBox.setEnabled(True)
                self.make_this_audio_default_checkBox.setEnabled(True)
                self.make_this_subtitle_default_checkBox.setEnabled(True)
                self.only_keep_those_audios_checkBox.setToolTip("")
                self.only_keep_those_subtitles_checkBox.setToolTip("")
                self.make_this_audio_default_comboBox.setToolTip("")
                self.make_this_subtitle_default_comboBox.setToolTip("")
                self.setup_tool_tip_hint()
            else:

                self.only_keep_those_subtitles_checkBox.setCheckState(Qt.Unchecked)
                self.only_keep_those_audios_checkBox.setCheckState(Qt.Unchecked)
                self.make_this_audio_default_checkBox.setCheckState(Qt.Unchecked)
                self.make_this_subtitle_default_checkBox.setCheckState(Qt.Unchecked)

                self.only_keep_those_audios_checkBox.setEnabled(False)
                self.only_keep_those_subtitles_checkBox.setEnabled(False)
                self.make_this_audio_default_checkBox.setEnabled(False)
                self.make_this_subtitle_default_checkBox.setEnabled(False)
                self.only_keep_those_audios_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                "are Mkv only")
                self.only_keep_those_subtitles_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                   "are Mkv only")

                self.make_this_audio_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                 "are Mkv only")

                self.make_this_subtitle_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                    "are Mkv only")
                self.make_this_audio_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                 "are Mkv only")
                self.make_this_subtitle_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                    "are Mkv only")
                self.only_keep_those_audios_multi_choose_comboBox.setToolTip(
                    "<b>[Disabled]</b> Only works when video files "
                    "are Mkv only")
                self.only_keep_those_subtitles_multi_choose_comboBox.setToolTip(
                    "<b>[Disabled]</b> Only works when video files "
                    "are Mkv only")

    def clear_job_queue_button_clicked(self):
        self.job_queue_layout.clear_queue()
        self.control_queue_button.set_state_add_to_queue()
        self.clear_job_queue_button.setDisabled(True)
        self.control_queue_button.setDisabled(False)
        self.enable_editable_widgets()
        self.enable_muxing_setting()
        self.setup_enable_options_for_mkv_only_options()
        self.update_task_bar_clear_signal.emit()

    def disable_editable_widgets(self):
        self.only_keep_those_subtitles_checkBox.setEnabled(False)
        self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled(False)
        self.only_keep_those_audios_checkBox.setEnabled(False)
        self.only_keep_those_audios_multi_choose_comboBox.setEnabled(False)
        self.make_this_subtitle_default_checkBox.setEnabled(False)
        self.make_this_subtitle_default_comboBox.setEnabled(False)
        self.make_this_audio_default_checkBox.setEnabled(False)
        self.make_this_audio_default_comboBox.setEnabled(False)

    def enable_editable_widgets(self):
        self.only_keep_those_subtitles_checkBox.setEnabled(True)
        self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled(
            self.only_keep_those_subtitles_checkBox.isChecked())
        self.only_keep_those_audios_checkBox.setEnabled(True)
        self.only_keep_those_audios_multi_choose_comboBox.setEnabled(self.only_keep_those_audios_checkBox.isChecked())
        self.make_this_subtitle_default_checkBox.setEnabled(True)
        self.make_this_subtitle_default_comboBox.setEnabled(self.make_this_subtitle_default_checkBox.isChecked())
        self.make_this_audio_default_checkBox.setEnabled(True)
        self.make_this_audio_default_comboBox.setEnabled(self.make_this_audio_default_checkBox.isChecked())

    def only_keep_those_audios_close_list(self):
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_LANGUAGES = self.only_keep_those_audios_multi_choose_comboBox.languages
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_TRACKS = self.only_keep_those_audios_multi_choose_comboBox.tracks

    def only_keep_those_subtitles_close_list(self):
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_LANGUAGES = self.only_keep_those_subtitles_multi_choose_comboBox.languages
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_TRACKS = self.only_keep_those_subtitles_multi_choose_comboBox.tracks

    def disable_make_this_subtitle_default_comboBox(self, state):
        self.make_this_subtitle_default_comboBox.setDisabled(state)
        if state:
            self.make_this_subtitle_default_comboBox.setCurrentIndex(-1)

    def disable_make_this_audio_default_comboBox(self, state):
        self.make_this_audio_default_comboBox.setDisabled(state)
        if state:
            self.make_this_audio_default_comboBox.setCurrentIndex(-1)

    def make_this_audio_default_comboBox_text_changed(self):
        GlobalSetting.MUX_SETTING_MAKE_THIS_AUDIO_DEFAULT_TRACK = str(
            self.make_this_audio_default_comboBox.currentText())

    def make_this_subtitle_default_comboBox_text_changed(self):
        GlobalSetting.MUX_SETTING_MAKE_THIS_SUBTITLE_DEFAULT_TRACK = str(
            self.make_this_subtitle_default_comboBox.currentText())

    def update_task_bar_progress(self, new_progress):
        self.update_task_bar_progress_signal.emit(new_progress)

    def enable_muxing_setting(self):
        self.destination_path_lineEdit.setEnabled(True)
        self.destination_path_button.setEnabled(True)
        self.abort_on_errors_checkBox.setEnabled(True)
        self.keep_log_file_checkBox.setEnabled(True)

    def disable_muxing_setting(self):
        self.destination_path_lineEdit.setEnabled(False)
        self.destination_path_button.setEnabled(False)
        self.abort_on_errors_checkBox.setEnabled(False)
        self.keep_log_file_checkBox.setEnabled(False)

    @staticmethod
    def abort_on_errors_state_changed(state):
        GlobalSetting.MUX_SETTING_ABORT_ON_ERRORS = bool(state)

    @staticmethod
    def keep_log_file_state_changed(state):
        GlobalSetting.MUX_SETTING_KEEP_LOG_FILE = bool(state)

    def start_multiplexing_button_clicked(self):
        at_least_one_muxing_setting_has_been_selected = check_if_at_least_one_muxing_setting_has_been_selected()
        if at_least_one_muxing_setting_has_been_selected:
            destination_path_valid = self.check_destination_path()
            if destination_path_valid:
                self.setup_log_file()
                self.control_queue_button.set_state_pause_multiplexing()
                self.disable_muxing_setting()
                self.job_queue_layout.start_muxing()
                self.start_muxing_signal.emit()
                self.clear_job_queue_button.setDisabled(True)

    def pause_multiplexing_button_clicked(self):
        self.job_queue_layout.pause_muxing()
        self.control_queue_button.setDisabled(True)
        self.control_queue_button.set_state_pausing_multiplexing()

    def paused_done(self):
        self.control_queue_button.set_state_resume_multiplexing()
        self.clear_job_queue_button.setDisabled(False)
        self.control_queue_button.setDisabled(False)
        self.update_task_bar_paused_signal.emit()

    def cancel_done(self):
        self.disable_editable_widgets()
        self.enable_muxing_setting()
        self.control_queue_button.set_state_start_multiplexing()
        self.clear_job_queue_button.setDisabled(False)
        change_global_LogFilePath()

    def finished_all_jobs(self):
        self.enable_editable_widgets()
        self.enable_muxing_setting()
        self.setup_enable_options_for_mkv_only_options()
        self.control_queue_button.set_state_start_multiplexing()
        self.control_queue_button.setDisabled(True)
        self.clear_job_queue_button.setDisabled(False)
        self.update_task_bar_clear_signal.emit()
        GlobalSetting.JOB_QUEUE_EMPTY = True
        check_if_want_to_keep_log_file()

    def setup_log_file(self):
        if self.control_queue_button.state == "START":
            open(GlobalFiles.LogFilePath, 'w+').close()
Ejemplo n.º 24
0
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.setWindowTitle('RetroUFO')

        # Create widgets
        self.chkboxPlatformDetect = QCheckBox('Platform Auto-Detect')
        self.chkboxPlatformDetect.setChecked(True)
        self.chkboxPlatformDetect.stateChanged.connect(self.auto_detect)

        self.cmbboxPlatform = QComboBox()
        self.cmbboxPlatform.setEnabled(False)
        self.cmbboxPlatform.setEditable(False)
        self.cmbboxPlatform.addItem('Linux')
        self.cmbboxPlatform.addItem('macOS')
        self.cmbboxPlatform.addItem('Windows')

        self.cmbboxArchitecture = QComboBox()
        self.cmbboxArchitecture.setEnabled(False)
        self.cmbboxArchitecture.setEditable(False)
        self.cmbboxArchitecture.addItem('x86')
        self.cmbboxArchitecture.addItem('x86_64')

        self.chkboxLocationDetect = QCheckBox('Core Location Auto-Detect')
        self.chkboxLocationDetect.setChecked(True)
        self.chkboxLocationDetect.stateChanged.connect(self.auto_location)

        self.leditCoreLocation = QLineEdit('')
        self.leditCoreLocation.setEnabled(False)

        self.btnCoreLocation = QPushButton('...')
        self.btnCoreLocation.setEnabled(False)
        self.btnCoreLocation.clicked.connect(self.choose_location)

        self.teditLog = QTextEdit()
        self.teditLog.setReadOnly(True)

        self.tcsrLog = QTextCursor(self.teditLog.document())

        self.chkboxKeepDownload = QCheckBox('Keep Downloaded Cores')
        self.chkboxKeepDownload.setChecked(False)

        self.btnGrabCores = QPushButton('Grab Cores')
        self.btnGrabCores.clicked.connect(self.grab_cores)

        # Create layout and add widgets
        self.formLayout = QVBoxLayout()
        self.formLayout.addWidget(self.chkboxPlatformDetect)
        self.formLayout.addWidget(self.cmbboxPlatform)
        self.formLayout.addWidget(self.cmbboxArchitecture)
        self.formLayout.addWidget(self.chkboxLocationDetect)
        self.formLayout.addWidget(self.leditCoreLocation)
        self.formLayout.addWidget(self.btnCoreLocation)
        self.formLayout.addWidget(self.teditLog)
        self.formLayout.addWidget(self.chkboxKeepDownload)
        self.formLayout.addWidget(self.btnGrabCores)

        # Set dialog layout
        self.setLayout(self.formLayout)

    def auto_detect(self):
        if self.chkboxPlatformDetect.isChecked():
            self.cmbboxPlatform.setEnabled(False)
            self.cmbboxArchitecture.setEnabled(False)
        else:
            self.cmbboxPlatform.setEnabled(True)
            self.cmbboxArchitecture.setEnabled(True)

    def auto_location(self):
        if self.chkboxLocationDetect.isChecked():
            self.leditCoreLocation.setEnabled(False)
            self.btnCoreLocation.setEnabled(False)
        else:
            self.leditCoreLocation.setEnabled(True)
            self.btnCoreLocation.setEnabled(True)

    def choose_location(self):
        directory = QFileDialog.getExistingDirectory(self,
                                                     'Choose Target Location',
                                                     os.path.expanduser('~'))

        self.leditCoreLocation.insert(directory)

    def update_log(self, _info):
        self.teditLog.insertPlainText('{}\n'.format(_info))

        # Auto scrolling on log UI
        self.teditLog.moveCursor(QTextCursor.End)

    def lock_ui(self, _lock):
        # Cycle through each widget and disable it except for log UI
        widgets = (self.formLayout.itemAt(i).widget()
                   for i in range(self.formLayout.count()))
        for widget in widgets:
            if isinstance(widget, QTextEdit):
                pass
            else:
                widget.setDisabled(_lock)
                # Have to run these to make sure only the correct things unlock after grab thread
                self.auto_detect()
                self.auto_location()

    def grab_cores(self):
        """ Where the magic happens """
        if not self.chkboxKeepDownload.isChecked():
            self.clean_up()

        target_platform = self.get_platform()
        architecture = self.get_architecture()
        location = self.get_location()

        self.grab = GrabThread(target_platform, architecture, location)
        self.grab.add_to_log.connect(self.update_log)
        self.grab.lock.connect(self.lock_ui)
        self.grab.start()

    def get_platform(self):
        """ Gets the Platform and Architecture if not supplied """

        if not self.chkboxPlatformDetect.isChecked():
            if self.cmbboxPlatform.currentText() == 'macOS':
                return 'apple/osx'  # macOS
            else:
                return self.cmbboxPlatform.currentText().lower()
        else:
            if platform.system() == 'Linux':
                return 'linux'
            elif platform.system() == 'Darwin':  # macOS
                return 'apple/osx'
            elif platform.system(
            ) == 'Windows' or 'MSYS_NT' in platform.system(
            ):  # Checks for MSYS environment as well
                return 'windows'
            else:
                msgBox = QMessageBox.warning(
                    self, 'Error', 'Platform not found or supported!',
                    QMessageBox.Ok)
                msgBox.exec_()

    def get_architecture(self):
        """ Gets the Platform and Architecture if not supplied """

        if '64' in platform.architecture()[0]:
            return 'x86_64'

        elif '32' in platform.architecture()[0]:
            return 'x86'
        else:
            msgBox = QMessageBox.warning(
                self, 'Error', 'Architecture not found or supported',
                QMessageBox.Ok)
            msgBox.exec_()

    def get_location(self):
        if not self.chkboxLocationDetect.isChecked():
            return self.leditCoreLocation.text()
        else:
            return CORE_LOCATION[self.get_platform()]

    def clean_up(self):
        """ Removes all the downloaded files """
        if os.path.isdir('cores'):
            rmtree('cores/')
Ejemplo n.º 25
0
class BrowserWin(QWidget):
    def __init__(self, *args, **kwargs):

        super(BrowserWin, self).__init__(*args, **kwargs)

        # parent Maya window
        self.setParent(mainWindow)
        self.setWindowFlags(Qt.Window)
        # Window settings
        self.setWindowTitle('AC_AssetBrowser')

        # Build window
        self.mainLayout = QVBoxLayout()
        self.btnLayout = QHBoxLayout()
        self.radioLayout = QHBoxLayout()

        # radio buttons load import
        self.radioLabel = QLabel("Action: ")
        self.importRadioBtn = QRadioButton("Import File")
        self.openRadioBtn = QRadioButton("Open File")
        self.saveRadioBtn = QRadioButton("Save File")

        # Find asset directories to load from and populate the drop down
        self.fileType = QComboBox()
        self.__populate_list(self.fileType)
        self.curr_cat = self.fileType.currentText()

        # list of assets in self.list
        self.fileList = QListWidget()
        self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

        self.fileName = QLineEdit()

        self.loadBtn = QPushButton("Load Asset")
        self.publishBtn = QPushButton("Publish")
        self.closeBtn = QPushButton("Close")

        # Add widgets to layouts
        self.radioLayout.addWidget(self.radioLabel)
        self.radioLayout.addWidget(self.importRadioBtn)
        self.radioLayout.addWidget(self.openRadioBtn)
        self.radioLayout.addWidget(self.saveRadioBtn)

        self.mainLayout.addLayout(self.radioLayout)

        self.mainLayout.addWidget(self.fileType)
        self.mainLayout.addWidget(self.fileList)
        self.mainLayout.addWidget(self.fileName)

        self.btnLayout.addWidget(self.loadBtn)
        self.btnLayout.addWidget(self.publishBtn)
        self.btnLayout.addWidget(self.closeBtn)

        self.mainLayout.addLayout(self.btnLayout)
        self.setLayout(self.mainLayout)

        # Set state of widgets
        self.importRadioBtn.toggle()
        self.fileName.setPlaceholderText("file_name")
        self.fileName.setEnabled(False)
        self.publishBtn.setEnabled(False)

        # Signals
        self.fileType.currentIndexChanged.connect(self.selectionChanged)
        self.loadBtn.clicked.connect(self.loadBtnCmd)
        self.publishBtn.clicked.connect(self.publishBtnCmd)
        self.closeBtn.clicked.connect(self.closeBtnCmd)
        self.importRadioBtn.toggled.connect(self.onImportToggled)
        self.openRadioBtn.toggled.connect(self.onOpenToggled)
        self.saveRadioBtn.toggled.connect(self.onSaveToggled)

    def __populate_list(self, destination, directory=DIRECTORY):
        _dirs = os.listdir(directory)
        _items = [_dir for _dir in _dirs]

        return destination.addItems(_items)

    def selectionChanged(self):
        self.curr_cat = self.fileType.currentText()
        self.fileList.clear()
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

    def loadBtnCmd(self):
        if self.importRadioBtn.isChecked():
            selected_files = self.fileList.selectedItems()
            for _file in selected_files:
                asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                          _file.text())
                cmds.file(asset_file, i=True)
        elif self.openRadioBtn.isChecked():
            selected_file = self.fileList.currentItem()
            asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                      selected_file.text())
            cmds.file(asset_file, o=True, force=True)
        else:
            print("Did you mean to publish this asset?")

    def publishBtnCmd(self):
        if self.saveRadioBtn.isChecked() and self.fileName.text() is not None:
            path_to_save = os.path.join(DIRECTORY, self.curr_cat,
                                        self.fileName.text())
            cmds.file(rn="{}.ma".format(path_to_save))
            cmds.file(save=True)
            self.fileList.clear()
            self.__populate_list(self.fileList,
                                 directory=os.path.join(
                                     DIRECTORY, self.curr_cat))

    def closeBtnCmd(self):
        self.close()

    def onSaveToggled(self):
        items = self.fileList.selectedItems()
        for item in items:
            item.setSelected(False)
        self.fileName.setEnabled(not self.fileName.isEnabled())
        self.publishBtn.setEnabled(not self.publishBtn.isEnabled())

    def onImportToggled(self):
        if self.importRadioBtn.isChecked():
            self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def onOpenToggled(self):
        if self.openRadioBtn.isChecked():
            items = self.fileList.selectedItems()
            items.pop()
            for item in items:
                item.setSelected(False)
            self.fileList.setSelectionMode(QAbstractItemView.SingleSelection)
Ejemplo n.º 26
0
class VideoDeck(QWidget):
    def __init__(self, vlc_instance=None):
        QWidget.__init__(self)
        self.layout = QHBoxLayout()

        self.setAcceptDrops(True)

        self.loaded_video = None
        self.vlc_instance = vlc_instance

        self.file_picker_field = FilePicker()

        self.info_layout = QGridLayout()

        vod_filepath_label = QLabel("VOD Filepath")
        id_twitch_label = QLabel("ID Twitch")
        created_at_label = QLabel("Created at")
        duration_label = QLabel("Duration")
        title_label = QLabel("Title")
        streamer_label = QLabel("Streamer")

        self.id_twitch_field = QLineEdit()
        self.created_at_field = QLineEdit()
        self.duration_field = QLineEdit()
        self.title_field = QLineEdit()
        self.streamer_field = QLineEdit()

        self.id_twitch_field.setEnabled(False)
        self.created_at_field.setEnabled(False)
        self.duration_field.setEnabled(False)
        self.title_field.setEnabled(False)
        self.streamer_field.setEnabled(False)

        self.info_layout.addWidget(vod_filepath_label, 0, 0)
        self.info_layout.addWidget(id_twitch_label, 1, 0)
        self.info_layout.addWidget(created_at_label, 2, 0)
        self.info_layout.addWidget(duration_label, 3, 0)
        self.info_layout.addWidget(title_label, 4, 0)
        self.info_layout.addWidget(streamer_label, 5, 0)

        self.info_layout.addWidget(self.file_picker_field, 0, 1)
        self.info_layout.addWidget(self.id_twitch_field, 1, 1)
        self.info_layout.addWidget(self.created_at_field, 2, 1)
        self.info_layout.addWidget(self.duration_field, 3, 1)
        self.info_layout.addWidget(self.title_field, 4, 1)
        self.info_layout.addWidget(self.streamer_field, 5, 1)

        self.layout.addLayout(self.info_layout)
        self.file_picker_field.changed.connect(self.on_video_url_changed)

        self.setLayout(self.layout)

    def load_video_url(self, url=None):
        self.file_picker_field.file_path_field.setText(
            "" if url is None else url)

        if url:
            self.loaded_video = InputVideo()

            if re.search(r"^(?:/|[a-z]:[\\/])", url, re.I):
                video_url = "file://" + url
                self.loaded_video.is_local = True
            elif url.lower().startswith("file://"):
                video_url = url
                self.loaded_video.is_local = True
            else:
                video_url = url

            def find_suitable_stream(streams):
                best_stream = streams.get("best", None)

                if best_stream:
                    if type(best_stream) is MuxedStream:
                        return best_stream.substreams[0].url
                    else:
                        return best_stream.url
                else:
                    raise Exception(f"<!!> Can't find best stream")

            if not self.loaded_video.is_local:
                try:
                    streams = streamlink.streams(video_url)
                except streamlink.exceptions.PluginError as e:
                    print(f"<!!> Error while loading video {video_url} : {e}")
                    return

                if streams:
                    self.loaded_video.video_url = find_suitable_stream(
                        streams)  #streams["best"]
                else:
                    self.loaded_video.video_url = video_url
            else:
                self.loaded_video.video_url = video_url

            if "twitch.tv" in video_url:
                try:
                    self.loaded_video.metadatas["service"] = "twitch"
                    self.update_twitch_metadatas()
                except requests.exceptions.ConnectionError:
                    print("<!!> Can't connect to Twitch API.")
            elif "youtube.com" in video_url:
                try:
                    self.loaded_video.metadatas["service"] = "youtube"
                    self.update_youtube_metadatas()
                except requests.exceptions.ConnectionError:
                    print("<!!> Can't connect to Youtube API.")

            try:
                self.vlc_instance.open_url(self.loaded_video.video_url)
            except requests.exceptions.ConnectionError:
                print("<!!> Can't connect to local VLC instance.")

    def seek(self, time):
        self.vlc_instance.set_current_time(time)

    def get_service_metadatas(self):
        pass

    def get_youtube_id_from_url(self):
        url = self.file_picker_field.file_path_field.text()

        # Ressource pour plus tard : https://webapps.stackexchange.com/questions/54443/format-for-id-of-youtube-video
        parsed_url = re.search("v=([0-9A-Za-z_-]+)", url, re.I)

        if parsed_url:
            video_id = parsed_url.group(1)
            return video_id
        else:
            raise Exception(
                f"<!!> Can't find video Youtube id in video url ({url})")

    def get_twitch_id_from_url(self):
        filename = self.file_picker_field.file_path_field.text()

        parsed_filename = re.search("([0-9]+)\.mp4$", filename, re.I)

        if parsed_filename:
            video_id = parsed_filename.group(1)
            return int(video_id)
        else:
            parsed_url = re.search("videos/([0-9]+)", filename, re.I)
            if parsed_url:
                video_id = parsed_url.group(1)
                return int(video_id)
            else:
                raise Exception(
                    f"<!!> Can't find video Twitch id in video filename ({filename})"
                )

    def update_youtube_metadatas(self):
        self.loaded_video.metadatas["id"] = self.get_youtube_id_from_url()

        self.id_twitch_field.setText(self.loaded_video.metadatas["id"])

    def update_twitch_metadatas(self):
        twitch_video_id = self.get_twitch_id_from_url()
        metadatas = self.topLevelWidget(
        ).twitch_interface.get_twitch_metadatas(twitch_video_id)

        self.loaded_video.metadatas = metadatas

        duration = parse_duration(metadatas["duration"])

        self.id_twitch_field.setText(metadatas["id"])
        self.created_at_field.setText(str(metadatas["created_at"]))
        self.duration_field.setText(format_time(duration.seconds))
        self.title_field.setText(metadatas["title"])
        self.streamer_field.setText(metadatas["user_login"])

    def on_video_url_changed(self):
        self.load_video_url(self.file_picker_field.file_path_field.text())

    def dragEnterEvent(self, event: PySide2.QtGui.QDragEnterEvent) -> None:
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event: PySide2.QtGui.QDropEvent) -> None:
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()

            if len(event.mimeData().urls()) > 0:
                url = event.mimeData().urls()[0]
                self.load_video_url(url.url())
        else:
            event.ignore()
Ejemplo n.º 27
0
class LayoutDialog(QMainWindow):
    def __init__(self, parent):
        super().__init__(parent)
        self.setWindowTitle("Layout for " + parent.name)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint
                            | QtCore.Qt.WindowTitleHint
                            | QtCore.Qt.WindowCloseButtonHint)
        self.resize(600, 600)
        self.parent = parent

        self.onlyInt = QtGui.QIntValidator()
        all_fonts = [
            "Arial", "Balto", "Courier New", "Droid Sans", "Droid Serif",
            "Droid Sans Mono", "Gravitas One", "Old Standard TT", "Open Sans",
            "Overpass", "PT Sans Narrow", "Raleway", "Times New Roman"
        ]

        self.bt_uplayout = QPushButton('Update layout')
        self.bt_uplayout.setIcon(self.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.bt_uplayout.clicked.connect(self.layout_update)

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.bt_uplayout)
        self.hbox.addWidget(QWidget())
        self.hbox.addStretch()

        # Overal Layout parameters
        self.lbl_layhover = QLabel('hovermode:')
        self.combo_layhover = QComboBox()
        self.combo_layhover.addItem('closest')
        self.combo_layhover.addItem('x')
        self.combo_layhover.addItem('y')
        self.combo_layhover.addItem('False')
        self.chk_layautosize = QCheckBox('autosize')
        self.chk_layautosize.setChecked(True)
        self.chk_layautosize.stateChanged.connect(self.toggle_enable_fields)
        self.lbl_laywidth = QLabel('width:')
        self.lin_laywidth = QLineEdit('700')
        self.lin_laywidth.setValidator(self.onlyInt)
        self.lbl_layheight = QLabel('height:')
        self.lin_layheight = QLineEdit('450')
        self.lin_layheight.setValidator(self.onlyInt)
        self.lbl_layfont = QLabel('font:')
        self.combo_layfont = QComboBox()
        for ft in all_fonts:
            self.combo_layfont.addItem(ft)
        self.lin_layfont = QLineEdit('10')
        self.lin_layfont.setValidator(self.onlyInt)
        self.lbl_layfontc = QLabel('font color (r,g,b,a):')
        self.btn_layfontc = QPushButton('Pick')
        self.btn_layfontc.clicked.connect(
            lambda: self.choose_color(target='layout_font'))
        self.lin_layfontr = QLineEdit('0')
        self.lin_layfontr.setValidator(self.onlyInt)
        self.lin_layfontg = QLineEdit('0')
        self.lin_layfontg.setValidator(self.onlyInt)
        self.lin_layfontb = QLineEdit('0')
        self.lin_layfontb.setValidator(self.onlyInt)
        self.lin_layfonta = QLineEdit('255')
        self.lin_layfonta.setValidator(self.onlyInt)
        self.lbl_laypaperc = QLabel('paper color (r,g,b,a):')
        self.btn_laypaperc = QPushButton('Pick')
        self.btn_laypaperc.clicked.connect(
            lambda: self.choose_color(target='layout_paper'))
        self.lin_laypaperr = QLineEdit('255')
        self.lin_laypaperr.setValidator(self.onlyInt)
        self.lin_laypaperg = QLineEdit('255')
        self.lin_laypaperg.setValidator(self.onlyInt)
        self.lin_laypaperb = QLineEdit('255')
        self.lin_laypaperb.setValidator(self.onlyInt)
        self.lin_laypapera = QLineEdit('255')
        self.lin_laypapera.setValidator(self.onlyInt)
        self.lbl_layplotc = QLabel('plot_bg color (r,g,b,a):')
        self.btn_layplotc = QPushButton('Pick')
        self.btn_layplotc.clicked.connect(
            lambda: self.choose_color(target='layout_plot'))
        self.lin_layplotr = QLineEdit('255')
        self.lin_layplotr.setValidator(self.onlyInt)
        self.lin_layplotg = QLineEdit('255')
        self.lin_layplotg.setValidator(self.onlyInt)
        self.lin_layplotb = QLineEdit('255')
        self.lin_layplotb.setValidator(self.onlyInt)
        self.lin_layplota = QLineEdit('255')
        self.lin_layplota.setValidator(self.onlyInt)
        self.chk_legend = QCheckBox('show legend')
        self.chk_legend.setChecked(True)

        self.general_grid = QGridLayout()
        self.general_grid.setColumnStretch(7, 1)
        self.general_grid.addWidget(self.lbl_layhover, 0, 0, 1, 1)
        self.general_grid.addWidget(self.combo_layhover, 0, 1, 1, 1)
        self.general_grid.addWidget(self.chk_layautosize, 1, 0, 1, 1)
        self.general_grid.addWidget(self.lbl_laywidth, 2, 0, 1, 1)
        self.general_grid.addWidget(self.lin_laywidth, 2, 1, 1, 1)
        self.general_grid.addWidget(self.lbl_layheight, 3, 0, 1, 1)
        self.general_grid.addWidget(self.lin_layheight, 3, 1, 1, 1)
        self.general_grid.addWidget(self.lbl_layfont, 4, 0, 1, 1)
        self.general_grid.addWidget(self.lin_layfont, 4, 1, 1, 1)
        self.general_grid.addWidget(self.combo_layfont, 4, 2, 1, 2)
        self.general_grid.addWidget(self.lbl_layfontc, 5, 0, 1, 1)
        self.general_grid.addWidget(self.lin_layfontr, 5, 1, 1, 1)
        self.general_grid.addWidget(self.lin_layfontg, 5, 2, 1, 1)
        self.general_grid.addWidget(self.lin_layfontb, 5, 3, 1, 1)
        self.general_grid.addWidget(self.lin_layfonta, 5, 4, 1, 1)
        self.general_grid.addWidget(self.btn_layfontc, 5, 5, 1, 1)
        self.general_grid.addWidget(self.lbl_laypaperc, 6, 0, 1, 1)
        self.general_grid.addWidget(self.lin_laypaperr, 6, 1, 1, 1)
        self.general_grid.addWidget(self.lin_laypaperg, 6, 2, 1, 1)
        self.general_grid.addWidget(self.lin_laypaperb, 6, 3, 1, 1)
        self.general_grid.addWidget(self.lin_laypapera, 6, 4, 1, 1)
        self.general_grid.addWidget(self.btn_laypaperc, 6, 5, 1, 1)
        self.general_grid.addWidget(self.lbl_layplotc, 7, 0, 1, 1)
        self.general_grid.addWidget(self.lin_layplotr, 7, 1, 1, 1)
        self.general_grid.addWidget(self.lin_layplotg, 7, 2, 1, 1)
        self.general_grid.addWidget(self.lin_layplotb, 7, 3, 1, 1)
        self.general_grid.addWidget(self.lin_layplota, 7, 4, 1, 1)
        self.general_grid.addWidget(self.btn_layplotc, 7, 5, 1, 1)
        self.general_grid.addWidget(self.chk_legend, 8, 0, 1, 1)
        self.general_grid.addWidget(QWidget(), 9, 0, 1, 7)

        self.general_group = CollapsibleBox(title='General', parent=self)
        self.general_group.setContentLayout(self.general_grid)

        # Title parameters
        self.lbl_titletext = QLabel('text:')
        self.lin_titletext = QLineEdit('')
        self.lbl_titlefont = QLabel('font:')
        self.combo_titlefont = QComboBox()
        for ft in all_fonts:
            self.combo_titlefont.addItem(ft)
        self.lin_titlefont = QLineEdit('18')
        self.lin_titlefont.setValidator(self.onlyInt)
        self.lbl_titlec = QLabel('color (r,g,b,a):')
        self.btn_titlec = QPushButton('Pick')
        self.btn_titlec.clicked.connect(
            lambda: self.choose_color(target='title'))
        self.lin_titler = QLineEdit('0')
        self.lin_titler.setValidator(self.onlyInt)
        self.lin_titleg = QLineEdit('0')
        self.lin_titleg.setValidator(self.onlyInt)
        self.lin_titleb = QLineEdit('0')
        self.lin_titleb.setValidator(self.onlyInt)
        self.lin_titlea = QLineEdit('255')
        self.lin_titlea.setValidator(self.onlyInt)

        self.title_grid = QGridLayout()
        self.title_grid.setColumnStretch(7, 1)
        self.title_grid.addWidget(self.lbl_titletext, 0, 0, 1, 1)
        self.title_grid.addWidget(self.lin_titletext, 0, 1, 1, 3)
        self.title_grid.addWidget(self.lbl_titlefont, 1, 0, 1, 1)
        self.title_grid.addWidget(self.lin_titlefont, 1, 1, 1, 1)
        self.title_grid.addWidget(self.combo_titlefont, 1, 2, 1, 2)
        self.title_grid.addWidget(self.lbl_titlec, 2, 0, 1, 1)
        self.title_grid.addWidget(self.lin_titler, 2, 1, 1, 1)
        self.title_grid.addWidget(self.lin_titleg, 2, 2, 1, 1)
        self.title_grid.addWidget(self.lin_titleb, 2, 3, 1, 1)
        self.title_grid.addWidget(self.lin_titlea, 2, 4, 1, 1)
        self.title_grid.addWidget(self.btn_titlec, 2, 5, 1, 1)

        self.title_group = CollapsibleBox(title='Title', parent=self)
        self.title_group.setContentLayout(self.title_grid)

        # X Axis parameters
        self.chk_xvisible = QCheckBox('visible')
        self.chk_xvisible.setChecked(True)
        self.lbl_xc = QLabel('color (r,g,b,a):')
        self.btn_xc = QPushButton('Pick')
        self.btn_xc.clicked.connect(lambda: self.choose_color(target='xaxis'))
        self.lin_xr = QLineEdit('255')
        self.lin_xr.setValidator(self.onlyInt)
        self.lin_xg = QLineEdit('255')
        self.lin_xg.setValidator(self.onlyInt)
        self.lin_xb = QLineEdit('255')
        self.lin_xb.setValidator(self.onlyInt)
        self.lin_xa = QLineEdit('255')
        self.lin_xa.setValidator(self.onlyInt)
        self.lbl_xtitletext = QLabel('text:')
        self.lin_xtitletext = QLineEdit('')
        self.lbl_xtitlefont = QLabel('font:')
        self.combo_xtitlefont = QComboBox()
        for ft in all_fonts:
            self.combo_xtitlefont.addItem(ft)
        self.lin_xtitlefont = QLineEdit('10')
        self.lin_xtitlefont.setValidator(self.onlyInt)
        self.lbl_xtitlec = QLabel('font color (r,g,b,a):')
        self.btn_xtitlec = QPushButton('Pick')
        self.btn_xtitlec.clicked.connect(
            lambda: self.choose_color(target='xaxis_title'))
        self.lin_xtitler = QLineEdit('27')
        self.lin_xtitler.setValidator(self.onlyInt)
        self.lin_xtitleg = QLineEdit('27')
        self.lin_xtitleg.setValidator(self.onlyInt)
        self.lin_xtitleb = QLineEdit('27')
        self.lin_xtitleb.setValidator(self.onlyInt)
        self.lin_xtitlea = QLineEdit('255')
        self.lin_xtitlea.setValidator(self.onlyInt)
        self.lbl_xtype = QLabel('type:')
        self.combo_xtype = QComboBox()
        self.combo_xtype.addItem("-")
        self.combo_xtype.addItem("linear")
        self.combo_xtype.addItem("log")
        self.combo_xtype.addItem("date")
        self.combo_xtype.addItem("category")
        self.combo_xtype.addItem("multicategory")
        self.chk_xautorange = QCheckBox('autorange')
        self.chk_xautorange.setChecked(True)
        self.lbl_xnticks = QLabel('nticks:')
        self.lin_xnticks = QLineEdit('4')
        self.lin_xnticks.setValidator(self.onlyInt)
        self.lbl_xticks = QLabel('ticks:')
        self.combo_xticks = QComboBox()
        self.combo_xticks.addItem("inside")
        self.combo_xticks.addItem("outside")
        self.combo_xticks.addItem("")
        self.lbl_xticklen = QLabel('tick length:')
        self.lin_xticklen = QLineEdit('5')
        self.lin_xticklen.setValidator(self.onlyInt)
        self.lbl_xtickwid = QLabel('tick width:')
        self.lin_xtickwid = QLineEdit('1')
        self.lin_xtickwid.setValidator(self.onlyInt)
        self.lbl_xtickc = QLabel('tick color (r,g,b,a):')
        self.btn_xtickc = QPushButton('Pick')
        self.btn_xtickc.clicked.connect(
            lambda: self.choose_color(target='xaxis_tick'))
        self.lin_xtickr = QLineEdit('27')
        self.lin_xtickr.setValidator(self.onlyInt)
        self.lin_xtickg = QLineEdit('27')
        self.lin_xtickg.setValidator(self.onlyInt)
        self.lin_xtickb = QLineEdit('27')
        self.lin_xtickb.setValidator(self.onlyInt)
        self.lin_xticka = QLineEdit('255')
        self.lin_xticka.setValidator(self.onlyInt)
        self.chk_xshowticklabels = QCheckBox('show tick labels')
        self.chk_xshowticklabels.setChecked(True)
        self.lbl_xtickangle = QLabel('tick angle:')
        self.chk_xtickangle = QCheckBox('auto')
        self.chk_xtickangle.setChecked(True)
        self.chk_xtickangle.stateChanged.connect(self.toggle_enable_fields)
        self.lin_xtickangle = QLineEdit('0')
        self.lin_xtickangle.setValidator(self.onlyInt)
        self.lbl_xtickprefix = QLabel('tick prefix:')
        self.lin_xtickprefix = QLineEdit('')
        self.combo_xshowtickprefix = QComboBox()
        self.combo_xshowtickprefix.addItem("all")
        self.combo_xshowtickprefix.addItem("first")
        self.combo_xshowtickprefix.addItem("last")
        self.combo_xshowtickprefix.addItem("none")
        self.lbl_xticksufix = QLabel('tick sufix:')
        self.lin_xticksufix = QLineEdit('')
        self.combo_xshowticksufix = QComboBox()
        self.combo_xshowticksufix.addItem("all")
        self.combo_xshowticksufix.addItem("first")
        self.combo_xshowticksufix.addItem("last")
        self.combo_xshowticksufix.addItem("none")
        self.lbl_xexponent = QLabel('exponent:')
        self.combo_xexponent = QComboBox()
        self.combo_xexponent.addItem("B")
        self.combo_xexponent.addItem("e")
        self.combo_xexponent.addItem("E")
        self.combo_xexponent.addItem("power")
        self.combo_xexponent.addItem("SI")
        self.combo_xexponent.addItem("none")
        self.combo_xshowexponent = QComboBox()
        self.combo_xshowexponent.addItem("all")
        self.combo_xshowexponent.addItem("first")
        self.combo_xshowexponent.addItem("last")
        self.combo_xshowexponent.addItem("none")
        self.lbl_xtickformat = QLabel('tick format:')
        self.lin_xtickformat = QLineEdit('')
        self.chk_xshowline = QCheckBox('show line')
        self.chk_xshowline.setChecked(False)
        self.chk_xshowline.stateChanged.connect(self.toggle_enable_fields)
        self.lbl_xlinewid = QLabel('line width:')
        self.lin_xlinewid = QLineEdit('1')
        self.lin_xlinewid.setValidator(self.onlyInt)
        self.lbl_xlinec = QLabel('line color (r,g,b,a):')
        self.btn_xlinec = QPushButton('Pick')
        self.btn_xlinec.clicked.connect(
            lambda: self.choose_color(target='xaxis_line'))
        self.lin_xliner = QLineEdit('27')
        self.lin_xliner.setValidator(self.onlyInt)
        self.lin_xlineg = QLineEdit('27')
        self.lin_xlineg.setValidator(self.onlyInt)
        self.lin_xlineb = QLineEdit('27')
        self.lin_xlineb.setValidator(self.onlyInt)
        self.lin_xlinea = QLineEdit('255')
        self.lin_xlinea.setValidator(self.onlyInt)
        self.chk_xshowgrid = QCheckBox('show grid')
        self.chk_xshowgrid.setChecked(False)
        self.chk_xshowgrid.stateChanged.connect(self.toggle_enable_fields)
        self.lbl_xgridwid = QLabel('grid width:')
        self.lin_xgridwid = QLineEdit('1')
        self.lin_xgridwid.setValidator(self.onlyInt)
        self.lbl_xgridc = QLabel('grid color (r,g,b,a):')
        self.btn_xgridc = QPushButton('Pick')
        self.btn_xgridc.clicked.connect(
            lambda: self.choose_color(target='xaxis_grid'))
        self.lin_xgridr = QLineEdit('238')
        self.lin_xgridr.setValidator(self.onlyInt)
        self.lin_xgridg = QLineEdit('238')
        self.lin_xgridg.setValidator(self.onlyInt)
        self.lin_xgridb = QLineEdit('238')
        self.lin_xgridb.setValidator(self.onlyInt)
        self.lin_xgrida = QLineEdit('255')
        self.lin_xgrida.setValidator(self.onlyInt)
        self.chk_xzeroline = QCheckBox('show zero-line')
        self.chk_xzeroline.setChecked(False)
        self.chk_xzeroline.stateChanged.connect(self.toggle_enable_fields)
        self.lbl_xzerolinewid = QLabel('zero-line width:')
        self.lin_xzerolinewid = QLineEdit('1')
        self.lin_xzerolinewid.setValidator(self.onlyInt)
        self.lbl_xzerolinec = QLabel('zero-line color (r,g,b,a):')
        self.btn_xzerolinec = QPushButton('Pick')
        self.btn_xzerolinec.clicked.connect(
            lambda: self.choose_color(target='xaxis_zeroline'))
        self.lin_xzeroliner = QLineEdit('68')
        self.lin_xzeroliner.setValidator(self.onlyInt)
        self.lin_xzerolineg = QLineEdit('68')
        self.lin_xzerolineg.setValidator(self.onlyInt)
        self.lin_xzerolineb = QLineEdit('68')
        self.lin_xzerolineb.setValidator(self.onlyInt)
        self.lin_xzerolinea = QLineEdit('255')
        self.lin_xzerolinea.setValidator(self.onlyInt)
        self.lbl_xside = QLabel('side:')
        self.combo_xside = QComboBox()
        self.combo_xside.addItem("bottom")
        self.combo_xside.addItem("top")

        self.xaxis_grid = QGridLayout()
        self.xaxis_grid.setColumnStretch(7, 1)
        self.xaxis_grid.addWidget(self.chk_xvisible, 0, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xc, 1, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xr, 1, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xg, 1, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xb, 1, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xa, 1, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xc, 1, 5, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtitletext, 2, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitletext, 2, 1, 1, 3)
        self.xaxis_grid.addWidget(self.lbl_xtitlefont, 3, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitlefont, 3, 1, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xtitlefont, 3, 2, 1, 2)
        self.xaxis_grid.addWidget(self.lbl_xtitlec, 4, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitler, 4, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitleg, 4, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitleb, 4, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtitlea, 4, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xtitlec, 4, 5, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtype, 5, 0, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xtype, 5, 1, 1, 2)
        self.xaxis_grid.addWidget(self.chk_xautorange, 6, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xnticks, 7, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xnticks, 7, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xticks, 8, 0, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xticks, 8, 1, 1, 2)
        self.xaxis_grid.addWidget(self.lbl_xticklen, 9, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xticklen, 9, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtickwid, 10, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickwid, 10, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtickc, 11, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickr, 11, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickg, 11, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickb, 11, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xticka, 11, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xtickc, 11, 5, 1, 1)
        self.xaxis_grid.addWidget(self.chk_xshowticklabels, 12, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtickangle, 13, 0, 1, 1)
        self.xaxis_grid.addWidget(self.chk_xtickangle, 13, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickangle, 13, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtickprefix, 14, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickprefix, 14, 1, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xshowtickprefix, 14, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xticksufix, 15, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xticksufix, 15, 1, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xshowticksufix, 15, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xexponent, 16, 0, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xexponent, 16, 1, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xshowexponent, 16, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xtickformat, 17, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xtickformat, 17, 1, 1, 1)
        self.xaxis_grid.addWidget(self.chk_xshowline, 18, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xlinewid, 19, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xlinewid, 19, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xlinec, 20, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xliner, 20, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xlineg, 20, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xlineb, 20, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xlinea, 20, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xlinec, 20, 5, 1, 1)
        self.xaxis_grid.addWidget(self.chk_xshowgrid, 21, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xgridwid, 22, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xgridwid, 22, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xgridc, 23, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xgridr, 23, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xgridg, 23, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xgridb, 23, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xgrida, 23, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xgridc, 23, 5, 1, 1)
        self.xaxis_grid.addWidget(self.chk_xzeroline, 24, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xzerolinewid, 25, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xzerolinewid, 25, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xzerolinec, 26, 0, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xzeroliner, 26, 1, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xzerolineg, 26, 2, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xzerolineb, 26, 3, 1, 1)
        self.xaxis_grid.addWidget(self.lin_xzerolinea, 26, 4, 1, 1)
        self.xaxis_grid.addWidget(self.btn_xzerolinec, 26, 5, 1, 1)
        self.xaxis_grid.addWidget(self.lbl_xside, 27, 0, 1, 1)
        self.xaxis_grid.addWidget(self.combo_xside, 27, 1, 1, 1)

        self.xaxis_group = CollapsibleBox(title='X Axis', parent=self)
        self.xaxis_group.setContentLayout(self.xaxis_grid)

        # Y Axis parameters
        self.lbl_ytitle = QLabel('y title')
        self.lin_ytitle = QLineEdit('')

        self.yaxis_grid = QGridLayout()
        self.yaxis_grid.setColumnStretch(7, 1)
        self.yaxis_grid.addWidget(self.lbl_ytitle, 0, 0, 1, 1)
        self.yaxis_grid.addWidget(self.lin_ytitle, 0, 1, 1, 2)

        self.yaxis_group = CollapsibleBox(title='Y Axis', parent=self)
        self.yaxis_group.setContentLayout(self.yaxis_grid)

        # Main window layout
        self.vbox1 = QVBoxLayout()
        self.vbox1.addWidget(self.general_group)
        self.vbox1.addWidget(self.title_group)
        self.vbox1.addWidget(self.xaxis_group)
        self.vbox1.addWidget(self.yaxis_group)
        self.vbox1.addStretch()
        scroll_aux = QWidget()
        scroll_aux.setLayout(self.vbox1)
        scroll = QScrollArea()
        scroll.setWidget(scroll_aux)
        scroll.setWidgetResizable(True)

        self.vbox2 = QVBoxLayout()
        self.vbox2.addLayout(self.hbox)
        self.vbox2.addWidget(scroll)

        centralw = QWidget()
        centralw.setLayout(self.vbox2)
        self.setCentralWidget(centralw)
        self.show()

        self.init_attributes()
        self.toggle_enable_fields()

        #self.general_group.toggle_button.click()
        #self.title_group.toggle_button.click()
        self.xaxis_group.toggle_button.click()
        #self.yaxis_group.toggle_button.click()

    def toggle_enable_fields(self):
        # General
        self.lin_laywidth.setEnabled(not self.chk_layautosize.isChecked())
        self.lin_layheight.setEnabled(not self.chk_layautosize.isChecked())

        # X axis
        self.lin_xtickangle.setEnabled(not self.chk_xtickangle.isChecked())
        self.lin_xlinewid.setEnabled(self.chk_xshowline.isChecked())
        self.btn_xlinec.setEnabled(self.chk_xshowline.isChecked())
        self.lin_xliner.setEnabled(self.chk_xshowline.isChecked())
        self.lin_xlineg.setEnabled(self.chk_xshowline.isChecked())
        self.lin_xlineb.setEnabled(self.chk_xshowline.isChecked())
        self.lin_xlinea.setEnabled(self.chk_xshowline.isChecked())
        self.lin_xgridwid.setEnabled(self.chk_xshowgrid.isChecked())
        self.btn_xgridc.setEnabled(self.chk_xshowgrid.isChecked())
        self.lin_xgridr.setEnabled(self.chk_xshowgrid.isChecked())
        self.lin_xgridg.setEnabled(self.chk_xshowgrid.isChecked())
        self.lin_xgridb.setEnabled(self.chk_xshowgrid.isChecked())
        self.lin_xgrida.setEnabled(self.chk_xshowgrid.isChecked())
        self.lin_xzerolinewid.setEnabled(self.chk_xzeroline.isChecked())
        self.btn_xzerolinec.setEnabled(self.chk_xzeroline.isChecked())
        self.lin_xzeroliner.setEnabled(self.chk_xzeroline.isChecked())
        self.lin_xzerolineg.setEnabled(self.chk_xzeroline.isChecked())
        self.lin_xzerolineb.setEnabled(self.chk_xzeroline.isChecked())
        self.lin_xzerolinea.setEnabled(self.chk_xzeroline.isChecked())

    def choose_color(self, target):
        color = QColorDialog.getColor()
        if color.isValid():
            if target == 'title':
                self.lin_titler.setText(str(color.red()))
                self.lin_titleg.setText(str(color.green()))
                self.lin_titleb.setText(str(color.blue()))
            elif target == 'layout_font':
                self.lin_layfontr.setText(str(color.red()))
                self.lin_layfontg.setText(str(color.green()))
                self.lin_layfontb.setText(str(color.blue()))
            elif target == 'layout_paper':
                self.lin_laypaperr.setText(str(color.red()))
                self.lin_laypaperg.setText(str(color.green()))
                self.lin_laypaperb.setText(str(color.blue()))
            elif target == 'layout_plot':
                self.lin_layplotr.setText(str(color.red()))
                self.lin_layplotg.setText(str(color.green()))
                self.lin_layplotb.setText(str(color.blue()))
            elif target == 'xaxis':
                self.lin_xr.setText(str(color.red()))
                self.lin_xg.setText(str(color.green()))
                self.lin_xb.setText(str(color.blue()))
            elif target == 'xaxis_title':
                self.lin_xtitler.setText(str(color.red()))
                self.lin_xtitleg.setText(str(color.green()))
                self.lin_xtitleb.setText(str(color.blue()))
            elif target == 'xaxis_tick':
                self.lin_xtickr.setText(str(color.red()))
                self.lin_xtickg.setText(str(color.green()))
                self.lin_xtickb.setText(str(color.blue()))
            elif target == 'xaxis_line':
                self.lin_xliner.setText(str(color.red()))
                self.lin_xlineg.setText(str(color.green()))
                self.lin_xlineb.setText(str(color.blue()))
            elif target == 'xaxis_grid':
                self.lin_xgridr.setText(str(color.red()))
                self.lin_xgridg.setText(str(color.green()))
                self.lin_xgridb.setText(str(color.blue()))
            elif target == 'xaxis_zeroline':
                self.lin_xzeroliner.setText(str(color.red()))
                self.lin_xzerolineg.setText(str(color.green()))
                self.lin_xzerolineb.setText(str(color.blue()))

    def layout_update(self):
        """Reads fields and updates parent's layout"""
        changes = AutoDictionary()

        # General
        if str(self.combo_layhover.currentText()) == 'False':
            changes['hovermode'] = False
        else:
            changes['hovermode'] = str(self.combo_layhover.currentText())
        changes['autosize'] = self.chk_layautosize.isChecked()
        changes['width'] = int(self.lin_laywidth.text()
                               ) if self.lin_laywidth.isEnabled() else None
        changes['height'] = int(self.lin_layheight.text()
                                ) if self.lin_layheight.isEnabled() else None
        changes['font']['family'] = str(self.combo_layfont.currentText())
        changes['font']['size'] = int(self.lin_layfont.text())
        r = str(self.lin_layfontr.text())
        g = str(self.lin_layfontg.text())
        b = str(self.lin_layfontb.text())
        a = str(self.lin_layfonta.text())
        changes['font'][
            'color'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        r = str(self.lin_laypaperr.text())
        g = str(self.lin_laypaperg.text())
        b = str(self.lin_laypaperb.text())
        a = str(self.lin_laypapera.text())
        changes[
            'paper_bgcolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        r = str(self.lin_layplotr.text())
        g = str(self.lin_layplotg.text())
        b = str(self.lin_layplotb.text())
        a = str(self.lin_layplota.text())
        changes[
            'plot_bgcolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['showlegend'] = self.chk_legend.isChecked()

        # Title
        changes['title']['text'] = str(self.lin_titletext.text())
        changes['title']['font']['family'] = str(
            self.combo_titlefont.currentText())
        changes['title']['font']['size'] = int(self.lin_titlefont.text())
        r = str(self.lin_titler.text())
        g = str(self.lin_titleg.text())
        b = str(self.lin_titleb.text())
        a = str(self.lin_titlea.text())
        changes['title']['font'][
            'color'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'

        # X axis
        changes['xaxis']['visible'] = self.chk_xvisible.isChecked()
        r = str(self.lin_xr.text())
        g = str(self.lin_xg.text())
        b = str(self.lin_xb.text())
        a = str(self.lin_xa.text())
        changes['xaxis'][
            'color'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        #changes['xaxis']['title']['text'] = str(self.lin_xtitletext.text())
        changes['xaxis']['title']['font']['family'] = str(
            self.combo_xtitlefont.currentText())
        changes['xaxis']['title']['font']['size'] = int(
            self.lin_xtitlefont.text())
        r = str(self.lin_xtitler.text())
        g = str(self.lin_xtitleg.text())
        b = str(self.lin_xtitleb.text())
        a = str(self.lin_xtitlea.text())
        changes['xaxis']['title']['font'][
            'color'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['xaxis']['type'] = str(self.combo_xtype.currentText())
        changes['xaxis']['autorange'] = self.chk_xautorange.isChecked()
        changes['xaxis']['nticks'] = int(self.lin_xnticks.text())
        changes['xaxis']['ticks'] = str(self.combo_xticks.currentText())
        changes['xaxis']['ticklen'] = int(self.lin_xticklen.text())
        changes['xaxis']['tickwidth'] = int(self.lin_xtickwid.text())
        r = str(self.lin_xtickr.text())
        g = str(self.lin_xtickg.text())
        b = str(self.lin_xtickb.text())
        a = str(self.lin_xticka.text())
        changes['xaxis'][
            'tickcolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['xaxis'][
            'showticklabels'] = self.chk_xshowticklabels.isChecked()
        changes['xaxis'][
            'tickangle'] = None if self.chk_xtickangle.isChecked else int(
                self.lin_xtickangle.text())
        changes['xaxis']['tickprefix'] = str(self.lin_xtickprefix.text())
        changes['xaxis']['showtickprefix'] = str(
            self.combo_xshowtickprefix.currentText())
        changes['xaxis']['ticksuffix'] = str(self.lin_xticksufix.text())
        changes['xaxis']['showticksuffix'] = str(
            self.combo_xshowticksufix.currentText())
        changes['xaxis']['showexponent'] = str(
            self.combo_xshowexponent.currentText())
        changes['xaxis']['exponentformat'] = str(
            self.combo_xexponent.currentText())
        changes['xaxis']['tickformat'] = str(self.lin_xtickformat.text())
        changes['xaxis']['showline'] = self.chk_xshowline.isChecked()
        changes['xaxis']['linewidth'] = int(self.lin_xlinewid.text())
        r = str(self.lin_xliner.text())
        g = str(self.lin_xlineg.text())
        b = str(self.lin_xlineb.text())
        a = str(self.lin_xlinea.text())
        changes['xaxis'][
            'linecolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['xaxis']['showgrid'] = self.chk_xshowgrid.isChecked()
        changes['xaxis']['gridwidth'] = int(self.lin_xgridwid.text())
        r = str(self.lin_xgridr.text())
        g = str(self.lin_xgridg.text())
        b = str(self.lin_xgridb.text())
        a = str(self.lin_xgrida.text())
        changes['xaxis'][
            'gridcolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['xaxis']['zeroline'] = self.chk_xzeroline.isChecked()
        changes['xaxis']['zerolinewidth'] = int(self.lin_xzerolinewid.text())
        r = str(self.lin_xzeroliner.text())
        g = str(self.lin_xzerolineg.text())
        b = str(self.lin_xzerolineb.text())
        a = str(self.lin_xzerolinea.text())
        changes['xaxis'][
            'zerolinecolor'] = 'rgb(' + r + ',' + g + ',' + b + ',' + a + ')'
        changes['xaxis']['side'] = str(self.combo_xside.currentText())

        # Run layout update
        self.parent.layout_update(changes=changes)

    def init_attributes(self):
        pass
Ejemplo n.º 28
0
class VODSync(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.twitch_interface = TwitchInterface(
            api_client_id=config.TWITCH_API_CLIENT_ID,
            api_oauth_token=config.TWITCH_API_OAUTH_TOKEN,
            browser_client_id=config.TWITCH_BROWSER_OAUTH_TOKEN,
            browser_oauth_token=config.TWITCH_BROWSER_OAUTH_TOKEN)

        self.loaded_videos = []
        self.video_decks = []

        self.corrected_time = None

        self.main_layout = QVBoxLayout()

        self.launch_vlc_btn = QPushButton("Launch VLC")

        self.playlist_widget = PlaylistWidget()

        self.sync_btn = QPushButton(text="SYNC")

        self.match_btn = QPushButton(text="MATCH")

        self.decks_layout = QHBoxLayout()

        self.main_layout.addWidget(self.launch_vlc_btn)
        self.main_layout.addWidget(self.playlist_widget)
        self.main_layout.addWidget(self.sync_btn)
        self.main_layout.addLayout(self.decks_layout)
        self.main_layout.addWidget(self.match_btn)

        match_infos_layout = QGridLayout()

        timecode_source_label = QLabel("Timecode Video Source")
        timecode_target_label = QLabel("Timecode Video Target")
        target_start_time_label = QLabel("Resulting VOD Start Time")

        self.timecode_source_field = QLineEdit()
        self.timecode_target_field = QLineEdit()
        self.target_start_time_field = QLineEdit()

        self.timecode_source_field.setEnabled(False)
        self.timecode_target_field.setEnabled(False)
        self.target_start_time_field.setEnabled(False)

        match_infos_layout.addWidget(timecode_source_label, 0, 0)
        match_infos_layout.addWidget(timecode_target_label, 1, 0)
        match_infos_layout.addWidget(target_start_time_label, 2, 0)

        match_infos_layout.addWidget(self.timecode_source_field, 0, 1)
        match_infos_layout.addWidget(self.timecode_target_field, 1, 1)
        match_infos_layout.addWidget(self.target_start_time_field, 2, 1)

        self.main_layout.addLayout(match_infos_layout)

        self.export_btn = QPushButton(text="EXPORT")
        self.main_layout.addWidget(self.export_btn)

        self.main_widget = QWidget()
        self.main_widget.setLayout(self.main_layout)

        self.setCentralWidget(self.main_widget)

        self.sync_btn.clicked.connect(self.sync_from_playlist_item)
        self.match_btn.clicked.connect(self.match)
        self.export_btn.clicked.connect(self.export_metadatas)
        self.launch_vlc_btn.clicked.connect(self.on_launch_vlc)
        self.playlist_widget.itemPlayed.connect(self.on_playlist_item_played)

        self.add_video_deck(8080)
        self.add_video_deck(8081)

    def get_loaded_video(self, idx):
        if idx < 0 or idx >= len(self.loaded_videos):
            raise IndexError(f"<!!> Unknown loaded video index: {idx}")
        return self.loaded_videos[idx]

    def get_vlc_instance(self, idx):
        if idx < 0 or idx >= len(self.vlc_instances):
            raise IndexError(f"<!!> Unknown loaded video index: {idx}")
        return self.vlc_instances[idx]

    def add_video_deck(self, vlc_port=8080):
        new_deck = VideoDeck(VLCInterface(config.VLC_PATH, port=vlc_port))
        self.video_decks.append(new_deck)
        self.decks_layout.addWidget(new_deck)

    def export_metadatas(self, fixed_created_at):
        time_offset = abs(self.video_decks[0].vlc_instance.get_current_time() -
                          self.video_decks[1].vlc_instance.get_current_time())

        created_at = self.video_decks[0].loaded_video.metadatas.get(
            "created_at")

        corrected_time = created_at + datetime.timedelta(seconds=time_offset)

        fixed_metadatas = dict(self.video_decks[0].loaded_video.metadatas)
        fixed_metadatas["created_at"] = corrected_time.isoformat()
        fixed_metadatas["permanent_id"] = {
            "service": self.video_decks[1].loaded_video.metadatas["service"],
            "id": self.video_decks[1].loaded_video.metadatas["id"]
        }
        print(fixed_metadatas)

    def match(self):
        if len(self.video_decks) < 2:
            raise Exception(
                f"Not enough decks opened ({len(self.video_decks)})")

        time_offset = abs(self.video_decks[0].vlc_instance.get_current_time() -
                          self.video_decks[1].vlc_instance.get_current_time())

        created_at = self.video_decks[0].loaded_video.metadatas.get(
            "created_at")

        self.corrected_time = created_at + datetime.timedelta(
            seconds=time_offset)

        self.timecode_source_field.setText(
            str(self.video_decks[0].vlc_instance.get_current_time()))
        self.timecode_target_field.setText(
            str(self.video_decks[1].vlc_instance.get_current_time()))
        self.target_start_time_field.setText(str(self.corrected_time))

        print(created_at)
        print(time_offset)
        print(self.corrected_time)

    def sync_from_playlist_item(self):
        for i, item in enumerate(
                self.playlist_widget.playlist_list.selectedItems()):
            if item.__class__ is PlaylistItemWidget:
                for i, m in enumerate(item.playlist_item.media_list):
                    self.video_decks[i].seek(m["time"])

    def on_launch_vlc(self):
        for deck in self.video_decks:
            deck.vlc_instance.launch()

    def on_playlist_item_played(self, playlist_item):
        for i, media_info in enumerate(playlist_item):
            if i >= len(self.video_decks):
                print(
                    "<!> Not enough decks to load all the playlist item videos!"
                )
                break

            self.video_decks[i].load_video_url(media_info["url"])
Ejemplo n.º 29
0
class SubtitleInfoDialog(QDialog):
    def __init__(self,
                 subtitle_name="Test",
                 subtitle_delay=0.0,
                 subtitle_language=Default_Subtitle_Language,
                 subtitle_track_name="Test",
                 subtitle_set_default=False,
                 subtitle_set_forced=False,
                 subtitle_default_value_delay=0.0,
                 subtitle_default_value_language=Default_Subtitle_Language,
                 subtitle_default_value_track_name="Test",
                 subtitle_default_value_set_default=False,
                 subtitle_default_value_set_forced=False,
                 subtitle_set_default_disabled=False,
                 subtitle_set_forced_disabled=False,
                 disable_edit=False,
                 parent=None):
        super().__init__(parent)
        self.window_title = "Subtitle Info"
        self.state = "no"
        self.messageIcon = QLabel()

        self.disable_edit = disable_edit

        self.current_subtitle_language = str(subtitle_language)
        self.current_subtitle_delay = str(subtitle_delay)
        self.current_subtitle_track_name = str(subtitle_track_name)
        self.current_subtitle_set_default = subtitle_set_default
        self.current_subtitle_set_forced = subtitle_set_forced

        self.default_subtitle_language = str(subtitle_default_value_language)
        self.default_subtitle_delay = str(subtitle_default_value_delay)
        self.default_subtitle_track_name = str(
            subtitle_default_value_track_name)
        self.default_subtitle_set_default = subtitle_default_value_set_default
        self.default_subtitle_set_forced = subtitle_default_value_set_forced

        self.subtitle_set_default_disabled = subtitle_set_default_disabled
        self.subtitle_set_forced_disabled = subtitle_set_forced_disabled

        self.subtitle_name_label = QLabel("Subtitle Name:")
        self.subtitle_name_value = QLabel(str(subtitle_name))

        self.subtitle_delay_label = QLabel("Subtitle Delay:")
        self.subtitle_delay_spin = QDoubleSpinBox()
        self.setup_subtitle_delay_spin()

        self.subtitle_language_label = QLabel("Subtitle Language:")
        self.subtitle_language_comboBox = QComboBox()
        self.setup_subtitle_language_comboBox()

        self.subtitle_track_name_label = QLabel("Subtitle Track Name:")
        self.subtitle_track_name_lineEdit = QLineEdit()
        self.setup_subtitle_track_name_lineEdit()

        self.subtitle_set_forced_label = QLabel("Subtitle Forced State:")
        self.subtitle_set_forced_checkBox = QCheckBox()
        self.setup_subtitle_set_forced_checkBox()

        self.subtitle_set_default_label = QLabel("Subtitle Default State:")
        self.subtitle_set_default_checkBox = QCheckBox()
        self.setup_subtitle_set_default_checkBox()

        self.yes_button = QPushButton("OK")
        self.no_button = QPushButton("Cancel")
        self.reset_button = QPushButton("Reset To Default")

        self.buttons_layout = QHBoxLayout()
        self.subtitle_delay_layout = QHBoxLayout()
        self.subtitle_language_layout = QHBoxLayout()
        self.subtitle_track_name_layout = QHBoxLayout()
        self.subtitle_set_default_layout = QHBoxLayout()
        self.subtitle_set_forced_layout = QHBoxLayout()
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.buttons_layout.addWidget(self.reset_button, stretch=2)
        self.buttons_layout.addWidget(self.yes_button, stretch=2)
        self.buttons_layout.addWidget(self.no_button, stretch=2)
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.subtitle_setting_layout = QGridLayout()
        self.subtitle_changeble_setting_layout = QFormLayout()
        self.subtitle_changeble_setting_layout.addRow(self.subtitle_name_label,
                                                      self.subtitle_name_value)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_track_name_label, self.subtitle_track_name_lineEdit)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_language_label, self.subtitle_language_comboBox)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_delay_label, self.subtitle_delay_spin)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_set_default_label,
            self.subtitle_set_default_checkBox)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_set_forced_label, self.subtitle_set_forced_checkBox)

        self.subtitle_setting_layout.addLayout(
            self.subtitle_changeble_setting_layout, 0, 0, 5, 2)
        self.subtitle_setting_layout.addWidget(self.messageIcon, 0, 3, 5, -1)

        self.main_layout = QGridLayout()
        self.main_layout.addLayout(self.subtitle_setting_layout, 0, 0, 2, 3)
        self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1)
        self.main_layout.setContentsMargins(20, 20, 20, 20)
        self.setLayout(self.main_layout)

        self.setup_ui()
        self.signal_connect()

    def setup_ui(self):
        self.disable_question_mark_window()
        self.messageIcon.setPixmap(
            QtGui.QPixmap(GlobalFiles.SubtitleIconPath).scaledToHeight(100))
        self.set_dialog_values()
        self.set_default_buttons()
        if self.subtitle_set_default_disabled:
            self.subtitle_set_default_disable()
        if self.subtitle_set_forced_disabled:
            self.subtitle_set_forced_disable()
        if self.disable_edit:
            self.subtitle_track_name_lineEdit.setEnabled(False)
            self.subtitle_language_comboBox.setEnabled(False)
            self.subtitle_delay_spin.setEnabled(False)
            self.subtitle_set_default_checkBox.setEnabled(False)
            self.subtitle_set_forced_checkBox.setEnabled(False)
            self.reset_button.setEnabled(False)

        self.setup_tool_tip_hint_subtitle_set_default()
        self.setup_tool_tip_hint_subtitle_set_forced()

    def signal_connect(self):
        self.subtitle_track_name_lineEdit.textEdited.connect(
            self.update_current_subtitle_track_name)
        self.subtitle_delay_spin.editingFinished.connect(
            self.update_current_subtitle_delay)
        self.subtitle_language_comboBox.currentTextChanged.connect(
            self.update_current_subtitle_language)
        self.subtitle_set_default_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_default)
        self.subtitle_set_forced_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_forced)
        self.yes_button.clicked.connect(self.click_yes)
        self.no_button.clicked.connect(self.click_no)
        self.reset_button.clicked.connect(self.reset_subtitle_setting)

    def click_yes(self):
        self.state = "yes"
        self.close()

    def click_no(self):
        self.close()

    def set_dialog_values(self):
        self.setWindowTitle(self.window_title)
        self.setWindowIcon(GlobalFiles.InfoSettingIcon)

    def disable_question_mark_window(self):
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False)

    def increase_message_font_size(self, value):
        message_font = self.message.font()
        message_font.setPointSize(self.message.fontInfo().pointSize() + value)
        self.message.setFont(message_font)

    def set_default_buttons(self):
        self.yes_button.setDefault(True)
        self.yes_button.setFocus()

    def showEvent(self, a0: QtGui.QShowEvent) -> None:
        super().showEvent(a0)
        self.setFixedSize(self.size())

    def setup_subtitle_track_name_lineEdit(self):
        self.subtitle_track_name_lineEdit.setClearButtonEnabled(True)
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name)

    def setup_subtitle_language_comboBox(self):
        self.subtitle_language_comboBox.addItems(AllSubtitlesLanguages)
        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(self.current_subtitle_language))
        self.subtitle_language_comboBox.setMaxVisibleItems(8)
        self.subtitle_language_comboBox.setStyleSheet(
            "QComboBox { combobox-popup: 0; }")

    def setup_subtitle_delay_spin(self):
        # self.subtitle_delay_spin.setMaximumWidth(screen_size.width() // 16)
        self.subtitle_delay_spin.setDecimals(3)
        self.subtitle_delay_spin.setMinimum(-9999.0)
        self.subtitle_delay_spin.setMaximum(9999.0)
        self.subtitle_delay_spin.setSingleStep(0.5)
        self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay))

    def setup_subtitle_set_default_checkBox(self):
        self.subtitle_set_default_checkBox.setText("Set Default")
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default))

    def setup_subtitle_set_forced_checkBox(self):
        self.subtitle_set_forced_checkBox.setText("Set Forced")
        self.subtitle_set_forced_checkBox.setChecked(
            bool(self.current_subtitle_set_forced))

    def update_current_subtitle_track_name(self):
        self.current_subtitle_track_name = str(
            self.subtitle_track_name_lineEdit.text())

    def update_current_subtitle_delay(self):
        self.current_subtitle_delay = round(self.subtitle_delay_spin.value(),
                                            5)

    def update_current_subtitle_language(self):
        self.current_subtitle_language = str(
            self.subtitle_language_comboBox.currentText())

    def update_current_subtitle_set_default(self):
        self.current_subtitle_set_default = (
            self.subtitle_set_default_checkBox.checkState() == Qt.Checked)

    def update_current_subtitle_set_forced(self):
        self.current_subtitle_set_forced = (
            self.subtitle_set_forced_checkBox.checkState() == Qt.Checked)

    def reset_subtitle_setting(self):
        self.current_subtitle_language = self.default_subtitle_language
        self.current_subtitle_delay = self.default_subtitle_delay
        self.current_subtitle_track_name = self.default_subtitle_track_name
        self.current_subtitle_set_default = self.default_subtitle_set_default
        self.current_subtitle_set_forced = self.default_subtitle_set_forced

        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(self.current_subtitle_language))
        self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay))
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name)
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default))
        self.subtitle_set_forced_checkBox.setChecked(
            bool(self.current_subtitle_set_forced))

    def subtitle_set_default_disable(self):
        self.subtitle_set_default_checkBox.setDisabled(True)

    def subtitle_set_forced_disable(self):
        self.subtitle_set_forced_checkBox.setDisabled(True)

    def setup_tool_tip_hint_subtitle_set_default(self):
        if self.subtitle_set_default_checkBox.isEnabled():
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track "
                "when play")
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default</b> is enabled on mux setting tab "
            )
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)

    def setup_tool_tip_hint_subtitle_set_forced(self):
        if self.subtitle_set_forced_checkBox.isEnabled():
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when "
                "play")
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default and forced</b> is enabled on mux setting tab "
            )
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)

    def execute(self):
        self.exec_()
Ejemplo n.º 30
0
class AdapterSettingsDialog(QDialog):
    def __init__(self, parent, data):
        assert type(data) == BinaryView
        self.bv = data
        QDialog.__init__(self, parent)

        debug_state = binjaplug.get_state(self.bv)

        self.setWindowTitle("Debug Adapter Settings")
        self.setMinimumSize(UIContext.getScaledWindowSize(400, 130))
        self.setAttribute(Qt.WA_DeleteOnClose)

        layout = QVBoxLayout()
        layout.setSpacing(0)

        titleLabel = QLabel("Adapter Settings")
        titleLayout = QHBoxLayout()
        titleLayout.setContentsMargins(0, 0, 0, 0)
        titleLayout.addWidget(titleLabel)

        self.adapterEntry = QPushButton(self)
        self.adapterMenu = QMenu(self)
        for adapter in DebugAdapter.ADAPTER_TYPE:
            if not DebugAdapter.ADAPTER_TYPE.can_use(adapter):
                continue

            def select_adapter(adapter):
                return lambda: self.selectAdapter(adapter)

            self.adapterMenu.addAction(adapter.name, select_adapter(adapter))
            if adapter == debug_state.adapter_type:
                self.adapterEntry.setText(adapter.name)

        self.adapterEntry.setMenu(self.adapterMenu)

        self.argumentsEntry = QLineEdit(self)
        self.addressEntry = QLineEdit(self)
        self.portEntry = QLineEdit(self)

        self.formLayout = QFormLayout()
        self.formLayout.addRow("Adapter Type", self.adapterEntry)
        self.formLayout.addRow("Command Line Arguments", self.argumentsEntry)
        self.formLayout.addRow("Address", self.addressEntry)
        self.formLayout.addRow("Port", self.portEntry)

        buttonLayout = QHBoxLayout()
        buttonLayout.setContentsMargins(0, 0, 0, 0)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(lambda: self.reject())
        self.acceptButton = QPushButton("Accept")
        self.acceptButton.clicked.connect(lambda: self.accept())
        self.acceptButton.setDefault(True)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.cancelButton)
        buttonLayout.addWidget(self.acceptButton)

        layout.addLayout(titleLayout)
        layout.addSpacing(10)
        layout.addLayout(self.formLayout)
        layout.addStretch(1)
        layout.addSpacing(10)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)

        self.addressEntry.setText(debug_state.remote_host)
        self.portEntry.setText(str(debug_state.remote_port))

        self.addressEntry.textEdited.connect(lambda: self.apply())
        self.portEntry.textEdited.connect(lambda: self.apply())

        self.argumentsEntry.setText(' '.join(
            shlex.quote(arg) for arg in debug_state.command_line_args))
        self.argumentsEntry.textEdited.connect(lambda: self.updateArguments())

        self.accepted.connect(lambda: self.apply())

    def selectAdapter(self, adapter):
        self.bv.store_metadata('debugger.adapter_type', adapter.value)
        debug_state = binjaplug.get_state(self.bv)
        debug_state.adapter_type = adapter
        self.adapterEntry.setText(adapter.name)

        if DebugAdapter.ADAPTER_TYPE.use_exec(adapter):
            self.argumentsEntry.setEnabled(True)
            self.addressEntry.setEnabled(False)
            self.portEntry.setEnabled(False)
        elif DebugAdapter.ADAPTER_TYPE.use_connect(adapter):
            self.argumentsEntry.setEnabled(False)
            self.addressEntry.setEnabled(True)
            self.portEntry.setEnabled(True)

    def apply(self):
        debug_state = binjaplug.get_state(self.bv)
        arguments = shlex.split(self.argumentsEntry.text())
        debug_state.command_line_args = arguments
        self.bv.store_metadata('debugger.command_line_args', arguments)

        address = self.addressEntry.text()
        port = int(self.portEntry.text())

        debug_state.remote_host = address
        debug_state.remote_port = port

        self.bv.store_metadata('debugger.remote_host', address)
        self.bv.store_metadata('debugger.remote_port', port)

    def updateArguments(self):
        try:
            arguments = shlex.split(self.argumentsEntry.text())
            self.acceptButton.setEnabled(True)
        except:
            self.acceptButton.setEnabled(False)