예제 #1
0
    def __init__(self, target_properties: List[str], parent=None):
        super().__init__(parent)
        self.target_properties = target_properties
        self.target = None

        layout = QGridLayout()
        for i in range(0, 8):
            label = QLabel(text=_EDITOR_LABELS[i])
            layout.addWidget(label, 0, i + 1)
        self.editors = []
        for i in range(0, len(target_properties)):
            self.editors.append([])
            label = QLabel(target_properties[i])
            label.setFixedWidth(80)
            layout.addWidget(label, i + 1, 0)
            for j in range(0, 8):
                editor = QSpinBox()
                editor.setRange(-128, 127)
                editor.setMaximumWidth(60)
                layout.addWidget(editor, row=i + 1, column=j + 1)
                self.editors[-1].append(editor)
                editor.valueChanged.connect(lambda v=None, e=editor, r=i, c=j:
                                            self._on_edit(v, e, r, c))
        self.setLayout(layout)
        self.setFixedHeight(200)
예제 #2
0
class ScoresDialog(QDialog):
    def __init__(self):
        super().__init__(GlobalAccess().get_main_window())

    def exec_(self):
        self.init_ui()
        return super().exec_()

    def init_ui(self):
        self.setWindowTitle(_('Scores assign'))
        self.setWindowIcon(QIcon(config.ICON))
        self.setSizeGripEnabled(False)
        self.setModal(False)
        self.setMinimumWidth(650)

        self.layout = QFormLayout(self)

        self.label_list = QRadioButton(_('Value list'))
        self.label_list.setChecked(True)
        self.item_list = QLineEdit()
        self.item_list.setText(
            '40;37;35;33;32;31;30;29;28;27;26;25;24;23;22;21;20;19;18;17;16;15;14;13;12;11;10;9;8;7;6;5;4;3;2;1'
        )
        self.layout.addRow(self.label_list, self.item_list)

        self.label_formula = QRadioButton(_('Formula'))
        self.item_formula = QLineEdit()
        self.layout.addRow(self.label_formula, self.item_formula)

        self.label_formula_hint = QLabel(
            'Hint: You can use following variables: LeaderTime, Time, Year, Place, Length'
        )
        self.layout.addRow(self.label_formula_hint)

        self.label_limit = QCheckBox(_('Limit per team'))
        self.item_limit = QSpinBox()
        self.item_limit.setMaximumWidth(50)
        self.layout.addRow(self.label_limit, self.item_limit)

        def cancel_changes():
            self.close()

        def apply_changes():
            try:
                self.apply_changes_impl()
            except Exception as e:
                logging.error(str(e))
            self.close()

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        self.button_ok = button_box.button(QDialogButtonBox.Ok)
        self.button_ok.setText(_('OK'))
        self.button_ok.clicked.connect(apply_changes)
        self.button_cancel = button_box.button(QDialogButtonBox.Cancel)
        self.button_cancel.setText(_('Cancel'))
        self.button_cancel.clicked.connect(cancel_changes)
        self.layout.addRow(button_box)

        self.show()

    def apply_changes_impl(self):
        cur_race = race()
        cur_race.set_setting('score_list', self.item_list.text())
        cur_race.set_setting('score_formula', self.item_formula.text())
        cur_race.set_setting('score_team_limit', self.item_limit.value())
        cur_race.set_setting('score_use_team_limit', self.item_limit.value())
예제 #3
0
class ParametersComponent(QGroupBox):

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

        self.setTitle("Paramètres")
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        
        # Main layout
        main_layout = QHBoxLayout(self)
        main_layout.setSpacing(20)

        left_layout = QFormLayout()
        left_layout.setHorizontalSpacing(20)
        left_layout.setVerticalSpacing(14)

        self._threshold_sbox = QSpinBox()
        self._threshold_sbox.setRange(1, 99)
        self._threshold_sbox.setSuffix(" %")
        self._threshold_sbox.setMaximumWidth(250)
        left_layout.addRow("Seuil de détection :", self._threshold_sbox)

        self._devices_list = QComboBox()
        self._devices_list.setMaximumWidth(250)
        self._setDevicesList()

        left_layout.addRow("Processeur à utiliser :", self._devices_list)

        morphotype_layout = QGridLayout()
        morphotype_layout.setSpacing(5)

        morphotype_layout.addWidget(QLabel("Morphotypes à détecter :"), 0, 0, 1, 4)

        self._tab_cbox = {}
        for k,m in Loader.SpongesMorphotypes().items():
            sponge_cbox = QCheckBox(m.name())
            self._tab_cbox[k] = sponge_cbox

            x = k%2 + 1
            y = k//2 + 1
            morphotype_layout.addWidget(sponge_cbox, x, y)

        morphotype_layout.setColumnMinimumWidth(0, 15)
        morphotype_layout.setColumnStretch(0, 0)

        main_layout.addLayout(left_layout)
        main_layout.addLayout(morphotype_layout)

        self.setLayout(main_layout)

    def _setDevicesList(self):
        self._devices_list.clear()
        available_devices = NeuralNetwork.getAvailableCalculationDevices()

        for device_id, device_name in available_devices.items():
            self._devices_list.addItem(device_name, device_id)

        if len(available_devices) == 1:
            self._devices_list.addItem("GPU (Indisponible)", None)
            self._devices_list.model().item(1).setEnabled(False)
        else:
            self._devices_list.setCurrentIndex(1)

    def reset(self, parameters: Parameters):
        self._threshold_sbox.setValue(parameters.threshold()*100)

        for k,v in parameters.morphotypes().items():
            self._tab_cbox[k].setChecked(v)

    def updateParameters(self, parameters: Parameters):
        parameters.setThreshold(self._threshold_sbox.value()/100)
        parameters.setDeviceId(self._devices_list.currentData())

        for k in parameters.morphotypes():
            parameters.morphotypes()[k] = self._tab_cbox[k].isChecked()
예제 #4
0
class MainWindow(QMainWindow):
    def __init__(self) -> None:
        QMainWindow.__init__(self)
        self.lib_chapters = self.__create_libchapters()
        self.prefs = Prefs()
        self.current_file: Optional[str] = None
        self.current_file_type: Optional[str] = None

        # UI components
        self.setWindowTitle(libchapters.APPLICATION_NAME)
        self.setMinimumSize(480, 320)
        self.resize(900, 500)
        self.__create_menu()

        self.podcast_title = QLineEdit()
        self.episode_title = QLineEdit()
        self.episode_number = QSpinBox()
        self.episode_number.setMaximumWidth(55)

        self.chapters_table_view = QTableView()
        self.chapters_table_model = ChaptersTableModel(
            self.chapters_table_view)
        self.chapters_table_view.setModel(self.chapters_table_model)
        self.chapters_table_view.horizontalHeader().setStretchLastSection(True)

        self.add_chapter_button = QPushButton("Add")
        self.add_chapter_button.clicked.connect(
            self.chapters_table_model.add_chapter)

        self.delete_chapter_button = QPushButton("Delete")
        self.delete_chapter_button.clicked.connect(
            self.chapters_table_model.remove_selected_chapters)

        self.progress_bar = QProgressBar()

        self.setCentralWidget(self.__create_center_widget())

        self.__create_status_bar()

    def __create_libchapters(self) -> LibChapters:
        listener = LibChaptersListener()
        listener.signals.encode_started.connect(self.__encode_started)
        listener.signals.encode_progress.connect(self.__encode_progress)
        listener.signals.encode_complete.connect(self.__encode_complete)
        listener.signals.read_metadata_started.connect(
            self.__read_metadata_started)
        listener.signals.read_metadata_complete.connect(
            self.__read_metadata_complete)
        listener.signals.write_mp3_file_started.connect(
            self.__write_mp3_started)
        listener.signals.write_mp3_file_progress.connect(
            self.__write_mp3_progress)
        listener.signals.write_mp3_file_complete.connect(
            self.__write_mp3_complete)
        return LibChapters(listener)

    def __create_center_widget(self) -> QWidget:
        episode_info_layout = QFormLayout()
        episode_info_layout.addRow("Podcast Title:", self.podcast_title)
        episode_info_layout.addRow("Episode Title:", self.episode_title)
        episode_info_layout.addRow("Episode Number:", self.episode_number)

        add_remove_chapters_layout = QHBoxLayout()
        add_remove_chapters_layout.addWidget(self.add_chapter_button)
        add_remove_chapters_layout.addWidget(self.delete_chapter_button)
        add_remove_chapters_layout.setAlignment(Qt.AlignLeft)

        center_widget_layout = QVBoxLayout()
        center_widget_layout.addLayout(episode_info_layout)
        center_widget_layout.addWidget(self.chapters_table_view)
        center_widget_layout.addLayout(add_remove_chapters_layout)

        center_widget = QWidget()
        center_widget.setLayout(center_widget_layout)

        return center_widget

    def __create_menu(self) -> None:
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("File")

        import_action = file_menu.addAction("Import Audio...")
        import_action.setShortcut(QKeySequence("Ctrl+I"))
        import_action.triggered.connect(self.__import_audio)

        open_file_action = file_menu.addAction("Open...")
        open_file_action.setShortcut(QKeySequence("Ctrl+O"))
        open_file_action.triggered.connect(self.__open_file)

        file_menu.addSeparator()

        save_action = file_menu.addAction("Save")
        save_action.setShortcut(QKeySequence("Ctrl+S"))
        save_action.triggered.connect(self.__save_current_file)

        save_as_action = file_menu.addAction("Save As...")
        save_as_action.setShortcut(QKeySequence("Ctrl+Shift+S"))
        save_as_action.triggered.connect(self.__save_current_file_as)

        file_menu.addSeparator()

        exit_action = file_menu.addAction("Exit")
        exit_action.setShortcut(QKeySequence("Alt+f4"))
        exit_action.triggered.connect(QCoreApplication.quit)

        help_menu = menu_bar.addMenu("Help")
        documentation_action = help_menu.addAction("Open Documentation...")
        documentation_action.triggered.connect(
            lambda: QDesktopServices.openUrl(libchapters.DOCUMENTATION))
        help_menu.addSeparator()
        about_action = help_menu.addAction("About...")
        about_action.triggered.connect(self.__show_about_dialog)

    def __create_status_bar(self) -> None:
        status_bar = self.statusBar()
        status_bar.addPermanentWidget(self.progress_bar)

    def __import_audio(self) -> None:
        file = self.__show_open_dialog("*.wav")
        if file:
            self.__set_current_file(file, "wav")
            self.lib_chapters.read_metadata_from_wav_file(file)
            self.lib_chapters.encode_wav_file(file)

    def __open_file(self) -> None:
        file = self.__show_open_dialog("*.mp3")
        if file:
            self.__set_current_file(file, "mp3")
            self.lib_chapters.read_metadata_from_mp3_file(file)

    def __encode_started(self) -> None:
        self.progress_bar.setValue(0)
        self.statusBar().showMessage("Importing file...")

    def __encode_progress(self, progress: int) -> None:
        self.progress_bar.setValue(progress)

    def __encode_complete(self) -> None:
        self.centralWidget().setDisabled(False)
        self.menuBar().setDisabled(False)
        self.statusBar().showMessage("Import complete")

    def __read_metadata_started(self) -> None:
        self.chapters_table_view.setDisabled(True)

    def __read_metadata_complete(self, metadata: MetaData) -> None:
        self.chapters_table_view.setDisabled(False)
        if metadata.podcast_title:
            self.podcast_title.setText(metadata.podcast_title)
        else:
            self.podcast_title.clear()

        if metadata.episode_title:
            self.episode_title.setText(metadata.episode_title)
        else:
            self.episode_title.clear()

        if metadata.episode_number:
            self.episode_number.setValue(metadata.episode_number)
        else:
            self.episode_number.clear()

        if metadata.chapters:
            self.chapters_table_model.set_chapters(metadata.chapters)
        else:
            self.chapters_table_model.clear_chapters()

    def __save_current_file(self) -> None:
        if self.current_file:
            meta_data = MetaData(
                podcast_title=self.podcast_title.text(),
                episode_title=self.episode_title.text(),
                episode_number=self.episode_number.value(),
                chapters=self.chapters_table_model.get_chapters())

            if self.current_file_type == "wav":
                output_file = self.__show_save_dialog("*.mp3")
                if output_file:
                    self.lib_chapters.write_mp3_data_with_metadata(
                        meta_data, output_file)
            elif self.current_file_type == "mp3":
                self.lib_chapters.write_metadata_to_file(
                    meta_data, self.current_file)

    def __save_current_file_as(self) -> None:
        if self.current_file:
            output_file = self.__show_save_dialog("*.mp3")
            if output_file:
                meta_data = MetaData(
                    podcast_title=self.podcast_title.text(),
                    episode_title=self.episode_title.text(),
                    episode_number=self.episode_number.value(),
                    chapters=self.chapters_table_model.get_chapters())

                if self.current_file_type == "wav":
                    self.lib_chapters.write_mp3_data_with_metadata(
                        meta_data, output_file)
                elif self.current_file_type == "mp3":
                    self.lib_chapters.copy_mp3_with_metadata(
                        self.current_file, output_file, meta_data)

    def __write_mp3_started(self) -> None:
        self.menuBar().setDisabled(True)
        self.centralWidget().setDisabled(True)
        self.progress_bar.setValue(0)
        self.statusBar().showMessage("Saving MP3...")

    def __write_mp3_progress(self, progress: int) -> None:
        self.progress_bar.setValue(progress)

    def __write_mp3_complete(self, path_to_mp3: str) -> None:
        self.menuBar().setDisabled(False)
        self.centralWidget().setDisabled(False)
        self.__set_current_file(path_to_mp3, "mp3")
        self.statusBar().showMessage("Save complete")

    def __show_about_dialog(self) -> None:
        about_dialog = AboutDialog(self)
        about_dialog.show()

    def __set_current_file(self, current_file: str,
                           current_file_type: str) -> None:
        self.current_file = current_file
        self.current_file_type = current_file_type
        self.setWindowTitle(
            f"{libchapters.APPLICATION_NAME} - {os.path.basename(current_file)}"
        )

    def __show_open_dialog(self, type_filter: str) -> Optional[str]:
        file, _ = QFileDialog.getOpenFileName(
            parent=self,
            dir=self.prefs.get_pref_open_dir(),
            filter=type_filter)

        if file:
            self.prefs.set_pref_open_dir(file)

        return file

    def __show_save_dialog(self, type_filter: str) -> Optional[str]:
        file, _ = QFileDialog.getSaveFileName(
            parent=self,
            dir=self.prefs.get_pref_save_dir(),
            filter=type_filter)

        if file:
            self.prefs.set_pref_save_dir(file)

        return file
예제 #5
0
class TimekeepingPropertiesDialog(QDialog):
    def __init__(self):
        super().__init__(GlobalAccess().get_main_window())
        self.time_format = 'hh:mm:ss'

    def exec_(self):
        self.init_ui()
        return super().exec_()

    def init_ui(self):
        # self.setFixedWidth(500)
        self.setWindowTitle(_('Timekeeping settings'))
        # self.setWindowIcon(QIcon(icon_dir('sportident.png')))
        self.setSizeGripEnabled(False)
        self.setModal(True)

        self.tab_widget = QTabWidget()

        # timekeeping tab
        self.timekeeping_tab = QWidget()
        self.tk_layout = QFormLayout()

        self.label_zero_time = QLabel(_('Zero time'))
        self.item_zero_time = QTimeEdit()
        self.item_zero_time.setDisplayFormat("HH:mm")
        self.item_zero_time.setMaximumSize(60, 20)
        self.item_zero_time.setDisabled(True)
        self.tk_layout.addRow(self.label_zero_time, self.item_zero_time)

        self.label_si_port = QLabel(_('Available Ports'))
        self.item_si_port = AdvComboBox()
        self.item_si_port.addItems(SIReaderClient().get_ports())
        self.tk_layout.addRow(self.label_si_port, self.item_si_port)

        self.start_group_box = QGroupBox(_('Start time'))
        self.start_layout = QFormLayout()
        self.item_start_protocol = QRadioButton(_('From protocol'))
        self.start_layout.addRow(self.item_start_protocol)
        self.item_start_station = QRadioButton(_('Start station'))
        self.start_layout.addRow(self.item_start_station)
        self.item_start_cp = QRadioButton(_('Control point'))
        self.item_start_cp_value = QSpinBox()
        self.item_start_cp_value.setMaximumSize(60, 20)
        self.start_layout.addRow(self.item_start_cp, self.item_start_cp_value)
        self.item_start_gate = QRadioButton(_('Start gate'))
        self.item_start_gate.setDisabled(True)
        self.start_layout.addRow(self.item_start_gate)
        self.start_group_box.setLayout(self.start_layout)
        self.tk_layout.addRow(self.start_group_box)

        self.finish_group_box = QGroupBox(_('Finish time'))
        self.finish_layout = QFormLayout()
        self.item_finish_station = QRadioButton(_('Finish station'))
        self.finish_layout.addRow(self.item_finish_station)
        self.item_finish_cp = QRadioButton(_('Control point'))
        self.item_finish_cp_value = QSpinBox()
        self.item_finish_cp_value.setMinimum(-1)
        self.item_finish_cp_value.setMaximumSize(60, 20)
        self.finish_layout.addRow(self.item_finish_cp, self.item_finish_cp_value)
        self.item_finish_beam = QRadioButton(_('Light beam'))
        self.item_finish_beam.setDisabled(True)
        self.finish_layout.addRow(self.item_finish_beam)
        self.finish_group_box.setLayout(self.finish_layout)
        self.tk_layout.addRow(self.finish_group_box)

        self.chip_reading_box = QGroupBox(_('Assigning a chip when reading'))
        self.chip_reading_layout = QFormLayout()
        self.chip_reading_off = QRadioButton(_('Off'))
        self.chip_reading_layout.addRow(self.chip_reading_off)
        self.chip_reading_unknown = QRadioButton(_('Only unknown members'))
        self.chip_reading_layout.addRow(self.chip_reading_unknown)
        self.chip_reading_always = QRadioButton(_('Always'))
        self.chip_reading_layout.addRow(self.chip_reading_always)
        self.chip_reading_autocreate = QRadioButton(_('Athlete auto create'))
        self.chip_reading_layout.addRow(self.chip_reading_autocreate)
        self.chip_reading_box.setLayout(self.chip_reading_layout)
        self.tk_layout.addRow(self.chip_reading_box)

        self.chip_duplicate_box = QGroupBox(_('Several readout of chip'))
        self.chip_duplicate_layout = QFormLayout()
        self.chip_duplicate_serveral_results = QRadioButton(_('Several results'))
        self.chip_duplicate_layout.addRow(self.chip_duplicate_serveral_results)
        self.chip_duplicate_bib_request = QRadioButton(_('Ask for a bib when re-reading the card'))
        self.chip_duplicate_layout.addRow(self.chip_duplicate_bib_request)
        self.chip_duplicate_relay_find_leg = QRadioButton(_('Find next relay leg'))
        self.chip_duplicate_layout.addRow(self.chip_duplicate_relay_find_leg)
        self.chip_duplicate_merge = QRadioButton(_('Merge punches'))
        self.chip_duplicate_layout.addRow(self.chip_duplicate_merge)
        self.chip_duplicate_box.setLayout(self.chip_duplicate_layout)
        self.tk_layout.addRow(self.chip_duplicate_box)

        self.assignment_mode = QCheckBox(_('Assignment mode'))
        self.assignment_mode.stateChanged.connect(self.on_assignment_mode)
        self.tk_layout.addRow(self.assignment_mode)

        self.timekeeping_tab.setLayout(self.tk_layout)

        # result processing tab
        self.result_proc_tab = QWidget()
        self.result_proc_layout = QFormLayout()
        self.rp_time_radio = QRadioButton(_('by time'))
        self.result_proc_layout.addRow(self.rp_time_radio)
        self.rp_scores_radio = QRadioButton(_('by scores'))
        self.result_proc_layout.addRow(self.rp_scores_radio)

        self.rp_scores_group = QGroupBox()
        self.rp_scores_layout = QFormLayout(self.rp_scores_group)
        self.rp_rogain_scores_radio = QRadioButton(_('rogain scores'))
        self.rp_scores_layout.addRow(self.rp_rogain_scores_radio)
        self.rp_fixed_scores_radio = QRadioButton(_('fixed scores'))
        self.rp_fixed_scores_edit = QSpinBox()
        self.rp_fixed_scores_edit.setMaximumWidth(50)
        self.rp_scores_layout.addRow(self.rp_fixed_scores_radio, self.rp_fixed_scores_edit)
        self.rp_scores_minute_penalty_label = QLabel(_('minute penalty'))
        self.rp_scores_minute_penalty_edit = QSpinBox()
        self.rp_scores_minute_penalty_edit.setMaximumWidth(50)
        self.rp_scores_layout.addRow(self.rp_scores_minute_penalty_label, self.rp_scores_minute_penalty_edit)
        self.result_proc_layout.addRow(self.rp_scores_group)
        self.result_proc_tab.setLayout(self.result_proc_layout)

        # marked route settings
        self.marked_route_tab = QWidget()
        self.mr_layout = QFormLayout()
        self.mr_off_radio = QRadioButton(_('no penalty'))
        self.mr_layout.addRow(self.mr_off_radio)
        self.mr_time_radio = QRadioButton(_('penalty time'))
        self.mr_time_edit = QTimeEdit()
        self.mr_time_edit.setDisplayFormat(self.time_format)
        self.mr_layout.addRow(self.mr_time_radio, self.mr_time_edit)
        self.mr_laps_radio = QRadioButton(_('penalty laps'))
        self.mr_layout.addRow(self.mr_laps_radio)
        self.mr_counting_lap_check = QCheckBox(_('counting lap'))
        self.mr_counting_lap_check.setDisabled(True)  # TODO
        self.mr_layout.addRow(self.mr_counting_lap_check)
        self.mr_lap_station_check = QCheckBox(_('lap station'))
        self.mr_lap_station_check.setDisabled(True)  # TODO
        self.mr_lap_station_edit = QSpinBox()
        self.mr_lap_station_edit.setMaximumWidth(50)
        self.mr_layout.addRow(self.mr_lap_station_check, self.mr_lap_station_edit)
        self.mr_dont_dqs_check = QCheckBox(_("Don't disqualify"))
        self.mr_layout.addRow(self.mr_dont_dqs_check)
        self.mr_max_penalty_by_cp = QCheckBox(_("Max penalty = quantity of cp"))
        self.mr_layout.addRow(self.mr_max_penalty_by_cp)
        self.marked_route_tab.setLayout(self.mr_layout)

        # scores
        """
        Scores
            [ x ] scores array
                40, 37, 35, 33, ... 2, 1 [ Edit ]
            [   ] scores formula
                1000 -  1000 * result / leader [ Edit ]
        """
        self.scores_tab = QWidget()
        self.scores_layout = QFormLayout()
        self.scores_off = QRadioButton(_('scores off'))
        self.scores_array = QRadioButton(_('scores array'))
        self.scores_array_edit = QLineEdit()
        self.scores_formula = QRadioButton(_('scores formula'))
        self.scores_formula_edit = QLineEdit()
        self.scores_formula_hint = QLabel(_('scores formula hint'))
        self.scores_formula_hint.setWordWrap(True)
        self.scores_layout.addRow(self.scores_off)
        self.scores_layout.addRow(self.scores_array)
        self.scores_layout.addRow(self.scores_array_edit)
        self.scores_layout.addRow(self.scores_formula)
        self.scores_layout.addRow(self.scores_formula_edit)
        self.scores_layout.addRow(self.scores_formula_hint)
        self.scores_tab.setLayout(self.scores_layout)

        # time settings
        self.time_settings_tab = QWidget()
        self.time_settings_layout = QFormLayout()
        self.time_settings_accuracy_label = QLabel(_('Accuracy'))
        self.time_settings_accuracy_edit = QSpinBox()
        self.time_settings_accuracy_edit.setMaximumWidth(50)
        self.time_settings_accuracy_edit.setMaximum(3)
        self.time_settings_layout.addRow(self.time_settings_accuracy_label, self.time_settings_accuracy_edit)

        self.time_settings_format = QGroupBox()
        self.time_settings_format.setTitle(_('Format of competitions'))
        self.time_settings_format_less = QRadioButton(_('< 24'))
        self.time_settings_format_more = QRadioButton(_('> 24'))
        self.time_settings_format_layout = QFormLayout()
        self.time_settings_format_layout.addRow(self.time_settings_format_less)
        self.time_settings_format_layout.addRow(self.time_settings_format_more)
        self.time_settings_format.setLayout(self.time_settings_format_layout)
        self.time_settings_layout.addRow(self.time_settings_format)

        self.time_settings_tab.setLayout(self.time_settings_layout)

        self.tab_widget.addTab(self.timekeeping_tab, _('SPORTident (Sportiduino, ...) settings'))
        self.tab_widget.addTab(self.result_proc_tab, _('Result processing'))
        self.tab_widget.addTab(self.scores_tab, _('Scores'))
        self.tab_widget.addTab(self.marked_route_tab, _('Penalty calculation'))
        self.tab_widget.addTab(self.time_settings_tab, _('Time settings'))

        def cancel_changes():
            self.close()

        def apply_changes():
            try:
                self.apply_changes_impl()
            except Exception as e:
                logging.error(str(e))
            self.close()

        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_ok = button_box.button(QDialogButtonBox.Ok)
        self.button_ok.setText(_('OK'))
        self.button_ok.clicked.connect(apply_changes)
        self.button_cancel = button_box.button(QDialogButtonBox.Cancel)
        self.button_cancel.setText(_('Cancel'))
        self.button_cancel.clicked.connect(cancel_changes)

        self.layout = QFormLayout(self)
        self.layout.addRow(self.tab_widget)
        self.layout.addRow(button_box)

        self.set_values_from_model()

        self.show()

    def on_assignment_mode(self):
        mode = False
        if self.assignment_mode.isChecked():
            mode = True
        self.start_group_box.setDisabled(mode)
        self.finish_group_box.setDisabled(mode)
        self.chip_reading_box.setDisabled(mode)
        self.chip_duplicate_box.setDisabled(mode)

    def set_values_from_model(self):
        cur_race = race()
        zero_time = cur_race.get_setting('system_zero_time', (8, 0, 0))
        start_source = cur_race.get_setting('system_start_source', 'protocol')
        start_cp_number = cur_race.get_setting('system_start_cp_number', 31)
        finish_source = cur_race.get_setting('system_finish_source', 'station')
        finish_cp_number = cur_race.get_setting('system_finish_cp_number', 90)
        assign_chip_reading = cur_race.get_setting('system_assign_chip_reading', 'off')
        duplicate_chip_processing = cur_race.get_setting('system_duplicate_chip_processing', 'several_results')
        assignment_mode = cur_race.get_setting('system_assignment_mode', False)
        si_port = cur_race.get_setting('system_port', '')

        self.item_zero_time.setTime(QTime(zero_time[0], zero_time[1]))

        self.item_si_port.setCurrentText(si_port)

        if start_source == 'protocol':
            self.item_start_protocol.setChecked(True)
        elif start_source == 'station':
            self.item_start_station.setChecked(True)
        elif start_source == 'cp':
            self.item_start_cp.setChecked(True)
        elif start_source == 'gate':
            self.item_start_gate.setChecked(True)

        self.item_start_cp_value.setValue(start_cp_number)

        if finish_source == 'station':
            self.item_finish_station.setChecked(True)
        elif finish_source == 'cp':
            self.item_finish_cp.setChecked(True)
        elif finish_source == 'beam':
            self.item_finish_beam.setChecked(True)

        self.item_finish_cp_value.setValue(finish_cp_number)

        if assign_chip_reading == 'off':
            self.chip_reading_off.setChecked(True)
        elif assign_chip_reading == 'only_unknown_members':
            self.chip_reading_unknown.setChecked(True)
        elif assign_chip_reading == 'always':
            self.chip_reading_always.setChecked(True)
        elif assign_chip_reading == 'autocreate':
            self.chip_reading_autocreate.setChecked(True)

        if duplicate_chip_processing == 'several_results':
            self.chip_duplicate_serveral_results.setChecked(True)
        elif duplicate_chip_processing == 'bib_request':
            self.chip_duplicate_bib_request.setChecked(True)
        elif duplicate_chip_processing == 'relay_find_leg':
            self.chip_duplicate_relay_find_leg.setChecked(True)
        elif duplicate_chip_processing == 'merge':
            self.chip_duplicate_merge.setChecked(True)

        self.assignment_mode.setChecked(assignment_mode)

        # result processing
        obj = cur_race
        rp_mode = obj.get_setting('result_processing_mode', 'time')
        rp_score_mode = obj.get_setting('result_processing_score_mode', 'rogain')
        rp_fixed_scores_value = obj.get_setting('result_processing_fixed_score_value', 1)
        rp_scores_minute_penalty = obj.get_setting('result_processing_scores_minute_penalty', 1)

        if rp_mode == 'time':
            self.rp_time_radio.setChecked(True)
        else:
            self.rp_scores_radio.setChecked(True)

        if rp_score_mode == 'rogain':
            self.rp_rogain_scores_radio.setChecked(True)
        else:
            self.rp_fixed_scores_radio.setChecked(True)

        self.rp_fixed_scores_edit.setValue(rp_fixed_scores_value)
        self.rp_scores_minute_penalty_edit.setValue(rp_scores_minute_penalty)

        # penalty calculation

        mr_mode = obj.get_setting('marked_route_mode', 'off')
        mr_penalty_time = OTime(msec=obj.get_setting('marked_route_penalty_time', 60000))
        mr_if_counting_lap = obj.get_setting('marked_route_if_counting_lap', True)
        mr_if_station_check = obj.get_setting('marked_route_if_station_check', False)
        mr_station_code = obj.get_setting('marked_route_station_code', 80)
        mr_if_dont_dsq_check = obj.get_setting('marked_route_dont_dsq', False)
        mr_if_max_penalty_by_cp = obj.get_setting('marked_route_max_penalty_by_cp', False)

        if mr_mode == 'off':
            self.mr_off_radio.setChecked(True)
        elif mr_mode == 'time':
            self.mr_time_radio.setChecked(True)
        else:
            self.mr_laps_radio.setChecked(True)

        self.mr_time_edit.setTime(mr_penalty_time.to_time())
        self.mr_counting_lap_check.setChecked(mr_if_counting_lap)
        self.mr_lap_station_check.setChecked(mr_if_station_check)
        self.mr_lap_station_edit.setValue(mr_station_code)
        self.mr_dont_dqs_check.setChecked(mr_if_dont_dsq_check)
        self.mr_max_penalty_by_cp.setChecked(mr_if_max_penalty_by_cp)

        # score settings

        scores_mode = obj.get_setting('scores_mode', 'off')
        scores_array = obj.get_setting('scores_array', '40,37,35,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,'
                                                       '16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1')
        scores_formula = obj.get_setting('scores_formula', '200 - 100 * time / leader')

        if scores_mode == 'off':
            self.scores_off.setChecked(True)
        elif scores_mode == 'array':
            self.scores_array.setChecked(True)
        elif scores_mode == 'formula':
            self.scores_formula.setChecked(True)

        self.scores_array_edit.setText(scores_array)
        self.scores_formula_edit.setText(scores_formula)

        # time settings
        time_accuracy = obj.get_setting('time_accuracy', 0)
        time_format_24 = obj.get_setting('time_format_24', 'less24')

        self.time_settings_accuracy_edit.setValue(time_accuracy)
        if time_format_24 == 'less24':
            self.time_settings_format_less.setChecked(True)
        elif time_format_24 == 'more24':
            self.time_settings_format_more.setChecked(True)

    def apply_changes_impl(self):
        obj = race()

        start_source = 'protocol'
        if self.item_start_station.isChecked():
            start_source = 'station'
        elif self.item_start_cp.isChecked():
            start_source = 'cp'
        elif self.item_start_gate.isChecked():
            start_source = 'gate'

        finish_source = 'station'
        if self.item_finish_cp.isChecked():
            finish_source = 'cp'
        elif self.item_finish_beam.isChecked():
            finish_source = 'beam'

        assign_chip_reading = 'off'
        if self.chip_reading_unknown.isChecked():
            assign_chip_reading = 'only_unknown_members'
        elif self.chip_reading_always.isChecked():
            assign_chip_reading = 'always'
        elif self.chip_reading_autocreate.isChecked():
            assign_chip_reading = 'autocreate'

        duplicate_chip_processing = 'several_results'
        if self.chip_duplicate_bib_request.isChecked():
            duplicate_chip_processing = 'bib_request'
        elif self.chip_duplicate_relay_find_leg.isChecked():
            duplicate_chip_processing = 'relay_find_leg'
        elif self.chip_duplicate_merge.isChecked():
            duplicate_chip_processing = 'merge'

        start_cp_number = self.item_start_cp_value.value()
        finish_cp_number = self.item_finish_cp_value.value()

        old_start_cp_number = obj.get_setting('system_start_cp_number', 31)
        old_finish_cp_number = obj.get_setting('system_finish_cp_number', 90)

        if old_start_cp_number != start_cp_number or old_finish_cp_number != finish_cp_number:
            race().clear_results()

        obj.set_setting('system_port', self.item_si_port.currentText())

        obj.set_setting('system_start_source', start_source)
        obj.set_setting('system_finish_source', finish_source)

        obj.set_setting('system_start_cp_number', start_cp_number)
        obj.set_setting('system_finish_cp_number', finish_cp_number)

        obj.set_setting('system_assign_chip_reading', assign_chip_reading)

        obj.set_setting('system_duplicate_chip_processing', duplicate_chip_processing)
        obj.set_setting('system_assignment_mode', self.assignment_mode.isChecked())

        # result processing
        rp_mode = 'time'
        if self.rp_scores_radio.isChecked():
            rp_mode = 'scores'

        rp_score_mode = 'rogain'
        if self.rp_fixed_scores_radio.isChecked():
            rp_score_mode = 'fixed'

        rp_fixed_scores_value = self.rp_fixed_scores_edit.value()

        rp_scores_minute_penalty = self.rp_scores_minute_penalty_edit.value()

        obj.set_setting('result_processing_mode', rp_mode)
        obj.set_setting('result_processing_score_mode', rp_score_mode)
        obj.set_setting('result_processing_fixed_score_value', rp_fixed_scores_value)
        obj.set_setting('result_processing_scores_minute_penalty', rp_scores_minute_penalty)

        # marked route
        mr_mode = 'off'
        if self.mr_laps_radio.isChecked():
            mr_mode = 'laps'
        if self.mr_time_radio.isChecked():
            mr_mode = 'time'

        obj.set_setting('marked_route_mode', mr_mode)
        mr_penalty_time = time_to_otime(self.mr_time_edit.time()).to_msec()
        mr_if_counting_lap = self.mr_counting_lap_check.isChecked()
        mr_if_station_check = self.mr_lap_station_check.isChecked()
        mr_station_code = self.mr_lap_station_edit.value()
        mr_if_dont_dsq = self.mr_dont_dqs_check.isChecked()
        mr_if_max_penalty_by_cp = self.mr_max_penalty_by_cp.isChecked()

        obj.set_setting('marked_route_mode', mr_mode)
        obj.set_setting('marked_route_penalty_time', mr_penalty_time)
        obj.set_setting('marked_route_if_counting_lap', mr_if_counting_lap)
        obj.set_setting('marked_route_if_station_check', mr_if_station_check)
        obj.set_setting('marked_route_station_code', mr_station_code)
        obj.set_setting('marked_route_dont_dsq', mr_if_dont_dsq)
        obj.set_setting('marked_route_max_penalty_by_cp', mr_if_max_penalty_by_cp)

        # score settings

        scores_mode = 'off'
        if self.scores_array.isChecked():
            scores_mode = 'array'
        elif self.scores_formula.isChecked():
            scores_mode = 'formula'

        scores_array = self.scores_array_edit.text()
        scores_formula = self.scores_formula_edit.text()

        obj.set_setting('scores_mode', scores_mode)
        obj.set_setting('scores_array', scores_array)
        obj.set_setting('scores_formula', scores_formula)

        # time settings
        time_accuracy = self.time_settings_accuracy_edit.value()
        time_format_24 = 'less24'
        if self.time_settings_format_more.isChecked():
            time_format_24 = 'more24'

        obj.set_setting('time_accuracy', time_accuracy)
        obj.set_setting('time_format_24', time_format_24)

        ResultCalculation(race()).process_results()
예제 #6
0
class Dashboard(QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QGridLayout()
        self.setMaximumHeight(300)

        # View
        available_cameras = self.get_available_cameras()
        self.available_cameras_combobox = QComboBox()
        self.available_cameras_combobox.addItems(available_cameras)
        self.layout.addWidget(QLabel("Camera:"), 1, 0, Qt.AlignRight)
        self.layout.addWidget(self.available_cameras_combobox, 1, 1)

        # HSV color
        self.hsv_min_hue_sb = QSpinBox(minimum=0,
                                       maximum=255,
                                       value=DEFAULT_HSV_MIN_HUE)
        self.hsv_max_hue_sb = QSpinBox(minimum=0,
                                       maximum=255,
                                       value=DEFAULT_HSV_MAX_HUE)
        self.hsv_min_value_sb = QSpinBox(minimum=0,
                                         maximum=255,
                                         value=DEFAULT_HSV_MIN_VALUE)
        self.hsv_max_value_sb = QSpinBox(minimum=0,
                                         maximum=255,
                                         value=DEFAULT_HSV_MAX_VALUE)
        self.hsv_min_saturation_sb = QSpinBox(minimum=0,
                                              maximum=255,
                                              value=DEFAULT_HSV_MIN_SATURATION)
        self.hsv_max_saturation_sb = QSpinBox(minimum=0,
                                              maximum=255,
                                              value=DEFAULT_HSV_MAX_SATURATION)

        self.hsv_min_hue_s = QSlider(minimum=0,
                                     maximum=255,
                                     value=DEFAULT_HSV_MIN_HUE,
                                     orientation=Qt.Horizontal)
        self.hsv_max_hue_s = QSlider(minimum=0,
                                     maximum=255,
                                     value=DEFAULT_HSV_MAX_HUE,
                                     orientation=Qt.Horizontal)
        self.hsv_min_value_s = QSlider(
            minimum=0,
            maximum=255,
            value=DEFAULT_HSV_MIN_VALUE,
            orientation=Qt.Horizontal,
        )
        self.hsv_max_value_s = QSlider(
            minimum=0,
            maximum=255,
            value=DEFAULT_HSV_MAX_VALUE,
            orientation=Qt.Horizontal,
        )
        self.hsv_min_saturation_s = QSlider(
            minimum=0,
            maximum=255,
            value=DEFAULT_HSV_MIN_SATURATION,
            orientation=Qt.Horizontal,
        )
        self.hsv_max_saturation_s = QSlider(
            minimum=0,
            maximum=255,
            value=DEFAULT_HSV_MAX_SATURATION,
            orientation=Qt.Horizontal,
        )

        max_width = 300
        self.hsv_min_hue_sb.setMaximumWidth(max_width)
        self.hsv_max_hue_sb.setMaximumWidth(max_width)
        self.hsv_min_value_sb.setMaximumWidth(max_width)
        self.hsv_max_value_sb.setMaximumWidth(max_width)
        self.hsv_min_saturation_sb.setMaximumWidth(max_width)
        self.hsv_max_saturation_sb.setMaximumWidth(max_width)
        self.hsv_min_hue_s.setMaximumWidth(max_width)
        self.hsv_max_hue_s.setMaximumWidth(max_width)
        self.hsv_min_value_s.setMaximumWidth(max_width)
        self.hsv_max_value_s.setMaximumWidth(max_width)
        self.hsv_min_saturation_s.setMaximumWidth(max_width)
        self.hsv_max_saturation_s.setMaximumWidth(max_width)

        self.layout.addWidget(QLabel("Min"), 0, 3,
                              Qt.AlignBottom | Qt.AlignHCenter)
        self.layout.addWidget(QLabel("Max"), 0, 4,
                              Qt.AlignBottom | Qt.AlignHCenter)

        self.layout.addWidget(QLabel("Hue:"), 1, 2, Qt.AlignRight)
        self.layout.addWidget(self.hsv_min_hue_sb, 1, 3)
        self.layout.addWidget(self.hsv_max_hue_sb, 1, 4)
        self.layout.addWidget(self.hsv_min_hue_s, 2, 3)
        self.layout.addWidget(self.hsv_max_hue_s, 2, 4)

        self.layout.addWidget(QLabel("Value:"), 3, 2, Qt.AlignRight)
        self.layout.addWidget(self.hsv_min_value_sb, 3, 3)
        self.layout.addWidget(self.hsv_max_value_sb, 3, 4)
        self.layout.addWidget(self.hsv_min_value_s, 4, 3)
        self.layout.addWidget(self.hsv_max_value_s, 4, 4)

        self.layout.addWidget(QLabel("Saturation:"), 5, 2, Qt.AlignRight)
        self.layout.addWidget(self.hsv_min_saturation_sb, 5, 3)
        self.layout.addWidget(self.hsv_max_saturation_sb, 5, 4)
        self.layout.addWidget(self.hsv_min_saturation_s, 6, 3)
        self.layout.addWidget(self.hsv_max_saturation_s, 6, 4)

        # Color selection
        self.current_color = QLabel()
        self.current_color.setFixedSize(50, 50)
        self.current_color.setAutoFillBackground(True)
        self.layout.addWidget(QLabel("Current color:"), 1, 5, Qt.AlignRight)
        self.layout.addWidget(self.current_color, 1, 6)

        self.selected_color = QLabel()
        self.selected_color.setFixedSize(50, 50)
        self.selected_color.setAutoFillBackground(True)
        self.layout.addWidget(QLabel("Base filtered color:"), 2, 5,
                              Qt.AlignRight)
        self.layout.addWidget(self.selected_color, 2, 6)

        self.lower_filtered_color = QLabel()
        self.lower_filtered_color.setFixedSize(50, 50)
        self.lower_filtered_color.setAutoFillBackground(True)
        self.layout.addWidget(QLabel("Lower filtered color:"), 3, 5,
                              Qt.AlignRight)
        self.layout.addWidget(self.lower_filtered_color, 3, 6)

        self.upper_filtered_color = QLabel()
        self.upper_filtered_color.setFixedSize(50, 50)
        self.upper_filtered_color.setAutoFillBackground(True)
        self.layout.addWidget(QLabel("Upper filtered color:"), 4, 5,
                              Qt.AlignRight)
        self.layout.addWidget(self.upper_filtered_color, 4, 6)

        self.setLayout(self.layout)

        self.hsv_min_hue_sb.valueChanged.connect(self.update_hsv)
        self.hsv_min_hue_sb.valueChanged.connect(self.hsv_min_hue_s.setValue)
        self.hsv_min_hue_s.valueChanged.connect(self.hsv_min_hue_sb.setValue)

        self.hsv_max_hue_sb.valueChanged.connect(self.update_hsv)
        self.hsv_max_hue_sb.valueChanged.connect(self.hsv_max_hue_s.setValue)
        self.hsv_max_hue_s.valueChanged.connect(self.hsv_max_hue_sb.setValue)

        self.hsv_min_value_sb.valueChanged.connect(self.update_hsv)
        self.hsv_min_value_sb.valueChanged.connect(
            self.hsv_min_value_s.setValue)
        self.hsv_min_value_s.valueChanged.connect(
            self.hsv_min_value_sb.setValue)

        self.hsv_max_value_sb.valueChanged.connect(self.update_hsv)
        self.hsv_max_value_sb.valueChanged.connect(
            self.hsv_max_value_s.setValue)
        self.hsv_max_value_s.valueChanged.connect(
            self.hsv_max_value_sb.setValue)

        self.hsv_min_saturation_sb.valueChanged.connect(self.update_hsv)
        self.hsv_min_saturation_sb.valueChanged.connect(
            self.hsv_min_saturation_s.setValue)
        self.hsv_min_saturation_s.valueChanged.connect(
            self.hsv_min_saturation_sb.setValue)

        self.hsv_max_saturation_sb.valueChanged.connect(self.update_hsv)
        self.hsv_max_saturation_sb.valueChanged.connect(
            self.hsv_max_saturation_s.setValue)
        self.hsv_max_saturation_s.valueChanged.connect(
            self.hsv_max_saturation_sb.setValue)

    def get_available_cameras(self):
        available_cameras = [""]
        q_camera_info = QCameraInfo()
        for available_camera in q_camera_info.availableCameras():
            device_name = available_camera.deviceName()
            available_cameras.append(device_name)
        return available_cameras

    # -----------------------------------------------------------------------------
    # --- SLOTS
    # -----------------------------------------------------------------------------

    def set_current_color(self, r, g, b):
        palette = QPalette()
        palette.setColor(QPalette.Background, QColor(r, g, b))
        self.current_color.setPalette(palette)

    def set_selected_color(self, r, g, b):
        palette = QPalette()
        palette.setColor(QPalette.Background, QColor(r, g, b))
        self.selected_color.setPalette(palette)

    def update_hsv(self, _):
        color = self.selected_color.palette().color(QPalette.Background)
        r, g, b = color.red(), color.green(), color.blue()
        lower_hsv, upper_hsv = rgb_to_hsv_range(
            r,
            g,
            b,
            min_h=self.hsv_min_hue_sb.value(),
            max_h=self.hsv_max_hue_sb.value(),
            min_s=self.hsv_min_saturation_sb.value(),
            max_s=self.hsv_max_saturation_sb.value(),
            min_v=self.hsv_min_value_sb.value(),
            max_v=self.hsv_max_value_sb.value(),
        )

        r, g, b = hsv_to_rgb(*lower_hsv)
        palette = QPalette()
        palette.setColor(QPalette.Background, QColor(r, g, b))
        self.lower_filtered_color.setPalette(palette)

        r, g, b = hsv_to_rgb(*upper_hsv)
        palette = QPalette()
        palette.setColor(QPalette.Background, QColor(r, g, b))
        self.upper_filtered_color.setPalette(palette)