diff --git a/quickevent/app/quickevent/CMakeLists.txt b/quickevent/app/quickevent/CMakeLists.txt index f5bb7412a..29e3ce15a 100644 --- a/quickevent/app/quickevent/CMakeLists.txt +++ b/quickevent/app/quickevent/CMakeLists.txt @@ -83,6 +83,7 @@ add_executable(quickevent plugins/Event/src/services/oresultsclientwidget.ui plugins/Event/src/services/ofeed/ofeedclient.cpp plugins/Event/src/services/ofeed/ofeedclientwidget.cpp + plugins/Event/src/services/ofeed/ofeedclientwidget.ui plugins/Event/src/services/service.cpp plugins/Event/src/services/serviceswidget.cpp plugins/Event/src/services/servicewidget.cpp diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp index 04d8b00a3..f821cdb24 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp @@ -118,8 +118,18 @@ bool CompetitorDocument::saveData() else { competitor_id = dataId().toInt(); } - if(m_isEmitDbEventsOnSave) { - getPlugin()->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_EDITED, competitor_id); + + // Emit db event + if (m_isEmitDbEventsOnSave) + { + if (old_mode == DataDocument::ModeInsert) + { + getPlugin()->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_ADDED, competitor_id); + } + else if (old_mode == DataDocument::ModeEdit) + { + getPlugin()->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_EDITED, competitor_id); + } } } return ret; diff --git a/quickevent/app/quickevent/plugins/Event/src/eventplugin.h b/quickevent/app/quickevent/plugins/Event/src/eventplugin.h index 823496c79..00f2509ed 100644 --- a/quickevent/app/quickevent/plugins/Event/src/eventplugin.h +++ b/quickevent/app/quickevent/plugins/Event/src/eventplugin.h @@ -53,6 +53,8 @@ class EventPlugin : public qf::gui::framework::Plugin static constexpr auto DBEVENT_COMPETITOR_COUNTS_CHANGED = "competitorCountsChanged"; static constexpr auto DBEVENT_CARD_READ = "cardRead"; static constexpr auto DBEVENT_COMPETITOR_EDITED = "competitorEdited"; + static constexpr auto DBEVENT_COMPETITOR_ADDED = "competitorAdded"; + static constexpr auto DBEVENT_COMPETITOR_DELETED = "competitorDeleted"; static constexpr auto DBEVENT_RUN_CHANGED = "runChanged"; static constexpr auto DBEVENT_CARD_PROCESSED_AND_ASSIGNED = "cardProcessedAndAssigned"; static constexpr auto DBEVENT_PUNCH_RECEIVED = "punchReceived"; diff --git a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.cpp b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.cpp index 3fc09ff1e..c686f2e6c 100644 --- a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.cpp +++ b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -30,13 +31,17 @@ #include #include #include - -#include -#include +#include +#include +#include #include #include +#include #include +#include +#include + using Event::EventPlugin; using qf::gui::framework::getPlugin; using Relays::RelaysPlugin; @@ -82,7 +87,7 @@ void OFeedClient::exportResultsIofXml3() ? getPlugin()->resultsIofXml30() : getPlugin()->resultsIofXml30Stage(current_stage); - sendFile("results upload", "/rest/v1/upload/iof", str); + sendFile(tr("results upload"), "/rest/v1/upload/iof", str); } void OFeedClient::exportStartListIofXml3(std::function on_success) @@ -94,7 +99,7 @@ void OFeedClient::exportStartListIofXml3(std::function on_success) ? getPlugin()->startListIofXml30() : getPlugin()->startListStageIofXml30(current_stage, false); - sendFile("start list upload", "/rest/v1/upload/iof", str, on_success); + sendFile(tr("start list upload"), "/rest/v1/upload/iof", str, on_success); } qf::gui::framework::DialogWidget *OFeedClient::createDetailWidget() @@ -111,6 +116,10 @@ void OFeedClient::init() void OFeedClient::onExportTimerTimeOut() { + // exportStartListIofXml3(); + if(runChangesProcessing()){ + getChangesByOrigin(); + } exportResultsIofXml3(); } @@ -120,6 +129,179 @@ void OFeedClient::loadSettings() init(); } +void OFeedClient::onDbEventNotify(const QString &domain, int connection_id, const QVariant &data) +{ + if (status() != Status::Running) + return; + Q_UNUSED(connection_id) + + // Handle read-out + if (domain == QLatin1String(Event::EventPlugin::DBEVENT_CARD_PROCESSED_AND_ASSIGNED)) + { + auto checked_card = quickevent::core::si::CheckedCard(data.toMap()); + int competitor_id = getPlugin()->competitorForRun(checked_card.runId()); + qfInfo() << serviceName().toStdString() + "DB event competitor READ-OUT, competitor id: " << competitor_id << ", runs.id: " << checked_card.runId(); + onCompetitorReadOut(competitor_id); + } + + // Handle edit competitor + if (domain == QLatin1String(Event::EventPlugin::DBEVENT_COMPETITOR_EDITED)) + { + int competitor_id = data.toInt(); + qfInfo() << serviceName().toStdString() + "DB event competitor EDITED, competitor id: " << competitor_id; + onCompetitorEdited(competitor_id); + } + + // Handle add competitor + if (domain == QLatin1String(Event::EventPlugin::DBEVENT_COMPETITOR_ADDED)) + { + if (isInsertFromOFeed) + { + qfWarning() << serviceName().toStdString() + " [new competitor]: added from OFeed, no need to send back as a new competitor from QE (already exists in OFeed)"; + // Set back default value + isInsertFromOFeed = false; + } + else + { + int competitor_id = data.toInt(); + qfInfo() << serviceName().toStdString() + "DB event competitor ADDED, competitor id: " << competitor_id; + onCompetitorAdded(competitor_id); + } + } + + // Handle delete competitor + if (domain == QLatin1String(Event::EventPlugin::DBEVENT_COMPETITOR_DELETED)) + { + int run_id = data.toInt(); + qfInfo() << serviceName().toStdString() + "DB event competitor DELETED, run id: " << run_id; + sendCompetitorDeleted(run_id); + } +} + +QString OFeedClient::hostUrl() const +{ + int current_stage = getPlugin()->currentStageId(); + QString key = serviceName().toLower() + ".hostUrl.E" + QString::number(current_stage); + return getPlugin()->eventConfig()->value(key, "https://api.orienteerfeed.com").toString(); +} + +QString OFeedClient::eventId() const +{ + int current_stage = getPlugin()->currentStageId(); + return getPlugin()->eventConfig()->value(serviceName().toLower() + ".eventId.E" + QString::number(current_stage)).toString(); +} + +QString OFeedClient::eventPassword() const +{ + int current_stage = getPlugin()->currentStageId(); + return getPlugin()->eventConfig()->value(serviceName().toLower() + ".eventPassword.E" + QString::number(current_stage)).toString(); +} + +QString OFeedClient::changelogOrigin() const +{ + int current_stage = getPlugin()->currentStageId(); + QString key = serviceName().toLower() + ".changelogOrigin.E" + QString::number(current_stage); + return getPlugin()->eventConfig()->value(key, "START").toString(); +} + +bool OFeedClient::isInsertFromOFeed = false; + +QDateTime OFeedClient::lastChangelogCall() { + int current_stage = getPlugin()->currentStageId(); + QString key = serviceName().toLower() + ".lastChangelogCall.E" + QString::number(current_stage); + + // Retrieve the stored value from the configuration + QVariant value = getPlugin()->eventConfig()->value(key); + + // Check if the value exists + if (!value.isValid() || value.toString().isEmpty()) { + // No valid value exists, set the initial value + QDateTime initialValue = QDateTime::fromSecsSinceEpoch(0); // Default to Unix epoch (1970-01-01T00:00:00Z) + getPlugin()->eventConfig()->setValue(key, initialValue.toString(Qt::ISODate)); + getPlugin()->eventConfig()->save(serviceName().toLower()); + // qDebug() << "No lastChangelogCall found. Setting initial value to:" << initialValue.toString(Qt::ISODate); + return initialValue; + } + + // Convert the stored string to QDateTime + QDateTime lastChangelog = QDateTime::fromString(value.toString(), Qt::ISODate); + + // Check if the conversion was successful + if (!lastChangelog.isValid()) { + // If invalid, set the default value + QDateTime initialValue = QDateTime::fromSecsSinceEpoch(0); // Default to Unix epoch + getPlugin()->eventConfig()->setValue(key, initialValue.toString(Qt::ISODate)); + getPlugin()->eventConfig()->save(serviceName().toLower()); + // qDebug() << "Invalid lastChangelogCall found. Setting initial value to:" << initialValue.toString(Qt::ISODate); + return initialValue; + } + + return lastChangelog; +} + +bool OFeedClient::runXmlValidation() +{ + int current_stage = getPlugin()->currentStageId(); + QString key = serviceName().toLower() + ".runXmlValidation.E" + QString::number(current_stage); + return getPlugin()->eventConfig()->value(key, "true").toBool(); +} + +bool OFeedClient::runChangesProcessing () +{ + int current_stage = getPlugin()->currentStageId(); + QString key = serviceName().toLower() + ".runChangesProcessing.E" + QString::number(current_stage); + return getPlugin()->eventConfig()->value(key, "false").toBool(); +}; + +void OFeedClient::setHostUrl(QString hostUrl) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".hostUrl.E" + QString::number(current_stage), hostUrl); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setEventId(QString eventId) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".eventId.E" + QString::number(current_stage), eventId); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setEventPassword(QString eventPassword) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".eventPassword.E" + QString::number(current_stage), eventPassword); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setChangelogOrigin(QString changelogOrigin) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".changelogOrigin.E" + QString::number(current_stage), changelogOrigin); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setLastChangelogCall(QDateTime lastChangelogCall) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".lastChangelogCall.E" + QString::number(current_stage), lastChangelogCall); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setRunXmlValidation(bool runXmlValidation) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".runXmlValidation.E" + QString::number(current_stage), runXmlValidation); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + +void OFeedClient::setRunChangesProcessing(bool runChangesProcessing) +{ + int current_stage = getPlugin()->currentStageId(); + getPlugin()->eventConfig()->setValue(serviceName().toLower() + ".runChangesProcessing.E" + QString::number(current_stage), runChangesProcessing); + getPlugin()->eventConfig()->save(serviceName().toLower()); +} + void OFeedClient::sendFile(QString name, QString request_path, QString file, std::function on_success) { // Create a multi-part request (like FormData in JS) @@ -137,10 +319,21 @@ void OFeedClient::sendFile(QString name, QString request_path, QString file, std event_id_part.setBody(eventId().toUtf8()); multi_part->append(event_id_part); + // Disable xml validation + bool xmlValidation = runXmlValidation(); + if(!xmlValidation){ + QHttpPart validate_xml_part; + validate_xml_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(R"(form-data; name="validateXml")")); + validate_xml_part.setBody(QByteArray(xmlValidation ? "true" : "false")); + multi_part->append(validate_xml_part); + qDebug() << "Upload without IOF XML validation, validateXml: " + QString(xmlValidation ? "true" : "false"); + } + // Add xml content with fake filename that must be present QHttpPart file_part; + file_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/zlib")); file_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(R"(form-data; name="file"; filename="uploaded_file.xml")")); - file_part.setBody(file.toUtf8()); + file_part.setBody(zlibCompress(file.toUtf8())); multi_part->append(file_part); // Create network request with authorization header @@ -155,14 +348,14 @@ void OFeedClient::sendFile(QString name, QString request_path, QString file, std // Cleanup connect(reply, &QNetworkReply::finished, this, [reply, name, request_url, on_success]() { if(reply->error()) { - auto err_msg = "OFeed [" + name + "] " + request_url.toString() + " : "; + auto err_msg = serviceName().toStdString() + " [" + name.toStdString() + "] " + request_url.toString().toStdString() + " : "; auto response_body = reply->readAll(); if (!response_body.isEmpty()) err_msg += response_body + " | "; - qfError() << err_msg + reply->errorString(); + qfError() << err_msg + reply->errorString().toStdString(); } else { - qfInfo() << "OFeed [" + name + "]: ok"; + qfInfo() << serviceName().toStdString() + " [" + name.toStdString() + "]: ok"; if (on_success) on_success(); } @@ -170,80 +363,67 @@ void OFeedClient::sendFile(QString name, QString request_path, QString file, std }); } -void OFeedClient::onDbEventNotify(const QString &domain, int connection_id, const QVariant &data) +/// @brief Update competitors data by OFeed id or external id (QE id -> runs.id) +/// @param json_body body with the competitors data +/// @param competitor_or_external_id ofeed competitor id or external id (for QE runs.id) +/// @param using_external_id indicator which id is used - competitor (internal OFeed) or external (QE id from runs table) +void OFeedClient::sendCompetitorUpdate(QString json_body, int competitor_or_external_id, bool using_external_id = true) { - if (status() != Status::Running) - return; - Q_UNUSED(connection_id) - if (domain == QLatin1String(Event::EventPlugin::DBEVENT_CARD_PROCESSED_AND_ASSIGNED)) + // Prepare the Authorization header base64 username:password + QString combined = eventId() + ":" + eventPassword(); + QByteArray base_64_auth = combined.toUtf8().toBase64(); + QString auth_value = "Basic " + QString(base_64_auth); + QByteArray auth_header = auth_value.toUtf8(); + + // Create the URL for the PUT request + QUrl url = hostUrl(); + if (using_external_id) { - auto checked_card = quickevent::core::si::CheckedCard(data.toMap()); - int competitor_id = getPlugin()->competitorForRun(checked_card.runId()); - onCompetitorReadOut(competitor_id); + // qDebug() << serviceName().toStdString() + " - request to change competitor with QE id (run id): " << competitor_or_external_id; + url.setPath(QStringLiteral("/rest/v1/events/%1/competitors/%2/external-id").arg(eventId(), QString::number(competitor_or_external_id))); } - if (domain == QLatin1String(Event::EventPlugin::DBEVENT_COMPETITOR_EDITED)) + else { - // TODO: use event DBEVENT_COMPETITOR_COUNTS_CHANGED - edit + count change -> new or deleted - int competitor_id = data.toInt(); - onCompetitorEdited(competitor_id); + // qDebug() << serviceName().toStdString() + " - request to change competitor with OFeed id: " << competitor_or_external_id; + url.setPath(QStringLiteral("/rest/v1/events/%1/competitors/%2").arg(eventId(), QString::number(competitor_or_external_id))); } -} - -// void OFeedClient::getChangesFromStart(){ -// TODO -// Get changes -// Update the database with changed values -// qf::core::sql::Query q(sqlModel()->connectionName()); -// q.prepare("UPDATE runs SET siId=:siId WHERE competitorId=:competitorId", qf::core::Exception::Throw); -// q.bindValue(":competitorId", competitor_id); -// q.bindValue(":siId", siid()); -// q.exec(qf::core::Exception::Throw); -// https://github.com/Quick-Box/quickevent/blob/master/quickevent/app/quickevent/plugins/Event/src/eventplugin.cpp#L434 -// https://github.com/Quick-Box/quickevent/blob/master/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.cpp#L191 -// Save them in the config table -// Display the processed records in the table -// } -QString OFeedClient::hostUrl() const -{ - int current_stage = getPlugin()->currentStageId(); - return getPlugin()->eventConfig()->value("ofeed.hostUrl.E" + QString::number(current_stage)).toString(); -} - -QString OFeedClient::eventId() const -{ - int current_stage = getPlugin()->currentStageId(); - return getPlugin()->eventConfig()->value("ofeed.eventId.E" + QString::number(current_stage)).toString(); -} - -QString OFeedClient::eventPassword() const -{ - int current_stage = getPlugin()->currentStageId(); - return getPlugin()->eventConfig()->value("ofeed.eventPassword.E" + QString::number(current_stage)).toString(); -} - -void OFeedClient::setHostUrl(QString hostUrl) -{ - int current_stage = getPlugin()->currentStageId(); - getPlugin()->eventConfig()->setValue("ofeed.hostUrl.E" + QString::number(current_stage), hostUrl); - getPlugin()->eventConfig()->save("ofeed"); -} + // Create the network request + QNetworkRequest request(url); + request.setRawHeader("Authorization", auth_header); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); -void OFeedClient::setEventId(QString eventId) -{ - int current_stage = getPlugin()->currentStageId(); - getPlugin()->eventConfig()->setValue("ofeed.eventId.E" + QString::number(current_stage), eventId); - getPlugin()->eventConfig()->save("ofeed"); -} + // Send request + QNetworkReply *reply = m_networkManager->put(request, json_body.toUtf8()); -void OFeedClient::setEventPassword(QString eventPassword) -{ - int current_stage = getPlugin()->currentStageId(); - getPlugin()->eventConfig()->setValue("ofeed.eventPassword.E" + QString::number(current_stage), eventPassword); - getPlugin()->eventConfig()->save("ofeed"); + connect(reply, &QNetworkReply::finished, this, [=]() + { + if(reply->error()) { + qfError() << serviceName().toStdString() + " [competitor update]: " << reply->errorString(); + } + else { + QByteArray response = reply->readAll(); + QJsonDocument json_response = QJsonDocument::fromJson(response); + QJsonObject json_object = json_response.object(); + + if (json_object.contains("error") && !json_object["error"].toBool()) { + QJsonObject results_object = json_object["results"].toObject(); + QJsonObject data_object = results_object["data"].toObject(); + + if (data_object.contains("message")) { + QString data_message = data_object["message"].toString(); + qfInfo() << serviceName().toStdString() + " [competitor details update]: " << data_message; + } else { + qfInfo() << serviceName().toStdString() + " [competitor details update]: ok, but no data message found."; + } + } else { + qfError() << serviceName().toStdString() + " [competitor details update] Unexpected response: " << response; + } + } + reply->deleteLater(); }); } -void OFeedClient::sendCompetitorChange(QString json_body, int competitor_id) +void OFeedClient::sendCompetitorAdded(QString json_body) { // Prepare the Authorization header base64 username:password QString combined = eventId() + ":" + eventPassword(); @@ -251,8 +431,8 @@ void OFeedClient::sendCompetitorChange(QString json_body, int competitor_id) QString auth_value = "Basic " + QString(base_64_auth); QByteArray auth_header = auth_value.toUtf8(); - // Create the URL for the PUT request - QUrl url(hostUrl() + "/rest/v1/events/" + eventId() + "/competitors/" + QString::number(competitor_id) + "/external-id"); + // Create the URL for the POST request + QUrl url(hostUrl() + "/rest/v1/events/" + eventId() + "/competitors"); // Create the network request QNetworkRequest request(url); @@ -260,36 +440,36 @@ void OFeedClient::sendCompetitorChange(QString json_body, int competitor_id) request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); // Send request - QNetworkReply *reply = m_networkManager->put(request, json_body.toUtf8()); + QNetworkReply *reply = m_networkManager->post(request, json_body.toUtf8()); connect(reply, &QNetworkReply::finished, this, [=]() { -if(reply->error()) { - qfError() << "OFeed [competitor change]:" << reply->errorString(); -} -else { - QByteArray response = reply->readAll(); - QJsonDocument json_response = QJsonDocument::fromJson(response); - QJsonObject json_object = json_response.object(); - - if (json_object.contains("error") && !json_object["error"].toBool()) { - QJsonObject results_object = json_object["results"].toObject(); - QJsonObject data_object = results_object["data"].toObject(); - - if (data_object.contains("message")) { - QString data_message = data_object["message"].toString(); - qfInfo() << "OFeed [competitor change]:" << data_message; - } else { - qfInfo() << "OFeed [competitor change]: ok, but no data message found."; - } - } else { - qfError() << "OFeed [competitor change] Unexpected response:" << response; - } -} -reply->deleteLater(); }); + if(reply->error()) { + qfError() << serviceName().toStdString() + " [new competitor]: " << reply->errorString(); + } + else { + QByteArray response = reply->readAll(); + QJsonDocument json_response = QJsonDocument::fromJson(response); + QJsonObject json_object = json_response.object(); + + if (json_object.contains("error") && !json_object["error"].toBool()) { + QJsonObject results_object = json_object["results"].toObject(); + QJsonObject data_object = results_object["data"].toObject(); + + if (data_object.contains("message")) { + QString data_message = data_object["message"].toString(); + qfInfo() << serviceName().toStdString() + " [new competitor]: " << data_message; + } else { + qfInfo() << serviceName().toStdString() + " [new competitor]: ok, but no data message found."; + } + } else { + qfError() << serviceName().toStdString() + " [new competitor] Unexpected response: " << response; + } + } + reply->deleteLater(); }); } -void OFeedClient::sendNewCompetitor(QString json_body) +void OFeedClient::sendCompetitorDeleted(int run_id) { // Prepare the Authorization header base64 username:password QString combined = eventId() + ":" + eventPassword(); @@ -298,7 +478,7 @@ void OFeedClient::sendNewCompetitor(QString json_body) QByteArray auth_header = auth_value.toUtf8(); // Create the URL for the POST request - QUrl url(hostUrl() + "/rest/v1/events/" + eventId() + "/competitors"); + QUrl url(hostUrl() + "/rest/v1/events/" + eventId() + "/competitors/" + QString::number(run_id) + "/external-id"); // Create the network request QNetworkRequest request(url); @@ -306,33 +486,418 @@ void OFeedClient::sendNewCompetitor(QString json_body) request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); // Send request - QNetworkReply *reply = m_networkManager->post(request, json_body.toUtf8()); + QNetworkReply *reply = m_networkManager->deleteResource(request); connect(reply, &QNetworkReply::finished, this, [=]() { -if(reply->error()) { - qfError() << "OFeed [new competitor]:" << reply->errorString(); -} -else { - QByteArray response = reply->readAll(); - QJsonDocument json_response = QJsonDocument::fromJson(response); - QJsonObject json_object = json_response.object(); - - if (json_object.contains("error") && !json_object["error"].toBool()) { - QJsonObject results_object = json_object["results"].toObject(); - QJsonObject data_object = results_object["data"].toObject(); - - if (data_object.contains("message")) { - QString data_message = data_object["message"].toString(); - qfInfo() << "OFeed [new competitor]:" << data_message; - } else { - qfInfo() << "OFeed [new competitor]: ok, but no data message found."; - } - } else { - qfError() << "OFeed [new competitor] Unexpected response:" << response; + if(reply->error()) { + qfError() << serviceName().toStdString() + " [deleted competitor]: " << reply->errorString(); + } + else { + QByteArray response = reply->readAll(); + QJsonDocument json_response = QJsonDocument::fromJson(response); + QJsonObject json_object = json_response.object(); + + if (json_object.contains("error") && !json_object["error"].toBool()) { + QJsonObject results_object = json_object["results"].toObject(); + + if (results_object.contains("data")) { + QString data = results_object["data"].toString(); + qfInfo() << serviceName().toStdString() + " [deleted competitor (external id)]: " << data; + } else { + qfInfo() << serviceName().toStdString() + " [deleted competitor (external id)]: ok, but no data message found."; + } + } else { + qfError() << serviceName().toStdString() + " [deleted competitor (external id)] Unexpected response: " << response; + } + } + reply->deleteLater(); }); +} + +void OFeedClient::sendGraphQLRequest(const QString &query, const QJsonObject &variables, std::function callback, bool withAuthorization = false) +{ + QUrl url(hostUrl() + "/graphql"); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + // Add authorization header if required + if (withAuthorization) + { + QString combined = eventId() + ":" + eventPassword(); + QByteArray auth = "Basic " + combined.toUtf8().toBase64(); + request.setRawHeader("Authorization", auth); + } + + // Construct the JSON payload for the GraphQL request + QJsonObject payload; + payload["query"] = query; + if (!variables.isEmpty()) + { + payload["variables"] = variables; } + + // Compact JSON + QByteArray request_body = QJsonDocument(payload).toJson(QJsonDocument::Compact); + + // Send the POST request + QNetworkReply *reply = m_networkManager->post(request, request_body); + + connect(reply, &QNetworkReply::finished, this, [=]() + { + // Default value + QJsonObject data_object; + + if (reply->error()) { + qfError() << serviceName().toStdString() + " [GraphQL request]: " << reply->errorString(); + } else { + QByteArray response = reply->readAll(); + QJsonDocument json_response = QJsonDocument::fromJson(response); + QJsonObject json_object = json_response.object(); + + if (json_object.contains("errors")) { + qfError() << serviceName().toStdString() + " [GraphQL request] Errors in response: " << json_object; + } else if (json_object.contains("data")) { + data_object = json_object["data"].toObject(); + } else { + qfError() << serviceName().toStdString() + " [GraphQL request] Unexpected response: " << json_object; + } + } + reply->deleteLater(); + + // Call the callback with the resulting data_object + callback(data_object); }); } -reply->deleteLater(); }); + +void OFeedClient::getChangesByOrigin() +{ + try + { + QDateTime last_changelog_call_value = lastChangelogCall(); + QDateTime initial_value = QDateTime::fromSecsSinceEpoch(0); // Unix epoch + + QString graphQLquery = R"( + query ChangelogByEvent($eventId: String!, $origin: String) { + changelogByEvent(eventId: $eventId, origin: $origin) { + id + type + previousValue + newValue + origin + competitor { + id + externalId + firstname + lastname + } + createdAt + } + } + )"; + + QJsonObject variables; + variables["eventId"] = eventId(); + variables["origin"] = changelogOrigin(); + + // Check if last_changelog_call_value is valid/not default + if (last_changelog_call_value != initial_value) + { + graphQLquery = R"( + query ChangelogByEvent($eventId: String!, $origin: String, $since: DateTime) { + changelogByEvent(eventId: $eventId, origin: $origin, since: $since) { + id + type + previousValue + newValue + origin + competitor { + id + externalId + firstname + lastname + } + createdAt + } + } + )"; + + variables["since"] = last_changelog_call_value.toString(Qt::ISODate); + } + + sendGraphQLRequest(graphQLquery, variables, [=, this](QJsonObject data) + { + if (!data.isEmpty()) + { + // Check if the "data" key exists and is an array + if (data.contains("changelogByEvent") && data["changelogByEvent"].isArray()) { + QJsonArray changelog_array = data["changelogByEvent"].toArray(); + + if (changelog_array.isEmpty()) { + qfInfo() << "No changes from origin: " << changelogOrigin(); + return; + } + + // Process the data + processCompetitorsChanges(changelog_array); + + // Update last changelog call with the adjusted execution time + QDateTime request_execution_time = QDateTime::currentDateTimeUtc(); + setLastChangelogCall(request_execution_time); + } + + } }, true); + } + catch (const std::exception &e) + { + qCritical() << tr("Exception occurred while getting changes by origin: ") << e.what(); + } +} + +void OFeedClient::processCompetitorsChanges(QJsonArray data_array) +{ + if (data_array.isEmpty()) + { + return; + } + + for (const QJsonValue &value : data_array) + { + + if (!value.isObject()) + { + continue; + } + + QJsonObject change = value.toObject(); + + // Extract values + QString type = change["type"].toString(); + QString previous_value = change["previousValue"].toString(); + QString new_value = change["newValue"].toString(); + + // Retrieve competitor and details + auto competitor = change.value("competitor").toObject(); + int ofeed_competitor_id = competitor["id"].toInt(); + QString external_id_str = competitor["externalId"].toString(); + int runs_id = external_id_str.toInt(); + qDebug() << "Processing change for competitorId (OFeed externalId):" << runs_id << ", type:" << type << ", " << previous_value << " -> " << new_value; + + // Handle each type of change + if (type == "si_card_change") + { + processCardChange(runs_id, new_value); + } + else if (type == "status_change") + { + processStatusChange(runs_id, new_value); + } + else if (type == "note_change") + { + processNoteChange(runs_id, new_value); + } + else if (type == "competitor_create") + { + processNewRunner(ofeed_competitor_id); + } + else + { + qfWarning() << "Unsupported change type: " << type.toStdString(); + continue; + } + + // Store the processed change + storeChange(change); + } +} + +void OFeedClient::processCardChange(int runs_id, const QString &new_value) +{ + qf::core::sql::Query q; + try + { + q.prepare("UPDATE runs SET siId=:siId WHERE id=:runsId", qf::core::Exception::Throw); + q.bindValue(":runsId", runs_id); + q.bindValue(":siId", new_value.toInt()); + if (!q.exec(qf::core::Exception::Throw)) + { + qfError() << tr("Database query failed: ") << q.lastError().text(); + } + } + catch (const std::exception &e) + { + qCritical() << tr("Exception occurred while executing query: ") << e.what(); + } + catch (...) + { + qCritical() << tr("Unknown exception occurred while executing query."); + } +} + +void OFeedClient::processStatusChange(int runs_id, const QString &new_value) +{ + bool notStart = new_value == "DidNotStart" ? true : false; + + qf::core::sql::Query q; + try + { + q.prepare("UPDATE runs SET notStart=:notStart WHERE id=:runsId", qf::core::Exception::Throw); + q.bindValue(":runsId", runs_id); + q.bindValue(":notStart", notStart); + if (!q.exec(qf::core::Exception::Throw)) + { + qfError() << tr("Database query failed: ") << q.lastError().text(); + } + } + catch (const std::exception &e) + { + qCritical() << tr("Exception occurred while executing query: ") << e.what(); + } + catch (...) + { + qCritical() << tr("Unknown exception occurred while executing query."); + } +} + +void OFeedClient::processNoteChange(int runs_id, const QString &new_value) +{ + int competitor_id = getPlugin()->competitorForRun(runs_id); + + qf::core::sql::Query q; + try + { + q.prepare("UPDATE competitors SET note = CASE WHEN note IS NULL OR note = '' THEN :newNote ELSE note || ', ' || :newNote END WHERE id = :competitorId", qf::core::Exception::Throw); + q.bindValue(":competitorId", competitor_id); + q.bindValue(":newNote", new_value); + if (!q.exec(qf::core::Exception::Throw)) + { + qfError() << tr("Database query failed: ") << q.lastError().text(); + } + } + catch (const std::exception &e) + { + qCritical() << tr("Exception occurred while executing query: ") << e.what(); + } + catch (...) + { + qCritical() << tr("Unknown exception occurred while executing query."); + } +} + +void OFeedClient::processNewRunner(int ofeed_competitor_id) +{ + qDebug() << "Storing a new runner (OFeed id):" << ofeed_competitor_id; + QString graphQLquery = R"( + query CompetitorById($competitorByIdId: Int!) { + competitorById(id: $competitorByIdId) { + firstname + lastname + registration + card + note + class { + externalId + } + } + } + )"; + + QJsonObject variables; + variables["competitorByIdId"] = ofeed_competitor_id; + sendGraphQLRequest(graphQLquery, variables, [=, this](QJsonObject data) + { + if (!data.isEmpty()) + { + QJsonObject competitor_by_id = data.value("competitorById").toObject(); + auto competitor_detail_class = competitor_by_id.value("class").toObject(); + // Create the competitor in QE + Competitors::CompetitorDocument doc; + doc.loadForInsert(); + doc.setValue("firstName", competitor_by_id.value("firstname").toString()); + doc.setValue("lastName", competitor_by_id.value("lastname").toString()); + doc.setValue("registration", competitor_by_id.value("registration").toString()); + doc.setValue("classid", competitor_detail_class.value("externalId").toString()); + doc.setSiid(competitor_by_id.value("card").toInt()); + doc.setValue("note", competitor_by_id.value("note").toString()); + + // Change the flag to handle emited db event + isInsertFromOFeed = true; + + // Save emits db event + doc.save(); + + auto competitor_id = doc.value("competitors.id"); + + // Get runs.id for current stage + int current_stage = getPlugin()->currentStageId(); + int run_id = doc.runsIds().value(current_stage - 1); + + // Update externalId at OFeed + std::stringstream json_payload; + json_payload << "{" + << R"("origin":"IT",)" + << R"("externalId":")" << run_id << R"(")" + << "}"; + + std::string json_str = json_payload.str(); + + // Convert std::string to QString + QString json_body = QString::fromStdString(json_str); + sendCompetitorUpdate(json_body, ofeed_competitor_id, false); + } + else + { + qfError() << tr("No data received or an error occurred."); + } + }, false); +} + +void OFeedClient::storeChange(const QJsonObject &change) +{ + int current_stage = getPlugin()->currentStageId(); + auto competitor = change.value("competitor").toObject(); + + QString external_id_str = competitor["externalId"].toString(); + int runs_id = external_id_str.toInt(); + int competitor_id = getPlugin()->competitorForRun(runs_id); + QString no_data = "(undefined)"; + + QString previous_value = change["previousValue"].isString() ? change["previousValue"].toString() : no_data; + QString new_value = change["newValue"].isString() ? change["newValue"].toString() : QString(); + QString firstname = competitor["firstname"].isString() ? competitor["firstname"].toString() : no_data; + QString lastname = competitor["lastname"].isString() ? competitor["lastname"].toString() : no_data; + + QJsonDocument change_json_doc(change); + QString change_json = QString::fromUtf8(change_json_doc.toJson(QJsonDocument::Compact)); + + int change_id = change["id"].toInt(); + auto created = QDateTime::fromString(change["createdAt"].toString(), Qt::ISODate); + + qf::core::sql::Query q; + try + { + q.prepare("INSERT INTO qxchanges (data_type, data, orig_data, source, user_id, stage_id, change_id, created, status_message)" + " VALUES (:dataType, :data, :origData, :source, :userId, :stageId, :changeId, :created, :statusMessage)"); + q.bindValue(":dataType", change["type"].toString()); + q.bindValue(":data", new_value); + q.bindValue(":origData", previous_value); + q.bindValue(":source", change_json); + q.bindValue(":userId", competitor_id); + q.bindValue(":stageId", current_stage); + q.bindValue(":changeId", change_id); + q.bindValue(":created", created); + q.bindValue(":statusMessage", firstname + " " + lastname + ": " + previous_value + " -> " + new_value); + if (!q.exec(qf::core::Exception::Throw)) + { + qfError() << "Database query failed:" << q.lastError().text(); + } + } + catch (const std::exception &e) + { + qCritical() << "Exception occurred while executing query:" << e.what(); + } + catch (...) + { + qCritical() << "Unknown exception occurred while executing query."; + } } static QString getIofResultStatus( @@ -382,38 +947,181 @@ static QString datetime_to_string(const QDateTime &dt) return quickevent::core::Utils::dateTimeToIsoStringWithUtcOffset(dt); } -void OFeedClient::onCompetitorEdited(int competitor_id) +void OFeedClient::onCompetitorAdded(int competitor_id) { if (competitor_id == 0) { return; } - bool update_competitor = true; - // Handle a new competitor - use the value of the sequence and check current value? - // TODO: fix schema name - // qf::core::sql::Connection::forName(); - // qf::core::utils::ConfigCLIOptions - // cliOptions()->eventName() - qf::core::sql::Query q_schema; - q_schema.exec("select current_schema", qf::core::Exception::Throw); - if (q_schema.next()) + + int INT_INITIAL_VALUE = -1; + + int stage_id = getPlugin()->currentStageId(); + QDateTime stage_start_date_time = getPlugin()->stageStartDateTime(stage_id); + qf::core::sql::Query q; + q.exec("SELECT competitors.registration, " + "competitors.startNumber, " + "competitors.firstName, " + "competitors.lastName, " + "competitors.note, " + "clubs.name AS organisationName, " + "clubs.abbr AS organisationAbbr, " + "classes.id AS classId, " + "runs.id AS runId, " + "runs.siId, " + "runs.disqualified, " + "runs.disqualifiedByOrganizer, " + "runs.misPunch, " + "runs.badCheck, " + "runs.notStart, " + "runs.notFinish, " + "runs.notCompeting, " + "runs.startTimeMs, " + "runs.finishTimeMs, " + "runs.timeMs " + "FROM runs " + "INNER JOIN competitors ON competitors.id = runs.competitorId " + "LEFT JOIN relays ON relays.id = runs.relayId " + "LEFT JOIN clubs ON substr(competitors.registration, 1, 3) = clubs.abbr " + "INNER JOIN classes ON classes.id = competitors.classId OR classes.id = relays.classId " + "WHERE competitors.id=" QF_IARG(competitor_id) " AND runs.stageId=" QF_IARG(stage_id), + qf::core::Exception::Throw); + if (q.next()) { - QString qe_event_id = q_schema.value(0).toString(); + int run_id = q.value("runId").toInt(); + QString registration = q.value(QStringLiteral("registration")).toString(); + QString first_name = q.value(QStringLiteral("firstName")).toString(); + QString last_name = q.value(QStringLiteral("lastName")).toString(); + int card_number = q.value(QStringLiteral("siId")).toInt(); + QString organisation_name = q.value(QStringLiteral("organisationName")).toString(); + QString organisation_abbr = q.value(QStringLiteral("organisationAbbr")).toString(); + QString organisation = !organisation_abbr.isEmpty() ? organisation_name : registration.left(3); + int class_id = q.value(QStringLiteral("classId")).toInt(); + QString nationality = ""; + QString origin = "IT"; + QString note = q.value(QStringLiteral("note")).toString();; + + // Start bib + int start_bib = INT_INITIAL_VALUE; + QVariant start_bib_variant = q.value(QStringLiteral("startNumber")); + if (!start_bib_variant.isNull()) + { + start_bib = start_bib_variant.toInt(); + } - // Query actual competitor id - qf::core::sql::Query q_seq_comp; - q_seq_comp.exec("SELECT last_value FROM pg_sequences WHERE schemaname = '" + qe_event_id + "' AND sequencename = 'competitors_id_seq'", qf::core::Exception::Throw); - if (q_seq_comp.next()) + // Start time + int start_time = INT_INITIAL_VALUE; + QVariant start_time_variant = q.value(QStringLiteral("startTimeMs")); + if (!start_time_variant.isNull()) { - int actual_seq_competitors_value = q_seq_comp.value(QStringLiteral("last_value")).toInt(); + start_time = start_time_variant.toInt(); + } - // Check if a new competitor was inserted - // if (actual_seq_competitors_value == competitor_id && domain == QLatin1String(Event::EventPlugin::DBEVENT_COMPETITOR_COUNTS_CHANGED)){ - if (actual_seq_competitors_value == competitor_id) - { - update_competitor = false; - } + // Finish time + int finish_time = INT_INITIAL_VALUE; + QVariant finish_time_variant = q.value(QStringLiteral("finishTimeMs")); + if (!finish_time_variant.isNull()) + { + finish_time = finish_time_variant.toInt(); + } + + // Time + int running_time = INT_INITIAL_VALUE; + QVariant running_time_variant = q.value(QStringLiteral("timeMs")); + if (!running_time_variant.isNull()) + { + running_time = running_time_variant.toInt(); + } + + // Status + bool is_disq = q.value(QStringLiteral("disqualified")).toBool(); + bool is_disq_by_organizer = q.value(QStringLiteral("disqualifiedByOrganizer")).toBool(); + bool is_miss_punch = q.value(QStringLiteral("misPunch")).toBool(); + bool is_bad_check = q.value(QStringLiteral("badCheck")).toBool(); + bool is_did_not_start = q.value(QStringLiteral("notStart")).toBool(); + bool is_did_not_finish = q.value(QStringLiteral("notFinish")).toBool(); + bool is_not_competing = q.value(QStringLiteral("notCompeting")).toBool(); + QString status = getIofResultStatus(running_time, is_disq, is_disq_by_organizer, is_miss_punch, is_bad_check, is_did_not_start, is_did_not_finish, is_not_competing); + + // Use std::stringstream to build the JSON string + std::stringstream json_payload; + + // Setup common values + json_payload << "{" + << R"("origin":")" << origin.toStdString() << R"(",)" + << R"("firstname":")" << first_name.toStdString() << R"(",)" + << R"("lastname":")" << last_name.toStdString() << R"(",)" + << R"("registration":")" << registration.toStdString() << R"(",)" + << R"("organisation":")" << organisation.toStdString() << R"(",)" + << R"("status":")" << status.toStdString() << R"(",)" + << R"("note":")" << note.toStdString() << R"(",)"; + + if (nationality != "") + { + json_payload << R"("nationality":")" << nationality.toStdString() << R"(",)"; } + + // External ids + json_payload << R"("classExternalId":")" << class_id << R"(",)" + << R"("externalId":")" << run_id << R"(",)"; + + // Card number - QE saves 0 for empty si card + if (card_number != 0) + { + json_payload << R"("card":)" << card_number << ","; + } + + // Finish time + if (finish_time != INT_INITIAL_VALUE) + { + json_payload << R"("finishTime":")" << datetime_to_string(stage_start_date_time.addMSecs(finish_time)).toStdString() << R"(",)"; + } + + // Star time + if (start_time != INT_INITIAL_VALUE) + { + json_payload << R"("startTime":")" << datetime_to_string(stage_start_date_time.addMSecs(start_time)).toStdString() << R"(",)"; + } + + // Start bib + if (start_bib != INT_INITIAL_VALUE) + { + json_payload << R"("bibNumber":)" << start_bib << ","; + } + + // Competitor's time + if (running_time != INT_INITIAL_VALUE) + { + json_payload << R"("time":)" << running_time << ","; + } + + // Get the final JSON string + std::string json_str = json_payload.str(); + + // Remove the trailing comma if necessary + if (json_str.back() == ',') + { + json_str.pop_back(); + } + + json_str += "}"; + + // Output the JSON for debugging + // qDebug() << serviceName().toStdString() + " - competitor added - json: " << json_str; + + // Convert std::string to QString + QString json_qstr = QString::fromStdString(json_str); + + // Send + sendCompetitorAdded(json_qstr); + } +} + +void OFeedClient::onCompetitorEdited(int competitor_id) +{ + if (competitor_id == 0) + { + return; } int INT_INITIAL_VALUE = -1; @@ -425,6 +1133,7 @@ void OFeedClient::onCompetitorEdited(int competitor_id) "competitors.startNumber, " "competitors.firstName, " "competitors.lastName, " + "competitors.note, " "clubs.name AS organisationName, " "clubs.abbr AS organisationAbbr, " "classes.id AS classId, " @@ -449,6 +1158,7 @@ void OFeedClient::onCompetitorEdited(int competitor_id) qf::core::Exception::Throw); if (q.next()) { + int run_id = q.value("runId").toInt(); QString registration = q.value(QStringLiteral("registration")).toString(); QString first_name = q.value(QStringLiteral("firstName")).toString(); QString last_name = q.value(QStringLiteral("lastName")).toString(); @@ -458,9 +1168,8 @@ void OFeedClient::onCompetitorEdited(int competitor_id) QString organisation = !organisation_abbr.isEmpty() ? organisation_name : registration.left(3); int class_id = q.value(QStringLiteral("classId")).toInt(); QString nationality = ""; - // int run_id = q.value("runId").toInt(); QString origin = "IT"; - QString note = "Edited from Quickevent"; + QString note = q.value(QStringLiteral("note")).toString(); // Start bib int start_bib = INT_INITIAL_VALUE; @@ -504,11 +1213,6 @@ void OFeedClient::onCompetitorEdited(int competitor_id) bool is_not_competing = q.value(QStringLiteral("notCompeting")).toBool(); QString status = getIofResultStatus(running_time, is_disq, is_disq_by_organizer, is_miss_punch, is_bad_check, is_did_not_start, is_did_not_finish, is_not_competing); - if (!update_competitor) - { - status = "Inactive"; - } - // Use std::stringstream to build the JSON string std::stringstream json_payload; @@ -527,18 +1231,10 @@ void OFeedClient::onCompetitorEdited(int competitor_id) json_payload << R"("nationality":")" << nationality.toStdString() << R"(",)"; } - // New competitor - if (!update_competitor) - { - json_payload << R"("classExternalId":")" << class_id << R"(",)" - << R"("externalId":")" << competitor_id << R"(",)"; - } - // Update existing competitor - else - { - json_payload << R"("useExternalId":true,)" + // External ids + json_payload << R"("useExternalId":true,)" << R"("classExternalId":")" << class_id << R"(",)"; - } + // Card number - QE saves 0 for empty si card if (card_number != 0) { @@ -581,20 +1277,13 @@ void OFeedClient::onCompetitorEdited(int competitor_id) json_str += "}"; // Output the JSON for debugging - std::cout << "JSON Payload: " << json_str << std::endl; + // qDebug() << serviceName().toStdString() + " - competitor edited - json: " << json_str; // Convert std::string to QString QString json_qstr = QString::fromStdString(json_str); - // Send only a new competitor with start time (E1 button click calls db event which should be skipped=start time is not set) - if (!update_competitor && start_time != INT_INITIAL_VALUE) - { - sendNewCompetitor(json_qstr); - } - else if (update_competitor && start_time != INT_INITIAL_VALUE) - { - sendCompetitorChange(json_qstr, competitor_id); - } + // Send + sendCompetitorUpdate(json_qstr, run_id); } } @@ -606,7 +1295,8 @@ void OFeedClient::onCompetitorReadOut(int competitor_id) int stage_id = getPlugin()->currentStageId(); QDateTime stage_start_date_time = getPlugin()->stageStartDateTime(stage_id); qf::core::sql::Query q; - q.exec("SELECT runs.disqualified, " + q.exec("SELECT runs.id AS runId, " + "runs.disqualified, " "runs.disqualifiedByOrganizer, " "runs.misPunch, " "runs.badCheck, " @@ -615,7 +1305,8 @@ void OFeedClient::onCompetitorReadOut(int competitor_id) "runs.notCompeting, " "runs.startTimeMs, " "runs.finishTimeMs, " - "runs.timeMs " + "runs.timeMs, " + "competitors.note " "FROM runs " "INNER JOIN competitors ON competitors.id = runs.competitorId " "LEFT JOIN relays ON relays.id = runs.relayId " @@ -624,6 +1315,7 @@ void OFeedClient::onCompetitorReadOut(int competitor_id) qf::core::Exception::Throw); if (q.next()) { + int run_id = q.value("runId").toInt(); bool is_disq = q.value(QStringLiteral("disqualified")).toBool(); bool is_disq_by_organizer = q.value(QStringLiteral("disqualifiedByOrganizer")).toBool(); bool is_miss_punch = q.value(QStringLiteral("misPunch")).toBool(); @@ -636,7 +1328,7 @@ void OFeedClient::onCompetitorReadOut(int competitor_id) int running_time = q.value(QStringLiteral("timeMs")).toInt(); QString status = getIofResultStatus(running_time, is_disq, is_disq_by_organizer, is_miss_punch, is_bad_check, is_did_not_start, is_did_not_finish, is_not_competing); QString origin = "IT"; - QString note = "Quickevent read-out "; + QString note = "QE read-out, " + q.value(QStringLiteral("note")).toString(); // Use std::stringstream to build the JSON string std::stringstream json_payload; @@ -653,14 +1345,19 @@ void OFeedClient::onCompetitorReadOut(int competitor_id) // Get the final JSON string std::string json_str = json_payload.str(); - // Output the JSON for debugging - std::cout << "JSON Payload: " << json_str << std::endl; - // Convert std::string to QString QString json_qstr = QString::fromStdString(json_str); - sendCompetitorChange(json_qstr, competitor_id); + sendCompetitorUpdate(json_qstr, run_id); } } +QByteArray OFeedClient::zlibCompress(QByteArray data) +{ + QByteArray compressedData = qCompress(data); + // remove 4-byte length header - leave only the raw zlib stream + compressedData.remove(0, 4); + return compressedData; } + +} \ No newline at end of file diff --git a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.h b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.h index 2cd3f7f64..0c1d63836 100644 --- a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.h +++ b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclient.h @@ -33,29 +33,51 @@ class OFeedClient : public Service OFeedClientSettings settings() const {return OFeedClientSettings(m_settings);} static QString serviceName(); + static bool isInsertFromOFeed; void exportResultsIofXml3(); void exportStartListIofXml3(std::function on_success = nullptr); void loadSettings() override; void onDbEventNotify(const QString &domain, int connection_id, const QVariant &data); + QString hostUrl() const; void setHostUrl(QString eventId); QString eventId() const; void setEventId(QString eventId); QString eventPassword() const; void setEventPassword(QString eventPassword); -private: + QString changelogOrigin() const; + void setChangelogOrigin(QString changelogOrigin); + QDateTime lastChangelogCall(); + void setLastChangelogCall(QDateTime lastChangelogCall); + bool runXmlValidation(); + void setRunXmlValidation(bool runXmlValidation); + bool runChangesProcessing(); + void setRunChangesProcessing(bool runChangesProcessing); + + private: QTimer *m_exportTimer = nullptr; QNetworkAccessManager *m_networkManager = nullptr; -private: + private: qf::gui::framework::DialogWidget *createDetailWidget() override; void onExportTimerTimeOut(); void init(); void sendFile(QString name, QString request_path, QString file, std::function on_success = nullptr); - void sendCompetitorChange(QString json_body, int competitor_id); - void sendNewCompetitor(QString json_body); + void sendCompetitorUpdate(QString json_body, int competitor_id, bool usingExternalId); + void sendCompetitorAdded(QString json_body); + void sendCompetitorDeleted(int run_id); + void onCompetitorAdded(int competitor_id); void onCompetitorEdited(int competitor_id); void onCompetitorReadOut(int competitor_id); + void sendGraphQLRequest(const QString &query, const QJsonObject &variables, std::function callback, bool withAuthorization); + void getChangesByOrigin(); + void processCompetitorsChanges(QJsonArray data_array); + void processCardChange(int runs_id, const QString &new_value); + void processStatusChange(int runs_id, const QString &new_value); + void processNoteChange(int runs_id, const QString &new_value); + void processNewRunner(int ofeed_competitor_id); + void storeChange(const QJsonObject &change); + QByteArray zlibCompress(QByteArray data); }; }} diff --git a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.cpp b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.cpp index 0517dd29c..1214832c4 100644 --- a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.cpp +++ b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.cpp @@ -28,10 +28,31 @@ OFeedClientWidget::OFeedClientWidget(QWidget *parent) ui->edHostUrl->setText(svc->hostUrl()); ui->edEventId->setText(svc->eventId()); ui->edEventPassword->setText(svc->eventPassword()); + ui->edChangelogOrigin->setText(svc->changelogOrigin()); + ui->additionalSettingsRunXmlValidation->setChecked(svc->runXmlValidation()); + ui->processChangesOnOffButton->setText(svc->runChangesProcessing() ? tr("ON") : tr("OFF")); + ui->processChangesOnOffButton->setChecked(svc->runChangesProcessing()); + ui->processChangesOnOffButton->setStyleSheet( + "QPushButton {" + " padding: 5px;" + " border-radius: 4px;" + " border: 2px solid gray;" + "}" + "QPushButton:checked {" + " border: 2px solid green;" + " color: green;" + "}" + "QPushButton:!checked {" + " border: 2px solid red;" + " color: red;" + "}" + ); + ui->processChangesOnOffLabel->setText(svc->runChangesProcessing() ? tr("Changes are automatically processed") : tr("Processing changes is deactivated")); } connect(ui->btExportResultsXml30, &QPushButton::clicked, this, &OFeedClientWidget::onBtExportResultsXml30Clicked); connect(ui->btExportStartListXml30, &QPushButton::clicked, this, &OFeedClientWidget::onBtExportStartListXml30Clicked); + connect(ui->processChangesOnOffButton, &QPushButton::clicked,this, &OFeedClientWidget::onProcessChangesOnOffButtonClicked); } OFeedClientWidget::~OFeedClientWidget() @@ -65,6 +86,8 @@ bool OFeedClientWidget::saveSettings() svc->setHostUrl(ui->edHostUrl->text().trimmed()); svc->setEventId(ui->edEventId->text().trimmed()); svc->setEventPassword(ui->edEventPassword->text().trimmed()); + svc->setChangelogOrigin(ui->edChangelogOrigin->text().trimmed()); + svc->setRunXmlValidation(ui->additionalSettingsRunXmlValidation->isChecked()); svc->setSettings(ss); } return true; @@ -75,7 +98,7 @@ void OFeedClientWidget::onBtExportResultsXml30Clicked() OFeedClient *svc = service(); if(svc) { saveSettings(); - qfInfo() << "OFeed [results - manual upload]"; + qfInfo() << OFeedClient::serviceName() + " [results - manual upload]"; svc->exportResultsIofXml3(); } } @@ -85,10 +108,23 @@ void OFeedClientWidget::onBtExportStartListXml30Clicked() OFeedClient *svc = service(); if(svc) { saveSettings(); - qfInfo() << "OFeed [startlist - manual upload]"; + qfInfo() << OFeedClient::serviceName() + " [startlist - manual upload]"; svc->exportStartListIofXml3(); } } -} +void OFeedClientWidget::onProcessChangesOnOffButtonClicked() +{ + OFeedClient *svc = service(); + if (!svc) + return; + bool newState = !svc->runChangesProcessing(); + svc->setRunChangesProcessing(newState); + + // Update button text or icon + ui->processChangesOnOffButton->setText(newState ? tr("ON") : tr("OFF")); + ui->processChangesOnOffButton->setChecked(svc->runChangesProcessing()); + ui->processChangesOnOffLabel->setText(svc->runChangesProcessing() ? tr("Changes are automatically processed") : tr("Processing changes is deactivated")); +} +} \ No newline at end of file diff --git a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.h b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.h index bce494bd2..288c8e60d 100644 --- a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.h +++ b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.h @@ -22,6 +22,7 @@ class OFeedClientWidget : public qf::gui::framework::DialogWidget private: void onBtExportResultsXml30Clicked(); void onBtExportStartListXml30Clicked(); + void onProcessChangesOnOffButtonClicked(); OFeedClient* service(); bool saveSettings(); private: diff --git a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.ui b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.ui index dec0a48e1..c11b9f59f 100644 --- a/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.ui +++ b/quickevent/app/quickevent/plugins/Event/src/services/ofeed/ofeedclientwidget.ui @@ -6,8 +6,8 @@ 0 0 - 298 - 555 + 445 + 543 @@ -15,23 +15,28 @@ - - - Service credentials - - - true - - - - - 0 - 20 - 281 - 111 - - - + + + + + + 10 + true + + + + Credentials + + + + + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + 6 @@ -39,7 +44,7 @@ 6 - + Export interval @@ -68,7 +73,7 @@ - + Url @@ -77,12 +82,18 @@ - <html><head/><body><p>https://api.orienteeringfeed.com</p></body></html> + <html><head/><body><p>OFeed instance url</p></body></html> + + + https://api.orienteerfeed.com + + + https://api.orienteerfeed.com - + Event id @@ -91,121 +102,223 @@ - <html><head/><body><p>cm2kwm3dz0008s43pa1i7rngb</p></body></html> + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + From OFeed settings page - + Password + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + - <html><head/><body><p>gps-stone-map99%</p></body></html> + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + From OFeed settings page - - - - - - - Upload data - - - true - - - false - - - - - - Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real-time. Both the results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. - -If you encounter any unexpected errors, please contact us at support@orienteerfeed.com or create an issue on our GitHub page. - - - true - - - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - Export start list - - - - - - - Export results - - - - - - - - - - - - Get changes from the start - - - true - - - - - 10 - 20 - 241 - 51 - - - - Sync changes from the start to the Quickevent (start status, new card numbers and notes). - - - true - - - - - - -5 - 81 - 291 - 181 - - - - + + + + + + 10 + true + + + + Upload data + + + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + true + + + true + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Export start list + + + + + + + Export results + + + + + + + + + + 10 + true + + + + Process changes setup + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + ArrowCursor + + + Turn on/off changes processing + + + Qt::LayoutDirection::LeftToRight + + + false + + + ON / OFF + + + true + + + + + + + Zpracování zapnuto/vypnuto + + + + + + + + + + + Origin + + + + + + + START + + + true + + + START + + + + + + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + true + + + + + + + + 10 + true + + + + Additional settings + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + false + + + + + + + + + + Run IOF XML validation + + + true + + + true + + + false + + + + diff --git a/quickevent/app/quickevent/plugins/Runs/src/runsplugin.cpp b/quickevent/app/quickevent/plugins/Runs/src/runsplugin.cpp index c827ac46f..a9b9ba9fa 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runsplugin.cpp +++ b/quickevent/app/quickevent/plugins/Runs/src/runsplugin.cpp @@ -414,13 +414,37 @@ int RunsPlugin::competitorForRun(int run_id) competitor_id = q.value(0).toInt(); } else { - qfWarning() << "Cannot find card record for run id:" << run_id; + qfWarning() << "Cannot find commpetitor record for run id:" << run_id; } } } return competitor_id; } +int RunsPlugin::runForCompetitorStage(int competitor_id, int stage_id) +{ + qfLogFuncFrame() << "competitor id:" << competitor_id << "stage id:" << stage_id; + if(!competitor_id) + return 0; + + int run_id = 0; + { + qf::core::sql::Query q; + if(q.exec("SELECT runs.id " + "FROM runs " + "INNER JOIN competitors ON competitors.id = runs.competitorId " + "WHERE competitors.id=" QF_IARG(competitor_id) " AND runs.stageId=" QF_IARG(stage_id))) { + if(q.next()) { + run_id = q.value(0).toInt(); + } + else { + qfWarning() << "Cannot find run id record for competitor id:" << competitor_id << "and stage id:" << stage_id; + } + } + } + return run_id; +} + QVariantList RunsPlugin::qxExportRunsCsvJson(int stage_id) { QVariantList csv; diff --git a/quickevent/app/quickevent/plugins/Runs/src/runsplugin.h b/quickevent/app/quickevent/plugins/Runs/src/runsplugin.h index 6238a56dd..56089313a 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runsplugin.h +++ b/quickevent/app/quickevent/plugins/Runs/src/runsplugin.h @@ -124,6 +124,7 @@ class RunsPlugin : public qf::gui::framework::Plugin QString startListStageIofXml30(int stage_id, bool with_vacants); QString resultsIofXml30Stage(int stage_id); int competitorForRun(int run_id); + int runForCompetitorStage(int competitor_id, int stage_id); private: Q_SLOT void onInstalled(); diff --git a/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp b/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp index b42403dc1..22358d640 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp +++ b/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp @@ -1053,19 +1053,34 @@ void RunsWidget::editCompetitors(int mode) return; if(qfd::MessageBox::askYesNo(this, tr("Really delete all the selected competitors? This action cannot be reverted."), false)) { qfs::Transaction transaction; - int n = 0; + QList deleted_ids; for(int ix : sel_rows) { int id = tv->tableRow(ix).value("competitors.id").toInt(); if(id > 0) { + // Get runs_id instead of competitor_id + int current_stage = getPlugin()->currentStageId(); + int run_id = getPlugin()->runForCompetitorStage(id, current_stage); + Competitors::CompetitorDocument doc; doc.load(id, qfm::DataDocument::ModeDelete); doc.drop(); - n++; + + deleted_ids.append(run_id); } } - if(n > 0) { - if(qfd::MessageBox::askYesNo(this, tr("Confirm deletion of %1 competitors.").arg(n), false)) { + if(!deleted_ids.isEmpty()) { + if(qfd::MessageBox::askYesNo(this, tr("Confirm deletion of %1 competitors.").arg(deleted_ids.count()), false)) { transaction.commit(); + + // Invoke db delete event for selected rows + auto *plugin = getPlugin(); + for (int run_id : deleted_ids) { + if (run_id > 0) + { + plugin->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_DELETED, run_id); + } + } + tv->reload(); } else { @@ -1185,8 +1200,13 @@ void RunsWidget::editCompetitor_helper(const QVariant &id, int mode, int siid) w->loadFromRegistrations(siid); } } - connect(doc, &Competitors::CompetitorDocument::saved, this, [this, doc]() { + connect(doc, &Competitors::CompetitorDocument::saved, this, [this, doc, mode]() { if (auto run_id = doc->runsIds().value(selectedStageId() - 1); run_id > 0) { + + // Invoke delete db event for single delete + if(mode == qfm::DataDocument::ModeDelete){ + getPlugin()->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_DELETED, run_id); + } ui->wRunsTableWidget->tableView()->rowExternallySaved(run_id); } }); diff --git a/quickevent/app/quickevent/quickevent-cs_CZ.ts b/quickevent/app/quickevent/quickevent-cs_CZ.ts index f5a7d6ccd..754e726d3 100644 --- a/quickevent/app/quickevent/quickevent-cs_CZ.ts +++ b/quickevent/app/quickevent/quickevent-cs_CZ.ts @@ -505,140 +505,140 @@ Otestovat - + Show receipt Ukázat mezičasy - + Show card data Show card Ukázat data čipu - + Print receipt Vytisknout mezičasy - + Print card data Print card Vytisknout data čipu - + Assign card to runner Přiřadit čip závodníkovi - + Recalculate times in selected rows Přepočítat časy ve vybraných řádcích - + Open COM to connect SI reader Připojit vyčítací jednotku - + Recalculating times for %1 Přepočítávání časů pro %1 - + &Station &Vyčítací jednotka - + Station info Informace o vyčítací jednotce - + Read station memory Načíst paměť kontroly - + &Tools &Nástroje - + Import cards Importovat čipy - + Laps only CSV Pouze mezičasy (CSV) - + SI reader backup memory CSV Záložní paměť vyčítací jednotky (CSV) - + Test audio Otestovat zvuk - - + + SI station not connected SI jednotka není připojena - + Assign card to runner Ctrl + Enter Přiřadit čip závodníkovi Ctrl + Enter - + Connected to %1 in direct mode. Připojeno k %1 v přímém módu. - + Error set SI station to direct mode. Při nastavování SI jednotky do přímého módu došlo k chybě. - + Error open device %1 - %2 Chyba při otevírání zařízení %1 - %2 - + DriverInfo: <%1> %2 DriverInfo: <%1> %2 - + DriverRawData: %1 DriverRawData: %1 - + card: %1 čip: %1 - + Saved punch: %1 %2 Uložený čip: %1 %2 - + Competitor off-race Nestartující závodník - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed @@ -647,89 +647,89 @@ If you continue, this flag will be removed Pokud budete pokračovat, toto označení bude odebráno - + Import TXT Importovat TXT - + Downloading station backup ... Načítám paměť kontroly... - + Cancelled by user Zrušeno uživatelem - + No. Čís. - + SI SI - + DateTime Datum/čas - + Card error Chyba čipu - + Station %1 backup memory Paměť SI kontroly %1 - + Station backup memory Paměť SI kontroly - + Cannot find run for punch record SI: %1 Nelze najít běh pro záznam ražení SI: %1 - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> <p>CSV záznam musí mít formát:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Jakýkoliv řádek může být zakomentován pomocí #</p><p>Desetinná tečka je také podporována, uvozovky mohou být v tom případě vynechány.</p> - + Import CSV Importovat CSV - - + + Cannot open file '%1' for reading. Soubor '%1' nelze otevřít pro čtení. - - + + Bad stage! Špatná etapa! - + Cannot find runs record for SI %1! Nelze najít závodníka s SI: %1! - + Cannot find class for SI %1! Nelze najít kategorii pro SI: %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. SI: %1 Kategorie %2 – Počet ražení (%3) a počet kontrol i s cílem (%4) musí být stejný! Odeberte nebo zakomentujte neplatné řádky pomocí #. @@ -752,37 +752,37 @@ Pokud budete pokračovat, toto označení bude odebráno ID závodu v ORISu - + Loading event list from Oris ... Načítám seznam závodů z ORISu... - + OB OB - + LOB LOB - + MTBO MTBO - + ??? ??? - + Search in events ... Vyhledávat v závodech... - + TRAIL TRAIL @@ -1001,130 +1001,144 @@ Pokud budete pokračovat, toto označení bude odebráno Převýšení - Rel.num - Čís. štaf. + Čís. štaf. + + + + Rel. count + - + + Relays count + + + + Relay start number Startovní číslo štafety - + + Rel. num + + + + Legs Úseky - + Relay leg count Počet úseků štafety - + &Edit &Upravit - + Cou&rses &Tratě - + Co&des &Kontroly - + Classes &layout &Rozvržení startu kategorií - + Ctrl+L Ctrl+L - + &Import &Importovat - + OCAD TXT OCad TXT OCAD TXT - + OCAD v8 OCad v8 OCAD v8 - + OCAD IOF XML 2.0 OCad IOF-XML 2.0 OCAD IOF XML 2.0 - + OCAD IOF XML 3.0 OCad IOF-XML 3.0 OCAD IOF XML 3.0 - + Stage Etapa - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. Kategorie bez nastaveného startovního intervalu nebudou zobrazeny. Zvažte nastavení intervalu pro všechny kategorie. - + E%1 E%1 - + Delete all courses definitions for stage %1? Chcete odstranit všechny definice tratí pro etapu %1? - - - + + + Warning Upozornění - - - + + + Import does not yet support relays. Import zatím nepodporuje štafety. - - - - + + + + Open file Otevřít soubor - + XML files (*.xml);; All files (*) XML soubory (*.xml);; Všechny soubory (*) - + Class name '%1' seems to be combined, separate it to more classes? Název kategorie '%1' je pravděpodobně složený. Mám jej rozdělit na více kategorií? @@ -1197,37 +1211,37 @@ Zvažte nastavení intervalu pro všechny kategorie. Kontrola - + Competitor Závodník - + Reg Reg. č. - + Time Čas - + DISQ DISK - + Results Výsledky - + Finish Cíl - + R Radio station R @@ -1236,118 +1250,129 @@ Zvažte nastavení intervalu pro všechny kategorie. CompetitorRunsModel - + DISQ Disqualified DISK - + DO disqualifiedByOrganizer DO - + MP MisPunch MP - + BC BadCheck BC - + NC NotCompeting MS - + DNS DidNotStart DNS - + DNF DidNotFinish DNF - + CR Card rent requested VP - + CT Card in lent cards table ČT - + RET Card returned ČV - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning Startuje - + Is running Startuje - + Stage Etapa - + Relay Štafeta - + Class Kategorie - + Leg Úsek - + SI SI - + Start Start - + Time Čas - + Run flags Příznaky závodníka - + Card flags Příznaky čipu @@ -1371,7 +1396,7 @@ Zvažte nastavení intervalu pro všechny kategorie. - + Competitor Závodník @@ -1390,6 +1415,16 @@ Zvažte nastavení intervalu pro všechny kategorie. &SI &SI + + + ID + + + + + Create runs + + First na&me @@ -1435,7 +1470,7 @@ Zvažte nastavení intervalu pro všechny kategorie. Startovní časy - + Runs Úseky / Etapy @@ -1444,25 +1479,35 @@ Zvažte nastavení intervalu pro všechny kategorie. E&%1 - - Quick Event get start time + + Select competitor's start time - + New start time: Nový čas startu: - + Class should be entered. Není zadána kategorie. - + SQL error SQL chyba + + + Competitor form check + + + + + Class must be set. + + Competitors::CompetitorsPlugin @@ -1688,7 +1733,7 @@ Zvažte nastavení intervalu pro všechny kategorie. Nastavení úložiště dat - + Event files directory Adresář se soubory závodu @@ -1704,138 +1749,138 @@ Zvažte nastavení intervalu pro všechny kategorie. Core::CorePlugin - + &File Soubo&r - + &Import &Importovat - + &Export &Exportovat - + &Settings &Nastavení - + &Quit &Ukončit - + &Tools &Nástroje - + &SQL tool &SQL nástroj - + &Locale &Regionální nastavení - + &Language &Jazyk - + System Systémový - + Czech Čeština - + English Angličtina - + Flemish Vlámština - + French Francouzština - + Norwegian Norština - + Polish Polština - + Russian Ruština - + Ukrainian Ukrajinština - + Information Informace - + Language change to '%1' will be applied after application restart. Změna jazyka na '%1' se projeví až po restartu aplikace. - + &View &Zobrazit - + &Toolbar &Panel nástrojů - + &Help Ná&pověda - + &About Quick Event &About Quick event O &aplikaci Quick Event - + About &Qt O knihovně &Qt - + About Quick Event O aplikaci Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 <b>Quick Event</b> je aplikace na pořádání závodů v orientačním běhu.<br/><br/>Verze aplikace: %1<br/>commit: %7<br/>Minimální verze databáze: %2<br/>Datum a čas sestavení: %3 %4<br/>Verze SSL knihovny při sestavení: %5<br/>Verze aktuálně využívané SSL knihovny: %6 @@ -1844,7 +1889,7 @@ Zvažte nastavení intervalu pro všechny kategorie. <b>Quick Event</b> je aplikace na pořádání závodů v orientačním běhu.<br/><br/>Verze aplikace: %1<br/>Minimální verze databáze: %2<br/>Datum a čas sestavení: %3 %4<br/>Verze SSL knihovny při sestavení: %5<br/>Verze aktuálně využívané SSL knihovny: %6 - + About Qt O knihovně Qt @@ -1982,10 +2027,58 @@ Zvažte nastavení intervalu pro všechny kategorie. Zeměpisná šířka + + CoursesTableModel + + + Id + + + + + Name + Jméno + + + + Length + Délka + + + + Climb + Převýšení + + + + Maps + Map + + + + Runners + Závodníků + + + + Note + Poznámka + + + + Code count + + + + + Codes + Kontroly + + DbSchema - + Data version Verze dat @@ -2204,96 +2297,89 @@ Zvažte nastavení intervalu pro všechny kategorie. Tratě - Name - Jméno + Jméno - Length - Délka + Délka - Climb - Převýšení + Převýšení - Note - Poznámka + Poznámka - Cnt - Počet + Počet - Control count - Počet kontrol + Počet kontrol - Codes - Kontroly + Kontroly Event::EventPlugin - + &Connect to database &Připojit k databázi - + &Open event &Otevřít závod - + Create eve&nt &Vytvořit závod - + E&dit event &Upravit závod - - + + Event (*.qbe) Závod (*.qbe) - + &Event &Závod - + Event Závod - + Current stage E%1 Aktuální etapa E%1 - + Services Služby - + Registrations Registrace - + You are not connected to database. Program features will be limited. @@ -2306,12 +2392,12 @@ Připojení k databázi nebo vybrání pracovního adresáře, do kterého jsou "Soubor --> Připojit k databázi" - + Connect Database Error: %1 Chyba při připojování k databázi: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. @@ -2320,7 +2406,7 @@ Enter path to the working directory or connect to SQL server. Zadejte cestu k pracovnímu adresáři nebo se připojte k SQL serveru. - + Entered directory does not exist: %1 @@ -2331,162 +2417,162 @@ Enter a valid path to the working directory. Zadejte platnou cestu k pracovnímu adresáři. - + Create event Vytvořit závod - + Event ID cannot be empty. ID závodu nemůže být prázdné. - + Event ID %1 exists already. ID závodu %1 již existuje. - - - - - + + + + + Open Database Error: %1 Chyba při připojování databáze: %1 - - - + + + Create Database Error: %1 Chyba při vytváření databáze: %1 - + Cannot create event, database is not open: %1 Nelze vytvořit závod, databáze není připojena: %1 - + Edit event Upravit závod - + Connected to an empty database. Start by creating or importing an event. Připojeno k prázdné databázi. Začněte vytvořením nebo importováním nového závodu. - + Working directory does not contain any event files. Start by creating or importing an event. Pracovní adresář neobsahuje žádné závody. Začněte vytvořením nebo importováním nového závodu. - + select event to open: Vyberte závod k otevření: - + Open event Otevřít závod - + Database file %1 doesn't exist. Databázový soubor %1 neexistuje. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. Závod využívá příliš starou verzi dat (%1), minimální verze je (%2). Použij: Soubor --> Importovat --> Závod (*.qbe) pro konverzi dat do aktuální verze. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. Závod byl vytvořen v novější verzi QuickEventu (%1) a aplikace možná nebude pracovat tak, jak je očekáváno. Je doporučeno si stáhnout nejnovětší verzi QuickEventu. - + Export as Quick Event Exportovat jako Quick Event - - + + Quick Event files *%1 (*%1) Soubory Quick Eventu *%1 (*%1) - + Cannot delete existing file %1 Nelze smazat existující soubor %1 - - + + Creating database Vytvářím databázi - - + + Copying table %1 Kopíruji tabulku %1 - + Import as Quick Event Importovat jako Quick Event - + Query Dotaz - + Event will be imported as ID: Závod bude importován s ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. Název PostgreSQL schématu musí začínat malým písmenem a může obsahovat pouze malá písmena, číslovky a podtržítka. - + Event ID '%1' exists already! Závod s ID '%1' již existuje! - + Open imported event '%1'? Otevřít importovaný závod '%1'? - + Name Jméno - + Reg Reg. č. - + Lic Lic - + SI SI @@ -2631,6 +2717,217 @@ Použij: Soubor --> Importovat --> Závod (*.qbe) pro konverzi dat do aktu Nelze vytvořit adresář '%1'. + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + Propojení s OFeed platformou + + + Service Setup + Nastavení služby + + + + Export interval + Interval pro exportování + + + + sec + sek + + + + Url + Url + + + + <html><head/><body><p>OFeed instance url</p></body></html> + <html><head/><body><p>Url OFeed instance</p></body></html> + + + + + https://api.orienteerfeed.com + https://api.orienteerfeed.com + + + + Event id + Id akce + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + <html><head/><body><p>Id akce zjistitelné na vastavení akce na OFeed webu. Je možné ho získat i vykopírováním z url.</p></body></html> + + + + + From OFeed settings page + V sekci nastavení akce na webu OFeedu + + + + Password + Heslo + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + <html><head/><body><p>Vygenerované heslo v nastavení akce.</p></body></html> + + + + Credentials + Přihlašovací údaje + + + + Upload data + Nahrání dat + + + + Turn on/off changes processing + + + + + ON / OFF + ON / OFF + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + Rozšířené nastavení + + + + Run IOF XML validation + Provést IOF XML validaci + + + Upload Data + Nahrát data + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + <html><head/><body><p>Startovní listiny a výsledky se automaticky exportují v určených intervalech a změny, jako upravené údaje závodníků nebo noví závodníci, se synchronizují v reálném čase. Výsledky i startovní listiny lze také exportovat ručně pomocí tlačítek níže. Kromě toho, když je služba aktivní, jsou po načtení a po uložení dialogu závodníka odesílána i jednotlivá data závodníků. Více informací najdeš v <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">dokumentaci</span></a>.</p><p>Pokud narazíš na chybu, <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">napiš nám</span></a> prosím nebo ideálně vytvoř novou issue na <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">GitHubu</span></a>.</p></body></html> + + + + Export start list + Exportovat startovku + + + + Export results + Exportovat výsledky + + + Processing Changes + Zpracování změn + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + Změny z uvedeného místa (aktuálně pevně daná hodnota START) jsou zpracovávány automaticky a k zobrazení v <b>qxchange</b> modulu. + + + + Origin + Místo + + + + Process changes setup + Nastavení zpracování změn + + + + + START + START + + + + + ON + ON + + + + + OFF + OFF + + + + + Changes are automatically processed + Probíhá automatické zpracování změn + + + + + Processing changes is deactivated + Zpracování změn je vypnuté + + Event::services::OResultsClientWidget @@ -2697,12 +2994,12 @@ V případě chyb neváhejte napsat na support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. Event ID není načteno, služba pravděpodobně neběží. @@ -2715,41 +3012,41 @@ V případě chyb neváhejte napsat na support@oresults.eu Služba SVH API - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList Vypňte toto url do HTTP POST synchronizační metody v O-CheckList - + API token API token - + Not loaded Není načteno - + Current stage Aktuální etapa - + OCheckList Url OCheckList Url - + Exchange server url Exchange server url - + Event ID ID závodu @@ -2784,103 +3081,261 @@ V případě chyb neváhejte napsat na support@oresults.eu - + Connected OK Připojení je OK - + Connection error: %1 Chyba připojení : %1 - + Event info updated OK Informace o závodu aktualizovány OK - + Event info update error: %1 %2 chyba aktualizace informací o závodu: %1 %2 - + Start list export started ... Export startovní listiny začal ... - + Start list exported Ok Export startovní listiny OK - - Runs export started ... + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + Formulář + + + + TextLabel + + + + + All + + + + + + Type + Typ + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + Data + + + + Source + Zdroj + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + Dialog + + + + Class + Kategorie + + + + Run ID + + + + + + + + + None + Žádná + + + + Change ID + + + + + Lock number + + + + + First name + Jméno + + + + + + + -> - - Runs exported Ok - + + Last name + Příjmení - - - Event::services::qx::QxLateRegistrationsWidget - - Form - Formulář + + Registration + Registrace - - TextLabel + + SI Card - - Type - Typ + + + Rent + - - Data - Data + + Note + Poznámka - - Source - Zdroj + + Message + - - Run + + Force - - User - + + Cancel + Zrušit - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -3124,92 +3579,92 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závodu EventStatisticsModel - + Class Kategorie - + Maps Map - + Free maps Volné mapy - + Runners Závodníků - + Start first Start prvního - + Start last Start posledního - + 1st time Čas prvního - + Finish time of first runner in current class. Cílový čas prvního závodníka v dané kategorii. - + 3rd time Čas třetího - + Finish time of third runner in current class. Cílový čas třetího závodníka v dané kategorii. - + Time to close Čas do uzavření - + Time until new finished competitors should not affect standings on first three places. Čas do okamžiku, kdy by nově doběhlí závodníci neměli ovlivnit pořadí na prvních třech místech. - + Finished Doběhlo - + Not finished Nedoběhlo - + New results Nové výsledky - + Number of finished competitors not printed in results. Počet doběhlých závodníků, kteří ještě nejsou ve vytisknutých výsledcích. - + Not printed time Čas od tisku - + Time since recent results printout. Čas od posledního tisku výsledků dané kategorie. @@ -3417,12 +3872,12 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závodu MainWindow - + Quick Event ver. %1 Quick Event ver. %1 - + Application log Záznam činnosti aplikace @@ -3430,52 +3885,67 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závodu Model - + SI SI - + Class Kategorie - + Name Jméno - + Reg Reg. č. - + Bib - + Start Start - + Time Čas - + Finish Cíl - + Run flags Příznaky závodníka - + + CR + VP + + + + Card rent + + + + + CRT + + + + Error Chyba @@ -3492,104 +3962,107 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závoduDiskvalifikace - RT - ČT + ČT - + Card in rent table Čip z tabulky čipů k zapůjčení - R - ČV + ČV - + Card returned Čip vrácen - + + CRET + + + + CTIME Čas-K - + Card check time Čas kontroly vynulování čipu - + STIME Čas-S - + Card start time Startovní čas na čipu - + FTIME Čas-C - + Card finish time Cílový čas na čipu - + Assign card to runner error Chyba při přiřazení čipu závodníkovi - + NC NotCompeting MS - + MP MisPunch MP - + BC BadCheck BC - + DNS DidNotStart DNS - + DNF DidNotFinish DNF - + DO disqualifiedByOrganizer DO - + OT OverTime OT - + DSQ Disqualified DISK @@ -3613,52 +4086,52 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závodu&Synchronizovat záznamy aktuálního závodu - + &Clubs and registrations &Kluby a registrace - + &Update one-time clubs &Aktualizovat jednorázové kluby - + &Text file &Textový soubor - + &Competitors CSOS &Seznam závodníků ve formátu ČSOS - + Competitors C&SV Seznam závodníků ve formátu &CSV - + &Ranking CSV (ORIS format) &Rankingová data v CSV (formát ORISu) - + Import CSV (key is CZE registration) Importovat CSV (klíč je CZE registrace) - + Import CSV (key is runs.id) Importovat CSV (klíč je runs.id) - + Import CSV (key is Iof ID) Importovat CSV (klíč je IOF ID) - + Import IOF XML 3.0 Importovat IOF XML 3.0 @@ -3666,107 +4139,107 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závodu OrisImporter - + Cannot find Oris import ID. Nelze najít ORIS ID pro provedení synchronizace. - + New entries Nové přihlášky - + Edited entries Upravené přihlášky - + Deleted entries Smazané přihlášky - + Oris import report Zpráva o importu z ORISu - + Save without drops Uložit bez smazaných - + Export Exportovat - + Export as ... Exportovat jako ... - + HTML files *.html (*.html) soubory HTML *.html(*.html) - + Cannot open file '%1' for writing. Soubor '%1' nelze otevřít pro zápis. - + Importing registrations Importuji registrace - + Importing clubs Importuji kluby - + Warning Upozornění - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event Pro import jednorázových klubů je potřeba mít vyplněn ORISový bezpečnostní klíč závodu v Soubor->Závod->Upravit závod - + Information Informace - + No missing one-time clubs found. Nenalezen žádný chybějící jednorázový klub. - + Importing one-time clubs Importuji jednorázové kluby - + JSON document parse error: %1 at: %2 near: %3 Chyba při analýze JSON dokumentu: %1 na: %2 poblíž: %3 - + Import finished successfully. Import byl úspěšně dokončen. - + Import ORIS Registrations Importovat registrace z ORISu - + Year of registration: Registrace z roku: @@ -3807,7 +4280,20 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závoduČip - + + + Warning + + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt Mezičas @@ -4038,48 +4524,48 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závoduVytisknout nové - + SI SI - + Class Kategorie - + Name Jméno - + Reg Reg. č. - + Start Start - + Time Čas - + printer Tiskárna - + Print receipts for selected rows Print selected cards Vytisknout mezičasy pro vybrané řádky - + Show receipt Zobrazit mezičasy @@ -4392,79 +4878,79 @@ zdroj - ORIS->Závod->Informace->Bezpečnostní klíč závoduV abecedním pořadí - + Start list by classes Startovní listina po kategoriích - + Start list by clubs Startovní listina po klubech - - - + + + Results Výsledky - + Save as %1 Uložit jako %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8.<br/>Oddělovač je středník(;).<br/>Aktualizuje pouze existujiící štafety (klíč je Klub, Název štafety a Kategorie). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> Každý řádek by měl mít následující sloupce:<ol><li>Zkratka klubu <i>- klíč (část1)</i></li><li>Název štafety<i> - klíč (část2)</i></li><li>Startovní číslo</li><li>Kategorii (Volitelné - pokud není vyplněno, zkouší se kategorie odhadnout podle startovního čísla)</li></ol> - + Open file Otevřít soubor - + CSV files (*.csv *.txt) soubory CSV (*.csv *.txt) - + Cannot open file '%1' for reading. Soubor '%1' nelze otevřít pro čtení. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] Chyba při analýze CSV souboru, neplatný formát, chyba při čtení řádky: [%1] - + Error reading CSV line: [%1] Chyba při čtení souboru CSV, řádek: [%1] - + Cannot guess class name from bib: '%1' Nemohu odhadnout název kategorie podle startovního čísla: '%1' - + Undefined class name: '%1' Neznámý název kategorie: '%1' - + Information Informace - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. @@ -4473,17 +4959,17 @@ Press refresh button to show imported data. Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. - + vac vak - + Enter number of new vacants Zadejte počet nových vakantů - + Vacants count for class %1 : Počet vakantů pro kategorii %1 : @@ -4663,29 +5149,29 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Pozdní registrace - + E%1 IOF XML stage results E%1 IOF XML etapové výsledky - - + + Start list by classes Startovní listina po kategoriích - - + + Start list by clubs Startovní listina po klubech - + Start list for starters Startovní listina pro startéry - + Start list by classes for %n stage(s) Startovní listina po kategoriích na %n etapu @@ -4694,7 +5180,7 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. - + Start list by clubs for %n stage(s) Startovní listina po klubech na %n etapu @@ -4703,19 +5189,19 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. - - + + Results by classes Výsledky po kategoriích - + Stage awards Etapové diplomy - - + + Results after %n stage(s) Results after %1 stages @@ -4725,169 +5211,169 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. - + Awards after %1 stages Diplomy po %1 etapách - - + + length: délka: - - + + climb: převýšení: - - - - + + + + Top Nahoru - - + + St. Num St. čís. - - - - - + + + + + Name Jméno - - - - - + + + + + Registration Registrace - - + + SI SI - - + + Start Start - + Class Kategorie - + Preparing data Připravuji data - - + + Procesing class %1 Zpracovávám kategorii %1 - + Laps Mezičasy - - - + + + Place Pořadí - - + + Club Klub - - - + + + Time Čas - - - + + + Loss Ztráta - + NC Not Competing MS - + DISQ DISK - + E%1 IOF XML stage startlist E%1 IOF XML startovka etapy - - - + + + Stage results Výsledky etapy - + Warning Varování - + Export error Chyba při exportu - + Information Informace - + Results exported to %1 Výsledky exportovány do %1 - + Overall results after stage %1 Celkové výsledky po %1. etapě - + Stage %1 Etapa %1 - + FIN CÍL @@ -4956,37 +5442,37 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Výstupní formát - + HTML multi page HTML stránka pro každou kategorii - + CSOS fixed column sizes ČSOS fixní šířka sloupců - + CSV one file CSV (jeden soubor) - + CSV multi file (file per class) CSV (soubor pro každou kategorii) - + IOF-XML 3.0 IOF XML 3.0 - + Open Directory Otevřít adresář - + Cannot create directory '%1'. Nelze vytvořit adresář '%1'. @@ -5108,70 +5594,70 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. RunsTableModel - + Running Runnig Startuje - + id id - + Relay Štafeta - + Leg Úsek - + Class Kategorie - + SN start number - + Start number Startovní číslo - - + + SI SI - + Registered SI SI v přihlášce - + Name Jméno - + Reg Reg. č. - + Lic Lic - + License Licence @@ -5184,131 +5670,131 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Ranking - + Actual SI Aktuální SI - + Corridor Koridor - + Time when the competitor entered start corridor Čas, kdy závodník vstoupil do startovacího koridoru - + Check Kontrola čipu - + Start Start - + Time Čas - + Finish Cíl - + Penalty Penalizace - + Run flags Příznaky závodníka - + Card flags Příznaky čipu - + Ranking pos Ranking umístění - + Runner's position in CZ ranking. Pozice závodníka v CZ rankingu. - + IOF ID IOF ID - + DO disqualifiedByOrganizer DO - + MP MisPunch MP - + BC BadCheck PK - + NC NotCompeting MS - + CR Card rent requested VP - + CT Card in lent cards table ČT - + RET Card returned ČV - + Note Poznámka - + DNS DidNotStart DNS - + DNF DidNotFinish DNF - + OT OverTime OT @@ -5319,18 +5805,18 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.DISK - + Cannot set not running flag for competitor with valid finish time. Canont set not running flag for competitor with valid finish time. Nelze nastavit příznak "nestartuje" závodníkovi s validním cílovým časem. - + Mid-air collision switching start times, reload table and try it again. Pokus o současné prohození startovního času ze dvou míst, obnovte tabulku a zkuste to znovu. - + Mid-air collision setting start time, reload table and try it again. Pokus o současnou změnu startovního času ze dvou míst, obnovte tabulku a zkuste to znovu. @@ -5359,65 +5845,65 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.interval - + Show receipt Show card Ukázat mezičasy - + Load times from card in selected rows Načíst časy z čipu ve vybraných řádcích - + Print receipt Print card Vytisknout mezičasy - + Shift start times in selected rows Posunout startovní čas ve vybraných řádcích - + Clear start times in selected rows Clear times in selected rows Vymazat startovní časy ve vybraných řádcích - + Set class in selected rows Nastavit kategorii ve vybraných řádcích - + Reloading times for %1 Znovu načítám časy pro %1 - + Get number Zadejte číslo - + Start times offset [min]: Offset startovního času [min]: - + Dialog Dialog - + Select class Vyberte kategorii - + Duplicate SI inserted. Vloženo duplicitní SI. @@ -5591,7 +6077,7 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. - + Competitors statistics Statistiky závodníků @@ -5680,27 +6166,26 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.ČSOS - + Really delete all the selected competitors? This action cannot be reverted. Opravdu odstranit všechny vybrané závodníky? Tato akce nemůže být vrácena. - + Confirm deletion of %1 competitors. Potvrďte odstranění %1 závodníků. - + Edit Competitor Upravit závodníka - Save - Uložit + Uložit - + Ok and &next Ok a &další @@ -5766,12 +6251,12 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Kategorie má uzamčené losování. - + Start interval is zero, proceed anyway? Startovní interval je nula. Chcete přesto pokračovat? - + Reset all start times and unlock drawing for this class? Reset all start times and unlock for drawing for this class? Odstranit všechny startovní časy v této kategorii a odemknout losování? @@ -5780,7 +6265,7 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. Speaker::SpeakerPlugin - + &Speaker &Komentátor @@ -5793,37 +6278,37 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Formulář - + Code Kontrola - + SI SI - + Punch time Čas ražení - + Runner time Čas závodníka - + Class Kategorie - + Registration Registrace - + Competitor Závodník @@ -5862,67 +6347,67 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. Importování souboru ve formátu ČSOS a kódování Windows-1250. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> Každá řádka by měla mít následující sloupce: <ol><li>7 znaků: registrační číslo</li><li>1 mezera</li><li>10 znaků: kategorie</li><li>1 mezera</li><li>10 znaků: číslo SI čipu</li><li>1 mezera</li><li>25 znaků: jméno a příjmení</li><li>1 mezera</li><li>2 znaky: licence</li><li>1 mezera</li><li>do konce řádky: poznámka</li></ol> - - - - - - + + + + + + Open file Otevřít soubor - + CSOS files (*.txt) soubory formátu ČSOS (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. Soubor '%1' nelze otevřít pro čtení. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8.<br/>Oddělovač je středník(;).<br/>Aktualizuje pouze existující závodníky (klíč je Česká registrace). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. Každá řádka by měla mít následující sloupce: <ol><li>Registrace <i>- klíč</i></li><li>SI</li><li>Kategorie</li><li>Startovní číslo</li><li>Startovní čas <i>(ve formátu: <b>mmm.ss</b> od času 00 nebo <b>hh:mm:ss</b>)</i></li></ol>Povinný je pouze první sloupec, ostatní mohou být prázdné. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8.<br/>Oddělovač je středník(;).<br/>Aktualizuje pouze existující závodníky (klíč je <b>id</b> v modulu(tabulce) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. Každá řádka by měla mít následující sloupce: <ol><li>Runs id <i>- klíč</i></li><li>SI</li><li>Kategorie</li><li>Startovní číslo</li><li>Startovní čas <i>(ve formátu: <b>mmm.ss</b> od času 00 nebo <b>hh:mm:ss</b>)</i></li></ol>Povinný je pouze první sloupec, ostatní mohou být prázdné. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8.<br/>Oddělovač je středník(;).<br/>Aktualizuje pouze existující závodníky (klíč je IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. Každá řádka by měla mít následující sloupce: <ol><li>IOF ID <i>- klíč</i></li><li>SI</li><li>Kategorie</li><li>Startovní číslo</li><li>Startovní čas <i>(ve formátu: <b>mmm.ss</b> od času 00 nebo <b>hh:mm:ss</b>)</i></li></ol>Povinný je pouze první sloupec, ostatní mohou být prázdné. @@ -5931,49 +6416,49 @@ Stskněte tlačítko pro obnovení pro zobrazení importovaných dat.Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8. - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> Každá řádka by měla mít následující sloupce: <ol><li>registrační číslo</li><li>kategorie</li><li>číslo SI čipu</li><li>příjmení</li><li>křestní jméno</li><li>licence</li><li>poznámka</li></ol> - - - - + + + + CSV files (*.csv *.txt) soubory CSV (*.csv *.txt) - - - - + + + + Error reading CSV line: [%1] Chyba při čtení souboru CSV, řádek: [%1] - - - - + + + + Undefined class name: '%1' Neznámý název kategorie: '%1' - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] Chyba při analýze CSV souboru, neplatný formát, chyba při čtení řádky: [%1] - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) Importovat soubor s hodnotami oddělenými čárkou (CSV), včetně záhlaví, v kódování UTF-8.<br/>Oddělovač je ČÁRKA(,) - + Oris ranking CSV files (*.txt *.csv) Soubory rankingu z ORISu (*.txt *.csv) diff --git a/quickevent/app/quickevent/quickevent-fr_FR.ts b/quickevent/app/quickevent/quickevent-fr_FR.ts index dc0ac16c3..dd13782ee 100644 --- a/quickevent/app/quickevent/quickevent-fr_FR.ts +++ b/quickevent/app/quickevent/quickevent-fr_FR.ts @@ -501,227 +501,227 @@ - + Show receipt Afficher le reçu - + Print receipt Afficher le reçu - + Show card data - + Print card data - + Assign card to runner - + Recalculate times in selected rows - + Open COM to connect SI reader - + Recalculating times for %1 - + &Station - + Station info - + Read station memory - + &Tools &Outils - + Import cards - + Laps only CSV - + SI reader backup memory CSV - + Test audio - - + + SI station not connected - + Assign card to runner Ctrl + Enter - + Connected to %1 in direct mode. - + Error set SI station to direct mode. - + Error open device %1 - %2 - + DriverInfo: <%1> %2 - + DriverRawData: %1 - + card: %1 - + Cannot find run for punch record SI: %1 - + Saved punch: %1 %2 - + Competitor off-race - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> - + Import CSV - - + + Cannot open file '%1' for reading. - - + + Bad stage! - + Cannot find runs record for SI %1! - + Cannot find class for SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. - + Import TXT - + Downloading station backup ... - + Cancelled by user - + No. - + SI - + DateTime - + Card error Erreur de carte - + Station %1 backup memory - + Station backup memory @@ -744,37 +744,37 @@ If you continue, this flag will be removed - + Loading event list from Oris ... - + OB - + LOB - + MTBO - + TRAIL - + ??? - + Search in events ... @@ -992,125 +992,139 @@ If you continue, this flag will be removed Escalade - Rel.num - Numéro de relai + Numéro de relai - - Relay start number + + Rel. count + Relays count + + + + + Relay start number + + + + + Rel. num + + + + Legs - + Relay leg count - + &Edit - + Cou&rses - + Co&des - + Classes &layout - + Ctrl+L - + &Import &Importer - + OCAD TXT - + OCAD v8 - + OCAD IOF XML 2.0 - + OCAD IOF XML 3.0 - + Stage Étape - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. - + E%1 E%1 - + Delete all courses definitions for stage %1? - - - + + + Warning Avertissement - - - + + + Import does not yet support relays. - - - - + + + + Open file - + XML files (*.xml);; All files (*) - + Class name '%1' seems to be combined, separate it to more classes? @@ -1182,37 +1196,37 @@ Consider setting "Interval" column for all classes before continuing.< Code - + Competitor Compétiteur - + Reg Ins - + Time Heure - + DISQ DISQ - + Results Résultats - + Finish Terminer - + R Radio station @@ -1221,118 +1235,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified DISQ - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting NP - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning - + Is running En train de courir - + Stage Étape - + Relay Relai - + Class Classe - + Leg Jambe - + SI - + Start Départ - + Time - + Run flags - + Card flags @@ -1356,7 +1381,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor Compétiteur @@ -1375,6 +1400,16 @@ Consider setting "Interval" column for all classes before continuing.< First na&me Prénom + + + ID + + + + + Create runs + + &Last name @@ -1420,30 +1455,40 @@ Consider setting "Interval" column for all classes before continuing.< Temps de départ - + Runs Courses - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. La classe doit être saisie. - + SQL error + + + Competitor form check + + + + + Class must be set. + + Competitors::CompetitorsPlugin @@ -1630,7 +1675,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Event files directory @@ -1646,143 +1691,143 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File &Fichier - + &Import &Importer - + &Export &Exporter - + &Settings - + &Quit &Quitter - + &Tools &Outils - + &SQL tool &Outils SQL - + &Locale &Langue - + &Language &Langue - + System Système - + Czech Tchèque - + English Anglais - + Flemish Flamand - + French Français - + Norwegian Norvégien - + Polish Polonais - + Russian Russe - + Ukrainian Ukrainien - + Information Information - + Language change to '%1' will be applied after application restart. Le changement de langue vers « %1 » sera appliqué après le redémarrage de l'application. - + &View &Fenêtre - + &Toolbar &Barre d'outils - + &Help &Aide - + &About Quick Event &About Quick event &À propos de Quick event - + About &Qt À propos de Qt - + About Quick Event À propos de Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 - + About Qt À propos de Qt @@ -1908,10 +1953,58 @@ Consider setting "Interval" column for all classes before continuing.< + + CoursesTableModel + + + Id + + + + + Name + Nom + + + + Length + Longueur + + + + Climb + Escalade + + + + Maps + Cartes + + + + Runners + Coureurs + + + + Note + Remarque + + + + Code count + + + + + Codes + Codes + + DbSchema - + Data version @@ -2130,96 +2223,81 @@ Consider setting "Interval" column for all classes before continuing.< - Name - Nom + Nom - Length - Longueur + Longueur - Climb - Escalade + Escalade - Note - Remarque - - - - Cnt - + Remarque - - Control count - - - - Codes - Codes + Codes Event::EventPlugin - + &Connect to database - + &Open event - + Create eve&nt - + E&dit event - - + + Event (*.qbe) - + &Event - + Event - + Current stage E%1 - + Services - + Registrations Inscriptions - + You are not connected to database. Program features will be limited. @@ -2228,19 +2306,19 @@ To connect to a database or to choose a working directory where event files can - + Connect Database Error: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. - + Entered directory does not exist: %1 @@ -2248,159 +2326,159 @@ Enter a valid path to the working directory. - + Create event - + Event ID cannot be empty. - + Event ID %1 exists already. - - - - - + + + + + Open Database Error: %1 - - - + + + Create Database Error: %1 - + Cannot create event, database is not open: %1 - + Edit event - + Connected to an empty database. Start by creating or importing an event. - + Working directory does not contain any event files. Start by creating or importing an event. - + Open event - + select event to open: - + Database file %1 doesn't exist. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. - + Export as Quick Event - - + + Quick Event files *%1 (*%1) - + Cannot delete existing file %1 - - + + Creating database - - + + Copying table %1 - + Import as Quick Event - + Query - + Event will be imported as ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. - + Event ID '%1' exists already! - + Open imported event '%1'? - + Name Nom - + Reg Ins - + Lic Lic - + SI @@ -2545,6 +2623,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version Impossible de créer le dossier « %1 ». + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + Exporter l'intervale + + + + sec + sec + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + + + + + Export results + Exporter les résultats + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2606,12 +2883,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2624,41 +2901,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage Étape courante - + OCheckList Url - + Exchange server url - + Event ID @@ -2693,102 +2970,260 @@ In case of unexpected errors, contact support@oresults.eu - + Connected OK - + Connection error: %1 - + Event info updated OK - + Event info update error: %1 %2 - - Start list export started ... + + Start list export started ... + + + + + Start list exported Ok + + + + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + Formulaire + + + + TextLabel + + + + + All + + + + + + Type + + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + Boîte de dialogue + + + + Class + Classe + + + + Run ID + + + + + + + + + None + + + + + Change ID + + + + + Lock number - - Start list exported Ok + + First name - - Runs export started ... + + + + + -> - - Runs exported Ok + + Last name - - - Event::services::qx::QxLateRegistrationsWidget - - Form - Formulaire + + Registration + Inscription - - TextLabel + + SI Card - - Type + + + Rent - - Data - + + Note + Remarque - - Source + + Message - - Run + + Force - - User + + Cancel - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -3020,92 +3455,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class Classe - + Maps Cartes - + Free maps Cartes libres - + Runners Coureurs - + Start first - + Start last - + 1st time Première place - + Finish time of first runner in current class. Heure d'arrivée du premier coureur de la classe courante. - + 3rd time Troisième place - + Finish time of third runner in current class. Heure d'arrivée du troisième coureur dans la classe courante. - + Time to close - + Time until new finished competitors should not affect standings on first three places. - + Finished Terminée - + Not finished Non terminée - + New results Nouveaux résultats - + Number of finished competitors not printed in results. Nombre de compétiteurs ayant terminé la course non affichés dans les résultats. - + Not printed time Durée de non affichage - + Time since recent results printout. Temps écoulé depuis le dernier affichage des résultats. @@ -3312,12 +3747,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 Quick Event vers. %1 - + Application log Journaux de l'application @@ -3325,52 +3760,67 @@ source - ORIS->Event->Information->Event key Model - + SI - + Class Classe - + Name Nom - + Reg Ins - + Bib - + Start Départ - + Time - + Finish - + Run flags - + + CR + + + + + Card rent + + + + + CRT + + + + Error Erreur @@ -3383,104 +3833,99 @@ source - ORIS->Event->Information->Event key Disqualifié - - RT - - - - + Card in rent table - - R + + Card returned - - Card returned + + CRET - + CTIME - + Card check time - + STIME - + Card start time - + FTIME - + Card finish time - + Assign card to runner error - + NC NotCompeting NP - + MP MisPunch - + BC BadCheck - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer - + OT OverTime - + DSQ Disqualified @@ -3504,52 +3949,52 @@ source - ORIS->Event->Information->Event key - + &Clubs and registrations - + &Update one-time clubs - + &Text file - + &Competitors CSOS - + Competitors C&SV - + &Ranking CSV (ORIS format) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3557,107 +4002,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 - + Cannot find Oris import ID. - + Import finished successfully. - + New entries - + Edited entries - + Deleted entries - + Oris import report - + Save without drops - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations - + Year of registration: - + Importing registrations - + Importing clubs - + Warning Avertissement - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information Information - + No missing one-time clubs found. - + Importing one-time clubs @@ -3698,7 +4143,20 @@ source - ORIS->Event->Information->Event key - + + + Warning + Avertissement + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt @@ -3923,47 +4381,47 @@ source - ORIS->Event->Information->Event key - + SI - + Class Classe - + Name Nom - + Reg Ins - + Start Départ - + Time - + printer - + Print receipts for selected rows - + Show receipt Afficher le reçu @@ -4269,96 +4727,96 @@ source - ORIS->Event->Information->Event key - + Start list by classes Démarrer la liste par les classes - + Start list by clubs Démarrer la liste par les clubs - - - + + + Results Résultats - + Save as %1 Enregistrer sous %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file - + CSV files (*.csv *.txt) - + Cannot open file '%1' for reading. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - + Error reading CSV line: [%1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' - + Information Information - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4529,29 +4987,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results - - + + Start list by classes Démarrer la liste par les classes - - + + Start list by clubs Démarrer la liste par les clubs - + Start list for starters - + Start list by classes for %n stage(s) @@ -4559,7 +5017,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) @@ -4567,19 +5025,19 @@ Press refresh button to show imported data. - - + + Results by classes Résultats par classe - + Stage awards Prix d'étape - - + + Results after %n stage(s) Résultats après %n étape @@ -4587,169 +5045,169 @@ Press refresh button to show imported data. - + Awards after %1 stages Prix après %1 étapes - - + + length: longueur : - - + + climb: dénivelé : - - - - + + + + Top Haut - - + + St. Num - - - - - + + + + + Name Nom - - - - - + + + + + Registration Inscription - - + + SI - - + + Start Départ - + Class Classe - + Preparing data Préparation des données - - + + Procesing class %1 Traitement de la classe %1 - + Laps Délais - - - + + + Place Place - - + + Club Club - - - + + + Time Heure - - - + + + Loss Perte - + NC Not Competing NP - + DISQ DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results Résultats de l'étape - + Warning Avertissement - + Export error Erreur d'exportation - + Information Information - + Results exported to %1 Résultats exportés vers %1 - + Overall results after stage %1 - + Stage %1 - + FIN @@ -4817,37 +5275,37 @@ Press refresh button to show imported data. Format de sortie - + HTML multi page Pages HTML - + CSOS fixed column sizes - + CSV one file - + CSV multi file (file per class) - + IOF-XML 3.0 IOF-XML 3.0 - + Open Directory Ouvrir le dossier - + Cannot create directory '%1'. Impossible de créer le dossier « %1 ». @@ -4915,69 +5373,69 @@ Press refresh button to show imported data. RunsTableModel - + Running Course - + id identifiant - + Relay Relai - + Leg Jambe - + Class Classe - + SN start number ND - + Start number Numéro de départ - - + + SI - + Registered SI - + Name Nom - + Reg Ins - + Lic Lic - + License Licence @@ -4990,147 +5448,147 @@ Press refresh button to show imported data. Classement - + Actual SI - + Corridor - + Time when the competitor entered start corridor - + Check Vérifier - + Start Départ - + Time Temps - + Finish Arrivée - + Penalty Pénalité - + Run flags - + Card flags - + Ranking pos - + Runner's position in CZ ranking. - + IOF ID - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting NP - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + Note Remarque - + DNS DidNotStart - + DNF DidNotFinish - + OT OverTime - + Cannot set not running flag for competitor with valid finish time. Impossible de définir un compétiteur comme non partant s'il possède une heure d'arrivée valide. - + Mid-air collision switching start times, reload table and try it again. - + Mid-air collision setting start time, reload table and try it again. @@ -5159,62 +5617,62 @@ Press refresh button to show imported data. intervale - + Show receipt Afficher le reçu - + Load times from card in selected rows - + Print receipt Afficher le reçu - + Shift start times in selected rows - + Clear start times in selected rows - + Set class in selected rows Définir la classe dans les lignes sélectionnées - + Reloading times for %1 Rechargement des temps pour %1 - + Get number Obtenir le numéro - + Start times offset [min]: - + Dialog Boîte de dialogue - + Select class Sélectionner la classe - + Duplicate SI inserted. @@ -5387,7 +5845,7 @@ Press refresh button to show imported data. - + Competitors statistics Statistiques des compétiteurs @@ -5476,27 +5934,22 @@ Press refresh button to show imported data. - + Really delete all the selected competitors? This action cannot be reverted. Voulez-vous vraiment supprimer les compétiteurs sélectionnés ? Cette action ne peut pas être annulée. - + Confirm deletion of %1 competitors. Confirmer la suppression de %1 compétiteurs. - + Edit Competitor Modifier le compétiteur - - Save - - - - + Ok and &next @@ -5561,12 +6014,12 @@ Press refresh button to show imported data. - + Start interval is zero, proceed anyway? - + Reset all start times and unlock drawing for this class? @@ -5574,7 +6027,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker &Intervenant @@ -5587,37 +6040,37 @@ Press refresh button to show imported data. Formulaire - + Code Code - + SI - + Punch time - + Runner time - + Class Classe - + Registration Inscription - + Competitor Compétiteur @@ -5644,114 +6097,114 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> - - - - - - + + + + + + Open file - + CSOS files (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> - - - - + + + + CSV files (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - - - - + + + + Error reading CSV line: [%1] - - - - + + + + Undefined class name: '%1' - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. diff --git a/quickevent/app/quickevent/quickevent-nb_NO.ts b/quickevent/app/quickevent/quickevent-nb_NO.ts index 19f9434a1..f332a0a5b 100644 --- a/quickevent/app/quickevent/quickevent-nb_NO.ts +++ b/quickevent/app/quickevent/quickevent-nb_NO.ts @@ -486,229 +486,229 @@ CardReaderWidget - + Show receipt Vis kvittering - + Print receipt - + Show card data Show card Vis kortdata - + Print card data Print card Skriv ut kartdata - + Assign card to runner - + Recalculate times in selected rows - + Open COM to connect SI reader - + Recalculating times for %1 - + &Station &Stasjon - + Station info Stasjonsinfo - + Read station memory Les stasjonsminne - + &Tools &Verktøy - + Import cards Importer kort - + Laps only CSV - + SI reader backup memory CSV - + Test audio Test lyd - - + + SI station not connected - + Assign card to runner Ctrl + Enter - + Connected to %1 in direct mode. - + Error set SI station to direct mode. - + Error open device %1 - %2 - + DriverInfo: <%1> %2 - + DriverRawData: %1 - + card: %1 - + Cannot find run for punch record SI: %1 - + Saved punch: %1 %2 - + Competitor off-race - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> - + Import CSV Importer CSV - - + + Cannot open file '%1' for reading. - - + + Bad stage! - + Cannot find runs record for SI %1! - + Cannot find class for SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. - + Import TXT - + Downloading station backup ... - + Cancelled by user - + No. Nei. - + SI - + DateTime - + Card error Kortfeil - + Station %1 backup memory - + Station backup memory @@ -746,37 +746,37 @@ If you continue, this flag will be removed - + Loading event list from Oris ... - + OB - + LOB - + MTBO - + TRAIL - + ??? - + Search in events ... @@ -995,129 +995,139 @@ If you continue, this flag will be removed - - Rel.num + + Rel. count + + + + + Relays count - + Relay start number - + + Rel. num + + + + Legs - + Relay leg count - + &Edit &Rediger - + Cou&rses - + Co&des - + Classes &layout - + Ctrl+L Ctrl+L - + &Import &Importer - + OCAD TXT OCad TXT - + OCAD v8 OCad v8 - + OCAD IOF XML 2.0 OCad IOF-XML 2.0 - + OCAD IOF XML 3.0 OCad IOF-XML 3.0 - + Stage - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. - + E%1 - + Delete all courses definitions for stage %1? - - - + + + Warning - - - + + + Import does not yet support relays. - - - - + + + + Open file Åpne fil - + XML files (*.xml);; All files (*) XML-filer (*.xml);; Alle filer (*) - + Class name '%1' seems to be combined, separate it to more classes? @@ -1189,37 +1199,37 @@ Consider setting "Interval" column for all classes before continuing.< Kode - + Competitor - + Reg - + Time Tid - + DISQ - + Results Resultater - + Finish Fullfør - + R Radio station @@ -1228,118 +1238,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning Kjører - + Is running Kjører - + Stage - + Relay - + Class Klasse - + Leg - + SI - + Start Start - + Time Tid - + Run flags - + Card flags @@ -1363,7 +1384,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor @@ -1382,6 +1403,16 @@ Consider setting "Interval" column for all classes before continuing.< &Class &Klasse + + + ID + + + + + Create runs + + &Last name @@ -1427,30 +1458,40 @@ Consider setting "Interval" column for all classes before continuing.< Starttider - + Runs Kjøringer - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. Klasse skal skrives inn. - + SQL error + + + Competitor form check + + + + + Class must be set. + + Competitors::CompetitorsPlugin @@ -1585,7 +1626,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Event files directory @@ -1601,143 +1642,143 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File &Fil - + &Import &Importer - + &Export - + &Settings - + &Quit &Avslutt - + &Tools &Verktøy - + &SQL tool &SQL-verktøy - + &Locale - + &Language &Språk - + System System - + Czech Tsjekkisk - + English Engelsk - + Flemish - + French - + Norwegian - + Polish - + Russian - + Ukrainian - + Information - + Language change to '%1' will be applied after application restart. - + &View &Vis - + &Toolbar &Verktøyslinje - + &Help &Hjelp - + &About Quick Event &About Quick event & Om Quick Event - + About &Qt Om &Qt - + About Quick Event Om Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 - + About Qt Om Qt @@ -1863,10 +1904,58 @@ Consider setting "Interval" column for all classes before continuing.< + + CoursesTableModel + + + Id + + + + + Name + Navn + + + + Length + Lengde + + + + Climb + + + + + Maps + Kart + + + + Runners + + + + + Note + Merknad + + + + Code count + + + + + Codes + Koder + + DbSchema - + Data version @@ -2085,96 +2174,77 @@ Consider setting "Interval" column for all classes before continuing.< - Name - Navn + Navn - Length - Lengde - - - - Climb - + Lengde - Note - Merknad - - - - Cnt - - - - - Control count - + Merknad - Codes - Koder + Koder Event::EventPlugin - + &Connect to database &Koble til database - + &Open event - + Create eve&nt - + E&dit event - - + + Event (*.qbe) - + &Event - + Event - + Current stage E%1 - + Services Tjenester - + Registrations Registreringer - + You are not connected to database. Program features will be limited. @@ -2183,19 +2253,19 @@ To connect to a database or to choose a working directory where event files can - + Connect Database Error: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. - + Entered directory does not exist: %1 @@ -2203,159 +2273,159 @@ Enter a valid path to the working directory. - + Create event - + Event ID cannot be empty. - + Event ID %1 exists already. - - - - - + + + + + Open Database Error: %1 Databaseåpningsfeil: %1 - - - + + + Create Database Error: %1 - + Cannot create event, database is not open: %1 - + Edit event - + Connected to an empty database. Start by creating or importing an event. - + Working directory does not contain any event files. Start by creating or importing an event. - + select event to open: - + Open event - + Database file %1 doesn't exist. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. - + Export as Quick Event - - + + Quick Event files *%1 (*%1) - + Cannot delete existing file %1 - - + + Creating database Oppretter database - - + + Copying table %1 - + Import as Quick Event - + Query Spørring - + Event will be imported as ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. - + Event ID '%1' exists already! - + Open imported event '%1'? - + Name Navn - + Reg - + Lic - + SI @@ -2500,6 +2570,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + + + + + sec + + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + + + + + Export results + + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2561,12 +2830,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2579,41 +2848,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage - + OCheckList Url - + Exchange server url - + Event ID @@ -2648,102 +2917,260 @@ In case of unexpected errors, contact support@oresults.eu - + Connected OK - + Connection error: %1 - + Event info updated OK - + Event info update error: %1 %2 - - Start list export started ... + + Start list export started ... + + + + + Start list exported Ok + + + + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + + + + + TextLabel + + + + + All + + + + + + Type + + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + Dialog + + + + Class + Klasse + + + + Run ID + + + + + + + + + None + Ingen + + + + Change ID + + + + + Lock number - - Start list exported Ok + + First name - - Runs export started ... + + + + + -> - - Runs exported Ok + + Last name - - - Event::services::qx::QxLateRegistrationsWidget - - Form - + + Registration + Registrering - - TextLabel + + SI Card - - Type + + + Rent - - Data - + + Note + Merknad - - Source + + Message - - Run + + Force - - User + + Cancel - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -2979,92 +3406,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class Klasse - + Maps Kart - + Free maps - + Runners - + Start first Start først - + Start last Start sist - + 1st time Tid 1 - + Finish time of first runner in current class. - + 3rd time Tid 3 - + Finish time of third runner in current class. - + Time to close - + Time until new finished competitors should not affect standings on first three places. - + Finished Fullført - + Not finished Ikke fullført - + New results Nye resultater - + Number of finished competitors not printed in results. - + Not printed time - + Time since recent results printout. @@ -3272,12 +3699,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 Quick Event ver. %1 - + Application log Programlogg @@ -3285,52 +3712,67 @@ source - ORIS->Event->Information->Event key Model - + SI - + Class Klasse - + Name Navn - + Reg - + Bib - + Start Start - + Time Tid - + Finish Fullfør - + Run flags - + + CR + + + + + Card rent + + + + + CRT + + + + Error Feil @@ -3339,104 +3781,99 @@ source - ORIS->Event->Information->Event key Diskvalifisert - - RT - - - - + Card in rent table - - R + + Card returned - - Card returned + + CRET - + CTIME - + Card check time - + STIME - + Card start time - + FTIME - + Card finish time - + Assign card to runner error - + NC NotCompeting - + MP MisPunch - + BC BadCheck - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer - + OT OverTime - + DSQ Disqualified @@ -3460,52 +3897,52 @@ source - ORIS->Event->Information->Event key - + &Clubs and registrations - + &Update one-time clubs - + &Text file &Tekstfil - + &Competitors CSOS - + Competitors C&SV - + &Ranking CSV (ORIS format) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3513,107 +3950,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 - + Cannot find Oris import ID. - + Import finished successfully. - + New entries - + Edited entries - + Deleted entries - + Oris import report - + Save without drops - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations - + Year of registration: - + Importing registrations - + Importing clubs - + Warning - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information - + No missing one-time clubs found. - + Importing one-time clubs @@ -3654,7 +4091,20 @@ source - ORIS->Event->Information->Event key Kort - + + + Warning + + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt Kvittering @@ -3879,48 +4329,48 @@ source - ORIS->Event->Information->Event key - + SI - + Class Klasse - + Name Navn - + Reg - + Start Start - + Time Tid - + printer - + Print receipts for selected rows Print selected cards - + Show receipt Vis kvittering @@ -4227,96 +4677,96 @@ source - ORIS->Event->Information->Event key - + Start list by classes - + Start list by clubs - - - + + + Results Resultater - + Save as %1 Lagre som %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file Åpne fil - + CSV files (*.csv *.txt) CSV-filer (*.csv *.txt) - + Cannot open file '%1' for reading. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - + Error reading CSV line: [%1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' Udefinert klassenavn: "%1" - + Information - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4487,29 +4937,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results - - + + Start list by classes - - + + Start list by clubs - + Start list for starters - + Start list by classes for %n stage(s) @@ -4517,7 +4967,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) @@ -4525,19 +4975,19 @@ Press refresh button to show imported data. - - + + Results by classes - + Stage awards - - + + Results after %n stage(s) Results after %1 stages @@ -4546,169 +4996,169 @@ Press refresh button to show imported data. - + Awards after %1 stages - - + + length: - - + + climb: - - - - + + + + Top - - + + St. Num - - - - - + + + + + Name Navn - - - - - + + + + + Registration Registrering - - + + SI - - + + Start Start - + Class Klasse - + Preparing data - - + + Procesing class %1 - + Laps - - - + + + Place - - + + Club - - - + + + Time Tid - - - + + + Loss Tap - + NC Not Competing - + DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results - + Warning - + Export error - + Information - + Results exported to %1 - + Overall results after stage %1 - + Stage %1 - + FIN @@ -4776,37 +5226,37 @@ Press refresh button to show imported data. - + HTML multi page - + CSOS fixed column sizes - + CSV one file - + CSV multi file (file per class) - + IOF-XML 3.0 - + Open Directory - + Cannot create directory '%1'. @@ -4851,215 +5301,215 @@ Press refresh button to show imported data. RunsTableModel - + Running Runnig Kjører - + id ID - + Relay - + Leg - + Class Klasse - + SN start number - + Start number Startnummer - - + + SI - + Registered SI - + Name Navn - + Reg - + Lic - + License Lisens - + Actual SI - + Corridor - + Time when the competitor entered start corridor - + Check - + Start Start - + Time Tid - + Finish Fullfør - + Penalty - + Run flags - + Card flags - + Ranking pos - + Runner's position in CZ ranking. - + IOF ID - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + Note Merknad - + DNS DidNotStart - + DNF DidNotFinish - + OT OverTime - + Cannot set not running flag for competitor with valid finish time. - + Mid-air collision switching start times, reload table and try it again. - + Mid-air collision setting start time, reload table and try it again. @@ -5088,63 +5538,63 @@ Press refresh button to show imported data. - + Show receipt Vis kvittering - + Load times from card in selected rows - + Print receipt Print card - + Shift start times in selected rows - + Clear start times in selected rows - + Set class in selected rows - + Reloading times for %1 - + Get number - + Start times offset [min]: - + Dialog Dialog - + Select class Velg klasse - + Duplicate SI inserted. @@ -5317,7 +5767,7 @@ Press refresh button to show imported data. - + Competitors statistics @@ -5406,27 +5856,22 @@ Press refresh button to show imported data. - + Really delete all the selected competitors? This action cannot be reverted. - + Confirm deletion of %1 competitors. - + Edit Competitor - - Save - - - - + Ok and &next @@ -5492,12 +5937,12 @@ Press refresh button to show imported data. - + Start interval is zero, proceed anyway? - + Reset all start times and unlock drawing for this class? @@ -5505,7 +5950,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker @@ -5518,37 +5963,37 @@ Press refresh button to show imported data. Skjema - + Code Kode - + SI - + Punch time - + Runner time - + Class Klasse - + Registration Registrering - + Competitor @@ -5567,114 +6012,114 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> - - - - - - + + + + + + Open file Åpne fil - + CSOS files (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> - - - - + + + + CSV files (*.csv *.txt) CSV-filer (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - - - - + + + + Error reading CSV line: [%1] - - - - + + + + Undefined class name: '%1' Udefinert klassenavn: "%1" - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. diff --git a/quickevent/app/quickevent/quickevent-nl_BE.ts b/quickevent/app/quickevent/quickevent-nl_BE.ts index 9bf147ea8..5da5f2ad5 100644 --- a/quickevent/app/quickevent/quickevent-nl_BE.ts +++ b/quickevent/app/quickevent/quickevent-nl_BE.ts @@ -486,227 +486,227 @@ CardReaderWidget - + Show receipt - + Print receipt - + Show card data - + Print card data - + Assign card to runner - + Recalculate times in selected rows - + Open COM to connect SI reader - + Recalculating times for %1 - + &Station - + Station info - + Read station memory - + &Tools - + Import cards - + Laps only CSV - + SI reader backup memory CSV - + Test audio - - + + SI station not connected - + Assign card to runner Ctrl + Enter - + Connected to %1 in direct mode. - + Error set SI station to direct mode. - + Error open device %1 - %2 - + DriverInfo: <%1> %2 - + DriverRawData: %1 - + card: %1 - + Cannot find run for punch record SI: %1 - + Saved punch: %1 %2 - + Competitor off-race - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> - + Import CSV - - + + Cannot open file '%1' for reading. - - + + Bad stage! - + Cannot find runs record for SI %1! - + Cannot find class for SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. - + Import TXT - + Downloading station backup ... - + Cancelled by user - + No. - + SI - + DateTime - + Card error - + Station %1 backup memory - + Station backup memory @@ -729,37 +729,37 @@ If you continue, this flag will be removed ChooseOrisEventDialog - + Loading event list from Oris ... - + OB - + LOB - + MTBO - + TRAIL - + ??? - + Search in events ... @@ -967,129 +967,139 @@ If you continue, this flag will be removed - - Rel.num + + Rel. count + + + + + Relays count - + Relay start number - + + Rel. num + + + + Legs - + Relay leg count - + &Edit - + Cou&rses - + Co&des - + Classes &layout - + Ctrl+L - + &Import - + OCAD TXT OCad TXT - + OCAD v8 OCad v8 - + OCAD IOF XML 2.0 OCad IOF-XML 2.0 - + OCAD IOF XML 3.0 OCad IOF-XML 3.0 - + Stage - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. - + E%1 - + Delete all courses definitions for stage %1? - - - + + + Warning - - - + + + Import does not yet support relays. - - - - + + + + Open file - + XML files (*.xml);; All files (*) - + Class name '%1' seems to be combined, separate it to more classes? @@ -1171,37 +1181,37 @@ Consider setting "Interval" column for all classes before continuing.< CodeClassResultsWidget - + Competitor - + Reg - + Time - + DISQ - + Results - + Finish - + R Radio station @@ -1225,118 +1235,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning - + Is running - + Stage - + Relay - + Class - + Leg - + SI - + Start - + Time - + Run flags - + Card flags @@ -1360,7 +1381,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor @@ -1420,30 +1441,50 @@ Consider setting "Interval" column for all classes before continuing.< - + + ID + + + + + Create runs + + + + Runs - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. - + SQL error + + + Competitor form check + + + + + Class must be set. + + ConnectDbDialogWidget @@ -1453,7 +1494,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Event files directory @@ -1539,143 +1580,143 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File - + &Import - + &Export - + &Settings - + &Quit - + &Tools - + &SQL tool - + &Locale - + &Language - + System - + Czech - + English - + Flemish - + French - + Norwegian - + Polish - + Russian - + Ukrainian - + Information - + Language change to '%1' will be applied after application restart. - + &View - + &Toolbar - + &Help - + &About Quick Event &About Quick event - + About &Qt - + About Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 - + About Qt @@ -1801,10 +1842,58 @@ Consider setting "Interval" column for all classes before continuing.< + + CoursesTableModel + + + Id + + + + + Name + + + + + Length + + + + + Climb + + + + + Maps + + + + + Runners + + + + + Note + + + + + Code count + + + + + Codes + + + DbSchema - + Data version @@ -2012,41 +2101,6 @@ Consider setting "Interval" column for all classes before continuing.< EditCoursesWidget - - - Name - - - - - Length - - - - - Climb - - - - - Note - - - - - Cnt - - - - - Control count - - - - - Codes - - Form @@ -2061,58 +2115,58 @@ Consider setting "Interval" column for all classes before continuing.< Event::EventPlugin - + &Connect to database - + &Open event - + Create eve&nt - + E&dit event - - + + Event (*.qbe) - + &Event - + Event - + Current stage E%1 - + Services - + Registrations - + You are not connected to database. Program features will be limited. @@ -2121,19 +2175,19 @@ To connect to a database or to choose a working directory where event files can - + Connect Database Error: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. - + Entered directory does not exist: %1 @@ -2141,159 +2195,159 @@ Enter a valid path to the working directory. - + Create event - + Event ID cannot be empty. - + Event ID %1 exists already. - - - - - + + + + + Open Database Error: %1 - - - + + + Create Database Error: %1 - + Cannot create event, database is not open: %1 - + Edit event - + Connected to an empty database. Start by creating or importing an event. - + Working directory does not contain any event files. Start by creating or importing an event. - + select event to open: - + Open event - + Database file %1 doesn't exist. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. - + Export as Quick Event - - + + Quick Event files *%1 (*%1) - + Cannot delete existing file %1 - - + + Creating database - - + + Copying table %1 - + Import as Quick Event - + Query - + Event will be imported as ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. - + Event ID '%1' exists already! - + Open imported event '%1'? - + Name - + Reg - + Lic - + SI @@ -2438,6 +2492,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + + + + + sec + + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + + + + + Export results + + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2499,12 +2752,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2517,41 +2770,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage - + OCheckList Url - + Exchange server url - + Event ID @@ -2586,102 +2839,260 @@ In case of unexpected errors, contact support@oresults.eu - - Connected OK + + Connected OK + + + + + Connection error: %1 + + + + + Event info updated OK + + + + + Event info update error: %1 +%2 + + + + + Start list export started ... + + + + + Start list exported Ok + + + + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + + + + + TextLabel + + + + + All + + + + + + Type + + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + + + + + Class - - Connection error: %1 + + Run ID - - Event info updated OK + + + + + + None - - Event info update error: %1 -%2 + + Change ID - - Start list export started ... + + Lock number - - Start list exported Ok + + First name - - Runs export started ... + + + + + -> - - Runs exported Ok + + Last name - - - Event::services::qx::QxLateRegistrationsWidget - - Form + + Registration - - TextLabel + + SI Card - - Type + + + Rent - - Data + + Note - - Source + + Message - - Run + + Force - - User + + Cancel - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -2913,92 +3324,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class - + Maps - + Free maps - + Runners - + Start first - + Start last - + 1st time - + Finish time of first runner in current class. - + 3rd time - + Finish time of third runner in current class. - + Time to close - + Time until new finished competitors should not affect standings on first three places. - + Finished - + Not finished - + New results - + Number of finished competitors not printed in results. - + Not printed time - + Time since recent results printout. @@ -3205,12 +3616,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 - + Application log @@ -3218,154 +3629,164 @@ source - ORIS->Event->Information->Event key Model - + SI - + Class - + Name - + Reg - + Bib - + Start - + Time - + Finish - + Run flags - - Error + + CR - - RT + + Card rent - - Card in rent table + + CRT - - R + + Error - + + Card in rent table + + + + Card returned - + + CRET + + + + CTIME - + Card check time - + STIME - + Card start time - + FTIME - + Card finish time - + Assign card to runner error - + NC NotCompeting - + MP MisPunch - + BC BadCheck - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer - + OT OverTime - + DSQ Disqualified @@ -3389,52 +3810,52 @@ source - ORIS->Event->Information->Event key - + &Clubs and registrations - + &Update one-time clubs - + &Text file - + &Competitors CSOS - + Competitors C&SV - + &Ranking CSV (ORIS format) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3442,107 +3863,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 - + Cannot find Oris import ID. - + Import finished successfully. - + New entries - + Edited entries - + Deleted entries - + Oris import report - + Save without drops - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations - + Year of registration: - + Importing registrations - + Importing clubs - + Warning - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information - + No missing one-time clubs found. - + Importing one-time clubs @@ -3583,7 +4004,20 @@ source - ORIS->Event->Information->Event key - + + + Warning + + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt @@ -3798,47 +4232,47 @@ source - ORIS->Event->Information->Event key ReceiptsWidget - + SI - + Class - + Name - + Reg - + Start - + Time - + printer - + Print receipts for selected rows - + Show receipt @@ -4149,96 +4583,96 @@ source - ORIS->Event->Information->Event key - + Start list by classes - + Start list by clubs - - - + + + Results - + Save as %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file - + CSV files (*.csv *.txt) - + Cannot open file '%1' for reading. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - + Error reading CSV line: [%1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' - + Information - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4414,29 +4848,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results - - + + Start list by classes - - + + Start list by clubs - + Start list for starters - + Start list by classes for %n stage(s) @@ -4444,7 +4878,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) @@ -4452,19 +4886,19 @@ Press refresh button to show imported data. - - + + Results by classes - + Stage awards - - + + Results after %n stage(s) Results after %1 stages @@ -4473,169 +4907,169 @@ Press refresh button to show imported data. - + Awards after %1 stages - - + + length: - - + + climb: - - - - + + + + Top - - + + St. Num - - - - - + + + + + Name - - - - - + + + + + Registration - - + + SI - - + + Start - + Class - + Preparing data - - + + Procesing class %1 - + Laps - - - + + + Place - - + + Club - - - + + + Time - - - + + + Loss - + NC Not Competing - + DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results - + Warning - + Export error - + Information - + Results exported to %1 - + Overall results after stage %1 - + Stage %1 - + FIN @@ -4643,37 +5077,37 @@ Press refresh button to show imported data. Runs::services::ResultsExporterWidget - + HTML multi page - + CSOS fixed column sizes - + CSV one file - + CSV multi file (file per class) - + IOF-XML 3.0 - + Open Directory - + Cannot create directory '%1'. @@ -4754,214 +5188,214 @@ Press refresh button to show imported data. RunsTableModel - + Running - + id - + Relay - + Leg - + Class - + SN start number - + Start number - - + + SI - + Registered SI - + Name - + Reg - + Lic - + License - + Actual SI - + Corridor - + Time when the competitor entered start corridor - + Check - + Start - + Time - + Finish - + Penalty - + Run flags - + Card flags - + Ranking pos - + Runner's position in CZ ranking. - + IOF ID - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + Note - + DNS DidNotStart - + DNF DidNotFinish - + OT OverTime - + Cannot set not running flag for competitor with valid finish time. - + Mid-air collision switching start times, reload table and try it again. - + Mid-air collision setting start time, reload table and try it again. @@ -4969,62 +5403,62 @@ Press refresh button to show imported data. RunsTableWidget - + Show receipt - + Load times from card in selected rows - + Print receipt - + Shift start times in selected rows - + Clear start times in selected rows - + Set class in selected rows - + Reloading times for %1 - + Get number - + Start times offset [min]: - + Dialog - + Select class - + Duplicate SI inserted. @@ -5188,7 +5622,7 @@ Press refresh button to show imported data. - + Competitors statistics @@ -5277,27 +5711,22 @@ Press refresh button to show imported data. - + Really delete all the selected competitors? This action cannot be reverted. - + Confirm deletion of %1 competitors. - + Edit Competitor - - Save - - - - + Ok and &next @@ -5362,12 +5791,12 @@ Press refresh button to show imported data. - + Start interval is zero, proceed anyway? - + Reset all start times and unlock drawing for this class? @@ -5405,7 +5834,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker @@ -5413,37 +5842,37 @@ Press refresh button to show imported data. SpeakerWidget - + Code - + SI - + Punch time - + Runner time - + Class - + Registration - + Competitor @@ -5456,114 +5885,114 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> - - - - - - + + + + + + Open file - + CSOS files (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> - - - - + + + + CSV files (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - - - - + + + + Error reading CSV line: [%1] - - - - + + + + Undefined class name: '%1' - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. diff --git a/quickevent/app/quickevent/quickevent-pl_PL.ts b/quickevent/app/quickevent/quickevent-pl_PL.ts index aaa87778d..865897568 100644 --- a/quickevent/app/quickevent/quickevent-pl_PL.ts +++ b/quickevent/app/quickevent/quickevent-pl_PL.ts @@ -486,227 +486,227 @@ CardReaderWidget - + Show receipt - + Print receipt - + Show card data - + Print card data - + Assign card to runner - + Recalculate times in selected rows - + Open COM to connect SI reader - + Recalculating times for %1 - + &Station - + Station info - + Read station memory - + &Tools - + Import cards - + Laps only CSV - + SI reader backup memory CSV - + Test audio - - + + SI station not connected - + Assign card to runner Ctrl + Enter - + Connected to %1 in direct mode. - + Error set SI station to direct mode. - + Error open device %1 - %2 - + DriverInfo: <%1> %2 - + DriverRawData: %1 - + card: %1 - + Cannot find run for punch record SI: %1 - + Saved punch: %1 %2 - + Competitor off-race - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> - + Import CSV - - + + Cannot open file '%1' for reading. - - + + Bad stage! - + Cannot find runs record for SI %1! - + Cannot find class for SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. - + Import TXT - + Downloading station backup ... - + Cancelled by user - + No. - + SI - + DateTime - + Card error - + Station %1 backup memory - + Station backup memory @@ -729,37 +729,37 @@ If you continue, this flag will be removed ChooseOrisEventDialog - + Loading event list from Oris ... - + OB - + LOB - + MTBO - + TRAIL - + ??? - + Search in events ... @@ -967,129 +967,139 @@ If you continue, this flag will be removed - - Rel.num + + Rel. count + + + + + Relays count - + Relay start number - + + Rel. num + + + + Legs - + Relay leg count - + &Edit - + Cou&rses - + Co&des - + Classes &layout - + Ctrl+L - + &Import - + OCAD TXT OCad TXT - + OCAD v8 OCad v8 - + OCAD IOF XML 2.0 OCad IOF-XML 2.0 - + OCAD IOF XML 3.0 OCad IOF-XML 3.0 - + Stage - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. - + E%1 - + Delete all courses definitions for stage %1? - - - + + + Warning - - - + + + Import does not yet support relays. - - - - + + + + Open file - + XML files (*.xml);; All files (*) - + Class name '%1' seems to be combined, separate it to more classes? @@ -1171,37 +1181,37 @@ Consider setting "Interval" column for all classes before continuing.< CodeClassResultsWidget - + Competitor - + Reg - + Time - + DISQ - + Results - + Finish - + R Radio station @@ -1225,118 +1235,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning - + Is running - + Stage - + Relay - + Class - + Leg - + SI - + Start - + Time - + Run flags - + Card flags @@ -1360,7 +1381,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor @@ -1420,30 +1441,50 @@ Consider setting "Interval" column for all classes before continuing.< - + + ID + + + + + Create runs + + + + Runs - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. - + SQL error + + + Competitor form check + + + + + Class must be set. + + ConnectDbDialogWidget @@ -1453,7 +1494,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Event files directory @@ -1539,143 +1580,143 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File - + &Import - + &Export - + &Settings - + &Quit - + &Tools - + &SQL tool - + &Locale - + &Language - + System - + Czech - + English - + Flemish - + French - + Norwegian - + Polish - + Russian - + Ukrainian - + Information - + Language change to '%1' will be applied after application restart. - + &View - + &Toolbar - + &Help - + &About Quick Event &About Quick event - + About &Qt - + About Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 - + About Qt @@ -1801,10 +1842,58 @@ Consider setting "Interval" column for all classes before continuing.< + + CoursesTableModel + + + Id + + + + + Name + + + + + Length + + + + + Climb + + + + + Maps + + + + + Runners + + + + + Note + + + + + Code count + + + + + Codes + + + DbSchema - + Data version @@ -2012,41 +2101,6 @@ Consider setting "Interval" column for all classes before continuing.< EditCoursesWidget - - - Name - - - - - Length - - - - - Climb - - - - - Note - - - - - Cnt - - - - - Control count - - - - - Codes - - Form @@ -2061,58 +2115,58 @@ Consider setting "Interval" column for all classes before continuing.< Event::EventPlugin - + &Connect to database - + &Open event - + Create eve&nt - + E&dit event - - + + Event (*.qbe) - + &Event - + Event - + Current stage E%1 - + Services - + Registrations - + You are not connected to database. Program features will be limited. @@ -2121,19 +2175,19 @@ To connect to a database or to choose a working directory where event files can - + Connect Database Error: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. - + Entered directory does not exist: %1 @@ -2141,159 +2195,159 @@ Enter a valid path to the working directory. - + Create event - + Event ID cannot be empty. - + Event ID %1 exists already. - - - - - + + + + + Open Database Error: %1 - - - + + + Create Database Error: %1 - + Cannot create event, database is not open: %1 - + Edit event - + Connected to an empty database. Start by creating or importing an event. - + Working directory does not contain any event files. Start by creating or importing an event. - + select event to open: - + Open event - + Database file %1 doesn't exist. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. - + Export as Quick Event - - + + Quick Event files *%1 (*%1) - + Cannot delete existing file %1 - - + + Creating database - - + + Copying table %1 - + Import as Quick Event - + Query - + Event will be imported as ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. - + Event ID '%1' exists already! - + Open imported event '%1'? - + Name - + Reg - + Lic - + SI @@ -2438,6 +2492,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + + + + + sec + + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + + + + + Export results + + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2499,12 +2752,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2517,41 +2770,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage - + OCheckList Url - + Exchange server url - + Event ID @@ -2586,102 +2839,260 @@ In case of unexpected errors, contact support@oresults.eu - - Connected OK + + Connected OK + + + + + Connection error: %1 + + + + + Event info updated OK + + + + + Event info update error: %1 +%2 + + + + + Start list export started ... + + + + + Start list exported Ok + + + + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + + + + + TextLabel + + + + + All + + + + + + Type + + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + + + + + Class - - Connection error: %1 + + Run ID - - Event info updated OK + + + + + + None - - Event info update error: %1 -%2 + + Change ID - - Start list export started ... + + Lock number - - Start list exported Ok + + First name - - Runs export started ... + + + + + -> - - Runs exported Ok + + Last name - - - Event::services::qx::QxLateRegistrationsWidget - - Form + + Registration - - TextLabel + + SI Card - - Type + + + Rent - - Data + + Note - - Source + + Message - - Run + + Force - - User + + Cancel - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -2913,92 +3324,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class - + Maps - + Free maps - + Runners - + Start first - + Start last - + 1st time - + Finish time of first runner in current class. - + 3rd time - + Finish time of third runner in current class. - + Time to close - + Time until new finished competitors should not affect standings on first three places. - + Finished - + Not finished - + New results - + Number of finished competitors not printed in results. - + Not printed time - + Time since recent results printout. @@ -3205,12 +3616,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 - + Application log @@ -3218,154 +3629,164 @@ source - ORIS->Event->Information->Event key Model - + SI - + Class - + Name - + Reg - + Bib - + Start - + Time - + Finish - + Run flags - - Error + + CR - - RT + + Card rent - - Card in rent table + + CRT - - R + + Error - + + Card in rent table + + + + Card returned - + + CRET + + + + CTIME - + Card check time - + STIME - + Card start time - + FTIME - + Card finish time - + Assign card to runner error - + NC NotCompeting - + MP MisPunch - + BC BadCheck - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer - + OT OverTime - + DSQ Disqualified @@ -3389,52 +3810,52 @@ source - ORIS->Event->Information->Event key - + &Clubs and registrations - + &Update one-time clubs - + &Text file - + &Competitors CSOS - + Competitors C&SV - + &Ranking CSV (ORIS format) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3442,107 +3863,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 - + Cannot find Oris import ID. - + Import finished successfully. - + New entries - + Edited entries - + Deleted entries - + Oris import report - + Save without drops - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations - + Year of registration: - + Importing registrations - + Importing clubs - + Warning - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information - + No missing one-time clubs found. - + Importing one-time clubs @@ -3583,7 +4004,20 @@ source - ORIS->Event->Information->Event key - + + + Warning + + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt @@ -3798,47 +4232,47 @@ source - ORIS->Event->Information->Event key ReceiptsWidget - + SI - + Class - + Name - + Reg - + Start - + Time - + printer - + Print receipts for selected rows - + Show receipt @@ -4149,96 +4583,96 @@ source - ORIS->Event->Information->Event key - + Start list by classes - + Start list by clubs - - - + + + Results - + Save as %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file - + CSV files (*.csv *.txt) - + Cannot open file '%1' for reading. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - + Error reading CSV line: [%1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' - + Information - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4414,29 +4848,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results - - + + Start list by classes - - + + Start list by clubs - + Start list for starters - + Start list by classes for %n stage(s) @@ -4445,7 +4879,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) @@ -4454,19 +4888,19 @@ Press refresh button to show imported data. - - + + Results by classes - + Stage awards - - + + Results after %n stage(s) Results after %1 stages @@ -4476,169 +4910,169 @@ Press refresh button to show imported data. - + Awards after %1 stages - - + + length: - - + + climb: - - - - + + + + Top - - + + St. Num - - - - - + + + + + Name - - - - - + + + + + Registration - - + + SI - - + + Start - + Class - + Preparing data - - + + Procesing class %1 - + Laps - - - + + + Place - - + + Club - - - + + + Time - - - + + + Loss - + NC Not Competing - + DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results - + Warning - + Export error - + Information - + Results exported to %1 - + Overall results after stage %1 - + Stage %1 - + FIN @@ -4646,37 +5080,37 @@ Press refresh button to show imported data. Runs::services::ResultsExporterWidget - + HTML multi page - + CSOS fixed column sizes - + CSV one file - + CSV multi file (file per class) - + IOF-XML 3.0 - + Open Directory - + Cannot create directory '%1'. @@ -4757,214 +5191,214 @@ Press refresh button to show imported data. RunsTableModel - + Running - + id - + Relay - + Leg - + Class - + SN start number - + Start number - - + + SI - + Registered SI - + Name - + Reg - + Lic - + License - + Actual SI - + Corridor - + Time when the competitor entered start corridor - + Check - + Start - + Time - + Finish - + Penalty - + Run flags - + Card flags - + Ranking pos - + Runner's position in CZ ranking. - + IOF ID - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + Note - + DNS DidNotStart - + DNF DidNotFinish - + OT OverTime - + Cannot set not running flag for competitor with valid finish time. - + Mid-air collision switching start times, reload table and try it again. - + Mid-air collision setting start time, reload table and try it again. @@ -4972,62 +5406,62 @@ Press refresh button to show imported data. RunsTableWidget - + Show receipt - + Load times from card in selected rows - + Print receipt - + Shift start times in selected rows - + Clear start times in selected rows - + Set class in selected rows - + Reloading times for %1 - + Get number - + Start times offset [min]: - + Dialog - + Select class - + Duplicate SI inserted. @@ -5191,7 +5625,7 @@ Press refresh button to show imported data. - + Competitors statistics @@ -5280,27 +5714,22 @@ Press refresh button to show imported data. - + Really delete all the selected competitors? This action cannot be reverted. - + Confirm deletion of %1 competitors. - + Edit Competitor - - Save - - - - + Ok and &next @@ -5365,12 +5794,12 @@ Press refresh button to show imported data. - + Start interval is zero, proceed anyway? - + Reset all start times and unlock drawing for this class? @@ -5408,7 +5837,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker @@ -5416,37 +5845,37 @@ Press refresh button to show imported data. SpeakerWidget - + Code - + SI - + Punch time - + Runner time - + Class - + Registration - + Competitor @@ -5459,114 +5888,114 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> - - - - - - + + + + + + Open file - + CSOS files (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> - - - - + + + + CSV files (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - - - - + + + + Error reading CSV line: [%1] - - - - + + + + Undefined class name: '%1' - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. diff --git a/quickevent/app/quickevent/quickevent-ru_RU.ts b/quickevent/app/quickevent/quickevent-ru_RU.ts index 40be56c2a..11fb5de01 100644 --- a/quickevent/app/quickevent/quickevent-ru_RU.ts +++ b/quickevent/app/quickevent/quickevent-ru_RU.ts @@ -501,227 +501,227 @@ - + Show receipt - + Print receipt - + Show card data - + Print card data - + Assign card to runner - + Recalculate times in selected rows - + Open COM to connect SI reader - + Recalculating times for %1 - + &Station - + Station info - + Read station memory - + &Tools &Инструменты - + Import cards - + Laps only CSV - + SI reader backup memory CSV - + Test audio - - + + SI station not connected - + Assign card to runner Ctrl + Enter - + Connected to %1 in direct mode. - + Error set SI station to direct mode. - + Error open device %1 - %2 - + DriverInfo: <%1> %2 - + DriverRawData: %1 - + card: %1 - + Cannot find run for punch record SI: %1 - + Saved punch: %1 %2 - + Competitor off-race - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> - + Import CSV - - + + Cannot open file '%1' for reading. Не удается открыть файл '%1' для чтения. - - + + Bad stage! - + Cannot find runs record for SI %1! - + Cannot find class for SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. - + Import TXT - + Downloading station backup ... - + Cancelled by user - + No. - + SI - + DateTime - + Card error - + Station %1 backup memory - + Station backup memory @@ -729,37 +729,37 @@ If you continue, this flag will be removed ChooseOrisEventDialog - + Loading event list from Oris ... - + OB - + LOB - + MTBO - + TRAIL - + ??? ??? - + Search in events ... @@ -992,129 +992,139 @@ If you continue, this flag will be removed - - Rel.num + + Rel. count + + + + + Relays count - + Relay start number - + + Rel. num + + + + Legs - + Relay leg count - + &Edit &Редактировать - + Cou&rses - + Co&des - + Classes &layout - + Ctrl+L Ctrl+L - + &Import &Импорт - + OCAD TXT OCad TXT OCad TXT - + OCAD v8 OCad v8 OCad v8 - + OCAD IOF XML 2.0 OCad IOF-XML 2.0 OCad IOF-XML 2.0 - + OCAD IOF XML 3.0 OCad IOF-XML 3.0 OCad IOF-XML 3.0 - + Stage Этап - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. - + E%1 E%1 - + Delete all courses definitions for stage %1? - - - + + + Warning - - - + + + Import does not yet support relays. - - - - + + + + Open file Открыть файл - + XML files (*.xml);; All files (*) XML-файлы (*.xml);; Все файлы (*) - + Class name '%1' seems to be combined, separate it to more classes? @@ -1186,37 +1196,37 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor - + Reg - + Time Время - + DISQ - + Results Результаты - + Finish Финиш - + R Radio station R @@ -1225,118 +1235,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning - + Is running - + Stage Этап - + Relay - + Class Класс - + Leg - + SI - + Start Старт - + Time Время - + Run flags - + Card flags @@ -1360,7 +1381,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor @@ -1405,7 +1426,17 @@ Consider setting "Interval" column for all classes before continuing.< - + + ID + + + + + Create runs + + + + Runs @@ -1429,25 +1460,35 @@ Consider setting "Interval" column for all classes before continuing.< E&%1 - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. - + SQL error + + + Competitor form check + + + + + Class must be set. + + Competitors::CompetitorsPlugin @@ -1574,7 +1615,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Event files directory @@ -1590,143 +1631,143 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File &Файл - + &Import &Импорт - + &Export - + &Settings - + &Quit &Выйти - + &Tools &Инструменты - + &SQL tool - + &Locale - + &Language &Язык - + System Система - + Czech Чешский - + English Английский - + Flemish - + French - + Norwegian Норвежский - + Polish Польский - + Russian Русский - + Ukrainian - + Information - + Language change to '%1' will be applied after application restart. Изменение языка на '%1' будет применено после перезапуска приложения. - + &View - + &Toolbar - + &Help &Справка - + &About Quick Event &About Quick event - + About &Qt О &Qt - + About Quick Event О Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 - + About Qt О Qt @@ -1852,10 +1893,58 @@ Consider setting "Interval" column for all classes before continuing.< Широта + + CoursesTableModel + + + Id + + + + + Name + Имя + + + + Length + Длина + + + + Climb + + + + + Maps + Карты + + + + Runners + + + + + Note + + + + + Code count + + + + + Codes + + + DbSchema - + Data version @@ -2074,96 +2163,69 @@ Consider setting "Interval" column for all classes before continuing.< - Name - Имя + Имя - Length - Длина - - - - Climb - - - - - Note - - - - - Cnt - - - - - Control count - - - - - Codes - + Длина Event::EventPlugin - + &Connect to database - + &Open event - + Create eve&nt - + E&dit event - - + + Event (*.qbe) - + &Event - + Event - + Current stage E%1 Текущий этап E%1 - + Services - + Registrations - + You are not connected to database. Program features will be limited. @@ -2172,19 +2234,19 @@ To connect to a database or to choose a working directory where event files can - + Connect Database Error: %1 Ошибка подключения к базе данных: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. - + Entered directory does not exist: %1 @@ -2192,159 +2254,159 @@ Enter a valid path to the working directory. - + Create event - + Event ID cannot be empty. - + Event ID %1 exists already. - - - - - + + + + + Open Database Error: %1 Ошибка открытия базы данных: %1 - - - + + + Create Database Error: %1 Ошибка создания базы данных: %1 - + Cannot create event, database is not open: %1 - + Edit event - + Connected to an empty database. Start by creating or importing an event. - + Working directory does not contain any event files. Start by creating or importing an event. - + select event to open: - + Open event - + Database file %1 doesn't exist. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. - + Export as Quick Event - - + + Quick Event files *%1 (*%1) - + Cannot delete existing file %1 - - + + Creating database Создание базы данных - - + + Copying table %1 Копирование таблицы %1 - + Import as Quick Event - + Query Запрос - + Event will be imported as ID: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. - + Event ID '%1' exists already! - + Open imported event '%1'? - + Name Имя - + Reg - + Lic - + SI @@ -2489,6 +2551,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version Не удается создать каталог '%1'. + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + + + + + sec + сек + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + Экспорт стартового списка + + + + Export results + Экспорт результатов + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2550,12 +2811,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2568,41 +2829,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage Текущий этап - + OCheckList Url - + Exchange server url - + Event ID @@ -2637,102 +2898,260 @@ In case of unexpected errors, contact support@oresults.eu - + Connected OK - + Connection error: %1 - + Event info updated OK - + Event info update error: %1 %2 - - Start list export started ... + + Start list export started ... + + + + + Start list exported Ok + + + + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + Форма + + + + TextLabel + + + + + All + + + + + + Type + Тип + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + + + + + Class + Класс + + + + Run ID + + + + + + + + + None + + + + + Change ID + + + + + Lock number - - Start list exported Ok + + First name - - Runs export started ... + + + + + -> - - Runs exported Ok + + Last name - - - Event::services::qx::QxLateRegistrationsWidget - - Form - Форма + + Registration + Регистрация - - TextLabel + + SI Card - - Type - Тип + + + Rent + - - Data + + Note - - Source + + Message - - Run + + Force - - User + + Cancel - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -2965,92 +3384,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class Класс - + Maps Карты - + Free maps - + Runners - + Start first - + Start last - + 1st time - + Finish time of first runner in current class. - + 3rd time - + Finish time of third runner in current class. - + Time to close Время закрытия - + Time until new finished competitors should not affect standings on first three places. - + Finished - + Not finished - + New results Новые результаты - + Number of finished competitors not printed in results. - + Not printed time - + Time since recent results printout. @@ -3257,12 +3676,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 Quick Event вер. %1 - + Application log Журнал активности приложения @@ -3270,154 +3689,168 @@ source - ORIS->Event->Information->Event key Model - + SI - + Class Класс - + Name Имя - + Reg - + Bib - + Start Старт - + Time Время - + Finish Финиш - + Run flags - - Error - Ошибка + + CR + - - RT + + Card rent - + + CRT + + + + + Error + Ошибка + + + Card in rent table - R - R + R - + Card returned - + + CRET + + + + CTIME - + Card check time - + STIME - + Card start time - + FTIME - + Card finish time - + Assign card to runner error - + NC NotCompeting - + MP MisPunch - + BC BadCheck - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer - + OT OverTime - + DSQ Disqualified @@ -3441,52 +3874,52 @@ source - ORIS->Event->Information->Event key - + &Clubs and registrations - + &Update one-time clubs - + &Text file &Текстовый файл - + &Competitors CSOS - + Competitors C&SV - + &Ranking CSV (ORIS format) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3494,107 +3927,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 - + Cannot find Oris import ID. - + Import finished successfully. - + New entries - + Edited entries - + Deleted entries - + Oris import report - + Save without drops - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations - + Year of registration: - + Importing registrations - + Importing clubs - + Warning - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information - + No missing one-time clubs found. - + Importing one-time clubs @@ -3635,7 +4068,20 @@ source - ORIS->Event->Information->Event key - + + + Warning + + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt @@ -3860,47 +4306,47 @@ source - ORIS->Event->Information->Event key - + SI - + Class Класс - + Name Имя - + Reg - + Start Старт - + Time Время - + printer принтер - + Print receipts for selected rows - + Show receipt @@ -4206,96 +4652,96 @@ source - ORIS->Event->Information->Event key - + Start list by classes Стартовый список по классам - + Start list by clubs Стартовый список по клубам - - - + + + Results Результаты - + Save as %1 Сохранить как %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file Открыть файл - + CSV files (*.csv *.txt) CSV файлы (*.csv *.txt) - + Cannot open file '%1' for reading. Не удается открыть файл '%1' для чтения. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - + Error reading CSV line: [%1] Ошибка чтения строки CSV: [% 1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' Неопределенное имя класса: '% 1' - + Information - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4466,29 +4912,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results - - + + Start list by classes Стартовый список по классам - - + + Start list by clubs Стартовый список по клубам - + Start list for starters - + Start list by classes for %n stage(s) Стартовый список по классам @@ -4497,7 +4943,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) Стартовый список по клубам @@ -4506,19 +4952,19 @@ Press refresh button to show imported data. - - + + Results by classes Результаты по классам - + Stage awards - - + + Results after %n stage(s) Results after %1 stages @@ -4528,169 +4974,169 @@ Press refresh button to show imported data. - + Awards after %1 stages - - + + length: длина: - - + + climb: - - - - + + + + Top - - + + St. Num - - - - - + + + + + Name Имя - - - - - + + + + + Registration Регистрация - - + + SI - - + + Start Старт - + Class Класс - + Preparing data - - + + Procesing class %1 - + Laps - - - + + + Place - - + + Club - - - + + + Time Время - - - + + + Loss - + NC Not Competing - + DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results - + Warning - + Export error - + Information - + Results exported to %1 - + Overall results after stage %1 - + Stage %1 - + FIN @@ -4758,37 +5204,37 @@ Press refresh button to show imported data. Формат вывода - + HTML multi page Многостраничный HTML - + CSOS fixed column sizes - + CSV one file - + CSV multi file (file per class) - + IOF-XML 3.0 IOF-XML 3.0 - + Open Directory - + Cannot create directory '%1'. Не удалось создать каталог '% 1'. @@ -4828,214 +5274,214 @@ Press refresh button to show imported data. RunsTableModel - + Running - + id - + Relay - + Leg - + Class Класс - + SN start number - + Start number Стартовый номер - - + + SI - + Registered SI - + Name Имя - + Reg - + Lic - + License Лицензия - + Actual SI - + Corridor - + Time when the competitor entered start corridor - + Check - + Start Старт - + Time Время - + Finish Финиш - + Penalty - + Run flags - + Card flags - + Ranking pos - + Runner's position in CZ ranking. - + IOF ID - + DO disqualifiedByOrganizer - + MP MisPunch - + BC BadCheck - + NC NotCompeting - + CR Card rent requested - + CT Card in lent cards table - + RET Card returned - + Note - + DNS DidNotStart - + DNF DidNotFinish - + OT OverTime - + Cannot set not running flag for competitor with valid finish time. - + Mid-air collision switching start times, reload table and try it again. - + Mid-air collision setting start time, reload table and try it again. @@ -5064,62 +5510,62 @@ Press refresh button to show imported data. Интервал - + Show receipt - + Load times from card in selected rows - + Print receipt - + Shift start times in selected rows - + Clear start times in selected rows - + Set class in selected rows - + Reloading times for %1 - + Get number - + Start times offset [min]: - + Dialog - + Select class Выбрать класс - + Duplicate SI inserted. @@ -5292,7 +5738,7 @@ Press refresh button to show imported data. - + Competitors statistics @@ -5381,27 +5827,22 @@ Press refresh button to show imported data. - + Really delete all the selected competitors? This action cannot be reverted. - + Confirm deletion of %1 competitors. - + Edit Competitor - - Save - - - - + Ok and &next @@ -5466,12 +5907,12 @@ Press refresh button to show imported data. - + Start interval is zero, proceed anyway? - + Reset all start times and unlock drawing for this class? @@ -5479,7 +5920,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker @@ -5492,37 +5933,37 @@ Press refresh button to show imported data. Форма - + Code - + SI - + Punch time - + Runner time - + Class Класс - + Registration Регистрация - + Competitor @@ -5545,114 +5986,114 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> - - - - - - + + + + + + Open file Открыть файл - + CSOS files (*.txt) CSOS файлы (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. Не удается открыть файл '%1' для чтения. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> - - - - + + + + CSV files (*.csv *.txt) CSV файлы (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] - - - - + + + + Error reading CSV line: [%1] Ошибка чтения строки CSV: [% 1] - - - - + + + + Undefined class name: '%1' Неопределенное имя класса: '% 1' - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. diff --git a/quickevent/app/quickevent/quickevent-uk_UA.ts b/quickevent/app/quickevent/quickevent-uk_UA.ts index 90c4df201..386575e05 100644 --- a/quickevent/app/quickevent/quickevent-uk_UA.ts +++ b/quickevent/app/quickevent/quickevent-uk_UA.ts @@ -505,143 +505,143 @@ Тест - + Show receipt Показати чек - + Print receipt Друкувати чек - + Show card data Показати дані картки - + Print card data Надрукувати дані картки - + Assign card to runner Призначити картку бігунові - + Recalculate times in selected rows Перерахувати час у вибраних рядках - + Open COM to connect SI reader Відкрити COM для з’єднання зі зчитувачем SI - + Recalculating times for %1 Перерахунок часу для %1 - + &Station &Станція - + Station info Інформація про станцію - + Read station memory Прочитати пам’ять станції - + &Tools &Інструменти - + Import cards Імпортувати картки - + Laps only CSV CSV лише етапів - + SI reader backup memory CSV CSV резервної пам’яті зчитувача SI - + Test audio Перевірити звук - - + + SI station not connected Станцію SI не під’єднано - + Assign card to runner Ctrl + Enter Призначити картку бігунові Ctrl + Enter - + Connected to %1 in direct mode. З’єднано з %1 у прямому режимі. - + Error set SI station to direct mode. Помилка перемикання станції SI у прямий режим. - + Error open device %1 - %2 Помилка відкриття пристрою %1 - %2 - + DriverInfo: <%1> %2 DriverInfo: <%1> %2 - + DriverRawData: %1 DriverRawData: %1 - + card: %1 картка: %1 - + Cannot find run for punch record SI: %1 Не вдалося знайти забіг для запису відмітки SI: %1 - + Saved punch: %1 %2 Збережено відмітку: %1 %2 - + Competitor off-race Учасник поза гонкою - + Runner to which you are assinging SI card is currently flagged "not running" for this stage (race). If you continue, this flag will be removed @@ -650,84 +650,84 @@ If you continue, this flag will be removed Якщо продовжити, позначку буде знято - + <p>CSV record must have format:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Any row can be commented by leading #</p><p>Decimal point is also supported, the quotes can be omited than.</p> <p>Запис CSV повинен мати формат:</p><p>7203463,"2,28","3,34","2,42","3,29","3,12","1,38","1,13","3,18","1,17","0,15"</p><p>Будь-який рядок можна закоментувати, почавши його з #</p><p>Десяткова крапка також підтримується, тоді можна обійтися без лапок.</p> - + Import CSV Імпортувати CSV - - + + Cannot open file '%1' for reading. Не вдалося відкрити для читання файл «%1». - - + + Bad stage! Некоректний забіг! - + Cannot find runs record for SI %1! Не вдалося знайти запис забігу для SI %1! - + Cannot find class for SI %1! Не вдалося знайти групу для SI %1! - + SI: %1 class %2 - Number of punches (%3) and number of codes including finish (%4) should be the same! Remove or comment invalid line by #. SI: %1 група %2 - Кількість відміток (%3) і кількість кодів разом із фінішом (%4) має бути однакова! Видаліть або закоментуйте некоректний рядок з допомогою #. - + Import TXT Імпортувати TXT - + Downloading station backup ... Завантажити резервну копію станції… - + Cancelled by user Скасовано користувачем - + No. Ні. - + SI Чип - + DateTime ДатаЧас - + Card error Помилка картки - + Station %1 backup memory Резервна пам’ять станції %1 - + Station backup memory Резервна пам’ять станції @@ -750,37 +750,37 @@ If you continue, this flag will be removed Ід. події Oris - + Loading event list from Oris ... Завантаження списку подій з Oris… - + OB ОБ - + LOB ОЛ - + MTBO МТБО - + TRAIL ТРЕЙЛ - + ??? ??? - + Search in events ... Шукати серед подій… @@ -998,126 +998,140 @@ If you continue, this flag will be removed Набір - Rel.num - Ном.ест + Ном.ест + + + + Rel. count + + + + + Relays count + - + Relay start number Стартовий номер естафети - + + Rel. num + + + + Legs Етапи - + Relay leg count Кількість етапів естафети - + &Edit Р&едагувати - + Cou&rses &Дистанції - + Co&des &Коди - + Classes &layout &Розміщення груп - + Ctrl+L Ctrl+L - + &Import &Імпорт - + OCAD TXT OCAD TXT - + OCAD v8 OCAD v8 - + OCAD IOF XML 2.0 OCAD IOF XML 2.0 - + OCAD IOF XML 3.0 OCAD IOF XML 3.0 - + Stage Забіг - + Classes without start interval won't be displayed. Consider setting "Interval" column for all classes before continuing. Групи без стартового інтервалу не буде показано. Задайте стовпець «Інтервал» у всіх групах перед продовженням. - + E%1 E%1 - + Delete all courses definitions for stage %1? Видалити всі дистанції для забігу %1? - - - + + + Warning Попередження - - - + + + Import does not yet support relays. - - - - + + + + Open file Відкрити файл - + XML files (*.xml);; All files (*) Файли XML (*.xml);; Усі файли (*) - + Class name '%1' seems to be combined, separate it to more classes? Назва групи «%1»; мабуть, комбінована; розділити їх на більше груп? @@ -1189,37 +1203,37 @@ Consider setting "Interval" column for all classes before continuing.< Код - + Competitor Учасник - + Reg Реє - + Time Час - + DISQ DISQ - + Results Результати - + Finish Фініш - + R Radio station Р @@ -1228,118 +1242,129 @@ Consider setting "Interval" column for all classes before continuing.< CompetitorRunsModel - + DISQ Disqualified - + DO disqualifiedByOrganizer DO - + MP MisPunch MP - + BC BadCheck BC - + NC NotCompeting NC - + DNS DidNotStart - + DNF DidNotFinish - + CR Card rent requested CR - + CT Card in lent cards table CT - + RET Card returned RET - + + Id + runs.id + + + + + Run Id + + + + Running runs.isRunning Біжить - + Is running Чи біжить - + Stage Забіг - + Relay Естафета - + Class Група - + Leg Етап - + SI - + Start Старт - + Time Час - + Run flags - + Card flags @@ -1363,7 +1388,7 @@ Consider setting "Interval" column for all classes before continuing.< - + Competitor Учасник @@ -1382,6 +1407,16 @@ Consider setting "Interval" column for all classes before continuing.< &SI &ЧИП + + + ID + + + + + Create runs + + First na&me @@ -1427,7 +1462,7 @@ Consider setting "Interval" column for all classes before continuing.< Час старту - + Runs Забіги @@ -1436,25 +1471,35 @@ Consider setting "Interval" column for all classes before continuing.< E&%1 - - Quick Event get start time + + Select competitor's start time - + New start time: - + Class should be entered. Група повинна бути вказана. - + SQL error Помилка SQL + + + Competitor form check + + + + + Class must be set. + + Competitors::CompetitorsPlugin @@ -1677,7 +1722,7 @@ Consider setting "Interval" column for all classes before continuing.< Налаштування сховища даних - + Event files directory Каталог файлів змагань @@ -1693,138 +1738,138 @@ Consider setting "Interval" column for all classes before continuing.< Core::CorePlugin - + &File &Файл - + &Import &Імпорт - + &Export &Експорт - + &Settings &Налаштування - + &Quit &Вихід - + &Tools І&нструменти - + &SQL tool Інструмент &SQL - + &Locale &Локаль - + &Language &Мова - + System Система - + Czech Чеська - + English Англійська - + Flemish Фламандська - + French Французька - + Norwegian Норвезька - + Polish Польська - + Russian Російська - + Ukrainian Українська - + Information Інформація - + Language change to '%1' will be applied after application restart. Зміна мови на «%1» відбудеться після перезапуску. - + &View Пе&регляд - + &Toolbar П&анель інстр - + &Help &Допомога - + &About Quick Event &About Quick event &Про Quick event - + About &Qt Про &Qt - + About Quick Event Про Quick Event - + The <b>Quick Event</b> is an application which helps you to organize the orienteering events.<br/><br/>version: %1<br/>commit: %7<br/>min. db version: %2<br/>build: %3 %4<br/>SSL build: %5<br/>SSL run: %6 @@ -1833,7 +1878,7 @@ Consider setting "Interval" column for all classes before continuing.< <b>Quick Event</b> — це додаток, який допомагає в організації тренувань і змагань зі спортивного оруєнтування.<br/><br/>версія: %1<br/>min. верся db: %2<br/>складання: %3 %4<br/>збірка SSL: %5<br/>запуск SSL: %6 - + About Qt Про Qt @@ -1971,10 +2016,58 @@ Consider setting "Interval" column for all classes before continuing.< Широта + + CoursesTableModel + + + Id + + + + + Name + + + + + Length + Довжина + + + + Climb + Набір + + + + Maps + + + + + Runners + Учасники + + + + Note + + + + + Code count + + + + + Codes + Коди + + DbSchema - + Data version Версія даних @@ -2193,96 +2286,89 @@ Consider setting "Interval" column for all classes before continuing.< Дистанції - Name - Назва + Назва - Length - Довжина + Довжина - Climb - Набір + Набір - Note - Нотатки + Нотатки - Cnt - К-сть + К-сть - Control count - Кількість КП + Кількість КП - Codes - Коди + Коди Event::EventPlugin - + &Connect to database &З’єднання з базою даних - + &Open event &Відкрити подію - + Create eve&nt Створити &подію - + E&dit event &Редагувати подію - - + + Event (*.qbe) Подія (*.qbe) - + &Event &Подія - + Event Подія - + Current stage E%1 Поточний забіг E%1 - + Services Служби - + Registrations Реєстрації - + You are not connected to database. Program features will be limited. @@ -2295,12 +2381,12 @@ To connect to a database or to choose a working directory where event files can «Файл -> Під’єднатись до бази даних» - + Connect Database Error: %1 Помилка під’єднання до бази даних: %1 - + Path to the working directory cannot be empty. Enter path to the working directory or connect to SQL server. @@ -2309,7 +2395,7 @@ Enter path to the working directory or connect to SQL server. Введіть шлях до робочого каталогу або під’єднайтесь до сервера SQL. - + Entered directory does not exist: %1 @@ -2320,162 +2406,162 @@ Enter a valid path to the working directory. Введіть коректний шлях до робочого каталогу. - + Create event Створити подію - + Event ID cannot be empty. ІД події не може бути порожнім. - + Event ID %1 exists already. ІД події %1 вже існує. - - - - - + + + + + Open Database Error: %1 Помилка відкриття бази даних: %1 - - - + + + Create Database Error: %1 Помилка створення бази даних: %1 - + Cannot create event, database is not open: %1 Неможливо створити подію, база даних не відкрита: %1 - + Edit event Редагувати подію - + Connected to an empty database. Start by creating or importing an event. Під’єднано до порожньої бази даних. Почніть зі створення або імпорту події. - + Working directory does not contain any event files. Start by creating or importing an event. Робочий каталог не містить файлів змагань. Почніть зі створення або імпорту події. - + Open event Відктрити подію - + select event to open: Виберіть змагання, які відкрити: - + Database file %1 doesn't exist. Файл бази даних %1 не існує. - + Event data version (%1) is too low, minimal version is (%2). Use: File --> Import --> Event (*.qbe) to convert event to current version. Версія даних події (%1) занадто стара, підтримується версія не нижче (%2). Користуйтесь: Файл --> Імпорт --> Подія (*.qbe), щоб перетворити змаганя до поточної версії. - + Event was created in more recent QuickEvent version (%1) and the application might not work as expected. Download latest QuickEvent is strongly recommended. Подію було створено новішою версією QuickEvent (%1) і додаток може не працювати як слід. Наполегливо радимо отримати найновіший QuickEvent. - + Export as Quick Event Експортувати як Quick Event - - + + Quick Event files *%1 (*%1) Файли Quick Event *%1 (*%1) - + Cannot delete existing file %1 Не можна видалити файл %1 - - + + Creating database Створення бази даних - - + + Copying table %1 Копіювання таблиці %1 - + Import as Quick Event Імпортувати як Quick Event - + Query Запит - + Event will be imported as ID: Подію буде імпортовано з ІД: - + PostgreSQL schema must start with small letter and it may contain small letters, digits and underscores only. Схема PostgreSQL має починатися з малої літери і може мати тільки малі літери, цифри і підкреслення. - + Event ID '%1' exists already! ІД події «%1» вже існує! - + Open imported event '%1'? Відкрити імпортовану подію «%1»? - + Name - + Reg Реє - + Lic - + SI @@ -2620,6 +2706,205 @@ Use: File --> Import --> Event (*.qbe) to convert event to current version Не можу створити каталог «%1». + + Event::services::OFeedClient + + + results upload + + + + + start list upload + + + + + Exception occurred while getting changes by origin: + + + + + + + Database query failed: + + + + + + + Exception occurred while executing query: + + + + + + + Unknown exception occurred while executing query. + + + + + No data received or an error occurred. + + + + + Event::services::OFeedClientWidget + + + Synchronize data with the OFeed platform + + + + + Export interval + Інтервал експорту + + + + sec + сек + + + + Url + + + + + <html><head/><body><p>OFeed instance url</p></body></html> + + + + + + https://api.orienteerfeed.com + + + + + Event id + + + + + <html><head/><body><p>Event id provided in the Settings section on the web site. Can be copied from OFeed url as well.</p></body></html> + + + + + + From OFeed settings page + + + + + Password + + + + + <html><head/><body><p>Password that was generated in the Settings section.</p></body></html> + + + + + Credentials + + + + + Upload data + + + + + Turn on/off changes processing + + + + + ON / OFF + + + + + Zpracování zapnuto/vypnuto + + + + + Additional settings + + + + + Run IOF XML validation + + + + + <html><head/><body><p>Start lists and results are automatically exported at specified intervals, with changes such as edited competitor data or new competitors being synced in real time. Both results and start lists can also be exported manually using the buttons below. Additionally, when the service is active, individual competitor data is sent after readout and upon saving the competitor dialog. Refer to the <a href="https://docs.orienteerfeed.com/"><span style=" text-decoration: underline; color:#007af4;">documentation</span></a> for more details.</p><p>If you encounter any unexpected errors, please <a href="mailto:support@orienteerfeed.com"><span style=" text-decoration: underline; color:#007af4;">contact us</span></a> or create an issue on our GitHub <a href="https://github.com/orienteerfeed/ofeed/issues"><span style=" text-decoration: underline; color:#007af4;">page</span></a>.</p></body></html> + + + + + Export start list + + + + + Export results + + + + + Changes from the origin specified (permanent value at this moment) are processed automatically and visualized in <b>qxchange</b> modul. + + + + + Origin + + + + + Process changes setup + + + + + + START + + + + + + ON + + + + + + OFF + + + + + + Changes are automatically processed + + + + + + Processing changes is deactivated + + + Event::services::OResultsClientWidget @@ -2686,12 +2971,12 @@ In case of unexpected errors, contact support@oresults.eu Event::services::qx::QxClientService - + QE Exchange - + Event ID is not loaded, service is not probably running. @@ -2704,41 +2989,41 @@ In case of unexpected errors, contact support@oresults.eu - - - - + + + + Fill this url into HTTP POST synchonization method in O-CheckList - + API token - + Not loaded - + Current stage Поточний забіг - + OCheckList Url - + Exchange server url - + Event ID ІД події @@ -2773,102 +3058,260 @@ In case of unexpected errors, contact support@oresults.eu - + Connected OK - + Connection error: %1 - + Event info updated OK - + Event info update error: %1 %2 - + Start list export started ... - + Start list exported Ok - - Runs export started ... + + Runs export started ... + + + + + Runs exported Ok + + + + + Event::services::qx::QxLateRegistrationsWidget + + + Form + Форма + + + + TextLabel + + + + + All + + + + + + Type + Тип + + + + Pending + + + + + Accepted + + + + + Rejected + + + + + Null + + + + + Data + + + + + Source + + + + + User + + + + + Status + + + + + Data ID + + + + + Status message + + + + + Created + + + + + Change ID + + + + + Lock + + + + + Orig data + + + + + Neco + + + + + Locked + + + + + Event::services::qx::RunChangeDialog + + + Dialog + Діалог + + + + Class + Група + + + + Run ID + + + + + + + + + None + Немає + + + + Change ID + + + + + Lock number + + + + + First name + Ім’я + + + + + + + -> - - Runs exported Ok - + + Last name + Прізвище - - - Event::services::qx::QxLateRegistrationsWidget - - Form - Форма + + Registration + Реєстрація - - TextLabel + + SI Card - - Type - Тип + + + Rent + - - Data + + Note - - Source + + Message - - Run + + Force - - User - + + Cancel + Скасувати - - Status + + Reject - - Status message + + Accept - - Created + + Update change error: %1 - - Locked + + Http error: %1 +%2 @@ -3105,92 +3548,92 @@ source - ORIS->Event->Information->Event key EventStatisticsModel - + Class Група - + Maps Карти - + Free maps Вільні карти - + Runners Учасники - + Start first Старт першого - + Start last Старт останнього - + 1st time Перший час - + Finish time of first runner in current class. Фінішний час першого учасника в поточній групі. - + 3rd time Третій час - + Finish time of third runner in current class. Фінішний час третього учасника поточної групи. - + Time to close Час закриття - + Time until new finished competitors should not affect standings on first three places. Час, після якого нові фінішери не повинні впливати на перші три місця. - + Finished Фінішувало - + Not finished Не фінішувало - + New results Нові результати - + Number of finished competitors not printed in results. Кількість фінішерів не надруковано в результаті. - + Not printed time Час без друку - + Time since recent results printout. Час від попереднього друку результатів. @@ -3397,12 +3840,12 @@ source - ORIS->Event->Information->Event key MainWindow - + Quick Event ver. %1 Quick Event вер. %1 - + Application log Журнал додатку @@ -3410,52 +3853,67 @@ source - ORIS->Event->Information->Event key Model - + SI ЧИП - + Class Група - + Name Ім’я - + Reg Реє - + Bib Bib - + Start Старт - + Time Час - + Finish Фініш - + Run flags - + + CR + CR + + + + Card rent + + + + + CRT + + + + Error Помилка @@ -3472,104 +3930,99 @@ source - ORIS->Event->Information->Event key Дискваліфікація - - RT - - - - + Card in rent table ЧИП в переліку орендованих - - R - - - - + Card returned ЧИП повернуто - + + CRET + + + + CTIME Чпер - + Card check time Час випробування картки - + STIME Чстарт - + Card start time Час старту в картці - + FTIME Чфін - + Card finish time Час фінішу в картці - + Assign card to runner error Помилка призначення картки учасникові - + NC NotCompeting NC - + MP MisPunch MP - + BC BadCheck BC - + DNS DidNotStart - + DNF DidNotFinish - + DO disqualifiedByOrganizer DO - + OT OverTime OT - + DSQ Disqualified DSQ @@ -3593,52 +4046,52 @@ source - ORIS->Event->Information->Event key &Синхронізувати записи поточної події - + &Clubs and registrations &Клуби і реєстрації - + &Update one-time clubs - + &Text file &Текстовий файл - + &Competitors CSOS &Учасники CSOS - + Competitors C&SV Учасники C&SV - + &Ranking CSV (ORIS format) &Розряди CSV (формат ORIS) - + Import CSV (key is CZE registration) - + Import CSV (key is runs.id) - + Import CSV (key is Iof ID) - + Import IOF XML 3.0 @@ -3646,107 +4099,107 @@ source - ORIS->Event->Information->Event key OrisImporter - + JSON document parse error: %1 at: %2 near: %3 Помилка розбирання документу JSON: %1 у: %2 коло: %3 - + Cannot find Oris import ID. Неможливо знайти ІД імпорту Oris. - + Import finished successfully. Імпортовано успішно. - + New entries Нові записи - + Edited entries Відредаговані записи - + Deleted entries Видалені записи - + Oris import report Звіт імпорту Oris - + Save without drops Записати без видалення - + Export - + Export as ... - + HTML files *.html (*.html) - + Cannot open file '%1' for writing. - + Import ORIS Registrations Імпорт реєстрацій ORIS - + Year of registration: Рік реєстрації: - + Importing registrations Імпорт реєстрацій - + Importing clubs Імпорт клубів - + Warning Попередження - + For import one-time clubs, you need to fill ORIS Event Key in File->Event->Edit event - + Information Інформація - + No missing one-time clubs found. - + Importing one-time clubs @@ -3787,7 +4240,20 @@ source - ORIS->Event->Information->Event key Картка - + + + Warning + Попередження + + + + + Receipt report type is not defined. +Please go to Settings->Receipts and set receipt type. + + + + Receipt Чек @@ -4012,47 +4478,47 @@ source - ORIS->Event->Information->Event key Друк нового - + SI ЧИП - + Class Група - + Name Ім’я - + Reg Реє - + Start Старт - + Time Час - + printer принтер - + Print receipts for selected rows Друкувати чеки для вибраних рядків - + Show receipt Показати чек @@ -4358,96 +4824,96 @@ source - ORIS->Event->Information->Event key В алфавітному порядку - + Start list by classes Стартовий протокол по групах - + Start list by clubs Стартовий протокол по клубах - - - + + + Results Результати - + Save as %1 Зберегти як %1 - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing relays (key is Club, Relay Name & Class). - + Each row should have following columns: <ol><li>Club abbr <i>- key (part1)</i></li><li>Relay name <i>- key (part2)</i></li><li>Start number (Bib)</li><li>Class (Optional - if not filed, trying to guess from the starting number)</li></ol> - + Open file Відкрити файл - + CSV files (*.csv *.txt) Файли CSV (*.csv *.txt) - + Cannot open file '%1' for reading. - + Fields separation error, invalid CSV format, Error reading CSV line: [%1] Помилка розділення полів, некоректний формат CSV, Помилка читання рядка CSV: [%1] - + Error reading CSV line: [%1] Помилка читання рядка CSV: [%1] - + Cannot guess class name from bib: '%1' - + Undefined class name: '%1' Невизначена назва групи: «%1» - + Information Інформація - + Import file finished. Imported %1 of %2 lines Press refresh button to show imported data. - + vac - + Enter number of new vacants - + Vacants count for class %1 : @@ -4627,29 +5093,29 @@ Press refresh button to show imported data. - + E%1 IOF XML stage results E%1 IOF XML результати забігу - - + + Start list by classes Стартовий протокол по групах - - + + Start list by clubs Стартовий протокол по клубах - + Start list for starters Стартовий протокол для суддів старту - + Start list by classes for %n stage(s) Стартовий протокол по групах для %n забігу @@ -4658,7 +5124,7 @@ Press refresh button to show imported data. - + Start list by clubs for %n stage(s) Стартовий протокол по клубах для %n забігу @@ -4667,19 +5133,19 @@ Press refresh button to show imported data. - - + + Results by classes Протокол результатів по групах - + Stage awards Нагородження забігу - - + + Results after %n stage(s) Результати після %n забігу @@ -4688,169 +5154,169 @@ Press refresh button to show imported data. - + Awards after %1 stages Переможці після %1 забігу(ів) - - + + length: довжина: - - + + climb: набір: - - - - + + + + Top Вгору - - + + St. Num - - - - - + + + + + Name Ім’я - - - - - + + + + + Registration Реєстрація - - + + SI ЧИП - - + + Start Старт - + Class Група - + Preparing data Підготування данних - - + + Procesing class %1 Обробляється група %1 - + Laps Етапи - - - + + + Place Місце - - + + Club Клуб - - - + + + Time Час - - - + + + Loss Програш - + NC Not Competing NC - + DISQ DISQ - + E%1 IOF XML stage startlist - - - + + + Stage results Результати забігу - + Warning Попередження - + Export error Помилка експорту - + Information Інформація - + Results exported to %1 Результати експортовано в %1 - + Overall results after stage %1 Підсумкові результати після забігу %1 - + Stage %1 Забіг %1 - + FIN FIN @@ -4919,37 +5385,37 @@ Press refresh button to show imported data. Формат виводу - + HTML multi page HTML багатосторінковий - + CSOS fixed column sizes CSOS фіксована ширина стовбців - + CSV one file CSV один файл - + CSV multi file (file per class) CSV багато файлів (файл на групу) - + IOF-XML 3.0 IOF-XML 3.0 - + Open Directory Відкрити каталог - + Cannot create directory '%1'. Не можу створити каталог «%1». @@ -5071,69 +5537,69 @@ Press refresh button to show imported data. RunsTableModel - + Running Біжить - + id ІД - + Relay Естафета - + Leg Етап - + Class Група - + SN start number - + Start number Стартовий номер - - + + SI ЧИП - + Registered SI Зареєстровані чипи - + Name Ім’я - + Reg Реє - + Lic Ліц - + License Ліцензія @@ -5146,131 +5612,131 @@ Press refresh button to show imported data. Розряд - + Actual SI Актуальний ЧИП - + Corridor - + Time when the competitor entered start corridor - + Check Випробування - + Start Старт - + Time Час - + Finish Фініш - + Penalty Штраф - + Run flags Стан пробігу - + Card flags Стан картки - + Ranking pos Поз розряду - + Runner's position in CZ ranking. Позиція бігуна у розрядній сітці Чехії. - + IOF ID IOF ID - + DO disqualifiedByOrganizer DO - + MP MisPunch MP - + BC BadCheck BC - + NC NotCompeting NC - + CR Card rent requested CR - + CT Card in lent cards table CT - + RET Card returned RET - + Note Нотатки - + DNS DidNotStart DNS - + DNF DidNotFinish DNF - + OT OverTime OT @@ -5281,17 +5747,17 @@ Press refresh button to show imported data. DSQ - + Cannot set not running flag for competitor with valid finish time. Не можу встановити стан «не біг» учасникові з коректним часом фінішу. - + Mid-air collision switching start times, reload table and try it again. Конфлікт при зміні стартового часу, перезавантажте таблицю і спробуйте знов. - + Mid-air collision setting start time, reload table and try it again. Конфлікт встановлення стартового часу, перезавантажте таблицю і спробуйте знову. @@ -5320,62 +5786,62 @@ Press refresh button to show imported data. інтервал - + Show receipt Показати чек - + Load times from card in selected rows Завантажити час з карток для обраних рядків - + Print receipt Друкувати чек - + Shift start times in selected rows Зсунути час старту для обраних рядків - + Clear start times in selected rows Очистити час старту для вибраних рядків - + Set class in selected rows Встановити групу для вибраних рядків - + Reloading times for %1 Перезавантажити час для %1 - + Get number Отримати номер - + Start times offset [min]: Встановити зсув часу (хв): - + Dialog Діалог - + Select class Виберіть групу - + Duplicate SI inserted. Вставлено дублікат ЧИПу. @@ -5548,7 +6014,7 @@ Press refresh button to show imported data. - + Competitors statistics @@ -5637,27 +6103,22 @@ Press refresh button to show imported data. CSOS - + Really delete all the selected competitors? This action cannot be reverted. Дійсно видалити всіх вибраних учасників? Цю дію не можна повернути. - + Confirm deletion of %1 competitors. Підтвердить видалення %1 учасників. - + Edit Competitor - - Save - - - - + Ok and &next @@ -5722,12 +6183,12 @@ Press refresh button to show imported data. Групу заблоковано для розміщення. - + Start interval is zero, proceed anyway? Стартовий інтервал нуль, все одно продовжити? - + Reset all start times and unlock drawing for this class? Скинути стартовий час і розблокувати розміщення цієї групи? @@ -5735,7 +6196,7 @@ Press refresh button to show imported data. Speaker::SpeakerPlugin - + &Speaker Гу&чномовець @@ -5748,37 +6209,37 @@ Press refresh button to show imported data. Форма - + Code Код - + SI ЧИП - + Punch time Час відмітки - + Runner time Час бігуна - + Class Група - + Registration Реєстрація - + Competitor Учасник @@ -5817,37 +6278,37 @@ Press refresh button to show imported data. TxtImporter - + Import windows-1250 coded fixed column size text files in CSOS format. Імпортувати текстові файли (cp1250) з фіксованим розміром стовпців у форматі CSOS. - + Each row should have following columns: <ol><li>7 chars: Registration</li><li>1 space</li><li>10 chars: Class</li><li>1 space</li><li>10 chars: SI</li><li>1 space</li><li>25 chars: Name</li><li>1 space</li><li>2 chars: Licence</li><li>1 space</li><li>rest of line: Note</li></ol> Кожен рядок має мати такі стовпці: <ol><li>7 символів: Реєстрація</li><li>1 пропуск</li><li>10 символів: Група</li><li>1 пропуск</li><li>10 символів: ЧИП</li><li>1 пропуск</li><li>25 символів: Ім’я</li><li>1 пропуск</li><li>2 символи: Ліцензія</li><li>1 пропуск</li><li>решта рядка: Нотатки</li></ol> - - - - - - + + + + + + Open file Відкрити файл - + CSOS files (*.txt) Файли CSOS (*.txt) - - - - - - + + + + + + Cannot open file '%1' for reading. Не вдалося відкрити файл «%1» для читання. @@ -5856,79 +6317,79 @@ Press refresh button to show imported data. Імпортувати текстові файли UTF8: розділені комами поля із заголовком. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is comma(,) - + Each row should have following columns: <ol><li>Registration</li><li>Class</li><li>SI</li><li>LastName</li><li>FirstName</li><li>Licence</li><li>Note</li></ol> Кожен рядок повинен мати такі стовпці: <ol><li>Реєстрація</li><li>Група</li><li>ЧИП</li><li>Ім’я</li><li>Прізвище</li><li>Ліцензія</li><li>Нотатки</li></ol> - - - - + + + + CSV files (*.csv *.txt) Файли CSV (*.csv *.txt) - + Oris ranking CSV files (*.txt *.csv) Файли Oris CSV з розрядами (*.txt *.csv) - - - - + + + + Fields separation error, invalid CSV format, Error reading CSV line: [%1] Помилка розділення полів, некоректний формат CSV, Помилка читання рядка CSV: [%1] - - - - + + + + Error reading CSV line: [%1] Помилка читання рядка CSV: [%1] - - - - + + + + Undefined class name: '%1' Невизначена назва групи: «%1» - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is Czech registration). - + Each row should have following columns: <ol><li>Registration <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is <b>id</b> in module(table) <b>runs</b>). - + Each row should have following columns: <ol><li>Runs Id <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty. - + Import UTF8 text file with comma separated values with first row as header.<br/>Separator is semicolon(;).<br/>Updates only existing runners (key is IOF ID). - + Each row should have following columns: <ol><li>IOF ID <i>- key</i></li><li>SI</li><li>Class</li><li>Bib</li><li>Start time <i>(in format: <b>mmm.ss</b> from zero time or <b>hh:mm:ss</b>)</i></li></ol> Only first column is mandatory, others can be empty.