Exemplo n.º 1
0
    def __generateKeyWidget__(self):
        topWidget = QWidget()
        topLayout = QHBoxLayout()
        topLayout.setSpacing(0)
        topLayout.setContentsMargins(0, 0, 0, 0)
        topWidget.setLayout(topLayout)

        keyInput = QComboBox()
        keyInput.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        keyInput.setEditable(True)
        keyInput.lineEdit().setPlaceholderText("'highway', 'name'...")
        keyInput.addItems(self.keyList)
        topLayout.addWidget(keyInput)

        filterOptionsButton = IconButton(
            QIcon(os.path.join(picturesDir, "options.png")),
            topWidget.windowHandle(), keyInput.height())
        filterOptionsButton.setStyleSheet(
            """QPushButton::menu-indicator{image: none;}""")

        filterOptionsMenu = QMenu()

        removeAct = QAction('Remove filter', self)
        removeAct.triggered.connect(self.deleteLater)
        filterOptionsMenu.addAction(removeAct)

        helpAct = QAction('Help', self)
        helpAct.triggered.connect(self.getInfo)
        filterOptionsMenu.addAction(helpAct)

        filterOptionsButton.setMenu(filterOptionsMenu)
        filterOptionsButton.setFlat(True)
        topLayout.addWidget(filterOptionsButton)

        return topWidget, keyInput
class ComboDelegate(QItemDelegate):
    def __init__(self, parent, items, model):
        super(ComboDelegate, self).__init__(parent)
        self.combo = None
        self.items = items
        self.tableModel = model
        self.oldData = ""

    def createEditor(self, parent, options, index):
        self.combo = QComboBox(parent)
        self.combo.addItems(self.items)
        self.combo.setEditable(True)
        self.combo.setCurrentIndex(0)
        self.combo.currentData(QtCore.Qt.DisplayRole)
        self.combo.lineEdit().setReadOnly(True)
        self.combo.currentIndexChanged.connect(self.currentIndexChanged)
        return self.combo

    def setModelData(self, editor, model, index):
        model.setData(index, editor.currentText(), QtCore.Qt.DisplayRole)

    @QtCore.pyqtSlot()
    def currentIndexChanged(self):
        self.commitData.emit(self.sender())

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        print("setData", index.row(), index.column(), value)
        self.tableModel.setData(index, value, role)
        print(self.tableModel.data)
Exemplo n.º 3
0
class Printing(preferences.Group):
    def __init__(self, page):
        super(Printing, self).__init__(page)

        layout = QGridLayout()
        self.setLayout(layout)
        self.printArthurBackend = QCheckBox(toggled=self.changed)
        self.useCups = QCheckBox(toggled=self.changed)
        self.resolutionLabel = QLabel()
        self.resolution = QComboBox(editable=True, editTextChanged=page.changed)
        self.resolution.addItems("300 600 1200".split())
        self.resolution.lineEdit().setInputMask("9000")

        layout.addWidget(self.printArthurBackend, 0, 0, 1, 2)
        layout.addWidget(self.useCups, 1, 0, 1, 2)
        layout.addWidget(self.resolutionLabel, 2, 0)
        layout.addWidget(self.resolution, 2, 1)

        app.translateUI(self)

        if not qpageview.cupsprinter.handle():
            self.useCups.setEnabled(False)

    def translateUI(self):
        self.setTitle(_("Printing of Music"))
        self.printArthurBackend.setText(_("Use vector based backend (Arthur) for printing PDF documents"))
        self.printArthurBackend.setToolTip(_(
            "If checked, Frescobaldi will use the Arthur backend of the Poppler\n"
            "library for printing PDF documents. A big advantage of the Arthur backend\n"
            "is that it is vector-based, in contrast to the default Splash backend,\n"
            "which is raster-based. But Arthur is more experimental."))
        self.useCups.setText(_("Print PDF documents directly to CUPS if available."))
        self.useCups.setToolTip(_(
            "If checked, Frescobaldi tries to print a PDF document directly using\n"
            "the CUPS server, if available."))
        self.resolutionLabel.setText(_("Resolution:"))
        self.resolution.setToolTip(_(
            "Set the resolution if Frescobaldi prints using raster images."))

    def loadSettings(self):
        s = QSettings()
        useArthurPrint = s.value("printing/arthurbackend_print", True, bool)
        self.printArthurBackend.setChecked(useArthurPrint)
        # see comment in pagedview and warning messages in musicview/__init__
        # and viewers/__init__ for the rationale for the default value
        self.useCups.setChecked(s.value("printing/directcups",
                False if sys.platform.startswith('darwin') else True,
                bool))
        with qutil.signalsBlocked(self.resolution):
            self.resolution.setEditText(format(s.value("printing/dpi", 300, int)))

    def saveSettings(self):
        s = QSettings()
        s.setValue("printing/arthurbackend_print", self.printArthurBackend.isChecked())
        s.setValue("printing/directcups", self.useCups.isChecked())
        s.setValue("printing/dpi", int(self.resolution.currentText()))
Exemplo n.º 4
0
 def createWidget(self, parent):
     w = QComboBox(parent)
     w.setSizeAdjustPolicy(QComboBox.AdjustToContents)
     w.setEditable(True)
     w.lineEdit().setReadOnly(True)
     w.setFocusPolicy(Qt.NoFocus)
     self._setupComboBox(w)
     self._adjustComboBox(w)
     w.activated[int].connect(self.setCurrentIndex)
     return w
Exemplo n.º 5
0
class Window(QMainWindow):
    def __init__(self, application):
        super().__init__()
        self.application = application
        self.screenSize = application.desktop().screenGeometry()
        self.title = 'Nexus visualisation'
        self.left = 0
        self.top = 0
        self.width = self.screenSize.width()
        self.height = self.screenSize.height()

        self.init_ui()

        self.show()

    def init_ui(self):
        # Set the title and the geometry for the window
        self.setWindowTitle(self.title)
        self.setGeometry((self.width - self.screenSize.width()) // 2,
                         (self.height - self.screenSize.height()) // 2,
                         self.width, self.height)

        # Create the widget that will contain the button selection and the tabs
        widget = QWidget()
        layout = QVBoxLayout()
        self.selectionButton = QComboBox(self)
        # Let the software edit the text in the button
        self.selectionButton.setEditable(True)
        # Prevent user from rewrite the names of the detector
        self.selectionButton.lineEdit().setReadOnly(True)
        # Align the text
        self.selectionButton.lineEdit().setAlignment(Qt.AlignCenter)
        # Populate the selection button with the detectors' name
        for detector in Detectors:
            self.selectionButton.addItem(detector.value)
        self.selectionButton.currentTextChanged.connect(self.change_tab)
        self.table_widget = self.init_detector_ui()

        layout.addWidget(self.selectionButton)
        layout.addWidget(self.table_widget)
        widget.setLayout(layout)
        # Set the global widget in the window
        self.setCentralWidget(widget)

    def init_detector_ui(self) -> QTabWidget or None:
        if self.selectionButton.currentText() == Detectors.XPAD.value:
            return xpad.Xpad(self.application)
        if self.selectionButton.currentText() == Detectors.CIRPAD.value:
            return cirpad.CirpadContext()

    def change_tab(self) -> None:
        clear_tab(self.centralWidget().layout())
        self.table_widget = self.initDetectorUI()
        self.centralWidget().layout().addWidget(self.table_widget)
Exemplo n.º 6
0
 def setup_combo_completer(combo_widget: QtWidgets.QComboBox):
     combo_widget.setEditable(True)
     combo_widget.setInsertPolicy(QtWidgets.QComboBox.NoInsert)
     combo_widget.lineEdit().editingFinished.connect(
         lambda: combo_widget.setCurrentIndex(
             combo_widget.findText(combo_widget.currentText())))
     completer = combo_widget.completer()
     completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
     completer.popup().setAlternatingRowColors(True)
     completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
     completer.setFilterMode(QtCore.Qt.MatchContains)
Exemplo n.º 7
0
class MainWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.w = None  # No external window yet.
        self.activity_list_menu = QComboBox()
        self.activity_list_menu.setEditable(True)
        self.activity_list_menu.addItems(self.get_activities())
        self.line_menu = self.activity_list_menu.lineEdit()
        self.line_menu.setAlignment(Qt.AlignCenter)
        self.button = QPushButton("Start Activity")
        self.button.clicked.connect(self.start_activity)
        layout=QGridLayout()
        layout.addWidget(self.activity_list_menu)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def start_activity(self):
       self.timer_window = Activity(self)
       self.hide()
       self.timer_window.show()

    def get_activities(self):
        with open("data/activity.csv") as f:
            reader = csv.reader(f, delimiter=',')
            activity_list = []
            a_list = set([row[0] for row in reader])
            for a in a_list:
                activity_list.append(a)
            return activity_list
Exemplo n.º 8
0
class Printing(preferences.Group):
    def __init__(self, page):
        super(Printing, self).__init__(page)

        layout = QGridLayout()
        self.setLayout(layout)
        self.useCups = QCheckBox(toggled=self.changed)
        self.resolutionLabel = QLabel()
        self.resolution = QComboBox(editable=True,
                                    editTextChanged=page.changed)
        self.resolution.addItems("300 600 1200".split())
        self.resolution.lineEdit().setInputMask("9000")

        layout.addWidget(self.useCups, 0, 0, 1, 2)
        layout.addWidget(self.resolutionLabel, 1, 0)
        layout.addWidget(self.resolution, 1, 1)

        app.translateUI(self)

        if not qpageview.cupsprinter.handle():
            self.useCups.setEnabled(False)

    def translateUI(self):
        self.setTitle(_("Printing of Music"))
        self.useCups.setText(
            _("Print PDF documents directly to CUPS if available."))
        self.useCups.setToolTip(
            _("If checked, Frescobaldi tries to print a PDF document direcly using\n"
              "the CUPS server, if available."))
        self.resolutionLabel.setText(_("Resolution:"))
        self.resolution.setToolTip(
            _("Set the resolution if Frescobaldi prints using raster images."))

    def loadSettings(self):
        s = QSettings()
        self.useCups.setChecked(s.value("printing/directcups", True, bool))
        with qutil.signalsBlocked(self.resolution):
            self.resolution.setEditText(
                format(s.value("printing/dpi", 300, int)))

    def saveSettings(self):
        s = QSettings()
        s.setValue("printing/directcups", self.useCups.isChecked())
        s.setValue("printing/dpi", int(self.resolution.currentText()))
Exemplo n.º 9
0
    def _showEditDialog(self, title, rSite='', rUserAgent=''):
        if not rSite or not rUserAgent:
            return False, '', ''

        dialog = QDialog(self)
        layout = QFormLayout(dialog)
        editSite = QLineEdit(dialog)
        editAgent = QComboBox(dialog)
        editAgent.setLayoutDirection(Qt.LeftToRight)
        editAgent.setEditable(True)
        editAgent.addItems(self._knownUserAgents)

        box = QDialogButtonBox(dialog)
        box.addButton(QDialogButtonBox.Ok)
        box.addButton(QDialogButtonBox.Cancel)

        box.rejected.connect(dialog.reject)
        box.accepted.connect(dialog.accept)

        layout.addRow(QLabel(_('Site domain:')), editSite)
        layout.addRow(QLabel(_('User Agent:')), editAgent)
        layout.addRow(box)

        editSite.setText(rSite)
        editAgent.lineEdit().setText(rUserAgent)

        editSite.setFocus()
        editAgent.lineEdit().setCursorPosition(0)

        dialog.setWindowTitle(title)
        dialog.setMinimumSize(550, 100)
        dialog.setMaximumWidth(550)

        if dialog.exec_():
            rSite = editSite.text()
            rUserAgent = editAgent.currentText()

            return bool(rSite and rUserAgent)

        return False
Exemplo n.º 10
0
    def createEditor(self):
        # setup data model
        self._model = QSqlTableModel()
        self._model.setTable(self.table)
        self._col = self._model.fieldIndex(self.column)

        # setup filter model for sorting and filtering
        self._proxy = QSortFilterProxyModel()
        self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self._proxy.setSourceModel(self._model)
        self._proxy.setFilterKeyColumn(self._col)

        # setup completer
        self._completer = QCompleter()
        self._completer.setModel(self._proxy)
        self._completer.setCompletionColumn(self._col)
        self._completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        # setup combobox
        editor = QComboBox()
        editor.setModel(self._proxy)
        editor.setModelColumn(self._col)
        editor.setEditable(True)
        editor.setFocusPolicy(Qt.StrongFocus)
        editor.setInsertPolicy(QComboBox.NoInsert)
        editor.setCompleter(self._completer)

        # setup connections
        editor.currentTextChanged[str].connect(self.onActivated)

        # setup editor appearence
        style = self.style()
        editor.setStyleSheet(style)
        editor.lineEdit().setStyleSheet(style)
        font = editor.font()
        self._completer.popup().setFont(font)

        return editor
Exemplo n.º 11
0
class FontToolBar(QToolBar):

    def __init__(self, string, pointSize, parent=None):
        super(FontToolBar, self).__init__(parent)
        auxiliaryWidth = self.fontMetrics().width('0') * 8
        self.leftTextField = QLineEdit(self)
        self.leftTextField.setMaximumWidth(auxiliaryWidth)
        self.textField = QLineEdit(string, self)
        self.rightTextField = QLineEdit(self)
        self.rightTextField.setMaximumWidth(auxiliaryWidth)
        self.leftTextField.textEdited.connect(self.textField.textEdited)
        self.rightTextField.textEdited.connect(self.textField.textEdited)
        self.comboBox = QComboBox(self)
        self.comboBox.setEditable(True)
        self.comboBox.setValidator(QIntValidator(self))
        for p in pointSizes:
            self.comboBox.addItem(str(p))
        self.comboBox.lineEdit().setText(str(pointSize))

        self.configBar = QPushButton(self)
        self.configBar.setFlat(True)
        self.configBar.setIcon(QIcon(":/resources/settings.svg"))
        self.configBar.setStyleSheet("padding: 2px 0px; padding-right: 10px")
        self.toolsMenu = QMenu(self)
        showKerning = self.toolsMenu.addAction(
            "Show Kerning", self.showKerning)
        showKerning.setCheckable(True)
        showMetrics = self.toolsMenu.addAction(
            "Show Metrics", self.showMetrics)
        showMetrics.setCheckable(True)
        self.toolsMenu.addSeparator()
        wrapLines = self.toolsMenu.addAction("Wrap lines", self.wrapLines)
        wrapLines.setCheckable(True)
        noWrapLines = self.toolsMenu.addAction("No wrap", self.noWrapLines)
        noWrapLines.setCheckable(True)
        self.toolsMenu.addSeparator()
        verticalFlip = self.toolsMenu.addAction(
            "Vertical flip", self.verticalFlip)
        verticalFlip.setCheckable(True)
        """
        lineHeight = QWidgetAction(self.toolsMenu)
        lineHeight.setText("Line height:")
        lineHeightSlider = QSlider(Qt.Horizontal, self)
        # QSlider works with integers so we'll just divide by 100 what comes
        # out of it
        lineHeightSlider.setMinimum(80)
        lineHeightSlider.setMaximum(160)
        lineHeightSlider.setValue(100)
        #lineHeightSlider.setContentsMargins(30, 0, 30, 0)
        lineHeightSlider.valueChanged.connect(self.lineHeight)
        lineHeight.setDefaultWidget(lineHeightSlider)
        self.toolsMenu.addAction(lineHeight)
        """

        wrapLinesGroup = QActionGroup(self)
        wrapLinesGroup.addAction(wrapLines)
        wrapLinesGroup.addAction(noWrapLines)
        wrapLines.setChecked(True)
        # self.toolsMenu.setActiveAction(wrapLines)
        self.configBar.setMenu(self.toolsMenu)

        self.addWidget(self.leftTextField)
        self.addWidget(self.textField)
        self.addWidget(self.rightTextField)
        self.addWidget(self.comboBox)
        self.addWidget(self.configBar)

    def showEvent(self, event):
        super(FontToolBar, self).showEvent(event)
        self.textField.setFocus(True)

    def setPointSize(self, pointSize):
        self.comboBox.blockSignals(True)
        self.comboBox.setEditText(str(pointSize))
        self.comboBox.blockSignals(False)

    def showKerning(self):
        action = self.sender()
        self.parent().canvas.setShowKerning(action.isChecked())

    def showMetrics(self):
        action = self.sender()
        self.parent().canvas.setShowMetrics(action.isChecked())

    def verticalFlip(self):
        action = self.sender()
        self.parent().canvas.setVerticalFlip(action.isChecked())

    def lineHeight(self, value):
        self.parent().canvas.setLineHeight(value / 100)

    def wrapLines(self):
        self.parent().canvas.setWrapLines(True)

    def noWrapLines(self):
        self.parent().canvas.setWrapLines(False)
Exemplo n.º 12
0
class LocationDialog(QDialog):
    def __init__(self, parent=None):
        super(LocationDialog, self).__init__(parent)

        self.formatComboBox = QComboBox()
        self.formatComboBox.addItem("Native")
        self.formatComboBox.addItem("INI")

        self.scopeComboBox = QComboBox()
        self.scopeComboBox.addItem("User")
        self.scopeComboBox.addItem("System")

        self.organizationComboBox = QComboBox()
        self.organizationComboBox.addItem("Trolltech")
        self.organizationComboBox.setEditable(True)

        self.applicationComboBox = QComboBox()
        self.applicationComboBox.addItem("Any")
        self.applicationComboBox.addItem("Application Example")
        self.applicationComboBox.addItem("Assistant")
        self.applicationComboBox.addItem("Designer")
        self.applicationComboBox.addItem("Linguist")
        self.applicationComboBox.setEditable(True)
        self.applicationComboBox.setCurrentIndex(3)

        formatLabel = QLabel("&Format:")
        formatLabel.setBuddy(self.formatComboBox)

        scopeLabel = QLabel("&Scope:")
        scopeLabel.setBuddy(self.scopeComboBox)

        organizationLabel = QLabel("&Organization:")
        organizationLabel.setBuddy(self.organizationComboBox)

        applicationLabel = QLabel("&Application:")
        applicationLabel.setBuddy(self.applicationComboBox)

        self.locationsGroupBox = QGroupBox("Setting Locations")

        self.locationsTable = QTableWidget()
        self.locationsTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.locationsTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.locationsTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.locationsTable.setColumnCount(2)
        self.locationsTable.setHorizontalHeaderLabels(("Location", "Access"))
        self.locationsTable.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch
        )
        self.locationsTable.horizontalHeader().resizeSection(1, 180)

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

        self.formatComboBox.activated.connect(self.updateLocationsTable)
        self.scopeComboBox.activated.connect(self.updateLocationsTable)
        self.organizationComboBox.lineEdit().editingFinished.connect(
            self.updateLocationsTable
        )
        self.applicationComboBox.lineEdit().editingFinished.connect(
            self.updateLocationsTable
        )
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        locationsLayout = QVBoxLayout()
        locationsLayout.addWidget(self.locationsTable)
        self.locationsGroupBox.setLayout(locationsLayout)

        mainLayout = QGridLayout()
        mainLayout.addWidget(formatLabel, 0, 0)
        mainLayout.addWidget(self.formatComboBox, 0, 1)
        mainLayout.addWidget(scopeLabel, 1, 0)
        mainLayout.addWidget(self.scopeComboBox, 1, 1)
        mainLayout.addWidget(organizationLabel, 2, 0)
        mainLayout.addWidget(self.organizationComboBox, 2, 1)
        mainLayout.addWidget(applicationLabel, 3, 0)
        mainLayout.addWidget(self.applicationComboBox, 3, 1)
        mainLayout.addWidget(self.locationsGroupBox, 4, 0, 1, 2)
        mainLayout.addWidget(self.buttonBox, 5, 0, 1, 2)
        self.setLayout(mainLayout)

        self.updateLocationsTable()

        self.setWindowTitle("Open Application Settings")
        self.resize(650, 400)

    def format(self):
        if self.formatComboBox.currentIndex() == 0:
            return QSettings.NativeFormat
        else:
            return QSettings.IniFormat

    def scope(self):
        if self.scopeComboBox.currentIndex() == 0:
            return QSettings.UserScope
        else:
            return QSettings.SystemScope

    def organization(self):
        return self.organizationComboBox.currentText()

    def application(self):
        if self.applicationComboBox.currentText() == "Any":
            return ""

        return self.applicationComboBox.currentText()

    def updateLocationsTable(self):
        self.locationsTable.setUpdatesEnabled(False)
        self.locationsTable.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue

                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ""

                settings = QSettings(
                    self.format(), actualScope, self.organization(), actualApplication
                )

                row = self.locationsTable.rowCount()
                self.locationsTable.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locationsTable.setItem(row, 0, item0)
                self.locationsTable.setItem(row, 1, item1)

        self.locationsTable.setUpdatesEnabled(True)
Exemplo n.º 13
0
class Widget(QWidget):
    def __init__(self, dockwidget):
        super(Widget, self).__init__(dockwidget)
        self._document = None
        self._fileSelector = QComboBox(editable=True, insertPolicy=QComboBox.NoInsert)
        gadgets.drag.ComboDrag(self._fileSelector).role = Qt.UserRole
        self._fileSelector.lineEdit().setReadOnly(True)
        self._fileSelector.lineEdit().setFocusPolicy(Qt.NoFocus)
        self._stopButton = QToolButton()
        self._playButton = QToolButton()
        self._timeSlider = QSlider(Qt.Horizontal, tracking=False,
            singleStep=500, pageStep=5000, invertedControls=True)
        self._display = Display()
        self._tempoFactor = QSlider(Qt.Vertical, minimum=-50, maximum=50,
            singleStep=1, pageStep=5)
        
        grid = QGridLayout(spacing=0)
        self.setLayout(grid)
        
        grid.addWidget(self._fileSelector, 0, 0, 1, 3)
        grid.addWidget(self._stopButton, 1, 0)
        grid.addWidget(self._playButton, 1, 1)
        grid.addWidget(self._timeSlider, 1, 2)
        grid.addWidget(self._display, 2, 0, 1, 3)
        grid.addWidget(self._tempoFactor, 0, 3, 3, 1)
        
        # size policy of combo
        p = self._fileSelector.sizePolicy()
        p.setHorizontalPolicy(QSizePolicy.Ignored)
        self._fileSelector.setSizePolicy(p)
        
        # size policy of combo popup
        p = self._fileSelector.view().sizePolicy()
        p.setHorizontalPolicy(QSizePolicy.MinimumExpanding)
        self._fileSelector.view().setSizePolicy(p)

        self._player = player.Player()
        self._outputCloseTimer = QTimer(interval=60000, singleShot=True,
            timeout=self.closeOutput)
        self._timeSliderTicker = QTimer(interval=200, timeout=self.updateTimeSlider)
        self._fileSelector.activated[int].connect(self.slotFileSelected)
        self._tempoFactor.valueChanged.connect(self.slotTempoChanged)
        self._timeSlider.valueChanged.connect(self.slotTimeSliderChanged)
        self._timeSlider.sliderMoved.connect(self.slotTimeSliderMoved)
        self._player.beat.connect(self.updateDisplayBeat)
        self._player.time.connect(self.updateDisplayTime)
        self._player.stateChanged.connect(self.slotPlayerStateChanged)
        self.slotPlayerStateChanged(False)
        dockwidget.mainwindow().currentDocumentChanged.connect(self.loadResults)
        app.jobFinished.connect(self.slotUpdatedFiles)
        app.aboutToQuit.connect(self.stop)
        midihub.aboutToRestart.connect(self.slotAboutToRestart)
        midihub.settingsChanged.connect(self.clearMidiSettings, -100)
        midihub.settingsChanged.connect(self.readMidiSettings)
        app.documentClosed.connect(self.slotDocumentClosed)
        app.translateUI(self)
        self.readMidiSettings()
        d = dockwidget.mainwindow().currentDocument()
        if d:
            self.loadResults(d)

    def translateUI(self):
        self._tempoFactor.setToolTip(_("Tempo"))
    
    def slotAboutToRestart(self):
        self.stop()
        self._player.set_output(None)
    
    def clearMidiSettings(self):
        """Called first when settings are changed."""
        self.stop()
        self._outputCloseTimer.stop()
        self._player.set_output(None)
        
    def readMidiSettings(self):
        """Called after clearMidiSettings(), and on first init."""
        pass
            
    def openOutput(self):
        """Called when playing starts. Ensures an output port is opened."""
        self._outputCloseTimer.stop()
        if not self._player.output():
            p = QSettings().value("midi/player/output_port", midihub.default_output(), str)
            o = midihub.output_by_name(p)
            if o:
                self._player.set_output(output.Output(o))
    
    def closeOutput(self):
        """Called when the output close timer fires. Closes the output."""
        self._player.set_output(None)
        
    def slotPlayerStateChanged(self, playing):
        ac = self.parentWidget().actionCollection
        # setDefaultAction also adds the action
        for b in self._stopButton, self._playButton:
            while b.actions():
                b.removeAction(b.actions()[0])
        if playing:
            self._timeSliderTicker.start()
            self._stopButton.setDefaultAction(ac.midi_stop)
            self._playButton.setDefaultAction(ac.midi_pause)
        else:
            self._timeSliderTicker.stop()
            self.updateTimeSlider()
            self._stopButton.setDefaultAction(ac.midi_restart)
            self._playButton.setDefaultAction(ac.midi_play)
            # close the output if the preference is set
            if QSettings().value("midi/close_outputs", False, bool):
                self._outputCloseTimer.start()
        
    def play(self):
        """Starts the MIDI player, opening an output if necessary."""
        if not self._player.is_playing() and not self._player.has_events():
            self.restart()
        self.openOutput()
        if not self._player.output():
            self._display.statusMessage(_("No output found!"))
        self._player.start()
    
    def stop(self):
        """Stops the MIDI player."""
        self._player.stop()
    
    def restart(self):
        """Restarts the MIDI player.
        
        If another file is in the file selector, or the file was updated,
        the new file is loaded.
        
        """
        self._player.seek(0)
        self.updateTimeSlider()
        self._display.reset()
        if self._document:
            files = midifiles.MidiFiles.instance(self._document)
            index = self._fileSelector.currentIndex()
            if files and (files.song(index) is not self._player.song()):
                self.loadSong(index)
        
    def slotTempoChanged(self, value):
        """Called when the user drags the tempo."""
        # convert -50 to 50 to 0.5 to 2.0
        factor = 2 ** (value / 50.0)
        self._player.set_tempo_factor(factor)
        self._display.setTempo("{0}%".format(int(factor * 100)))
    
    def slotTimeSliderChanged(self, value):
        self._player.seek(value)
        self._display.setTime(value)
        if self._player.song():
            self._display.setBeat(*self._player.song().beat(value)[1:])
    
    def slotTimeSliderMoved(self, value):
        self._display.setTime(value)
        if self._player.song():
            self._display.setBeat(*self._player.song().beat(value)[1:])
    
    def updateTimeSlider(self):
        if not self._timeSlider.isSliderDown():
            with qutil.signalsBlocked(self._timeSlider):
                self._timeSlider.setMaximum(self._player.total_time())
                self._timeSlider.setValue(self._player.current_time())

    def updateDisplayBeat(self, measnum, beat, num, den):
        if not self._timeSlider.isSliderDown():
            self._display.setBeat(measnum, beat, num, den)
    
    def updateDisplayTime(self, time):
        if not self._timeSlider.isSliderDown():
            self._display.setTime(time)
    
    def slotUpdatedFiles(self, document, job=None):
        """Called when there are new MIDI files."""
        mainwindow = self.parentWidget().mainwindow()
        import engrave
        if document not in (mainwindow.currentDocument(), engrave.engraver(mainwindow).document()):
            return
        import jobattributes
        if job and jobattributes.get(job).mainwindow != mainwindow:
            return
        self.loadResults(document)
    
    def loadResults(self, document):
        files = midifiles.MidiFiles.instance(document)
        if files.update():
            self._document = document
            self._fileSelector.setModel(files.model())
            self._fileSelector.setCurrentIndex(files.current)
            if not self._player.is_playing():
                self.loadSong(files.current)
    
    def loadSong(self, index):
        files = midifiles.MidiFiles.instance(self._document)
        self._player.set_song(files.song(index))
        m, s = divmod(self._player.total_time() // 1000, 60)
        name = self._fileSelector.currentText()
        self.updateTimeSlider()
        self._display.reset()
        self._display.statusMessage(
            _("midi lcd screen", "LOADED"), name,
            _("midi lcd screen", "TOTAL"), "{0}:{1:02}".format(m, s))
    
    def slotFileSelected(self, index):
        if self._document:
            self._player.stop()
            files = midifiles.MidiFiles.instance(self._document)
            if files:
                files.current = index
                self.restart()
    
    def slotDocumentClosed(self, document):
        if document == self._document:
            self._document = None
            self._fileSelector.clear()
            self._player.stop()
            self._player.clear()
            self.updateTimeSlider()
            self._display.reset()
Exemplo n.º 14
0
class LocationDialog(QDialog):
    def __init__(self, parent=None):
        super(LocationDialog, self).__init__(parent)

        self.formatComboBox = QComboBox()
        self.formatComboBox.addItem("Native")
        self.formatComboBox.addItem("INI")

        self.scopeComboBox = QComboBox()
        self.scopeComboBox.addItem("User")
        self.scopeComboBox.addItem("System")

        self.organizationComboBox = QComboBox()
        self.organizationComboBox.addItem("Trolltech")
        self.organizationComboBox.setEditable(True)

        self.applicationComboBox = QComboBox()
        self.applicationComboBox.addItem("Any")
        self.applicationComboBox.addItem("Application Example")
        self.applicationComboBox.addItem("Assistant")
        self.applicationComboBox.addItem("Designer")
        self.applicationComboBox.addItem("Linguist")
        self.applicationComboBox.setEditable(True)
        self.applicationComboBox.setCurrentIndex(3)

        formatLabel = QLabel("&Format:")
        formatLabel.setBuddy(self.formatComboBox)

        scopeLabel = QLabel("&Scope:")
        scopeLabel.setBuddy(self.scopeComboBox)

        organizationLabel = QLabel("&Organization:")
        organizationLabel.setBuddy(self.organizationComboBox)

        applicationLabel = QLabel("&Application:")
        applicationLabel.setBuddy(self.applicationComboBox)

        self.locationsGroupBox = QGroupBox("Setting Locations")

        self.locationsTable = QTableWidget()
        self.locationsTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.locationsTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.locationsTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.locationsTable.setColumnCount(2)
        self.locationsTable.setHorizontalHeaderLabels(("Location", "Access"))
        self.locationsTable.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.locationsTable.horizontalHeader().resizeSection(1, 180)

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

        self.formatComboBox.activated.connect(self.updateLocationsTable)
        self.scopeComboBox.activated.connect(self.updateLocationsTable)
        self.organizationComboBox.lineEdit().editingFinished.connect(self.updateLocationsTable)
        self.applicationComboBox.lineEdit().editingFinished.connect(self.updateLocationsTable)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        locationsLayout = QVBoxLayout()
        locationsLayout.addWidget(self.locationsTable)
        self.locationsGroupBox.setLayout(locationsLayout)

        mainLayout = QGridLayout()
        mainLayout.addWidget(formatLabel, 0, 0)
        mainLayout.addWidget(self.formatComboBox, 0, 1)
        mainLayout.addWidget(scopeLabel, 1, 0)
        mainLayout.addWidget(self.scopeComboBox, 1, 1)
        mainLayout.addWidget(organizationLabel, 2, 0)
        mainLayout.addWidget(self.organizationComboBox, 2, 1)
        mainLayout.addWidget(applicationLabel, 3, 0)
        mainLayout.addWidget(self.applicationComboBox, 3, 1)
        mainLayout.addWidget(self.locationsGroupBox, 4, 0, 1, 2)
        mainLayout.addWidget(self.buttonBox, 5, 0, 1, 2)
        self.setLayout(mainLayout)

        self.updateLocationsTable()

        self.setWindowTitle("Open Application Settings")
        self.resize(650, 400)

    def format(self):
        if self.formatComboBox.currentIndex() == 0:
            return QSettings.NativeFormat
        else:
            return QSettings.IniFormat

    def scope(self):
        if self.scopeComboBox.currentIndex() == 0:
            return QSettings.UserScope
        else:
            return QSettings.SystemScope

    def organization(self):
        return self.organizationComboBox.currentText()

    def application(self):
        if self.applicationComboBox.currentText() == "Any":
            return ''

        return self.applicationComboBox.currentText()

    def updateLocationsTable(self):
        self.locationsTable.setUpdatesEnabled(False)
        self.locationsTable.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue

                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ''

                settings = QSettings(self.format(), actualScope,
                        self.organization(), actualApplication)

                row = self.locationsTable.rowCount()
                self.locationsTable.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locationsTable.setItem(row, 0, item0)
                self.locationsTable.setItem(row, 1, item1)

        self.locationsTable.setUpdatesEnabled(True)
Exemplo n.º 15
0
class DuelLinksGui(QFrame, QMainWindow):
    _shouldShowSystrayBox = mock_data
    dlRunTime = None

    def __init__(self, duelLinksRunTime=None, assets=None):
        super(DuelLinksGui, self).__init__()
        self.assets = assets
        assert (type(duelLinksRunTime) is DuelLinkRunTime)
        self.dlRunTime = duelLinksRunTime  # type: DuelLinkRunTime
        self.createRunTimeFields()
        self.createBotControls()

        self.setObjectName("BotFrame")
        self.setStyleSheet("#BotFrame {border: 2px solid #9e3939;}")

        self.createActions()
        self.createBotActions()
        self.createTrayIcon()
        self.setShouldShowSystrayBox(mock_data)
        self.hideButton.clicked.connect(self.close)
        self.exitButton.clicked.connect(self.__quit__)
        self.trayIcon.messageClicked.connect(self.messageClicked)
        self.trayIcon.activated.connect(self.iconActivated)

        # bot actions connected
        self.pauseButton.clicked.connect(self.pause_bot)
        self.runButton.clicked.connect(self.start_bot)

        # log creation
        textViewLog = QtHandler()
        # You can format what is printed to text box
        textViewLog.setFormatter(
            logging.Formatter(
                '%(asctime)s | %(levelname)s | %(name)s | %(message)s',
                datefmt='%Y-%m-%d %H:%M:%S'))
        logging.getLogger('bot').addHandler(textViewLog)

        # self.textViewLog.signal.connect(self.add_to_log)
        self.tabs = QTabWidget(self)

        self.tab1 = QWidget(self)
        mainLayout = QVBoxLayout(self.tab1)
        mainLayout.addWidget(self.runTimeGroupBox)
        mainLayout.addWidget(self.botControls)
        self.tab1.setLayout(mainLayout)
        self.tabs.addTab(self.tab1, "General")

        self.clear_log = QPushButton("Clear log")
        self.tab2 = QWidget(self)
        logLayout = QVBoxLayout(self.tab2)
        self.textViewLog = QTextEdit(self.tab2)
        self.textViewLog.setReadOnly(True)
        self.clear_log.clicked.connect(self.textViewLog.clear)
        XStream.stdout().messageWritten.connect(self.add_to_log)
        XStream.stderr().messageWritten.connect(self.add_to_log)
        logLayout.addWidget(self.textViewLog)
        logLayout.addWidget(self.clear_log)
        self.tab2.setLayout(logLayout)
        self.tabs.addTab(self.tab2, "Log")

        viewlayout = QVBoxLayout(self)
        viewlayout.addWidget(self.tabs)
        self.setLayout(viewlayout)

        self.setIcon()
        self.trayIcon.show()
        self.setWindowTitle(app_name)
        self.setFixedSize(400, 300)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup)
        self.location_on_the_screen()
        self.update_values(True)

    def add_to_log(self, msg):
        try:
            cursor = self.textViewLog.textCursor()
            src = msg.split('|')
            if len(src) != 4:
                self.textViewLog.append(msg)
            else:
                text = ""
                text += "<span>"
                text += "<b>{}</b>".format(src[0])
                text += "<span style=\"color:blue;\">{}</span>".format(src[1])
                text += src[2]
                text += src[3]
                text += "</span>"
                cursor.insertHtml(text + "<br>")
            self.textViewLog.moveCursor(QtGui.QTextCursor.End)
        except Exception as e:
            print('Error on updating log: ', end='')
            print(e)

    def location_on_the_screen(self):
        ag = QDesktopWidget().availableGeometry()
        sg = QDesktopWidget().screenGeometry()
        widget = self.geometry()
        position = self.get_task_bar_position()
        if position == WINDOWS_TASKBAR_LOCATION.BOTTOM:
            x = ag.width() - widget.width()
            y = 2 * ag.height() - sg.height() - widget.height()
        elif position == WINDOWS_TASKBAR_LOCATION.LEFT:
            x = sg.width() - ag.width() + default_open_offset
            y = 2 * ag.height() - sg.height() - widget.height(
            ) - default_open_offset
        elif position == WINDOWS_TASKBAR_LOCATION.TOP:
            x = ag.width() - widget.width() - default_open_offset
            y = sg.height() - ag.height() + default_open_offset
        elif position == WINDOWS_TASKBAR_LOCATION.RIGHT:
            x = ag.width() - widget.width() - default_open_offset
            y = 2 * ag.height() - sg.height() - widget.height(
            ) - default_open_offset
        self.move(x, y)

    def get_task_bar_position(self):
        desktop = QDesktopWidget()
        displayRect = desktop.screenGeometry()
        desktopRect = desktop.availableGeometry()
        if desktopRect.height() < displayRect.height():
            if desktopRect.y() > displayRect.y():
                return WINDOWS_TASKBAR_LOCATION.TOP
            else:
                return WINDOWS_TASKBAR_LOCATION.BOTTOM
        else:
            if desktopRect.x() > displayRect.x():
                return WINDOWS_TASKBAR_LOCATION.LEFT
            else:
                return WINDOWS_TASKBAR_LOCATION.RIGHT

    def setVisible(self, visible):
        self.minimizeAction.setEnabled(visible)
        self.maximizeAction.setEnabled(not self.isMaximized())
        self.restoreAction.setEnabled(self.isMaximized() or not visible)
        super(DuelLinksGui, self).setVisible(visible)

    def closeEvent(self, event):
        if self.trayIcon.isVisible():
            if self.shouldShowSystrayBox():
                QMessageBox.information(
                    self, app_name,
                    "The program will keep running in the system tray. To "
                    "terminate the program, choose <b>Quit</b> in the "
                    "context menu of the system tray entry.")
            self.hide()
            event.ignore()

    def setShouldShowSystrayBox(self, callback):
        self._shouldShowSystrayBox = callback

    def shouldShowSystrayBox(self):
        self._shouldShowSystrayBox()

    def setIcon(self):
        icon = QIcon(QIcon(':/assets/yugioh.ico'))
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

        self.trayIcon.setToolTip('Duel-Links Bot')

    def iconActivated(self, reason):
        if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
            self.showNormal()
        elif reason == QSystemTrayIcon.MiddleClick:
            self.showNotifcation(
                "In Development",
                "You pressed the middle mouse button.\n Hidden Feature!!!!")

    def showMessage(self):
        icon = QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(self.titleEdit.text(),
                                  self.bodyEdit.toPlainText(), icon,
                                  self.durationSpinBox.value() * 1000)

    def showNotifcation(self, title, message):
        icon = QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(title, message, icon,
                                  self.durationSpinBox.value() * 1000)

    def messageClicked(self):
        QMessageBox.information(
            None, "Systray",
            "Sorry, I already gave what help I could.\nMaybe you should "
            "try asking a human?")

    def modeChange(self, index):
        self.dlRunTime.playmode = self.available_modes.currentData()

    def createBotControls(self):
        self.botControls = QGroupBox("Controls")
        controlLayout = QGridLayout()
        self.runLabel = QLabel("Run the bot:")
        self.modeLabel = QLabel("Current Mode:")
        self.available_modes = QComboBox()
        for index, mode in enumerate(self.dlRunTime._available_modes):
            self.available_modes.addItem(mode.title(), mode)
        self.available_modes.setStyleSheet("QComboBox {text-align: center;}")
        self.available_modes.setEditable(True)
        self.available_modes.lineEdit().setReadOnly(True)
        self.available_modes.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
        self.available_modes.setCurrentIndex(
            self.dlRunTime._available_modes.index(self.dlRunTime.playmode))
        self.available_modes.currentIndexChanged.connect(self.modeChange)
        # self.available_modes.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
        self.runButton = QPushButton("Run")
        self.showLabel = QLabel("Pause the bot:")
        self.pauseButton = QPushButton("Pause")
        self.exitButton = QPushButton("Exit")
        self.hideButton = QPushButton("Hide")
        controlLayout.addWidget(self.modeLabel, 0, 0, 1, 2)
        controlLayout.addWidget(self.available_modes, 0, 2, 1, 2)
        controlLayout.addWidget(self.runLabel, 1, 0)
        controlLayout.addWidget(self.runButton, 1, 2, 1, 2)
        controlLayout.addWidget(self.showLabel, 2, 0)
        controlLayout.addWidget(self.pauseButton, 2, 2, 1, 2)
        controlLayout.addWidget(self.hideButton, 3, 0, 1, 2)
        controlLayout.addWidget(self.exitButton, 3, 2, 1, 2)
        self.botControls.setLayout(controlLayout)

    def createRunTimeFields(self):
        self.runTimeGroupBox = QGroupBox("RunTime Fields")
        self.current_time = QLabel("Current Time: ")
        self.current_time_value = QLabel("")
        self.nox_status_label = QLabel("{} status: ".format(
            self.dlRunTime.get_provider().__str__()))
        self.nox_status_value = QLabel("")
        self.next_run_at_label = QLabel("Next Run At:")
        self.next_run_at_value = QLabel("")
        self.in_timer = QtCore.QTimer(self)
        self.in_timer.setInterval(1000)
        self.in_timer.timeout.connect(self.update_values)
        self.in_timer.start()
        layout = QVBoxLayout()
        top = QHBoxLayout()
        top.addWidget(self.current_time)
        top.addWidget(self.current_time_value)
        top.addStretch()
        runTimeLayout = QHBoxLayout()
        runTimeLayout.addWidget(self.nox_status_label)
        runTimeLayout.addWidget(self.nox_status_value)
        runTimeLayout.addStretch()
        runTimeLayout.addWidget(self.next_run_at_label)
        runTimeLayout.addWidget(self.next_run_at_value)
        layout.addLayout(top)
        layout.addLayout(runTimeLayout)
        self.runTimeGroupBox.setLayout(layout)

    _counter = 0

    def update_values(self, force=False):
        self._counter += 1
        if self._counter % update_intervals.get('current_time',
                                                1) == 0 or force:
            self.current_time_value.setText(
                QtCore.QDateTime.currentDateTime().toString())
        if self._counter % update_intervals.get('nox_status', 1) == 0 or force:
            self.nox_status_value.setText((lambda: "Running"
                                           if self.dlRunTime.get_provider().
                                           is_process_running() else "Off")())
        if self._counter % update_intervals.get('next_run_at',
                                                1) == 0 or force:
            self.next_run_at_value.setText(
                self.dlRunTime.next_run_at.strftime("%Y-%m-%dT%H:%M:%S"))
        if self.dlRunTime.get_provider().current_thread is not None:
            self.runButton.setDisabled(False)
            self.runButton.setEnabled(False)
            self.pauseButton.setDisabled(True)
            self.pauseButton.setEnabled(True)
        else:
            self.runButton.setDisabled(True)
            self.runButton.setEnabled(True)
            self.pauseButton.setDisabled(False)
            self.pauseButton.setEnabled(False)
        if self.dlRunTime._shutdown:
            self.__quit__()

    def createActions(self):
        self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide)
        self.maximizeAction = QAction("Ma&ximize",
                                      self,
                                      triggered=self.showMaximized)
        self.restoreAction = QAction("&Restore",
                                     self,
                                     triggered=self.showNormal)
        self.quitAction = QAction("&Quit", self, triggered=self.__quit__)

    def __quit__(self):
        QApplication.instance().closingDown()
        self.hide()
        if not self.dlRunTime._shutdown:
            self.dlRunTime.shutdown()
        self.in_timer.stop()
        self.in_timer.deleteLater()
        self.close()
        qApp.closeAllWindows()
        time.sleep(1)
        del self.dlRunTime
        QApplication.instance().quit()

    def createBotActions(self):
        self.startAction = QAction('Start', self, triggered=self.start_bot)
        self.pauseAction = QAction('Pause', self, triggered=self.pause_bot)

    def start_bot(self):
        self.dlRunTime.stop = False
        self.dlRunTime.run_now = True

    def pause_bot(self):
        self.dlRunTime.stop = True
        self.dlRunTime.run_now = False

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.minimizeAction)
        self.trayIconMenu.addAction(self.maximizeAction)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)
Exemplo n.º 16
0
class DuelLinksGui(QFrame):
    _shouldShowSystrayBox = mock_data
    dlRunTime = None

    def __init__(self, duelLinksRunTime=None, assets=None):
        super(DuelLinksGui, self).__init__()
        self.assets = assets
        assert (type(duelLinksRunTime) is DuelLinkRunTime)
        self.dlRunTime = duelLinksRunTime  # type: DuelLinkRunTime
        # self.createIconGroupBox()
        self.createRunTimeFields()
        self.createMessageGroupBox()
        self.createBotControls()

        self.setObjectName("BotFrame")
        self.setStyleSheet("#BotFrame {border: 2px solid #9e3939;}")

        self.createActions()
        self.createBotActions()
        self.createTrayIcon()
        self.setShouldShowSystrayBox(mock_data)
        # self.showMessageButton.clicked.connect(self.showMessage)
        self.hideButton.clicked.connect(self.close)
        self.exitButton.clicked.connect(self.__quit__)
        # self.showIconCheckBox.toggled.connect(self.trayIcon.setVisible)
        # self.iconComboBox.currentIndexChanged.connect(self.setIcon)
        self.trayIcon.messageClicked.connect(self.messageClicked)
        self.trayIcon.activated.connect(self.iconActivated)

        # bot actions connected
        self.pauseButton.clicked.connect(self.pause_bot)
        self.runButton.clicked.connect(self.start_bot)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.runTimeGroupBox)
        mainLayout.addWidget(self.botControls)
        # mainLayout.addWidget(self.iconGroupBox)
        # mainLayout.addWidget(self.messageGroupBox)
        self.setLayout(mainLayout)

        self.setIcon()
        self.trayIcon.show()
        self.setWindowTitle(app_name)
        self.setFixedSize(400, 300)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup)
        self.location_on_the_screen()
        self.update_values(True)

    def location_on_the_screen(self):
        ag = QDesktopWidget().availableGeometry()
        sg = QDesktopWidget().screenGeometry()
        print(ag, sg)
        widget = self.geometry()
        position = self.get_task_bar_position()
        if position == WINDOWS_TASKBAR_LOCATION.BOTTOM:
            x = ag.width() - widget.width()
            y = 2 * ag.height() - sg.height() - widget.height()
        elif position == WINDOWS_TASKBAR_LOCATION.LEFT:
            x = sg.width() - ag.width() + default_open_offset
            y = 2 * ag.height() - sg.height() - widget.height(
            ) - default_open_offset
        elif position == WINDOWS_TASKBAR_LOCATION.TOP:
            x = ag.width() - widget.width() - default_open_offset
            y = sg.height() - ag.height() + default_open_offset
        elif position == WINDOWS_TASKBAR_LOCATION.RIGHT:
            x = ag.width() - widget.width() - default_open_offset
            y = 2 * ag.height() - sg.height() - widget.height(
            ) - default_open_offset
        self.move(x, y)

    def get_task_bar_position(self):
        desktop = QDesktopWidget()
        displayRect = desktop.screenGeometry()
        desktopRect = desktop.availableGeometry()
        if desktopRect.height() < displayRect.height():
            if desktopRect.y() > displayRect.y():
                return WINDOWS_TASKBAR_LOCATION.TOP
            else:
                return WINDOWS_TASKBAR_LOCATION.BOTTOM
        else:
            if desktopRect.x() > displayRect.x():
                return WINDOWS_TASKBAR_LOCATION.LEFT
            else:
                return WINDOWS_TASKBAR_LOCATION.RIGHT

    def setVisible(self, visible):
        self.minimizeAction.setEnabled(visible)
        self.maximizeAction.setEnabled(not self.isMaximized())
        self.restoreAction.setEnabled(self.isMaximized() or not visible)
        super(DuelLinksGui, self).setVisible(visible)

    def closeEvent(self, event):
        if self.trayIcon.isVisible():
            if self.shouldShowSystrayBox():
                QMessageBox.information(
                    self, app_name,
                    "The program will keep running in the system tray. To "
                    "terminate the program, choose <b>Quit</b> in the "
                    "context menu of the system tray entry.")
            self.hide()
            event.ignore()

    def setShouldShowSystrayBox(self, callback):
        self._shouldShowSystrayBox = callback

    def shouldShowSystrayBox(self):
        self._shouldShowSystrayBox()

    def setIcon(self):
        icon = QIcon(QIcon(':/assets/yugioh.ico'))
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

        self.trayIcon.setToolTip('Duel-Links Bot')

    def iconActivated(self, reason):
        if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
            self.showNormal()
        elif reason == QSystemTrayIcon.MiddleClick:
            self.showNotifcation(
                "In Development",
                "You pressed the middle mouse button.\n Hidden Feature!!!!")

    def showMessage(self):
        icon = QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(self.titleEdit.text(),
                                  self.bodyEdit.toPlainText(), icon,
                                  self.durationSpinBox.value() * 1000)

    def showNotifcation(self, title, message):
        icon = QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(title, message, icon,
                                  self.durationSpinBox.value() * 1000)

    def messageClicked(self):
        QMessageBox.information(
            None, "Systray",
            "Sorry, I already gave what help I could.\nMaybe you should "
            "try asking a human?")

    def modeChange(self, index):
        self.dlRunTime.playmode = self.available_modes.currentData()

    def createIconGroupBox(self):
        self.iconGroupBox = QGroupBox("Tray Icon")

        self.iconLabel = QLabel("Icon:")

        self.iconComboBox = QComboBox()
        self.iconComboBox.addItem(QIcon('assets/yugioh.ico'), "Duel-Card")

        self.showIconCheckBox = QCheckBox("Show icon")
        self.showIconCheckBox.setChecked(True)

        iconLayout = QHBoxLayout()
        iconLayout.addWidget(self.iconLabel)
        iconLayout.addWidget(self.iconComboBox)
        iconLayout.addStretch()
        iconLayout.addWidget(self.showIconCheckBox)
        self.iconGroupBox.setLayout(iconLayout)

    def createBotControls(self):
        self.botControls = QGroupBox("Controls")
        controlLayout = QGridLayout()
        self.runLabel = QLabel("Run the bot:")
        self.modeLabel = QLabel("Current Mode:")
        self.available_modes = QComboBox()
        for index, mode in enumerate(self.dlRunTime._available_modes):
            self.available_modes.addItem(mode.title(), mode)
        self.available_modes.setStyleSheet("QComboBox {text-align: center;}")
        self.available_modes.setEditable(True)
        self.available_modes.lineEdit().setReadOnly(True)
        self.available_modes.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
        self.available_modes.setCurrentIndex(
            self.dlRunTime._available_modes.index(self.dlRunTime.playmode))
        self.available_modes.currentIndexChanged.connect(self.modeChange)
        # self.available_modes.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
        self.runButton = QPushButton("Run")
        self.showLabel = QLabel("Pause the bot:")
        self.pauseButton = QPushButton("Pause")
        self.exitButton = QPushButton("Exit")
        self.hideButton = QPushButton("Hide")
        controlLayout.addWidget(self.modeLabel, 0, 0, 1, 2)
        controlLayout.addWidget(self.available_modes, 0, 2, 1, 2)
        controlLayout.addWidget(self.runLabel, 1, 0)
        controlLayout.addWidget(self.runButton, 1, 2, 1, 2)
        controlLayout.addWidget(self.showLabel, 2, 0)
        controlLayout.addWidget(self.pauseButton, 2, 2, 1, 2)
        controlLayout.addWidget(self.hideButton, 3, 0, 1, 2)
        controlLayout.addWidget(self.exitButton, 3, 2, 1, 2)
        self.botControls.setLayout(controlLayout)

    def createMessageGroupBox(self):
        # self.messageGroupBox = QGroupBox("Balloon Message")

        typeLabel = QLabel("Type:")

        self.typeComboBox = QComboBox()
        self.typeComboBox.addItem("None", QSystemTrayIcon.NoIcon)
        self.typeComboBox.addItem(
            self.style().standardIcon(QStyle.SP_MessageBoxInformation),
            "Information", QSystemTrayIcon.Information)
        self.typeComboBox.addItem(
            self.style().standardIcon(QStyle.SP_MessageBoxWarning), "Warning",
            QSystemTrayIcon.Warning)
        self.typeComboBox.addItem(
            self.style().standardIcon(QStyle.SP_MessageBoxCritical),
            "Critical", QSystemTrayIcon.Critical)
        self.typeComboBox.setCurrentIndex(1)

        self.durationLabel = QLabel("Duration:")

        self.durationSpinBox = QSpinBox()
        self.durationSpinBox.setRange(5, 60)
        self.durationSpinBox.setSuffix(" s")
        self.durationSpinBox.setValue(15)

        durationWarningLabel = QLabel("(some systems might ignore this hint)")
        durationWarningLabel.setIndent(10)

        titleLabel = QLabel("Title:")

        self.titleEdit = QLineEdit("Cannot connect to network")

        bodyLabel = QLabel("Body:")

        self.bodyEdit = QTextEdit()
        self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have "
                                   "a clue.\nClick this balloon for details.")

        # self.showMessageButton = QPushButton("Show Message")
        # self.showMessageButton.setDefault(True)
        """
        messageLayout = QGridLayout()
        messageLayout.addWidget(typeLabel, 0, 0)
        messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2)
        messageLayout.addWidget(self.durationLabel, 1, 0)
        messageLayout.addWidget(self.durationSpinBox, 1, 1)
        messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3)
        messageLayout.addWidget(titleLabel, 2, 0)
        messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4)
        messageLayout.addWidget(bodyLabel, 3, 0)
        messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4)
        messageLayout.addWidget(self.showMessageButton, 5, 4)
        messageLayout.setColumnStretch(3, 1)
        messageLayout.setRowStretch(4, 1)
        self.messageGroupBox.setLayout(messageLayout)"""

    def createRunTimeFields(self):
        self.runTimeGroupBox = QGroupBox("RunTime Fields")
        self.current_time = QLabel("Current Time: ")
        self.current_time_value = QLabel("")
        self.nox_status_label = QLabel("{} status: ".format(
            self.dlRunTime.get_provider().__str__()))
        self.nox_status_value = QLabel("")
        self.next_run_at_label = QLabel("Next Run At:")
        self.next_run_at_value = QLabel("")
        self.in_timer = QtCore.QTimer(self)
        self.in_timer.setInterval(1000)
        self.in_timer.timeout.connect(self.update_values)
        self.in_timer.start()
        layout = QVBoxLayout()
        top = QHBoxLayout()
        top.addWidget(self.current_time)
        top.addWidget(self.current_time_value)
        top.addStretch()
        runTimeLayout = QHBoxLayout()
        runTimeLayout.addWidget(self.nox_status_label)
        runTimeLayout.addWidget(self.nox_status_value)
        runTimeLayout.addStretch()
        runTimeLayout.addWidget(self.next_run_at_label)
        runTimeLayout.addWidget(self.next_run_at_value)
        layout.addLayout(top)
        layout.addLayout(runTimeLayout)
        self.runTimeGroupBox.setLayout(layout)

    _counter = 0

    def update_values(self, force=False):
        self._counter += 1
        if self._counter % update_intervals.get('current_time',
                                                1) == 0 or force:
            self.current_time_value.setText(
                QtCore.QDateTime.currentDateTime().toString())
        if self._counter % update_intervals.get('nox_status', 1) == 0 or force:
            self.nox_status_value.setText((lambda: "Running"
                                           if self.dlRunTime.get_provider().
                                           is_process_running() else "Off")())
        if self._counter % update_intervals.get('next_run_at',
                                                1) == 0 or force:
            self.next_run_at_value.setText(
                self.dlRunTime.next_run_at.strftime("%Y-%m-%dT%H:%M:%S"))
        if self.dlRunTime.get_provider().current_thread is not None:
            self.runButton.setDisabled(False)
            self.runButton.setEnabled(False)
            self.pauseButton.setDisabled(True)
            self.pauseButton.setEnabled(True)
        else:
            self.runButton.setDisabled(True)
            self.runButton.setEnabled(True)
            self.pauseButton.setDisabled(False)
            self.pauseButton.setEnabled(False)
        if self.dlRunTime._shutdown:
            self.hide()
            QApplication.instance().quit()

    def createActions(self):
        self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide)
        self.maximizeAction = QAction("Ma&ximize",
                                      self,
                                      triggered=self.showMaximized)
        self.restoreAction = QAction("&Restore",
                                     self,
                                     triggered=self.showNormal)
        self.quitAction = QAction("&Quit", self, triggered=self.__quit__)

    def __quit__(self):
        self.hide()
        self.dlRunTime.shutdown()
        self.close()

    def createBotActions(self):
        self.startAction = QAction('Start', self, triggered=self.start_bot)
        self.pauseAction = QAction('Pause', self, triggered=self.pause_bot)

    def start_bot(self):
        self.dlRunTime.stop = False
        self.dlRunTime.run_now = True

    def pause_bot(self):
        self.dlRunTime.stop = True
        self.dlRunTime.run_now = False

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.minimizeAction)
        self.trayIconMenu.addAction(self.maximizeAction)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)
Exemplo n.º 17
0
    def addParam(self,
                 *,
                 layout=None,
                 label='some param name',
                 box=None,
                 paramName='n/a',
                 rowIndex=1,
                 decimals=2,
                 minimum=0,
                 maximum=10000,
                 unit='',
                 float=True,
                 listport=False,
                 listmonitor=False,
                 boolean=False):
        self.settings += [paramName]
        layout.addWidget(QLabel(label, box), rowIndex, 1, 1, 1)
        if listmonitor:
            valc = QComboBox()
            i = 0
            for monitor in QApplication.screens():
                valc.insertItem(i, str(i) + ': ' + monitor.name(), i)
                i += 1
            sindex = valc.findData(AppData.configParams[paramName][-1][0])
            if sindex == -1:
                sindex = 0
            valc.setCurrentIndex(sindex)
        elif listport:
            valc = QComboBox()
            i = 0
            for port in self.comports:
                valc.insertItem(i, 'RTS on ' + port[0] + ': ' + port[1],
                                (port[0], 'RTS'))
                valc.insertItem(i, 'BREAK on ' + port[0] + ': ' + port[1],
                                (port[0], 'BREAK'))
                i += 1
            sindex = valc.findData(AppData.configParams[paramName][-1][0][1])
            if sindex == -1:
                valc.insertItem(
                    i, AppData.configParams[paramName][-1][0][1] + ' on ' +
                    AppData.configParams[paramName][-1][0][0] +
                    ': no device detected',
                    AppData.configParams[paramName][-1][0])
            else:
                valc.setCurrentIndex(sindex)
        elif boolean:
            valc = QComboBox()
            valc.insertItem(0, 'True', True)
            valc.insertItem(1, 'False', False)
            sindex = valc.findData(AppData.configParams[paramName][-1][0])
            valc.setCurrentIndex(sindex)
        else:
            if float:
                valc = QDoubleSpinBox()
                valc.setDecimals(decimals)
            else:
                valc = QSpinBox()
            valc.lineEdit().setCursor(AppData.cursors['text'])
            valc.setMinimum(minimum)
            valc.setMaximum(maximum)
            valc.setValue(AppData.configParams[paramName][-1][0])
        setattr(self, paramName, valc)
        dowc = QLabel()
        checkc = QPushButton()
        filec = QLabel()
        setattr(self, paramName + 'Default', checkc)

        def resetParam():
            setattr(self, paramName + 'Override', False)
            if AppData.configParams[paramName][-1][1] == self.filename:
                dowc.setText('')
                checkc.setText('')
                filec.setText(unit + ' from ' +
                              AppData.configParams[paramName][-2][1])
                dowc.setEnabled(False)
                checkc.setEnabled(False)
                filec.setEnabled(False)
                valc.blockSignals(True)
                if listmonitor or listport or boolean:
                    sindex = valc.findData(
                        AppData.configParams[paramName][-2][0])
                    valc.setCurrentIndex(sindex)
                else:
                    valc.setValue(AppData.configParams[paramName][-2][0])
                valc.blockSignals(False)
            else:
                dowc.setText('')
                checkc.setText('')
                filec.setText(unit + ' from ' +
                              AppData.configParams[paramName][-1][1])
                dowc.setEnabled(False)
                checkc.setEnabled(False)
                filec.setEnabled(False)
                valc.blockSignals(True)
                if listmonitor or listport or boolean:
                    sindex = valc.findData(
                        AppData.configParams[paramName][-1][0])
                    valc.setCurrentIndex(sindex)
                else:
                    valc.setValue(AppData.configParams[paramName][-1][0])
                valc.blockSignals(False)

        def trumpParam():
            setattr(self, paramName + 'Override', True)
            if AppData.configParams[paramName][-1][1] == self.filename:
                dowc.setText(unit + ' overriding')
                checkc.setText(
                    str(AppData.configParams[paramName][-2][0]) + ' ' + unit)
                filec.setText('specified in ' +
                              AppData.configParams[paramName][-2][1])
                dowc.setEnabled(True)
                checkc.setEnabled(True)
                filec.setEnabled(True)
            else:
                dowc.setText(unit + ' overriding')
                checkc.setText(
                    str(AppData.configParams[paramName][-1][0]) + ' ' + unit)
                filec.setText('\tspecified in ' +
                              AppData.configParams[paramName][-1][1])
                dowc.setEnabled(True)
                checkc.setEnabled(True)
                filec.setEnabled(True)

        checkc.pressed.connect(resetParam)
        if listport or listmonitor or boolean:
            valc.currentIndexChanged.connect(trumpParam)
        else:
            valc.valueChanged.connect(trumpParam)
        overridesParam = AppData.configParams[paramName][-1][
            1] == self.filename
        setattr(self, paramName + 'Override', overridesParam)
        if overridesParam:
            trumpParam()
        else:
            resetParam()
        layout.addWidget(valc, rowIndex, 2, 1, 1)
        layout.addWidget(dowc, rowIndex, 3, 1, 1)
        layout.addWidget(checkc, rowIndex, 4, 1, 1)
        layout.addWidget(filec, rowIndex, 5, 1, 1)
Exemplo n.º 18
0
class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self._filename = None
        self._page = None
        self._rect = None
        self.imageViewer = widgets.imageviewer.ImageViewer()
        self.dpiLabel = QLabel()
        self.dpiCombo = QComboBox(insertPolicy=QComboBox.NoInsert, editable=True)
        self.dpiCombo.lineEdit().setCompleter(None)
        self.dpiCombo.setValidator(QDoubleValidator(10.0, 1200.0, 4, self.dpiCombo))
        self.dpiCombo.addItems([format(i) for i in (72, 100, 200, 300, 600, 1200)])

        self.colorButton = widgets.colorbutton.ColorButton()
        self.colorButton.setColor(QColor(Qt.white))
        self.grayscale = QCheckBox(checked=False)
        self.crop = QCheckBox()
        self.antialias = QCheckBox(checked=True)
        self.scaleup = QCheckBox(checked=False)
        self.dragfile = QPushButton(icons.get("image-x-generic"), None, None)
        self.fileDragger = FileDragger(self.dragfile)
        self.buttons = QDialogButtonBox(QDialogButtonBox.Close)
        self.copyButton = self.buttons.addButton('', QDialogButtonBox.ApplyRole)
        self.copyButton.setIcon(icons.get('edit-copy'))
        self.saveButton = self.buttons.addButton('', QDialogButtonBox.ApplyRole)
        self.saveButton.setIcon(icons.get('document-save'))

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self.imageViewer)

        controls = QHBoxLayout()
        layout.addLayout(controls)
        controls.addWidget(self.dpiLabel)
        controls.addWidget(self.dpiCombo)
        controls.addWidget(self.colorButton)
        controls.addWidget(self.grayscale)
        controls.addWidget(self.crop)
        controls.addWidget(self.antialias)
        controls.addWidget(self.scaleup)
        controls.addStretch()
        controls.addWidget(self.dragfile)
        layout.addWidget(widgets.Separator())
        layout.addWidget(self.buttons)

        app.translateUI(self)
        self.readSettings()
        self.finished.connect(self.writeSettings)
        self.dpiCombo.editTextChanged.connect(self.drawImage)
        self.colorButton.colorChanged.connect(self.drawImage)
        self.grayscale.toggled.connect(self.drawImage)
        self.antialias.toggled.connect(self.drawImage)
        self.scaleup.toggled.connect(self.drawImage)
        self.crop.toggled.connect(self.cropImage)
        self.buttons.rejected.connect(self.reject)
        self.copyButton.clicked.connect(self.copyToClipboard)
        self.saveButton.clicked.connect(self.saveAs)
        qutil.saveDialogSize(self, "copy_image/dialog/size", QSize(480, 320))

    def translateUI(self):
        self.setCaption()
        self.dpiLabel.setText(_("DPI:"))
        self.colorButton.setToolTip(_("Paper Color"))
        self.grayscale.setText(_("Gray"))
        self.grayscale.setToolTip(_("Convert image to grayscale."))
        self.crop.setText(_("Auto-crop"))
        self.antialias.setText(_("Antialias"))
        self.scaleup.setText(_("Scale 2x"))
        self.scaleup.setToolTip(_(
            "Render twice as large and scale back down\n"
            "(recommended for small DPI values)."))
        self.dragfile.setText(_("Drag"))
        self.dragfile.setToolTip(_("Drag the image as a PNG file."))
        self.copyButton.setText(_("&Copy to Clipboard"))
        self.saveButton.setText(_("&Save As..."))
        self.imageViewer.setWhatsThis(_(
            #xgettext:no-python-format
            "<p>\n"
            "Clicking toggles the display between 100% size and window size. "
            "Drag to copy the image to another application. "
            "Drag with Ctrl (or {command}) to scroll a large image.\n"
            "</p>\n"
            "<p>\n"
            "You can also drag the small picture icon in the bottom right, "
            "which drags the actual file on disk, e.g. to an e-mail message.\n"
            "</p>").format(command="\u2318"))

    def readSettings(self):
        s = QSettings()
        s.beginGroup('copy_image')
        self.dpiCombo.setEditText(s.value("dpi", "100", str))
        self.colorButton.setColor(s.value("papercolor", QColor(Qt.white), QColor))
        self.grayscale.setChecked(s.value("grayscale", False, bool))
        self.crop.setChecked(s.value("autocrop", False, bool))
        self.antialias.setChecked(s.value("antialias", True, bool))
        self.scaleup.setChecked(s.value("scaleup", False, bool))

    def writeSettings(self):
        s = QSettings()
        s.beginGroup('copy_image')
        s.setValue("dpi", self.dpiCombo.currentText())
        s.setValue("papercolor", self.colorButton.color())
        s.setValue("grayscale", self.grayscale.isChecked())
        s.setValue("autocrop", self.crop.isChecked())
        s.setValue("antialias", self.antialias.isChecked())
        s.setValue("scaleup", self.scaleup.isChecked())

    def setCaption(self):
        if self._filename:
            filename = os.path.basename(self._filename)
        else:
            filename = _("<unknown>")
        title = _("Image from {filename}").format(filename = filename)
        self.setWindowTitle(app.caption(title))

    def setPage(self, page, rect, filename):
        self._page = page
        self._rect = rect
        self._filename = filename
        self.fileDragger.basename = os.path.splitext(os.path.basename(self._filename))[0]
        self.setCaption()
        self.drawImage()

    def drawImage(self):
        dpi = float(self.dpiCombo.currentText() or '100')
        dpi = max(dpi, self.dpiCombo.validator().bottom())
        dpi = min(dpi, self.dpiCombo.validator().top())
        options = qpopplerview.RenderOptions()
        options.setPaperColor(self.colorButton.color())
        if self.antialias.isChecked():
            if popplerqt5:
                options.setRenderHint(
                    popplerqt5.Poppler.Document.Antialiasing |
                    popplerqt5.Poppler.Document.TextAntialiasing)
        else:
            options.setRenderHint(0)
        m = 2 if self.scaleup.isChecked() else 1
        i = self._page.image(self._rect, dpi * m, dpi * m , options)
        if m == 2:
            i = i.scaled(i.size() / 2, transformMode=Qt.SmoothTransformation)
        if self.grayscale.isChecked():
            i = i.convertToFormat(QImage.Format_Grayscale8)
        self._image = i
        self.cropImage()

    def cropImage(self):
        image = self._image
        if self.crop.isChecked():
            image = image.copy(autoCropRect(image))
        self.imageViewer.setImage(image)
        self.fileDragger.setImage(image)

    def copyToClipboard(self):
        QApplication.clipboard().setImage(self.imageViewer.image())

    def saveAs(self):
        if self._filename and not self.imageViewer.image().isNull():
            filename = os.path.splitext(self._filename)[0] + ".png"
        else:
            filename = 'image.png'
        filename = QFileDialog.getSaveFileName(self,
            _("Save Image As"), filename)[0]
        if filename:
            if not self.imageViewer.image().save(filename):
                QMessageBox.critical(self, _("Error"), _(
                    "Could not save the image."))
            else:
                self.fileDragger.currentFile = filename
Exemplo n.º 19
0
class DeviceManagementWidget(WidgetBase):
    # noinspection PyArgumentList,PyUnresolvedReferences
    def __init__(
        self,
        parent: typing.Optional[QWidget],
        on_connection_request: ConnectionRequestCallback,
        on_disconnection_request: DisconnectionRequestCallback,
    ):
        super(DeviceManagementWidget, self).__init__(parent)
        self.setAttribute(
            Qt.WA_DeleteOnClose)  # This is required to stop background timers!

        self._port_discoverer = PortDiscoverer()
        self._port_mapping: typing.Dict[str:str] = {}

        self._port_combo = QComboBox(self)
        self._port_combo.setEditable(True)
        self._port_combo.setInsertPolicy(QComboBox.NoInsert)
        self._port_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self._port_combo.setFont(get_monospace_font())
        self._port_combo.lineEdit().returnPressed.connect(
            self._on_confirmation)

        self._connect_button = make_button(self,
                                           "Connect",
                                           "disconnected",
                                           on_clicked=self._on_confirmation)
        self._connect_button.setEnabled(
            False)  # Empty by default, therefore disabled

        self._port_combo.currentTextChanged.connect(
            lambda: self._connect_button.setEnabled(
                bool(self._port_combo.currentText().strip())))

        self._status_text = QLabel(self)
        self._status_text.setText(_STATUS_WHEN_NOT_CONNECTED)
        self._status_text.setWordWrap(True)

        self._device_info_widget = LittleBobbyTablesWidget(self)

        combo_completer = QCompleter()
        combo_completer.setCaseSensitivity(Qt.CaseInsensitive)
        combo_completer.setModel(self._port_combo.model())
        self._port_combo.setCompleter(combo_completer)

        self._update_timer = QTimer(self)
        self._update_timer.timeout.connect(self._update_ports)
        self._update_timer.start(2000)

        self._connection_progress_bar = QProgressBar(self)
        self._connection_progress_bar.setMinimum(0)
        self._connection_progress_bar.setMaximum(100)

        self._connection_established = False
        self._last_task: typing.Optional[asyncio.Task] = None

        self._connection_request_callback: ConnectionRequestCallback = (
            on_connection_request)
        self._disconnection_request_callback: DisconnectionRequestCallback = (
            on_disconnection_request)

        # Layout
        self._overlay = QStackedLayout(self)
        self._init_overlay_widgets()
        self.setLayout(self._overlay)

        # Initialization
        self._update_ports()

    def on_connection_loss(self, reason: str):
        """
        This method should be invoked when the connection becomes lost.
        It will cause the widget to change its state accordingly.
        :param reason: Human-readable description of the reason in one line.
        """
        if self._connection_established:
            self._switch_state_disconnected()
            self._status_text.setText(
                f'Connection lost: {reason.strip() or "Unknown reason"}')

    def on_connection_initialization_progress_report(self,
                                                     stage_description: str,
                                                     progress: float):
        """
        This method should be periodically invoked while connection is being initialized.
        :param stage_description: Human-readable short string displaying what is currently being done.
                                  E.g. "Opening port"
        :param progress:          A float in [0, 1] that displays how much of the work has been completed so far,
                                  where 0 - nothing, 1 - all done.
        """
        if self._overlay.currentIndex() != 1:
            raise RuntimeError(
                "Invalid usage: this method can only be invoked when connection initialization is "
                "in progress. Currently it is not.")

        # noinspection PyTypeChecker
        if not (0.0 <= progress <= 1.0):
            _logger.error(
                f"Connection progress estimate falls outside of [0, 1]: {progress}"
            )

        stage_description = stage_description.strip()
        if stage_description[-1] in string.ascii_letters:
            stage_description += "..."

        self._connection_progress_bar.setValue(int(progress * 100))
        self._connection_progress_bar.setFormat(stage_description)
        self._connection_progress_bar.setAlignment(Qt.AlignCenter)

    # noinspection PyArgumentList,PyUnresolvedReferences
    def _init_overlay_widgets(self):
        # Main widget
        operational = WidgetBase(self)

        operational_layout_top = QHBoxLayout()
        operational_layout_top.addWidget(QLabel("Port:"))
        operational_layout_top.addWidget(self._port_combo, stretch=1)
        operational_layout_top.addWidget(self._connect_button)

        operational_layout_bottom = QHBoxLayout()
        operational_layout_bottom.addWidget(self._status_text)

        operational_layout = QVBoxLayout()
        operational_layout.addLayout(operational_layout_top)
        operational_layout.addLayout(operational_layout_bottom)
        operational_layout.addWidget(self._device_info_widget, 1)

        operational.setLayout(operational_layout)
        self._overlay.addWidget(operational)

        # Progress widget - shown while connecting/disconnecting
        progress = WidgetBase(self)
        progress_layout = QVBoxLayout()
        progress_layout.addStretch(1)
        progress_layout.addWidget(self._connection_progress_bar)
        progress_layout.addStretch(1)
        progress.setLayout(progress_layout)
        self._overlay.addWidget(progress)

    def _update_ports(self):
        if self._connection_established:
            return

        # noinspection PyBroadException
        try:
            ports = self._port_discoverer.get_ports()
        except Exception as ex:
            _logger.exception("Could not list ports")
            self.flash(f"Could not list ports: {ex}", duration=10)
            ports = []

        self._port_mapping = self._port_discoverer.display_ports(
            ports, self._port_combo)

    def _switch_state_connected(self, device_info: BasicDeviceInfo):
        self._connection_established = True
        self._overlay.setCurrentIndex(0)

        self._port_combo.setEnabled(False)

        self._connect_button.setEnabled(True)
        self._connect_button.setText("Disconnect")
        self._connect_button.setIcon(get_icon("connected"))

        self._status_text.setText("Connected")
        self._device_info_widget.set(device_info)

    def _switch_state_disconnected(self):
        self._connection_established = False
        self._overlay.setCurrentIndex(0)

        self._port_combo.setEnabled(True)

        self._connect_button.setEnabled(True)
        self._connect_button.setText("Connect")
        self._connect_button.setIcon(get_icon("disconnected"))

        self._device_info_widget.clear()
        self._status_text.setText(_STATUS_WHEN_NOT_CONNECTED)

        self._update_ports()

    async def _do_connect(self):
        _logger.info("Connection initialization task spawned")
        try:
            selected_port = self._port_mapping[str(
                self._port_combo.currentText()).strip()]
        except KeyError:
            selected_port = str(self._port_combo.currentText()).strip()

        # Activate the progress view and initialize it
        self._overlay.setCurrentIndex(1)
        self._connection_progress_bar.setValue(0)
        self._connection_progress_bar.setFormat("Requesting connection...")

        # noinspection PyBroadException
        try:
            device_info: BasicDeviceInfo = await self._connection_request_callback(
                selected_port)
        except Exception as ex:
            show_error(
                "Could not connect",
                f"Connection via the port {selected_port} could not be established.",
                f"Reason: {str(ex)}",
                parent=self,
            )
            self._switch_state_disconnected()
        else:
            assert device_info is not None
            self._switch_state_connected(device_info)

    async def _do_disconnect(self):
        _logger.info("Connection termination task spawned")

        # Activate the progress view and initialize it
        self._overlay.setCurrentIndex(1)
        self._connection_progress_bar.setValue(100)
        self._connection_progress_bar.setFormat(
            "Disconnecting, please wait...")

        # noinspection PyBroadException
        try:
            await self._disconnection_request_callback()
        except Exception as ex:
            _logger.exception("Disconnect request failed")
            self.flash(f"Disconnection problem: {ex}", duration=10)

        self._switch_state_disconnected()

    def _on_confirmation(self):
        # Deactivate the controls in order to prevent accidental double-entry
        self._port_combo.setEnabled(False)
        self._connect_button.setEnabled(False)

        if (self._last_task is not None) and not self._last_task.done():
            show_error(
                "I'm sorry Dave, I'm afraid I can't do that",
                "Cannot connect/disconnect while another connection/disconnection operation is still running",
                f"Pending future: {self._last_task}",
                self,
            )
        else:
            if not self._connection_established:
                self._last_task = asyncio.get_event_loop().create_task(
                    self._do_connect())
            else:
                self._last_task = asyncio.get_event_loop().create_task(
                    self._do_disconnect())
Exemplo n.º 20
0
class Printing(preferences.Group):
    def __init__(self, page):
        super(Printing, self).__init__(page)

        layout = QGridLayout(spacing=1)
        self.setLayout(layout)

        self.messageLabel = QLabel(wordWrap=True)
        self.printCommandLabel = QLabel()
        self.printCommand = widgets.urlrequester.UrlRequester()
        self.printCommand.setFileMode(QFileDialog.ExistingFile)
        self.printCommand.changed.connect(page.changed)
        self.printDialogCheck = QCheckBox(toggled=page.changed)
        self.resolutionLabel = QLabel()
        self.resolution = QComboBox(editable=True, editTextChanged=page.changed)
        self.resolution.addItems("300 600 1200".split())
        self.resolution.lineEdit().setInputMask("9000")

        layout.addWidget(self.messageLabel, 0, 0, 1, 2)
        layout.addWidget(self.printCommandLabel, 1, 0)
        layout.addWidget(self.printCommand, 1, 1)
        layout.addWidget(self.printDialogCheck, 2, 0, 1, 2)
        layout.addWidget(self.resolutionLabel, 3, 0)
        layout.addWidget(self.resolution, 3, 1)

        app.translateUI(self)

    def translateUI(self):
        self.setTitle(_("Printing Music"))
        self.messageLabel.setText(_(
            "Here you can enter a command to print a PDF or PostScript file. "
            "See the Help page for more information about printing music."))
        self.printCommandLabel.setText(_("Printing command:"))
        self.printCommand.setToolTip('<qt>' + _(
            "The printing command is used to print a PostScript or PDF file. "
            "On Linux you don't need this, but on Windows and Mac OS X you can "
            "provide a command to avoid that PDF documents are being printed "
            "using raster images, which is less optimal.\n"
            "<code>$pdf</code> gets replaced with the PDF filename, or alternatively, "
            "<code>$ps</code> is replaced with the PostScript filename. "
            "<code>$printer</code> is replaced with the printer's name to use."))
        self.printDialogCheck.setText(_("Use Frescobaldi's print dialog"))
        self.printDialogCheck.setToolTip('<qt>' + _(
            "If enabled, Frescobaldi will show the print dialog and create a "
            "PDF or PostScript document containing only the selected pages "
            "to print. Otherwise, the command is called directly and is expected "
            "to show a print dialog itself."))
        self.resolutionLabel.setText(_("Resolution:"))
        self.resolution.setToolTip(_(
            "Set the resolution if Frescobaldi prints using raster images."))

    def loadSettings(self):
        s = QSettings()
        s.beginGroup("helper_applications")
        self.printCommand.setPath(s.value("printcommand", "", str))
        self.printDialogCheck.setChecked(s.value("printcommand/dialog", False, bool))
        with qutil.signalsBlocked(self.resolution):
            self.resolution.setEditText(format(s.value("printcommand/dpi", 300, int)))

    def saveSettings(self):
        s= QSettings()
        s.beginGroup("helper_applications")
        s.setValue("printcommand", self.printCommand.path())
        s.setValue("printcommand/dialog", self.printDialogCheck.isChecked())
        s.setValue("printcommand/dpi", int(self.resolution.currentText()))
Exemplo n.º 21
0
class Dataqc(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon(':/assets/icon.svg'))
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.header_key = {'NOx': 'NOx (uM)', 'Phosphate': 'Phosphate (uM)', 'Silicate': 'Silicate (uM)',
                           'Ammonia': 'Ammonia (uM)', 'Nitrite': 'Nitrite (uM)', 'Salinity': 'Salinity (PSU)',
                           'Oxygen': 'Oxygen (uM)'}
        self.flag_key = {'NOx': 'NOx flag', 'Phosphate': 'Phosphate flag', 'Silicate': 'Silicate flag',
                         'Ammonia': 'Ammonia flag', 'Nitrite': 'Nitrite flag', 'Salinity': 'Salinity flag',
                         'Oxygen': 'Oxygen flag'}

        self.init_ui()

        self.csvdf = pd.DataFrame()
        self.csvtempdf = pd.DataFrame()
        self.ncdf = pd.DataFrame()

        self.setStyleSheet('''
        QLabel {
            font: 14px;
        }   
        QPushButton {
            font: 14px;
        }
        QComboBox {
            font: 14px;
        }
        QListWidget {
        
            font: 14px;
        }
        QTableWidget {
            font: 14px;
        }
        QCheckBox {
            font: 14px;
        }
        ''')

    def init_ui(self):
        self.setFont(QFont('Segoe UI'))

        grid_layout = QGridLayout()
        grid_layout.setSpacing(10)

        self.setGeometry(0, 0, 1350, 750)
        qtRectangle = self.frameGeometry()
        screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos())
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

        self.setWindowTitle('Hydro Data QuickQCer')

        depscsv_label = QLabel('Hydro Deps CSV:')

        self.csv_path = QLineEdit('')
        self.csv_path.setReadOnly(True)

        csv_browse = QPushButton('Browse for CSV')
        csv_browse.clicked.connect(self.csv_browse_path)

        depnc_label = QLabel('Hydro Deps NC Folder:')

        self.nc_path = QLineEdit('')
        self.nc_path.setReadOnly(True)

        nc_browse = QPushButton('Browse for NC folder')
        nc_browse.clicked.connect(self.nc_browse_path)

        load_files = QPushButton('Load files')
        load_files.clicked.connect(self.load_filesf)

        self.csv_loaded = QCheckBox('CSV Loaded!')
        # self.csv_loaded.setCheckable(False)

        self.nc_loaded = QCheckBox('NC Loaded!')
        # self.nc_loaded.setCheckable(False)

        linesep1 = QFrame()
        linesep1.setFrameShape(QFrame.HLine)
        linesep1.setFrameShadow(QFrame.Sunken)

        param_label = QLabel('Parameter: ')

        self.params_combo = QComboBox()
        self.params_combo.addItems(['NOx', 'Phosphate', 'Silicate', 'Ammonia', 'Nitrite', 'Salinity', 'Oxygen'])
        self.params_combo.setEditable(True)
        self.params_combo.lineEdit().setAlignment(Qt.AlignHCenter)
        self.params_combo.lineEdit().setReadOnly(True)

        deps_label = QLabel('Deployments:')

        self.deps_list = QListWidget()
        self.deps_list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.draw_csv = QCheckBox('Draw CSV')
        self.draw_nc = QCheckBox('Draw NC')
        self.draw_woa = QCheckBox('Draw WOA18')


        view = QPushButton('View')
        view.setFixedWidth(130)
        view.clicked.connect(self.view_data)

        self.figure = plt.figure()
        self.figure.set_tight_layout(tight=True)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(self)

        self.flag_table = QTableWidget()
        self.flag_table.setColumnCount(7)
        self.flag_table.setHorizontalHeaderLabels(['Dep', 'RP', 'CSV Flag', 'NC Flag', 'Match', 'CSV Conc', 'NC Conc'])
        header = self.flag_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(6, QHeaderView.ResizeToContents)

        grid_layout.addWidget(depscsv_label, 0, 0)
        grid_layout.addWidget(self.csv_path, 1, 0, 1, 2)
        grid_layout.addWidget(csv_browse, 2, 1)
        grid_layout.addWidget(depnc_label, 3, 0)
        grid_layout.addWidget(self.nc_path, 4, 0, 1, 2)
        grid_layout.addWidget(nc_browse, 5, 1)
        grid_layout.addWidget(load_files, 6, 0, 1, 2)
        grid_layout.addWidget(self.csv_loaded, 7, 0, Qt.AlignHCenter)
        grid_layout.addWidget(self.nc_loaded, 7, 1, Qt.AlignHCenter)
        grid_layout.addWidget(linesep1, 8, 0, 1, 2)
        grid_layout.addWidget(param_label, 9, 0)
        grid_layout.addWidget(self.params_combo, 9, 1)
        grid_layout.addWidget(deps_label, 10, 0)
        grid_layout.addWidget(self.deps_list, 11, 0, 14, 2)
        grid_layout.addWidget(self.draw_csv, 25, 0)
        grid_layout.addWidget(self.draw_nc, 26, 0)
        grid_layout.addWidget(self.draw_woa, 27, 0)

        grid_layout.addWidget(view, 25, 1, 3, 1, Qt.AlignHCenter)

        grid_layout.addWidget(self.canvas, 0, 3, 27, 5)

        grid_layout.addWidget(self.flag_table, 0, 9, 27, 3)

        self.mainplot = self.figure.add_subplot(111)
        self.mainplot.set_facecolor('#f4f4f4')

        self.centralWidget().setLayout(grid_layout)

        self.show()

    def increment_deployment(self):
        # Used to increment the deployment number by 1, this then updates the plot and tables
        # uses keyboard button/letter N to increment the deployment number
        try:
            selected_index = self.deps_list.currentRow()
            next_index = selected_index + 1
            self.deps_list.setCurrentRow(next_index)

            self.view_data()

        except Exception:
            print(traceback.print_exc())

    def view_flags(self):
        # The function that populates the table with all the flags and concentrations for each point

        # Get current parameter of interest and convert it the relevant header name
        current_param = self.params_combo.currentText()
        param_header_key = self.header_key[current_param]
        param_flag_key = self.flag_key[current_param]

        deps = []
        rp = []
        match = []
        csvflags = []
        csvconc = []
        ncflags = []
        ncconc = []

        # Need to check if either dataset is getting drawn, as the draw function initially creates
        # the subsetted data to use
        if self.draw_csv.isChecked() == True:
            deps = self.csvdf['Deployment']
            rp = self.csvdf['RP']
            csvflags = self.csvdf[param_flag_key]
            csvflags = [int(x) for x in csvflags]
            csvconc = self.csvdf[param_header_key]
            csvconc = [round(x, 3) for x in csvconc]

        if self.draw_nc.isChecked() == True:
            ncflags = self.ncdf[param_flag_key]
            ncconc = self.ncdf[param_header_key]
            ncconc = [round(x, 3) for i, x in enumerate(ncconc) if x != '--' and ncflags[i] != 133]
            ncflags = [x for x in ncflags if x != 141 and x != 133]

            # Checking if the flags match and adding the result to a list to get displayed
            if self.draw_csv.isChecked() == True:
                match = []
                for i, x in enumerate(csvflags):
                    if x == ncflags[i]:
                        match.append('OK')
                    elif int(ncflags[i]) == 141:
                        match.append('OK')
                    elif int(ncflags[i] == 133):
                        match.append('OK')
                    else:
                        match.append('*DIF*')

        # If both are csv and nc are ticked to be drawn, package data from both and populate table
        if self.draw_csv.isChecked() == True and self.draw_nc.isChecked() == True:
            packed = list(zip(deps, rp, csvflags, ncflags, match, csvconc, ncconc))

            self.flag_table.setRowCount(len(packed))

            for row, x in enumerate(packed):
                for col, y in enumerate(x):
                    self.flag_table.setItem(row, col, QTableWidgetItem(str(y)))


    def view_data(self):
        # This subsets the data from the initial datasets based on the deployments selected to be viewed
        # this will also plot the nc data with varying markers based on bad data, csv includes no bad data so it is
        # just a straight plot
        self.mainplot.clear()

        self.csvdf = pd.DataFrame()
        self.ncdf = pd.DataFrame()
        data_hold = pd.DataFrame()
        legend_labels = []

        current_param = self.params_combo.currentText()
        param_header_key = self.header_key[current_param]
        param_flag_key = self.flag_key[current_param]

        selected_deps = self.deps_list.selectedItems()
        sel_deps = [item.text() for item in selected_deps]

        try:
            if self.draw_csv.isChecked() == True:
                # If draw csv checkbox is checked draw the csv data to the plot, this is basic due to
                # the csv not carrying any bad data, the load data function already made the csv a DF for us
                for x in sel_deps:
                    data_hold = data_hold.append(self.csvtempdf.loc[self.csvtempdf['Deployment'] == int(x)])
                    data_hold = data_hold.dropna(0, subset=[param_header_key])
                    self.mainplot.plot(data_hold[param_header_key], data_hold['Pressure'], marker='o', ms=5, mfc='none',
                                       linewidth=0.75)
                    legend_labels.append('Deployment ' + str(x))
                    self.csvdf = self.csvdf.append(data_hold)
                    data_hold = pd.DataFrame()
                if self.draw_woa.isChecked() == True and self.params_combo.currentText() == 'NOx':
                    #The WOA data is separated by month, so work out the closest month data that will match the CTD
                    time_check = self.csvdf['Time'].iloc[0]
                    month = time_check[5:7]
                    # Open file that corresponds to that month

                    file_path = 'C:/Users/she384/Documents/woa18nitratecsv/woa18_all_n' + str(month) + 'mn01.csv'
                    print(file_path)
                    woa_df = pd.read_csv(file_path, header=1)

                    lat_check = round(self.csvdf['Latitude'].iloc[0], 1)
                    string_lat_check = str(lat_check)
                    if int(string_lat_check[-1]) > 5:
                        tt = float(str(string_lat_check[:-2] + '.5'))
                        pp = lat_check - tt
                        lat_check = lat_check - pp
                    else:
                        tt = float(str(string_lat_check[:-2] + '.5'))
                        pp = tt - lat_check
                        lat_check = lat_check + pp

                    lon_check = round(self.csvdf['Longitude'].iloc[0], 1)
                    string_lon_check = str(lon_check)
                    if int(string_lon_check[-1]) > 5:
                        tt = float(str(string_lon_check[:-2] + '.5'))
                        pp = lon_check - tt
                        lon_check = lon_check - pp
                    else:
                        tt = float(str(string_lon_check[:-2] + '.5'))
                        pp = tt - lon_check
                        lon_check = lon_check + pp

                    woa_df2 = woa_df.loc[woa_df['#COMMA SEPARATED LATITUDE'] == lat_check]
                    woa_df3 = woa_df2.loc[woa_df2[' LONGITUDE'] == lon_check]

                    print(str(lat_check) + '  ' + str(lon_check))
                    print(woa_df3)
                    woa_depths = []
                    woa_concs = []
                    if not woa_df3.empty:
                        for i, col in enumerate(woa_df3):
                            if i > 1:
                                if i == 2:
                                    woa_depths.append(0)
                                else:
                                    woa_depths.append(int(col))
                                woa_concs.append(woa_df3[col].iloc[0])

                    print(woa_depths)
                    self.mainplot.plot(woa_concs, woa_depths, marker='o', ms=7, mfc='none', linewidth=0.75)




            if self.draw_nc.isChecked() == True:
                # If the nc checkbox is checked draw the nc data to the plot, this is more complicated due to a number
                # of factors, 1: the nc includes bad data, 2: missing data is stored as '--' which we need to get
                # rid of, 3: for missing data it includes an extra flag which needs to be discarded

                files_in_direc = os.listdir(self.nc_path.text())
                for file in files_in_direc: # Cycle through the files in the specified directory
                    if file[-2:] == 'nc':
                        ds = Dataset(self.nc_path.text() + '/' + file)
                        deploy = ds.Deployment
                        for x in sel_deps: # Loop through the selected deployments to find the right file
                            if int(x) == int(deploy):
                                deps_list = []
                                for y in range(ds.dimensions['pressure'].size):
                                    deps_list.append(deploy) # Make a list of the dep number the length of data

                                # Zip up the data so it can be easily input into a dataframe, the 3rd dimension
                                # contains the data we want, this is the dimension based along pressure
                                dszipped = list(zip(deps_list,
                                                    ds.variables['pressure'][:],
                                                    ds.variables['rosettePosition'][0, 0, :, 0],
                                                    ds.variables['oxygen'][0, 0, :, 0],
                                                    ds.variables['oxygenFlag'][0, 0, :, 0],
                                                    ds.variables['salinity'][0, 0, :, 0],
                                                    ds.variables['salinityFlag'][0, 0, :, 0],
                                                    ds.variables['nox'][0, 0, :, 0],
                                                    ds.variables['noxFlag'][0, 0, :, 0],
                                                    ds.variables['phosphate'][0, 0, :, 0],
                                                    ds.variables['phosphateFlag'][0, 0, :, 0],
                                                    ds.variables['silicate'][0, 0, :, 0],
                                                    ds.variables['silicateFlag'][0, 0, :, 0],
                                                    ds.variables['ammonia'][0, 0, :, 0],
                                                    ds.variables['ammoniaFlag'][0, 0, :, 0],
                                                    ds.variables['nitrite'][0, 0, :, 0],
                                                    ds.variables['nitriteFlag'][0, 0, :, 0]))

                                tempdf = pd.DataFrame(dszipped,
                                                         columns=['Deployment', 'Pressure', 'RP', 'Oxygen (uM)',
                                                                  'Oxygen flag',
                                                                  'Salinity (PSU)', 'Salinity flag',
                                                                  'NOx (uM)',
                                                                  'NOx flag', 'Phosphate (uM)', 'Phosphate flag',
                                                                  'Silicate (uM)',
                                                                  'Silicate flag',
                                                                  'Ammonia (uM)', 'Ammonia flag', 'Nitrite (uM)',
                                                                  'Nitrite flag'])

                                # Plot the NC data onto the figure
                                self.mainplot.plot(tempdf[param_header_key], tempdf['Pressure'], marker='o',
                                                   ms=0, mfc='none',
                                                   linewidth=0.0)

                                ncflags = tempdf[param_flag_key]
                                pres = tempdf['Pressure']
                                for i, v in enumerate(tempdf[param_header_key]):
                                    #print(ncflags[i])
                                    if ncflags[i] == 133 or ncflags[i] == 134 or ncflags[i] == 129:
                                        self.mainplot.plot(v, pres[i], marker='x', ms=7, linewidth=0, mec='#ac3232',
                                                           mfc='none')
                                    if ncflags[i] == 69 or ncflags[i] == 65:
                                        self.mainplot.plot(v, pres[i], marker='x', ms=9, linewidth=0, mec='#5fcde4',
                                                           mfc='none')
                                    else:
                                        self.mainplot.plot(v, pres[i], marker='s', ms=2, linewidth=0, mec='#39c88e',
                                                           mfc='#39c88e')
                                # For use in matching up flags an instance var is used to hold the selected deployments
                                # worth of data, appending using ignore index so it will just tack each dep on
                                # to the bottom of the dataframe for each loop
                                self.ncdf = self.ncdf.append(tempdf, ignore_index=True)

            # At the end of the whole fiasco format the figure to how we like
            self.mainplot.invert_yaxis()
            self.mainplot.set_facecolor('#f4f4f4')
            self.mainplot.grid(alpha=0.2, linewidth=0.5)
            self.mainplot.legend(legend_labels)
            self.mainplot.set_xlabel(self.header_key[str(current_param)])
            self.mainplot.set_ylabel('Pressure (db)')

            self.canvas.draw()

            self.view_flags()

        except Exception:
            print(traceback.print_exc())

    def load_filesf(self):
        # This function is a bit of a facade, it only really loads in the CSV file as a dataframe, this is to
        # populate the deployments list so a user can select a dep, it checks to make sure a nc file is in the
        # directory then ticks the nc loaded checkbox as a visual indicator for the user
        try:
            if os.path.exists(self.csv_path.text()):
                self.csvtempdf = pd.read_csv(self.csv_path.text())
                deps = list(set(self.csvtempdf['Deployment']))
                self.populate_list(deps)
                self.csv_loaded.setChecked(True)

            if os.path.exists(self.nc_path.text()):
                files_in_direc = os.listdir(self.nc_path.text())
                for file in files_in_direc:
                    if file[-2:] == 'nc':
                        self.nc_loaded.setChecked(True)

        except Exception:
            print(traceback.print_exc())

    def populate_list(self, items):
        # Adds the dep numbers to the qlistwidget
        self.deps_list.clear()
        for x in items:
            self.deps_list.addItem(str(x))

    def csv_browse_path(self):
        path = QFileDialog.Options()
        files = QFileDialog.getOpenFileName(self, "Select CSV", 'c://', "csv (*.csv)")
        if os.path.exists(files[0]):
            self.csv_path.setText(files[0])

    def nc_browse_path(self):
        path = QFileDialog.Options()
        files = QFileDialog.getExistingDirectory(self, "Select Folder containing NC files")
        if os.path.exists(files):
            self.nc_path.setText(files)

    def keyPressEvent(self, event):
        #print(event.key())
        # Used for incrementing the deployment number to quickly zoom through plots
        if event.key() == 78:
            self.increment_deployment()
Exemplo n.º 22
0
class PanelPlot(QFrame):
    flag = 0
    padre = None

    def __init__(self, pPadre):
        super(PanelPlot, self).__init__()
        super().setFrameShape(QFrame.StyledPanel)
        super().setStyleSheet('background-color: #444952; border-radius: 10px')
        super().setFixedWidth(1150)
        self.lay = QVBoxLayout()
        self.lay2 = QVBoxLayout()
        self.lay3 = QHBoxLayout()

        self.panelGrafica = QFrame()
        self.panelBotones = QFrame()

        self.panelGrafica.setStyleSheet('border-radius: 10px')
        self.panelBotones.setStyleSheet('border-radius: 10px')

        self.setLayout(self.lay)
        self.panelGrafica.setLayout(self.lay2)
        self.padre = pPadre
        self.combo = QComboBox(self)
        self.combo.addItem("VOLTAJE CARGA")
        self.combo.addItem("SOC BATERÍA")
        self.lay.addWidget(self.panelGrafica)

        self.panelBotones.setLayout(self.lay3)

        self.panelBotones.setFixedHeight(100)

        self.font = QFont()
        self.font.setFamily('Times font')
        self.font.setFixedPitch(False)
        self.font.setPointSize(10)
        self.font.setBold(True)

        self.combo.setStyleSheet('QComboBox'
                                 '{'
                                 'color:white;'
                                 'background-color: #23252a;'
                                 'border-radius: 10px'
                                 '}'
                                 'QComboBox::drop-down'
                                 '{'
                                 'width: 20px;'
                                 'border-color: #23252a;'
                                 'color: white'
                                 'background-color: #23252a;'
                                 '}')

        self.combo.setFont(self.font)

        self.combo.setEditable(True)
        self.ledit = self.combo.lineEdit()
        self.ledit.setAlignment(Qt.AlignCenter)
        self.ledit.setReadOnly(True)

        self.ledit.setStyleSheet('background-color:#23252a')
        self.lay3.addWidget(self.combo)
        self.ledit.setFont(self.font)

        self.combo.setFixedSize(200, 50)

        self.lay.addWidget(self.panelBotones)
        self.panelGrafica.show()
        self.combo.currentIndexChanged.connect(self.on_currentIndexChanged)
        self.y2 = None
        self.y1 = None

        self.sc = MplCanvas(self, 5, 4, 100)
        self.lay2.addWidget(self.sc)
        self.activar = False

    def on_currentIndexChanged(self):
        self.plot()

    def setActivar(self):
        self.activar = True

    def plot(self):
        if self.activar == True:
            self.data = self.padre.getData()
            self.tiempo = self.data[:, 0]
            self.y1 = self.data[:, 1]
            self.y2 = self.data[:, 2]

            if (self.combo.currentText() == "VOLTAJE CARGA"):
                y = self.y1
            elif (self.combo.currentText() == "SOC BATERÍA"):
                y = self.y2

            self.sc.axes.clear()
            self.sc.axes.plot(self.tiempo, y, color='#6a8922', linewidth=1)
            self.sc.draw()
Exemplo n.º 23
0
class TFWindow(QWidget):
    # take project object as input
    def __init__(self, parent=None):
        QWidget.__init__(self)
        self._threadExe = None
        self._threadSS = None
        self._ptName = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), "tf_proj.xml")
        self._p = project_io.Project()
        self._pTree = ET.ElementTree()
        # widgets for multithread
        self._qst_exe_button = QStackedWidget()
        self._qst_exe_param = QStackedWidget()
        self._qpr_exe_progress = QProgressBar()
        self._qpr_exe_progress.setRange(0, 100)
        # info widget for updating infomation
        # history statistics
        self._ql_hist_exe = QLabel(str(self.get_hist_item("exe")))
        self._ql_hist_ss = QLabel(str(self.get_hist_item("ss")))
        self._ql_hist_doc = QLabel(str(self.get_hist_item("doc")))
        # text
        self._qle_proj_filter = QLineEdit()  # filter to project list
        self._qle_proj_filter.setPlaceholderText("Search...")
        self._qle_proj_filter.textChanged.connect(
            lambda: ui_logic.slot_project_list_filter(self))
        self._qle_conf_file = QLineEdit()
        self._qle_dir_in = QLineEdit()
        self._qle_dir_out = QLineEdit()
        self._qle_exe_pv = QLineEdit()
        self._qle_exe_demo = QLineEdit()
        self._qcb_cur_ver = QComboBox()
        self._qcb_cur_ver.setEditable(True)
        self._qcb_cur_ver.lineEdit().setPlaceholderText("Input or Select..")
        self._qle_doc_name = QLineEdit()
        self._qpt_exe_param = QPlainTextEdit()
        # listview
        self._qlv_all_proj = create_QListView(self)
        self._qlv_all_proj.clicked.disconnect()
        self._qlv_all_proj.clicked.connect(
            lambda: ui_logic.slot_switch_proj(self))
        self._qlv_all_proj.doubleClicked.connect(
            lambda: ui_logic.slot_open_proj_path(self))
        self._qlv_exe_case = create_QListView(self, self._qle_dir_in)
        self._qlv_ss_case = create_QListView(self, self._qle_dir_out)
        self._qlv_ss_alg = create_QListView(self)
        self._qlv_ss_ver = create_QListView(self)
        self._qlv_doc_case = create_QListView(self, self._qle_dir_out)
        self._qlv_doc_alg = create_QListView(self)
        self._qlv_doc_ver = create_QListView(self)
        self._qlv_ss_ver.doubleClicked.connect(
            lambda: ui_logic.slot_open_ss_ver(self))
        self._qlv_ss_alg.doubleClicked.connect(
            lambda: ui_logic.slot_open_ss_alg(self))
        self._qlv_doc_ver.doubleClicked.connect(
            lambda: ui_logic.slot_open_doc_ver(self))
        self._qlv_doc_alg.doubleClicked.connect(
            lambda: ui_logic.slot_open_doc_alg(self))
        # doc type selector
        self._qcb_doc_type = QComboBox()  # type of document to be generated
        self._qcb_doc_type.setEditable(False)
        self._qcb_doc_type.addItems([
            "Screenshots", "Time_statistics", "CPU_MEM_statistics",
            "Hausdorf_dist"
        ])
        # other object
        self._cmdDialog = ui_cmd_history.CMDHistory(self._qpt_exe_param)
        self._filenameSelector = None
        # layout
        grid = QGridLayout()
        grid.addWidget(self.create_history(), 0, 0)
        grid.addWidget(self.create_project_manage(), 1, 0, 2, 1)
        grid.addWidget(self.create_project_info(), 0, 1)
        grid.addWidget(self.create_list_manage(), 1, 1)
        grid.addWidget(self.create_control_region(), 2, 1)
        grid.setColumnStretch(0, 1)
        grid.setColumnStretch(1, 3)
        self.setLayout(grid)
        self.setWindowTitle("Test Framework")
        self.resize(1200, 800)
        ui_logic.load_ptree_obj(self)
        self.fill_proj_list()

    def fill_proj_list(self, flt=""):
        m = QStandardItemModel()
        flag = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled
        for item in self._pTree.getroot():
            p_name = item.attrib["name"]
            flt_pass = True
            if len(flt) > 0:
                sub_pname = p_name
                for c in flt:
                    pos = sub_pname.find(c)
                    if pos == -1:
                        flt_pass = False
                        break
                    else:
                        sub_pname = sub_pname[pos + 1:]
            if not flt_pass:
                continue
            qsi = QStandardItem(p_name)
            qsi.setFlags(flag)
            qsi.setCheckable(False)
            m.appendRow(qsi)
        self._qlv_all_proj.setModel(m)

    def get_pv_path(self):
        tr = self._pTree.getroot()
        return tr.find(pv_default).attrib["path"]

    # load information from TFobject to ui
    def fill_ui_info(self, in_obj):
        self._p = in_obj
        cur_obj = self._p
        self._qle_conf_file.setText(cur_obj._configFile)
        self._qle_dir_in.setText(cur_obj._dirInput)
        self._qle_dir_out.setText(cur_obj._dirOutput)
        self._qle_exe_pv.setText(cur_obj._exePV)
        self._qle_exe_demo.setText(cur_obj._exeDemo)
        self._qle_doc_name.setText(cur_obj._docName)
        self._qcb_cur_ver.clear()
        self._qcb_doc_type.setCurrentText(in_obj._curDocType)

        for v in cur_obj._ver:
            self._qcb_cur_ver.addItem(v)
        self._qcb_cur_ver.setEditText(cur_obj._eVer)
        self._qpt_exe_param.setPlainText(cur_obj._exeParam)
        self.fill_check_list(self._qlv_exe_case, cur_obj._case,
                             cur_obj._eCaseCheck)
        self.fill_check_list(self._qlv_ss_case, cur_obj._case,
                             cur_obj._sCaseCheck)
        self.fill_check_list(self._qlv_ss_ver, cur_obj._ver,
                             cur_obj._sVerCheck)
        self.fill_check_list(self._qlv_ss_alg, cur_obj._alg,
                             cur_obj._sAlgCheck)
        self.fill_check_list(self._qlv_doc_case, cur_obj._case,
                             cur_obj._dCaseCheck)
        self.fill_check_list(self._qlv_doc_ver, cur_obj._ver,
                             cur_obj._dVerCheck)
        self.fill_check_list(self._qlv_doc_alg, cur_obj._alg,
                             cur_obj._dAlgCheck)

    def collect_ui_info(self):
        #out_obj = project_io.Project()
        out_obj = self._p
        out_obj._configFile = self._qle_conf_file.text()
        out_obj._dirInput = self._qle_dir_in.text()
        out_obj._dirOutput = self._qle_dir_out.text()
        out_obj._exePV = self._qle_exe_pv.text()
        out_obj._exeDemo = self._qle_exe_demo.text()
        out_obj._docName = self._qle_doc_name.text()
        out_obj._eVer = self._qcb_cur_ver.currentText()
        out_obj._exeParam = self._qpt_exe_param.toPlainText()
        out_obj._curDocType = self._qcb_doc_type.currentText()
        self.read_check_list(self._qlv_exe_case, out_obj._case,
                             out_obj._eCaseCheck)
        self.read_check_list(self._qlv_ss_case, out_obj._case,
                             out_obj._sCaseCheck)
        self.read_check_list(self._qlv_ss_ver, out_obj._ver,
                             out_obj._sVerCheck)
        self.read_check_list(self._qlv_ss_alg, out_obj._alg,
                             out_obj._sAlgCheck)
        self.read_check_list(self._qlv_doc_case, out_obj._case,
                             out_obj._dCaseCheck)
        self.read_check_list(self._qlv_doc_ver, out_obj._ver,
                             out_obj._dVerCheck)
        self.read_check_list(self._qlv_doc_alg, out_obj._alg,
                             out_obj._dAlgCheck)
        return out_obj

    def get_hist_item(self, hist_type):
        return int(float(utils.get_reg_item(hist_type)) + 0.1)

    def add_hist_item(self, hist_type, val):
        cur_num = self.get_hist_item(hist_type)
        new_num = str(cur_num + val)
        utils.set_reg_item(hist_type, new_num)
        if hist_type == "exe":
            self._ql_hist_exe.setText(new_num)
        elif hist_type == "ss":
            self._ql_hist_ss.setText(new_num)
        elif hist_type == "doc":
            self._ql_hist_doc.setText(new_num)

    def create_history(self):
        hist = QGroupBox("History Statistics")
        grid = QGridLayout()
        grid.addWidget(QLabel("Total Demo Run: "), 0, 0)
        grid.addWidget(self._ql_hist_exe, 0, 1)
        grid.addWidget(QLabel("Total ScreenShots: "), 1, 0)
        grid.addWidget(self._ql_hist_ss, 1, 1)
        grid.addWidget(QLabel("Total Docs: "), 2, 0)
        grid.addWidget(self._ql_hist_doc, 2, 1)
        hist.setLayout(grid)
        return hist

    def create_project_manage(self):
        manage = QGroupBox("Project Manage")
        qpb_new = QPushButton("New Project")
        qpb_new.setStyleSheet("background-color:#9a9a9a")
        qpb_delete = QPushButton("Delete Project")
        qpb_save = QPushButton("Save Project")
        qpb_load = QPushButton("Load Project")
        qpb_new.clicked.connect(lambda: ui_logic.slot_new_project(self))
        qpb_delete.clicked.connect(lambda: ui_logic.slot_delete_project(self))
        qpb_save.clicked.connect(lambda: ui_logic.slot_save_project(self))
        qpb_load.clicked.connect(lambda: ui_logic.slot_load_project(self))
        grid = QGridLayout()
        grid.addWidget(self._qle_proj_filter, 0, 0, 1, 2)
        grid.addWidget(self._qlv_all_proj, 1, 0, 1, 2)
        grid.addWidget(qpb_new, 2, 0)
        grid.addWidget(qpb_load, 2, 1)
        grid.addWidget(qpb_delete, 3, 0)
        grid.addWidget(qpb_save, 3, 1)
        manage.setLayout(grid)
        return manage

    def create_project_info(self):
        # fill information
        # create widget
        info = QGroupBox("Project Information")
        grid = QGridLayout()
        self.get_f_bsw(self._qle_conf_file, grid, 0, "Configuration File",
                       "xml")
        qpb_set_dir_in = QPushButton("Browse..")
        qpb_set_dir_in.setStyleSheet("background-color:#9a9a9a")
        qpb_open_dir_in = QPushButton("Open")
        grid.addWidget(QLabel("Input Directory"), 1, 0)
        grid.addWidget(self._qle_dir_in, 1, 1)
        grid.addWidget(qpb_set_dir_in, 1, 2)
        grid.addWidget(qpb_open_dir_in, 1, 3)
        qpb_set_dir_in.clicked.connect(
            lambda: ui_logic.slot_open_input_path(self))
        qpb_open_dir_in.clicked.connect(
            lambda: ui_logic.slot_open_path(self._qle_dir_in))
        self.get_f_bsw(self._qle_dir_out, grid, 2, "Output Directory")
        self.get_f_bsw(self._qle_exe_pv, grid, 3, "PVPython Interpreter",
                       "exe")
        self.get_f_bsw(self._qle_exe_demo, grid, 4, "Demo Executable", "exe")
        info.setLayout(grid)
        return info

    def create_list_manage(self):
        lm = QGroupBox("List Manage")
        l_hb = QGridLayout()
        qpb_scan_input = QPushButton("Scan Input Dir")
        qpb_build_output = QPushButton("Build Output Dir")
        qpb_add_case = QPushButton("Add Case Item")
        qpb_add_ver = QPushButton("Add Version Item")
        qpb_add_alg = QPushButton("Add FillName Item")
        qpb_del_case = QPushButton("Del Case Item")
        qpb_del_ver = QPushButton("Del Version Item")
        qpb_del_alg = QPushButton("Del FillName Item")
        qpb_del_case.setStyleSheet("background-color:#c82508")
        qpb_del_ver.setStyleSheet("background-color:#c82508")
        qpb_del_alg.setStyleSheet("background-color:#c82508")
        qpb_scan_input.clicked.connect(lambda: ui_logic.slot_scan_input(self))
        qpb_build_output.clicked.connect(
            lambda: ui_logic.slot_build_output(self))
        qpb_add_case.clicked.connect(
            lambda: ui_logic.slot_add_list(self, self._p._case, "Case"))
        qpb_add_ver.clicked.connect(
            lambda: ui_logic.slot_add_list(self, self._p._ver, "Version"))
        #qpb_add_alg.clicked.connect(
        #    lambda: ui_logic.slot_add_list(self, self._p._alg, "Algorithm"))
        qpb_add_alg.clicked.connect(self.slot_add_alg_list)
        qpb_del_case.clicked.connect(lambda: ui_logic.slot_del_list(
            self, self._qlv_ss_case, self._p._case))
        qpb_del_ver.clicked.connect(lambda: ui_logic.slot_del_list(
            self, self._qlv_ss_ver, self._p._ver))
        qpb_del_alg.clicked.connect(lambda: ui_logic.slot_del_list(
            self, self._qlv_ss_alg, self._p._alg))
        l_hb.addWidget(qpb_scan_input, 0, 0)
        l_hb.addWidget(qpb_add_case, 0, 1)
        l_hb.addWidget(qpb_add_ver, 0, 2)
        l_hb.addWidget(qpb_add_alg, 0, 3)
        l_hb.addWidget(qpb_build_output, 1, 0)
        l_hb.addWidget(qpb_del_case, 1, 1)
        l_hb.addWidget(qpb_del_ver, 1, 2)
        l_hb.addWidget(qpb_del_alg, 1, 3)
        lm.setLayout(l_hb)
        return lm

    # get listview from project_object
    def fill_check_list(self, lv, item_list, check_dict):
        model = QStandardItemModel()
        #pt_item = QStandardItem()
        flag = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled
        for i in item_list:
            item = QStandardItem(i)
            item.setFlags(flag)
            check = Qt.Checked if i in check_dict else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            model.appendRow(item)
        lv.setModel(model)

    # get project_object info from listview
    def read_check_list(self, lv, item_list, check_dict):
        item_list.clear()
        check_dict.clear()
        model = lv.model()
        if model is None:
            return
        for index in range(model.rowCount()):
            item = model.item(index)
            text = item.text()
            item_list.append(text)
            if item.checkState() == Qt.Checked:
                check_dict[text] = 1

    def create_control_region(self):
        control_region = QWidget()
        box = QHBoxLayout()
        box.addWidget(self.create_exe_region())
        box.addWidget(self.create_ss_region())
        box.addWidget(self.create_doc_region())
        control_region.setLayout(box)
        return control_region

    # create a file browser
    def get_f_bsw(self, qle, grid, grid_line, label, f_type=""):
        qpb = QPushButton("Browse..", self)
        qpb_open = QPushButton("Open", self)
        qpb_open.clicked.connect(lambda: ui_logic.slot_open_path(qle))
        grid.addWidget(QLabel(label), grid_line, 0)
        grid.addWidget(qle, grid_line, 1)
        grid.addWidget(qpb, grid_line, 2)
        grid.addWidget(qpb_open, grid_line, 3)
        if f_type == "":
            qpb.clicked.connect(lambda: ui_logic.slot_get_path(qle))
        else:
            qpb.clicked.connect(lambda: ui_logic.slot_get_file(qle, f_type))

    def create_exe_region(self):
        exe_region = QGroupBox("Executable Configuration")
        qpb_cmd_his = QPushButton("历史命令", self)
        qpb_cmd_his.clicked.connect(self.slot_show_cmd_history)

        qpb_exe_run = QPushButton('Run Demo')
        qpb_exe_stop = QPushButton('中断')
        qpb_exe_param = QPushButton("命令预览", self)
        qpb_exe_stop.setStyleSheet("background-color: red")
        qpb_exe_run.clicked.connect(lambda: ui_logic.slot_exe_run(self))
        qpb_exe_stop.clicked.connect(lambda: ui_logic.slot_exe_stop(self))
        qpb_exe_param.clicked.connect(lambda: ui_logic.slot_exe_param(self))
        # initial stack widget
        # 1st group
        self._qst_exe_param.addWidget(qpb_exe_param)
        self._qst_exe_button.addWidget(qpb_exe_run)
        # 2nd group
        self._qst_exe_param.addWidget(self._qpr_exe_progress)
        self._qst_exe_button.addWidget(qpb_exe_stop)
        # initi group
        self._qst_exe_param.setCurrentIndex(0)
        self._qst_exe_button.setCurrentIndex(0)

        grid = QGridLayout()
        grid.addWidget(QLabel('Input Case'), 0, 0)
        grid.addWidget(self._qlv_exe_case, 0, 1)
        grid.addWidget(
            QLabel(
                "Parameter Line\n{i} for input\n{o} for output\n{case} for case"
            ), 1, 0)
        grid.addWidget(qpb_cmd_his, 2, 0)
        grid.addWidget(self._qpt_exe_param, 1, 1, 2, 1)
        grid.addWidget(QLabel('Use Version Name'), 3, 0)
        grid.addWidget(self._qcb_cur_ver, 3, 1)
        grid.addWidget(self._qst_exe_param, 4, 0)
        grid.addWidget(self._qst_exe_button, 4, 1)
        exe_region.setLayout(grid)
        return exe_region

    def create_ss_region(self):
        ss_region = QGroupBox("ScreenShot Configuration")
        qpb_ss_shot = QPushButton('Take Screenshot', self)
        qpb_ss_shot.clicked.connect(
            lambda: ui_logic.slot_create_screenshots(self))
        qpb_ss_manage = QPushButton('设置视角', self)
        qpb_ss_manage.clicked.connect(lambda: ui_logic.slot_ss_manage(self))
        qpb_ss_preview = QPushButton('截图预览', self)
        qpb_ss_preview.clicked.connect(lambda: ui_logic.slot_ss_preview(self))
        grid = QGridLayout()
        grid.addWidget(QLabel('Case'), 1, 0)
        grid.addWidget(self._qlv_ss_case, 1, 1)
        grid.addWidget(QLabel('Version'), 2, 0)
        grid.addWidget(self._qlv_ss_ver, 2, 1)
        grid.addWidget(QLabel('FileName'), 3, 0)
        grid.addWidget(self._qlv_ss_alg, 3, 1)
        grid.addWidget(qpb_ss_manage, 4, 0)
        grid.addWidget(qpb_ss_preview, 4, 1)
        grid.addWidget(qpb_ss_shot, 5, 0, 1, 2)
        ss_region.setLayout(grid)
        return ss_region

    def create_doc_region(self):
        doc_region = QGroupBox("Docx Configuration")
        qpb_g_doc = QPushButton('Generate Doc', self)
        qpb_g_doc.clicked.connect(lambda: ui_logic.slot_generate_docx(self))
        # qpb_gt_doc = QPushButton('Time Docx', self)
        # qpb_gt_doc.clicked.connect(lambda: ui_logic.slot_generate_time_docx(self))
        # qpb_gp_doc = QPushButton('Proc Docx', self)
        # qpb_gp_doc.clicked.connect(lambda: ui_logic.slot_generate_proc_docx(self))
        qpb_o_doc = QPushButton('Open Document', self)
        qpb_o_doc.clicked.connect(lambda: ui_logic.slot_open_docx(self))
        qpb_o_path = QPushButton('Open Path', self)
        qpb_o_path.clicked.connect(lambda: ui_logic.slot_open_docx_path(self))
        qw_doc = QWidget()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        # hbox.addWidget(qpb_gt_doc)
        # hbox.addWidget(qpb_gp_doc)
        hbox.addWidget(self._qcb_doc_type)
        hbox.addWidget(qpb_g_doc)
        qw_doc.setLayout(hbox)
        grid = QGridLayout()
        grid.addWidget(QLabel('Case'), 1, 0)
        grid.addWidget(self._qlv_doc_case, 1, 1)
        grid.addWidget(QLabel('Version'), 2, 0)
        grid.addWidget(self._qlv_doc_ver, 2, 1)
        grid.addWidget(QLabel('FileName'), 3, 0)
        grid.addWidget(self._qlv_doc_alg, 3, 1)
        grid.addWidget(QLabel('FileName'), 3, 0)
        grid.addWidget(self._qlv_doc_alg, 3, 1)
        grid.addWidget(QLabel('Doc Name'), 4, 0)
        grid.addWidget(self._qle_doc_name, 4, 1)
        grid.addWidget(qpb_o_path, 5, 0)
        grid.addWidget(qpb_o_doc, 5, 1)
        grid.addWidget(qw_doc, 6, 0, 1, 2)
        doc_region.setLayout(grid)
        return doc_region

    def slot_show_cmd_history(self):
        self._cmdDialog.resize(800, 200)
        self._cmdDialog.fill_list()
        self._cmdDialog.show()

    def slot_add_alg_list(self):
        cand = ui_logic.get_all_filenames(self._p)
        self._filenameSelector = FileNameSelector(self, cand)
        self._filenameSelector.exec_()
        self.fill_ui_info(self._p)

    # button status switch
    def new_run_button(self):
        self._qst_exe_button.setCurrentIndex(0)
        self._qst_exe_param.setCurrentIndex(0)

    def new_stop_button(self):
        self._qst_exe_button.setCurrentIndex(1)
        self._qst_exe_param.setCurrentIndex(1)

    def exe_progress(self, p):
        self._qpr_exe_progress.setValue(p)

    def exe_finish(self):
        self.new_run_button()
        self._qlv_all_proj.setEnabled(True)
Exemplo n.º 24
0
class MainWindow(QWidget):
    def __init__(self, app):
        super().__init__()
        self.app = app
        self.async_fetch = AsyncFetch(CachedHttpClient(HttpClient(), 'cache'))
        self.async_fetch.ready.connect(self.on_fetch_ready)

        self.comboxBox = QComboBox(self)
        self.comboxBox.setEditable(True)
        self.comboxBox.setCurrentText('')
        self.comboxBox.currentTextChanged.connect(self.on_text_changed)

        font = QFont()
        font.setPointSize(font.pointSize() + ADD_TO_FONT_SIZE)
        self.comboxBox.setFont(font)

        self.browser = QTextBrowser(self)
        self.browser.setText(STYLE + HTML)
        self.browser.show()

        mainLayout = QVBoxLayout(self)
        mainLayout.setSpacing(0)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.addWidget(self.comboxBox)
        mainLayout.addWidget(self.browser)
        self.setLayout(mainLayout)

        self.setWindowTitle('OrdbokUibNo')
        self.resize(WINDOW_WIDTH, WINDOW_HEIGHT)
        self.setWindowIcon(QIcon(ICON_FILENAME))

        QTimer.singleShot(1, self.center)

        self.center()
        self.show()

    def activate(self):
        self.center()
        self.show()
        self.raise_()
        self.activateWindow()
        self.comboxBox.lineEdit().selectAll()
        self.comboxBox.setFocus()

    def center(self):
        qr = self.frameGeometry()
        desktop = QApplication.desktop()
        screen = desktop.screenNumber(desktop.cursor().pos())
        cp = desktop.screenGeometry(screen).center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def suggest(self, words):
        completer = QCompleter(words, self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.comboxBox.setCompleter(completer)
        completer.complete()

    def set_text(self, text):
        self.browser.setText(STYLE + text)

    def on_text_changed(self, text):
        if text == '':
            return

        QTimer.singleShot(UPDATE_DELAY, lambda: self.update(text))

    def update(self, old_text):
        if self.same_text(old_text):
            self.fetch(old_text)

    @pyqtSlot(object)
    def on_fetch_ready(self, result: object):
        if isinstance(result, Article):
            if self.same_text(result.word) and result.parts:
                self.set_text(result.html)
        elif isinstance(result, Suggestions):
            if self.same_text(result.word) and result.top:
                print(result)
                self.suggest(result.top)
        else:
            logging.warn('unknown fetch result: %s', result)

    def fetch(self, word):
        self.async_fetch.add(lambda client: Article(client, word))
        self.async_fetch.add(lambda client: Suggestions(client, word))

    def onTrayActivated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.show()

    def same_text(self, word):
        return word == self.text()

    def text(self):
        return self.comboxBox.currentText()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.hide()
        elif (e.key() == Qt.Key_Q) and (e.modifiers() == Qt.ControlModifier):
            self.close()
        elif (e.key() == Qt.Key_L) and (e.modifiers() == Qt.ControlModifier):
            self.comboxBox.lineEdit().selectAll()
            self.comboxBox.setFocus()
        elif e.key() == Qt.Key_Return:
            self.fetch(self.text())
Exemplo n.º 25
0
def edit_contact_dialog(wallet_api, contact_key=None):
    editing = contact_key is not None
    if editing:
        title = _("Edit Contact")
    else:
        title = _("New Contact")

    d = WindowModalDialog(wallet_api.wallet_window, title)
    vbox = QVBoxLayout(d)
    vbox.addWidget(QLabel(title + ':'))

    def _contact_insert_completion(text):
        if text:
            index = combo1.findText(text)
            combo1.setCurrentIndex(index)

    identity_line = QLineEdit()
    name_line = QLineEdit()
    combo1 = QComboBox()
    combo1.setFixedWidth(280)
    combo1.setEditable(True)

    # add a filter model to filter matching items
    contact_filter_model = QSortFilterProxyModel(combo1)
    contact_filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
    contact_filter_model.setSourceModel(combo1.model())

    contact_completer = QCompleter(contact_filter_model, combo1)
    contact_completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
    combo1.setCompleter(contact_completer)

    ok_button = OkButton(d)
    ok_button.setEnabled(False)

    def _validate_form() -> None:
        def _set_validation_state(element, is_valid) -> None:
            if not is_valid:
                element.setStyleSheet("border: 1px solid red")
            else:
                element.setStyleSheet("")

        can_submit = True

        system_name = combo1.currentText().lower().strip()
        is_valid = True
        try:
            system_id = get_system_id(system_name)
        except ContactDataError:
            system_id = None
            is_valid = False
        _set_validation_state(combo1, is_valid)
        can_submit = can_submit and is_valid

        identity_text = identity_line.text().strip()
        if system_id is None:
            identity_result = IdentityCheckResult.Invalid
        else:
            identity_result = wallet_api.check_identity_valid(system_id, identity_text,
                skip_exists=editing)
        is_valid = identity_result == IdentityCheckResult.Ok
        _set_validation_state(identity_line, is_valid)
        if is_valid:
            identity_line.setToolTip("")
        elif identity_result == IdentityCheckResult.Invalid:
            if system_id == IdentitySystem.OnChain:
                identity_line.setToolTip(_("Not a valid Bitcoin address"))
            else:
                identity_line.setToolTip(_("Incorrect format"))
        elif identity_result == IdentityCheckResult.InUse:
            identity_line.setToolTip(_("Already in use"))
        can_submit = can_submit and is_valid

        name_text = name_line.text().strip()
        name_result = wallet_api.check_label(name_text)
        is_valid = (name_result == IdentityCheckResult.Ok or
            editing and name_result == IdentityCheckResult.InUse)
        _set_validation_state(name_line, is_valid)
        if is_valid:
            name_line.setToolTip("")
        elif name_result == IdentityCheckResult.Invalid:
            name_line.setToolTip(_("Name too short"))
        elif name_result == IdentityCheckResult.InUse:
            name_line.setToolTip(_("Name already in use"))
        can_submit = can_submit and is_valid

        ok_button.setEnabled(can_submit)

    def _contact_text_changed(text: str) -> None:
        _validate_form()

    combo1.lineEdit().textEdited.connect(contact_filter_model.setFilterFixedString)
    combo1.editTextChanged.connect(_contact_text_changed)
    identity_line.textChanged.connect(_contact_text_changed)
    name_line.textChanged.connect(_contact_text_changed)
    contact_completer.activated.connect(_contact_insert_completion)

    combo1.addItems(list(IDENTITY_SYSTEM_NAMES.values()))

    grid = QGridLayout()
    identity_line.setFixedWidth(280)
    name_line.setFixedWidth(280)
    grid.addWidget(QLabel(_("Identity Type")), 1, 0)
    grid.addWidget(combo1, 1, 1)
    grid.addWidget(QLabel(_("Identity")), 2, 0)
    grid.addWidget(identity_line, 2, 1)
    grid.addWidget(QLabel(_("Name")), 3, 0)
    grid.addWidget(name_line, 3, 1)

    vbox.addLayout(grid)
    vbox.addLayout(Buttons(CancelButton(d), ok_button))

    if contact_key is None:
        combo1.lineEdit().setText(IDENTITY_SYSTEM_NAMES[IdentitySystem.OnChain])
        identity_line.setFocus()
    else:
        entry = wallet_api.get_contact(contact_key[0])
        identity = [ ci for ci in entry.identities if ci.identity_id == contact_key[1] ][0]
        combo1.lineEdit().setText(IDENTITY_SYSTEM_NAMES[identity.system_id])
        identity_line.setText(identity.system_data)
        name_line.setText(entry.label)
        name_line.setFocus()

    if d.exec_():
        name_text = name_line.text().strip()
        identity_text = identity_line.text().strip()
        system_id = get_system_id(combo1.currentText())
        if contact_key is not None:
            contact = wallet_api.get_contact(contact_key[0])
            identity = [ ci for ci in contact.identities if ci.identity_id == contact_key[1] ][0]
            if contact_key[1] != identity.identity_id:
                wallet_api.remove_identity(contact_key[0], contact_key[1])
                wallet_api.add_identity(contact_key[0], system_id, identity_text)
            if contact.label != name_text:
                wallet_api.set_label(contact_key[0], name_text)
        else:
            wallet_api.add_contact(system_id, name_text, identity_text)
Exemplo n.º 26
0
class Printing(preferences.Group):
    def __init__(self, page):
        super(Printing, self).__init__(page)
        
        layout = QGridLayout(spacing=1)
        self.setLayout(layout)
        
        self.messageLabel = QLabel(wordWrap=True)
        self.printCommandLabel = QLabel()
        self.printCommand = widgets.urlrequester.UrlRequester()
        self.printCommand.setFileMode(QFileDialog.ExistingFile)
        self.printCommand.changed.connect(page.changed)
        self.printDialogCheck = QCheckBox(toggled=page.changed)
        self.resolutionLabel = QLabel()
        self.resolution = QComboBox(editable=True, editTextChanged=page.changed)
        self.resolution.addItems("300 600 1200".split())
        self.resolution.lineEdit().setInputMask("9000")

        layout.addWidget(self.messageLabel, 0, 0, 1, 2)
        layout.addWidget(self.printCommandLabel, 1, 0)
        layout.addWidget(self.printCommand, 1, 1)
        layout.addWidget(self.printDialogCheck, 2, 0, 1, 2)
        layout.addWidget(self.resolutionLabel, 3, 0)
        layout.addWidget(self.resolution, 3, 1)
        
        app.translateUI(self)
    
    def translateUI(self):
        self.setTitle(_("Printing Music"))
        self.messageLabel.setText(_(
            "Here you can enter a command to print a PDF or PostScript file. "
            "See the Help page for more information about printing music."))
        self.printCommandLabel.setText(_("Printing command:"))
        self.printCommand.setToolTip('<qt>' + _(
            "The printing command is used to print a PostScript or PDF file. "
            "On Linux you don't need this, but on Windows and Mac OS X you can "
            "provide a command to avoid that PDF documents are being printed "
            "using raster images, which is less optimal.\n"
            "<code>$pdf</code> gets replaced with the PDF filename, or alternatively, "
            "<code>$ps</code> is replaced with the PostScript filename. "
            "<code>$printer</code> is replaced with the printer's name to use."))
        self.printDialogCheck.setText(_("Use Frescobaldi's print dialog"))
        self.printDialogCheck.setToolTip('<qt>' + _(
            "If enabled, Frescobaldi will show the print dialog and create a "
            "PDF or PostScript document containing only the selected pages "
            "to print. Otherwise, the command is called directly and is expected "
            "to show a print dialog itself."))
        self.resolutionLabel.setText(_("Resolution:"))
        self.resolution.setToolTip(_(
            "Set the resolution if Frescobaldi prints using raster images."))
    
    def loadSettings(self):
        s = QSettings()
        s.beginGroup("helper_applications")
        self.printCommand.setPath(s.value("printcommand", "", str))
        self.printDialogCheck.setChecked(s.value("printcommand/dialog", False, bool))
        with qutil.signalsBlocked(self.resolution):
            self.resolution.setEditText(format(s.value("printcommand/dpi", 300, int)))
    
    def saveSettings(self):
        s= QSettings()
        s.beginGroup("helper_applications")
        s.setValue("printcommand", self.printCommand.path())
        s.setValue("printcommand/dialog", self.printDialogCheck.isChecked())
        s.setValue("printcommand/dpi", int(self.resolution.currentText()))
Exemplo n.º 27
0
class MainWindow(QMainWindow):
    """
    handle the bulk of the ugliness of window/widget geometry
    QMainWindow affords a built-in status bar, otherwise this could just be a QWidget
    written by 'hand' instead of by Qt Designer as an exercise in understanding PyQt5
    in hindsight, this should've been broken down into more functions or even classes...
    """
    def __init__(self):
        super(MainWindow, self).__init__()

        self.mission_folder = getcwd()

        # central widgets/layouts
        self.central_widget = QTabWidget()
        self.central_layout = QVBoxLayout(self.central_widget)
        self.tabs = QTabWidget()
        self.label_about = QLabelClickable('About Maximum Roverdrive',
                                           self.tabs)
        self.label_about.setObjectName('label_about')

        # monitor widgets (left tab)
        self.widget_mav_monitor = QWidget()
        self.layout_mav_monitor = QVBoxLayout(self.widget_mav_monitor)
        self.frame_connect = QFrame()
        self.layout_connect = QHBoxLayout(self.frame_connect)
        self.button_connect = QPushButton('Connect')
        self.combo_port = QComboBox()
        self.widget_add_remove_buttons = QWidget()
        self.layout_add_remove_buttons = QHBoxLayout(
            self.widget_add_remove_buttons)
        self.button_msg_add = QPushButton('Add Message')
        self.button_msg_remove = QPushButton('Remove Selected Message')
        self.table_messages = QTableView()
        self.frame_msg_request = QFrame()
        self.form_msg_request = QFormLayout()
        self.form_msg_request.setLabelAlignment(Qt.AlignRight)
        self.button_msg_refresh = QPushButton('Refresh Messages')
        self.combo_msg_select = QComboBox()
        self.combo_attr_select = QComboBox()
        self.text_multiplier = QLineEdit('1.0')
        self.text_low = QLineEdit('0.0')
        self.text_high = QLineEdit('1000.0')

        # utilities widgets (center tab)
        self.widget_utilities = QWidget()
        self.layout_utilities = QVBoxLayout(self.widget_utilities)
        self.frame_utilities_header = QFrame()
        self.grid_utilities_header = QGridLayout(self.frame_utilities_header)
        self.button_arm = QPushButton('ARM')
        self.button_disarm = QPushButton('DISARM')
        self.label_headlight_relay = QLabel('Light Relay')
        self.checkbox_auto_headlights = QCheckBox(
            '   Enable\n Automatic\nHeadlights')
        self.checkbox_relay_active_low = QCheckBox('  Relays\nActive Low')
        self.combo_headlight_relay = QComboBox()
        self.frame_mav_command_start = QFrame()
        self.frame_mav_command_start.setObjectName('mav_command_start')
        self.grid_mav_command_start = QGridLayout(self.frame_mav_command_start)
        self.label_mav_command_start = QLabel(
            'Command at <span style="color: #94d6a3; font-weight: bold;">'
            'Mission Start:</span>')
        self.combo_mav_command_start = QComboBox()
        self.labels_mav_command_start = [QLabel()] * 8
        self.texts_mav_command_start = [QComboBox()]
        self.texts_mav_command_start.extend([QLineEdit()] * 7)
        self.button_mav_command_start_send = QPushButton('Send Now')
        self.checkbox_mav_command_start = QCheckBox('On Mission Start')
        self.checkbox_mav_command_start_all = QCheckBox('At Each WP')
        self.frame_mav_command_end = QFrame()
        self.frame_mav_command_end.setObjectName('mav_command_end')
        self.grid_mav_command_end = QGridLayout(self.frame_mav_command_end)
        self.label_mav_command_end = QLabel(
            'Command at <span style="color: #ffe383; font-weight: bold;">'
            'Mission End:</span>')
        self.combo_mav_command_end = QComboBox()
        self.labels_mav_command_end = [QLabel()] * 8
        self.texts_mav_command_end = [QComboBox()]
        self.texts_mav_command_end.extend([QLineEdit()] * 7)
        self.button_mav_command_end_send = QPushButton('Send Now')
        self.checkbox_mav_command_end = QCheckBox('On Mission End')
        self.checkbox_mav_command_end_all = QCheckBox('At Each WP')

        # status messages (right tab)
        self.widget_status = QWidget()
        self.layout_status = QVBoxLayout(self.widget_status)
        self.text_status = QTextStatus()

        # file widgets at bottom of central vertical layout
        self.frame_mission_file = QFrame()
        self.grid_mission_file = QGridLayout(self.frame_mission_file)
        self.button_mission_file = QPushButton('Select\nMission File')
        self.text_mission_file = QTextEdit()
        self.button_convert_file = QPushButton('Convert File')
        self.button_modify_file = QPushButton('Modify File')

    def __init_ui__(self):
        """ called by 'public' method self.initialize()  """
        # set up the monitor widget layout
        self.layout_connect.setContentsMargins(0, 0, 0, 0)
        self.frame_connect.setStyleSheet('QFrame { border: 0px; }')
        self.combo_port.setEditable(True)
        self.button_connect.setMaximumWidth(85)
        self.layout_connect.addWidget(self.combo_port)
        self.layout_connect.addWidget(self.button_connect)
        self.layout_mav_monitor.addWidget(self.frame_connect)
        self.table_messages.horizontalHeader().setStretchLastSection(True)
        self.table_messages.horizontalHeader().hide()
        self.table_messages.verticalHeader().hide()
        self.layout_mav_monitor.addWidget(self.table_messages)
        self.layout_add_remove_buttons.addWidget(self.button_msg_add)
        self.layout_add_remove_buttons.addWidget(self.button_msg_remove)
        self.layout_add_remove_buttons.setContentsMargins(5, 5, 5, 5)
        self.layout_mav_monitor.addWidget(self.widget_add_remove_buttons)
        self.combo_msg_select.addItem('Click refresh')
        self.form_msg_request.addRow(self.button_msg_refresh,
                                     self.combo_msg_select)
        self.form_msg_request.addRow('Message Content:',
                                     self.combo_attr_select)
        self.form_msg_request.addRow('Multiplier:', self.text_multiplier)
        self.form_msg_request.addRow('Low Threshold:', self.text_low)
        self.form_msg_request.addRow('High Threshold:', self.text_high)
        self.frame_msg_request.setLayout(self.form_msg_request)
        self.layout_mav_monitor.addWidget(self.frame_msg_request)

        # set up the utilities widget layout
        self.grid_utilities_header.setColumnStretch(0, 4)
        self.button_arm.setMinimumWidth(76)
        self.button_disarm.setMinimumWidth(76)
        self.grid_utilities_header.setRowStretch(1, 2)
        self.button_arm.setEnabled(False)
        self.button_disarm.setEnabled(False)
        self.button_mav_command_start_send.setEnabled(False)
        self.button_mav_command_end_send.setEnabled(False)
        self.grid_utilities_header.addWidget(self.button_arm, 0, 0)
        self.grid_utilities_header.addWidget(self.button_disarm, 1, 0)
        self.grid_utilities_header.addWidget(self.checkbox_relay_active_low, 0,
                                             2, 2, 1)
        self.grid_utilities_header.addWidget(self.checkbox_auto_headlights, 0,
                                             3, 2, 1)
        self.label_headlight_relay.setStyleSheet(
            'QLabel { qproperty-alignment: AlignCenter; }')
        self.grid_utilities_header.addWidget(self.label_headlight_relay, 0, 4)
        self.combo_headlight_relay.addItems([str(x) for x in range(7)])
        self.combo_headlight_relay.setEditable(True)
        self.combo_headlight_relay.lineEdit().setReadOnly(True)
        self.combo_headlight_relay.lineEdit().setAlignment(Qt.AlignCenter)
        self.grid_utilities_header.addWidget(self.combo_headlight_relay, 1, 4)
        self.grid_utilities_header.setContentsMargins(5, 5, 5, 5)

        self.grid_mav_command_start.addWidget(self.label_mav_command_start, 0,
                                              0, 1, 2)
        self.grid_mav_command_start.addWidget(self.combo_mav_command_start, 0,
                                              2, 1, 2)
        for x in range(8):
            self.grid_mav_command_start.setColumnStretch(x, 2)
            y = 1 if x < 4 else 3
            self.labels_mav_command_start[x] = QLabel(f'Arg{x + 1}')
            self.labels_mav_command_start[x].setObjectName('label_arg')
            if x > 1:
                self.texts_mav_command_start[x] = QLineEdit()
            else:
                self.texts_mav_command_start[x] = QWideComboBox()
                self.texts_mav_command_start[x].setEditable(True)
                self.texts_mav_command_start[x].lineEdit().setAlignment(
                    Qt.AlignCenter)
                self.texts_mav_command_start[x].SizeAdjustPolicy(
                    QComboBox.AdjustToContentsOnFirstShow)
            self.texts_mav_command_start[x].setObjectName('text_arg')
            self.texts_mav_command_start[x].setMinimumWidth(82)
            self.grid_mav_command_start.addWidget(
                self.labels_mav_command_start[x], y, x % 4)
            self.grid_mav_command_start.addWidget(
                self.texts_mav_command_start[x], y + 1, x % 4)

        self.grid_mav_command_start.addWidget(
            self.button_mav_command_start_send, 5, 3)
        self.grid_mav_command_start.addWidget(self.checkbox_mav_command_start,
                                              5, 0, 1, 2)
        self.grid_mav_command_start.addWidget(
            self.checkbox_mav_command_start_all, 5, 2)

        self.grid_mav_command_end.addWidget(self.label_mav_command_end, 0, 0,
                                            1, 2)
        self.grid_mav_command_end.addWidget(self.combo_mav_command_end, 0, 2,
                                            1, 2)
        for x in range(8):
            self.grid_mav_command_end.setColumnStretch(x, 2)
            y = 1 if x < 4 else 3
            self.labels_mav_command_end[x] = QLabel(f'Arg{x + 1}')
            self.labels_mav_command_end[x].setObjectName('label_arg')
            if x > 1:
                self.texts_mav_command_end[x] = QLineEdit()
            else:
                self.texts_mav_command_end[x] = QWideComboBox()
                self.texts_mav_command_end[x].setEditable(True)
                self.texts_mav_command_end[x].lineEdit().setAlignment(
                    Qt.AlignCenter)
                self.texts_mav_command_end[x].SizeAdjustPolicy(
                    QComboBox.AdjustToContentsOnFirstShow)
            self.texts_mav_command_end[x].setMinimumWidth(82)
            self.grid_mav_command_end.addWidget(self.labels_mav_command_end[x],
                                                y, x % 4)
            self.grid_mav_command_end.addWidget(self.texts_mav_command_end[x],
                                                y + 1, x % 4)
        self.grid_mav_command_end.addWidget(self.button_mav_command_end_send,
                                            5, 3)
        self.grid_mav_command_end.addWidget(self.checkbox_mav_command_end, 5,
                                            0, 1, 2)
        self.grid_mav_command_end.addWidget(self.checkbox_mav_command_end_all,
                                            5, 2)

        self.layout_utilities.addWidget(self.frame_utilities_header)
        self.layout_utilities.addWidget(self.frame_mav_command_start)
        self.layout_utilities.addWidget(self.frame_mav_command_end)

        # set up the filename container at the bottom of the central vertical layout
        self.frame_mission_file.setStyleSheet(
            'QFrame { border: 0px; }'
            'QTextEdit { border: 1px solid #515253; }'
            'QTextEdit:focus { border: 1px solid #53a0ed; }')
        self.button_mission_file.setContentsMargins(10, 10, 10, 10)
        self.text_mission_file.setFixedHeight(40)
        self.text_mission_file.setToolTip(
            'Auto-filled when files change in the Mission file folder\n'
            'Override by clicking the button to choose a file')
        for x in range(4):
            self.grid_mission_file.setColumnStretch(x, 2)
        self.grid_mission_file.addWidget(self.button_mission_file, 0, 0)
        self.grid_mission_file.addWidget(self.text_mission_file, 0, 1, 1, 3)
        self.grid_mission_file.addWidget(self.button_convert_file, 1, 0, 1, 2)
        self.grid_mission_file.addWidget(self.button_modify_file, 1, 2, 1, 2)
        self.grid_mission_file.setContentsMargins(5, 0, 5, 5)

        # set up the status messages tab
        self.text_status.setReadOnly(True)
        self.layout_status.addWidget(self.text_status)
        self.layout_status.setContentsMargins(0, 0, 0, 0)

    def initialize(
        self
    ):  # allows for instantiating method to populate list/text items before painting
        """ must be called after class instantiation for window to be displayed """
        self.__init_ui__()  # populate the layouts

        # set up the main window
        self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.setWindowTitle('Maximum Roverdrive')

        # put the central widget together
        self.central_layout.setContentsMargins(5, 5, 5, 5)
        self.layout_mav_monitor.setContentsMargins(5, 5, 5, 5)
        self.layout_utilities.setContentsMargins(5, 5, 5, 5)
        self.central_widget.setMinimumWidth(400)
        self.central_widget.setMinimumHeight(502)
        self.tabs.addTab(self.widget_mav_monitor, 'Monitor')
        self.tabs.addTab(self.widget_utilities, 'Utilities')
        self.tabs.addTab(self.widget_status, 'Messages')
        self.central_layout.addWidget(self.tabs)
        self.central_layout.addWidget(self.frame_mission_file)
        self.label_about.setCursor(QCursor(Qt.PointingHandCursor))
        self.label_about.move(240, 2)
        self.setCentralWidget(self.central_widget)

        self.__init_connections__()  # connect the ui signals

    def __init_connections__(self):
        """
            called by 'public' method self.initialize()
            instances of this class must define slots for the following connections:
         """
        self.combo_port.lineEdit().returnPressed.connect(self.mav_connect)
        self.button_connect.clicked.connect(self.mav_connect)
        self.button_msg_add.clicked.connect(self.add_msg)
        self.button_msg_remove.clicked.connect(self.remove_selected_msg)
        self.button_msg_refresh.clicked.connect(self.refresh_msg_select)
        self.combo_msg_select.currentIndexChanged.connect(
            self.refresh_attr_select)
        self.combo_attr_select.currentIndexChanged.connect(
            self.update_button_msg_add)

        self.button_arm.clicked.connect(self.arm)
        self.button_disarm.clicked.connect(self.disarm)
        self.checkbox_relay_active_low.clicked.connect(self.save_relay_state)
        self.checkbox_auto_headlights.clicked.connect(
            self.save_auto_headlights_state)
        self.combo_headlight_relay.currentTextChanged.connect(
            self.save_headlight_relay)
        self.button_mav_command_start_send.clicked.connect(
            self.mav_command_send)
        self.button_mav_command_end_send.clicked.connect(self.mav_command_send)

        self.combo_mav_command_start.currentIndexChanged.connect(
            self.update_combo_mav_command)
        self.combo_mav_command_end.currentIndexChanged.connect(
            self.update_combo_mav_command)
        self.button_convert_file.clicked.connect(self.convert_mission_file)
        self.button_modify_file.clicked.connect(self.modify_mission_file)

        # these are not abstract
        self.label_about.clicked.connect(self.about)
        self.button_mission_file.clicked.connect(self.mission_file_dialog)

    @pyqtSlot()
    def mission_file_dialog(self):
        filename = QFileDialog.getOpenFileName(
            self,
            caption='Select Waypoint/Poly File',
            directory=self.mission_folder,
            filter='Mission Files (*.waypoints *.poly);;All files (*.*)',
            options=QFileDialog.DontUseNativeDialog)
        if filename != ('', ''):
            filename = QDir.toNativeSeparators(filename[0])
            self.text_mission_file.setText(filename)
            return filename
        return None

    @pyqtSlot()
    def about(self):
        msg = QMessageBox(icon=QMessageBox.NoIcon)
        msg.setWindowFlag(Qt.WindowStaysOnTopHint)
        msg.setWindowTitle('About Maximum Roverdrive')
        msg.setStandardButtons(QMessageBox.Ok)
        msg.setTextFormat(Qt.RichText)
        msg.setStyleSheet(
            'QMessageBox { border-image: url(:/images/logo.png); }'
            'QLabel { width: 443px; min-width: 443px; max-width: 443px;'
            'height: 251px; min-height: 251px; max-height: 251px; '
            'font-family: "Copperplate Gothic Bold", sans-serif; '
            'font-size: 20px; font-weight: 500; }')
        msg.setText(
            '© 2020, Yuri<br>'
            '''<a style="font-family: 'Calibri, sans-serif'; font-size: 12px; font-weight: normal;"'''
            'href="https://github.com/yuri-rage/MaximumRoverdrive">View on GitHub</a>'
            '<br><br><br><br><br><br><br><br><br><br>')
        msg.exec()
Exemplo n.º 28
0
class SnapshotCompareWidget(QWidget):
    pvs_filtered = QtCore.pyqtSignal(set)
    restore_requested = QtCore.pyqtSignal(list)
    rgx_icon = None

    def __init__(self, snapshot, common_settings, parent=None, **kw):
        super().__init__(parent, **kw)
        self.snapshot = snapshot
        self.common_settings = common_settings

        # ----------- PV Table -------------
        # PV table consist of:
        #     self.model: holding the data, values, being updated by PV callbacks, etc
        #     self._proxy: a proxy model implementing the filter functionality
        #     self.view: visual representation of the PV table

        self.view = SnapshotPvTableView(self)
        self.view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.view.restore_requested.connect(self._handle_restore_request)

        self.model = SnapshotPvTableModel(snapshot, self)
        self.model.file_parse_errors.connect(self._show_snapshot_parse_errors)
        self._proxy = SnapshotPvFilterProxyModel(self)
        self._proxy.setSourceModel(self.model)
        self._proxy.filtered.connect(self.pvs_filtered)

        # Build model and set default visualization on view (column widths, etc)
        self.model.set_pvs(snapshot.pvs.values())
        self.view.setModel(self._proxy)

        # ---------- Filter control elements ---------------
        # - text input to filter by name
        # - drop down to filter by compare status
        # - check box to select if showing pvs with incomplete data

        if SnapshotCompareWidget.rgx_icon is None:
            SnapshotCompareWidget.rgx_icon = QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             "images/rgx.png"))

        # #### PV name filter
        pv_filter_label = QLabel("Filter:", self)
        pv_filter_label.setAlignment(Qt.AlignCenter | Qt.AlignRight)

        self.pv_filter_sel = QComboBox(self)
        self.pv_filter_sel.setEditable(True)
        self.pv_filter_sel.setIconSize(QtCore.QSize(35, 15))
        self.pv_filter_inp = self.pv_filter_sel.lineEdit()
        self.pv_filter_inp.setPlaceholderText("Filter by PV name")

        policy = self.pv_filter_sel.sizePolicy()
        policy.setHorizontalPolicy(policy.Expanding)
        self.pv_filter_sel.setSizePolicy(policy)

        self.pv_filter_sel.currentIndexChanged.connect(
            self._predefined_filter_selected)
        self.pv_filter_inp.textChanged.connect(self._create_name_filter)

        self._populate_filter_list()

        # Prepare pallets to color the pv name filter input if rgx not valid
        self._inp_palette_ok = self.pv_filter_inp.palette()
        self._inp_palette_err = QPalette()
        self._inp_palette_err.setColor(QPalette.Base, QColor("#F39292"))

        # Create a PV name filter layout and add items
        pv_filter_layout = QHBoxLayout()
        pv_filter_layout.setSpacing(10)
        pv_filter_layout.addWidget(pv_filter_label)
        pv_filter_layout.addWidget(self.pv_filter_sel)

        # #### Regex selector
        self.regex = QCheckBox("Regex", self)
        self.regex.stateChanged.connect(self._handle_regex_change)

        # #### Selector for comparison filter
        self.compare_filter_inp = QComboBox(self)
        self.compare_filter_inp.addItems(
            ["Show all", "Different only", "Equal only"])

        self.compare_filter_inp.currentIndexChanged.connect(
            self._proxy.set_eq_filter)
        self.compare_filter_inp.setMaximumWidth(200)

        # ### Show disconnected selector
        self.show_disconn_inp = QCheckBox("Show disconnected PVs.", self)
        self.show_disconn_inp.setChecked(True)
        self.show_disconn_inp.stateChanged.connect(
            self._proxy.set_disconn_filter)
        self.show_disconn_inp.setMaximumWidth(500)

        # Tolerance setting
        tol_label = QLabel("Tolerance:")
        tol = QSpinBox()
        tol.setRange(1, 1000000)
        tol.setValue(1)
        tol.valueChanged[int].connect(self.model.change_tolerance)
        self.model.change_tolerance(tol.value())

        # ### Put all tolerance and filter selectors in one layout
        filter_layout = QHBoxLayout()
        filter_layout.addWidget(tol_label)
        filter_layout.addWidget(tol)
        filter_layout.addWidget(make_separator(self, 'vertical'))

        filter_layout.addLayout(pv_filter_layout)
        filter_layout.addWidget(self.regex)

        filter_layout.addWidget(make_separator(self, 'vertical'))

        filter_layout.addWidget(self.compare_filter_inp)

        filter_layout.addWidget(self.show_disconn_inp)
        filter_layout.setAlignment(Qt.AlignLeft)
        filter_layout.setSpacing(10)

        # ------- Build main layout ---------
        layout = QVBoxLayout(self)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.addLayout(filter_layout)
        layout.addWidget(self.view)
        self.setLayout(layout)

    def _populate_filter_list(self):
        predefined_filters = self.common_settings['predefined_filters']
        self.pv_filter_sel.blockSignals(True)
        self.pv_filter_sel.clear()
        self.pv_filter_sel.addItem(None)
        for rgx in predefined_filters.get('rgx-filters', list()):
            self.pv_filter_sel.addItem(SnapshotCompareWidget.rgx_icon, rgx)
        self.pv_filter_sel.addItems(predefined_filters.get('filters', list()))
        self.pv_filter_sel.blockSignals(False)

    def _handle_regex_change(self, state):
        txt = self.pv_filter_inp.text()
        if state and txt.strip() == '':
            self.pv_filter_inp.setText('.*')
        elif not state and txt.strip() == '.*':
            self.pv_filter_inp.setText('')
        else:
            self._create_name_filter(txt)

    def _create_name_filter(self, txt):
        if self.regex.isChecked():
            try:
                srch_filter = re.compile(txt)
                self.pv_filter_inp.setPalette(self._inp_palette_ok)
            except:
                # Syntax error (happens a lot during typing an expression). In such cases make compiler which will
                # not match any pv name
                srch_filter = re.compile("")
                self.pv_filter_inp.setPalette(self._inp_palette_err)
        else:
            srch_filter = txt
            self.pv_filter_inp.setPalette(self._inp_palette_ok)

        self._proxy.set_name_filter(srch_filter)

    def _show_snapshot_parse_errors(self, errors):
        show_snapshot_parse_errors(self, errors)

    def new_selected_files(self, selected_files):
        self.model.clear_snap_files()
        self.model.add_snap_files(selected_files)
        self._proxy.apply_filter()

    def clear_snap_files(self):
        self.model.clear_snap_files()

    def handle_new_snapshot_instance(self, snapshot):
        self.snapshot = snapshot
        self.model.snapshot = snapshot
        self.model.set_pvs(snapshot.pvs.values())
        self.view.sortByColumn(0, Qt.AscendingOrder)  # default sorting
        self._populate_filter_list()

    def _handle_restore_request(self, pvs_list):
        self.restore_requested.emit(pvs_list)

    def _predefined_filter_selected(self, idx):
        txt = self.pv_filter_inp.text()
        if idx == 0:
            # First empty option; the menu is always reset to this.
            return
        if not self.pv_filter_sel.itemIcon(idx).isNull():
            # Set back to first index, to get rid of the icon. Set to regex and
            # pass text of filter to the input
            self.pv_filter_sel.setCurrentIndex(0)
            self.regex.setChecked(True)
            self.pv_filter_inp.setText(txt)
        else:
            # Imitate same behaviour
            self.pv_filter_sel.setCurrentIndex(0)
            self.regex.setChecked(False)
            self.pv_filter_inp.setText(txt)

    def filter_update(self):
        self._proxy.apply_filter()
Exemplo n.º 29
0
class Widget(QWidget):
    def __init__(self, dockwidget):
        super(Widget, self).__init__(dockwidget)
        self._document = None
        self._fileSelector = QComboBox(editable=True, insertPolicy=QComboBox.NoInsert)
        gadgets.drag.ComboDrag(self._fileSelector).role = Qt.UserRole
        self._fileSelector.lineEdit().setReadOnly(True)
        self._fileSelector.lineEdit().setFocusPolicy(Qt.NoFocus)
        self._stopButton = QToolButton()
        self._playButton = QToolButton()
        self._timeSlider = QSlider(Qt.Horizontal, tracking=False,
            singleStep=500, pageStep=5000, invertedControls=True)
        self._display = Display()
        self._tempoFactor = QSlider(Qt.Vertical, minimum=-50, maximum=50,
            singleStep=1, pageStep=5)

        grid = QGridLayout(spacing=0)
        self.setLayout(grid)

        grid.addWidget(self._fileSelector, 0, 0, 1, 3)
        grid.addWidget(self._stopButton, 1, 0)
        grid.addWidget(self._playButton, 1, 1)
        grid.addWidget(self._timeSlider, 1, 2)
        grid.addWidget(self._display, 2, 0, 1, 3)
        grid.addWidget(self._tempoFactor, 0, 3, 3, 1)

        # size policy of combo
        p = self._fileSelector.sizePolicy()
        p.setHorizontalPolicy(QSizePolicy.Ignored)
        self._fileSelector.setSizePolicy(p)

        # size policy of combo popup
        p = self._fileSelector.view().sizePolicy()
        p.setHorizontalPolicy(QSizePolicy.MinimumExpanding)
        self._fileSelector.view().setSizePolicy(p)

        self._player = player.Player()
        self._outputCloseTimer = QTimer(interval=60000, singleShot=True,
            timeout=self.closeOutput)
        self._timeSliderTicker = QTimer(interval=200, timeout=self.updateTimeSlider)
        self._fileSelector.activated[int].connect(self.slotFileSelected)
        self._tempoFactor.valueChanged.connect(self.slotTempoChanged)
        self._timeSlider.valueChanged.connect(self.slotTimeSliderChanged)
        self._timeSlider.sliderMoved.connect(self.slotTimeSliderMoved)
        self._player.beat.connect(self.updateDisplayBeat)
        self._player.time.connect(self.updateDisplayTime)
        self._player.stateChanged.connect(self.slotPlayerStateChanged)
        self.slotPlayerStateChanged(False)
        dockwidget.mainwindow().currentDocumentChanged.connect(self.loadResults)
        app.documentLoaded.connect(self.slotDocumentLoaded)
        app.jobFinished.connect(self.slotUpdatedFiles)
        app.aboutToQuit.connect(self.stop)
        midihub.aboutToRestart.connect(self.slotAboutToRestart)
        midihub.settingsChanged.connect(self.clearMidiSettings, -100)
        midihub.settingsChanged.connect(self.readMidiSettings)
        app.documentClosed.connect(self.slotDocumentClosed)
        app.translateUI(self)
        self.readMidiSettings()
        d = dockwidget.mainwindow().currentDocument()
        if d:
            self.loadResults(d)

    def translateUI(self):
        self._tempoFactor.setToolTip(_("Tempo"))

    def slotAboutToRestart(self):
        self.stop()
        self._player.set_output(None)

    def clearMidiSettings(self):
        """Called first when settings are changed."""
        self.stop()
        self._outputCloseTimer.stop()
        self._player.set_output(None)

    def readMidiSettings(self):
        """Called after clearMidiSettings(), and on first init."""
        pass

    def openOutput(self):
        """Called when playing starts. Ensures an output port is opened."""
        self._outputCloseTimer.stop()
        if not self._player.output():
            p = QSettings().value("midi/player/output_port", midihub.default_output(), str)
            o = midihub.output_by_name(p)
            if o:
                self._player.set_output(output.Output(o))

    def closeOutput(self):
        """Called when the output close timer fires. Closes the output."""
        self._player.set_output(None)

    def slotPlayerStateChanged(self, playing):
        ac = self.parentWidget().actionCollection
        # setDefaultAction also adds the action
        for b in self._stopButton, self._playButton:
            while b.actions():
                b.removeAction(b.actions()[0])
        if playing:
            self._timeSliderTicker.start()
            self._stopButton.setDefaultAction(ac.midi_stop)
            self._playButton.setDefaultAction(ac.midi_pause)
        else:
            self._timeSliderTicker.stop()
            self.updateTimeSlider()
            self._stopButton.setDefaultAction(ac.midi_restart)
            self._playButton.setDefaultAction(ac.midi_play)
            # close the output if the preference is set
            if QSettings().value("midi/close_outputs", False, bool):
                self._outputCloseTimer.start()

    def play(self):
        """Starts the MIDI player, opening an output if necessary."""
        if not self._player.is_playing() and not self._player.has_events():
            self.restart()
        self.openOutput()
        if not self._player.output():
            self._display.statusMessage(_("No output found!"))
        self._player.start()

    def stop(self):
        """Stops the MIDI player."""
        self._player.stop()

    def restart(self):
        """Restarts the MIDI player.

        If another file is in the file selector, or the file was updated,
        the new file is loaded.

        """
        self._player.seek(0)
        self.updateTimeSlider()
        self._display.reset()
        if self._document:
            files = midifiles.MidiFiles.instance(self._document)
            index = self._fileSelector.currentIndex()
            if files and (files.song(index) is not self._player.song()):
                self.loadSong(index)

    def slotTempoChanged(self, value):
        """Called when the user drags the tempo."""
        # convert -50 to 50 to 0.5 to 2.0
        factor = 2 ** (value / 50.0)
        self._player.set_tempo_factor(factor)
        self._display.setTempo("{0}%".format(int(factor * 100)))

    def slotTimeSliderChanged(self, value):
        self._player.seek(value)
        self._display.setTime(value)
        if self._player.song():
            self._display.setBeat(*self._player.song().beat(value)[1:])

    def slotTimeSliderMoved(self, value):
        self._display.setTime(value)
        if self._player.song():
            self._display.setBeat(*self._player.song().beat(value)[1:])

    def updateTimeSlider(self):
        if not self._timeSlider.isSliderDown():
            with qutil.signalsBlocked(self._timeSlider):
                self._timeSlider.setMaximum(self._player.total_time())
                self._timeSlider.setValue(self._player.current_time())

    def updateDisplayBeat(self, measnum, beat, num, den):
        if not self._timeSlider.isSliderDown():
            self._display.setBeat(measnum, beat, num, den)

    def updateDisplayTime(self, time):
        if not self._timeSlider.isSliderDown():
            self._display.setTime(time)

    def slotDocumentLoaded(self, document):
        """Called when a new document is loaded.

        Only calls slotUpdatedFiles when this is the first document, as that
        slot will be called anyway when the current document is switched. When
        the first document is loaded, it is loaded into the existing empty
        document, so mainwindow.currentDocumentChanged() will never be emitted.

        """
        if len(app.documents) == 1:
            self.slotUpdatedFiles(document)

    def slotUpdatedFiles(self, document, j=None):
        """Called when there are new MIDI files."""
        mainwindow = self.parentWidget().mainwindow()
        import engrave
        if document not in (mainwindow.currentDocument(), engrave.engraver(mainwindow).document()):
            return
        import job
        if j and job.attributes.get(j).mainwindow != mainwindow:
            return
        self.loadResults(document)

    def loadResults(self, document):
        files = midifiles.MidiFiles.instance(document)
        if files.update():
            self._document = document
            self._fileSelector.setModel(files.model())
            self._fileSelector.setCurrentIndex(files.current)
            if not self._player.is_playing():
                self.loadSong(files.current)

    def loadSong(self, index):
        files = midifiles.MidiFiles.instance(self._document)
        self._player.set_song(files.song(index))
        m, s = divmod(self._player.total_time() // 1000, 60)
        name = self._fileSelector.currentText()
        self.updateTimeSlider()
        self._display.reset()
        self._display.statusMessage(
            _("midi lcd screen", "LOADED"), name,
            _("midi lcd screen", "TOTAL"), "{0}:{1:02}".format(m, s))

    def slotFileSelected(self, index):
        if self._document:
            self._player.stop()
            files = midifiles.MidiFiles.instance(self._document)
            if files:
                files.current = index
                self.restart()

    def slotDocumentClosed(self, document):
        if document == self._document:
            self._document = None
            self._fileSelector.setModel(listmodel.ListModel([]))
            self._player.stop()
            self._player.clear()
            self.updateTimeSlider()
            self._display.reset()
Exemplo n.º 30
0
class SettingInput(Widget):

    key = "SettingInput"

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

        self.settings = settings

        self.formatComboBox = QComboBox(self)
        self.formatComboBox.addItem('INI')
        self.formatComboBox.addItem('Native')

        self.scopeComboBox = QComboBox(self)
        self.scopeComboBox.addItem('User')
        self.scopeComboBox.addItem('System')

        self.organizationComboBox = QComboBox(self)
        self.organizationComboBox.addItem('DAMGteam')
        self.organizationComboBox.setEditable(True)

        self.applicationComboBox = QComboBox(self)
        self.applicationComboBox.addItem('PLM')
        self.applicationComboBox.setEditable(True)
        self.applicationComboBox.setCurrentIndex(0)

        for cb in [
                self.formatComboBox, self.scopeComboBox,
                self.organizationComboBox, self.applicationComboBox
        ]:
            cb.currentIndexChanged.connect(self.updateLocationsTable)

        formatLabel = Label({
            'txt': "&Format: ",
            'setBuddy': self.formatComboBox
        })
        scopeLabel = Label({'txt': "&Scope:", 'setBuddy': self.scopeComboBox})
        organizationLabel = Label({
            'txt': "&Organization:",
            'setBuddy': self.organizationComboBox
        })
        applicationLabel = Label({
            'txt': "&Application:",
            'setBuddy': self.applicationComboBox
        })

        grpBox, grid = GroupGrid("Setting Locations")

        self.locationsTable = QTableWidget()
        self.locationsTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.locationsTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.locationsTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.locationsTable.setColumnCount(2)
        self.locationsTable.setHorizontalHeaderLabels(("Location", "Access"))
        self.locationsTable.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.locationsTable.horizontalHeader().resizeSection(1, 180)
        self.locationsTable.setMinimumHeight(180)

        self.formatComboBox.activated.connect(self.updateLocationsTable)
        self.scopeComboBox.activated.connect(self.updateLocationsTable)
        self.organizationComboBox.lineEdit().editingFinished.connect(
            self.updateLocationsTable)
        self.applicationComboBox.lineEdit().editingFinished.connect(
            self.updateLocationsTable)

        self.layout = QGridLayout()

        grid.addWidget(formatLabel, 1, 0)
        grid.addWidget(self.formatComboBox, 1, 1)
        grid.addWidget(scopeLabel, 2, 0)
        grid.addWidget(self.scopeComboBox, 2, 1)
        grid.addWidget(organizationLabel, 3, 0)
        grid.addWidget(self.organizationComboBox, 3, 1)
        grid.addWidget(applicationLabel, 4, 0)
        grid.addWidget(self.applicationComboBox, 4, 1)
        grid.addWidget(self.locationsTable, 0, 2, 6, 4)

        self.updateLocationsTable()
        self.layout.addWidget(grpBox)

        self.setLayout(self.layout)

    def format(self):
        if self.formatComboBox.currentIndex() == 0:
            return QSettings.NativeFormat
        else:
            return INI

    def scope(self):
        if self.scopeComboBox.currentIndex() == 0:
            return QSettings.UserScope
        else:
            return QSettings.SystemScope

    def organization(self):
        return self.organizationComboBox.currentText()

    def application(self):
        if self.applicationComboBox.currentText() == "Any":
            return ''

        return self.applicationComboBox.currentText()

    def updateLocationsTable(self):

        self.locationsTable.setUpdatesEnabled(False)
        self.locationsTable.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue
                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ''

                settings = QSettings(self.format(), actualScope,
                                     self.organization(), actualApplication)

                row = self.locationsTable.rowCount()
                self.locationsTable.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    # self.buttonBox.okButton(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locationsTable.setItem(row, 0, item0)
                self.locationsTable.setItem(row, 1, item1)
        self.locationsTable.setUpdatesEnabled(True)
Exemplo n.º 31
0
    def __init__(self, dictionary: dict):
        super().__init__()

        self.setFocus()
        self.setMinimumWidth(300)
        self.setWindowTitle('Any Dictionary Tester')
        self.setFont(QFont('Arial', 14))

        self.setLayout(self.grid)

        self.dictionary = dict((value, key) for key, value in dictionary.items()) if self.get_translation_swap_flag() \
            else dictionary

        words = list(self.dictionary.keys())
        random.shuffle(words)

        self.is_hard_mode = self.get_hard_mode_flag()

        if self.is_hard_mode:
            self.is_hard_mode_with_autocomplete = self.get_hard_mode_with_autocomplete_flag(
            )

        for word in words:
            dialog = QDialog()

            dialog_grid = QGridLayout()
            dialog.setLayout(dialog_grid)

            values = list(
                np.random.choice(list(self.dictionary.values()),
                                 4,
                                 replace=False))

            if self.dictionary[word] not in values:
                values.remove(values[0])
                values.append(self.dictionary[word])
                random.shuffle(values)

            original_word_label = QLabel(word)
            dialog_grid.addWidget(original_word_label, 0, 0, Qt.AlignCenter)

            if self.is_hard_mode and not self.is_hard_mode_with_autocomplete:
                answer_line_edit = QLineEdit()
                answer_line_edit.returnPressed.connect(
                    lambda associated_word=word, associated_line_edit=
                    answer_line_edit: self.set_answer(
                        associated_word, associated_line_edit.text()))
                dialog_grid.addWidget(answer_line_edit, 1, 0)

                answer_button = QPushButton("Answer")
                answer_button.clicked.connect(
                    lambda state, associated_word=word, associated_line_edit=
                    answer_line_edit: self.set_answer(
                        associated_word, associated_line_edit.text()))
                dialog_grid.addWidget(answer_button, 2, 0)
            elif self.is_hard_mode and self.is_hard_mode_with_autocomplete:
                answer_combo_box = QComboBox()

                answer_combo_box.setEditable(True)
                answer_combo_box.addItems(
                    sample(list(self.dictionary.values()),
                           len(self.dictionary.values())))
                answer_combo_box.setCurrentText('')
                answer_combo_box.lineEdit().returnPressed.connect(
                    lambda associated_word=word, associated_combo_box=
                    answer_combo_box: self.set_answer(
                        associated_word, associated_combo_box.currentText()))
                dialog_grid.addWidget(answer_combo_box, 1, 0)

                answer_button = QPushButton("Answer")
                answer_button.clicked.connect(
                    lambda state, associated_word=word, associated_combo_box=
                    answer_combo_box: self.set_answer(
                        associated_word, associated_combo_box.currentText()))
                dialog_grid.addWidget(answer_button, 2, 0)
            else:
                for i in range(4):
                    answer_button = QPushButton(values[i])
                    answer_button.clicked.connect(
                        partial(self.set_answer, word, values[i]))
                    dialog_grid.addWidget(answer_button, i + 1, 0)

            self.dialogs.append(dialog)

        self.current_dialog = next(self.dialogs_iterator)
        self.grid.addWidget(self.current_dialog)

        self.show()
Exemplo n.º 32
0
class ConvGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.camera_chosen = 0
        self.log_chosen = 0
        self.log_type_chosen = 0
        self.output_dir_chosen = 0

        centralWidget = QWidget()

        # ______Labels______

        # Label for camera drop down list
        cameraLabel = QLabel('Choose Camera')
        cameraLabel.setAlignment(Qt.AlignCenter)

        # Label for log type drown down list
        logTypeLabel = QLabel('Choose Type of Log')
        logTypeLabel.setAlignment(Qt.AlignCenter)

        # Label for log conversion buttons
        self.logLabel = QLabel('Log Conversion')
        self.logLabel.setAlignment(Qt.AlignCenter)

        # Labels for User Input values
        inputLabel = QLabel('User Values')
        inputLabel.setAlignment(Qt.AlignCenter)
        amslLabel = QLabel('Average AMSL (m)')
        amslLabel.setAlignment(Qt.AlignCenter)

        # Unnecessary labels
        #
        # missionIdLabel = QLabel('Name of Mission')
        # missionIdLabel.setAlignment(Qt.AlignCenter)
        # tailNumLabel = QLabel('Aircraft N or registration number')
        # tailNumLabel.setAlignment(Qt.AlignCenter)
        # platDesigLabel = QLabel('Aircraft Designation')
        # platDesigLabel.setAlignment(Qt.AlignCenter)
        # imageSensorLabel = QLabel('Image sensor name')
        # imageSensorLabel.setAlignment(Qt.AlignCenter)
        # coordSysLabel = QLabel('Coordinate system (e.g. WGS84)')
        # coordSysLabel.setAlignment(Qt.AlignCenter)

        # QLineEdits for getting user values
        self.amslInput = QLineEdit()
        # self.missionIdInput = QLineEdit()
        # self.tailNumInput = QLineEdit()
        # self.platDesigInput = QLineEdit()
        # self.imageSensorInput = QLineEdit()
        # self.coordSysInput = QLineEdit()

        # ______Buttons______

        # Create camera drop down list of supported cameras
        # from cameras.xml profile document
        # Use parser to ensure pretty print works, see:
        # http://lxml.de/FAQ.html#why-doesn-t-the-
        # pretty-print-option-reformat-my-xml-output
        parser = etree.XMLParser(remove_blank_text=True)
        self.xml_tree = etree.parse('cameras.xml', parser)
        self.xml_root = self.xml_tree.getroot()

        # Initialize QComboBox object with default text
        cameraType = QComboBox(self)
        cameraType.addItem('Select a Camera')

        # Loop through the children of the xml root
        # get the camera name and add to the drop down list
        index = 0
        for child in self.xml_root:

            self.camera = child[NAME].text
            cameraType.addItem(self.camera)
            # Populate the xml map list with the camera name and
            # it's index in the root list so we can refer to it's values
            # later
            xml_map[self.camera] = index
            index += 1

        cameraType.setEditable(True)
        cameraType.lineEdit().setReadOnly(True)
        cameraType.lineEdit().setAlignment(Qt.AlignCenter)

        # Align the dropdown options to be centered
        for i in range(0, cameraType.count()):
            cameraType.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole)

        cameraType.activated[str].connect(self.cameraChosen)

        # Create Log type drop down menu
        self.logType = QComboBox(self)
        self.logType.addItem('Select Log Type')
        # self.logType.addItem('DJI GO')
        self.logType.addItem('Litchi')

        for i in range(0, self.logType.count()):
            self.logType.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole)

        self.logType.setEditable(True)
        self.logType.lineEdit().setReadOnly(True)
        self.logType.lineEdit().setAlignment(Qt.AlignCenter)

        self.logType.activated[str].connect(self.logTypeChosen)

        # Create push button for adding a new camera profile
        newCameraBtn = QPushButton('Add New Camera')
        newCameraBtn.clicked.connect(self.newCamera)

        # Create push button object that opens the log file
        # to be converted
        chooseLogBtn = QPushButton('Open log file...')
        chooseLogBtn.clicked.connect(self.openFile)

        # Push button to start log conversion
        convertBtn = QPushButton('Convert!')
        convertBtn.clicked.connect(self.convertLog)

        # Button for setting output file location
        saveLocBtn = QPushButton('Set output save location...')
        saveLocBtn.clicked.connect(self.saveLocation)

        # Quit button
        quitBtn = QPushButton('Exit Program')
        quitBtn.clicked.connect(self.close)

        # ______Layout______

        # Create vertical box layout
        vbox = QVBoxLayout()
        vbox.addStretch()
        vbox.addWidget(cameraLabel)
        vbox.addWidget(cameraType)
        vbox.addWidget(newCameraBtn)
        vbox.addStretch()
        vbox.addWidget(logTypeLabel)
        vbox.addWidget(self.logType)
        vbox.addStretch()
        vbox.addWidget(inputLabel)
        vbox.addWidget(amslLabel)
        vbox.addWidget(self.amslInput)
        # vbox.addWidget(missionIdLabel)
        # vbox.addWidget(self.missionIdInput)
        # vbox.addWidget(tailNumLabel)
        # vbox.addWidget(self.tailNumInput)
        # vbox.addWidget(platDesigLabel)
        # vbox.addWidget(self.platDesigInput)
        # vbox.addWidget(imageSensorLabel)
        # vbox.addWidget(self.imageSensorInput)
        # vbox.addWidget(coordSysLabel)
        # vbox.addWidget(self.coordSysInput)
        vbox.addStretch()
        vbox.addWidget(self.logLabel)
        vbox.addWidget(chooseLogBtn)
        vbox.addWidget(saveLocBtn)
        vbox.addWidget(convertBtn)
        vbox.addStretch()
        vbox.addWidget(quitBtn)

        centralWidget.setLayout(vbox)

        # Create quit action
        quit = QAction('Quit', self)
        quit.setShortcut('Ctrl+Q')
        quit.setStatusTip('Exit program')
        quit.triggered.connect(self.close)

        # Create about action
        about = QAction('About LogConverter', self)
        about.setShortcut('Ctrl+A')
        about.setStatusTip('About program')
        about.triggered.connect(self.aboutProgram)

        # Create menubar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(quit)
        aboutMenu = menubar.addMenu('&About')
        aboutMenu.addAction(about)

        self.setCentralWidget(centralWidget)

        self.resize(WINDOW_WIDTH, WINDOW_HEIGHT)
        self.center()

        self.setWindowTitle('Log Converter')
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def openFile(self):
        self.log_file = QFileDialog.getOpenFileName(self, 'Open file', None)[0]
        self.log_chosen = 1

    # QFileDialog:getSaveFileName will pass name even if it doesn't exist
    # unlike QFileDialog:getOpenFileName; Linux doesn't seem to care but
    # Windows definitely does
    def saveLocation(self):
        self.save_location = QFileDialog.getSaveFileName(
            self, 'Choose save location', None)[0]

    def cameraChosen(self, text):

        # Make sure an actual camera was chosen
        if text != 'Select a Camera':
            # When a camera is chosen change the value in our camera variable
            self.camera = text

            # We need the index for the particular camera chosen.
            # We obtain this from our xml_map dictionary:
            # xml_map[camera] maps to index number of that
            # particular camera's element in root
            # the constant e.g. FLEN then maps to the index of that subelement
            # So we get: xml_root[camera_index][parameter_index]
            # and .text gives us the actual text value of that element
            self.flen = self.xml_root[xml_map[self.camera]][FLEN].text
            self.imagew = self.xml_root[xml_map[self.camera]][IMGW].text
            self.imageh = self.xml_root[xml_map[self.camera]][IMGH].text
            self.sensorw = self.xml_root[xml_map[self.camera]][SENW].text
            self.sensorh = self.xml_root[xml_map[self.camera]][SENH].text

            self.camera_chosen = 1

    def logTypeChosen(self, text):

        if text != 'Select Log Type':
            self.log = text
            self.log_type_chosen = 1

    def newCamera(self):
        self.newCamera = QWidget()

        # Labels for popup window
        nameLbl = QLabel('Enter Descriptive Camera Name:')
        flenLbl = QLabel('Enter Camera Focal Length [mm]:')
        imghLbl = QLabel('Enter Image Height [pixels]:')
        imgwLbl = QLabel('Enter Image Width [pixels]:')
        senwLbl = QLabel('Enter Sensor Width [mm]:')
        senhLbl = QLabel('Enter Sensor Height [mm]:')
        notice = QLabel('New camera will be available upon restart of the GUI')

        notice.setAlignment(Qt.AlignCenter)

        # Set font size and color for notice
        notice_font = QFont()
        notice_font.setPointSize(8)
        notice_font.setBold(True)
        notice.setFont(notice_font)
        notice.setStyleSheet("QLabel { color : red;}")

        # QLineEdit objects for user values
        self.nameEdit = QLineEdit()
        self.flenEdit = QLineEdit()
        self.imghEdit = QLineEdit()
        self.imgwEdit = QLineEdit()
        self.senwEdit = QLineEdit()
        self.senhEdit = QLineEdit()

        # Button for submitting values
        submitBtn = QPushButton('Create Camera Profile')
        submitBtn.clicked.connect(self.writeXML)

        # Build a vertical layout
        vLayout = QVBoxLayout()
        vLayout.addStretch()
        vLayout.addWidget(nameLbl)
        vLayout.addWidget(self.nameEdit)
        vLayout.addWidget(flenLbl)
        vLayout.addWidget(self.flenEdit)
        vLayout.addWidget(imgwLbl)
        vLayout.addWidget(self.imgwEdit)
        vLayout.addWidget(imghLbl)
        vLayout.addWidget(self.imghEdit)
        vLayout.addWidget(senwLbl)
        vLayout.addWidget(self.senwEdit)
        vLayout.addWidget(senhLbl)
        vLayout.addWidget(self.senhEdit)
        vLayout.addStretch()
        vLayout.addWidget(submitBtn)
        vLayout.addStretch()
        vLayout.addWidget(notice)
        vLayout.addStretch()

        # Set up and show window
        self.newCamera.setLayout(vLayout)
        self.newCamera.resize(WINDOW_WIDTH, WINDOW_HEIGHT)

        # Center widget
        qr = self.newCamera.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.newCamera.move(qr.topLeft())

        # Set title, show and call exec function
        self.newCamera.setWindowTitle('Add New Camera')
        self.newCamera.show()
        # self.newCamera.exec_()

    def writeXML(self):
        # Get values from user
        name = self.nameEdit.text()
        flen = self.flenEdit.text()
        imgw = self.imgwEdit.text()
        imgh = self.imghEdit.text()
        senw = self.senwEdit.text()
        senh = self.senhEdit.text()

        # Create subelement "camera" and then sub elements to that:
        # name, flen, imgw, imagh, senw, senh
        Camera = etree.SubElement(self.xml_root, 'Camera')
        xml_name = etree.SubElement(Camera, 'name')
        xml_name.text = name
        xml_flen = etree.SubElement(Camera, 'flen')
        xml_flen.text = flen
        xml_imgw = etree.SubElement(Camera, 'imgw')
        xml_imgw.text = imgw
        xml_imgh = etree.SubElement(Camera, 'imgh')
        xml_imgh.text = imgh
        xml_senw = etree.SubElement(Camera, 'senw')
        xml_senw.text = senw
        xml_senh = etree.SubElement(Camera, 'senh')
        xml_senh.text = senh

        # Overwrite camera profile file
        self.xml_tree.write('cameras.xml', pretty_print=True)

        # Close widget to return user to main GUI window
        self.newCamera.close()

    def aboutProgram(self):
        QMessageBox.about(self, "About LogConverter", ABOUT_TEXT)

    def convertLog(self):

        if self.camera_chosen == 0:
            QMessageBox.information(self, 'Warning', 'Select a Camera!')

        elif self.log_type_chosen == 0:
            QMessageBox.information(self, 'Warning', 'Select Log Type!')

        elif self.log_chosen == 0:
            QMessageBox.information(self, 'Warning', 'Select Log File!')

        else:
            fov_values = fov.fov(self.flen, self.sensorw, self.sensorh)
            fov_horizontal = fov_values[0]
            fov_vertical = fov_values[1]

            amsl = self.amslInput.text()

            # if (self.log == 'DJI GO'):
            #     converter.converter(
            #         self.log_file, self.save_location,
            #         fov_h, fov_w, amsl)
            #     QMessageBox.information(self, 'Message', 'Log converted!')

            if (self.log == 'Litchi'):
                self.converted = litchiconverter.converter(
                    self.log_file, self.save_location, fov_horizontal,
                    fov_vertical, amsl)
                if (self.converted):
                    QMessageBox.information(self, 'Message', 'Log converted!')
                else:
                    QMessageBox.information(self, 'Message',
                                            'No video in log file.')
Exemplo n.º 33
0
class AuthWindowUI(object):
    def __init__(self, MainWin):
        # Main Window
        MainWin.setObjectName("AuthWindow")
        MainWin.setWindowIcon(MainWin.window_icon)
        MainWin.setWindowTitle(MainWin.tr(MainWin.window_title))
        MainWin.resize(1024, 860)
        self.config = MainWin.config
        self.centralWidget = QWidget(MainWin)
        self.centralWidget.setObjectName("centralWidget")
        MainWin.setCentralWidget(self.centralWidget)
        self.verticalLayout = QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        self.tabWidget = QTabWidget(MainWin)
        self.tabWidget.currentChanged.connect(MainWin.onTabChanged)
        self.tabWidget.tabCloseRequested.connect(MainWin.onTabClosed)
        self.tabWidget.setTabsClosable(True)
        # workaround for https://bugreports.qt.io/browse/QTBUG-58267
        if "darwin" in sys.platform:
            self.tabWidget.setDocumentMode(True)

        # Splitter for log
        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.addWidget(self.tabWidget)

        # Log Widget
        self.logTextBrowser = QPlainTextEditLogger(self.centralWidget)
        self.logTextBrowser.widget.setObjectName("logTextBrowser")
        self.logTextBrowser.widget.setStyleSheet("""
            QPlainTextEdit {
                    border: 2px solid grey;
                    border-radius: 5px;
                    background-color: lightgray;
            }
            """)
        self.splitter.addWidget(self.logTextBrowser.widget)

        # add splitter
        self.splitter.setSizes([800, 100])
        self.verticalLayout.addWidget(self.splitter)

        # Tool Bar
        self.mainToolBar = QToolBar(MainWin)
        self.mainToolBar.setObjectName("mainToolBar")
        self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.mainToolBar.setContextMenuPolicy(Qt.PreventContextMenu)
        MainWin.addToolBar(Qt.TopToolBarArea, self.mainToolBar)

        # Servers
        self.serverWidget = QWidget(MainWin)
        self.serverLayout = QHBoxLayout()
        self.serverLabel = QLabel("Server:")
        self.serverLayout.addWidget(self.serverLabel)
        self.serverComboBox = QComboBox()
        self.serverComboBox.setEditable(True)
        self.serverComboBox.setDuplicatesEnabled(False)
        self.serverComboBox.setMinimumContentsLength(50)
        self.serverComboBox.currentIndexChanged.connect(
            MainWin.onServerListChanged)
        lineEdit = self.serverComboBox.lineEdit()
        lineEdit.returnPressed.connect(MainWin.on_actionAdd_triggered)
        self.serverLayout.addWidget(self.serverComboBox)
        self.serverWidget.setLayout(self.serverLayout)
        self.mainToolBar.addWidget(self.serverWidget)

        # Add
        self.actionAdd = QAction(MainWin)
        self.actionAdd.setObjectName("actionAdd")
        self.actionAdd.setText(MainWin.tr("Add"))
        self.actionAdd.setToolTip(MainWin.tr("Add to server list"))
        self.actionAdd.setShortcut(MainWin.tr("Ctrl+A"))

        # Remove
        self.actionRemove = QAction(MainWin)
        self.actionRemove.setObjectName("actionRemove")
        self.actionRemove.setText(MainWin.tr("Remove"))
        self.actionRemove.setToolTip(MainWin.tr("Remove from server list"))
        self.actionRemove.setShortcut(MainWin.tr("Ctrl+X"))

        # Show Token
        self.actionShowToken = QAction(MainWin)
        self.actionShowToken.setEnabled(False)
        self.actionShowToken.setObjectName("actionShowToken")
        self.actionShowToken.setText(MainWin.tr("Show Token"))
        self.actionShowToken.setToolTip(
            MainWin.tr("Display the current authentication token"))
        self.actionShowToken.setShortcut(MainWin.tr("Ctrl+S"))

        # Login
        self.actionLogin = QAction(MainWin)
        self.actionLogin.setObjectName("actionLogin")
        self.actionLogin.setText(MainWin.tr("Login"))
        self.actionLogin.setToolTip(
            MainWin.tr("Login to the currently selected server"))
        self.actionLogin.setShortcut(MainWin.tr("Ctrl+L"))

        # Logout
        self.actionLogout = QAction(MainWin)
        self.actionLogout.setObjectName("actionLogout")
        self.actionLogout.setText(MainWin.tr("Logout"))
        self.actionLogout.setToolTip(
            MainWin.tr("Logout of the currently selected server"))
        self.actionLogout.setShortcut(MainWin.tr("Ctrl+O"))

        # Add
        self.mainToolBar.addAction(self.actionAdd)
        self.actionAdd.setIcon(qApp.style().standardIcon(
            QStyle.SP_FileDialogNewFolder))

        # Remove
        self.mainToolBar.addAction(self.actionRemove)
        self.actionRemove.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogDiscardButton))

        # Show Token
        self.mainToolBar.addAction(self.actionShowToken)
        self.actionShowToken.setIcon(qApp.style().standardIcon(
            QStyle.SP_FileDialogInfoView))
        self.mainToolBar.addSeparator()

        # this spacer right justifies everything that comes after it
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainToolBar.addWidget(spacer)

        # Login
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actionLogin)
        self.actionLogin.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogApplyButton))

        # Logout
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actionLogout)
        self.actionLogout.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogOkButton))

        # Status Bar
        self.statusBar = QStatusBar(MainWin)
        self.statusBar.setToolTip("")
        self.statusBar.setStatusTip("")
        self.statusBar.setObjectName("statusBar")
        MainWin.setStatusBar(self.statusBar)

        # configure logging
        self.logTextBrowser.widget.log_update_signal.connect(MainWin.updateLog)
        self.logTextBrowser.setFormatter(
            logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
        logging.getLogger().addHandler(self.logTextBrowser)
        logging.getLogger().setLevel(logging.INFO)

        # finalize UI setup
        QMetaObject.connectSlotsByName(MainWin)
Exemplo n.º 34
0
    def initUI(self):

        self.camera_chosen = 0
        self.log_chosen = 0
        self.log_type_chosen = 0
        self.output_dir_chosen = 0

        centralWidget = QWidget()

        # ______Labels______

        # Label for camera drop down list
        cameraLabel = QLabel('Choose Camera')
        cameraLabel.setAlignment(Qt.AlignCenter)

        # Label for log type drown down list
        logTypeLabel = QLabel('Choose Type of Log')
        logTypeLabel.setAlignment(Qt.AlignCenter)

        # Label for log conversion buttons
        self.logLabel = QLabel('Log Conversion')
        self.logLabel.setAlignment(Qt.AlignCenter)

        # Labels for User Input values
        inputLabel = QLabel('User Values')
        inputLabel.setAlignment(Qt.AlignCenter)
        amslLabel = QLabel('Average AMSL (m)')
        amslLabel.setAlignment(Qt.AlignCenter)

        # Unnecessary labels
        #
        # missionIdLabel = QLabel('Name of Mission')
        # missionIdLabel.setAlignment(Qt.AlignCenter)
        # tailNumLabel = QLabel('Aircraft N or registration number')
        # tailNumLabel.setAlignment(Qt.AlignCenter)
        # platDesigLabel = QLabel('Aircraft Designation')
        # platDesigLabel.setAlignment(Qt.AlignCenter)
        # imageSensorLabel = QLabel('Image sensor name')
        # imageSensorLabel.setAlignment(Qt.AlignCenter)
        # coordSysLabel = QLabel('Coordinate system (e.g. WGS84)')
        # coordSysLabel.setAlignment(Qt.AlignCenter)

        # QLineEdits for getting user values
        self.amslInput = QLineEdit()
        # self.missionIdInput = QLineEdit()
        # self.tailNumInput = QLineEdit()
        # self.platDesigInput = QLineEdit()
        # self.imageSensorInput = QLineEdit()
        # self.coordSysInput = QLineEdit()

        # ______Buttons______

        # Create camera drop down list of supported cameras
        # from cameras.xml profile document
        # Use parser to ensure pretty print works, see:
        # http://lxml.de/FAQ.html#why-doesn-t-the-
        # pretty-print-option-reformat-my-xml-output
        parser = etree.XMLParser(remove_blank_text=True)
        self.xml_tree = etree.parse('cameras.xml', parser)
        self.xml_root = self.xml_tree.getroot()

        # Initialize QComboBox object with default text
        cameraType = QComboBox(self)
        cameraType.addItem('Select a Camera')

        # Loop through the children of the xml root
        # get the camera name and add to the drop down list
        index = 0
        for child in self.xml_root:

            self.camera = child[NAME].text
            cameraType.addItem(self.camera)
            # Populate the xml map list with the camera name and
            # it's index in the root list so we can refer to it's values
            # later
            xml_map[self.camera] = index
            index += 1

        cameraType.setEditable(True)
        cameraType.lineEdit().setReadOnly(True)
        cameraType.lineEdit().setAlignment(Qt.AlignCenter)

        # Align the dropdown options to be centered
        for i in range(0, cameraType.count()):
            cameraType.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole)

        cameraType.activated[str].connect(self.cameraChosen)

        # Create Log type drop down menu
        self.logType = QComboBox(self)
        self.logType.addItem('Select Log Type')
        # self.logType.addItem('DJI GO')
        self.logType.addItem('Litchi')

        for i in range(0, self.logType.count()):
            self.logType.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole)

        self.logType.setEditable(True)
        self.logType.lineEdit().setReadOnly(True)
        self.logType.lineEdit().setAlignment(Qt.AlignCenter)

        self.logType.activated[str].connect(self.logTypeChosen)

        # Create push button for adding a new camera profile
        newCameraBtn = QPushButton('Add New Camera')
        newCameraBtn.clicked.connect(self.newCamera)

        # Create push button object that opens the log file
        # to be converted
        chooseLogBtn = QPushButton('Open log file...')
        chooseLogBtn.clicked.connect(self.openFile)

        # Push button to start log conversion
        convertBtn = QPushButton('Convert!')
        convertBtn.clicked.connect(self.convertLog)

        # Button for setting output file location
        saveLocBtn = QPushButton('Set output save location...')
        saveLocBtn.clicked.connect(self.saveLocation)

        # Quit button
        quitBtn = QPushButton('Exit Program')
        quitBtn.clicked.connect(self.close)

        # ______Layout______

        # Create vertical box layout
        vbox = QVBoxLayout()
        vbox.addStretch()
        vbox.addWidget(cameraLabel)
        vbox.addWidget(cameraType)
        vbox.addWidget(newCameraBtn)
        vbox.addStretch()
        vbox.addWidget(logTypeLabel)
        vbox.addWidget(self.logType)
        vbox.addStretch()
        vbox.addWidget(inputLabel)
        vbox.addWidget(amslLabel)
        vbox.addWidget(self.amslInput)
        # vbox.addWidget(missionIdLabel)
        # vbox.addWidget(self.missionIdInput)
        # vbox.addWidget(tailNumLabel)
        # vbox.addWidget(self.tailNumInput)
        # vbox.addWidget(platDesigLabel)
        # vbox.addWidget(self.platDesigInput)
        # vbox.addWidget(imageSensorLabel)
        # vbox.addWidget(self.imageSensorInput)
        # vbox.addWidget(coordSysLabel)
        # vbox.addWidget(self.coordSysInput)
        vbox.addStretch()
        vbox.addWidget(self.logLabel)
        vbox.addWidget(chooseLogBtn)
        vbox.addWidget(saveLocBtn)
        vbox.addWidget(convertBtn)
        vbox.addStretch()
        vbox.addWidget(quitBtn)

        centralWidget.setLayout(vbox)

        # Create quit action
        quit = QAction('Quit', self)
        quit.setShortcut('Ctrl+Q')
        quit.setStatusTip('Exit program')
        quit.triggered.connect(self.close)

        # Create about action
        about = QAction('About LogConverter', self)
        about.setShortcut('Ctrl+A')
        about.setStatusTip('About program')
        about.triggered.connect(self.aboutProgram)

        # Create menubar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(quit)
        aboutMenu = menubar.addMenu('&About')
        aboutMenu.addAction(about)

        self.setCentralWidget(centralWidget)

        self.resize(WINDOW_WIDTH, WINDOW_HEIGHT)
        self.center()

        self.setWindowTitle('Log Converter')
        self.show()