Exemplo n.º 1
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()
Exemplo n.º 2
0
class ResultEditDialog(QDialog):
    def __init__(self, result, is_new=False):
        super().__init__(GlobalAccess().get_main_window())
        assert (isinstance(result, Result))
        self.current_object = result
        self.is_new = is_new

        self.time_format = 'hh:mm:ss'
        time_accuracy = race().get_setting('time_accuracy', 0)
        if time_accuracy:
            self.time_format = 'hh:mm:ss.zzz'

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

    def init_ui(self):
        self.setWindowTitle(_('Result'))
        self.setWindowIcon(QIcon(config.ICON))
        self.setSizeGripEnabled(False)
        self.setModal(True)
        self.setMaximumWidth(300)

        self.layout = QFormLayout(self)

        self.item_created_at = QTimeEdit()
        self.item_created_at.setDisplayFormat(self.time_format)
        self.item_created_at.setReadOnly(True)

        self.item_card_number = QSpinBox()
        self.item_card_number.setMaximum(9999999)

        self.item_bib = QSpinBox()
        self.item_bib.setMaximum(Limit.BIB)
        self.item_bib.valueChanged.connect(self.show_person_info)

        self.label_person_info = QLabel('')

        self.item_days = QSpinBox()
        self.item_days.setMaximum(365)

        self.item_finish = QTimeEdit()
        self.item_finish.setDisplayFormat(self.time_format)

        self.item_start = QTimeEdit()
        self.item_start.setDisplayFormat(self.time_format)

        self.item_result = QLineEdit()
        self.item_result.setEnabled(False)

        self.item_credit = QTimeEdit()
        self.item_credit.setDisplayFormat(self.time_format)

        self.item_penalty = QTimeEdit()
        self.item_penalty.setDisplayFormat(self.time_format)

        self.item_penalty_laps = QSpinBox()
        self.item_penalty_laps.setMaximum(1000000)

        self.item_status = QComboBox()
        self.item_status.addItems(ResultStatus.get_titles())

        self.item_status_comment = AdvComboBox()
        self.item_status_comment.setMaximumWidth(300)
        self.item_status_comment.view().setMinimumWidth(600)
        self.item_status_comment.addItems(StatusComments().get_all())
        for i, k in enumerate(StatusComments().get_all()):
            self.item_status_comment.setItemData(i, k, Qt.ToolTipRole)

        more24 = race().get_setting('time_format_24', 'less24') == 'more24'
        self.splits = SplitsText(more24=more24)

        self.layout.addRow(QLabel(_('Created at')), self.item_created_at)
        if self.current_object.is_punch():
            self.layout.addRow(QLabel(_('Card')), self.item_card_number)
        self.layout.addRow(QLabel(_('Bib')), self.item_bib)
        self.layout.addRow(QLabel(''), self.label_person_info)
        if more24:
            self.layout.addRow(QLabel(_('Days')), self.item_days)
        self.layout.addRow(QLabel(_('Start')), self.item_start)
        self.layout.addRow(QLabel(_('Finish')), self.item_finish)
        self.layout.addRow(QLabel(_('Credit')), self.item_credit)
        self.layout.addRow(QLabel(_('Penalty')), self.item_penalty)
        self.layout.addRow(QLabel(_('Penalty legs')), self.item_penalty_laps)
        self.layout.addRow(QLabel(_('Result')), self.item_result)
        self.layout.addRow(QLabel(_('Status')), self.item_status)
        self.layout.addRow(QLabel(_('Comment')), self.item_status_comment)

        if self.current_object.is_punch():
            start_source = race().get_setting('system_start_source', 'protocol')
            finish_source = race().get_setting('system_finish_source', 'station')
            if start_source == 'protocol' or start_source == 'cp':
                self.item_start.setDisabled(True)
            if finish_source == 'cp':
                self.item_finish.setDisabled(True)
            self.layout.addRow(self.splits.widget)

        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)

        if self.current_object.person:
            button_person = button_box.addButton(_('Entry properties'), QDialogButtonBox.ActionRole)
            button_person.clicked.connect(self.open_person)

        self.layout.addRow(button_box)

        self.show()
        self.item_bib.setFocus()

    def show_person_info(self):
        bib = self.item_bib.value()
        self.label_person_info.setText('')
        if bib:
            person = find(race().persons, bib=bib)
            if person:
                info = person.full_name
                if person.group:
                    info = '{}\n{}: {}'.format(info, _('Group'), person.group.name)
                if person.card_number:
                    info = '{}\n{}: {}'.format(info, _('Card'), person.card_number)
                self.label_person_info.setText(info)
            else:
                self.label_person_info.setText(_('not found'))

    def set_values_from_model(self):
        if self.current_object.is_punch():
            if self.current_object.card_number:
                self.item_card_number.setValue(int(self.current_object.card_number))
            self.splits.splits(self.current_object.splits)
            self.splits.show()
        if self.current_object.created_at:
            self.item_created_at.setTime(time_to_qtime(datetime.fromtimestamp(self.current_object.created_at)))
        if self.current_object.finish_time:
            self.item_finish.setTime(time_to_qtime(self.current_object.finish_time))
        if self.current_object.start_time is not None:
            self.item_start.setTime(time_to_qtime(self.current_object.start_time))
        if self.current_object.finish_time:
            self.item_result.setText(str(self.current_object.get_result()))
        if self.current_object.credit_time is not None:
            self.item_credit.setTime(time_to_qtime(self.current_object.credit_time))
        if self.current_object.penalty_time is not None:
            self.item_penalty.setTime(time_to_qtime(self.current_object.penalty_time))
        if self.current_object.penalty_laps:
            self.item_penalty_laps.setValue(self.current_object.penalty_laps)
        self.item_bib.setValue(self.current_object.get_bib())

        self.item_days.setValue(self.current_object.days)

        self.item_status.setCurrentText(self.current_object.status.get_title())

        self.item_status_comment.setCurrentText(self.current_object.status_comment)

        self.item_bib.selectAll()

    def open_person(self):
        try:
            PersonEditDialog(self.current_object.person).exec_()
        except Exception as e:
            logging.error(str(e))

    def apply_changes_impl(self):
        result = self.current_object
        if self.is_new:
            race().results.insert(0, result)

        if result.is_punch():
            if result.card_number != self.item_card_number.value():
                result.card_number = self.item_card_number.value()

            new_splits = self.splits.splits()
            if len(result.splits) == len(new_splits):
                for i, split in enumerate(result.splits):
                    if split != new_splits[i]:
                        break
            result.splits = new_splits

        time_ = time_to_otime(self.item_finish.time())
        if result.finish_time != time_:
            result.finish_time = time_

        time_ = time_to_otime(self.item_start.time())
        if result.start_time != time_:
            result.start_time = time_

        time_ = time_to_otime(self.item_credit.time())
        if result.credit_time != time_:
            result.credit_time = time_

        time_ = time_to_otime(self.item_penalty.time())
        if result.penalty_time != time_:
            result.penalty_time = time_

        if result.penalty_laps != self.item_penalty_laps.value():
            result.penalty_laps = self.item_penalty_laps.value()

        cur_bib = -1
        new_bib = self.item_bib.value()
        if result.person:
            cur_bib = result.person.bib

        if new_bib == 0:
            if result.person and result.is_punch():
                if result.person.card_number == result.card_number:
                    result.person.card_number = 0
            result.person = None
        elif cur_bib != new_bib:
            new_person = find(race().persons, bib=new_bib)
            if new_person is not None:
                assert isinstance(new_person, Person)
                if result.person:
                    if result.is_punch():
                        result.person.card_number = 0
                result.person = new_person
                if result.is_punch():
                    race().person_card_number(result.person, result.card_number)
            result.bib = new_bib

            GlobalAccess().get_main_window().get_result_table().model().init_cache()

        if self.item_days.value() != result.days:
            result.days = self.item_days.value()

        result.status = ResultStatus.get_by_name(self.item_status.currentText())

        status = StatusComments().remove_hint(self.item_status_comment.currentText())
        if result.status_comment != status:
            result.status_comment = status

        if result.is_punch():
            result.clear()
            try:
                ResultChecker.checking(result)
                ResultChecker.calculate_penalty(result)
                if result.person and result.person.group:
                    GroupSplits(race(), result.person.group).generate(True)
            except ResultCheckerException as e:
                logging.error(str(e))
        ResultCalculation(race()).process_results()
        Teamwork().send(result.to_dict())
Exemplo n.º 3
0
class StartHandicapDialog(QDialog):
    def __init__(self):
        super().__init__(GlobalAccess().get_main_window())
        self.time_format = 'hh:mm:ss'

        self.setWindowTitle(_('Handicap start time'))
        self.setWindowIcon(QIcon(config.ICON))
        self.setSizeGripEnabled(False)
        self.setModal(True)
        self.layout = QFormLayout(self)

        self.handicap_mode = QRadioButton(_('Handicap mode'))
        self.reverse_mode = QRadioButton(_('Reverse mode'))
        self.layout.addRow(self.handicap_mode)
        self.layout.addRow(self.reverse_mode)

        self.zero_time_label = QLabel(_('Start time'))
        self.zero_time = QTimeEdit()
        self.zero_time.setDisplayFormat(self.time_format)
        self.layout.addRow(self.zero_time_label, self.zero_time)

        self.max_gap_label = QLabel(_('Max gap from leader'))
        self.max_gap = QTimeEdit()
        self.max_gap.setDisplayFormat(self.time_format)
        self.layout.addRow(self.max_gap_label, self.max_gap)

        self.second_start_time_label = QLabel(_('Start time for 2 group'))
        self.second_time = QTimeEdit()
        self.second_time.setDisplayFormat(self.time_format)
        self.layout.addRow(self.second_start_time_label, self.second_time)

        self.interval_time_label = QLabel(_('Start interval'))
        self.interval_time = QTimeEdit()
        self.interval_time.setDisplayFormat(self.time_format)
        self.layout.addRow(self.interval_time_label, self.interval_time)

        self.dsq_offset_label = QLabel(_('Offset after DSQ'))
        self.dsq_offset = QTimeEdit()
        self.dsq_offset.setDisplayFormat(self.time_format)
        self.layout.addRow(self.dsq_offset_label, self.dsq_offset)

        def mode_changed():
            status = self.handicap_mode.isChecked()
            self.max_gap.setEnabled(status)
            self.second_time.setEnabled(status)
            self.dsq_offset.setDisabled(status)

        self.handicap_mode.toggled.connect(mode_changed)
        self.reverse_mode.toggled.connect(mode_changed)

        def cancel_changes():
            self.close()

        def apply_changes():
            try:
                self.apply_changes_impl()
            except Exception as e:
                logging.error(str(e))
                logging.exception(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.set_values()
        self.show()

    def set_values(self):
        obj = race()
        if obj.get_setting('handicap_mode', True):
            self.handicap_mode.toggle()
        else:
            self.reverse_mode.toggle()
        self.zero_time.setTime(OTime(msec=obj.get_setting('handicap_start', OTime(0, 11).to_msec())).to_time())
        self.max_gap.setTime(OTime(msec=obj.get_setting('handicap_max_gap', OTime(0, 0, 30).to_msec())).to_time())
        self.second_time.setTime(
            OTime(msec=obj.get_setting('handicap_second_start', OTime(0, 11, 30).to_msec())).to_time())
        self.interval_time.setTime(OTime(msec=obj.get_setting('handicap_interval', OTime(0, 0, 1).to_msec())).to_time())
        self.dsq_offset.setTime(OTime(msec=obj.get_setting('handicap_dsq_offset', OTime(0, 0, 10).to_msec())).to_time())

    def apply_changes_impl(self):
        obj = race()
        obj.set_setting('handicap_mode', self.handicap_mode.isChecked())
        obj.set_setting('handicap_start', time_to_otime(self.zero_time.time()).to_msec())
        obj.set_setting('handicap_max_gap', time_to_otime(self.max_gap.time()).to_msec())
        obj.set_setting('handicap_second_start', time_to_otime(self.second_time.time()).to_msec())
        obj.set_setting('handicap_interval', time_to_otime(self.interval_time.time()).to_msec())
        obj.set_setting('handicap_dsq_offset', time_to_otime(self.dsq_offset.time()).to_msec())

        if obj.get_setting('handicap_mode', True):
            handicap_start_time()
        else:
            reverse_start_time()