Esempio n. 1
0
class ConnectionSettings(QWidget):
    def __init__(self):
        super(ConnectionSettings, self).__init__()

        self.name_label = QLabel("Grid name:")
        self.name_line_edit = QLineEdit()

        self.introducer_label = QLabel("Introducer fURL:")
        self.introducer_text_edit = QPlainTextEdit()
        self.introducer_text_edit.setMaximumHeight(70)
        self.introducer_text_edit.setTabChangesFocus(True)

        self.mode_label = QLabel("Connection mode:")
        self.mode_combobox = QComboBox()
        self.mode_combobox.addItem("Normal")
        self.mode_combobox.addItem("Tor")
        self.mode_combobox.model().item(1).setEnabled(False)
        self.mode_combobox.addItem("I2P")
        self.mode_combobox.model().item(2).setEnabled(False)

        form = QFormLayout(self)
        form.setWidget(0, QFormLayout.LabelRole, self.name_label)
        form.setWidget(0, QFormLayout.FieldRole, self.name_line_edit)
        form.setWidget(1, QFormLayout.LabelRole, self.introducer_label)
        form.setWidget(1, QFormLayout.FieldRole, self.introducer_text_edit)
        form.setWidget(2, QFormLayout.LabelRole, self.mode_label)
        form.setWidget(2, QFormLayout.FieldRole, self.mode_combobox)
Esempio n. 2
0
class StaffGroup(_base.Container):
    @staticmethod
    def title(_=_base.translate):
        return _("Staff Group")

    def accepts(self):
        return (StaffGroup, _base.Part)

    def createWidgets(self, layout):
        self.systemStartLabel = QLabel()
        self.systemStart = QComboBox()
        self.systemStartLabel.setBuddy(self.systemStart)
        self.systemStart.setModel(
            listmodel.ListModel(
                (
                    # L10N: Brace like a piano staff
                    (lambda: _("Brace"), 'system_start_brace'),
                    # L10N: Bracket like a choir staff
                    (lambda: _("Bracket"), 'system_start_bracket'),
                    # L10N: Square bracket like a sub-group
                    (lambda: _("Square"), 'system_start_square'),
                ),
                self.systemStart,
                display=listmodel.translate_index(0),
                icon=lambda item: symbols.icon(item[1])))
        self.systemStart.setIconSize(QSize(64, 64))
        self.connectBarLines = QCheckBox(checked=True)

        box = QHBoxLayout()
        box.addWidget(self.systemStartLabel)
        box.addWidget(self.systemStart)
        layout.addLayout(box)
        layout.addWidget(self.connectBarLines)

    def translateWidgets(self):
        self.systemStartLabel.setText(_("Type:"))
        self.connectBarLines.setText(_("Connect Barlines"))
        self.connectBarLines.setToolTip(
            _("If checked, barlines are connected between the staves."))
        self.systemStart.model().update()

    def build(self, data, builder):
        s = self.systemStart.currentIndex()
        b = self.connectBarLines.isChecked()
        if s == 0:
            node = ly.dom.GrandStaff()
            if not b:
                ly.dom.Line("\\remove Span_bar_engraver", node.getWith())
        else:
            node = ly.dom.StaffGroup() if b else ly.dom.ChoirStaff()
            if s == 2:
                node.getWith()['systemStartDelimiter'] = ly.dom.Scheme(
                    "'SystemStartSquare")
        data.nodes.append(node)
        data.music = ly.dom.Simr(node)
Esempio n. 3
0
def addItem(combo: QComboBox, db_manager, data: dict, check=False) -> int:
    """добавление элемента"""
    display_key = combo.model().display
    if check:
        index = findItem(combo, data[display_key])
        if index >= 0:
            return index
    table_class = getattr(combo.model(), 'TableClass')
    new_id = db_manager.createRecord(table_class, data)
    data.update({'ID': new_id})
    combo.addItem(data[display_key], data)
    return combo.count() - 1
Esempio n. 4
0
    def add_combo_box(self, type):
        '''
            This function is called inside add_question. It adds the combo box with the question types.
            Currently the Binary type is disabled because it has not been implemented into the player.
        '''
        comboBox = QComboBox(self)

        comboBox.addItem(self.parent.MultiLang.find_correct_word("continuous"))
        comboBox.addItem("binary")
        comboBox.model().item(1).setEnabled(False)
        comboBox.setCurrentIndex(type)

        self.layout.addWidget(comboBox, self.number_of_fields + 1, 3)
        self.combo_box_list.append(comboBox)
Esempio n. 5
0
class StaffGroup(_base.Container):
    @staticmethod
    def title(_=_base.translate):
        return _("Staff Group")

    def accepts(self):
        return (StaffGroup, _base.Part)

    def createWidgets(self, layout):
        self.systemStartLabel = QLabel()
        self.systemStart = QComboBox()
        self.systemStartLabel.setBuddy(self.systemStart)
        self.systemStart.setModel(listmodel.ListModel((
            # L10N: Brace like a piano staff
            (lambda: _("Brace"), 'system_start_brace'),
            # L10N: Bracket like a choir staff
            (lambda: _("Bracket"), 'system_start_bracket'),
            # L10N: Square bracket like a sub-group
            (lambda: _("Square"), 'system_start_square'),
            ), self.systemStart, display=listmodel.translate_index(0),
            icon=lambda item: symbols.icon(item[1])))
        self.systemStart.setIconSize(QSize(64, 64))
        self.connectBarLines = QCheckBox(checked=True)
        
        box = QHBoxLayout()
        box.addWidget(self.systemStartLabel)
        box.addWidget(self.systemStart)
        layout.addLayout(box)
        layout.addWidget(self.connectBarLines)
    
    def translateWidgets(self):
        self.systemStartLabel.setText(_("Type:"))
        self.connectBarLines.setText(_("Connect Barlines"))
        self.connectBarLines.setToolTip(_("If checked, barlines are connected between the staves."))
        self.systemStart.model().update()
    
    def build(self, data, builder):
        s = self.systemStart.currentIndex()
        b = self.connectBarLines.isChecked()
        if s == 0:
            node = ly.dom.GrandStaff()
            if not b:
                ly.dom.Line("\\remove Span_bar_engraver", node.getWith())
        else:
            node = ly.dom.StaffGroup() if b else ly.dom.ChoirStaff()
            if s == 2:
                node.getWith()['systemStartDelimiter'] = ly.dom.Scheme("'SystemStartSquare")
        data.nodes.append(node)
        data.music = ly.dom.Simr(node)
class comics_template_dialog(QDialog):
    templateDirectory = str()
    templates = QComboBox()
    buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

    def __init__(self, templateDirectory):
        super().__init__()
        self.templateDirectory = templateDirectory
        self.setWindowTitle(i18n("Add new Template"))
        self.setLayout(QVBoxLayout())

        self.templates = QComboBox()
        self.templates.setEnabled(False)

        self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.buttons.button(QDialogButtonBox.Ok).setEnabled(False)
        mainWidget = QWidget()
        self.layout().addWidget(mainWidget)
        self.layout().addWidget(self.buttons)
        mainWidget.setLayout(QVBoxLayout())

        btn_create = QPushButton(i18n("Create Template"))
        btn_create.clicked.connect(self.slot_create_template)
        btn_import = QPushButton(i18n("Import Templates"))
        btn_import.clicked.connect(self.slot_import_template)
        mainWidget.layout().addWidget(self.templates)
        mainWidget.layout().addWidget(btn_create)
        mainWidget.layout().addWidget(btn_import)
        self.fill_templates()

    def fill_templates(self):
        self.templates.clear()
        for entry in os.scandir(self.templateDirectory):
            if entry.name.endswith('.kra') and entry.is_file():
                name = os.path.relpath(entry.path, self.templateDirectory)
                self.templates.addItem(name)
        if self.templates.model().rowCount() > 0:
            self.templates.setEnabled(True)
            self.buttons.button(QDialogButtonBox.Ok).setEnabled(True)

    def slot_create_template(self):
        create = comics_template_create(self.templateDirectory)

        if create.exec_() == QDialog.Accepted:
            if (create.prepare_krita_file()):
                self.fill_templates()

    def slot_import_template(self):
        filenames = QFileDialog.getOpenFileNames(caption=i18n("Which files should be added to the template folder?"), directory=self.templateDirectory, filter=str(i18n("Krita files") + "(*.kra)"))[0]
        for file in filenames:
            shutil.copy2(file, self.templateDirectory)
        self.fill_templates()

    def url(self):
        return os.path.join(self.templateDirectory, self.templates.currentText())
Esempio n. 7
0
class ChordNames(object):
    def createWidgets(self, layout):
        self.chordStyleLabel = QLabel()
        self.chordStyle = QComboBox()
        self.chordStyleLabel.setBuddy(self.chordStyle)
        self.chordStyle.setModel(
            listmodel.ListModel(chordNameStyles,
                                self.chordStyle,
                                display=listmodel.translate))
        self.guitarFrets = QCheckBox()

        box = QHBoxLayout()
        box.addWidget(self.chordStyleLabel)
        box.addWidget(self.chordStyle)
        layout.addLayout(box)
        layout.addWidget(self.guitarFrets)

    def translateWidgets(self):
        self.chordStyleLabel.setText(_("Chord style:"))
        self.guitarFrets.setText(_("Guitar fret diagrams"))
        self.guitarFrets.setToolTip(
            _("Show predefined guitar fret diagrams below the chord names "
              "(LilyPond 2.12 and above)."))
        self.chordStyle.model().update()

    def build(self, data, builder):
        p = ly.dom.ChordNames()
        a = data.assign('chordNames')
        ly.dom.Identifier(a.name, p)
        s = ly.dom.ChordMode(a)
        ly.dom.Identifier(data.globalName, s).after = 1
        i = self.chordStyle.currentIndex()
        if i > 0:
            ly.dom.Line(
                '\\{0}Chords'.format(
                    ('german', 'semiGerman', 'italian', 'french')[i - 1]), s)
        ly.dom.LineComment(_("Chords follow here."), s)
        ly.dom.BlankLine(s)
        data.nodes.append(p)
        if self.guitarFrets.isChecked():
            f = ly.dom.FretBoards()
            ly.dom.Identifier(a.name, f)
            data.nodes.append(f)
            data.includes.append("predefined-guitar-fretboards.ly")
Esempio n. 8
0
 def createDefaultWidget(self, parent):
     cboPorts = QComboBox()
     for port, name in QgsGpsDetector.availablePorts():
         if port.startswith('COM'):
             cboPorts.addItem(name, port)
     cboPorts.model().sort(0)
     port = self.getPort()
     cboPorts.currentIndexChanged.connect(
         lambda: self.setPort(cboPorts.currentData()))
     idx = cboPorts.findData(port)
     if idx == -1: idx = 1
     cboPorts.setCurrentIndex(idx)
     # create the widget
     wid = QWidget(parent)
     layout = QHBoxLayout(wid)
     layout.addWidget(QLabel('GPS:'))
     layout.addWidget(cboPorts)
     wid.setLayout(layout)
     return wid
Esempio n. 9
0
class ChordNames(object):
    def createWidgets(self, layout):
        self.chordStyleLabel = QLabel()
        self.chordStyle = QComboBox()
        self.chordStyleLabel.setBuddy(self.chordStyle)
        self.chordStyle.setModel(listmodel.ListModel(chordNameStyles, self.chordStyle,
            display=listmodel.translate))
        self.guitarFrets = QCheckBox()
        
        box = QHBoxLayout()
        box.addWidget(self.chordStyleLabel)
        box.addWidget(self.chordStyle)
        layout.addLayout(box)
        layout.addWidget(self.guitarFrets)
        
    def translateWidgets(self):
        self.chordStyleLabel.setText(_("Chord style:"))
        self.guitarFrets.setText(_("Guitar fret diagrams"))
        self.guitarFrets.setToolTip(_(
            "Show predefined guitar fret diagrams below the chord names "
            "(LilyPond 2.12 and above)."))
        self.chordStyle.model().update()

    def build(self, data, builder):
        p = ly.dom.ChordNames()
        a = data.assign('chordNames')
        ly.dom.Identifier(a.name, p)
        s = ly.dom.ChordMode(a)
        ly.dom.Identifier(data.globalName, s).after = 1
        i = self.chordStyle.currentIndex()
        if i > 0:
            ly.dom.Line('\\{0}Chords'.format(
                ('german', 'semiGerman', 'italian', 'french')[i-1]), s)
        ly.dom.LineComment(_("Chords follow here."), s)
        ly.dom.BlankLine(s)
        data.nodes.append(p)
        if self.guitarFrets.isChecked():
            f = ly.dom.FretBoards()
            ly.dom.Identifier(a.name, f)
            data.nodes.append(f)
            data.includes.append("predefined-guitar-fretboards.ly")
Esempio n. 10
0
    def create_surface_dropdown(self, model_faces=None):
        """
        Populates the surfaces dropdown
        """
        self.model_faces = model_faces

        surfaces = QComboBox()

        if model_faces is not None:
            for i, face in enumerate(model_faces):
                if np.array_equal(face.normal.vec, [0.0, 1.0, 0.0]):
                    faceStr = "Ceiling [" + str(i) + "]"
                elif np.array_equal(face.normal.vec, [0.0, -1.0, 0.0]):
                    faceStr = "Floor [" + str(i) + "]"
                else:
                    faceStr = "Wall [" + str(i) + "]"
                surfaces.addItem(faceStr, face)
            surfaces.addItem("All", None)
            surfaces.model().sort(0)

        return surfaces
Esempio n. 11
0
    def choose_standard_level(self):
        self.chooseStandardDialog = QDialog()
        layout = QGridLayout()

        noXMLLabel = QLabel("No XML found", self)
        layout.addWidget(noXMLLabel, 0, 0)

        chooseStandardLabel = QLabel("Standard", self)
        chooseStandardCombo = QComboBox(self)
        chooseStandardCombo.addItem("Factur-X")
        chooseStandardCombo.addItem("Zugferd")
        chooseStandardCombo.addItem("UBL")
        chooseStandardCombo.model().item(2).setEnabled(False)
        chooseStandardCombo.activated[str].connect(self.on_select_level)

        chooseLevelLabel = QLabel("Level", self)
        self.chooseLevelCombo = QComboBox(self)
        self.chooseLevelCombo.addItem("Minimum")
        self.chooseLevelCombo.addItem("Basic WL")
        self.chooseLevelCombo.addItem("Basic")
        self.chooseLevelCombo.addItem("EN16931")
        self.chooseLevelCombo.activated[str].connect(self.set_level)

        applyStandard = QPushButton("Apply")
        applyStandard.clicked.connect(self.set_standard_level)
        discardStandard = QPushButton("Cancel")
        discardStandard.clicked.connect(self.discard_standard_level)

        layout.addWidget(chooseStandardLabel, 1, 0)
        layout.addWidget(chooseStandardCombo, 1, 1)
        layout.addWidget(chooseLevelLabel, 2, 0)
        layout.addWidget(self.chooseLevelCombo, 2, 1)
        layout.addWidget(discardStandard, 3, 0)
        layout.addWidget(applyStandard, 3, 1)

        self.chooseStandardDialog.setLayout(layout)
        self.chooseStandardDialog.setWindowTitle("Choose Standard")
        self.chooseStandardDialog.setWindowModality(Qt.ApplicationModal)
        self.chooseStandardDialog.exec_()
Esempio n. 12
0
class BarcodePropsEdit(PropsEdit):
    def __init__(self, data: BarcodeData, parent, printable):
        super().__init__(data, parent, printable)
        self.setMinimumWidth(256)

        self.combo_type = QComboBox()
        model = QStandardItemModel(0, 2)
        curr_index = 0
        for key in barcode.PROVIDED_BARCODES:
            bc = barcode.get(key)
            model.appendRow([QStandardItem(bc.name), QStandardItem(key)])
            if data.code_type == key:
                curr_index = model.rowCount() - 1

        self.combo_type.setModel(model)
        self.combo_type.setCurrentIndex(curr_index)
        self.combo_type.currentIndexChanged.connect(self.combo_type_changed)
        self.layout.addWidget(QLabel('Barcode type:'))
        self.layout.addWidget(self.combo_type)

        self.edit_text = QLineEdit(data.text, self)
        self.edit_text.textChanged.connect(self.edit_text_changed)
        self.layout.addWidget(QLabel('Value:'))
        self.layout.addWidget(self.edit_text)

        self.show_label = QCheckBox("Include label", self)
        self.show_label.setChecked(data.draw_label)
        self.layout.addWidget(self.show_label)

        self.layout.addStretch()

    def combo_type_changed(self):
        model: QStandardItemModel = self.combo_type.model()
        item = model.item(self.combo_type.currentIndex(), 1)
        print(item.text(), item.data())
        self.data.code_type = item.text()
        self.save()
        pass

    def serialize(self, clone=False):
        data = super().serialize(clone)

        data.text = self.edit_text.text()
        data.draw_label = self.show_label.isChecked()
        return data

    def edit_text_changed(self):
        self.save()
Esempio n. 13
0
    def __init__(self, form_context, parent=None):
        super().__init__(parent)
        self._form_context = form_context

        self.setObjectName("PaymentAmount")

        amount_widget = QLineEdit()
        currency_widget = QLineEdit()

        currency_combo = QComboBox()
        currency_combo.setEditable(True)

        filter_model = QSortFilterProxyModel(currency_combo)
        filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        filter_model.setSourceModel(currency_combo.model())

        contact_completer = QCompleter(filter_model, currency_combo)
        contact_completer.setCompletionMode(
            QCompleter.UnfilteredPopupCompletion)
        currency_combo.setCompleter(contact_completer)

        # base unit.
        # selected fiat currency.

        options = []
        base_unit = form_context.wallet_api.get_base_unit()
        options.append(base_unit)
        fiat_unit = form_context.wallet_api.get_fiat_unit()
        if fiat_unit is not None:
            options.append(fiat_unit)

        currency_combo.addItems(options)
        currency_combo.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(currency_combo)
        layout.addWidget(amount_widget)
        self.setLayout(layout)

        self._currency_combo_options = options
        self._currency_combo = currency_combo
        self._amount_widget = amount_widget
        self._form_context.set_payment_amount.connect(self._set_payment_amount)
Esempio n. 14
0
    def apply(self):
        self.froms = []
        self.tos = []
        self.colors = []
        self.num_intervals = self.editor2.text()
        self.range = self.editor1.text()
        self.current_value = self.comboBox.currentText()
        for _ in range(int(self.num_intervals)):
            hbox = QHBoxLayout()
            mylabel_1 = QLabel()
            mylabel_1.setText("From:")
            myeditor_1 = QLineEdit()
            self.froms.append(myeditor_1)

            hbox.addWidget(mylabel_1)
            hbox.addWidget(myeditor_1)


            mylabel_2 = QLabel()
            mylabel_2.setText("to:")
            myeditor_2 = QLineEdit()
            self.tos.append(myeditor_2)

            hbox.addWidget(mylabel_2)
            hbox.addWidget(myeditor_2)



            mylabel_3 = QLabel()
            mylabel_3.setText("Color:")
            color_combobox = QComboBox()
            model = color_combobox.model()
            for a,b,c,color in colors:
                entry = QStandardItem(color)
                entry.setForeground(QColor(a,b,c))
                # color_combobox.addItem(color)
                model.appendRow(entry)
            self.colors.append(color_combobox)

            hbox.addWidget(mylabel_3)
            hbox.addWidget(color_combobox)

            self.v_lay.addLayout(hbox)
Esempio n. 15
0
class stats(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.bold_font = QFont()
        self.bold_font.setBold(True)

        stats_content = get_home_stats()

        # -- LEVEL TWO GRID
        self.grid = QGridLayout()
        self.grid.setSpacing(20)
        self.grid.setContentsMargins(0, 1, 0, 1)
        self.setLayout(self.grid)

        # -- CELL ZERO
        self.funds_group = QGroupBox("Funds Status")

        self.stats_pie = QLabel()
        self.image = QPixmap('pie.png')
        self.resized_image = self.image.scaled(500, 500, Qt.KeepAspectRatio,
                                               Qt.FastTransformation)
        self.stats_pie.setPixmap(self.resized_image)

        self.stats_pie.setAlignment(Qt.AlignCenter)

        self.currency_label = QLabel()
        currency_content = f"FUNDS COLLECTED IN {all_months_values[currentMonth-1].upper()} : {stats_content['funds']} INR"
        self.currency_label.setText(currency_content)
        self.currency_label.setWordWrap(True)
        self.currency_label.setAlignment(Qt.AlignCenter)
        self.currency_label.setStyleSheet("font: bold 10pt")

        self.funds_layout = QFormLayout()
        self.funds_layout.addRow(self.stats_pie)
        self.funds_layout.addRow(self.currency_label)
        self.funds_layout.setVerticalSpacing(10)

        self.funds_group.setLayout(self.funds_layout)

        # -- CELL ONE
        self.members_group = QGroupBox("Members Status")

        stats_content, self.defaulters = get_stats_content()

        self.stats_result_table = QTableWidget()

        self.stats_result_table.setRowCount(len(stats_content))
        self.stats_result_table.setColumnCount(3)
        self.stats_result_table.setHorizontalHeaderLabels(
            ["Flat", "Name", "Fees Paid Upto"])

        for index, row in enumerate(stats_content):
            for inner_index, row_content in enumerate(row):
                table_item = QTableWidgetItem(str(row_content))

                if inner_index != 1:
                    table_item.setTextAlignment(Qt.AlignCenter)

                if index in self.defaulters:
                    table_item.setForeground(QBrush(QColor(249, 56, 34)))

                    if inner_index == 2:
                        table_item.setFont(self.bold_font)

                self.stats_result_table.setItem(index, inner_index, table_item)

        header = self.stats_result_table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)

        self.members_layout = QHBoxLayout()
        self.members_layout.addWidget(self.stats_result_table)

        self.members_group.setLayout(self.members_layout)

        # -- CELL TWO
        self.additional_layout = QVBoxLayout()

        self.remainder_group = QGroupBox("Remainders")

        self.backup_group = QGroupBox("Backup")
        self.excel_group = QGroupBox("Excel")

        self.backup_h = QHBoxLayout()
        self.backup_h.addWidget(self.backup_group)
        self.backup_h.addWidget(self.excel_group)

        self.responsibility_group = QGroupBox("Responsibility")

        self.additional_layout.addWidget(self.remainder_group)
        self.additional_layout.addLayout(self.backup_h)
        self.additional_layout.addWidget(self.responsibility_group)
        self.additional_layout.setSpacing(20)
        self.additional_layout.setContentsMargins(0, 0, 0, 0)

        # ---
        self.remainder_desc = QLabel(
            "Send a mail to all the pending members for this month, as a remainder to pay the fees."
        )
        self.remainder_desc.setWordWrap(True)
        self.remainder_button = QPushButton("Send REMAINDERS")

        self.rbar = QProgressBar()
        self.rbar.setValue(0)
        self.rbar.setMaximum(100)
        self.rbar.setTextVisible(True)
        self.rbar.setFixedSize(472, 15)

        self.remainder_layout = QVBoxLayout()
        self.remainder_layout.addWidget(self.remainder_desc)
        self.remainder_layout.addWidget(self.remainder_button)
        self.remainder_layout.addWidget(self.rbar)
        self.remainder_group.setLayout(self.remainder_layout)
        self.remainder_group.setFixedWidth(500)

        # ---
        self.backup_desc = QLabel(
            "Backup the current state of database, and save it online.")
        self.backup_desc.setWordWrap(True)
        self.backup_button = QPushButton("Generate BACKUP")
        self.backup_button.setToolTip(
            "Backups are automatically generated at the start of every month.")

        self.backup_layout = QVBoxLayout()
        self.backup_layout.addWidget(self.backup_desc)
        self.backup_layout.addWidget(self.backup_button)

        self.backup_group.setLayout(self.backup_layout)

        self.excel_desc = QLabel(
            "Generate an Excel file for current state of database.")
        self.excel_desc.setWordWrap(True)
        self.excel_button = QPushButton("Generate EXCEL")
        self.excel_button.setToolTip(
            "Create Excel files of Members and Records.")

        self.excel_layout = QVBoxLayout()
        self.excel_layout.addWidget(self.excel_desc)
        self.excel_layout.addWidget(self.excel_button)

        self.excel_group.setLayout(self.excel_layout)

        # ---
        self.responsibility_desc = QLabel(
            "Pass on the responsibility of fee collection to a different member."
        )

        self.responsibility_desc.setWordWrap(True)

        self.responsibility_combo = QComboBox()
        model = self.responsibility_combo.model()

        for flat in flats:
            model.appendRow(QStandardItem(flat))

        self.responsibility_combo.setStyleSheet(
            'text-color: black; selection-background-color: rgb(215,215,215)')
        self.responsibility_combo.setFixedWidth(140)

        self.responsibility_button = QPushButton("TRANSFER")
        self.responsibility_button.setToolTip(
            "This will send a mail with latest database and the software to new member."
        )

        self.responsibility_h = QHBoxLayout()
        self.responsibility_h.addWidget(self.responsibility_combo)
        self.responsibility_h.addWidget(self.responsibility_button)

        self.responsibility_layout = QVBoxLayout()
        self.responsibility_layout.addWidget(self.responsibility_desc)
        self.responsibility_layout.addLayout(self.responsibility_h)

        self.responsibility_group.setLayout(self.responsibility_layout)

        # -- FUNCTIONALITY
        self.backup_button.clicked.connect(backup)
        self.excel_button.clicked.connect(csv)
        self.responsibility_button.clicked.connect(self.transfer)
        self.remainder_button.clicked.connect(self.remainder)

        # -- STATS GRID
        self.grid.addWidget(self.funds_group, 0, 0, 2, 1)
        self.grid.addWidget(self.members_group, 0, 1, 2, 2)
        self.grid.addLayout(self.additional_layout, 0, 3, 2, 1)

    def transfer(self):
        flat = self.responsibility_combo.currentText()
        transfer_responsibility(flat=flat)

    def remainder(self):
        self.backup_group.setEnabled(False)
        self.excel_group.setEnabled(False)
        self.responsibility_group.setEnabled(False)

        self.remainder_desc.setText(
            "Sending Remainders.\nPlease do not perform any other operations until its complete."
        )

        defaulters = [f"A - {x + 1}" for x in self.defaulters]
        self.rbar.setValue(1)

        for index, defaulter in enumerate(defaulters):
            send_remainder(defaulter=defaulter,
                           month=all_months_values[currentMonth - 1])
            self.rbar.setValue((index + 1) * 100 // len(defaulters))

        self.rbar.setValue(100)
        self.backup_group.setEnabled(True)
        self.excel_group.setEnabled(True)
        self.responsibility_group.setEnabled(True)
        self.rbar.setValue(0)

        self.remainder_desc.setText(
            "Send a mail to all the pending members for this month, as a remainder to pay the fees."
        )
Esempio n. 16
0
class TablaturePart(_base.Part):
    """Base class for tablature instrument part types."""

    octave = 0
    clef = None
    transposition = None
    tunings = ()    # may contain a list of tunings.
    tabFormat = ''  # can contain a tablatureFormat value.

    def createWidgets(self, layout):
        self.staffTypeLabel = QLabel()
        self.staffType = QComboBox()
        self.staffTypeLabel.setBuddy(self.staffType)
        self.staffType.setModel(listmodel.ListModel(tablatureStaffTypes,
            self.staffType, display=listmodel.translate))
        box = QHBoxLayout()
        layout.addLayout(box)
        box.addWidget(self.staffTypeLabel)
        box.addWidget(self.staffType)
        if self.tunings:
            self.createTuningWidgets(layout)
            self.staffType.activated.connect(self.slotTabEnable)
            self.slotTabEnable(0)

    def createTuningWidgets(self, layout):
        self.tuningLabel = QLabel()
        self.tuning = QComboBox()
        self.tuningLabel.setBuddy(self.tuning)
        tunings = [('', lambda: _("Default"))]
        tunings.extend(self.tunings)
        tunings.append(('', lambda: _("Custom tuning")))
        self.tuning.setModel(listmodel.ListModel(tunings, self.tuning,
            display=listmodel.translate_index(1)))
        self.tuning.setCurrentIndex(1)
        self.customTuning = QLineEdit(enabled=False)
        completionmodel.complete(self.customTuning,
            "scorewiz/completion/plucked_strings/custom_tuning")
        self.tuning.currentIndexChanged.connect(self.slotCustomTuningEnable)
        box = QHBoxLayout()
        layout.addLayout(box)
        box.addWidget(self.tuningLabel)
        box.addWidget(self.tuning)
        layout.addWidget(self.customTuning)

    def translateWidgets(self):
        self.staffTypeLabel.setText(_("Staff type:"))
        self.staffType.model().update()
        if self.tunings:
            self.translateTuningWidgets()

    def translateTuningWidgets(self):
        self.tuningLabel.setText(_("Tuning:"))
        self.customTuning.setToolTip('<qt>' + _(
            "Select custom tuning in the combobox and "
            "enter a custom tuning here, e.g. <code>e, a d g b e'</code>. "
            "Use absolute note names in the same language as you want to use "
            "in your document (by default: \"nederlands\")."))
        try:
            self.customTuning.setPlaceholderText(_("Custom tuning..."))
        except AttributeError:
            pass # only in Qt 4.7+
        self.tuning.model().update()

    def slotTabEnable(self, enable):
        """Called when the user changes the staff type.

        Non-zero if the user wants a TabStaff.

        """
        self.tuning.setEnabled(bool(enable))
        if enable:
            self.slotCustomTuningEnable(self.tuning.currentIndex())
        else:
            self.customTuning.setEnabled(False)

    def slotCustomTuningEnable(self, index):
        self.customTuning.setEnabled(index > len(self.tunings))

    def voiceCount(self):
        """Returns the number of voices.

        Inherit to make this user-settable.

        """
        return 1

    def build(self, data, builder):
        # First make assignments for the voices we want to create
        numVoices = self.voiceCount()
        if numVoices == 1:
            voices = (ly.util.mkid(data.name()),)
        elif numVoices == 2:
            order = 1, 2
            voices = 'upper', 'lower'
        elif numVoices == 3:
            order = 1, 3, 2
            voices = 'upper', 'middle', 'lower'
        else:
            order = 1, 2, 3, 4
            voices = [ly.util.mkid(data.name(), "voice") + ly.util.int2text(i) for i in order]

        assignments = [data.assignMusic(name, self.octave, self.transposition)
                       for name in voices]

        staffType = self.staffType.currentIndex()
        if staffType in (0, 2):
            # create a normal staff
            staff = ly.dom.Staff()
            seq = ly.dom.Seqr(staff)
            if self.clef:
                ly.dom.Clef(self.clef, seq)
            mus = ly.dom.Simr(seq)
            for a in assignments[:-1]:
                ly.dom.Identifier(a.name, mus)
                ly.dom.VoiceSeparator(mus)
            ly.dom.Identifier(assignments[-1].name, mus)
            builder.setMidiInstrument(staff, self.midiInstrument)

        if staffType in (1, 2):
            # create a tab staff
            tabstaff = ly.dom.TabStaff()
            if self.tabFormat:
                tabstaff.getWith()['tablatureFormat'] = ly.dom.Scheme(self.tabFormat)
            self.setTunings(tabstaff)
            sim = ly.dom.Simr(tabstaff)
            if numVoices == 1:
                ly.dom.Identifier(assignments[0].name, sim)
            else:
                for num, a in zip(order, assignments):
                    s = ly.dom.Seq(ly.dom.TabVoice(parent=sim))
                    ly.dom.Text('\\voice' + ly.util.int2text(num), s)
                    ly.dom.Identifier(a.name, s)

        if staffType == 0:
            # only a normal staff
            p = staff
        elif staffType == 1:
            # only a TabStaff
            builder.setMidiInstrument(tabstaff, self.midiInstrument)
            p = tabstaff
        else:
            # both TabStaff and normal staff
            p = ly.dom.StaffGroup()
            s = ly.dom.Sim(p)
            s.append(staff)
            s.append(tabstaff)

        builder.setInstrumentNamesFromPart(p, self, data)
        data.nodes.append(p)

    def setTunings(self, tab):
        if self.tunings:
            i = self.tuning.currentIndex()
            if i == 0:
                return
            elif i > len(self.tunings):
                value = ly.dom.Text("\\stringTuning <{0}>".format(self.customTuning.text()))
            else:
                tuning = self.tunings[self.tuning.currentIndex() - 1][0]
                value = ly.dom.Scheme(tuning)
            tab.getWith()['stringTunings'] = value
Esempio n. 17
0
class ScoreProperties(object):
    """This is only the base class, it should be mixed in with a widget or a different way."""

    def createWidgets(self):
        """Creates all widgets."""
        self.createKeySignatureWidget()
        self.createTimeSignatureWidget()
        self.createPickupWidget()
        self.createMetronomeWidget()
        self.createTempoWidget()

    def layoutWidgets(self, layout):
        """Adds all widgets to a vertical layout."""
        self.layoutKeySignatureWidget(layout)
        self.layoutTimeSignatureWidget(layout)
        self.layoutPickupWidget(layout)
        self.layoutMetronomeWidget(layout)
        self.layoutTempoWidget(layout)

    def translateWidgets(self):
        self.translateKeySignatureWidget()
        self.translateTimeSignatureWidget()
        self.translatePickupWidget()
        self.tranlateMetronomeWidget()
        self.translateTempoWidget()

    def ly(self, node, builder):
        """Adds appropriate LilyPond command nodes to the parent node.

        Settings from the builder are used where that makes sense.
        All widgets must be present.

        """
        self.lyKeySignature(node, builder)
        self.lyTimeSignature(node, builder)
        self.lyPickup(node, builder)
        self.lyTempo(node, builder)

    def globalSection(self, builder):
        """Returns a sequential expression between { } containing the output of ly()."""
        seq = ly.dom.Seq()
        self.ly(seq, builder)
        return seq

    # Key signature
    def createKeySignatureWidget(self):
        self.keySignatureLabel = QLabel()
        self.keyNote = QComboBox()
        self.keyNote.setModel(listmodel.ListModel(keyNames['nederlands'], self.keyNote))
        self.keyMode = QComboBox()
        self.keyMode.setModel(listmodel.ListModel(modes, self.keyMode, display=listmodel.translate_index(1)))
        self.keySignatureLabel.setBuddy(self.keyNote)

    def translateKeySignatureWidget(self):
        self.keySignatureLabel.setText(_("Key signature:"))
        self.keyMode.model().update()

    def layoutKeySignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.keySignatureLabel)
        box.addWidget(self.keyNote)
        box.addWidget(self.keyMode)
        layout.addLayout(box)

    def setPitchLanguage(self, language='nederlands'):
        self.keyNote.model()._data = keyNames[language or 'nederlands']
        self.keyNote.model().update()

    def lyKeySignature(self, node, builder):
        """Adds the key signature to the ly.dom node parent."""
        note, alter = keys[self.keyNote.currentIndex()]
        alter = fractions.Fraction(alter, 2)
        mode = modes[self.keyMode.currentIndex()][0]
        ly.dom.KeySignature(note, alter, mode, node).after = 1

    # Time signature
    def createTimeSignatureWidget(self):
        self.timeSignatureLabel = QLabel()
        self.timeSignature = QComboBox(editable=True)
        icons = {
            '(4/4)': symbols.icon('time_c44'),
            '(2/2)': symbols.icon('time_c22'),
        }
        self.timeSignature.setModel(listmodel.ListModel(timeSignaturePresets, self.timeSignature,
            icon=icons.get))
        self.timeSignature.setCompleter(None)
        self.timeSignatureLabel.setBuddy(self.timeSignature)

    def translateTimeSignatureWidget(self):
        self.timeSignatureLabel.setText(_("Time signature:"))

    def layoutTimeSignatureWidget(self, layout):
        """Adds our widgets to a layout, assuming it is a QVBoxLayout."""
        box = QHBoxLayout()
        box.addWidget(self.timeSignatureLabel)
        box.addWidget(self.timeSignature)
        layout.addLayout(box)

    def lyTimeSignature(self, node, builder):
        """Adds the time signature to the ly.dom node parent."""
        sig = self.timeSignature.currentText().strip()
        if '+' in sig:
            pass # TODO: implement support for \compoundMeter
        else:
            if sig == '(2/2)':
                ly.dom.TimeSignature(2, 2, node).after = 1
            elif sig == '(4/4)':
                ly.dom.TimeSignature(4, 4, node).after = 1
            else:
                match = re.search(r'(\d+).*?(\d+)', sig)
                if match:
                    if builder.lyVersion >= (2, 11, 44):
                        ly.dom.Line(r"\numericTimeSignature", node)
                    else:
                        ly.dom.Line(r"\override Staff.TimeSignature #'style = #'()", node)
                    num, beat = map(int, match.group(1, 2))
                    ly.dom.TimeSignature(num, beat, node).after = 1

    # Pickup bar
    def createPickupWidget(self):
        self.pickupLabel = QLabel()
        self.pickup = QComboBox()
        pickups = ['']
        pickups.extend(durations)
        self.pickup.setModel(listmodel.ListModel(pickups, self.pickup,
            display = lambda item: item or _("None"),
            icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd'))) if item else None))
        self.pickup.view().setIconSize(QSize(22, 22))
        self.pickupLabel.setBuddy(self.pickup)

    def translatePickupWidget(self):
        self.pickupLabel.setText(_("Pickup measure:"))
        self.pickup.model().update()

    def layoutPickupWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.pickupLabel)
        box.addWidget(self.pickup)
        layout.addLayout(box)

    def lyPickup(self, node, builder):
        if self.pickup.currentIndex() > 0:
            dur, dots = partialDurations[self.pickup.currentIndex() - 1]
            ly.dom.Partial(dur, dots, parent=node)

    # Metronome value
    def createMetronomeWidget(self):
        self.metronomeLabel = QLabel()
        self.metronomeNote = QComboBox()
        self.metronomeNote.setModel(listmodel.ListModel(durations, display=None,
            icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd')))))
        self.metronomeNote.setCurrentIndex(durations.index('4'))
        self.metronomeNote.view().setIconSize(QSize(22, 22))
        self.metronomeEqualSign = QLabel('=')
        self.metronomeEqualSign.setFixedWidth(self.metronomeEqualSign.minimumSizeHint().width())
        self.metronomeValue = QComboBox(editable=True)
        self.metronomeValue.setModel(listmodel.ListModel(metronomeValues, self.metronomeValue,
            display=format))
        self.metronomeValue.setCompleter(None)
        self.metronomeValue.setValidator(QIntValidator(0, 999, self.metronomeValue))
        self.metronomeValue.setCurrentIndex(metronomeValues.index(100))
        self.metronomeTempo = widgets.tempobutton.TempoButton()
        self.metronomeTempo.tempo.connect(self.setMetronomeValue)
        self.metronomeLabel.setBuddy(self.metronomeNote)
        self.metronomeRound = QCheckBox()


    def layoutMetronomeWidget(self, layout):
        grid = QGridLayout()
        grid.addWidget(self.metronomeLabel, 0, 0)

        box = QHBoxLayout(spacing=0)
        box.addWidget(self.metronomeNote)
        box.addWidget(self.metronomeEqualSign)
        box.addWidget(self.metronomeValue)
        box.addWidget(self.metronomeTempo)
        grid.addLayout(box, 0, 1)

        grid.addWidget(self.metronomeRound, 1, 1)
        layout.addLayout(grid)

    def tranlateMetronomeWidget(self):
        self.metronomeLabel.setText(_("Metronome mark:"))
        self.metronomeRound.setText(_("Round tap tempo value"))
        self.metronomeRound.setToolTip(_(
            "Round the entered tap tempo to a common value."
            ))

    def setMetronomeValue(self, bpm):
        """ Tap the tempo tap button """
        if  self.metronomeRound.isChecked():
            l = [abs(t - bpm) for t in metronomeValues]
            m = min(l)
            if m < 6:
                self.metronomeValue.setCurrentIndex(l.index(m))

        else:
            self.metronomeValue.setEditText(str(bpm))

    # Tempo indication
    def createTempoWidget(self):
        self.tempoLabel = QLabel()
        self.tempo = widgets.lineedit.LineEdit()
        completionmodel.complete(self.tempo, "scorewiz/completion/scoreproperties/tempo")
        self.tempo.completer().setCaseSensitivity(Qt.CaseInsensitive)
        self.tempoLabel.setBuddy(self.tempo)

    def layoutTempoWidget(self, layout):
        box = QHBoxLayout()
        box.addWidget(self.tempoLabel)
        box.addWidget(self.tempo)
        layout.addLayout(box)

    def translateTempoWidget(self):
        self.tempoLabel.setText(_("Tempo indication:"))

    def lyTempo(self, node, builder):
        """Returns an appropriate tempo indication."""
        text = self.tempo.text().strip()
        if builder.showMetronomeMark:
            dur = durations[self.metronomeNote.currentIndex()]
            val = self.metronomeValue.currentText() or '60'
        elif text:
            dur = None
            val = None
        else:
            return
        tempo = ly.dom.Tempo(dur, val, node)
        if text:
            ly.dom.QuotedString(text, tempo)

    def lyMidiTempo(self, node):
        """Sets the configured tempo in the tempoWholesPerMinute variable."""
        node['tempoWholesPerMinute'] = ly.dom.Scheme(self.schemeMidiTempo())

    def schemeMidiTempo(self):
        """Returns a string with the tempo like '(ly:make-moment 100 4)' from the settings."""
        base, mul = midiDurations[self.metronomeNote.currentIndex()]
        val = int(self.metronomeValue.currentText() or '60') * mul
        return "(ly:make-moment {0} {1})".format(val, base)

    def lySimpleMidiTempo(self, node):
        r"""Return a simple \tempo x=y node for the currently set tempo."""
        dur = durations[self.metronomeNote.currentIndex()]
        val = self.metronomeValue.currentText() or '60'
        return ly.dom.Tempo(dur, val, node)
class FluidPropertyInterrogatorPlugin(QtWidgets.QWidget):
    """
    Fluid property interrogator GUI
    """

    SINGLE_PHASE = 1
    TWO_PHASE = 2
    TWO_PHASE_NCG = 3

    def __init__(self, **kwargs):
        super(FluidPropertyInterrogatorPlugin, self).__init__(**kwargs)

        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

        self.layoutMain = QVBoxLayout(self)

        self.ctlFPType = QComboBox(self)
        self.layoutMain.addWidget(self.ctlFPType)

        self.layoutFPParams = QStackedLayout()
        self.ctlSinglePhaseWidget = self.setupSinglePhaseUI(self.layoutFPParams)
        self.ctlTwoPhaseWidget = self.setupTwoPhaseUI(self.layoutFPParams)
        self.layoutFPParams.addWidget(self.ctlSinglePhaseWidget)
        self.layoutFPParams.addWidget(self.ctlTwoPhaseWidget)
        self.layoutMain.addLayout(self.layoutFPParams)

        self.ctlFPType.currentIndexChanged.connect(self.onFluidPropertyChanged)

    def setupSinglePhaseUI(self, layout):
        widget = QTabWidget(self)
        widget.addTab(FluidPropertyWidget1PhasePT(self), "p, T")
        widget.addTab(FluidPropertyWidget1PhaseRhoE(self), "rho, e")
        widget.addTab(FluidPropertyWidget1PhaseRhoP(self), "rho, p")
        return widget

    def setupTwoPhaseUI(self, layout):
        widget = QTabWidget(self)
        widget.addTab(FluidPropertyWidget2PhaseP(self), "p")
        widget.addTab(FluidPropertyWidget2PhaseT(self), "T")
        return widget

    def fillFluidProperties(self):
        """
        Fill the combo box with single phase fluid property classes
        """

        fp_classes = [
            {
                'name': 'Single phase',
                'classes': [],
                'data': self.SINGLE_PHASE
            },
            {
                'name': 'Two phase',
                'classes': [],
                'data': self.TWO_PHASE
            }
        ]

        json_fps = self.exe_info.json_data.json_data["blocks"]['Modules']['subblocks']['FluidProperties']['star']['subblock_types']

        for class_name, vals in json_fps.items():
            params = vals['parameters']
            if 'fp_type' in params:
                fp_type = params['fp_type']['default']
                if fp_type == 'single-phase-fp':
                    fp_classes[0]['classes'].append(class_name)
                elif fp_type == 'two-phase-fp':
                    fp_classes[1]['classes'].append(class_name)

        for fpc in fp_classes:
            fpc['classes'].sort()

        sep_indices = []
        model = QStandardItemModel()
        for fpc in fp_classes:
            parent = QStandardItem(fpc['name'])
            parent.setEnabled(False)
            model.appendRow(parent)
            for c in fpc['classes']:
                item = QStandardItem(c)
                item.setData(fpc['data'])
                model.appendRow(item)
            sep_indices.append(model.rowCount())

        self.ctlFPType.setModel(model)
        for idx in sep_indices[:-1]:
            self.ctlFPType.insertSeparator(idx)

    def onFluidPropertyChanged(self, index):
        fp_type = self.ctlFPType.model().item(index).data()
        if fp_type == self.SINGLE_PHASE:
            self.layoutFPParams.setCurrentWidget(self.ctlSinglePhaseWidget)
            self.ctlSinglePhaseWidget.currentWidget().updateWidgets()
        elif fp_type == self.TWO_PHASE:
            self.layoutFPParams.setCurrentWidget(self.ctlTwoPhaseWidget)
            self.ctlTwoPhaseWidget.currentWidget().updateWidgets()
        else:
            raise SystemExit("Unknown fp_type")

    def fluidPropertyInputFileBlock(self):
        str = ""
        str += "[./fp]\n"
        str += "type = {}\n".format(self.ctlFPType.currentText())
        str += "[../]\n"
        return str

    def setExecutablePath(self, exe_path):
        self.exe_path = exe_path
        self.exe_info = ExecutableInfo()
        self.exe_info.setPath(self.exe_path)
        self.fillFluidProperties()

        for tab in range(self.ctlSinglePhaseWidget.count()):
            self.ctlSinglePhaseWidget.widget(tab).setExecutablePath(exe_path)
        for tab in range(self.ctlTwoPhaseWidget.count()):
            self.ctlTwoPhaseWidget.widget(tab).setExecutablePath(exe_path)
Esempio n. 19
0
class InstrumentNames(QGroupBox):
    def __init__(self, parent):
        super(InstrumentNames, self).__init__(parent, checkable=True, checked=True)

        grid = QGridLayout()
        self.setLayout(grid)

        self.firstSystemLabel = QLabel()
        self.firstSystem = QComboBox()
        self.firstSystemLabel.setBuddy(self.firstSystem)
        self.otherSystemsLabel = QLabel()
        self.otherSystems = QComboBox()
        self.otherSystemsLabel.setBuddy(self.otherSystems)
        self.languageLabel = QLabel()
        self.language = QComboBox()
        self.languageLabel.setBuddy(self.language)

        self.firstSystem.setModel(listmodel.ListModel(
            (lambda: _("Long"), lambda: _("Short")), self.firstSystem,
            display = listmodel.translate))
        self.otherSystems.setModel(listmodel.ListModel(
            (lambda: _("Long"), lambda: _("Short"), lambda: _("None")), self.otherSystems,
            display = listmodel.translate))

        self._langs = l = ['','C']
        l.extend(sorted(po.available()))
        def display(lang):
            if lang == 'C':
                return _("English (untranslated)")
            elif not lang:
                return _("Default")
            return language_names.languageName(lang, po.setup.current())
        self.language.setModel(listmodel.ListModel(l, self.language, display=display))

        grid.addWidget(self.firstSystemLabel, 0, 0)
        grid.addWidget(self.firstSystem, 0, 1)
        grid.addWidget(self.otherSystemsLabel, 1, 0)
        grid.addWidget(self.otherSystems, 1, 1)
        grid.addWidget(self.languageLabel, 2, 0)
        grid.addWidget(self.language, 2, 1)
        app.translateUI(self)
        self.loadSettings()
        self.window().finished.connect(self.saveSettings)

    def translateUI(self):
        self.setTitle(_("Instrument names"))
        self.firstSystemLabel.setText(_("First system:"))
        self.otherSystemsLabel.setText(_("Other systems:"))
        self.languageLabel.setText(_("Language:"))
        self.firstSystem.setToolTip(_(
            "Use long or short instrument names before the first system."))
        self.otherSystems.setToolTip(_(
            "Use short, long or no instrument names before the next systems."))
        self.language.setToolTip(_(
            "Which language to use for the instrument names."))
        self.firstSystem.model().update()
        self.otherSystems.model().update()
        self.language.model().update()

    def getLanguage(self):
        """Returns the language the user has set.

        '' means:  default (use same translation as system)
        'C' means: English (untranslated)
        or a language code that is available in Frescobaldi's translation.

        """
        return self._langs[self.language.currentIndex()]

    def loadSettings(self):
        s = QSettings()
        s.beginGroup('scorewiz/instrumentnames')
        self.setChecked(s.value('enabled', True, bool))
        allow = ['long', 'short']
        first = s.value('first', '', str)
        self.firstSystem.setCurrentIndex(allow.index(first) if first in allow else 0)
        allow = ['long', 'short', 'none']
        other = s.value('other', '', str)
        self.otherSystems.setCurrentIndex(allow.index(other) if other in allow else 2)
        language = s.value('language', '', str)
        self.language.setCurrentIndex(self._langs.index(language) if language in self._langs else 0)

    def saveSettings(self):
        s = QSettings()
        s.beginGroup('scorewiz/instrumentnames')
        s.setValue('enable', self.isChecked())
        s.setValue('first', ('long', 'short')[self.firstSystem.currentIndex()])
        s.setValue('other', ('long', 'short', 'none')[self.otherSystems.currentIndex()])
        s.setValue('language', self._langs[self.language.currentIndex()])
Esempio n. 20
0
class GuiPreferencesEditor(QWidget):
    def __init__(self, theParent):
        QWidget.__init__(self, theParent)

        self.mainConf = nw.CONFIG
        self.theParent = theParent
        self.theTheme = theParent.theTheme

        # The Form
        self.mainForm = QConfigLayout()
        self.mainForm.setHelpTextStyle(self.theTheme.helpText)
        self.setLayout(self.mainForm)

        # Spell Checking
        # ==============
        self.mainForm.addGroupLabel("Spell Checking")

        ## Spell Check Provider and Language
        self.spellLangList = QComboBox(self)
        self.spellToolList = QComboBox(self)
        self.spellToolList.addItem("Internal (difflib)", nwConst.SP_INTERNAL)
        self.spellToolList.addItem("Spell Enchant (pyenchant)",
                                   nwConst.SP_ENCHANT)

        theModel = self.spellToolList.model()
        idEnchant = self.spellToolList.findData(nwConst.SP_ENCHANT)
        theModel.item(idEnchant).setEnabled(self.mainConf.hasEnchant)

        self.spellToolList.currentIndexChanged.connect(self._doUpdateSpellTool)
        toolIdx = self.spellToolList.findData(self.mainConf.spellTool)
        if toolIdx != -1:
            self.spellToolList.setCurrentIndex(toolIdx)
        self._doUpdateSpellTool(0)

        self.mainForm.addRow(
            "Spell check provider", self.spellToolList,
            "Note that the internal spell check tool is quite slow.")
        self.mainForm.addRow(
            "Spell check language", self.spellLangList,
            "Available languages are determined by your system.")

        ## Big Document Size Limit
        self.bigDocLimit = QSpinBox(self)
        self.bigDocLimit.setMinimum(10)
        self.bigDocLimit.setMaximum(10000)
        self.bigDocLimit.setSingleStep(10)
        self.bigDocLimit.setValue(self.mainConf.bigDocLimit)
        self.mainForm.addRow(
            "Big document limit",
            self.bigDocLimit,
            "Full spell checking is disabled above this limit.",
            theUnit="kB")

        # Word Count
        # ==========
        self.mainForm.addGroupLabel("Word Count")

        ## Word Count Timer
        self.wordCountTimer = QDoubleSpinBox(self)
        self.wordCountTimer.setDecimals(1)
        self.wordCountTimer.setMinimum(2.0)
        self.wordCountTimer.setMaximum(600.0)
        self.wordCountTimer.setSingleStep(0.1)
        self.wordCountTimer.setValue(self.mainConf.wordCountTimer)
        self.mainForm.addRow("Word count interval",
                             self.wordCountTimer,
                             "How often the word count is updated.",
                             theUnit="seconds")

        # Writing Guides
        # ==============
        self.mainForm.addGroupLabel("Writing Guides")

        ## Show Tabs and Spaces
        self.showTabsNSpaces = QSwitch()
        self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces)
        self.mainForm.addRow(
            "Show tabs and spaces", self.showTabsNSpaces,
            "Add symbols to indicate tabs and spaces in the editor.")

        ## Show Line Endings
        self.showLineEndings = QSwitch()
        self.showLineEndings.setChecked(self.mainConf.showLineEndings)
        self.mainForm.addRow(
            "Show line endings", self.showLineEndings,
            "Add a symbol to indicate line endings in the editor.")

        # Scroll Behaviour
        # ================
        self.mainForm.addGroupLabel("Scroll Behaviour")

        ## Scroll Past End
        self.scrollPastEnd = QSwitch()
        self.scrollPastEnd.setChecked(self.mainConf.scrollPastEnd)
        self.mainForm.addRow(
            "Scroll past end of the document", self.scrollPastEnd,
            "Also improves trypewriter scrolling for short documents.")

        ## Typewriter Scrolling
        self.autoScroll = QSwitch()
        self.autoScroll.setChecked(self.mainConf.autoScroll)
        self.mainForm.addRow(
            "Typewriter style scrolling when you type", self.autoScroll,
            "Try to keep the cursor at a fixed vertical position.")

        ## Typewriter Position
        self.autoScrollPos = QSpinBox(self)
        self.autoScrollPos.setMinimum(10)
        self.autoScrollPos.setMaximum(90)
        self.autoScrollPos.setSingleStep(1)
        self.autoScrollPos.setValue(int(self.mainConf.autoScrollPos))
        self.mainForm.addRow("Minimum position for Typewriter scrolling",
                             self.autoScrollPos,
                             "Percentage of the editor height from the top.",
                             theUnit="%")

        return

    def saveValues(self):
        """Save the values set for this tab.
        """
        # Spell Checking
        self.mainConf.spellTool = self.spellToolList.currentData()
        self.mainConf.spellLanguage = self.spellLangList.currentData()
        self.mainConf.bigDocLimit = self.bigDocLimit.value()

        # Word Count
        self.mainConf.wordCountTimer = self.wordCountTimer.value()

        # Writing Guides
        self.mainConf.showTabsNSpaces = self.showTabsNSpaces.isChecked()
        self.mainConf.showLineEndings = self.showLineEndings.isChecked()

        # Scroll Behaviour
        self.mainConf.scrollPastEnd = self.scrollPastEnd.isChecked()
        self.mainConf.autoScroll = self.autoScroll.isChecked()
        self.mainConf.autoScrollPos = self.autoScrollPos.value()

        self.mainConf.confChanged = True

        return

    ##
    #  Internal Functions
    ##

    def _doUpdateSpellTool(self, currIdx):
        """Update the list of dictionaries based on spell tool selected.
        """
        spellTool = self.spellToolList.currentData()
        self._updateLanguageList(spellTool)
        return

    def _updateLanguageList(self, spellTool):
        """Updates the list of available spell checking dictionaries
        available for the selected spell check tool. It will try to
        preserve the language choice, if the language exists in the
        updated list.
        """
        if spellTool == nwConst.SP_ENCHANT:
            theDict = NWSpellEnchant()
        else:
            theDict = NWSpellSimple()

        self.spellLangList.clear()
        for spTag, spName in theDict.listDictionaries():
            self.spellLangList.addItem(spName, spTag)

        spellIdx = self.spellLangList.findData(self.mainConf.spellLanguage)
        if spellIdx != -1:
            self.spellLangList.setCurrentIndex(spellIdx)

        return
Esempio n. 21
0
class GuiConfigEditEditingTab(QWidget):
    def __init__(self, theParent):
        QWidget.__init__(self, theParent)

        self.mainConf = nw.CONFIG
        self.theParent = theParent
        self.theTheme = theParent.theTheme

        # The Form
        self.mainForm = QConfigLayout()
        self.mainForm.setHelpTextStyle(self.theTheme.helpText)
        self.setLayout(self.mainForm)

        # Spell Checking
        # ==============
        self.mainForm.addGroupLabel("Syntax Highlighting")

        ## Syntax Highlighting
        self.selectSyntax = QComboBox()
        self.selectSyntax.setMinimumWidth(self.mainConf.pxInt(200))
        self.theSyntaxes = self.theTheme.listSyntax()
        for syntaxFile, syntaxName in self.theSyntaxes:
            self.selectSyntax.addItem(syntaxName, syntaxFile)
        syntaxIdx = self.selectSyntax.findData(self.mainConf.guiSyntax)
        if syntaxIdx != -1:
            self.selectSyntax.setCurrentIndex(syntaxIdx)

        self.mainForm.addRow(
            "Highlight theme", self.selectSyntax,
            "Colour theme to apply to the editor and viewer.")

        self.highlightQuotes = QSwitch()
        self.highlightQuotes.setChecked(self.mainConf.highlightQuotes)
        self.mainForm.addRow("Highlight text wrapped in quotes",
                             self.highlightQuotes,
                             "Applies to single, double and straight quotes.")

        self.highlightEmph = QSwitch()
        self.highlightEmph.setChecked(self.mainConf.highlightEmph)
        self.mainForm.addRow("Add highlight colour to emphasised text",
                             self.highlightEmph,
                             "Applies to emphasis, strong and strikethrough.")

        # Spell Checking
        # ==============
        self.mainForm.addGroupLabel("Spell Checking")

        ## Spell Check Provider and Language
        self.spellLangList = QComboBox(self)
        self.spellToolList = QComboBox(self)
        self.spellToolList.addItem("Internal (difflib)", nwConst.SP_INTERNAL)
        self.spellToolList.addItem("Spell Enchant (pyenchant)",
                                   nwConst.SP_ENCHANT)

        theModel = self.spellToolList.model()
        idEnchant = self.spellToolList.findData(nwConst.SP_ENCHANT)
        theModel.item(idEnchant).setEnabled(self.mainConf.hasEnchant)

        self.spellToolList.currentIndexChanged.connect(self._doUpdateSpellTool)
        toolIdx = self.spellToolList.findData(self.mainConf.spellTool)
        if toolIdx != -1:
            self.spellToolList.setCurrentIndex(toolIdx)
        self._doUpdateSpellTool(0)

        self.mainForm.addRow(
            "Spell check provider", self.spellToolList,
            "Note that the internal spell check tool is quite slow.")
        self.mainForm.addRow(
            "Spell check language", self.spellLangList,
            "Available languages are determined by your system.")

        ## Big Document Size Limit
        self.bigDocLimit = QSpinBox(self)
        self.bigDocLimit.setMinimum(10)
        self.bigDocLimit.setMaximum(10000)
        self.bigDocLimit.setSingleStep(10)
        self.bigDocLimit.setValue(self.mainConf.bigDocLimit)
        self.mainForm.addRow(
            "Big document limit",
            self.bigDocLimit,
            "Full spell checking is disabled above this limit.",
            theUnit="kB")

        # Writing Guides
        # ==============
        self.mainForm.addGroupLabel("Writing Guides")

        ## Show Tabs and Spaces
        self.showTabsNSpaces = QSwitch()
        self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces)
        self.mainForm.addRow(
            "Show tabs and spaces", self.showTabsNSpaces,
            "Add symbols to indicate tabs and spaces in the editor.")

        ## Show Line Endings
        self.showLineEndings = QSwitch()
        self.showLineEndings.setChecked(self.mainConf.showLineEndings)
        self.mainForm.addRow(
            "Show line endings", self.showLineEndings,
            "Add a symbol to indicate line endings in the editor.")

        return

    def saveValues(self):
        """Save the values set for this tab.
        """
        validEntries = True
        needsRestart = False

        guiSyntax = self.selectSyntax.currentData()
        highlightQuotes = self.highlightQuotes.isChecked()
        highlightEmph = self.highlightEmph.isChecked()
        spellTool = self.spellToolList.currentData()
        spellLanguage = self.spellLangList.currentData()
        bigDocLimit = self.bigDocLimit.value()
        showTabsNSpaces = self.showTabsNSpaces.isChecked()
        showLineEndings = self.showLineEndings.isChecked()

        self.mainConf.guiSyntax = guiSyntax
        self.mainConf.highlightQuotes = highlightQuotes
        self.mainConf.highlightEmph = highlightEmph
        self.mainConf.spellTool = spellTool
        self.mainConf.spellLanguage = spellLanguage
        self.mainConf.bigDocLimit = bigDocLimit
        self.mainConf.showTabsNSpaces = showTabsNSpaces
        self.mainConf.showLineEndings = showLineEndings

        self.mainConf.confChanged = True

        return validEntries, needsRestart

    ##
    #  Internal Functions
    ##

    def _doUpdateSpellTool(self, currIdx):
        """Update the list of dictionaries based on spell tool selected.
        """
        spellTool = self.spellToolList.currentData()
        self._updateLanguageList(spellTool)
        return

    def _updateLanguageList(self, spellTool):
        """Updates the list of available spell checking dictionaries
        available for the selected spell check tool. It will try to
        preserve the language choice, if the language exists in the
        updated list.
        """
        if spellTool == nwConst.SP_ENCHANT:
            theDict = NWSpellEnchant()
        else:
            theDict = NWSpellSimple()

        self.spellLangList.clear()
        for spTag, spName in theDict.listDictionaries():
            self.spellLangList.addItem(spName, spTag)

        spellIdx = self.spellLangList.findData(self.mainConf.spellLanguage)
        if spellIdx != -1:
            self.spellLangList.setCurrentIndex(spellIdx)

        return
class OWCSVFileImport(widget.OWWidget):
    name = "CSV File Import"
    description = "Import a data table from a CSV formatted file."
    icon = "icons/CSVFile.svg"

    outputs = [
        widget.OutputSignal(
            name="Data",
            type=Orange.data.Table,
            doc="Loaded data set."),
        widget.OutputSignal(
            name="Data Frame",
            type=pd.DataFrame,
            doc=""
        )
    ]

    class Error(widget.OWWidget.Error):
        error = widget.Msg(
            "Unexpected error"
        )
        encoding_error = widget.Msg(
            "Encoding error\n"
            "The file might be encoded in an unsupported encoding or it "
            "might be binary"
        )

    #: Paths and options of files accessed in a 'session'
    _session_items = settings.Setting(
        [], schema_only=True)  # type: List[Tuple[str, dict]]

    #: Saved dialog state (last directory and selected filter)
    dialog_state = settings.Setting({
        "directory": "",
        "filter": ""
    })  # type: Dict[str, str]
    MaxHistorySize = 50

    want_main_area = False
    buttons_area_orientation = None

    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)

        self.__committimer = QTimer(self, singleShot=True)
        self.__committimer.timeout.connect(self.commit)

        self.__executor = qconcurrent.ThreadExecutor()
        self.__watcher = None  # type: Optional[qconcurrent.FutureWatcher]

        self.controlArea.layout().setSpacing(-1)  # reset spacing
        grid = QGridLayout()
        grid.addWidget(QLabel("File:", self), 0, 0, 1, 1)

        self.import_items_model = QStandardItemModel(self)
        self.recent_combo = QComboBox(
            self, objectName="recent-combo", toolTip="Recent files.",
            sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon,
            minimumContentsLength=16,
        )
        self.recent_combo.setModel(self.import_items_model)
        self.recent_combo.activated.connect(self.activate_recent)
        self.recent_combo.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        self.browse_button = QPushButton(
            "…", icon=self.style().standardIcon(QStyle.SP_DirOpenIcon),
            toolTip="Browse filesystem", autoDefault=False,
        )
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.browse_button.clicked.connect(self.browse)
        grid.addWidget(self.recent_combo, 0, 1, 1, 1)
        grid.addWidget(self.browse_button, 0, 2, 1, 1)
        self.controlArea.layout().addLayout(grid)

        ###########
        # Info text
        ###########
        box = gui.widgetBox(self.controlArea, "Info", addSpace=False)
        self.summary_text = QTextBrowser(
            verticalScrollBarPolicy=Qt.ScrollBarAsNeeded,
            readOnly=True,
        )
        self.summary_text.viewport().setBackgroundRole(QPalette.NoRole)
        self.summary_text.setFrameStyle(QTextBrowser.NoFrame)
        self.summary_text.setMinimumHeight(self.fontMetrics().ascent() * 2 + 4)
        self.summary_text.viewport().setAutoFillBackground(False)
        box.layout().addWidget(self.summary_text)

        button_box = QDialogButtonBox(
            orientation=Qt.Horizontal,
            standardButtons=QDialogButtonBox.Cancel | QDialogButtonBox.Retry
        )
        self.load_button = b = button_box.button(QDialogButtonBox.Retry)
        b.setText("Load")
        b.clicked.connect(self.__committimer.start)
        b.setEnabled(False)
        b.setDefault(True)

        self.cancel_button = b = button_box.button(QDialogButtonBox.Cancel)
        b.clicked.connect(self.cancel)
        b.setEnabled(False)
        b.setAutoDefault(False)

        self.import_options_button = QPushButton(
            "Import Options…", enabled=False, autoDefault=False,
            clicked=self._activate_import_dialog
        )

        self.recent_combo.currentIndexChanged.connect(
            lambda idx:
                self.import_options_button.setEnabled(idx != -1) or
                self.load_button.setEnabled(idx != -1)
        )
        button_box.addButton(
            self.import_options_button, QDialogButtonBox.ActionRole
        )
        button_box.setStyleSheet(
            "button-layout: {:d};".format(QDialogButtonBox.MacLayout)
        )
        self.controlArea.layout().addWidget(button_box)

        self._restoreState()
        if self.current_item() is not None:
            self._invalidate()
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)

    @Slot(int)
    def activate_recent(self, index):
        """
        Activate an item from the recent list.
        """
        if 0 <= index < self.import_items_model.rowCount():
            item = self.import_items_model.item(index)
            assert item is not None
            path = item.data(ImportItem.PathRole)
            opts = item.data(ImportItem.OptionsRole)
            if not isinstance(opts, Options):
                opts = None
            self.set_selected_file(path, opts)
        else:
            self.recent_combo.setCurrentIndex(-1)

    @Slot()
    def browse(self):
        """
        Open a file dialog and select a user specified file.
        """
        formats = [
            "Text - comma separated (*.csv, *)",
            "Text - tab separated (*.tsv, *)",
            "Text - all files (*)"
        ]

        dlg = QFileDialog(
            self, windowTitle="Open Data File",
            acceptMode=QFileDialog.AcceptOpen,
            fileMode=QFileDialog.ExistingFile
        )
        dlg.setNameFilters(formats)
        state = self.dialog_state
        lastdir = state.get("directory", "")
        lastfilter = state.get("filter", "")

        if lastdir and os.path.isdir(lastdir):
            dlg.setDirectory(lastdir)
        if lastfilter:
            dlg.selectNameFilter(lastfilter)

        status = dlg.exec_()
        dlg.deleteLater()
        if status == QFileDialog.Accepted:
            self.dialog_state["directory"] = dlg.directory().absolutePath()
            self.dialog_state["filter"] = dlg.selectedNameFilter()

            selected_filter = dlg.selectedNameFilter()
            path = dlg.selectedFiles()[0]
            # pre-flight check; try to determine the nature of the file
            mtype = _mime_type_for_path(path)
            if not mtype.inherits("text/plain"):
                mb = QMessageBox(
                    parent=self,
                    windowTitle="",
                    icon=QMessageBox.Question,
                    text="The '{basename}' may be a binary file.\n"
                         "Are you sure you want to continue?".format(
                            basename=os.path.basename(path)),
                    standardButtons=QMessageBox.Cancel | QMessageBox.Yes
                )
                mb.setWindowModality(Qt.WindowModal)
                if mb.exec() == QMessageBox.Cancel:
                    return

            # initialize dialect based on selected extension
            if selected_filter in formats[:-1]:
                filter_idx = formats.index(selected_filter)
                if filter_idx == 0:
                    dialect = csv.excel()
                elif filter_idx == 1:
                    dialect = csv.excel_tab()
                else:
                    dialect = csv.excel_tab()
                header = True
            else:
                try:
                    dialect, header = sniff_csv_with_path(path)
                except Exception:
                    dialect, header = csv.excel(), True

            options = None
            # Search for path in history.
            # If found use the stored params to initialize the import dialog
            items = self.itemsFromSettings()
            idx = index_where(items, lambda t: samepath(t[0], path))
            if idx is not None:
                _, options_ = items[idx]
                if options_ is not None:
                    options = options_

            if options is None:
                if not header:
                    rowspec = []
                else:
                    rowspec = [(range(0, 1), RowSpec.Header)]
                options = Options(
                    encoding="utf-8", dialect=dialect, rowspec=rowspec)

            dlg = CSVImportDialog(
                self, windowTitle="Import Options",  sizeGripEnabled=True)
            dlg.setWindowModality(Qt.WindowModal)
            dlg.setPath(path)
            dlg.setOptions(options)
            status = dlg.exec_()
            dlg.deleteLater()
            if status == QDialog.Accepted:
                self.set_selected_file(path, dlg.options())

    def current_item(self):
        # type: () -> Optional[ImportItem]
        """
        Return the current selected item (file) or None if there is no
        current item.
        """
        idx = self.recent_combo.currentIndex()
        if idx == -1:
            return None

        item = self.recent_combo.model().item(idx)  # type: QStandardItem
        if isinstance(item, ImportItem):
            return item
        else:
            return None

    def _activate_import_dialog(self):
        """Activate the Import Options dialog for the  current item."""
        item = self.current_item()
        assert item is not None
        dlg = CSVImportDialog(
            self, windowTitle="Import Options", sizeGripEnabled=True,
        )
        dlg.setWindowModality(Qt.WindowModal)
        dlg.setAttribute(Qt.WA_DeleteOnClose)
        settings = QSettings()
        qualname = qname(type(self))
        settings.beginGroup(qualname)
        size = settings.value("size", QSize(), type=QSize)  # type: QSize
        if size.isValid():
            dlg.resize(size)

        path = item.data(ImportItem.PathRole)
        options = item.data(ImportItem.OptionsRole)
        dlg.setPath(path)  # Set path before options so column types can
        if isinstance(options, Options):
            dlg.setOptions(options)

        def update():
            newoptions = dlg.options()
            item.setData(newoptions, ImportItem.OptionsRole)
            # update the stored item
            self._add_recent(path, newoptions)
            if newoptions != options:
                self._invalidate()
        dlg.accepted.connect(update)

        def store_size():
            settings.setValue("size", dlg.size())
        dlg.finished.connect(store_size)
        dlg.show()

    def set_selected_file(self, filename, options=None):
        """
        Set the current selected filename path.
        """
        self._add_recent(filename, options)
        self._invalidate()

    #: Saved options for a filename
    SCHEMA = {
        "path": str,  # Local filesystem path
        "options": str,  # json encoded 'Options'
    }

    @classmethod
    def _local_settings(cls):
        # type: () -> QSettings
        """Return a QSettings instance with local persistent settings."""
        filename = "{}.ini".format(qname(cls))
        fname = os.path.join(settings.widget_settings_dir(), filename)
        return QSettings(fname, QSettings.IniFormat)

    def _add_recent(self, filename, options=None):
        # type: (str, Optional[Options]) -> None
        """
        Add filename to the list of recent files.
        """
        model = self.import_items_model
        index = index_where(
            (model.index(i, 0).data(ImportItem.PathRole)
             for i in range(model.rowCount())),
            lambda path: isinstance(path, str) and samepath(path, filename)
        )
        if index is not None:
            item, *_ = model.takeRow(index)
        else:
            item = ImportItem.fromPath(filename)

        model.insertRow(0, item)

        if options is not None:
            item.setOptions(options)

        self.recent_combo.setCurrentIndex(0)
        # store items to local persistent settings
        s = self._local_settings()
        arr = QSettings_readArray(s, "recent", OWCSVFileImport.SCHEMA)
        item = {"path": filename}
        if options is not None:
            item["options"] = json.dumps(options.as_dict())

        arr = [item for item in arr if item.get("path") != filename]
        arr.append(item)
        QSettings_writeArray(s, "recent", arr)

        # update workflow session items
        items = self._session_items[:]
        idx = index_where(items, lambda t: samepath(t[0], filename))
        if idx is not None:
            del items[idx]
        items.insert(0, (filename, options.as_dict()))
        self._session_items = items[:OWCSVFileImport.MaxHistorySize]

    def _invalidate(self):
        # Invalidate the current output and schedule a new commit call.
        # (NOTE: The widget enters a blocking state)
        self.__committimer.start()
        if self.__watcher is not None:
            self.__cancel_task()
        self.setBlocking(True)

    def commit(self):
        """
        Commit the current state and submit the load task for execution.

        Note
        ----
        Any existing pending task is canceled.
        """
        self.__committimer.stop()
        if self.__watcher is not None:
            self.__cancel_task()
        self.error()

        item = self.current_item()
        if item is None:
            return
        path = item.data(ImportItem.PathRole)
        opts = item.data(ImportItem.OptionsRole)
        if not isinstance(opts, Options):
            return

        task = state = TaskState()
        state.future = ...
        state.watcher = qconcurrent.FutureWatcher()
        state.progressChanged.connect(self.__set_read_progress,
                                      Qt.QueuedConnection)

        def progress_(i, j):
            task.emitProgressChangedOrCancel(i, j)

        task.future = self.__executor.submit(
            clear_stack_on_cancel(load_csv),
            path, opts, progress_,
        )
        task.watcher.setFuture(task.future)
        w = task.watcher
        w.done.connect(self.__handle_result)
        w.progress = state
        self.__watcher = w
        self.__set_running_state()

    @Slot('qint64', 'qint64')
    def __set_read_progress(self, read, count):
        if count > 0:
            self.progressBarSet(100 * read / count)

    def __cancel_task(self):
        # Cancel and dispose of the current task
        assert self.__watcher is not None
        w = self.__watcher
        w.future().cancel()
        w.progress.cancel = True
        w.done.disconnect(self.__handle_result)
        w.progress.progressChanged.disconnect(self.__set_read_progress)
        w.progress.deleteLater()
        # wait until completion
        futures.wait([w.future()])
        self.__watcher = None

    def cancel(self):
        """
        Cancel current pending or executing task.
        """
        if self.__watcher is not None:
            self.__cancel_task()
            self.__clear_running_state()
            self.setStatusMessage("Cancelled")
            self.summary_text.setText(
                "<div>Cancelled<br/><small>Press 'Reload' to try again</small></div>"
            )

    def __set_running_state(self):
        self.progressBarInit()
        self.setBlocking(True)
        self.setStatusMessage("Running")
        self.cancel_button.setEnabled(True)
        self.load_button.setText("Restart")
        path = self.current_item().path()
        self.Error.clear()
        self.summary_text.setText(
            "<div>Loading: <i>{}</i><br/>".format(prettyfypath(path))
        )

    def __clear_running_state(self, ):
        self.progressBarFinished()
        self.setStatusMessage("")
        self.setBlocking(False)
        self.cancel_button.setEnabled(False)
        self.load_button.setText("Reload")

    def __set_error_state(self, err):
        self.Error.clear()
        if isinstance(err, UnicodeDecodeError):
            self.Error.encoding_error(exc_info=err)
        else:
            self.Error.error(exc_info=err)

        path = self.current_item().path()
        basename = os.path.basename(path)
        if isinstance(err, UnicodeDecodeError):
            text = (
                "<div><i>{basename}</i> was not loaded due to a text encoding "
                "error. The file might be saved in an unknown or invalid "
                "encoding, or it might be a binary file.</div>"
            ).format(
                basename=escape(basename)
            )
        else:
            text = (
                "<div><i>{basename}</i> was not loaded due to an error:"
                "<p style='white-space: pre;'>{err}</p>"
            ).format(
                basename=escape(basename),
                err="".join(traceback.format_exception_only(type(err), err))
            )
        self.summary_text.setText(text)

    def __clear_error_state(self):
        self.Error.error.clear()
        self.summary_text.setText("")

    def onDeleteWidget(self):
        """Reimplemented."""
        if self.__watcher is not None:
            self.__cancel_task()
            self.__executor.shutdown()
        super().onDeleteWidget()

    @Slot(object)
    def __handle_result(self, f):
        # type: (qconcurrent.Future[pd.DataFrame]) -> None
        assert f.done()
        assert f is self.__watcher.future()
        self.__watcher = None
        self.__clear_running_state()

        try:
            df = f.result()
            assert isinstance(df, pd.DataFrame)
        except pd.errors.EmptyDataError:
            df = pd.DataFrame({})
        except Exception as e:  # pylint: disable=broad-except
            self.__set_error_state(e)
            df = None
        else:
            self.__clear_error_state()

        if df is not None:
            table = pandas_to_table(df)
        else:
            table = None
        self.send("Data Frame", df)
        self.send('Data', table)
        self._update_status_messages(table)

    def _update_status_messages(self, data):
        if data is None:
            return

        def pluralize(seq):
            return "s" if len(seq) != 1 else ""

        summary = ("{n_instances} row{plural_1}, "
                   "{n_features} feature{plural_2}, "
                   "{n_meta} meta{plural_3}").format(
                        n_instances=len(data), plural_1=pluralize(data),
                        n_features=len(data.domain.attributes),
                        plural_2=pluralize(data.domain.attributes),
                        n_meta=len(data.domain.metas),
                        plural_3=pluralize(data.domain.metas))
        self.summary_text.setText(summary)

    def itemsFromSettings(self):
        # type: () -> List[Tuple[str, Options]]
        """
        Return items from local history.
        """
        s = self._local_settings()
        items_ = QSettings_readArray(s, "recent", OWCSVFileImport.SCHEMA)
        items = []  # type: List[Tuple[str, Options]]
        for item in items_:
            path = item.get("path", "")
            if not path:
                continue
            opts_json = item.get("options", "")
            try:
                opts = Options.from_dict(json.loads(opts_json))
            except (csv.Error, LookupError, TypeError, json.JSONDecodeError):
                _log.error("Could not reconstruct options for '%s'", path,
                           exc_info=True)
                pass
            else:
                items.append((path, opts))
        return items[::-1]

    def _restoreState(self):
        # Restore the state. Merge session (workflow) items with the
        # local history.
        model = self.import_items_model
        # local history
        items = self.itemsFromSettings()
        # stored session items
        sitems = []
        for p, m in self._session_items:
            try:
                item_ = (p, Options.from_dict(m))
            except (csv.Error, LookupError) as e:
                # Is it better to fail then to lose a item slot?
                _log.error("Failed to restore '%s'", p, exc_info=True)
            else:
                sitems.append(item_)

        items = sitems + items
        items = unique(items, key=lambda t: pathnormalize(t[0]))

        curr = self.recent_combo.currentIndex()
        if curr != -1:
            currentpath = self.recent_combo.currentData(ImportItem.PathRole)
        else:
            currentpath = None
        for path, options in items:
            item = ImportItem.fromPath(path)
            item.setOptions(options)
            model.appendRow(item)

        if currentpath is not None:
            idx = self.recent_combo.findData(currentpath, ImportItem.PathRole)
            if idx != -1:
                self.recent_combo.setCurrentIndex(idx)
Esempio n. 23
0
def run_iface_config_window(icon):
    ifaces = list_ifaces()

    win = QDialog()
    win.setWindowTitle('CAN Interface Configuration')
    win.setWindowIcon(icon)
    win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint)

    combo = QComboBox(win)
    combo.setEditable(True)
    combo.setInsertPolicy(QComboBox.NoInsert)
    combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    combo.addItems(ifaces.keys())

    combo_completer = QCompleter()
    combo_completer.setCaseSensitivity(Qt.CaseSensitive)
    combo_completer.setModel(combo.model())
    combo.setCompleter(combo_completer)

    bitrate = QSpinBox()
    bitrate.setMaximum(1000000)
    bitrate.setMinimum(10000)
    bitrate.setValue(1000000)

    extra_args = QLineEdit()
    extra_args.setFont(get_monospace_font())

    ok = QPushButton('OK', win)

    result = None
    kwargs = {}

    def on_ok():
        nonlocal result, kwargs
        a = str(extra_args.text())
        if a:
            try:
                kwargs = dict(eval(a))
            except Exception as ex:
                show_error('Invalid parameters', 'Could not parse optional arguments', ex, parent=win)
                return
        kwargs['bitrate'] = int(bitrate.value())
        result_key = str(combo.currentText()).strip()
        try:
            result = ifaces[result_key]
        except KeyError:
            result = result_key
        win.close()

    ok.clicked.connect(on_ok)

    layout = QVBoxLayout()
    layout.addWidget(QLabel('Select CAN interface or serial port for SLCAN:'))
    layout.addWidget(combo)
    layout.addWidget(QLabel('Interface bitrate (SLCAN only):'))
    layout.addWidget(bitrate)
    layout.addWidget(QLabel('Optional arguments (refer to Pyuavcan for info):'))
    layout.addWidget(extra_args)
    layout.addWidget(ok)
    layout.setSizeConstraint(layout.SetFixedSize)
    win.setLayout(layout)
    win.exec()

    return result, kwargs
Esempio n. 24
0
class Choir(VocalPart):
    @staticmethod
    def title(_=_base.translate):
        return _("Choir")

    def createWidgets(self, layout):
        self.label = QLabel(wordWrap=True)
        self.voicingLabel = QLabel()
        self.voicing = QComboBox(editable=True)
        self.voicingLabel.setBuddy(self.voicing)
        self.voicing.setCompleter(None)
        self.voicing.setValidator(QRegExpValidator(
            QRegExp("[SATB]+(-[SATB]+)*", Qt.CaseInsensitive), self.voicing))
        self.voicing.addItems((
            'SA-TB', 'S-A-T-B',
            'SA', 'S-A', 'SS-A', 'S-S-A',
            'TB', 'T-B', 'TT-B', 'T-T-B',
            'SS-A-T-B', 'S-A-TT-B', 'SS-A-TT-B',
            'S-S-A-T-T-B', 'S-S-A-A-T-T-B-B',
            ))
        self.lyricsLabel = QLabel()
        self.lyrics = QComboBox()
        self.lyricsLabel.setBuddy(self.lyrics)
        self.lyrics.setModel(listmodel.ListModel(lyricStyles, self.lyrics,
            display=listmodel.translate_index(0),
            tooltip=listmodel.translate_index(1)))
        self.lyrics.setCurrentIndex(0)
        self.pianoReduction = QCheckBox()
        self.rehearsalMidi = QCheckBox()

        layout.addWidget(self.label)
        box = QHBoxLayout()
        layout.addLayout(box)
        box.addWidget(self.voicingLabel)
        box.addWidget(self.voicing)
        self.createStanzaWidget(layout)
        box = QHBoxLayout()
        layout.addLayout(box)
        box.addWidget(self.lyricsLabel)
        box.addWidget(self.lyrics)
        self.createAmbitusWidget(layout)
        layout.addWidget(self.pianoReduction)
        layout.addWidget(self.rehearsalMidi)

    def translateWidgets(self):
        self.translateStanzaWidget()
        self.translateAmbitusWidget()
        self.lyrics.model().update()
        self.label.setText('<p>{0} <i>({1})</i></p>'.format(
            _("Please select the voices for the choir. "
              "Use the letters S, A, T, or B. A hyphen denotes a new staff."),
            _("Hint: For a double choir you can use two choir parts.")))
        self.voicingLabel.setText(_("Voicing:"))
        self.lyricsLabel.setText(_("Lyrics:"))
        self.pianoReduction.setText(_("Piano reduction"))
        self.pianoReduction.setToolTip(_(
            "Adds an automatically generated piano reduction."))
        self.rehearsalMidi.setText(_("Rehearsal MIDI files"))
        self.rehearsalMidi.setToolTip(_(
            "Creates a rehearsal MIDI file for every voice, "
            "even if no MIDI output is generated for the main score."))

    def build(self, data, builder):
        # normalize voicing
        staves = self.voicing.currentText().upper()
        # remove unwanted characters
        staves = re.sub(r'[^SATB-]+', '', staves)
        # remove double hyphens, and from begin and end
        staves = re.sub('-+', '-', staves).strip('-')
        if not staves:
            return

        splitStaves = staves.split('-')
        numStaves = len(splitStaves)
        staffCIDs = collections.defaultdict(int)    # number same-name staff Context-IDs
        voiceCounter = collections.defaultdict(int) # dict to number same voice types
        maxNumVoices = max(map(len, splitStaves))   # largest number of voices
        numStanzas = self.stanzas.value()
        lyrics = collections.defaultdict(list)      # lyrics grouped by stanza number
        pianoReduction = collections.defaultdict(list)
        rehearsalMidis = []

        p = ly.dom.ChoirStaff()
        choir = ly.dom.Sim(p)
        data.nodes.append(p)

        # print main instrumentName if there are more choirs, and we
        # have more than one staff.
        if numStaves > 1 and data.num:
            builder.setInstrumentNames(p,
                builder.instrumentName(lambda _: _("Choir"), data.num),
                builder.instrumentName(lambda _: _("abbreviation for Choir", "Ch."), data.num))

        # get the preferred way of adding lyrics
        lyrAllSame, lyrEachSame, lyrEachDiff, lyrSpread = (
            self.lyrics.currentIndex() == i for i in range(4))
        lyrEach = lyrEachSame or lyrEachDiff

        # stanzas to print (0 = don't print stanza number):
        if numStanzas == 1:
            allStanzas = [0]
        else:
            allStanzas = list(range(1, numStanzas + 1))

        # Which stanzas to print where:
        if lyrSpread and numStanzas > 1 and numStaves > 2:
            spaces = numStaves - 1
            count, rest = divmod(max(numStanzas, spaces), spaces)
            stanzaSource = itertools.cycle(allStanzas)
            stanzaGroups = (itertools.islice(stanzaSource, num)
                            for num in itertools.chain(
                                itertools.repeat(count + 1, rest),
                                itertools.repeat(count, numStaves - rest)))
        else:
            stanzaGroups = itertools.repeat(allStanzas, numStaves)

        # a function to set staff affinity (in LilyPond 2.13.4 and above):
        if builder.lyVersion >= (2, 13, 4):
            def setStaffAffinity(context, affinity):
                ly.dom.Line("\\override VerticalAxisGroup "
                     "#'staff-affinity = #" + affinity, context.getWith())
        else:
            def setStaffAffinity(lyricsContext, affinity):
                pass

        # a function to make a column markup:
        if builder.lyVersion >= (2, 11, 57):
            columnCommand = 'center-column'
        else:
            columnCommand = 'center-align'
        def makeColumnMarkup(names):
            node = ly.dom.Markup()
            column = ly.dom.MarkupEnclosed(columnCommand, node)
            for name in names:
                ly.dom.QuotedString(name, column)
            return node

        stavesLeft = numStaves
        for staff, stanzas in zip(splitStaves, stanzaGroups):
            # are we in the last staff?
            stavesLeft -= 1
            # the number of voices in this staff
            numVoices = len(staff)
            # sort the letters in order SATB
            staff = ''.join(i * staff.count(i) for i in 'SATB')
            # Create the staff for the voices
            s = ly.dom.Staff(parent=choir)
            builder.setMidiInstrument(s, self.midiInstrument)

            # Build a list of the voices in this staff.
            # Each entry is a tuple(name, num).
            # name is one of 'S', 'A', 'T', or 'B'
            # num is an integer: 0 when a voice occurs only once, or >= 1 when
            # there are more voices of the same type (e.g. Soprano I and II)
            voices = []
            for voice in staff:
                if staves.count(voice) > 1:
                    voiceCounter[voice] += 1
                voices.append((voice, voiceCounter[voice]))

            # Add the instrument names to the staff:
            if numVoices == 1:
                voice, num = voices[0]
                longName = builder.instrumentName(voice2Voice[voice].title, num)
                shortName = builder.instrumentName(voice2Voice[voice].short, num)
                builder.setInstrumentNames(s, longName, shortName)
            else:
                # stack instrument names (long and short) in a markup column.
                # long names
                longNames = makeColumnMarkup(
                    builder.instrumentName(voice2Voice[voice].title, num) for voice, num in voices)
                shortNames = makeColumnMarkup(
                    builder.instrumentName(voice2Voice[voice].short, num) for voice, num in voices)
                builder.setInstrumentNames(s, longNames, shortNames)

            # Make the { } or << >> holder for this staff's children.
            # If *all* staves have only one voice, addlyrics is used.
            # In that case, don't remove the braces.
            staffMusic = (ly.dom.Seq if lyrEach and maxNumVoices == 1 else
                          ly.dom.Seqr if numVoices == 1 else ly.dom.Simr)(s)

            # Set the clef for this staff:
            if 'B' in staff:
                ly.dom.Clef('bass', staffMusic)
            elif 'T' in staff:
                ly.dom.Clef('treble_8', staffMusic)

            # Determine voice order (\voiceOne, \voiceTwo etc.)
            if numVoices == 1:
                order = (0,)
            elif numVoices == 2:
                order = 1, 2
            elif staff in ('SSA', 'TTB'):
                order = 1, 3, 2
            elif staff in ('SAA', 'TBB'):
                order = 1, 2, 4
            elif staff in ('SSAA', 'TTBB'):
                order = 1, 3, 2, 4
            else:
                order = range(1, numVoices + 1)

            # What name would the staff get if we need to refer to it?
            # If a name (like 's' or 'sa') is already in use in this part,
            # just add a number ('ss2' or 'sa2', etc.)
            staffCIDs[staff] += 1
            cid = ly.dom.Reference(staff.lower() +
                str(staffCIDs[staff] if staffCIDs[staff] > 1 else ""))

            # Create voices and their lyrics:
            for (voice, num), voiceNum in zip(voices, order):
                name = voice2id[voice]
                if num:
                    name += ly.util.int2text(num)
                a = data.assignMusic(name, voice2Voice[voice].octave)
                lyrName = name + 'Verse' if lyrEachDiff else 'verse'

                # Use \addlyrics if all staves have exactly one voice.
                if lyrEach and maxNumVoices == 1:
                    for verse in stanzas:
                        lyrics[verse].append((ly.dom.AddLyrics(s), lyrName))
                    ly.dom.Identifier(a.name, staffMusic)
                else:
                    voiceName = voice2id[voice] + str(num or '')
                    v = ly.dom.Voice(voiceName, parent=staffMusic)
                    voiceMusic = ly.dom.Seqr(v)
                    if voiceNum:
                        ly.dom.Text('\\voice' + ly.util.int2text(voiceNum), voiceMusic)
                    ly.dom.Identifier(a.name, voiceMusic)

                    if stanzas and (lyrEach or (voiceNum <= 1 and
                                    (stavesLeft or numStaves == 1))):
                        # Create the lyrics. If they should be above the staff,
                        # give the staff a suitable name, and use alignAbove-
                        # Context to align the Lyrics above the staff.
                        above = voiceNum & 1 if lyrEach else False
                        if above and s.cid is None:
                            s.cid = cid

                        for verse in stanzas:
                            l = ly.dom.Lyrics(parent=choir)
                            if above:
                                l.getWith()['alignAboveContext'] = cid
                                setStaffAffinity(l, "DOWN")
                            elif not lyrEach and stavesLeft:
                                setStaffAffinity(l, "CENTER")
                            lyrics[verse].append((ly.dom.LyricsTo(voiceName, l), lyrName))

                # Add ambitus:
                if self.ambitus.isChecked():
                    ambitusContext = (s if numVoices == 1 else v).getWith()
                    ly.dom.Line('\\consists "Ambitus_engraver"', ambitusContext)
                    if voiceNum > 1:
                        ly.dom.Line("\\override Ambitus #'X-offset = #{0}".format(
                                 (voiceNum - 1) * 2.0), ambitusContext)

                pianoReduction[voice].append(a.name)
                rehearsalMidis.append((voice, num, a.name, lyrName))

        # Assign the lyrics, so their definitions come after the note defs.
        # (These refs are used again below in the midi rehearsal routine.)
        refs = {}
        for verse in allStanzas:
            for node, name in lyrics[verse]:
                if (name, verse) not in refs:
                    refs[(name, verse)] = self.assignLyrics(data, name, verse).name
                ly.dom.Identifier(refs[(name, verse)], node)

        # Create the piano reduction if desired
        if self.pianoReduction.isChecked():
            a = data.assign('pianoReduction')
            data.nodes.append(ly.dom.Identifier(a.name))
            piano = ly.dom.PianoStaff(parent=a)

            sim = ly.dom.Sim(piano)
            rightStaff = ly.dom.Staff(parent=sim)
            leftStaff = ly.dom.Staff(parent=sim)
            right = ly.dom.Seq(rightStaff)
            left = ly.dom.Seq(leftStaff)

            # Determine the ordering of voices in the staves
            upper = pianoReduction['S'] + pianoReduction['A']
            lower = pianoReduction['T'] + pianoReduction['B']

            preferUpper = 1
            if not upper:
                # Male choir
                upper = pianoReduction['T']
                lower = pianoReduction['B']
                ly.dom.Clef("treble_8", right)
                ly.dom.Clef("bass", left)
                preferUpper = 0
            elif not lower:
                # Female choir
                upper = pianoReduction['S']
                lower = pianoReduction['A']
            else:
                ly.dom.Clef("bass", left)

            # Otherwise accidentals can be confusing
            ly.dom.Line("#(set-accidental-style 'piano)", right)
            ly.dom.Line("#(set-accidental-style 'piano)", left)

            # Move voices if unevenly spread
            if abs(len(upper) - len(lower)) > 1:
                voices = upper + lower
                half = (len(voices) + preferUpper) // 2
                upper = voices[:half]
                lower = voices[half:]

            for staff, voices in (ly.dom.Simr(right), upper), (ly.dom.Simr(left), lower):
                if voices:
                    for v in voices[:-1]:
                        ly.dom.Identifier(v, staff)
                        ly.dom.VoiceSeparator(staff).after = 1
                    ly.dom.Identifier(voices[-1], staff)

            # Make the piano part somewhat smaller
            ly.dom.Line("fontSize = #-1", piano.getWith())
            ly.dom.Line("\\override StaffSymbol #'staff-space = #(magstep -1)",
                piano.getWith())

            # Nice to add Mark engravers
            ly.dom.Line('\\consists "Mark_engraver"', rightStaff.getWith())
            ly.dom.Line('\\consists "Metronome_mark_engraver"', rightStaff.getWith())

            # Keep piano reduction out of the MIDI output
            if builder.midi:
                ly.dom.Line('\\remove "Staff_performer"', rightStaff.getWith())
                ly.dom.Line('\\remove "Staff_performer"', leftStaff.getWith())

        # Create MIDI files if desired
        if self.rehearsalMidi.isChecked():
            a = data.assign('rehearsalMidi')
            rehearsalMidi = a.name

            func = ly.dom.SchemeList(a)
            func.pre = '#\n(' # hack
            ly.dom.Text('define-music-function', func)
            ly.dom.Line('(parser location name midiInstrument lyrics) '
                 '(string? string? ly:music?)', func)
            choir = ly.dom.Sim(ly.dom.Command('unfoldRepeats', ly.dom.SchemeLily(func)))

            data.afterblocks.append(ly.dom.Comment(_("Rehearsal MIDI files:")))

            for voice, num, ref, lyrName in rehearsalMidis:
                # Append voice to the rehearsalMidi function
                name = voice2id[voice] + str(num or '')
                seq = ly.dom.Seq(ly.dom.Voice(name, parent=ly.dom.Staff(name, parent=choir)))
                if builder.lyVersion < (2, 18, 0):
                    ly.dom.Text('<>\\f', seq) # add one dynamic
                ly.dom.Identifier(ref, seq) # add the reference to the voice

                book = ly.dom.Book()

                # Append score to the aftermath (stuff put below the main score)
                suffix = "choir{0}-{1}".format(data.num, name) if data.num else name
                if builder.lyVersion < (2, 12, 0):
                    data.afterblocks.append(
                        ly.dom.Line('#(define output-suffix "{0}")'.format(suffix)))
                else:
                    ly.dom.Line('\\bookOutputSuffix "{0}"'.format(suffix), book)
                data.afterblocks.append(book)
                data.afterblocks.append(ly.dom.BlankLine())
                score = ly.dom.Score(book)

                # TODO: make configurable
                midiInstrument = voice2Midi[voice]

                cmd = ly.dom.Command(rehearsalMidi, score)
                ly.dom.QuotedString(name, cmd)
                ly.dom.QuotedString(midiInstrument, cmd)
                ly.dom.Identifier(refs[(lyrName, allStanzas[0])], cmd)
                ly.dom.Midi(score)

            ly.dom.Text("\\context Staff = $name", choir)
            seq = ly.dom.Seq(choir)
            ly.dom.Line("\\set Score.midiMinimumVolume = #0.5", seq)
            ly.dom.Line("\\set Score.midiMaximumVolume = #0.5", seq)
            ly.dom.Line("\\set Score.tempoWholesPerMinute = #" + data.scoreProperties.schemeMidiTempo(), seq)
            ly.dom.Line("\\set Staff.midiMinimumVolume = #0.8", seq)
            ly.dom.Line("\\set Staff.midiMaximumVolume = #1.0", seq)
            ly.dom.Line("\\set Staff.midiInstrument = $midiInstrument", seq)
            lyr = ly.dom.Lyrics(parent=choir)
            lyr.getWith()['alignBelowContext'] = ly.dom.Text('$name')
            ly.dom.Text("\\lyricsto $name $lyrics", lyr)
Esempio n. 25
0
class QDataSet(DataSet, QWidget, Ui_DataSet):
    """[summary]
    
    [description]
    """
    def __init__(self, name="QDataSet", parent=None):
        """
        **Constructor**
        
        [description]
        
        Keyword Arguments:
            - name {[type]} -- [description] (default: {"QDataSet"})
            - parent {[type]} -- [description] (default: {None})
        """
        super().__init__(name=name, parent=parent)
        QWidget.__init__(self)
        Ui_DataSet.__init__(self)

        self.setupUi(self)

        self.DataSettreeWidget = DataSetWidget(self)
        self.splitter.insertWidget(0, self.DataSettreeWidget)

        self.DataSettreeWidget.setIndentation(0)
        self.DataSettreeWidget.setHeaderItem(QTreeWidgetItem([""]))
        self.DataSettreeWidget.setSelectionMode(
            1)  #QAbstractItemView::SingleSelection
        hd = self.DataSettreeWidget.header()
        hd.setSectionsMovable(False)
        w = self.DataSettreeWidget.width()
        w /= hd.count()
        for i in range(hd.count()):
            hd.resizeSection(0, w)

        # Theory Toolbar
        tb = QToolBar()
        tb.setIconSize(QSize(24, 24))
        tb.addAction(self.actionNew_Theory)
        self.cbtheory = QComboBox()
        model = self.cbtheory.model()
        self.cbtheory.setToolTip("Choose a Theory")

        item = QStandardItem('Select:')
        item.setForeground(QColor('grey'))
        model.appendRow(item)
        i = 1
        for th_name in self.parent_application.theories:
            if th_name not in self.parent_application.common_theories:
                item = QStandardItem(th_name)
                item.setToolTip(
                    self.parent_application.theories[th_name].description)
                model.appendRow(item)
        flag_first = True
        for th_name in self.parent_application.theories:
            if th_name in self.parent_application.common_theories:
                if flag_first:
                    # add separator if al least one common theories is added
                    self.cbtheory.insertSeparator(self.cbtheory.count())
                    flag_first = False
                item = QStandardItem(th_name)
                item.setToolTip(
                    self.parent_application.theories[th_name].description)
                model.appendRow(item)
        self.cbtheory.setCurrentIndex(0)

        ###

        self.cbtheory.setMaximumWidth(115)
        self.cbtheory.setMinimumWidth(50)
        tb.addWidget(self.cbtheory)
        tb.addAction(self.actionCalculate_Theory)
        tb.addAction(self.actionMinimize_Error)
        #Buttons not wired yet
        # tb.addAction(self.actionTheory_Options)
        # self.actionTheory_Options.setDisabled(True)
        tbut = QToolButton()
        tbut.setPopupMode(QToolButton.MenuButtonPopup)
        tbut.setDefaultAction(self.actionShow_Limits)
        menu = QMenu()
        menu.addAction(self.actionVertical_Limits)
        menu.addAction(self.actionHorizontal_Limits)
        tbut.setMenu(menu)
        tb.addWidget(tbut)
        tbut2 = QToolButton()
        tbut2.setPopupMode(QToolButton.MenuButtonPopup)
        self.action_save_theory_data = QAction(
            QIcon(':/Icon8/Images/new_icons/icons8-save_TH.png'),
            "Save Theory Data", self)
        tbut2.setDefaultAction(self.action_save_theory_data)
        menu2 = QMenu()
        menu2.addAction(self.actionCopy_Parameters)
        menu2.addAction(self.actionPaste_Parameters)
        tbut2.setMenu(menu2)
        tb.addWidget(tbut2)

        self.TheoryLayout.insertWidget(0, tb)
        self.splitter.setSizes((1000, 3000))

        #desactive buttons when no theory tab
        self.theory_actions_disabled(True)

        connection_id = self.actionNew_Theory.triggered.connect(
            self.handle_actionNew_Theory)
        connection_id = self.DataSettreeWidget.itemChanged.connect(
            self.handle_itemChanged)
        #connection_id = self.DataSettreeWidget.itemClicked.connect(self.handle_itemClicked)
        connection_id = self.DataSettreeWidget.itemDoubleClicked.connect(
            self.handle_itemDoubleClicked)
        connection_id = self.DataSettreeWidget.header(
        ).sortIndicatorChanged.connect(self.handle_sortIndicatorChanged)
        connection_id = self.DataSettreeWidget.itemSelectionChanged.connect(
            self.handle_itemSelectionChanged)
        # connection_id = self.DataSettreeWidget.currentItemChanged.connect(self.handle_currentItemChanged)

        connection_id = self.TheorytabWidget.tabCloseRequested.connect(
            self.handle_thTabCloseRequested)
        connection_id = self.TheorytabWidget.tabBarDoubleClicked.connect(
            self.handle_thTabBarDoubleClicked)
        connection_id = self.TheorytabWidget.currentChanged.connect(
            self.handle_thCurrentChanged)
        connection_id = self.actionMinimize_Error.triggered.connect(
            self.handle_actionMinimize_Error)
        connection_id = self.actionCalculate_Theory.triggered.connect(
            self.handle_actionCalculate_Theory)
        connection_id = self.action_save_theory_data.triggered.connect(
            self.handle_action_save_theory_data)
        connection_id = self.actionCopy_Parameters.triggered.connect(
            self.copy_parameters)
        connection_id = self.actionPaste_Parameters.triggered.connect(
            self.paste_parameters)

        connection_id = self.actionVertical_Limits.triggered.connect(
            self.toggle_vertical_limits)
        connection_id = self.actionHorizontal_Limits.triggered.connect(
            self.toggle_horizontal_limits)

    def copy_parameters(self):
        """Copy the parameters of the currently active theory to the clipboard"""
        th = self.current_theory
        if th:
            self.theories[th].copy_parameters()

    def paste_parameters(self):
        """Paste the parameters from the clipboard to the currently active theory"""
        th = self.current_theory
        if th:
            self.theories[th].paste_parameters()

    def handle_action_save_theory_data(self):
        """Save theory data of current theory"""
        th = self.current_theory
        if th:
            # file browser window
            dir_start = "data/"
            dilogue_name = "Select Folder"
            folder = QFileDialog.getExistingDirectory(self, dilogue_name,
                                                      dir_start)
            if os.path.isdir(folder):
                dialog = QInputDialog(self)
                dialog.setWindowTitle('Add label to filename(s)?')
                dialog.setLabelText(
                    'Add the following text to each saved theory filename(s):')
                dialog.setTextValue('')
                dialog.setCancelButtonText('None')
                if dialog.exec():
                    txt = dialog.textValue()
                    if txt != '':
                        txt = '_' + txt
                else:
                    txt = ''
                self.theories[th].do_save(folder, txt)

    def set_table_icons(self, table_icon_list):
        """The list 'table_icon_list' contains tuples (file_name_short, marker_name, face, color)
        
        [description]
        
        Arguments:
            - table_icon_list {[type]} -- [description]
        """
        self.DataSettreeWidget.blockSignals(
            True
        )  #avoid triggering 'itemChanged' signal that causes a call to do_plot()

        for fname, marker_name, face, color in table_icon_list:
            item = self.DataSettreeWidget.findItems(
                fname, Qt.MatchCaseSensitive,
                column=0)  #returns list of items matching file name
            if item:
                #paint icon
                folder = ':/Markers/Images/Matplotlib_markers/'
                if face == 'none':  #empty symbol
                    marker_path = folder + 'marker_%s' % marker_name
                else:  #filled symbol
                    marker_path = folder + 'marker_filled_%s' % marker_name
                qp = QPixmap(marker_path)
                mask = qp.createMaskFromColor(QColor(0, 0, 0), Qt.MaskOutColor)
                qpainter = QPainter()
                qpainter.begin(qp)
                qpainter.setPen(
                    QColor(int(255 * color[0]), int(255 * color[1]),
                           int(255 * color[2]), 255))
                qpainter.drawPixmap(qp.rect(), mask, qp.rect())
                qpainter.end()
                item[0].setIcon(0, QIcon(qp))

        self.DataSettreeWidget.blockSignals(False)

    def theory_actions_disabled(self, state):
        """Disable theory buttons if no theory tab is open
        
        [description]
        
        Arguments:
            - state {[type]} -- [description]
        """
        self.actionCalculate_Theory.setDisabled(state)
        self.actionMinimize_Error.setDisabled(state)
        # self.actionTheory_Options.setDisabled(state)
        self.actionShow_Limits.setDisabled(state)
        self.actionVertical_Limits.setDisabled(state)
        self.actionHorizontal_Limits.setDisabled(state)
        self.action_save_theory_data.setDisabled(state)

    def set_limit_icon(self):
        """[summary]
        
        [description]
        """
        if self.current_theory:
            th = self.theories[self.current_theory]
        vlim = th.is_xrange_visible
        hlim = th.is_yrange_visible
        if hlim and vlim:
            img = "Line Chart Both Limits"
        elif vlim:
            img = "Line Chart Vertical Limits"
        elif hlim:
            img = "Line Chart Horizontal Limits"
        else:
            img = "Line Chart"
        self.actionShow_Limits.setIcon(QIcon(':/Images/Images/%s.png' % img))

    def set_no_limits(self, th_name):
        """Turn the x and yrange selectors off
        
        [description]
        
        Arguments:
            - th_name {[type]} -- [description]
        """
        if th_name in self.theories:
            self.theories[self.current_theory].set_xy_limits_visible(
                False, False)  #hide xrange and yrange

    def toggle_vertical_limits(self, checked):
        """Show/Hide the xrange selector for fit
        
        [description]
        """
        if self.current_theory:
            th = self.theories[self.current_theory]
            th.do_xrange("", checked)
            th.is_xrange_visible = checked
            self.set_limit_icon()

    def toggle_horizontal_limits(self, checked):
        """Show/Hide the yrange selector for fit
        
        [description]
        """
        if self.current_theory:
            th = self.theories[self.current_theory]
            th.do_yrange("", checked)
            th.is_yrange_visible = checked
            self.set_limit_icon()

    def end_of_computation(self, th_name):
        """Action when theory has finished computations"""
        try:
            th = self.theories[th_name]
            th.stop_theory_flag = False
        except KeyError:
            pass
        if self.current_theory == th_name:
            self.icon_calculate_is_stop(False)
            self.icon_fit_is_stop(False)

    def handle_actionCalculate_Theory(self):
        if self.current_theory and self.files:
            th = self.theories[self.current_theory]
            if th.thread_calc_busy:  # request stop if in do_calculate
                th.request_stop_computations()
                return
            elif th.is_fitting or th.thread_fit_busy:  #do nothing if already busy in do_fit
                th.Qprint("Busy minimising theory...")
                return
            if th.single_file and (len(self.files) -
                                   len(self.inactive_files)) > 1:
                header = "Calculate"
                message = "<p>Too many active files: \"%s\" uses only one data file.</p>\
                    <p>The theory will be applied to the highlighted file if any or to the first active file.</p>" % th.thname
                QMessageBox.warning(self, header, message)
            self.icon_calculate_is_stop(True)
            th.handle_actionCalculate_Theory()

    def handle_actionMinimize_Error(self):
        """Minimize the error
        
        [description]
        """
        if self.current_theory and self.files:
            th = self.theories[self.current_theory]
            if th.is_fitting or th.thread_fit_busy:  # request stop if in do_fit
                th.request_stop_computations()
                return
            elif th.calculate_is_busy or th.thread_calc_busy:  #do nothing if already busy in do_calculate
                th.Qprint("Busy calculating theory...")
                return
            if th.single_file and (len(self.files) -
                                   len(self.inactive_files)) > 1:
                header = "Minimization"
                message = "<p>Too many active files: \"%s\" uses only one data file.</p>\
                    <p>The theory will be applied to the highlighted file if any or to the first active file.</p>" % th.thname
                QMessageBox.warning(self, header, message)
            self.icon_fit_is_stop(True)
            th.handle_actionMinimize_Error()

    def icon_calculate_is_stop(self, ans):
        """Change the "calculate" button to "stop" button"""
        if ans:
            self.actionCalculate_Theory.setIcon(
                QIcon(":/Icon8/Images/new_icons/icons8-stop-sign.png"))
            self.actionCalculate_Theory.setToolTip("Stop current calculations")
        else:
            self.actionCalculate_Theory.setIcon(
                QIcon(":/Icon8/Images/new_icons/icons8-abacus.png"))
            self.actionCalculate_Theory.setToolTip("Calculate Theory (Alt+C)")

    def icon_fit_is_stop(self, ans):
        """Change the "fit" button to "stop" button"""
        if ans:
            self.actionMinimize_Error.setIcon(
                QIcon(":/Icon8/Images/new_icons/icons8-stop-sign.png"))
            self.actionCalculate_Theory.setToolTip("Stop current calculations")
        else:
            self.actionMinimize_Error.setIcon(
                QIcon(":/Icon8/Images/new_icons/icons8-minimum-value.png"))
            self.actionCalculate_Theory.setToolTip("Calculate Theory (Alt+C)")

    def handle_thCurrentChanged(self, index):
        """Change figure when the active theory tab is changed
        
        [description]
        
        Arguments:
            - index {[type]} -- [description]
        """
        self.icon_calculate_is_stop(False)
        self.icon_fit_is_stop(False)
        th = self.TheorytabWidget.widget(index)
        if th:
            self.current_theory = th.name
            ntab = self.TheorytabWidget.count()
            #hide all theory curves
            for i in range(ntab):
                if i != index:
                    th_to_hide = self.TheorytabWidget.widget(i)
                    th_to_hide.do_hide()
            th.do_show()  #must be called last, after hiding other theories

            if th.thread_calc_busy or th.thread_fit_busy:
                self.icon_calculate_is_stop(th.thread_calc_busy)
                self.icon_fit_is_stop(th.thread_fit_busy)
                return
        else:
            self.current_theory = None
            self.theory_actions_disabled(True)
        self.parent_application.update_plot()
        self.parent_application.update_Qplot()

    def handle_thTabBarDoubleClicked(self, index):
        """Edit Theory name
        
        Edit the theory tab name, leave 'theories' dictionary keys unchanged.
        Two tabs can share the same name

        Arguments:
            - index {[type]} -- [description]
        """
        old_name = self.TheorytabWidget.tabText(index)
        dlg = QInputDialog(self)
        dlg.setWindowTitle("Change Theory Name")
        dlg.setLabelText("New Theory Name:")
        dlg.setTextValue(old_name)
        dlg.resize(400, 100)
        success = dlg.exec()
        new_tab_name = dlg.textValue()
        if (success and new_tab_name != ""):
            self.TheorytabWidget.setTabText(index, new_tab_name)
            # self.theories[old_name].name = new_tab_name
            # self.theories[new_tab_name] = self.theories.pop(old_name)
            # self.current_theory = new_tab_name

    def handle_thTabCloseRequested(self, index):
        """Delete a theory tab from the current dataset
        
        [description]
        
        Arguments:
            - index {[type]} -- [description]
        """
        th_name = self.TheorytabWidget.widget(index).name
        th = self.theories[th_name]
        th.Qprint("Close theory tab requested")
        th.request_stop_computations()
        self.set_no_limits(th_name)
        self.do_theory_delete(th_name)  #call DataSet.do_theory_delete
        self.TheorytabWidget.removeTab(index)

    def handle_itemSelectionChanged(self):
        """Define actions for when a file table is selected
        
        [description]
        """
        selection = self.DataSettreeWidget.selectedItems()
        if selection == []:
            self.selected_file = None
            self.highlight_series()
            return
        for f in self.files:
            if f.file_name_short == selection[0].text(0):
                self.parent_application.disconnect_curve_drag()
                self.selected_file = f
                self.highlight_series()
                self.populate_inspector()
                self.parent_application.handle_actionShiftTriggered()

    def highlight_series(self):
        """Highligh the data series of the selected file
        
        [description]
        """
        self.do_plot()  #remove current series highlight
        file = self.selected_file
        thname = self.current_theory
        if thname:
            th = self.theories[thname]
        else:
            th = None
        if file is not None:
            dt = file.data_table
            if th:
                tt = th.tables[file.file_name_short]
            for i in range(dt.MAX_NUM_SERIES):
                for nx in range(self.nplots):
                    view = self.parent_application.multiviews[nx]
                    if (i < view.n and file.active):
                        dt.series[nx][i].set_marker('.')
                        # dt.series[nx][i].set_linestyle(":")
                        dt.series[nx][i].set_markerfacecolor(
                            dt.series[nx][i].get_markeredgecolor())
                        dt.series[nx][i].set_markeredgecolor('peachpuff')
                        dt.series[nx][i].set_markersize(self.marker_size + 3)
                        dt.series[nx][i].set_markeredgewidth(2)
                        dt.series[nx][i].set_zorder(
                            self.parent_application.zorder)  #put series on top
                        if th:
                            if th.active:
                                tt.series[nx][i].set_color('k')
                                tt.series[nx][i].set_path_effects([
                                    pe.Stroke(linewidth=self.th_line_width + 3,
                                              foreground='chartreuse'),
                                    pe.Normal()
                                ])
                                tt.series[nx][i].set_zorder(
                                    self.parent_application.zorder)

            self.parent_application.zorder += 1
        self.parent_application.update_plot()

    def populate_inspector(self):
        """[summary]
        
        [description]
        """
        file = self.selected_file
        if not file:
            self.parent_application.inspector_table.setRowCount(0)
            self.parent_application.DataInspectordockWidget.setWindowTitle(
                "File:")
            return
        if self.parent_application.DataInspectordockWidget.isHidden():
            return
        dt = file.data_table
        nrow = dt.num_rows
        ncol = dt.num_columns
        inspec_tab = self.parent_application.inspector_table
        inspec_tab.file_repr = file
        inspec_tab.setRowCount(nrow)
        inspec_tab.setColumnCount(ncol)
        for i in range(nrow):
            for j in range(ncol):
                item = QTableWidgetItem("%.3e" % dt.data[i, j])
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                inspec_tab.setItem(i, j, item)  # dt.setItem(row, column, item)
        ds_index = self.parent_application.DataSettabWidget.currentIndex()
        self.parent_application.DataInspectordockWidget.setWindowTitle(
            "File: \"%s\" in %s" %
            (file.file_name_short,
             self.parent_application.DataSettabWidget.tabText(ds_index)))
        inspec_tab.resizeColumnsToContents()
        inspec_tab.resizeRowsToContents()
        # Update shift factors
        for i in range(DataTable.MAX_NUM_SERIES):
            self.parent_application.update_shifts(0, 0, i)

    def handle_itemChanged(self, item, column):
        """[summary]
        
        [description]
        
        Arguments:
            - item {[type]} -- [description]
            - column {[type]} -- [description]
        """
        if column == 0:
            self.change_file_visibility(item.text(0),
                                        item.checkState(column) == Qt.Checked)

    def handle_sortIndicatorChanged(self, column, order):
        """Sort files according to the selected parameter (column) and replot
        
        [description]
        
        Arguments:
            - column {[type]} -- [description]
            - order {[type]} -- [description]
        """
        # if column == 0: #do not sort file name
        #     return
        if self.DataSettreeWidget.topLevelItemCount() > 0:
            # sort iff there are some files in the dataset
            sort_param = self.DataSettreeWidget.headerItem().text(column)
            rev = True if order == Qt.AscendingOrder else False
            if rev:
                sort_param = sort_param + ",reverse"
            self.do_sort(sort_param)
            self.do_plot()
            self.set_table_icons(self.table_icon_list)

    def Qshow_all(self):
        """Show all the files in this dataset, except those previously hiden
        
        [description]
        """
        self.do_show_all()
        for i in range(self.DataSettreeWidget.topLevelItemCount()):
            file_name = self.DataSettreeWidget.topLevelItem(i).text(0)
            if file_name in self.inactive_files:
                self.DataSettreeWidget.topLevelItem(i).setCheckState(0, 0)
            else:
                self.DataSettreeWidget.topLevelItem(i).setCheckState(0, 2)

    def resizeEvent(self, evt=None):
        """[summary]
        
        [description]
        
        Keyword Arguments:
            - evt {[type]} -- [description] (default: {None})
        """
        hd = self.DataSettreeWidget.header()
        w = self.DataSettreeWidget.width()
        w /= hd.count()
        for i in range(hd.count()):
            hd.resizeSection(i, w)
            #hd.setTextAlignment(i, Qt.AlignHCenter)

    def handle_itemDoubleClicked(self, item, column):
        """Edit item entry upon double click
        
        [description]
        
        Arguments:
            - item {[type]} -- [description]
            - column {[type]} -- [description]
        """
        # if column>0:
        #     param = self.DataSettreeWidget.headerItem().text(column) #retrive parameter name
        #     file_name_short = item.text(0) #retrive file name
        #     header = "Edit Parameter"
        #     message = "Do you want to edit %s of \"%s\"?"%(param, file_name_short)
        #     answer = QMessageBox.question(self, header, message)
        #     if answer == QMessageBox.Yes:
        #         old_value = item.text(column) #old parameter value
        #         message = "New value of %s"%param
        #         new_value, success = QInputDialog.getDouble(self, header, message, float(old_value))
        #         if success:
        #             for file in self.files:
        #                 if file.file_name_short == file_name_short:
        #                     file.file_parameters[param] = new_value #change value in DataSet
        #             self.DataSettreeWidget.blockSignals(True) #avoid triggering 'itemChanged' signal that causes a false checkbox change
        #             item.setText(column, str(new_value)) #change table label
        #             self.DataSettreeWidget.blockSignals(False)
        # else:
        file_name_short = item.text(0)
        for file in self.files:
            if file.file_name_short == file_name_short:
                d = EditFileParametersDialog(self, file)
                if d.exec_():
                    for p in d.param_dict:
                        if isinstance(file.file_parameters[p], str):
                            file.file_parameters[p] = d.param_dict[p].text()
                        else:
                            try:
                                file.file_parameters[p] = float(
                                    d.param_dict[p].text())
                            except Exception as e:
                                print(e)
                        for i in range(self.DataSettreeWidget.columnCount()):
                            if p == self.DataSettreeWidget.headerItem().text(
                                    i):
                                item.setText(i, str(file.file_parameters[p]))
                    # theory xmin/max
                    try:
                        file.theory_xmin = float(d.th_xmin.text())
                    except ValueError:
                        file.theory_xmin = "None"
                    try:
                        file.theory_xmax = float(d.th_xmax.text())
                    except ValueError:
                        file.theory_xmax = "None"
                    # theory logspace and Npoints
                    try:
                        file.th_num_pts = float(d.th_num_pts.text())
                    except ValueError:
                        pass
                    try:
                        file.th_num_pts = max(int(d.th_num_pts.text()), 2)
                    except ValueError:
                        pass
                    file.theory_logspace = d.th_logspace.isChecked()
                    file.with_extra_x = d.with_extra_x.isChecked() and (
                        file.theory_xmin != "None"
                        or file.theory_xmax != "None")

    def handle_actionNew_Theory(self):
        """Create new theory and do fit
        
        [description]
        """
        self.actionNew_Theory.setDisabled(True)
        if self.cbtheory.currentIndex() == 0:
            # by default, open first theory in the list
            th_name = self.cbtheory.itemText(1)
        else:
            th_name = self.cbtheory.currentText()
        self.cbtheory.setCurrentIndex(0)  # reset the combobox selection
        if th_name != '':
            self.new_theory(th_name)
        self.actionNew_Theory.setDisabled(False)

    def new_theory(self, th_name, th_tab_id="", calculate=True, show=True):
        """[summary]
        
        [description]
        
        Arguments:
            - th_name {[type]} -- [description]
        """
        if not self.files:
            return
        if self.current_theory:
            self.set_no_limits(
                self.current_theory)  #remove the xy-range limits
        self.theory_actions_disabled(False)  #enable theory buttons
        newth = self.do_theory_new(th_name, calculate)

        # add new theory tab
        if th_tab_id == "":
            th_tab_id = newth.name
            th_tab_id = ''.join(
                c for c in th_tab_id
                if c.isupper())  #get the upper case letters of th_name
            th_tab_id = "%s%d" % (th_tab_id, self.num_theories)  #append number

        #hide all theory curves
        ntab = self.TheorytabWidget.count()
        for i in range(ntab):
            th_to_hide = self.TheorytabWidget.widget(i)
            th_to_hide.do_hide()
        #add theory tab
        self.TheorytabWidget.blockSignals(
            True)  #avoid trigger handle_thCurrentChanged()
        index = self.TheorytabWidget.addTab(newth, th_tab_id)
        self.TheorytabWidget.setCurrentIndex(
            index)  #set new theory tab as curent tab
        self.TheorytabWidget.setTabToolTip(index,
                                           th_name)  #set new-tab tool tip
        self.TheorytabWidget.blockSignals(False)
        if show:
            newth.update_parameter_table()
            newth.do_show("")
        return newth
Esempio n. 26
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)
Esempio n. 27
0
class Palette_Docker(DockWidget):
    # Init the docker

    def __init__(self):
        super(Palette_Docker, self).__init__()
        # make base-widget and layout
        widget = QWidget()
        layout = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        widget.setLayout(layout)
        self.setWindowTitle(i18n("Python Palette Docker"))

        # Make a combobox and add palettes
        self.cmb_palettes = QComboBox()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(allPalettes[list(
                allPalettes.keys())[0]])
        else:
            self.currentPalette = None

        self.cmb_palettes.currentTextChanged.connect(self.slot_paletteChanged)
        layout.addWidget(self.cmb_palettes)  # add combobox to the layout
        self.paletteView = PaletteView()
        self.paletteView.setPalette(self.currentPalette)
        layout.addWidget(self.paletteView)
        self.paletteView.entrySelectedForeGround.connect(
            self.slot_swatchSelected)

        self.colorComboBox = QComboBox()
        self.colorList = list()
        buttonLayout.addWidget(self.colorComboBox)
        self.bnSetColor = QToolButton()
        self.bnSetColor.setText(i18n("Set"))
        self.bnSetColor.clicked.connect(self.slot_get_color_from_combobox)
        buttonLayout.addWidget(self.bnSetColor)

        self.addEntry = QAction(self)
        self.addEntry.setIconText(i18n("+"))
        self.addEntry.triggered.connect(self.slot_add_entry)
        self.addGroup = QAction(self)
        self.addGroup.triggered.connect(self.slot_add_group)
        self.addGroup.setText(i18n("Add Group"))
        self.addGroup.setIconText(str("\U0001F4C2"))
        self.removeEntry = QAction(self)
        self.removeEntry.setText(i18n("Remove Entry"))
        self.removeEntry.setIconText("-")
        self.removeEntry.triggered.connect(self.slot_remove_entry)
        addEntryButton = QToolButton()
        addEntryButton.setDefaultAction(self.addEntry)
        buttonLayout.addWidget(addEntryButton)
        addGroupButton = QToolButton()
        addGroupButton.setDefaultAction(self.addGroup)
        buttonLayout.addWidget(addGroupButton)
        removeEntryButton = QToolButton()
        removeEntryButton.setDefaultAction(self.removeEntry)
        buttonLayout.addWidget(removeEntryButton)

        # QActions
        self.extra = QToolButton()
        self.editPaletteData = QAction(self)
        self.editPaletteData.setText(i18n("Edit Palette Settings"))
        self.editPaletteData.triggered.connect(self.slot_edit_palette_data)
        self.extra.setDefaultAction(self.editPaletteData)
        buttonLayout.addWidget(self.extra)
        self.actionMenu = QMenu()
        self.exportToGimp = QAction(self)
        self.exportToGimp.setText(i18n("Export as GIMP Palette File"))
        self.exportToGimp.triggered.connect(self.slot_export_to_gimp_palette)
        self.exportToInkscape = QAction(self)
        self.exportToInkscape.setText(
            i18n("Export as Inkscape SVG with Swatches"))
        self.exportToInkscape.triggered.connect(
            self.slot_export_to_inkscape_svg)
        self.sortColors = QAction(self)
        self.sortColors.setText(i18n("Sort Colors"))
        self.sortColors.triggered.connect(self.slot_sort_colors)
        self.actionMenu.addAction(self.editPaletteData)
        self.actionMenu.addAction(self.exportToGimp)
        self.actionMenu.addAction(self.exportToInkscape)
        # self.actionMenu.addAction(self.sortColors)

        self.extra.setMenu(self.actionMenu)

        layout.addLayout(buttonLayout)
        self.slot_fill_combobox()
        self.setWidget(widget)  # add widget to the docker

    def slot_paletteChanged(self, name):
        allPalettes = Application.resources("palette")
        if len(allPalettes) > 0 and name in allPalettes:
            self.currentPalette = Palette(
                Application.resources("palette")[name])
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()

    @pyqtSlot('PaletteEntry')
    def slot_swatchSelected(self, entry):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                name = entry.name()
                if len(entry.id) > 0:
                    name = entry.id() + " - " + entry.name()
                if len(name) > 0:
                    if name in self.colorList:
                        self.colorComboBox.setCurrentIndex(
                            self.colorList.index(name))
                color = self.currentPalette.colorForEntry(entry)
                self.canvas().view().setForeGroundColor(color)

    '''
    A function for making a combobox with the available colors. We use QCompleter on the colorComboBox so that people
    can type in the name of a color to select it. This is useful for people with carefully made palettes where the colors
    are named properly, which makes it easier for them to find colors.
    '''

    def slot_fill_combobox(self):
        if self.currentPalette is None:
            pass
        palette = self.currentPalette
        self.colorComboBox.clear()
        self.colorList = list()
        for i in range(palette.colorsCountTotal()):
            entry = palette.colorSetEntryByIndex(i)
            color = palette.colorForEntry(entry).colorForCanvas(self.canvas())
            colorSquare = QPixmap(12, 12)
            if entry.spotColor() is True:
                img = colorSquare.toImage()
                circlePainter = QPainter()
                img.fill(self.colorComboBox.palette().color(QPalette.Base))
                circlePainter.begin(img)
                brush = QBrush(Qt.SolidPattern)
                brush.setColor(color)
                circlePainter.setBrush(brush)
                circlePainter.pen().setWidth(0)
                circlePainter.drawEllipse(0, 0, 11, 11)
                circlePainter.end()
                colorSquare = QPixmap.fromImage(img)
            else:
                colorSquare.fill(color)
            name = entry.name()
            if len(entry.id()) > 0:
                name = entry.id() + " - " + entry.name()
            self.colorList.append(name)
            self.colorComboBox.addItem(QIcon(colorSquare), name)
        self.colorComboBox.setEditable(True)
        self.colorComboBox.setInsertPolicy(QComboBox.NoInsert)
        self.colorComboBox.completer().setCompletionMode(
            QCompleter.PopupCompletion)
        self.colorComboBox.completer().setCaseSensitivity(False)
        self.colorComboBox.completer().setFilterMode(Qt.MatchContains)

    def slot_get_color_from_combobox(self):
        if self.currentPalette is not None:
            entry = self.currentPalette.colorSetEntryByIndex(
                self.colorComboBox.currentIndex())
            self.slot_swatchSelected(entry)

    def slot_add_entry(self):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                color = self.canvas().view().foregroundColor()
                success = self.paletteView.addEntryWithDialog(color)
                if success is True:
                    self.slot_fill_combobox()

    def slot_add_group(self):
        success = self.paletteView.addGroupWithDialog()
        if success is True:
            self.slot_fill_combobox()

    def slot_remove_entry(self):
        success = self.paletteView.removeSelectedEntryWithDialog()
        if success is True:
            self.slot_fill_combobox()

    '''
    A function for giving a gui to edit palette metadata... I also want this to be the way to edit the settings of the
    palette docker.
    '''

    def slot_edit_palette_data(self):
        dialog = QDialog(self)
        tabWidget = QTabWidget()
        dialog.setWindowTitle(i18n("Edit Palette Data"))
        dialog.setLayout(QVBoxLayout())
        dialog.layout().addWidget(tabWidget)
        paletteWidget = QWidget()
        paletteWidget.setLayout(QVBoxLayout())
        tabWidget.addTab(paletteWidget, i18n("Palette Data"))
        paletteName = QLineEdit()
        paletteName.setText(self.cmb_palettes.currentText())
        paletteWidget.layout().addWidget(paletteName)
        paletteColumns = QSpinBox()
        paletteColumns.setValue(self.currentPalette.columnCount())
        paletteWidget.layout().addWidget(paletteColumns)
        paletteComment = QPlainTextEdit()
        paletteComment.appendPlainText(self.currentPalette.comment())
        paletteWidget.layout().addWidget(paletteComment)
        buttons = QDialogButtonBox(QDialogButtonBox.Ok)
        dialog.layout().addWidget(buttons)
        buttons.accepted.connect(dialog.accept)
        # buttons.rejected.connect(dialog.reject())

        if dialog.exec_() == QDialog.Accepted:
            Resource = Application.resources("palette")[
                self.cmb_palettes.currentText()]
            Resource.setName(paletteName.text())
            self.currentPalette = Palette(Resource)
            self.currentPalette.setColumnCount(paletteColumns.value())
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()
            self.currentPalette.setComment(paletteComment.toPlainText())
            self.currentPalette.save()

    def slot_export_to_gimp_palette(self):
        palette_exporter_gimppalette.gimpPaletteExporter(
            self.cmb_palettes.currentText())

    def slot_export_to_inkscape_svg(self):
        palette_exporter_inkscapeSVG.inkscapeSVGExporter(
            self.cmb_palettes.currentText())

    def slot_sort_colors(self):
        colorSorter = palette_sortColors.sortColors(
            self.cmb_palettes.currentText())
        self.paletteView.setPalette(colorSorter.palette())

    def canvasChanged(self, canvas):
        self.cmb_palettes.clear()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if self.currentPalette == None and len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(allPalettes[list(
                allPalettes.keys())[0]])
Esempio n. 28
0
class OWCSVFileImport(widget.OWWidget):
    name = "CSV File Import"
    description = "Import a data table from a CSV formatted file."
    icon = "icons/CSVFile.svg"
    priority = 11
    category = "Data"
    keywords = ["file", "load", "read", "open", "csv"]

    outputs = [
        widget.OutputSignal(
            name="Data",
            type=Orange.data.Table,
            doc="Loaded data set."),
        widget.OutputSignal(
            name="Data Frame",
            type=pd.DataFrame,
            doc=""
        )
    ]

    class Error(widget.OWWidget.Error):
        error = widget.Msg(
            "Unexpected error"
        )
        encoding_error = widget.Msg(
            "Encoding error\n"
            "The file might be encoded in an unsupported encoding or it "
            "might be binary"
        )

    #: Paths and options of files accessed in a 'session'
    _session_items = settings.Setting(
        [], schema_only=True)  # type: List[Tuple[str, dict]]

    #: Saved dialog state (last directory and selected filter)
    dialog_state = settings.Setting({
        "directory": "",
        "filter": ""
    })  # type: Dict[str, str]
    MaxHistorySize = 50

    want_main_area = False
    buttons_area_orientation = None

    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)

        self.__committimer = QTimer(self, singleShot=True)
        self.__committimer.timeout.connect(self.commit)

        self.__executor = qconcurrent.ThreadExecutor()
        self.__watcher = None  # type: Optional[qconcurrent.FutureWatcher]

        self.controlArea.layout().setSpacing(-1)  # reset spacing
        grid = QGridLayout()
        grid.addWidget(QLabel("File:", self), 0, 0, 1, 1)

        self.import_items_model = QStandardItemModel(self)
        self.recent_combo = QComboBox(
            self, objectName="recent-combo", toolTip="Recent files.",
            sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon,
            minimumContentsLength=16,
        )
        self.recent_combo.setModel(self.import_items_model)
        self.recent_combo.activated.connect(self.activate_recent)
        self.recent_combo.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        self.browse_button = QPushButton(
            "…", icon=self.style().standardIcon(QStyle.SP_DirOpenIcon),
            toolTip="Browse filesystem", autoDefault=False,
        )
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.browse_button.clicked.connect(self.browse)
        grid.addWidget(self.recent_combo, 0, 1, 1, 1)
        grid.addWidget(self.browse_button, 0, 2, 1, 1)
        self.controlArea.layout().addLayout(grid)

        ###########
        # Info text
        ###########
        box = gui.widgetBox(self.controlArea, "Info", addSpace=False)
        self.summary_text = QTextBrowser(
            verticalScrollBarPolicy=Qt.ScrollBarAsNeeded,
            readOnly=True,
        )
        self.summary_text.viewport().setBackgroundRole(QPalette.NoRole)
        self.summary_text.setFrameStyle(QTextBrowser.NoFrame)
        self.summary_text.setMinimumHeight(self.fontMetrics().ascent() * 2 + 4)
        self.summary_text.viewport().setAutoFillBackground(False)
        box.layout().addWidget(self.summary_text)

        button_box = QDialogButtonBox(
            orientation=Qt.Horizontal,
            standardButtons=QDialogButtonBox.Cancel | QDialogButtonBox.Retry
        )
        self.load_button = b = button_box.button(QDialogButtonBox.Retry)
        b.setText("Load")
        b.clicked.connect(self.__committimer.start)
        b.setEnabled(False)
        b.setDefault(True)

        self.cancel_button = b = button_box.button(QDialogButtonBox.Cancel)
        b.clicked.connect(self.cancel)
        b.setEnabled(False)
        b.setAutoDefault(False)

        self.import_options_button = QPushButton(
            "Import Options…", enabled=False, autoDefault=False,
            clicked=self._activate_import_dialog
        )

        def update_buttons(cbindex):
            self.import_options_button.setEnabled(cbindex != -1)
            self.load_button.setEnabled(cbindex != -1)
        self.recent_combo.currentIndexChanged.connect(update_buttons)

        button_box.addButton(
            self.import_options_button, QDialogButtonBox.ActionRole
        )
        button_box.setStyleSheet(
            "button-layout: {:d};".format(QDialogButtonBox.MacLayout)
        )
        self.controlArea.layout().addWidget(button_box)

        self._restoreState()
        if self.current_item() is not None:
            self._invalidate()
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)

    @Slot(int)
    def activate_recent(self, index):
        """
        Activate an item from the recent list.
        """
        if 0 <= index < self.import_items_model.rowCount():
            item = self.import_items_model.item(index)
            assert item is not None
            path = item.data(ImportItem.PathRole)
            opts = item.data(ImportItem.OptionsRole)
            if not isinstance(opts, Options):
                opts = None
            self.set_selected_file(path, opts)
        else:
            self.recent_combo.setCurrentIndex(-1)

    @Slot()
    def browse(self):
        """
        Open a file dialog and select a user specified file.
        """
        formats = [
            "Text - comma separated (*.csv, *)",
            "Text - tab separated (*.tsv, *)",
            "Text - all files (*)"
        ]

        dlg = QFileDialog(
            self, windowTitle="Open Data File",
            acceptMode=QFileDialog.AcceptOpen,
            fileMode=QFileDialog.ExistingFile
        )
        dlg.setNameFilters(formats)
        state = self.dialog_state
        lastdir = state.get("directory", "")
        lastfilter = state.get("filter", "")

        if lastdir and os.path.isdir(lastdir):
            dlg.setDirectory(lastdir)
        if lastfilter:
            dlg.selectNameFilter(lastfilter)

        status = dlg.exec_()
        dlg.deleteLater()
        if status == QFileDialog.Accepted:
            self.dialog_state["directory"] = dlg.directory().absolutePath()
            self.dialog_state["filter"] = dlg.selectedNameFilter()

            selected_filter = dlg.selectedNameFilter()
            path = dlg.selectedFiles()[0]
            # pre-flight check; try to determine the nature of the file
            mtype = _mime_type_for_path(path)
            if not mtype.inherits("text/plain"):
                mb = QMessageBox(
                    parent=self,
                    windowTitle="",
                    icon=QMessageBox.Question,
                    text="The '{basename}' may be a binary file.\n"
                         "Are you sure you want to continue?".format(
                             basename=os.path.basename(path)),
                    standardButtons=QMessageBox.Cancel | QMessageBox.Yes
                )
                mb.setWindowModality(Qt.WindowModal)
                if mb.exec() == QMessageBox.Cancel:
                    return

            # initialize dialect based on selected extension
            if selected_filter in formats[:-1]:
                filter_idx = formats.index(selected_filter)
                if filter_idx == 0:
                    dialect = csv.excel()
                elif filter_idx == 1:
                    dialect = csv.excel_tab()
                else:
                    dialect = csv.excel_tab()
                header = True
            else:
                try:
                    dialect, header = sniff_csv_with_path(path)
                except Exception:  # pylint: disable=broad-except
                    dialect, header = csv.excel(), True

            options = None
            # Search for path in history.
            # If found use the stored params to initialize the import dialog
            items = self.itemsFromSettings()
            idx = index_where(items, lambda t: samepath(t[0], path))
            if idx is not None:
                _, options_ = items[idx]
                if options_ is not None:
                    options = options_

            if options is None:
                if not header:
                    rowspec = []
                else:
                    rowspec = [(range(0, 1), RowSpec.Header)]
                options = Options(
                    encoding="utf-8", dialect=dialect, rowspec=rowspec)

            dlg = CSVImportDialog(
                self, windowTitle="Import Options", sizeGripEnabled=True)
            dlg.setWindowModality(Qt.WindowModal)
            dlg.setPath(path)
            dlg.setOptions(options)
            status = dlg.exec_()
            dlg.deleteLater()
            if status == QDialog.Accepted:
                self.set_selected_file(path, dlg.options())

    def current_item(self):
        # type: () -> Optional[ImportItem]
        """
        Return the current selected item (file) or None if there is no
        current item.
        """
        idx = self.recent_combo.currentIndex()
        if idx == -1:
            return None

        item = self.recent_combo.model().item(idx)  # type: QStandardItem
        if isinstance(item, ImportItem):
            return item
        else:
            return None

    def _activate_import_dialog(self):
        """Activate the Import Options dialog for the  current item."""
        item = self.current_item()
        assert item is not None
        dlg = CSVImportDialog(
            self, windowTitle="Import Options", sizeGripEnabled=True,
        )
        dlg.setWindowModality(Qt.WindowModal)
        dlg.setAttribute(Qt.WA_DeleteOnClose)
        settings = QSettings()
        qualname = qname(type(self))
        settings.beginGroup(qualname)
        size = settings.value("size", QSize(), type=QSize)  # type: QSize
        if size.isValid():
            dlg.resize(size)

        path = item.data(ImportItem.PathRole)
        options = item.data(ImportItem.OptionsRole)
        dlg.setPath(path)  # Set path before options so column types can
        if isinstance(options, Options):
            dlg.setOptions(options)

        def update():
            newoptions = dlg.options()
            item.setData(newoptions, ImportItem.OptionsRole)
            # update the stored item
            self._add_recent(path, newoptions)
            if newoptions != options:
                self._invalidate()
        dlg.accepted.connect(update)

        def store_size():
            settings.setValue("size", dlg.size())
        dlg.finished.connect(store_size)
        dlg.show()

    def set_selected_file(self, filename, options=None):
        """
        Set the current selected filename path.
        """
        self._add_recent(filename, options)
        self._invalidate()

    #: Saved options for a filename
    SCHEMA = {
        "path": str,  # Local filesystem path
        "options": str,  # json encoded 'Options'
    }

    @classmethod
    def _local_settings(cls):
        # type: () -> QSettings
        """Return a QSettings instance with local persistent settings."""
        filename = "{}.ini".format(qname(cls))
        fname = os.path.join(settings.widget_settings_dir(), filename)
        return QSettings(fname, QSettings.IniFormat)

    def _add_recent(self, filename, options=None):
        # type: (str, Optional[Options]) -> None
        """
        Add filename to the list of recent files.
        """
        model = self.import_items_model
        index = index_where(
            (model.index(i, 0).data(ImportItem.PathRole)
             for i in range(model.rowCount())),
            lambda path: isinstance(path, str) and samepath(path, filename)
        )
        if index is not None:
            item, *_ = model.takeRow(index)
        else:
            item = ImportItem.fromPath(filename)

        model.insertRow(0, item)

        if options is not None:
            item.setOptions(options)

        self.recent_combo.setCurrentIndex(0)
        # store items to local persistent settings
        s = self._local_settings()
        arr = QSettings_readArray(s, "recent", OWCSVFileImport.SCHEMA)
        item = {"path": filename}
        if options is not None:
            item["options"] = json.dumps(options.as_dict())

        arr = [item for item in arr if item.get("path") != filename]
        arr.append(item)
        QSettings_writeArray(s, "recent", arr)

        # update workflow session items
        items = self._session_items[:]
        idx = index_where(items, lambda t: samepath(t[0], filename))
        if idx is not None:
            del items[idx]
        items.insert(0, (filename, options.as_dict()))
        self._session_items = items[:OWCSVFileImport.MaxHistorySize]

    def _invalidate(self):
        # Invalidate the current output and schedule a new commit call.
        # (NOTE: The widget enters a blocking state)
        self.__committimer.start()
        if self.__watcher is not None:
            self.__cancel_task()
        self.setBlocking(True)

    def commit(self):
        """
        Commit the current state and submit the load task for execution.

        Note
        ----
        Any existing pending task is canceled.
        """
        self.__committimer.stop()
        if self.__watcher is not None:
            self.__cancel_task()
        self.error()

        item = self.current_item()
        if item is None:
            return
        path = item.data(ImportItem.PathRole)
        opts = item.data(ImportItem.OptionsRole)
        if not isinstance(opts, Options):
            return

        task = state = TaskState()
        state.future = ...
        state.watcher = qconcurrent.FutureWatcher()
        state.progressChanged.connect(self.__set_read_progress,
                                      Qt.QueuedConnection)

        def progress_(i, j):
            task.emitProgressChangedOrCancel(i, j)

        task.future = self.__executor.submit(
            clear_stack_on_cancel(load_csv),
            path, opts, progress_,
        )
        task.watcher.setFuture(task.future)
        w = task.watcher
        w.done.connect(self.__handle_result)
        w.progress = state
        self.__watcher = w
        self.__set_running_state()

    @Slot('qint64', 'qint64')
    def __set_read_progress(self, read, count):
        if count > 0:
            self.progressBarSet(100 * read / count)

    def __cancel_task(self):
        # Cancel and dispose of the current task
        assert self.__watcher is not None
        w = self.__watcher
        w.future().cancel()
        w.progress.cancel = True
        w.done.disconnect(self.__handle_result)
        w.progress.progressChanged.disconnect(self.__set_read_progress)
        w.progress.deleteLater()
        # wait until completion
        futures.wait([w.future()])
        self.__watcher = None

    def cancel(self):
        """
        Cancel current pending or executing task.
        """
        if self.__watcher is not None:
            self.__cancel_task()
            self.__clear_running_state()
            self.setStatusMessage("Cancelled")
            self.summary_text.setText(
                "<div>Cancelled<br/><small>Press 'Reload' to try again</small></div>"
            )

    def __set_running_state(self):
        self.progressBarInit()
        self.setBlocking(True)
        self.setStatusMessage("Running")
        self.cancel_button.setEnabled(True)
        self.load_button.setText("Restart")
        path = self.current_item().path()
        self.Error.clear()
        self.summary_text.setText(
            "<div>Loading: <i>{}</i><br/>".format(prettyfypath(path))
        )

    def __clear_running_state(self, ):
        self.progressBarFinished()
        self.setStatusMessage("")
        self.setBlocking(False)
        self.cancel_button.setEnabled(False)
        self.load_button.setText("Reload")

    def __set_error_state(self, err):
        self.Error.clear()
        if isinstance(err, UnicodeDecodeError):
            self.Error.encoding_error(exc_info=err)
        else:
            self.Error.error(exc_info=err)

        path = self.current_item().path()
        basename = os.path.basename(path)
        if isinstance(err, UnicodeDecodeError):
            text = (
                "<div><i>{basename}</i> was not loaded due to a text encoding "
                "error. The file might be saved in an unknown or invalid "
                "encoding, or it might be a binary file.</div>"
            ).format(
                basename=escape(basename)
            )
        else:
            text = (
                "<div><i>{basename}</i> was not loaded due to an error:"
                "<p style='white-space: pre;'>{err}</p>"
            ).format(
                basename=escape(basename),
                err="".join(traceback.format_exception_only(type(err), err))
            )
        self.summary_text.setText(text)

    def __clear_error_state(self):
        self.Error.error.clear()
        self.summary_text.setText("")

    def onDeleteWidget(self):
        """Reimplemented."""
        if self.__watcher is not None:
            self.__cancel_task()
            self.__executor.shutdown()
        super().onDeleteWidget()

    @Slot(object)
    def __handle_result(self, f):
        # type: (qconcurrent.Future[pd.DataFrame]) -> None
        assert f.done()
        assert f is self.__watcher.future()
        self.__watcher = None
        self.__clear_running_state()

        try:
            df = f.result()
            assert isinstance(df, pd.DataFrame)
        except pandas.errors.EmptyDataError:
            df = pd.DataFrame({})
        except Exception as e:  # pylint: disable=broad-except
            self.__set_error_state(e)
            df = None
        else:
            self.__clear_error_state()

        if df is not None:
            table = pandas_to_table(df)
        else:
            table = None
        self.send("Data Frame", df)
        self.send('Data', table)
        self._update_status_messages(table)

    def _update_status_messages(self, data):
        if data is None:
            return

        def pluralize(seq):
            return "s" if len(seq) != 1 else ""

        summary = ("{n_instances} row{plural_1}, "
                   "{n_features} feature{plural_2}, "
                   "{n_meta} meta{plural_3}").format(
                       n_instances=len(data), plural_1=pluralize(data),
                       n_features=len(data.domain.attributes),
                       plural_2=pluralize(data.domain.attributes),
                       n_meta=len(data.domain.metas),
                       plural_3=pluralize(data.domain.metas))
        self.summary_text.setText(summary)

    def itemsFromSettings(self):
        # type: () -> List[Tuple[str, Options]]
        """
        Return items from local history.
        """
        s = self._local_settings()
        items_ = QSettings_readArray(s, "recent", OWCSVFileImport.SCHEMA)
        items = []  # type: List[Tuple[str, Options]]
        for item in items_:
            path = item.get("path", "")
            if not path:
                continue
            opts_json = item.get("options", "")
            try:
                opts = Options.from_dict(json.loads(opts_json))
            except (csv.Error, LookupError, TypeError, json.JSONDecodeError):
                _log.error("Could not reconstruct options for '%s'", path,
                           exc_info=True)
            else:
                items.append((path, opts))
        return items[::-1]

    def _restoreState(self):
        # Restore the state. Merge session (workflow) items with the
        # local history.
        model = self.import_items_model
        # local history
        items = self.itemsFromSettings()
        # stored session items
        sitems = []
        for p, m in self._session_items:
            try:
                item_ = (p, Options.from_dict(m))
            except (csv.Error, LookupError):
                # Is it better to fail then to lose a item slot?
                _log.error("Failed to restore '%s'", p, exc_info=True)
            else:
                sitems.append(item_)

        items = sitems + items
        items = unique(items, key=lambda t: pathnormalize(t[0]))

        curr = self.recent_combo.currentIndex()
        if curr != -1:
            currentpath = self.recent_combo.currentData(ImportItem.PathRole)
        else:
            currentpath = None
        for path, options in items:
            item = ImportItem.fromPath(path)
            item.setOptions(options)
            model.appendRow(item)

        if currentpath is not None:
            idx = self.recent_combo.findData(currentpath, ImportItem.PathRole)
            if idx != -1:
                self.recent_combo.setCurrentIndex(idx)
Esempio n. 29
0
class OptionsWidget(QWidget):
    ''' main class to create the tabs containing the
        different options to steer the analysis'''
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.layout = QGridLayout()
        self.group = QGroupBox()
        self.add_contents()
        self.group.setLayout(self.layout)
        self.setLayout(self.layout)

    def add_contents(self):
        pass 

    def add_start_button(self, h):
        pushButton = QPushButton("Start")
        pushButton.clicked.connect(self.on_pushButton_start)
        self.layout.addWidget(pushButton, h, 0, 2, 3)

    def add_detail_button(self, h):
        pushButton = QPushButton("Details")
        pushButton.clicked.connect(self.on_pushButton_details)
        self.layout.addWidget(pushButton, h, 0, 2, 3)        

    def add_time_period(self, h):
        inner_group = QGroupBox()
        inner_layout = QGridLayout()
        self.ComboBoxStart = QComboBox()
        for i,key in enumerate(self.parent.all_dates):
            self.ComboBoxStart.addItem(key)
        inner_layout.addWidget(self.ComboBoxStart, 0, 0)

        inner_layout.addWidget(QLabel("-"), 0, 1)            
        
        self.ComboBoxEnd = QComboBox()
        for i,key in enumerate(self.parent.all_dates):
            self.ComboBoxEnd.addItem(key)
        self.ComboBoxEnd.setCurrentIndex(len(self.parent.all_dates)-1)
        inner_layout.addWidget(self.ComboBoxEnd, 0, 2)
        inner_group.setLayout(inner_layout)
        self.layout.addWidget(QLabel("Zeitraum"), h, 0)
        self.layout.addWidget(inner_group, h, 1, 1, 2)
        # self.layout.addWidget(QColumn(QLabel("Zeitraum"),inner_group)) 
        # 
        newl = QLabel()
        newl.setFrameStyle(QFrame.HLine )
        self.layout.addWidget(newl, h+1, 0, 1, 3)


    def add_configure(self,h):
        pushButton = QPushButton("Auswahl")
        pushButton.clicked.connect(self.on_pushButton_config)
        # self.layout.addWidget(QColumn(QLabel("Kategorien"), pushButton))
        self.layout.addWidget(QLabel("Kategorien"), h, 0)
        self.layout.addWidget(pushButton, h, 1, 1, 2)

        newl = QLabel()
        newl.setFrameStyle(QFrame.HLine )
        self.layout.addWidget(newl, h+1, 0, 1, 3)


    def add_radio_log(self, h, lines=1):	
        plot1_group=QButtonGroup(QWidget(self)) 
        self.radioPlot1 = QRadioButton("Linear")	 
        self.radioPlot2 = QRadioButton("Log")	
        plot1_group.addButton(self.radioPlot1) 
        plot1_group.addButton(self.radioPlot2) 
        self.radioPlot1.setChecked(True) 	   
        # self.layout.addWidget(QColumn3(QLabel("Skala Plot 1"),self.radioPlot1, self.radioPlot2 ))        
        self.layout.addWidget(QLabel("Skala Plot 1"), h, 0)
        self.layout.addWidget(self.radioPlot1, h, 1)
        self.layout.addWidget(self.radioPlot2, h, 2)        
        if lines > 1:
            self.radioPlot1b = QRadioButton("Linear")	 
            self.radioPlot2b = QRadioButton("Log")	 
            self.radioPlot1b.setChecked(True) 	
            plot2_group=QButtonGroup(QWidget(self))            
            plot2_group.addButton(self.radioPlot1b) 
            plot2_group.addButton(self.radioPlot2b)                
            # self.layout.addWidget(QColumn3(QLabel("Skala Plot 2"),self.radioPlot1b, self.radioPlot2b))        
            self.layout.addWidget(QLabel("Skala Plot 2"), h+1, 0)
            self.layout.addWidget(self.radioPlot1b, h+1, 1)
            self.layout.addWidget(self.radioPlot2b, h+1, 2)    

        newl = QLabel()
        newl.setFrameStyle(QFrame.HLine )
        self.layout.addWidget(newl, h+2, 0, 1, 3)


    def add_radio_level(self, h):	
        self.radioLevel1 = QRadioButton("fein")	 
        self.radioLevel2 = QRadioButton("grob")	 
        self.radioLevel2.setChecked(True) 	   
        level_group=QButtonGroup(QWidget(self))            
        level_group.addButton(self.radioLevel1) 
        level_group.addButton(self.radioLevel2)                

        # self.layout.addWidget(QColumn(self.radioLevel1, self.radioLevel2 ))               
        self.layout.addWidget(QLabel("Zusammenfassung"), h, 0)
        self.layout.addWidget(self.radioLevel1, h, 1)
        self.layout.addWidget(self.radioLevel2, h, 2)

    def add_fine_category(self,h):
        self.ComboBoxFine = QComboBox()
        for i,key in enumerate(self.parent.KEYS.OUT[1]):
            self.ComboBoxFine.addItem(key)
            item = self.ComboBoxFine.model().item(i, 0)
            item.setCheckState(Qt.Unchecked)    

        newl = QLabel()
        newl.setFrameStyle(QFrame.HLine )
        self.layout.addWidget(newl, h+1, 0, 1, 3)             

        self.layout.addWidget(QLabel("Details"), h+2, 0)            
        self.layout.addWidget(self.ComboBoxFine, h+2, 1, 1, 2)   


    def on_pushButton_start(self):
        pass

    def on_pushButton_config(self):
        pass    

    def on_pushButton_details(self):
        pass          

    def set_dates(self):
        self.date_start = analyse.go_to_last_day(datetime.datetime.strptime(self.ComboBoxStart.currentText() ,"%m/%Y").date())
        self.date_end = analyse.go_to_last_day(datetime.datetime.strptime(self.ComboBoxEnd.currentText() ,"%m/%Y").date())
Esempio n. 30
0
class SvgView(QWidget):
    def __init__(self, dockwidget):
        super(SvgView, self).__init__(dockwidget)

        self._document = None
        self._setting_zoom = False

        self.view = view.View(self)

        self.pageLabel = QLabel()
        self.pageCombo = QComboBox(sizeAdjustPolicy=QComboBox.AdjustToContents)

        layout = QVBoxLayout(spacing=0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        hbox = QHBoxLayout(spacing=0)
        hbox.addWidget(self.pageLabel)
        hbox.addWidget(self.pageCombo)

        self.zoomInButton = QToolButton(autoRaise=True)
        self.zoomOutButton = QToolButton(autoRaise=True)
        self.zoomOriginalButton = QToolButton(autoRaise=True)
        self.zoomNumber = QSpinBox(minimum=10, maximum=1000, suffix='%')
        ac = dockwidget.actionCollection
        self.zoomInButton.setDefaultAction(ac.svg_zoom_in)
        self.zoomOutButton.setDefaultAction(ac.svg_zoom_out)
        self.zoomOriginalButton.setDefaultAction(ac.svg_zoom_original)
        hbox.addWidget(self.zoomInButton)
        hbox.addWidget(self.zoomNumber)
        hbox.addWidget(self.zoomOutButton)
        hbox.addWidget(self.zoomOriginalButton)

        self.resetButton = QPushButton("reload", self)
        self.resetButton.clicked.connect(self.reLoadDoc)
        hbox.addWidget(self.resetButton)

        self.saveButton = QPushButton("save edits", self)
        self.saveButton.clicked.connect(self.callSave)
        hbox.addWidget(self.saveButton)

        hbox.addStretch(1)
        layout.addLayout(hbox)
        layout.addWidget(self.view)

        app.jobFinished.connect(self.initSvg)
        app.documentClosed.connect(self.slotDocumentClosed)
        app.documentLoaded.connect(self.initSvg)
        self.pageCombo.currentIndexChanged.connect(self.changePage)
        self.zoomNumber.valueChanged.connect(self.slotZoomNumberChanged)
        self.view.zoomFactorChanged.connect(self.slotViewZoomChanged)
        dockwidget.mainwindow().currentDocumentChanged.connect(self.initSvg)
        self.zoomNumber.setValue(100)
        doc = dockwidget.mainwindow().currentDocument()
        if doc:
            self.initSvg(doc)
        app.translateUI(self)

    def translateUI(self):
        self.pageLabel.setText(_("Page:"))

    def mainwindow(self):
        return self.parent().mainwindow()

    def initSvg(self, doc):
        """Opens first page of score after compilation"""
        if doc == self.mainwindow().currentDocument():
            files = svgfiles.SvgFiles.instance(doc)
            model = files.model()  # forces update
            if files:
                self._document = doc
                with qutil.signalsBlocked(self.pageCombo):
                    self.pageCombo.setModel(model)
                    self.pageCombo.setCurrentIndex(files.current)
                self.view.load(files.url(files.current))

    def reLoadDoc(self):
        """Reloads current document."""
        if self._document:
            self.initSvg(self._document)

    def callSave(self):
        """Call save function"""
        self.view.evalSave()

    def getCurrent(self):
        files = svgfiles.SvgFiles.instance(self._document)
        return files.filename(files.current)

    def slotZoomNumberChanged(self, value):
        self._setting_zoom = True
        self.view.setZoomFactor(value / 100.0)
        self._setting_zoom = False

    def slotViewZoomChanged(self):
        if not self._setting_zoom:
            self.zoomNumber.setValue(int(self.view.zoomFactor() * 100))

    def changePage(self, page_index):
        """change page of score"""
        doc = self._document
        if doc:
            files = svgfiles.SvgFiles.instance(doc)
            if files:
                files.current = page_index
                svg = files.url(page_index)
                self.view.load(svg)

    def slotDocumentClosed(self, doc):
        if doc == self._document:
            self._document = None
            if self.pageCombo.model():
                self.pageCombo.model().deleteLater()
            self.pageCombo.clear()
            self.pageCombo.update()  # otherwise it doesn't redraw
            self.view.clear()
Esempio n. 31
0
def run_iface_config_window(icon):
    win = QDialog()
    win.setWindowTitle('CAN Interface Configuration')
    win.setWindowIcon(icon)
    win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
    win.setAttribute(Qt.WA_DeleteOnClose)              # This is required to stop background timers!

    combo = QComboBox(win)
    combo.setEditable(True)
    combo.setInsertPolicy(QComboBox.NoInsert)
    combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    combo.setFont(get_monospace_font())

    combo_completer = QCompleter()
    combo_completer.setCaseSensitivity(Qt.CaseSensitive)
    combo_completer.setModel(combo.model())
    combo.setCompleter(combo_completer)

    bitrate = QSpinBox(win)
    bitrate.setMaximum(1000000)
    bitrate.setMinimum(10000)
    bitrate.setValue(1000000)

    baudrate = QComboBox(win)
    baudrate.setEditable(True)
    baudrate.setInsertPolicy(QComboBox.NoInsert)
    baudrate.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    baudrate.setFont(get_monospace_font())

    baudrate_completer = QCompleter(win)
    baudrate_completer.setModel(baudrate.model())
    baudrate.setCompleter(baudrate_completer)

    baudrate.setValidator(QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)))
    baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES))
    baudrate.setCurrentText(str(DEFAULT_BAUD_RATE))

    ok = QPushButton('OK', win)

    def update_slcan_options_visibility():
        if RUNNING_ON_LINUX:
            slcan_active = '/' in combo.currentText()
        else:
            slcan_active = True
        slcan_group.setEnabled(slcan_active)

    combo.currentTextChanged.connect(update_slcan_options_visibility)

    ifaces = None

    def update_iface_list():
        nonlocal ifaces
        ifaces = iface_lister.get_list()
        known_keys = set()
        remove_indices = []
        was_empty = combo.count() == 0
        # Marking known and scheduling for removal
        for idx in count():
            tx = combo.itemText(idx)
            if not tx:
                break
            known_keys.add(tx)
            if tx not in ifaces:
                logger.debug('Removing iface %r', tx)
                remove_indices.append(idx)
        # Removing - starting from the last item in order to retain indexes
        for idx in remove_indices[::-1]:
            combo.removeItem(idx)
        # Adding new items - starting from the last item in order to retain the final order
        for key in list(ifaces.keys())[::-1]:
            if key not in known_keys:
                logger.debug('Adding iface %r', key)
                combo.insertItem(0, key)
        # Updating selection
        if was_empty:
            combo.setCurrentIndex(0)

    result = None
    kwargs = {}

    def on_ok():
        nonlocal result, kwargs
        try:
            baud_rate_value = int(baudrate.currentText())
        except ValueError:
            show_error('Invalid parameters', 'Could not parse baud rate', 'Please specify correct baud rate',
                       parent=win)
            return
        if not (min(STANDARD_BAUD_RATES) <= baud_rate_value <= max(STANDARD_BAUD_RATES)):
            show_error('Invalid parameters', 'Baud rate is out of range',
                       'Baud rate value should be within [%s, %s]' %
                       (min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)),
                       parent=win)
            return
        kwargs['baudrate'] = baud_rate_value
        kwargs['bitrate'] = int(bitrate.value())
        result_key = str(combo.currentText()).strip()
        if not result_key:
            show_error('Invalid parameters', 'Interface name cannot be empty', 'Please select a valid interface',
                       parent=win)
            return
        try:
            result = ifaces[result_key]
        except KeyError:
            result = result_key
        win.close()

    ok.clicked.connect(on_ok)

    layout = QVBoxLayout(win)
    layout.addWidget(QLabel('Select CAN interface'))
    layout.addWidget(combo)

    slcan_group = QGroupBox('SLCAN adapter settings', win)
    slcan_layout = QVBoxLayout(slcan_group)

    slcan_layout.addWidget(QLabel('CAN bus bit rate:'))
    slcan_layout.addWidget(bitrate)
    slcan_layout.addWidget(QLabel('Adapter baud rate (not applicable to USB-CAN adapters):'))
    slcan_layout.addWidget(baudrate)

    slcan_group.setLayout(slcan_layout)

    layout.addWidget(slcan_group)
    layout.addWidget(ok)
    layout.setSizeConstraint(layout.SetFixedSize)
    win.setLayout(layout)

    with BackgroundIfaceListUpdater() as iface_lister:
        update_slcan_options_visibility()
        update_iface_list()
        timer = QTimer(win)
        timer.setSingleShot(False)
        timer.timeout.connect(update_iface_list)
        timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000))
        win.exec()

    return result, kwargs
def run_setup_window(icon):
    win = QDialog()
    win.setWindowTitle('Application Setup')
    win.setWindowIcon(icon)
    win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint
                       | Qt.WindowCloseButtonHint)
    win.setAttribute(
        Qt.WA_DeleteOnClose)  # This is required to stop background timers!

    combo = QComboBox(win)
    combo.setEditable(True)
    combo.setInsertPolicy(QComboBox.NoInsert)
    combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    combo.setFont(get_monospace_font())

    combo_completer = QCompleter()
    combo_completer.setCaseSensitivity(Qt.CaseSensitive)
    combo_completer.setModel(combo.model())
    combo.setCompleter(combo_completer)

    bitrate = QSpinBox(win)
    bitrate.setMaximum(1000000)
    bitrate.setMinimum(10000)
    bitrate.setValue(1000000)

    baudrate = QComboBox(win)
    baudrate.setEditable(True)
    baudrate.setInsertPolicy(QComboBox.NoInsert)
    baudrate.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    baudrate.setFont(get_monospace_font())

    baudrate_completer = QCompleter(win)
    baudrate_completer.setModel(baudrate.model())
    baudrate.setCompleter(baudrate_completer)

    baudrate.setValidator(
        QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)))
    baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES))
    baudrate.setCurrentText(str(DEFAULT_BAUD_RATE))

    dir_selection = DirectorySelectionWidget(win)

    ok = QPushButton('OK', win)

    def update_slcan_options_visibility():
        if RUNNING_ON_LINUX:
            slcan_active = '/' in combo.currentText()
        else:
            slcan_active = True
        slcan_group.setEnabled(slcan_active)

    combo.currentTextChanged.connect(update_slcan_options_visibility)

    ifaces = None

    def update_iface_list():
        nonlocal ifaces
        ifaces = iface_lister.get_list()
        known_keys = set()
        remove_indices = []
        was_empty = combo.count() == 0
        # Marking known and scheduling for removal
        for idx in count():
            tx = combo.itemText(idx)
            if not tx:
                break
            known_keys.add(tx)
            if tx not in ifaces:
                logger.debug('Removing iface %r', tx)
                remove_indices.append(idx)
        # Removing - starting from the last item in order to retain indexes
        for idx in remove_indices[::-1]:
            combo.removeItem(idx)
        # Adding new items - starting from the last item in order to retain the final order
        for key in list(ifaces.keys())[::-1]:
            if key not in known_keys:
                logger.debug('Adding iface %r', key)
                combo.insertItem(0, key)
        # Updating selection
        if was_empty:
            combo.setCurrentIndex(0)

    result = None
    kwargs = {}

    def on_ok():
        nonlocal result, kwargs
        try:
            baud_rate_value = int(baudrate.currentText())
        except ValueError:
            show_error('Invalid parameters',
                       'Could not parse baud rate',
                       'Please specify correct baud rate',
                       parent=win)
            return
        if not (min(STANDARD_BAUD_RATES) <= baud_rate_value <=
                max(STANDARD_BAUD_RATES)):
            show_error('Invalid parameters',
                       'Baud rate is out of range',
                       'Baud rate value should be within [%s, %s]' %
                       (min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)),
                       parent=win)
            return
        kwargs['baudrate'] = baud_rate_value
        kwargs['bitrate'] = int(bitrate.value())
        result_key = str(combo.currentText()).strip()
        if not result_key:
            show_error('Invalid parameters',
                       'Interface name cannot be empty',
                       'Please select a valid interface',
                       parent=win)
            return
        try:
            result = ifaces[result_key]
        except KeyError:
            result = result_key
        win.close()

    ok.clicked.connect(on_ok)

    can_group = QGroupBox('CAN interface setup', win)
    can_layout = QVBoxLayout()
    can_layout.addWidget(QLabel('Select CAN interface'))
    can_layout.addWidget(combo)

    slcan_group = QGroupBox('SLCAN adapter settings', win)
    slcan_layout = QGridLayout()
    slcan_layout.addWidget(QLabel('CAN bus bit rate:'), 0, 0)
    slcan_layout.addWidget(bitrate, 0, 1)
    slcan_layout.addWidget(
        QLabel('Adapter baud rate (not applicable to USB-CAN adapters):'), 1,
        0)
    slcan_layout.addWidget(baudrate, 1, 1)
    slcan_group.setLayout(slcan_layout)

    can_layout.addWidget(slcan_group)
    can_group.setLayout(can_layout)

    layout = QVBoxLayout()
    layout.addWidget(can_group)
    layout.addWidget(dir_selection)
    layout.addWidget(ok)
    layout.setSizeConstraint(layout.SetFixedSize)
    win.setLayout(layout)

    with BackgroundIfaceListUpdater() as iface_lister:
        update_slcan_options_visibility()
        update_iface_list()
        timer = QTimer(win)
        timer.setSingleShot(False)
        timer.timeout.connect(update_iface_list)
        timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000))
        win.exec()

    return result, kwargs, dir_selection.get_selection()
Esempio n. 33
0
class SvgView(QWidget):
    def __init__(self, dockwidget):
        super(SvgView, self).__init__(dockwidget)

        self._document = None
        self._setting_zoom = False

        self.view = view.View(self)

        self.pageLabel = QLabel()
        self.pageCombo = QComboBox(sizeAdjustPolicy=QComboBox.AdjustToContents)

        layout = QVBoxLayout(spacing=0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        hbox = QHBoxLayout(spacing=0)
        hbox.addWidget(self.pageLabel)
        hbox.addWidget(self.pageCombo)

        self.zoomInButton = QToolButton(autoRaise=True)
        self.zoomOutButton = QToolButton(autoRaise=True)
        self.zoomOriginalButton = QToolButton(autoRaise=True)
        self.zoomNumber = QSpinBox(minimum=10, maximum=1000, suffix="%")
        ac = dockwidget.actionCollection
        self.zoomInButton.setDefaultAction(ac.svg_zoom_in)
        self.zoomOutButton.setDefaultAction(ac.svg_zoom_out)
        self.zoomOriginalButton.setDefaultAction(ac.svg_zoom_original)
        hbox.addWidget(self.zoomInButton)
        hbox.addWidget(self.zoomNumber)
        hbox.addWidget(self.zoomOutButton)
        hbox.addWidget(self.zoomOriginalButton)

        self.resetButton = QPushButton("reload", self)
        self.resetButton.clicked.connect(self.reLoadDoc)
        hbox.addWidget(self.resetButton)

        self.saveButton = QPushButton("save edits", self)
        self.saveButton.clicked.connect(self.callSave)
        hbox.addWidget(self.saveButton)

        hbox.addStretch(1)
        layout.addLayout(hbox)
        layout.addWidget(self.view)

        app.jobFinished.connect(self.initSvg)
        app.documentClosed.connect(self.slotDocumentClosed)
        app.documentLoaded.connect(self.initSvg)
        self.pageCombo.currentIndexChanged.connect(self.changePage)
        self.zoomNumber.valueChanged.connect(self.slotZoomNumberChanged)
        self.view.zoomFactorChanged.connect(self.slotViewZoomChanged)
        dockwidget.mainwindow().currentDocumentChanged.connect(self.initSvg)
        self.zoomNumber.setValue(100)
        doc = dockwidget.mainwindow().currentDocument()
        if doc:
            self.initSvg(doc)
        app.translateUI(self)

    def translateUI(self):
        self.pageLabel.setText(_("Page:"))

    def mainwindow(self):
        return self.parent().mainwindow()

    def initSvg(self, doc):
        """Opens first page of score after compilation"""
        if doc == self.mainwindow().currentDocument():
            files = svgfiles.SvgFiles.instance(doc)
            model = files.model()  # forces update
            if files:
                self._document = doc
                with qutil.signalsBlocked(self.pageCombo):
                    self.pageCombo.setModel(model)
                    self.pageCombo.setCurrentIndex(files.current)
                self.view.load(files.url(files.current))

    def reLoadDoc(self):
        """Reloads current document."""
        if self._document:
            self.initSvg(self._document)

    def callSave(self):
        """Call save function"""
        self.view.evalSave()

    def getCurrent(self):
        files = svgfiles.SvgFiles.instance(self._document)
        return files.filename(files.current)

    def slotZoomNumberChanged(self, value):
        self._setting_zoom = True
        self.view.setZoomFactor(value / 100.0)
        self._setting_zoom = False

    def slotViewZoomChanged(self):
        if not self._setting_zoom:
            self.zoomNumber.setValue(int(self.view.zoomFactor() * 100))

    def changePage(self, page_index):
        """change page of score"""
        doc = self._document
        if doc:
            files = svgfiles.SvgFiles.instance(doc)
            if files:
                files.current = page_index
                svg = files.url(page_index)
                self.view.load(svg)

    def slotDocumentClosed(self, doc):
        if doc == self._document:
            self._document = None
            if self.pageCombo.model():
                self.pageCombo.model().deleteLater()
            self.pageCombo.clear()
            self.pageCombo.update()  # otherwise it doesn't redraw
            self.view.clear()
Esempio n. 34
0
class SelectModelWidget(QWidget):
    """QTabWidget that holds all of the selectable models and the accompanying ModelDialog for each.
    """
    update_progressbar = pyqtSignal(int, bool)

    def __init__(self, parent=None):
        super(SelectModelWidget, self).__init__(parent)
        self.logger = logging.getLogger(__name__)
        self.parent = parent
        self.threadpool = QThreadPool()
        self.logger.info(
            f"Multithreading enabled with a maximum of {self.threadpool.maxThreadCount()} threads."
        )

        print("Multithreading with maximum %d threads" %
              self.threadpool.maxThreadCount())
        self.training_data = pd.DataFrame()
        self.training_predictions = pd.DataFrame()
        self.selected_version = CONFIG.get('PATHS', 'DefaultModelDirectory')
        self.comms = Communicate()

        self.selected_models = {}
        self.selected_models['sklearn'] = {}
        self.selected_models['tensorflow'] = {}
        self.model_checkboxes = []
        # * Initialize training parameter dict.
        # * Has entry for both model base types
        self.training_params = {}
        self.training_params['sklearn'] = {}
        self.training_params['sklearn']['type'] = None
        self.training_params['sklearn']['value'] = None
        self.training_params['tensorflow'] = {}
        # * Init tuning param dict
        # * Currently only using gridsearch
        self.tuning_params = {}
        self.tuning_params['gridsearch'] = {
            'n_iter': 20,
            'cv': 3,
            'n_jobs': -1,
            'scoring': ['accuracy'],
            'tune_stacker': False
        }

        self.sklearn_model_dialogs = []
        self.sklearn_model_dialog_btns = []
        self.sklearn_training_inputs = []

        self.tensorflow_training_inputs = []
        self.tensorflow_model_dialogs = []
        self.tensorflow_model_dialog_btns = []

        self.main_layout = QVBoxLayout()
        self.upper_hbox = QHBoxLayout()

        self.version_form = QFormLayout()
        self.header_hbox = QHBoxLayout()
        self.header_hbox.addLayout(self.version_form)
        self.header_hbox.addStretch()
        self.tune_models_chkbox = QCheckBox("Tune Models")
        self.header_hbox.addWidget(self.tune_models_chkbox)
        self.tune_models_chkbox.stateChanged.connect(
            lambda state: self._enable_tuning_ui(state))
        self.main_layout.addLayout(self.header_hbox)
        self.main_layout.addLayout(self.upper_hbox)

        self.model_vbox = QVBoxLayout()
        self.tuning_vbox = QVBoxLayout()

        self.upper_hbox.addLayout(self.model_vbox)
        self.upper_hbox.addSpacing(10)
        self.upper_hbox.addLayout(self.tuning_vbox)
        self.upper_hbox.addSpacing(200)
        # * Build sklearn ui components
        self.sklearn_hbox = QHBoxLayout()
        self.sklearn_groupbox = QGroupBox("Sklearn")
        self.sklearn_groupbox.setLayout(self.sklearn_hbox)

        self.skmodel_groupbox = QGroupBox("Model Selection")
        self.sklearn_hbox.addWidget(self.skmodel_groupbox)
        self.sklearn_model_form = QFormLayout()
        self.sklearn_model_form.setFormAlignment(Qt.AlignTop)
        self.skmodel_groupbox.setLayout(self.sklearn_model_form)

        # * Sklearn training and tuning ui components
        self.sklearn_training_groupbox = QGroupBox("Training")
        self.sklearn_training_form = QFormLayout()
        self.sklearn_training_groupbox.setLayout(self.sklearn_training_form)
        self.sklearn_hbox.addWidget(self.sklearn_training_groupbox)

        self.model_vbox.addWidget(self.sklearn_groupbox)

        # * Build Tensorflow ui components
        self.tensorflow_hbox = QHBoxLayout()
        self.tensorflow_groupbox = QGroupBox("Tensorflow")
        self.tensorflow_groupbox.setLayout(self.tensorflow_hbox)

        self.tensorflow_model_groupbox = QGroupBox("Model Selection")
        self.tensorflow_hbox.addWidget(self.tensorflow_model_groupbox)
        self.tensorflow_model_form = QFormLayout()

        self.tensorflow_model_groupbox.setLayout(self.tensorflow_model_form)
        self.tensorflow_training_groupbox = QGroupBox("Training")
        self.tensorflow_training_form = QFormLayout()
        self.tensorflow_training_groupbox.setLayout(
            self.tensorflow_training_form)
        self.tensorflow_hbox.addWidget(self.tensorflow_training_groupbox)

        # * This is the tensorflow groupbox for models and training params.
        # self.model_vbox.addWidget(self.tensorflow_groupbox)

        self.tuning_groupbox = QGroupBox("Tuning")
        self.tuning_form = QFormLayout()
        self.tuning_groupbox.setLayout(self.tuning_form)
        self.tuning_vbox.addWidget(self.tuning_groupbox)
        self.tuning_groupbox.setEnabled(False)
        self.model_form_grid = QGridLayout()

        self.setup_model_selection_ui()
        self.setup_training_ui()
        self.setup_tuning_ui()
        # * QTextEdit box for training/tuning status
        self.training_logger = QTextEdit()
        self.training_logger.setReadOnly(True)
        self.training_logger.setAcceptRichText(True)
        self.training_logger.insertHtml(
            "<i>Multithreading with maximum %d threads</i><br>" %
            self.threadpool.maxThreadCount())
        self.training_logger.setMinimumHeight(400)
        self.main_layout.addWidget(self.training_logger)
        self.clear_btn_hbox = QHBoxLayout()
        self.clear_text_btn = QPushButton('Clear')
        self.clear_text_btn.setMaximumWidth(50)
        self.clear_text_btn.clicked.connect(
            lambda: self.training_logger.clear())
        self.clear_btn_hbox.addStretch()
        self.clear_btn_hbox.addWidget(self.clear_text_btn)

        self.main_layout.addLayout(self.clear_btn_hbox)

        self.main_layout.addStretch()
        self.run_btn = QPushButton("&Train Models")
        self.run_btn.setMinimumWidth(200)
        self.run_btn.clicked.connect(lambda: self.train_models())
        self.run_btn.setEnabled(False)

        self.stop_btn = QPushButton('Sto&p')
        self.stop_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)

        self.comms.enable_training_btn.connect(self.set_training_btn_state)
        self.button_hbox = QHBoxLayout()

        icon = QIcon()
        icon.addPixmap(QPixmap('icons/Programming-Save-icon.png'))
        self.save_results_btn = QPushButton()
        self.save_results_btn.setIcon(icon)
        self.save_results_btn.setEnabled(False)
        self.save_results_btn.setToolTip(
            'Save model evaluation predictions, agreement ratio, and bamboozled score'
        )
        self.save_results_btn.clicked.connect(lambda: self.save_predictions())

        self.button_hbox.addWidget(self.run_btn)
        self.button_hbox.addWidget(self.stop_btn)
        self.button_hbox.addStretch()
        self.button_hbox.addWidget(self.save_results_btn)
        self.main_layout.addLayout(self.button_hbox)
        self.setLayout(self.main_layout)

        # Trigger update to load model parameters
        self._update_version(self.version_selection.currentData())

    def setup_model_selection_ui(self):
        """
        Setup model selection ui.

        The order of the parameters in ModelDialog matters.  model_data must come first!
        """
        self.version_selection_label = QLabel("Select version: ")
        self.version_selection = QComboBox(objectName='version_select')
        self.version_selection.setMinimumWidth(100)
        # Changed default models to a unique directory.  This
        # is where default models will be saved.
        # self.version_selection.addItem(
        #     'default', '.\\package\\data\\default_models\\default')
        available_versions = os.listdir(BASE_VERSION_DIR)
        for version in available_versions:
            v_path = os.path.join(BASE_VERSION_DIR, version)
            if os.path.isdir(v_path):
                self.version_selection.addItem(version, v_path)
        self.version_selection.currentIndexChanged.connect(
            lambda x, y=self.version_selection: self._update_version(
                y.currentData()))
        self.version_form.addRow(self.version_selection_label,
                                 self.version_selection)

        # Load base TF-IDF features
        # and feature selection data
        try:
            with open(CONFIG.get('PATHS', 'BaseTfidfDirectory'), 'r') as f:
                tfidf_data = json.load(f)
        except IOError as ioe:
            self.logger.error("Error loading base TFIDF params", exc_info=True)
            exceptionWarning(
                'Error occurred while loading base TFIDF parameters.',
                repr(ioe))
        try:
            with open(CONFIG.get('PATHS', 'BaseFeatureSeletionDirectory'),
                      'r') as f:
                self.fs_params = json.load(f)
        except IOError as ioe:
            self.logger.error("Error loading base feature selector params",
                              exc_info=True)
            exceptionWarning(
                'Error occurred while loading base feature selector parameters.',
                repr(ioe))
        # Dynamically generate ModelDialogs for each model in the base model directory.
        # Only considers *.json file extension.
        try:
            row = 0
            for filename in os.listdir(
                    CONFIG.get('PATHS', 'BaseModelDirectory')):
                if filename.endswith('.json'):
                    with open(
                            os.path.join(
                                CONFIG.get('PATHS', 'BaseModelDirectory'),
                                filename), 'r') as f:
                        model_data = json.load(f)
                        model = model_data['model_class']
                        model_base = model_data['model_base']
                        model_module = model_data['model_module']
                        #! The order of the arguments matters!  model_data must come first.
                        if model_base == 'tensorflow':
                            continue
                            # model_dialog = SkModelDialog(self, model_data)
                        if model_module == 'tpot':
                            model_dialog = TPOTModelDialog(
                                self, model_data, tfidf_data)
                        else:
                            model_dialog = SkModelDialog(
                                self, model_data, tfidf_data, self.fs_params)
                        self.comms.version_change.connect(
                            model_dialog.update_version)
                        # Initialize model as unselected
                        self.selected_models[model_base][model] = False
                        btn = QPushButton(model, objectName=model + '_btn')
                        # Partial allows the connection of dynamically generated QObjects
                        btn.clicked.connect(
                            partial(self.open_dialog, model_dialog))
                        chkbox = QCheckBox(objectName=model)
                        chkbox.stateChanged.connect(
                            lambda state, x=model, y=model_base: self.
                            _update_selected_models(x, y, state))
                        if model_base == 'tensorflow':
                            self.tensorflow_model_form.addRow(chkbox, btn)
                            self.tensorflow_model_dialogs.append(model_dialog)
                            self.tensorflow_model_dialog_btns.append(btn)
                        else:
                            self.sklearn_model_form.addRow(chkbox, btn)
                            self.sklearn_model_dialogs.append(model_dialog)
                            self.sklearn_model_dialog_btns.append(btn)
                        self.model_checkboxes.append(chkbox)
                        row += 1
        except OSError as ose:
            self.logger.error("OSError opening model config files",
                              exc_info=True)
            exceptionWarning('OSError opening model config files!', ose)
            tb = traceback.format_exc()
            print(tb)
        except Exception as e:
            self.logger.error("Error opening model config files",
                              exc_info=True)
            exceptionWarning('Error occured.', e)
            tb = traceback.format_exc()
            print(tb)

    def setup_training_ui(self):
        """
        Build ui components for training parameters for both Sklearn and Tensorflow
        """
        # Sklearn training first
        self.cv_n_fold_input = QSpinBox(objectName='n_folds')
        self.cv_n_fold_input.setRange(2, 10)
        self.cv_n_fold_input.setValue(5)
        self.cv_n_fold_input.setEnabled(False)
        self.cv_n_fold_input.valueChanged.connect(
            lambda state, x=self.cv_n_fold_input: self.update_training_params(
                'sklearn', 'cv', x.value()))
        self.cv_radio_btn = QRadioButton("Cross-validation", objectName='cv')
        self.cv_radio_btn.toggled.connect(
            lambda state, x=self.cv_n_fold_input: self.
            _update_sklearn_training_type('cv', x.value()))
        self.sklearn_training_form.addRow(self.cv_radio_btn,
                                          self.cv_n_fold_input)

        self.sk_validation_radio_btn = QRadioButton("Validation set")
        self.sk_validation_percent_input = QDoubleSpinBox(
            objectName='test_split')
        self.sk_validation_percent_input.setRange(0.05, 1)
        self.sk_validation_percent_input.setSingleStep(0.1)
        self.sk_validation_percent_input.setEnabled(False)
        self.sk_validation_percent_input.valueChanged.connect(
            lambda state, x=self.sk_validation_percent_input: self.
            update_training_params('sklearn', 'validation', x.value()))

        self.sk_validation_radio_btn.toggled.connect(
            lambda state, x=self.sk_validation_percent_input: self.
            _update_sklearn_training_type('validation', x.value()))
        # NOTE: Removing validation split option from evaluation.  It seems less than useful and
        # requires time that could be spent elsewhere as we near the end of our time together.
        # self.sklearn_training_form.addRow(self.sk_validation_radio_btn, self.sk_validation_percent_input)

        self.no_eval_btn = QRadioButton("No evaluation set",
                                        objectName='no_eval')
        self.no_eval_btn.toggled.connect(
            lambda: self._update_sklearn_training_type(None, None))
        self.sklearn_training_form.addRow(self.no_eval_btn)
        # TENSORFLOW TRAINING UI.  Removed as of 10/04/19

        # Toggle to set params on load
        self.cv_radio_btn.toggle()

        # * Select stacker
        # self.stacker_groupbox = QGroupBox('Stacking algorithm')
        # self.stacker_vbox = QVBoxLayout()
        # self.train_stacker

    def setup_tuning_ui(self):
        self.tuning_n_iter_label = QLabel("Number of iterations:")
        self.tuning_n_iter_input = QSpinBox(objectName='n_iter')
        self.tuning_n_iter_input.setRange(2, 1000)
        self.tuning_n_iter_input.setSingleStep(1)
        self.tuning_n_iter_input.setValue(10)
        self.tuning_n_iter_input.valueChanged.connect(
            lambda state, x=self.tuning_n_iter_input: self.
            update_tuning_params('gridsearch', 'n_iter', x.value()))
        self.tuning_form.addRow(self.tuning_n_iter_label,
                                self.tuning_n_iter_input)

        self.tuning_cv_label = QLabel("CV folds:")
        self.tuning_cv_input = QSpinBox(objectName='cv')
        self.tuning_cv_input.setRange(2, 10)
        self.tuning_cv_input.setValue(3)
        self.tuning_cv_input.valueChanged.connect(
            lambda state, x=self.tuning_cv_input: self.update_tuning_params(
                'gridsearch', 'cv', x.value()))
        self.tuning_form.addRow(self.tuning_cv_label, self.tuning_cv_input)

        self.tuning_n_jobs_label = QLabel("Number of parallel jobs:")
        self.tuning_n_jobs_input = QSpinBox(objectName='n_jobs')
        self.tuning_n_jobs_input.setRange(-1, 4)
        self.tuning_n_jobs_input.setValue(-1)
        self.tuning_n_jobs_input.valueChanged.connect(
            lambda state, x=self.tuning_n_jobs_input: self.
            update_tuning_params('gridsearch', 'n_jobs', x.value()))
        self.tuning_form.addRow(self.tuning_n_jobs_label,
                                self.tuning_n_jobs_input)

        self.scoring_metric_groupbox = QGroupBox('Scoring metrics')

        self.scoring_metric_vbox = QVBoxLayout()
        # * The following code is for metric radio buttons.  Left in for posterity
        # self.acc_checkbox = QRadioButton('Accuracy')
        # self.acc_checkbox.setChecked(True)
        # self.acc_checkbox.toggled.connect(
        #     lambda state, x=self.acc_checkbox:
        #     self.update_tuning_params('gridsearch', 'scoring', 'accuracy')
        # )
        # self.scoring_metric_vbox.addWidget(self.acc_checkbox)

        # self.f1_weighted_checkbox = QRadioButton('F1 weighted')
        # self.f1_weighted_checkbox.setChecked(False)
        # self.f1_weighted_checkbox.toggled.connect(
        #     lambda state, x=self.f1_weighted_checkbox:
        #     self.update_tuning_params('gridsearch', 'scoring', 'f1_weighted')
        # )
        # self.scoring_metric_vbox.addWidget(self.f1_weighted_checkbox)

        # self.prec_weighted_checkbox = QRadioButton('Precision weighted')
        # self.prec_weighted_checkbox.setChecked(False)
        # self.prec_weighted_checkbox.toggled.connect(
        #     lambda state, x=self.prec_weighted_checkbox:
        #     self.update_tuning_params(
        #         'gridsearch', 'scoring', 'precision_weighted')
        # )
        # self.scoring_metric_vbox.addWidget(self.prec_weighted_checkbox)

        self.acc_checkbox = QCheckBox('Accuracy')
        self.acc_checkbox.setChecked(True)
        self.acc_checkbox.stateChanged.connect(
            lambda state, x=self.acc_checkbox: self.update_tuning_params(
                'gridsearch', 'accuracy', state, True))
        self.scoring_metric_vbox.addWidget(self.acc_checkbox)

        self.f1_weighted_checkbox = QCheckBox('F1 weighted')
        self.f1_weighted_checkbox.setChecked(False)
        self.f1_weighted_checkbox.stateChanged.connect(
            lambda state, x=self.f1_weighted_checkbox: self.
            update_tuning_params('gridsearch', 'f1_weighted', state, True))
        self.scoring_metric_vbox.addWidget(self.f1_weighted_checkbox)

        self.prec_weighted_checkbox = QCheckBox('Precision weighted')
        self.prec_weighted_checkbox.setChecked(False)
        self.prec_weighted_checkbox.stateChanged.connect(
            lambda state, x=self.
            prec_weighted_checkbox: self.update_tuning_params(
                'gridsearch', 'precision_weighted', state, True))
        self.scoring_metric_vbox.addWidget(self.prec_weighted_checkbox)

        self.scoring_metric_groupbox.setLayout(self.scoring_metric_vbox)

        self.tune_stacker_checkbox = QCheckBox('Tune Stacking Algorithm')
        self.tune_stacker_checkbox.setChecked(False)
        self.tune_stacker_checkbox.stateChanged.connect(
            lambda state, x=self.tune_stacker_checkbox: self.
            update_tuning_params('gridsearch', 'tune_stacker', state))
        self.tuning_form.addRow(self.scoring_metric_groupbox)
        self.tuning_form.addRow(self.tune_stacker_checkbox)

    def open_dialog(self, dialog):
        """
        Opens the passed ModelDialog via the save_params function, allowing the user
        to specify hyperparameters for each available version field.  

            # Arguments
                dialog: ModelDialog, Specified model dialog.
        """
        dialog.save_params()

    @pyqtSlot(str)
    def add_new_version(self, v_dir):
        """
        pyqtSlot to receive new version created pyqtSignal.

            # Arguments
                v_dir: string, directory of newly created version.
        """
        version = v_dir.split('\\')[-1]
        self.version_selection.addItem(version, v_dir)
        self.version_selection.model().sort(0)

    @pyqtSlot(pd.DataFrame)
    def load_data(self, data):
        """
        pyqtSlot to receive pandas DataFrame after DataLoader has completed it's work

            # Arguments
                data: pandas.DataFrame, training data
        """
        self.training_data = data
        self.comms.enable_training_btn.emit(True)

    @pyqtSlot(Qt.CheckState)
    def set_training_btn_state(self):
        """
        Sets the run button enabled state.
        Checks that there are models selected in sklearn or tensorflow 
        """
        if (not self.training_data.empty
                and (1 in self.selected_models['sklearn'].values()
                     or 1 in self.selected_models['tensorflow'].values())):
            self.run_btn.setEnabled(True)
        else:
            self.run_btn.setEnabled(False)

    @pyqtSlot(str, bool)
    def model_exists(self, model_name, truth):
        """
        Adds styling to button if a trained model exists for the model in the selected version

            # Arguments
                model_name: string, name of the model designated by the button.
                truth: bool, true if there exists any trained model of type model_name in the current
                    version.
        """
        btn = self.findChild(QPushButton, model_name + '_btn')
        if btn:
            text = btn.text()
            if text.endswith("*"):
                text = text[:-2]
            if truth:
                btn.setText(text + " *")
            else:
                btn.setText(text)
        else:
            return

    def train_models(self):
        try:
            tune_models = self.tune_models_chkbox.isChecked()
            self.model_trainer = ModelTrainer(
                selected_models=self.selected_models,
                version_directory=self.selected_version,
                training_eval_params=self.training_params,
                training_data=self.training_data,
                tune_models=tune_models,
                tuning_params=self.tuning_params)
            self.model_trainer.signals.update_training_logger.connect(
                self.update_training_logger)
            self.update_progressbar.emit(1, True)
            self.model_trainer.signals.training_complete.connect(
                self.training_complete)
            self.comms.stop_training.connect(self.model_trainer.stop_thread)
            self.run_btn.setEnabled(False)
            self.stop_btn.clicked.connect(lambda: self._abort_training())

            self.training_predictions = pd.DataFrame()
            self.threadpool.start(self.model_trainer)
        except Exception as e:
            self.logger.error("SelectModelWidget.train_models", exc_info=True)
            exceptionWarning('Exception occured when training models.', e)
            tb = traceback.format_exc()
            print(tb)

    @pyqtSlot(str, bool, bool)
    def update_training_logger(self, msg, include_time=True, use_html=True):
        '''
        Slot that receives signals updating the terminal.  
        
            # Arguments
                msg: string, Message to display in terminal
                include_time: bool, prepend time to message
                use_html: bool, insert text as html 
        '''
        if (include_time):
            current_time = time.localtime()
            outbound = f"{time.strftime('%Y-%m-%d %H:%M:%S', current_time)} - {msg}<br>"
        else:
            outbound = f"{msg}<br>"
        if (use_html):
            self.training_logger.insertHtml(outbound)
            self.training_logger.moveCursor(QTextCursor.End)
        else:
            self.training_logger.insertPlainText(msg)

    @pyqtSlot(pd.DataFrame)
    def training_complete(self, prediction_df=None):
        """
        Resets progressbar, unchecks 'Train models', and emits signal to refresh the parameter
        values in each ModelDialog

            # Arguments
                val: int or float, value used to set progressbar
                pulse: bool, used to toggle progressbar pulse
        """
        self.update_progressbar.emit(0, False)
        self.run_btn.setEnabled(True)
        self.run_btn.setText("Train models")
        self.tune_models_chkbox.setChecked(False)
        self.save_results_btn.setEnabled(True)

        if (prediction_df is not None and not prediction_df.empty):
            self.training_predictions = prediction_df
        # Emitting a version change here reloads all parameters.  i.e. we update the
        # parameters displayed in the dialog.
        self.comms.version_change.emit(self.selected_version)

    def save_predictions(self):
        '''
        Save predictions to user specified file.  Opens a QFileDialog to choose save directory.
        '''
        try:
            if self.training_predictions.empty:
                exceptionWarning('No predictions to save')
                return
            file_name, filter = QFileDialog.getSaveFileName(
                self, 'Save to CSV', os.getenv('HOME'), 'CSV(*.csv)')
            if file_name:
                self.training_predictions.to_csv(file_name,
                                                 index_label='testnum',
                                                 quoting=1,
                                                 encoding='utf-8')
                self.comms.update_statusbar.emit(
                    "Predictions saved successfully.")
        except PermissionError as pe:
            self.logger.warning("SelectModelWidget.save_predictions",
                                exc_info=True)
            exceptionWarning(
                f'Permission denied while attempting to save {file_name}')
        except Exception as e:
            self.logger.error("SelectModelWidget.save_predictions",
                              exc_info=True)
            exceptionWarning(
                "Exception occured.  SelectModelWidget.save_predictions.",
                exception=e)
            tb = traceback.format_exc()
            print(tb)

    def _abort_training(self):
        '''
        Notifies the ModelTrainer to abort training.
        ! Note: training ends only after the current training or tuning event ends.
        '''
        self.comms.stop_training.emit()

    def _update_version(self, directory):
        """
        Parses selected version directory and emits pyqtSignal to update each ModelDialog

            # Arguments
                directory: string, directory selected by user.
        """
        self.selected_version = directory
        # Emit pyqtSignal
        self.comms.version_change.emit(directory)

    def _update_selected_models(self, model, model_base, state):
        """
        Update the models selected by the user.  This function is connected to the
        checkboxes associated with each model.

            # Arguments:
                model: string, name of the selected model
                state: bool, the truth of the selection.  True->selected, False->unselected
        """
        truth = False
        if state == Qt.Checked:
            truth = True
        self.selected_models[model_base][model] = truth
        self.comms.enable_training_btn.emit(truth)

    def _enable_tuning_ui(self, state):
        """
        Helper function to enable/disable the tuning parameter UI if selected 
        by the user.

            # Arguments:
                state: bool, the state of tuning.  False->no tuning, True->tune models
        """
        self.run_btn.setText("Tune Models" if state else "Train Models")
        self.tuning_groupbox.setEnabled(state)

    def update_tuning_params(self, model_base, param, value, scorer=False):
        '''
        Updates the tuning parameters passed to ModelTrainer.

            # Arguments
                model_base: string, Signifies which type of tuning parameter to update.  Currently, only
                    used by RandomizedSearchCV (sklearn)
                param: string, parameter name
                value: [int, float, string], parameter value
        '''
        if model_base is None or param is None:
            return
        try:
            if scorer:
                if value:
                    self.tuning_params[model_base]['scoring'].append(param)
                else:
                    if param in self.tuning_params[model_base]['scoring']:
                        self.tuning_params[model_base]['scoring'].remove(param)
            else:
                self.tuning_params[model_base][param] = value
        except KeyError as ke:
            self.tuning_params[model_base][param] = {}
            self.tuning_params[model_base][param] = value
        except Exception as e:
            self.logger.error("SelectModelWidget.update_tuning_params",
                              exc_info=True)
            exceptionWarning('Exception occured when training models.', e)
            tb = traceback.format_exc()
            print(tb)
        print(self.tuning_params)

    def update_training_params(self, model_base, param, value):
        """
        Update the various training parameters with values supplied by the user.
        Needs work as the sklearn training parameters are mutually exclusive.

            # Arguments
                model_base: string, model base for specified training params
                param: string, parameter name
                value: string, int, or double, value of specified parameter
        """
        if model_base is None or param is None:
            return
        try:
            # FIXME: This is super hackish and brittle.  Can it be done more eloquently?
            if model_base == 'sklearn':
                self._update_sklearn_training_type(param, value)
            else:
                self.training_params[model_base][param] = value
        except KeyError as ke:
            print(ke)

    def _update_sklearn_training_type(self, eval_type, value):
        """
        SKlearn model tuning is mutually exclusive.  This helper function
        Enables/disables the appropriate field and updates the appropriate
        parameters of self.training_params

        Currently, for Sklearn models, only cross-validation (cv) or a holdout set
        (validation) or None are model evaluation options.  

            # Arguments
                eval_type: string, The type of model evaluation specified by the user.
                value: int or double, value corresponding to selected type
        """
        truth = False
        if eval_type == 'cv':
            self.cv_n_fold_input.setEnabled(not truth)
            self.sk_validation_percent_input.setEnabled(truth)
        elif eval_type == 'validation':
            self.cv_n_fold_input.setEnabled(truth)
            self.sk_validation_percent_input.setEnabled(not truth)
        elif eval_type == None:
            self.cv_n_fold_input.setEnabled(False)
            self.sk_validation_percent_input.setEnabled(False)
        else:
            raise ValueError("eval_type %s is invalid" % (eval_type))

        self.training_params['sklearn']['type'] = eval_type
        self.training_params['sklearn']['value'] = value
def run_iface_config_window(icon):
    win = QDialog()
    win.setWindowTitle('CAN Interface Configuration')
    win.setWindowIcon(icon)
    win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint)

    combo = QComboBox(win)
    combo.setEditable(True)
    combo.setInsertPolicy(QComboBox.NoInsert)
    combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    combo.setFont(get_monospace_font())

    combo_completer = QCompleter()
    combo_completer.setCaseSensitivity(Qt.CaseSensitive)
    combo_completer.setModel(combo.model())
    combo.setCompleter(combo_completer)

    bitrate = QSpinBox()
    bitrate.setMaximum(1000000)
    bitrate.setMinimum(10000)
    bitrate.setValue(1000000)

    extra_args = QLineEdit()
    extra_args.setFont(get_monospace_font())

    ok = QPushButton('OK', win)

    ifaces = None

    def update_iface_list():
        nonlocal ifaces
        ifaces = iface_lister.get_list()
        known_keys = set()
        remove_indices = []
        was_empty = combo.count() == 0
        # Marking known and scheduling for removal
        for idx in count():
            tx = combo.itemText(idx)
            if not tx:
                break
            known_keys.add(tx)
            if tx not in ifaces:
                logger.debug('Removing iface %r', tx)
                remove_indices.append(idx)
        # Removing - starting from the last item in order to retain indexes
        for idx in remove_indices[::-1]:
            combo.removeItem(idx)
        # Adding new items - starting from the last item in order to retain the final order
        for key in list(ifaces.keys())[::-1]:
            if key not in known_keys:
                logger.debug('Adding iface %r', key)
                combo.insertItem(0, key)
        # Updating selection
        if was_empty:
            combo.setCurrentIndex(0)

    result = None
    kwargs = {}

    def on_ok():
        nonlocal result, kwargs
        a = str(extra_args.text())
        if a:
            try:
                kwargs = dict(eval(a))
            except Exception as ex:
                show_error('Invalid parameters', 'Could not parse optional arguments', ex, parent=win)
                return
        kwargs['bitrate'] = int(bitrate.value())
        result_key = str(combo.currentText()).strip()
        if not result_key:
            show_error('Invalid parameters', 'Interface name cannot be empty', 'Please select a valid interface',
                       parent=win)
            return
        try:
            result = ifaces[result_key]
        except KeyError:
            result = result_key
        win.close()

    ok.clicked.connect(on_ok)

    layout = QVBoxLayout()
    layout.addWidget(QLabel('Select CAN interface or serial port for SLCAN:'))
    layout.addWidget(combo)
    layout.addWidget(QLabel('Interface bitrate (SLCAN only):'))
    layout.addWidget(bitrate)
    layout.addWidget(QLabel('Optional arguments (refer to PyUAVCAN for info):'))
    layout.addWidget(extra_args)
    layout.addWidget(ok)
    layout.setSizeConstraint(layout.SetFixedSize)
    win.setLayout(layout)

    with BackgroundIfaceListUpdater() as iface_lister:
        update_iface_list()
        timer = QTimer(win)
        timer.setSingleShot(False)
        timer.timeout.connect(update_iface_list)
        timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000))
        win.exec()

    return result, kwargs
Esempio n. 36
0
class Drums(_base.Part):
    @staticmethod
    def title(_=_base.translate):
        return _("Drums")
    
    @staticmethod
    def short(_=_base.translate):
        return _("abbreviation for Drums", "Dr.")
        
    def createWidgets(self, layout):
        self.voicesLabel = QLabel()
        self.voices = QSpinBox(minimum=1, maximum=4, value=1)
        self.drumStyleLabel = QLabel()
        self.drumStyle = QComboBox()
        self.drumStyle.setModel(listmodel.ListModel(drumStyles, self.drumStyle, display=listmodel.translate))
        self.drumStems = QCheckBox()
        
        box = QHBoxLayout()
        box.addWidget(self.voicesLabel)
        box.addWidget(self.voices)
        layout.addLayout(box)
        box = QHBoxLayout()
        box.addWidget(self.drumStyleLabel)
        box.addWidget(self.drumStyle)
        layout.addLayout(box)
        layout.addWidget(self.drumStems)
        
    def translateWidgets(self):
        self.voicesLabel.setText(_("Voices:"))
        self.drumStyleLabel.setText(_("Style:"))
        self.drumStems.setText(_("Remove stems"))
        self.drumStems.setToolTip(_("Remove the stems from the drum notes."))
        self.drumStyle.model().update()
    
    def assignDrums(self, data, name = None):
        r"""Creates an empty name = \drummode assignment.

        Returns the assignment.
        
        """
        a = data.assign(name)
        s = ly.dom.DrumMode(a)
        ly.dom.Identifier(data.globalName, s)
        ly.dom.LineComment(_("Drums follow here."), s)
        ly.dom.BlankLine(s)
        return a

    def build(self, data, builder):
        p = ly.dom.DrumStaff()
        s = ly.dom.Simr(p)
        if self.voices.value() > 1:
            for i in range(1, self.voices.value() + 1):
                q = ly.dom.Seq(ly.dom.DrumVoice(parent=s))
                ly.dom.Text('\\voice' + ly.util.int2text(i), q)
                a = self.assignDrums(data, 'drum' + ly.util.int2text(i))
                ly.dom.Identifier(a.name, q)
        else:
            a = self.assignDrums(data, 'drum')
            ly.dom.Identifier(a.name, s)
        builder.setInstrumentNamesFromPart(p, self, data)
        i = self.drumStyle.currentIndex()
        if i > 0:
            v = ('drums', 'timbales', 'congas', 'bongos', 'percussion')[i]
            p.getWith()['drumStyleTable'] = ly.dom.Scheme(v + '-style')
            v = (5, 2, 2, 2, 1)[i]
            ly.dom.Line("\\override StaffSymbol #'line-count = #{0}".format(v), p.getWith())
        if self.drumStems.isChecked():
            ly.dom.Line("\\override Stem #'stencil = ##f", p.getWith())
            ly.dom.Line("\\override Stem #'length = #3  % " + _("keep some distance."),
                p.getWith())
        data.nodes.append(p)
class SinglePlayerWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(200, 200, 1000, 600)
        self.setWindowTitle("OnePlayer")
        self.initUI()

    def initUI(self):
        self.initWindow()
        self.username()
        self.chooseShip()
        self.buttonPlay()

    def initWindow(self):
        self.BackGround = QPixmap(get_full_image_path("galaxy.jpg"))
        self.BackGroundLabel = QtWidgets.QLabel(self)
        self.BackGroundLabel.setPixmap(self.BackGround)
        self.BackGroundLabel.setGeometry(0, 0, 1000, 600)

    def username(self):
        self.enterNameLabel = QtWidgets.QLabel(self)
        self.enterNameLabel.setText("Enter name")
        self.enterNameLabel.setGeometry(200, 150, 200, 50)
        self.enterNameLabel.setStyleSheet(" color: white;font-size: 26px; font-family: Arial Black;");

        self.player1NameLineEdit = QLineEdit(self)
        self.player1NameLineEdit.setGeometry(200, 200, 200, 50)

    def chooseShip(self):
        self.choseShipLabel = QLabel(self)
        self.choseShipLabel.setText("Choose ship")
        self.choseShipLabel.setGeometry(410, 150, 200, 50)
        self.choseShipLabel.setStyleSheet(" color: white;font-size: 26px; font-family: Arial Black;");

        self.player1Cb = QComboBox(self)
        self.player1Cb.setStyleSheet("border:1px solid rgb(220, 20, 60); color: red; font-family: Helvetica;");
        self.player1Cb.addItem("")
        self.player1Cb.addItem("red")
        self.player1Cb.addItem("green")
        self.player1Cb.addItem("yellow")
        self.player1Cb.addItem("blue")

        self.player1Cb.model().item(0).setEnabled(False)
        self.player1Cb.setGeometry(410, 200, 200, 50)

    def buttonPlay(self):
        self.playButton = QtWidgets.QPushButton(self)
        self.playButton.setText("PLAY")
        self.playButton.setGeometry(750, 400, 200, 50)
        self.playButton.setStyleSheet(
            "border:2px solid rgb(120, 20, 60); color: blue;font-size: 26px; font-family: Arial Black;")
        self.playButton.clicked.connect(self.onPlayButtonClicked)

    def onPlayButtonClicked(self):
        if self.player1NameLineEdit.text() == "" or str(self.player1Cb.currentText()) == "":
            msg = QMessageBox()
            msg.setIcon(QMessageBox.NoIcon)
            msg.setText("Enter your username and choose ship")
            msg.setWindowTitle("Error")
            msg.exec_()
        else:

            player1_input = PlayerInput(player_id=self.player1NameLineEdit.text(), color=self.player1Cb.currentText())

            _start_game_process(player1_input, title="Asteroids - SinglePlayer")
            self.hide()
            self.player1NameLineEdit.setText("")
Esempio n. 38
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.gain = 0xffff
        self.shape = ecodes.FF_SQUARE
        self.period_ms = 10
        self.magnitude = 0x7fff
        self.offset = 0
        self.phase = 0
        self.duration_ms = 1000
        self.repeat_count = 1
        self.envelope_attack_length = 0
        self.envelope_attack_level = 0
        self.envelope_fade_length = 0
        self.envelope_fade_level = 0
        self.id = None

        widget = QWidget(parent=self)
        self.setCentralWidget(widget)

        self.device_selector = QComboBox(parent=widget)
        self.device_selector.setModel(DeviceProvider())

        refresh_button = QPushButton('Refresh', parent=widget)
        refresh_button.clicked.connect(
            lambda: self.device_selector.model().refresh())

        play_button = QPushButton('Play', parent=widget)
        play_button.clicked.connect(self.play_clicked)
        stop_button = QPushButton('Stop', parent=widget)
        stop_button.clicked.connect(self.stop_clicked)

        layout = QGridLayout()

        layout.addWidget(QLabel("Device:"), 0, 0)
        layout.addWidget(self.device_selector, 0, 1)
        layout.addWidget(refresh_button, 0, 2)

        self.add_form(layout, 1, "Gain", 0, 100, 100, self.update_gain)

        effect_widget = QGroupBox("Effect")
        effect_layout = QGridLayout()
        effect_widget.setLayout(effect_layout)
        layout.addWidget(effect_widget, 2, 0, 1, -1)

        effect_layout.addWidget(QLabel("Shape:"), 0, 0)
        shape_selector = ShapeSelector()
        shape_selector.currentIndexChanged.connect(self.update_shape)
        effect_layout.addWidget(shape_selector, 0, 1)

        self.add_form(effect_layout, 1, "Period (ms)", 0, 0xffff, 10,
                      self.update_period)
        self.add_form(effect_layout, 2, "Magnitude", -100, 100, 100,
                      self.update_magnitude)
        self.add_form(effect_layout, 3, "Offset", -0x8000, 0x7fff, 0,
                      self.update_offset)
        self.add_form(effect_layout, 4, "Phase", 0, 0xffff, 0,
                      self.update_phase)
        self.add_form(effect_layout, 5, "Duration (ms)", 0, 0xffff, 1000,
                      self.update_duration)
        self.add_form(effect_layout, 6, "Repeat count", 0, 0x7fffffff, 1,
                      self.update_repeat_count)

        envelope_widget = QGroupBox("Envelope parameters")
        envelope_layout = QGridLayout()
        self.add_form(envelope_layout, 0, "Attack length (ms)", 0, 0xffff, 0,
                      self.update_attack_length)
        self.add_form(envelope_layout, 1, "Attack level", 0, 0xffff, 0,
                      self.update_attack_level)
        self.add_form(envelope_layout, 2, "Fade length (ms)", 0, 0xffff, 0,
                      self.update_fade_length)
        self.add_form(envelope_layout, 3, "Fade level", 0, 0xffff, 0,
                      self.update_fade_level)
        envelope_widget.setLayout(envelope_layout)

        effect_layout.addWidget(envelope_widget, 7, 0, 1, -1)

        w2 = QWidget()
        blayout = QHBoxLayout()
        blayout.addWidget(stop_button)
        blayout.addWidget(play_button)
        w2.setLayout(blayout)
        layout.addWidget(w2, 3, 0, 1, -1)

        layout.setRowStretch(0, 1)
        layout.setRowStretch(1, 1)
        layout.setRowStretch(2, 4)
        layout.setRowStretch(3, 0)

        widget.setLayout(layout)

    def add_form(self, layout, row, label, minimum, maximum, default_value,
                 valueChanged_handler):
        sbox = QSpinBox()
        slider = QSlider()

        sbox.setMinimum(minimum)
        sbox.setMaximum(maximum)
        sbox.setValue(default_value)

        slider.setMinimum(minimum)
        slider.setMaximum(maximum)
        slider.setValue(default_value)
        slider.setOrientation(Qt.Horizontal)

        slider.valueChanged.connect(lambda value: sbox.setValue(value))
        sbox.valueChanged.connect(valueChanged_handler)

        layout.addWidget(QLabel(label + ":"), row, 0)
        layout.addWidget(slider, row, 1)
        layout.addWidget(sbox, row, 2)

    def update_gain(self, value):
        self.gain = int(0xffff * value / 100)

    def update_shape(self, index):
        if index == 0:
            self.shape = ecodes.FF_SQUARE
        elif index == 1:
            self.shape = ecodes.FF_TRIANGLE
        else:
            self.shape = ecodes.FF_SINE

    def update_period(self, value):
        self.period_ms = value

    def update_magnitude(self, value):
        if value > 0:
            self.magnitude = int(0x7fff * value / 100)
        else:
            self.magnitude = int(0xffff * value / 100)

    def update_offset(self, value):
        self.offset = value

    def update_phase(self, value):
        self.phase = value

    def update_duration(self, value):
        self.duration_ms = value

    def update_repeat_count(self, value):
        self.repeat_count = value

    def update_attack_length(self, value):
        self.envelope_attack_length = value

    def update_attack_level(self, value):
        self.envelope_attack_level = value

    def update_fade_length(self, value):
        self.envelope_fade_length = value

    def update_fade_level(self, value):
        self.envelope_fade_level = value

    def play_clicked(self):
        path = self.device_selector.currentData(DEVICE_PATH_ROLE)
        if path is None:
            return

        self.device = InputDevice(path)

        # set the gain
        print("Setting gain to " + str(self.gain))
        self.device.write(ecodes.EV_FF, ecodes.FF_GAIN, self.gain)

        envelope = ff.Envelope(attack_length=self.envelope_attack_length,
                               attack_level=self.envelope_attack_level,
                               fade_length=self.envelope_fade_length,
                               fade_level=self.envelope_fade_level)

        periodic_effect = ff.Periodic(waveform=self.shape,
                                      period=self.period_ms,
                                      magnitude=self.magnitude,
                                      offset=self.offset,
                                      phase=self.phase,
                                      envelope=envelope)

        effect = ff.Effect(ecodes.FF_PERIODIC, -1, 0, ff.Trigger(0, 0),
                           ff.Replay(self.duration_ms, 0),
                           ff.EffectType(ff_periodic_effect=periodic_effect))

        print("playing effect: period: " + str(self.period_ms) +
              ", magnitude: " + str(self.magnitude) + ", offset: " +
              str(self.offset) + ", phase: " + str(self.phase) +
              ", envelope: (" + str(self.envelope_attack_length) + ", " +
              str(self.envelope_fade_level) + ", " +
              str(self.envelope_fade_length) + ", " +
              str(self.envelope_fade_level) + ")")
        self.id = self.device.upload_effect(effect)
        self.device.write(ecodes.EV_FF, self.id, self.repeat_count)

    def stop_clicked(self):
        self.device = None
Esempio n. 39
0
class MultiPlayerWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(200, 200, 1000, 600)
        self.setWindowTitle("MultiPlayer")
        self.initUI()

    def initUI(self):
        self.initWindow()
        self.username()
        self.chooseShip()
        self.labels()
        self.buttonPlay()
        self.buttonCreateOnline()
        self.buttonConnect()

    def initWindow(self):
        self.BackGround = QPixmap(get_full_image_path("galaxy.jpg"))
        self.BackGroundLabel = QtWidgets.QLabel(self)
        self.BackGroundLabel.setPixmap(self.BackGround)
        self.BackGroundLabel.setGeometry(0, 0, 1000, 600)

    def username(self):
        self.lbl2 = QtWidgets.QLabel(self)
        self.lbl2.setText("Enter name")
        self.lbl2.setGeometry(200, 150, 200, 50)
        self.lbl2.setStyleSheet(" color: white;font-size: 26px; font-family: Arial Black;");

        self.player1NameLineEdit = QLineEdit(self)
        self.player1NameLineEdit.setGeometry(200, 200, 200, 50)
        self.player2NameLineEdit = QLineEdit(self)
        self.player2NameLineEdit.setGeometry(200, 300, 200, 50)

    def chooseShip(self):
        self.lbl2 = QLabel(self)
        self.lbl2.setText("Choose ship")
        self.lbl2.setGeometry(410, 150, 200, 50)
        self.lbl2.setStyleSheet(" color: white;font-size: 26px; font-family: Arial Black;");

        self.player1Cb = QComboBox(self)
        self.player1Cb.setStyleSheet(
            "border:1px solid rgb(220, 20, 60);font-size: 20px; color: red; font-family: Helvetica;");
        self.player1Cb.addItem("")
        self.player1Cb.addItem("red")
        self.player1Cb.addItem("green")
        self.player1Cb.addItem("yellow")
        self.player1Cb.addItem("blue")
        self.player1Cb.model().item(0).setEnabled(False)
        self.player1Cb.setGeometry(410, 200, 200, 50)

        self.player2Cb = QComboBox(self)
        self.player2Cb.setStyleSheet(
            "border:1px solid rgb(220, 20, 60);font-size: 20px; color: red; font-family: Helvetica;");
        self.player2Cb.addItem("")
        self.player2Cb.addItem("red")
        self.player2Cb.addItem("green")
        self.player2Cb.addItem("yellow")
        self.player2Cb.addItem("blue")
        self.player2Cb.model().item(0).setEnabled(False)
        self.player2Cb.setGeometry(410, 300, 200, 50)

    def labels(self):
        self.lbl3 = QtWidgets.QLabel(self)
        self.lbl3.setText("First player")
        self.lbl3.setGeometry(10, 200, 200, 50)
        self.lbl3.setStyleSheet(" color: red;font-size: 20px; font-family: Arial ;");

        self.lbl4 = QtWidgets.QLabel(self)
        self.lbl4.setText("Second player")
        self.lbl4.setGeometry(10, 300, 200, 50)
        self.lbl4.setStyleSheet(" color: red;font-size: 20px; font-family: Arial ;");

    def buttonPlay(self):
        self.playButton = QtWidgets.QPushButton(self)
        self.playButton.setText("PLAY LOCAL")
        self.playButton.setGeometry(750, 400, 200, 50)
        self.playButton.setStyleSheet(
            "border:2px solid rgb(120, 20, 60); color: blue;font-size: 26px; font-family: Arial Black;");
        self.playButton.clicked.connect(self.onPlayButtonClicked)

    def buttonCreateOnline(self):
        self.onlineButton = QtWidgets.QPushButton(self)
        self.onlineButton.setText("CREATE GAME")
        self.onlineButton.setGeometry(750, 300, 200, 50)
        self.onlineButton.setStyleSheet(
            "border:2px solid rgb(120, 20, 60); color: blue;font-size: 22px; font-family: Arial Black;");
        self.onlineButton.clicked.connect(self.onCreateButtonClicked)

    def buttonConnect(self):
        self.connectButton = QtWidgets.QPushButton(self)
        self.connectButton.setText("JOIN GAME")
        self.connectButton.setGeometry(750, 350, 200, 50)
        self.connectButton.setStyleSheet(
            "border:2px solid rgb(120, 20, 60); color: blue;font-size: 26px; font-family: Arial Black;");

    def onPlayButtonClicked(self):
        if self.player1NameLineEdit.text() == "" or self.player2NameLineEdit.text() == "" or str(
                self.player1Cb.currentText()) == "" or str(self.player2Cb.currentText()) == "":
            msg = QMessageBox()
            msg.setIcon(QMessageBox.NoIcon)
            msg.setText("Enter your username and choose ship")
            msg.setWindowTitle("Error")
            msg.exec_()

        elif self.player1NameLineEdit.text() == self.player2NameLineEdit.text():
            msg = QMessageBox()
            msg.setIcon(QMessageBox.NoIcon)
            msg.setText("Username must be unique")
            msg.setWindowTitle("Error")
            msg.exec_()

        else:

            player1_input = PlayerInput(player_id=self.player1NameLineEdit.text(), color=self.player1Cb.currentText())
            player2_input = PlayerInput(player_id=self.player2NameLineEdit.text(), color=self.player2Cb.currentText())

            _start_game_process(player1_input, player2_input, title="Asteroids - Multi Player")
            self.hide()
            self.player1NameLineEdit.setText("")
            self.player2NameLineEdit.setText("")


    def onCreateButtonClicked(self):
        if self.player1NameLineEdit.text() == "" or str(self.player1Cb.currentText()) == "":
            msg = QMessageBox()
            msg.setIcon(QMessageBox.NoIcon)
            msg.setText("Enter your username and choose ship")
            msg.setWindowTitle("Error")
            msg.exec_()

        else:
            player1_input = PlayerInput(player_id=self.player1NameLineEdit.text(), color=self.player1Cb.currentText())

            self.server = Server(5)

            self.game = ClientAsteroidsGame('seed', player_inputs=[player1_input], title="Asteroids - Client")
            self.game.start()
Esempio n. 40
0
class InOutTab(OptionsWidget):
    def __init__(self, parent):
        super().__init__(parent)

    def add_contents(self):
        self.add_categories(0)
        self.add_configure(2)
        self.add_radio_level(4)        
        self.add_time_period(5)        
        self.add_radio_log(7,lines=2)
        # self.add_button_data(8)
        self.add_start_button(10)

        self.add_fine_category(11)
        self.add_detail_button(14)        


    def add_categories(self, h):
        self.ComboBox = QComboBox()
        for i,key in enumerate(['Einnahmen', 'Ausgaben']):
            self.ComboBox.addItem(key)
            item = self.ComboBox.model().item(i, 0)
            item.setCheckState(Qt.Unchecked)

        self.ComboBoxAccount = QComboBox()
        self.ComboBoxAccount.addItem("Alle")
        item = self.ComboBoxAccount.model().item(0, 0)        
        for i,key in enumerate(self.parent.DATA.names):
            self.ComboBoxAccount.addItem(key)
            item = self.ComboBoxAccount.model().item(i+1, 0)
            item.setCheckState(Qt.Unchecked)      

        self.layout.addWidget(QLabel("Geldfluss"), h, 0)            
        self.layout.addWidget(self.ComboBox, h, 1, 1, 2)            

        self.layout.addWidget(QLabel("Konto"), h+1, 0)            
        self.layout.addWidget(self.ComboBoxAccount, h+1, 1, 1, 2)   

        # new_frame = QFrame()         


        # self.layout.addWidget(QColumn(QLabel("Geldfluss"),self.ComboBox))
        # self.layout.addWidget(QColumn(QLabel("Konto"),self.ComboBoxAccount))

      


    def on_pushButton_config(self):
        self.cw = ConfigWindow(self, [self.parent.KEYS.IN, self.parent.KEYS.OUT], 
            ["Einnahmen","Ausgaben"], self.parent.KEYS, depth=2)
        self.cw.show()

    def update_data(self, target, df, keywords, level, start, end):
        use_data = analyse.last_entry_of_month_inout(df, keywords, level, start, end)
        data_tab = DataTabs(target, use_data)

    def on_pushButton_start(self):
        self.set_dates()

        if self.radioLevel1.isChecked():            
            level = 0
        else:
            level = 1


        if (self.ComboBox.currentText() == "Einnahmen"):
                all_keys = self.parent.KEYS.IN[level]
        else:
                all_keys = self.parent.KEYS.OUT[level]


        if (self.ComboBoxAccount.currentText() == "Alle"):
                used_data = self.parent.DATA.df_transactions
        else:
                print(self.ComboBoxAccount.currentText())
                used_data = self.parent.DATA.df_transactions[self.parent.DATA.df_transactions['Account']==self.ComboBoxAccount.currentText()]
        print("used_data", used_data)

        s_inout = self.ComboBox.currentText()

        selected_keys = [key for key  in all_keys.keys() if key in self.parent.KEYS.is_included[level]]
        arguments = [used_data, selected_keys, level, self.date_start, self.date_end]

        self.new_plot_window = NewPlotWindow( 
                arg1=["StackedBar" if self.radioPlot1.isChecked() else "StackedBarLog", 
                    *analyse.prepare_stacked_bar(*arguments), s_inout + " pro Monat"],
                arg3 = [],
                arg4=["PieChart", *analyse.prepare_pie_chart(*arguments), "Prozentuale Verteilung der " + s_inout], 
                arg2=["HorizontalBar" if  self.radioPlot1b.isChecked() else "HorizontalBarLog", 
                    *analyse.prepare_horizontal_bar(*arguments), "Durchschnittliche " + s_inout], 
                title="Plots")

        self.update_data(self.new_plot_window, *arguments)    

        self.new_plot_window.show()

    def on_pushButton_details(self):
        self.set_dates()

        level = 0
        all_keys = self.parent.KEYS.OUT[level]

        if (self.ComboBoxAccount.currentText() == "Alle"):
                used_data = self.parent.DATA.df_transactions
        else:
                used_data = self.parent.DATA.df_transactions[self.parent.DATA.df_transactions['Account']==self.ComboBoxAccount.currentText()]

        s_inout = self.ComboBox.currentText()

        selected_keys = [key for key  in all_keys.keys() if key in self.parent.KEYS.OUT[1][self.ComboBoxFine.currentText()]]
        arguments = [used_data, selected_keys, level, self.date_start, self.date_end]

        self.new_plot_window = NewPlotWindow( 
                arg1=["StackedBar" if self.radioPlot1.isChecked() else "StackedBarLog", 
                    *analyse.prepare_stacked_bar(*arguments), s_inout + " pro Monat"],
                arg3 = [],
                arg4=["PieChart", *analyse.prepare_pie_chart(*arguments), "Prozentuale Verteilung der " + s_inout], 
                arg2=["HorizontalBar" if  self.radioPlot1b.isChecked() else "HorizontalBarLog", 
                    *analyse.prepare_horizontal_bar(*arguments), "Durchschnittliche " + s_inout], 
                title="Plots")

        self.update_data(self.new_plot_window, *arguments)    

        self.new_plot_window.show()        
Esempio n. 41
0
class GuiConfigEditGeneral(QWidget):

    def __init__(self, theParent):
        QWidget.__init__(self, theParent)

        self.mainConf  = nw.CONFIG
        self.theParent = theParent
        self.theTheme  = theParent.theTheme
        self.outerBox  = QGridLayout()

        # User Interface
        self.guiLook     = QGroupBox("User Interface", self)
        self.guiLookForm = QGridLayout(self)
        self.guiLook.setLayout(self.guiLookForm)

        self.guiLookTheme = QComboBox()
        self.guiLookTheme.setMinimumWidth(200)
        self.theThemes = self.theTheme.listThemes()
        for themeDir, themeName in self.theThemes:
            self.guiLookTheme.addItem(themeName, themeDir)
        themeIdx = self.guiLookTheme.findData(self.mainConf.guiTheme)
        if themeIdx != -1:
            self.guiLookTheme.setCurrentIndex(themeIdx)

        self.guiLookSyntax = QComboBox()
        self.guiLookSyntax.setMinimumWidth(200)
        self.theSyntaxes = self.theTheme.listSyntax()
        for syntaxFile, syntaxName in self.theSyntaxes:
            self.guiLookSyntax.addItem(syntaxName, syntaxFile)
        syntaxIdx = self.guiLookSyntax.findData(self.mainConf.guiSyntax)
        if syntaxIdx != -1:
            self.guiLookSyntax.setCurrentIndex(syntaxIdx)

        self.guiDarkIcons = QCheckBox("Prefer icons for dark backgrounds", self)
        self.guiDarkIcons.setToolTip("This may improve the look of icons if the system theme is dark.")
        self.guiDarkIcons.setChecked(self.mainConf.guiDark)

        self.guiLookForm.addWidget(QLabel("Theme"),    0, 0)
        self.guiLookForm.addWidget(self.guiLookTheme,  0, 1)
        self.guiLookForm.addWidget(QLabel("Syntax"),   1, 0)
        self.guiLookForm.addWidget(self.guiLookSyntax, 1, 1)
        self.guiLookForm.addWidget(self.guiDarkIcons,  2, 0, 1, 2)
        self.guiLookForm.setColumnStretch(3, 1)

        # Spell Checking
        self.spellLang     = QGroupBox("Spell Checker", self)
        self.spellLangForm = QGridLayout(self)
        self.spellLang.setLayout(self.spellLangForm)

        self.spellLangList = QComboBox(self)
        self.spellToolList = QComboBox(self)
        self.spellToolList.addItem("Internal (difflib)",        NWSpellCheck.SP_INTERNAL)
        self.spellToolList.addItem("Spell Enchant (pyenchant)", NWSpellCheck.SP_ENCHANT)
        self.spellToolList.addItem("SymSpell (symspellpy)",     NWSpellCheck.SP_SYMSPELL)

        theModel   = self.spellToolList.model()
        idEnchant  = self.spellToolList.findData(NWSpellCheck.SP_ENCHANT)
        idSymSpell = self.spellToolList.findData(NWSpellCheck.SP_SYMSPELL)
        theModel.item(idEnchant).setEnabled(self.mainConf.hasEnchant)
        theModel.item(idSymSpell).setEnabled(self.mainConf.hasSymSpell)

        self.spellToolList.currentIndexChanged.connect(self._doUpdateSpellTool)
        toolIdx = self.spellToolList.findData(self.mainConf.spellTool)
        if toolIdx != -1:
            self.spellToolList.setCurrentIndex(toolIdx)
        self._doUpdateSpellTool(0)

        self.spellBigDoc = QSpinBox(self)
        self.spellBigDoc.setMinimum(10)
        self.spellBigDoc.setMaximum(10000)
        self.spellBigDoc.setSingleStep(10)
        self.spellBigDoc.setToolTip((
            "Disable spell checking when loading large documents. "
            "Spell checking will only run on paragraphs you edit."
        ))
        self.spellBigDoc.setValue(self.mainConf.bigDocLimit)

        self.spellLangForm.addWidget(QLabel("Provider"),   0, 0)
        self.spellLangForm.addWidget(self.spellToolList,   0, 1, 1, 3)
        self.spellLangForm.addWidget(QLabel("Language"),   1, 0)
        self.spellLangForm.addWidget(self.spellLangList,   1, 1, 1, 3)
        self.spellLangForm.addWidget(QLabel("Size limit"), 2, 0)
        self.spellLangForm.addWidget(self.spellBigDoc,     2, 1)
        self.spellLangForm.addWidget(QLabel("kb"),         2, 2)
        self.spellLangForm.setColumnStretch(4, 1)

        # AutoSave
        self.autoSave     = QGroupBox("Automatic Save", self)
        self.autoSaveForm = QGridLayout(self)
        self.autoSave.setLayout(self.autoSaveForm)

        self.autoSaveDoc = QSpinBox(self)
        self.autoSaveDoc.setMinimum(5)
        self.autoSaveDoc.setMaximum(600)
        self.autoSaveDoc.setSingleStep(1)
        self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc)

        self.autoSaveProj = QSpinBox(self)
        self.autoSaveProj.setMinimum(5)
        self.autoSaveProj.setMaximum(600)
        self.autoSaveProj.setSingleStep(1)
        self.autoSaveProj.setValue(self.mainConf.autoSaveProj)

        self.autoSaveForm.addWidget(QLabel("Document"), 0, 0)
        self.autoSaveForm.addWidget(self.autoSaveDoc,   0, 1)
        self.autoSaveForm.addWidget(QLabel("seconds"),  0, 2)
        self.autoSaveForm.addWidget(QLabel("Project"),  1, 0)
        self.autoSaveForm.addWidget(self.autoSaveProj,  1, 1)
        self.autoSaveForm.addWidget(QLabel("seconds"),  1, 2)
        self.autoSaveForm.setColumnStretch(3, 1)

        # Backup
        self.projBackup     = QGroupBox("Backup Folder", self)
        self.projBackupForm = QGridLayout(self)
        self.projBackup.setLayout(self.projBackupForm)

        self.projBackupPath = QLineEdit()
        if path.isdir(self.mainConf.backupPath):
            self.projBackupPath.setText(self.mainConf.backupPath)

        self.projBackupGetPath = QPushButton(self.theTheme.getIcon("folder"),"")
        self.projBackupGetPath.clicked.connect(self._backupFolder)

        self.projBackupClose = QCheckBox("Run on close",self)
        self.projBackupClose.setToolTip("Backup automatically on project close.")
        self.projBackupClose.setChecked(self.mainConf.backupOnClose)

        self.projBackupAsk = QCheckBox("Ask before backup",self)
        self.projBackupAsk.setToolTip("Ask before backup.")
        self.projBackupAsk.setChecked(self.mainConf.askBeforeBackup)

        self.projBackupForm.addWidget(self.projBackupPath,    0, 0, 1, 2)
        self.projBackupForm.addWidget(self.projBackupGetPath, 0, 2)
        self.projBackupForm.addWidget(self.projBackupClose,   1, 0)
        self.projBackupForm.addWidget(self.projBackupAsk,     1, 1, 1, 2)
        self.projBackupForm.setColumnStretch(1, 1)

        # Assemble
        self.outerBox.addWidget(self.guiLook,    0, 0)
        self.outerBox.addWidget(self.spellLang,  1, 0)
        self.outerBox.addWidget(self.autoSave,   2, 0)
        self.outerBox.addWidget(self.projBackup, 3, 0, 1, 2)
        self.outerBox.setColumnStretch(1, 1)
        self.outerBox.setRowStretch(4, 1)
        self.setLayout(self.outerBox)

        return

    def saveValues(self):

        validEntries = True
        needsRestart = False

        guiTheme        = self.guiLookTheme.currentData()
        guiSyntax       = self.guiLookSyntax.currentData()
        guiDark         = self.guiDarkIcons.isChecked()
        spellTool       = self.spellToolList.currentData()
        spellLanguage   = self.spellLangList.currentData()
        bigDocLimit     = self.spellBigDoc.value()
        autoSaveDoc     = self.autoSaveDoc.value()
        autoSaveProj    = self.autoSaveProj.value()
        backupPath      = self.projBackupPath.text()
        backupOnClose   = self.projBackupClose.isChecked()
        askBeforeBackup = self.projBackupAsk.isChecked()

        # Check if restart is needed
        needsRestart |= self.mainConf.guiTheme != guiTheme

        self.mainConf.guiTheme        = guiTheme
        self.mainConf.guiSyntax       = guiSyntax
        self.mainConf.guiDark         = guiDark
        self.mainConf.spellTool       = spellTool
        self.mainConf.spellLanguage   = spellLanguage
        self.mainConf.bigDocLimit     = bigDocLimit
        self.mainConf.autoSaveDoc     = autoSaveDoc
        self.mainConf.autoSaveProj    = autoSaveProj
        self.mainConf.backupPath      = backupPath
        self.mainConf.backupOnClose   = backupOnClose
        self.mainConf.askBeforeBackup = askBeforeBackup

        self.mainConf.confChanged = True

        return validEntries, needsRestart

    ##
    #  Internal Functions
    ##

    def _backupFolder(self):

        currDir = self.projBackupPath.text()
        if not path.isdir(currDir):
            currDir = ""

        dlgOpt  = QFileDialog.Options()
        dlgOpt |= QFileDialog.ShowDirsOnly
        dlgOpt |= QFileDialog.DontUseNativeDialog
        newDir = QFileDialog.getExistingDirectory(
            self,"Backup Directory",currDir,options=dlgOpt
        )
        if newDir:
            self.projBackupPath.setText(newDir)
            return True

        return False

    def _disableComboItem(self, theList, theValue):
        theIdx = theList.findData(theValue)
        theModel = theList.model()
        anItem = theModel.item(1)
        anItem.setFlags(anItem.flags() ^ Qt.ItemIsEnabled)
        return theModel

    def _doUpdateSpellTool(self, currIdx):
        spellTool = self.spellToolList.currentData()
        self._updateLanguageList(spellTool)
        return

    def _updateLanguageList(self, spellTool):
        """Updates the list of available spell checking dictionaries
        available for the selected spell check tool. It will try to
        preserve the language choice, if the language exists in the
        updated list.
        """
        if spellTool == NWSpellCheck.SP_ENCHANT:
            theDict = NWSpellEnchant()
        else:
            theDict = NWSpellSimple()

        self.spellLangList.clear()
        for spTag, spName in theDict.listDictionaries():
            self.spellLangList.addItem(spName, spTag)

        spellIdx = self.spellLangList.findData(self.mainConf.spellLanguage)
        if spellIdx != -1:
            self.spellLangList.setCurrentIndex(spellIdx)

        return