def createDateDialog(self): popup = QDialog(self) popup.setFixedSize(270, 60) popup.setWindowTitle("Nouvelle date") layout = QHBoxLayout() prefix = QLabel("Heure cible: ") layout.addWidget(prefix) qline = QTimeEdit() qline.setDisplayFormat("hh:mm:ss") qline.setTime(QTime.currentTime()) layout.addWidget(qline) button = QPushButton("Ok") button.clicked.connect(lambda: self.createDate(popup, qline.time().hour(), qline.time().minute(), qline.time().second())) layout.addWidget(button) popup.setLayout(layout) popup.exec_()
class QPackageDialog(QDialog): """Base package management dialog. The dialogs for creating a new package and editing an existing dialog are very similar, and this implements the shared behavior. """ #: Emitted when a change is made to the package. package_changed = Signal() def __init__(self, game_model: GameModel, model: PackageModel, parent=None) -> None: super().__init__(parent) self.game_model = game_model self.package_model = model self.add_flight_dialog: Optional[QFlightCreator] = None self.setMinimumSize(1000, 440) self.setWindowTitle( f"Mission Package: {self.package_model.mission_target.name}") self.setWindowIcon(EVENT_ICONS["strike"]) self.layout = QVBoxLayout() self.summary_row = QHBoxLayout() self.layout.addLayout(self.summary_row) self.package_type_column = QHBoxLayout() self.summary_row.addLayout(self.package_type_column) self.package_type_label = QLabel("Package Type:") self.package_type_text = QLabel(self.package_model.description) # noinspection PyUnresolvedReferences self.package_changed.connect(lambda: self.package_type_text.setText( self.package_model.description)) self.package_type_column.addWidget(self.package_type_label) self.package_type_column.addWidget(self.package_type_text) self.summary_row.addStretch(1) self.tot_column = QHBoxLayout() self.summary_row.addLayout(self.tot_column) self.tot_label = QLabel("Time Over Target:") self.tot_column.addWidget(self.tot_label) self.tot_spinner = QTimeEdit(self.tot_qtime()) self.tot_spinner.setMinimumTime(QTime(0, 0)) self.tot_spinner.setDisplayFormat("T+hh:mm:ss") self.tot_spinner.timeChanged.connect(self.save_tot) self.tot_spinner.setToolTip("Package TOT relative to mission TOT") self.tot_spinner.setEnabled(not self.package_model.package.auto_asap) self.tot_column.addWidget(self.tot_spinner) self.auto_asap = QCheckBox("ASAP") self.auto_asap.setToolTip( "Sets the package TOT to the earliest time that all flights can " "arrive at the target.") self.auto_asap.setChecked(self.package_model.package.auto_asap) self.auto_asap.toggled.connect(self.set_asap) self.tot_column.addWidget(self.auto_asap) self.tot_help_label = QLabel( "<a href=\"https://github.com/Khopa/dcs_liberation/wiki/Mission-planning\"><span style=\"color:#FFFFFF;\">Help</span></a>" ) self.tot_help_label.setAlignment(Qt.AlignCenter) self.tot_help_label.setOpenExternalLinks(True) self.tot_column.addWidget(self.tot_help_label) self.package_view = QFlightList(self.game_model, self.package_model) self.package_view.selectionModel().selectionChanged.connect( self.on_selection_changed) self.layout.addWidget(self.package_view) self.button_layout = QHBoxLayout() self.layout.addLayout(self.button_layout) self.add_flight_button = QPushButton("Add Flight") self.add_flight_button.clicked.connect(self.on_add_flight) self.button_layout.addWidget(self.add_flight_button) self.delete_flight_button = QPushButton("Delete Selected") self.delete_flight_button.setProperty("style", "btn-danger") self.delete_flight_button.clicked.connect(self.on_delete_flight) self.delete_flight_button.setEnabled(model.rowCount() > 0) self.button_layout.addWidget(self.delete_flight_button) self.package_model.tot_changed.connect(self.update_tot) self.button_layout.addStretch() self.setLayout(self.layout) self.accepted.connect(self.on_save) self.finished.connect(self.on_close) self.rejected.connect(self.on_cancel) @property def game(self) -> Game: return self.game_model.game def tot_qtime(self) -> QTime: delay = int( self.package_model.package.time_over_target.total_seconds()) hours = delay // 3600 minutes = delay // 60 % 60 seconds = delay % 60 return QTime(hours, minutes, seconds) def on_cancel(self) -> None: pass @staticmethod def on_close(_result) -> None: GameUpdateSignal.get_instance().redraw_flight_paths() def on_save(self) -> None: self.save_tot() def save_tot(self) -> None: time = self.tot_spinner.time() seconds = time.hour() * 3600 + time.minute() * 60 + time.second() self.package_model.set_tot(timedelta(seconds=seconds)) def set_asap(self, checked: bool) -> None: self.package_model.set_asap(checked) self.tot_spinner.setEnabled(not self.package_model.package.auto_asap) self.update_tot() def update_tot(self) -> None: self.tot_spinner.setTime(self.tot_qtime()) def on_selection_changed(self, selected: QItemSelection, _deselected: QItemSelection) -> None: """Updates the state of the delete button.""" self.delete_flight_button.setEnabled(not selected.empty()) def on_add_flight(self) -> None: """Opens the new flight dialog.""" self.add_flight_dialog = QFlightCreator(self.game, self.package_model.package, parent=self.window()) self.add_flight_dialog.created.connect(self.add_flight) self.add_flight_dialog.show() def add_flight(self, flight: Flight) -> None: """Adds the new flight to the package.""" self.game.aircraft_inventory.claim_for_flight(flight) self.package_model.add_flight(flight) planner = FlightPlanBuilder(self.game, self.package_model.package, is_player=True) try: planner.populate_flight_plan(flight) except PlanningError as ex: self.game.aircraft_inventory.return_from_flight(flight) self.package_model.delete_flight(flight) logging.exception("Could not create flight") QMessageBox.critical(self, "Could not create flight", str(ex), QMessageBox.Ok) self.package_model.update_tot() # noinspection PyUnresolvedReferences self.package_changed.emit() def on_delete_flight(self) -> None: """Removes the selected flight from the package.""" flight = self.package_view.selected_item if flight is None: logging.error(f"Cannot delete flight when no flight is selected.") return self.game.aircraft_inventory.return_from_flight(flight) self.package_model.delete_flight(flight) # noinspection PyUnresolvedReferences self.package_changed.emit()
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())
class ExportSrt(QDialog): def __init__(self): super().__init__() self.setWindowTitle('输出.srt时间轴文件') self.resize(550, 350) self.layout = QGridLayout() self.setLayout(self.layout) self.startPos = QTimeEdit() self.startPos.setDisplayFormat('hh:mm:ss.zzz') self.layout.addWidget(QLabel('开始位置'), 0, 0, 1, 3) self.layout.addWidget(self.startPos, 0, 2, 1, 3) self.endPos = QTimeEdit() self.endPos.setDisplayFormat('hh:mm:ss.zzz') self.layout.addWidget(QLabel('结束位置'), 0, 6, 1, 3) self.layout.addWidget(self.endPos, 0, 8, 1, 3) self.timeMarkType = QComboBox() self.timeMarkType.addItems(['相对时间', '绝对时间']) self.layout.addWidget(QLabel('记录方式'), 1, 0, 1, 3) self.layout.addWidget(self.timeMarkType, 1, 2, 1, 3) self.offset = QTimeEdit() self.offset.setDisplayFormat('hh:mm:ss.zzz') self.layout.addWidget(QLabel('时间轴偏移'), 1, 6, 1, 4) self.layout.addWidget(self.offset, 1, 8, 1, 3) self.layout.addWidget(QLabel('最大无效时长(毫秒)'), 2, 0, 1, 6) self.maxIgnore = QLineEdit() self.layout.addWidget(self.maxIgnore, 2, 4, 1, 4) self.maxIgnore.setText("100") self.layout.addWidget(QLabel('最大合并间隔(毫秒)'), 3, 0, 1, 6) self.maxMerge = QLineEdit() self.layout.addWidget(self.maxMerge, 3, 4, 1, 4) self.maxMerge.setText("100") self.mergeOrIgnore = QComboBox() self.mergeOrIgnore.addItems(['优先合并', '优先忽略']) self.layout.addWidget(QLabel('合并&忽略优先设置'), 4, 0, 1, 6) self.layout.addWidget(self.mergeOrIgnore, 4, 4, 1, 3) self.isExportUnnumbering = QCheckBox() self.layout.addWidget(self.isExportUnnumbering, 5, 0, 1, 1) self.layout.addWidget(QLabel('同时导出无编号.srt文件'), 5, 1, 1, 6) self.saveDir = QLineEdit() self.layout.addWidget(self.saveDir, 6, 0, 1, 6) self.setPath = QPushButton('保存位置') self.layout.addWidget(self.setPath, 6, 6, 1, 1) self.setPath.clicked.connect(self.choosePath) self.exportSrt = QPushButton('导出文件') self.cancel = QPushButton('取消') self.help = QPushButton('帮助') self.layout.addWidget(self.exportSrt, 7, 0, 1, 2) self.layout.addWidget(self.cancel, 7, 2, 1, 2) self.layout.addWidget(self.help, 7, 4, 1, 2) self.exportSrt.clicked.connect(self.execExportSrt) self.cancel.clicked.connect(self.closeWindow) self.help.clicked.connect(self.dispHelp) def setDefault(self, autoSub, videoDuration): self.autoSub = autoSub self.endPos.setTime(ms2QTime(videoDuration)) def closeWindow(self): self.destroy(True, True) def dispHelp(self): self.helpContents = '''- 开始位置 & 结束位置:.srt文件开始及结束的时间点 - 记录方式:记录原始视频的绝对时间,或是以开始位置为0记录相对时间 - 时间轴偏移:时间点位置整体调整 - 最大无效时长:语音段时长不超过这个值时,该语音段会被忽略。0:不忽略任何语音段 - 最大合并间隔:两个语音段之间的空白时长不超过这个值时,两个语音段将被合并。0:不合并任何语音段 - 合并&忽略优先设置:如果一个语音段同时可以被合并以及被忽略,设置指定进行哪个操作''' self.helpPage = QMessageBox() self.helpPage.setText(self.helpContents) self.helpPage.show() def choosePath(self): subtitlePath = QFileDialog.getSaveFileName(self, "选择文件夹", '', "字幕文件 (*.srt)")[0] if subtitlePath: self.saveDir.setText(subtitlePath) def execExportSrt(self): voiceCntRaw = len(self.autoSub) if voiceCntRaw == 0: self.timeNotFound = QMessageBox() self.timeNotFound.setText("没有找到时间轴信息。") self.timeNotFound.show() return startPos = QTime2ms(self.startPos.time()) endPos = QTime2ms(self.endPos.time())
class GroupEditDialog(QDialog): def __init__(self, group, is_new=False): super().__init__(GlobalAccess().get_main_window()) assert (isinstance(group, Group)) self.current_object = group self.is_new = is_new self.time_format = 'hh:mm:ss' def exec_(self): self.init_ui() self.set_values_from_model() return super().exec_() def init_ui(self): self.setWindowTitle(_('Group properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_name = QLabel(_('Name')) self.item_name = QLineEdit() self.item_name.textChanged.connect(self.check_name) self.layout.addRow(self.label_name, self.item_name) self.label_full_name = QLabel(_('Full name')) self.item_full_name = QLineEdit() self.layout.addRow(self.label_full_name, self.item_full_name) self.label_course = QLabel(_('Course')) self.item_course = AdvComboBox() self.item_course.addItems(get_race_courses()) self.layout.addRow(self.label_course, self.item_course) self.label_is_any_course = QLabel(_('Is any course')) self.item_is_any_course = QCheckBox() self.item_is_any_course.stateChanged.connect(self.is_any_course_update) self.layout.addRow(self.label_is_any_course, self.item_is_any_course) self.label_sex = QLabel(_('Sex')) self.item_sex = AdvComboBox() self.item_sex.addItems(Sex.get_titles()) self.layout.addRow(self.label_sex, self.item_sex) self.label_age_min = QLabel(_('Min age')) self.item_age_min = QSpinBox() # self.layout.addRow(self.label_age_min, self.item_age_min) self.label_age_max = QLabel(_('Max age')) self.item_age_max = QSpinBox() # self.layout.addRow(self.label_age_max, self.item_age_max) self.label_year_min = QLabel(_('Min year')) self.item_year_min = QSpinBox() self.item_year_min.setMaximum(date.today().year) self.item_year_min.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year_min, self.item_year_min) self.label_year_max = QLabel(_('Max year')) self.item_year_max = QSpinBox() self.item_year_max.setMaximum(date.today().year) self.item_year_max.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year_max, self.item_year_max) self.label_max_time = QLabel(_('Max time')) self.item_max_time = QTimeEdit() self.item_max_time.setDisplayFormat(self.time_format) self.layout.addRow(self.label_max_time, self.item_max_time) self.label_corridor = QLabel(_('Start corridor')) self.item_corridor = QSpinBox() self.layout.addRow(self.label_corridor, self.item_corridor) self.label_corridor_order = QLabel(_('Order in corridor')) self.item_corridor_order = QSpinBox() self.layout.addRow(self.label_corridor_order, self.item_corridor_order) self.label_start_interval = QLabel(_('Start interval')) self.item_start_interval = QTimeEdit() self.item_start_interval.setDisplayFormat(self.time_format) self.layout.addRow(self.label_start_interval, self.item_start_interval) self.label_price = QLabel(_('Start fee')) self.item_price = QSpinBox() self.item_price.setSingleStep(50) self.item_price.setMaximum(Limit.PRICE) self.layout.addRow(self.label_price, self.item_price) self.type_label = QLabel(_('Type')) self.type_combo = AdvComboBox() self.type_combo.addItems(RaceType.get_titles()) self.layout.addRow(self.type_label, self.type_combo) self.rank_checkbox = QCheckBox(_('Rank calculation')) self.rank_button = QPushButton(_('Configuration')) self.layout.addRow(self.rank_checkbox, self.rank_button) 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() self.button_ok.setFocus() def check_name(self): name = self.item_name.text() self.button_ok.setDisabled(False) if name and name != self.current_object.name: group = find(race().groups, name=name) if group: self.button_ok.setDisabled(True) def year_change(self): """ Convert 2 digits of year to 4 2 -> 2002 11 - > 2011 33 -> 1933 56 -> 1956 98 - > 1998 0 -> 0 exception! """ widget = self.sender() assert isinstance(widget, QSpinBox) year = widget.value() if 0 < year < 100: cur_year = date.today().year new_year = cur_year - cur_year % 100 + year if new_year > cur_year: new_year -= 100 widget.setValue(new_year) def is_any_course_update(self): if self.item_is_any_course.isChecked(): self.item_course.setDisabled(True) else: self.item_course.setDisabled(False) def set_values_from_model(self): self.item_name.setText(self.current_object.name) if self.current_object.long_name: self.item_full_name.setText(self.current_object.long_name) if self.current_object.course: self.item_course.setCurrentText(self.current_object.course.name) if self.current_object.sex: self.item_sex.setCurrentText(self.current_object.sex.get_title()) if self.current_object.min_age: self.item_age_min.setValue(self.current_object.min_age) if self.current_object.max_age: self.item_age_max.setValue(self.current_object.max_age) if self.current_object.min_year: self.item_year_min.setValue(self.current_object.min_year) if self.current_object.max_year: self.item_year_max.setValue(self.current_object.max_year) if self.current_object.max_time: self.item_max_time.setTime( time_to_qtime(self.current_object.max_time)) if self.current_object.start_interval: self.item_start_interval.setTime( time_to_qtime(self.current_object.start_interval)) if self.current_object.start_corridor: self.item_corridor.setValue(self.current_object.start_corridor) if self.current_object.order_in_corridor: self.item_corridor_order.setValue( self.current_object.order_in_corridor) if self.current_object.price: self.item_price.setValue(self.current_object.price) self.item_is_any_course.setChecked(self.current_object.is_any_course) self.rank_checkbox.setChecked(self.current_object.ranking.is_active) self.type_combo.setCurrentText(race().get_type( self.current_object).get_title()) def rank_configuration(): group = self.current_object GroupRankingDialog(group).exec_() self.rank_button.clicked.connect(rank_configuration) def apply_changes_impl(self): group = self.current_object assert (isinstance(group, Group)) if self.is_new: race().groups.insert(0, group) if group.name != self.item_name.text(): group.name = self.item_name.text() if group.long_name != self.item_full_name.text(): group.long_name = self.item_full_name.text() if (group.course is not None and group.course.name != self.item_course.currentText()) \ or (group.course is None and len(self.item_course.currentText()) > 0): group.course = find(race().courses, name=self.item_course.currentText()) if group.sex.get_title() != self.item_sex.currentText(): group.sex = Sex(self.item_sex.currentIndex()) if group.min_age != self.item_age_min.value(): group.min_age = self.item_age_min.value() if group.max_age != self.item_age_max.value(): group.max_age = self.item_age_max.value() if group.min_year != self.item_year_min.value(): group.min_year = self.item_year_min.value() if group.max_year != self.item_year_max.value(): group.max_year = self.item_year_max.value() if group.start_corridor != self.item_corridor.value(): group.start_corridor = self.item_corridor.value() if group.order_in_corridor != self.item_corridor_order.value(): group.order_in_corridor = self.item_corridor_order.value() if group.price != self.item_price.value(): group.price = self.item_price.value() time = time_to_otime(self.item_start_interval.time()) if group.start_interval != time: group.start_interval = time time = time_to_otime(self.item_max_time.time()) if group.max_time != time: group.max_time = time if group.ranking.is_active != self.rank_checkbox.isChecked(): group.ranking.is_active = self.rank_checkbox.isChecked() t = RaceType.get_by_name(self.type_combo.currentText()) selected_type = t if t is not None else group.get_type() if group.get_type() != selected_type: group.set_type(selected_type) group.is_any_course = self.item_is_any_course.isChecked() ResultCalculation(race()).set_rank(group) Teamwork().send(group.to_dict())
class PersonEditDialog(QDialog): GROUP_NAME = '' ORGANIZATION_NAME = '' def __init__(self, person, is_new=False): super().__init__(GlobalAccess().get_main_window()) self.is_ok = {} assert (isinstance(person, Person)) self.current_object = person 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(_('Entry properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_surname = QLabel(_('Last name')) self.item_surname = QLineEdit() self.layout.addRow(self.label_surname, self.item_surname) self.label_name = QLabel(_('First name')) self.item_name = AdvComboBox() self.item_name.addItems(get_names()) self.layout.addRow(self.label_name, self.item_name) self.label_group = QLabel(_('Group')) self.item_group = AdvComboBox() self.item_group.addItems(get_race_groups()) self.layout.addRow(self.label_group, self.item_group) self.label_team = QLabel(_('Team')) self.item_team = AdvComboBox() self.item_team.addItems(get_race_teams()) self.layout.addRow(self.label_team, self.item_team) use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: self.label_birthday = QLabel(_('Birthday')) self.item_birthday = QDateEdit() self.item_birthday.setDate(date.today()) self.item_birthday.setMaximumDate(date.today()) self.layout.addRow(self.label_birthday, self.item_birthday) else: self.label_year = QLabel(_('Year of birth')) self.item_year = QSpinBox() self.item_year.setMinimum(0) self.item_year.setMaximum(date.today().year) self.item_year.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year, self.item_year) self.label_qual = QLabel(_('Qualification')) self.item_qual = AdvComboBox() for i in list(Qualification): self.item_qual.addItem(i.get_title()) self.layout.addRow(self.label_qual, self.item_qual) self.is_ok['bib'] = True self.label_bib = QLabel(_('Bib')) self.item_bib = QSpinBox() self.item_bib.setMinimum(0) self.item_bib.setMaximum(Limit.BIB) self.item_bib.valueChanged.connect(self.check_bib) self.layout.addRow(self.label_bib, self.item_bib) self.label_bib_info = QLabel('') self.layout.addRow(QLabel(''), self.label_bib_info) self.label_start = QLabel(_('Start time')) self.item_start = QTimeEdit() self.item_start.setDisplayFormat(self.time_format) self.layout.addRow(self.label_start, self.item_start) self.label_start_group = QLabel(_('Start group')) self.item_start_group = QSpinBox() self.item_start_group.setMinimum(0) self.item_start_group.setMaximum(99) self.layout.addRow(self.label_start_group, self.item_start_group) self.is_ok['card'] = True self.label_card = QLabel(_('Punch card #')) self.item_card = QSpinBox() self.item_card.setMinimum(0) self.item_card.setMaximum(9999999) self.item_card.valueChanged.connect(self.check_card) self.layout.addRow(self.label_card, self.item_card) self.label_card_info = QLabel('') self.layout.addRow(QLabel(''), self.label_card_info) self.item_rented = QCheckBox(_('rented card')) self.item_paid = QCheckBox(_('is paid')) self.item_out_of_competition = QCheckBox(_('out of competition')) self.item_personal = QCheckBox(_('personal participation')) self.layout.addRow(self.item_rented, self.item_out_of_competition) self.layout.addRow(self.item_paid, self.item_personal) self.label_comment = QLabel(_('Comment')) self.item_comment = QTextEdit() self.item_comment.setTabChangesFocus(True) self.layout.addRow(self.label_comment, self.item_comment) 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 year_change(self): """ Convert 2 digits of year to 4 2 -> 2002 11 - > 2011 33 -> 1933 56 -> 1956 98 - > 1998 0 -> 0 exception! """ widget = self.sender() assert isinstance(widget, QSpinBox) year = widget.value() if 0 < year < 100: cur_year = date.today().year new_year = cur_year - cur_year % 100 + year if new_year > cur_year: new_year -= 100 widget.setValue(new_year) def items_ok(self): ret = True for item_name in self.is_ok.keys(): if self.is_ok[item_name] is not True: ret = False break return ret def check_bib(self): bib = self.item_bib.value() self.label_bib_info.setText('') if bib: person = find(race().persons, bib=bib) if person: if person.bib == self.current_object.bib: self.button_ok.setEnabled(True) return self.button_ok.setDisabled(True) self.is_ok['bib'] = False info = '{}\n{}'.format(_('Number already exists'), person.full_name) if person.group: info = '{}\n{}: {}'.format(info, _('Group'), person.group.name) self.label_bib_info.setText(info) else: self.label_bib_info.setText(_('Number is unique')) self.is_ok['bib'] = True if self.items_ok(): self.button_ok.setEnabled(True) else: self.button_ok.setEnabled(True) def check_card(self): number = self.item_card.value() self.label_card_info.setText('') if number: person = None for _p in race().persons: if _p.card_number and _p.card_number == number: person = _p break if person: if person.card_number == self.current_object.card_number: self.button_ok.setEnabled(True) return self.button_ok.setDisabled(True) self.is_ok['card'] = False info = '{}\n{}'.format(_('Card number already exists'), person.full_name) if person.group: info = '{}\n{}: {}'.format(info, _('Group'), person.group.name) if person.bib: info = '{}\n{}: {}'.format(info, _('Bib'), person.bib) self.label_card_info.setText(info) else: self.label_card_info.setText(_('Card number is unique')) self.is_ok['card'] = True if self.items_ok(): self.button_ok.setEnabled(True) else: self.button_ok.setEnabled(True) def set_values_from_model(self): self.item_surname.setText(self.current_object.surname) self.item_surname.selectAll() self.item_name.setCurrentText(self.current_object.name) if self.current_object.group is not None: self.item_group.setCurrentText(self.current_object.group.name) else: self.item_group.setCurrentText(self.GROUP_NAME) if self.current_object.organization is not None: self.item_team.setCurrentText( self.current_object.organization.name) else: self.item_team.setCurrentText(self.ORGANIZATION_NAME) if self.current_object.qual: self.item_qual.setCurrentText(self.current_object.qual.get_title()) if self.current_object.bib: self.item_bib.setValue(int(self.current_object.bib)) if self.current_object.start_time is not None: time = time_to_qtime(self.current_object.start_time) self.item_start.setTime(time) if self.current_object.start_group is not None: self.item_start_group.setValue(int( self.current_object.start_group)) if self.current_object.card_number: self.item_card.setValue(self.current_object.card_number) self.item_out_of_competition.setChecked( self.current_object.is_out_of_competition) self.item_paid.setChecked(self.current_object.is_paid) self.item_paid.setChecked(self.current_object.is_paid) self.item_personal.setChecked(self.current_object.is_personal) self.item_rented.setChecked(self.current_object.is_rented_card) self.item_comment.setText(self.current_object.comment) use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: if self.current_object.birth_date: self.item_birthday.setDate(self.current_object.birth_date) else: if self.current_object.get_year(): self.item_year.setValue(self.current_object.get_year()) def apply_changes_impl(self): person = self.current_object assert (isinstance(person, Person)) if self.is_new: race().persons.insert(0, person) if person.name != self.item_name.currentText(): person.name = self.item_name.currentText() if person.surname != self.item_surname.text(): person.surname = self.item_surname.text() if (person.group is not None and person.group.name != self.item_group.currentText()) or\ (person.group is None and len(self.item_group.currentText()) > 0): person.group = find(race().groups, name=self.item_group.currentText()) if (person.organization is not None and person.organization.name != self.item_team.currentText()) or \ (person.organization is None and len(self.item_team.currentText()) > 0): organization = find(race().organizations, name=self.item_team.currentText()) if organization is None: organization = Organization() organization.name = self.item_team.currentText() race().organizations.append(organization) Teamwork().send(organization.to_dict()) person.organization = organization if person.qual.get_title() != self.item_qual.currentText(): person.qual = Qualification.get_qual_by_name( self.item_qual.currentText()) if person.bib != self.item_bib.value(): person.bib = self.item_bib.value() new_time = time_to_otime(self.item_start.time()) if person.start_time != new_time: person.start_time = new_time if person.start_group != self.item_start_group.value( ) and self.item_start_group.value(): person.start_group = self.item_start_group.value() if (not person.card_number or int(person.card_number) != self.item_card.value()) \ and self.item_card.value: race().person_card_number(person, self.item_card.value()) if person.is_out_of_competition != self.item_out_of_competition.isChecked( ): person.is_out_of_competition = self.item_out_of_competition.isChecked( ) if person.is_paid != self.item_paid.isChecked(): person.is_paid = self.item_paid.isChecked() if person.is_rented_card != self.item_rented.isChecked(): person.is_rented_card = self.item_rented.isChecked() if person.is_personal != self.item_personal.isChecked(): person.is_personal = self.item_personal.isChecked() if person.comment != self.item_comment.toPlainText(): person.comment = self.item_comment.toPlainText() use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: new_birthday = qdate_to_date(self.item_birthday.date()) if person.birth_date != new_birthday and new_birthday: if person.birth_date or new_birthday != date.today(): person.birth_date = new_birthday else: if person.get_year() != self.item_year.value(): person.set_year(self.item_year.value()) ResultCalculation(race()).process_results() Teamwork().send(person.to_dict())
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()
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()