diff --git a/code/HTMLWriter.cpp b/code/HTMLWriter.cpp index db326a1..434ff27 100644 --- a/code/HTMLWriter.cpp +++ b/code/HTMLWriter.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/HTMLWriter.h b/code/HTMLWriter.h index eaecad5..89ae1c5 100644 --- a/code/HTMLWriter.h +++ b/code/HTMLWriter.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/MeOSFeatures.cpp b/code/MeOSFeatures.cpp index 9a5d4f1..718efc9 100644 --- a/code/MeOSFeatures.cpp +++ b/code/MeOSFeatures.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/MeOSFeatures.h b/code/MeOSFeatures.h index fa52890..ac31161 100644 --- a/code/MeOSFeatures.h +++ b/code/MeOSFeatures.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/MeosSQL.cpp b/code/MeosSQL.cpp index 9176b2f..c1b6819 100644 --- a/code/MeosSQL.cpp +++ b/code/MeosSQL.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +35,7 @@ #include "RunnerDB.h" #include "progress.h" #include "metalist.h" +#include "machinecontainer.h" #include "MeOSFeatures.h" #include "meosexception.h" #include "generalresult.h" @@ -419,6 +420,11 @@ void MeosSQL::upgradeDB(const string &db, oDataContainer const * dc) { sql = sql.substr(0, sql.length() - 2); query.execute(sql); } + if (!eCol.count("Machine")) { + string sql = "ALTER TABLE oEvent ADD COLUMN " + C_MTEXT("Machine"); + sql = sql.substr(0, sql.length() - 2); + query.execute(sql); + } } else if (db == "oCourse") { if (!eCol.count("Legs")) { @@ -556,7 +562,8 @@ bool MeosSQL::openDB(oEvent *oe) << C_STRING("NameId", 64) << C_UINT("BuildVersion") << oe->getDI().generateSQLDefinition() - << C_MTEXT("Lists") << C_END(); + << C_MTEXT("Lists") + << C_MTEXT("Machine") << C_END(); query.execute(); // Upgrade oEvent @@ -818,7 +825,8 @@ OpFailStatus MeosSQL::SyncUpdate(oEvent *oe) << " NameId=" << quote << toString(oe->currentNameId) << ", " << " ZeroTime=" << unsigned(oe->ZeroTime) << ", " << " BuildVersion=" << buildVersion << ", " - << " Lists=" << quote << listEnc + << " Lists=" << quote << listEnc << ", " + << " Machine=" <getMachineContainer().save() << oe->getDI().generateSQLSet(true); if (syncUpdate(queryset, "oEvent", oe) == opStatusFail) @@ -1185,6 +1193,9 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) { retValue = opStatusWarning; } + const string &mRaw = row.raw_string(res.field_num("Machine")); + oe->getMachineContainer().load(mRaw); + oDataInterface odi=oe->getDI(); storeData(odi, row, oe->dataRevision); oe->changed = false; @@ -2589,7 +2600,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oClub *c) } try { auto query = con->query(); - query << "SELECT * FROM oClub WHERE Id=" << c->Id; + query << "SELECT * FROM oClub WHERE Id=" << c->Id << andWhereOld(c); auto res = query.store(); RowWrapper row; @@ -2611,8 +2622,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oClub *c) return syncUpdate(c, false); } } - else { - //Something is wrong!? Deleted? + else if (c->changed) { return syncUpdate(c, true); } return opStatusOK; @@ -3097,6 +3107,9 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) { catch (std::exception &ex) { alert(ex.what()); } + const string &mRaw = row.raw_string(res.field_num("Machine")); + oe->getMachineContainer().load(mRaw); + oe->counter = counter; oDataInterface odi=oe->getDI(); storeData(odi, row, oe->dataRevision); @@ -3124,7 +3137,8 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) { << " ZeroTime=" << unsigned(oe->ZeroTime) << ", " << " BuildVersion=if (BuildVersion<" << buildVersion << "," << buildVersion << ",BuildVersion), " - << " Lists=" << quote << listEnc + << " Lists=" << quote << listEnc << ", " + << " Machine=" << quote << oe->getMachineContainer().save() << oe->getDI().generateSQLSet(false); syncUpdate(queryset, "oEvent", oe); @@ -3156,7 +3170,8 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) { << " ZeroTime=" << unsigned(oe->ZeroTime) << "," << " BuildVersion=if (BuildVersion<" << buildVersion << "," << buildVersion << ",BuildVersion)," - << " Lists=" << quote << listEnc + << " Lists=" << quote << listEnc << ", " + << " Machine=" << quote << oe->getMachineContainer().save() << oe->getDI().generateSQLSet(false); syncUpdate(queryset, "oEvent", oe); @@ -3223,7 +3238,7 @@ bool MeosSQL::syncListRunner(oEvent *oe) st = OpFailStatus::opStatusOK; oRunner *r=oe->getRunner(Id, 0); - if (r) { + if (r && !r->Removed) { r->Removed=true; if (r->tInTeam) r->tInTeam->correctRemove(r); @@ -3233,6 +3248,8 @@ bool MeosSQL::syncListRunner(oEvent *oe) } r->changedObject(); + r->changed = false; + oe->dataRevision++; } } else{ @@ -3290,9 +3307,11 @@ bool MeosSQL::syncListClass(oEvent *oe) { if (int(row["Removed"])) { st = OpFailStatus::opStatusOK; oClass *c = oe->getClass(Id); - if (c) { + if (c && !c->Removed) { c->changedObject(); c->Removed = true; + c->changed = false; + oe->dataRevision++; } } else { @@ -3355,9 +3374,11 @@ bool MeosSQL::syncListClub(oEvent *oe) st = opStatusOK; oClub *c = oe->getClub(Id); - if (c) { + if (c && !c->Removed) { c->Removed = true; c->changedObject(); + c->changed = false; + oe->dataRevision++; } } else { @@ -3413,9 +3434,11 @@ bool MeosSQL::syncListCourse(oEvent *oe) { st = opStatusOK; oCourse *c = oe->getCourse(Id); - if (c) { + if (c && !c->Removed) { c->Removed = true; c->changedObject(); + c->changed = false; + oe->dataRevision++; } } else { @@ -3469,9 +3492,11 @@ bool MeosSQL::syncListCard(oEvent *oe) if (int(row["Removed"])) { st = opStatusOK; oCard *c = oe->getCard(Id); - if (c) { + if (c && !c->Removed) { c->changedObject(); c->Removed = true; + c->changed = false; + oe->dataRevision++; } } else { @@ -3529,9 +3554,11 @@ bool MeosSQL::syncListControl(oEvent *oe) { st = opStatusOK; oControl *c = oe->getControl(Id, false); - if (c) { + if (c && !c->Removed) { c->Removed = true; c->changedObject(); + c->changed = false; + oe->dataRevision++; } } else { @@ -3588,13 +3615,16 @@ bool MeosSQL::syncListPunch(oEvent *oe) if (int(row["Removed"])) { st = OpFailStatus::opStatusOK; oFreePunch *c=oe->getPunch(Id); - if (c) { + if (c && !c->Removed) { c->Removed=true; int cid = c->getControlId(); oFreePunch::rehashPunches(*oe, c->CardNo, 0); pRunner r = oe->getRunner(c->tRunnerId, 0); if (r) r->markClassChanged(cid); + + c->changed = false; + oe->dataRevision++; } } else { @@ -3653,10 +3683,12 @@ bool MeosSQL::syncListTeam(oEvent *oe) { if (int(row["Removed"])) { st = OpFailStatus::opStatusOK; oTeam *t = oe->getTeam(Id); - if (t) { + if (t && !t->Removed) { t->changedObject(); t->prepareRemove(); t->Removed = true; + t->changed = false; + oe->dataRevision++; } } else { @@ -3696,15 +3728,19 @@ bool MeosSQL::syncListTeam(oEvent *oe) { string MeosSQL::selectUpdated(const char *oTable, const SqlUpdated &updated) { string p1 = string("SELECT Id, Counter, Modified, Removed FROM ") + oTable; - - string q = "(" + p1 + " WHERE Counter>" + itos(updated.counter) + ") UNION ALL ("+ + string cond1 = p1 + " WHERE Counter>" + itos(updated.counter); + if (updated.updated.empty()) + return cond1; + + string q = "(" + cond1 + ") UNION ALL ("+ p1 + " WHERE Modified>'" + updated.updated + "' AND Counter<=" + itos(updated.counter) + ")"; - return q; } bool MeosSQL::checkConnection(oEvent *oe) { + if (!con->connected()) + return false; errorMessage.clear(); if (!oe) { diff --git a/code/MeosSQL.h b/code/MeosSQL.h index 9477d2f..328d5e3 100644 --- a/code/MeosSQL.h +++ b/code/MeosSQL.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/Printer.h b/code/Printer.h index a52d506..12b44b4 100644 --- a/code/Printer.h +++ b/code/Printer.h @@ -4,7 +4,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/RestService.cpp b/code/RestService.cpp index ec7baa0..4ec1fba 100644 --- a/code/RestService.cpp +++ b/code/RestService.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +40,9 @@ RestService::~RestService() { } } -void RestService::save(oEvent &oe, gdioutput &gdi) { +void RestService::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); + if (!server) { server = RestServer::construct(); @@ -49,7 +51,8 @@ void RestService::save(oEvent &oe, gdioutput &gdi) { oe.setProperty("ServicePort", xport); port = xport; - server->startService(port); + if (doProcess) + server->startService(port); } else throw meosException("Invalid port number"); @@ -74,7 +77,7 @@ void RestService::save(oEvent &oe, gdioutput &gdi) { void ListIpAddresses(vector& ip); -void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) { +void RestService::settings(gdioutput &gdi, oEvent &oe, State state) { if (port == -1) { port = oe.getPropertyInt("ServicePort", 2009); rootMap = oe.getPropertyString("ServiceRootMap", ""); @@ -100,7 +103,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) { gdi.addInput("RootMap", gdi.recodeToWide(rootMap)); gdi.setInputStatus("RootMap", !rootMap.empty()); - startCancelInterval(gdi, "Save", created, IntervalNone, L""); + startCancelInterval(gdi, "Save", state, IntervalNone, L""); if (!server) { gdi.addInput("Port", itow(port), 10, 0, L"Port:", L"#http://localhost:[PORT]/meos"); @@ -128,8 +131,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) { } void RestService::status(gdioutput &gdi) { - gdi.pushX(); - gdi.addString("", 1, name); + AutoMachine::status(gdi); if (server) { gdi.addString("", 0, "Server startad pÃ¥ X#" + itos(port)); diff --git a/code/RestService.h b/code/RestService.h index 6f6d6c7..8380ab4 100644 --- a/code/RestService.h +++ b/code/RestService.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,8 +34,8 @@ class RestService : string rootMap; public: - void save(oEvent &oe, gdioutput &gdi) override; - void settings(gdioutput &gdi, oEvent &oe, bool created) override; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) override; + void settings(gdioutput &gdi, oEvent &oe, State state) override; RestService *clone() const override { return new RestService(*this); } void status(gdioutput &gdi) override; void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) override; diff --git a/code/RunnerDB.cpp b/code/RunnerDB.cpp index 2189a11..d023d20 100644 --- a/code/RunnerDB.cpp +++ b/code/RunnerDB.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/RunnerDB.h b/code/RunnerDB.h index e6caa34..91ab598 100644 --- a/code/RunnerDB.h +++ b/code/RunnerDB.h @@ -11,7 +11,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/SportIdent.cpp b/code/SportIdent.cpp index 353f84b..af14257 100644 --- a/code/SportIdent.cpp +++ b/code/SportIdent.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/SportIdent.h b/code/SportIdent.h index 713ba97..f82386b 100644 --- a/code/SportIdent.h +++ b/code/SportIdent.h @@ -13,7 +13,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabAuto.cpp b/code/TabAuto.cpp index 0a96136..55b99e0 100644 --- a/code/TabAuto.cpp +++ b/code/TabAuto.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ #include "gdiconstants.h" #include "meosexception.h" +#include "machinecontainer.h" #include "HTMLWriter.h" static TabAuto *tabAuto = 0; @@ -98,6 +99,18 @@ AutoMachine *TabAuto::getMachine(int id) { throw meosException("Service X not found.#" + itos(id)); } +void AutoMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + machineName = gdi.getText("MachineName"); +} + +void AutoMachine::status(gdioutput &gdi) { + gdi.pushX(); + if (machineName.empty()) + gdi.addString("", 1, name); + else + gdi.addString("", 1, L"#" + lang.tl(name) + L" (" + machineName + L")"); +} + TabAuto::~TabAuto(void) { list::iterator it; @@ -108,27 +121,41 @@ TabAuto::~TabAuto(void) tabAuto=0; } - -void tabAutoKillMachines() +void TabAuto::tabAutoKillMachines() { if (tabAuto) tabAuto->killMachines(); } -void tabAutoRegister(TabAuto *ta) +void TabAuto::tabAutoRegister(TabAuto *ta) { tabAuto=ta; } -void tabAutoAddMachinge(const AutoMachine &am) +AutoMachine &TabAuto::tabAutoAddMachinge(const AutoMachine &am) { - if (tabAuto) { - tabAuto->addMachine(am); - } + if (tabAuto) + return tabAuto->addMachine(am); + throw meosException("Internal error"); } -void tabForceSync(gdioutput &gdi, pEvent oe) +bool TabAuto::hasActiveReconnectionMachine() { + if (tabAuto) + return tabAuto->hasActiveReconnection(); + return false; +} + +bool TabAuto::hasActiveReconnection() const { + for (auto am : machines) { + if (am->getType() == Machines::mMySQLReconnect) + return true; + } + + return false; +} + +void tabForceSync(gdioutput &gdi, pEvent oe) { if (tabAuto) tabAuto->syncCallback(gdi); } @@ -152,31 +179,38 @@ int AutomaticCB(gdioutput *gdi, int type, void *data) return 0; } -void TabAuto::syncCallback(gdioutput &gdi) +void TabAuto::syncCallback(gdioutput& gdi) { + list toRemove; wstring msg; - try { - list::iterator it; - for (it=machines.begin(); it!=machines.end(); ++it) { - AutoMachine *am=*it; + list::iterator it; + for (it = machines.begin(); it != machines.end(); ++it) { + try { + AutoMachine* am = *it; if (am && am->synchronize && !am->isEditMode()) am->process(gdi, oe, SyncDataUp); + if (am->removeMe()) + toRemove.push_back(am); + } + catch (meosException& ex) { + msg = ex.wwhat(); + } + catch (std::exception& ex) { + msg = gdi.widen(ex.what()); + } + catch (...) { + msg = L"Ett okänt fel inträffade."; } } - catch (meosException &ex) { - msg = ex.wwhat(); - } - catch(std::exception &ex) { - msg = gdi.widen(ex.what()); - } - catch(...) { - msg = L"Ett okänt fel inträffade."; + + for (auto* r : toRemove) { + stopMachine(r); } + if (!msg.empty()) { gdi.alert(msg); gdi.setWaitCursor(false); } - } void TabAuto::updateSyncInfo() @@ -195,25 +229,45 @@ void TabAuto::updateSyncInfo() } } -void TabAuto::timerCallback(gdioutput &gdi) -{ +void TabAuto::timerCallback(gdioutput &gdi) { DWORD tc=GetTickCount(); - list::iterator it; bool reload=false; + list toRemove; + wstring msg; - for (it=machines.begin(); it!=machines.end(); ++it) { - AutoMachine *am=*it; + for (it = machines.begin(); it != machines.end(); ++it) { + AutoMachine* am = *it; if (am && am->interval && tc >= am->timeout && !am->isEditMode()) { - am->process(gdi, oe, SyncTimer); - setTimer(am); - reload=true; + try { + am->process(gdi, oe, SyncTimer); + } + catch (meosException& ex) { + msg = ex.wwhat(); + } + catch (std::exception& ex) { + msg = gdi.widen(ex.what()); + } + catch (...) { + msg = L"Ett okänt fel inträffade."; + } + reload = true; + if (am->removeMe()) + toRemove.push_back(am); + else + setTimer(am); } } + for (auto* r : toRemove) { + stopMachine(r); + } DWORD d=0; if (reload && !editMode && gdi.getData("AutoPage", d) && d) loadPage(gdi, false); + + if (!msg.empty()) + throw meosException(msg); } void TabAuto::setTimer(AutoMachine *am) @@ -255,16 +309,8 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu) if (!newPath.empty()) gdi.setText(edit, newPath); } - else if (bu.id == "StartBackup") { - SaveMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - if (sm) - sm->saveSettings(gdi); - updateSyncInfo(); - loadPage(gdi, false); - } else if (bu.id=="Result") { - PrintResultMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mPrintResultsMachine); + settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mPrintResultsMachine); } else if (bu.id == "BrowseFile") { static int index = 0; @@ -302,168 +348,37 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu) } else if (bu.id=="Splits") { SplitsMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mSplitsMachine); + settings(gdi, sm, AutoMachine::State::Create, mSplitsMachine); } else if (bu.id=="Prewarning") { PrewarningMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mPrewarningMachine); + settings(gdi, sm, AutoMachine::State::Create, mPrewarningMachine); } else if (bu.id=="Punches") { PunchMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mPunchMachine); + settings(gdi, sm, AutoMachine::State::Create, mPunchMachine); } else if (bu.id=="OnlineResults") { - OnlineResults *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mOnlineResults); + settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mOnlineResults); } else if (bu.id=="OnlineInput") { - OnlineInput *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mOnlineInput); + settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mOnlineInput); } else if (bu.id=="SaveBackup") { - SaveMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - settings(gdi, sm, mSaveBackup); + settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mSaveBackup); } else if (bu.id == "InfoService") { - settings(gdi, getMachine(bu.getExtraInt()), mInfoService); - } - else if (bu.id=="StartResult") { -#ifndef MEOSDB - wstring minute=gdi.getText("Interval"); - int t=convertAbsoluteTimeMS(minute); - - if (t<2 || t>7200) { - gdi.alert("Intervallet mÃ¥ste anges pÃ¥ formen MM:SS."); - } - else { - PrintResultMachine *prm=dynamic_cast(getMachine(bu.getExtraInt())); - - if (prm) { - prm->interval = t; - prm->doExport = gdi.isChecked("DoExport"); - prm->doPrint = gdi.isChecked("DoPrint"); - prm->exportFile = gdi.getText("ExportFile"); - prm->exportScript = gdi.getText("ExportScript"); - - if (!prm->readOnly) { - prm->structuredExport = gdi.isChecked("StructuredExport"); - prm->htmlRefresh = gdi.isChecked("HTMLRefresh") ? t : 0; - - gdi.getSelection("Classes", prm->classesToPrint); - - ListBoxInfo lbi; - if (gdi.getSelectedItem("ListType", lbi)) { - oListParam par; - par.selection=prm->classesToPrint; - par.listCode = EStdListType(lbi.data); - par.pageBreak = gdi.isChecked("PageBreak"); - par.showHeader = gdi.isChecked("ShowHeader"); - par.showInterTimes = gdi.isChecked("ShowInterResults"); - par.splitAnalysis = gdi.isChecked("SplitAnalysis"); - int legNr = gdi.getSelectedItem("LegNumber").first; - if (legNr >= 0) - par.setLegNumberCoded(legNr); - else - par.setLegNumberCoded(0); - - oe->generateListInfo(par, prm->listInfo); - } - } - prm->po.onlyChanged = gdi.isChecked("OnlyChanged"); - prm->pageBreak = gdi.isChecked("PageBreak"); - prm->showHeader = gdi.isChecked("ShowHeader"); - - prm->showInterResult = gdi.isChecked("ShowInterResults"); - prm->splitAnalysis = gdi.isChecked("SplitAnalysis"); - prm->synchronize=true; //To force continuos data sync. - setTimer(prm); - } - updateSyncInfo(); - loadPage(gdi, false); - } -#endif - } - else if (bu.id=="StartSplits") { - - wstring ivt = gdi.getText("Interval"); - - int iv = gdi.getTextNo("Interval"); - const wstring &file=gdi.getText("FileName"); - - if (!ivt.empty() && (iv < 1 || iv > 7200)) { - throw meosException(L"Ogiltigt antal sekunder: X#" + gdi.getText("Interval")); - } - - if (file.empty()) { - throw meosException("Filnamnet fÃ¥r inte vara tomt"); - } - - //Try exporting. - oe->exportIOFSplits(oEvent::IOF20, file.c_str(), true, false, - set(), -1, false, true, true, false); - SplitsMachine *sm=dynamic_cast(getMachine(bu.getExtraInt())); - - if (sm) { - sm->interval=iv; - - sm->file=file; - sm->synchronize=true; - setTimer(sm); - } - updateSyncInfo(); - loadPage(gdi, false); + settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mInfoService); } else if (bu.id=="Save") { // General save AutoMachine *sm=getMachine(bu.getExtraInt()); if (sm) { - sm->save(*oe, gdi); + sm->save(*oe, gdi, true); setTimer(sm); } updateSyncInfo(); loadPage(gdi, false); } - else if (bu.id=="StartPrewarning") { - PrewarningMachine *pwm=dynamic_cast(getMachine(bu.getExtraInt())); - - if (pwm) { - pwm->waveFolder=gdi.getText("WaveFolder"); - gdi.getSelection("Controls", pwm->controls); - - oe->synchronizeList(oListId::oLPunchId); - oe->clearPrewarningSounds(); - - pwm->synchronizePunches=true; - pwm->controlsSI.clear(); - for (set::iterator it=pwm->controls.begin();it!=pwm->controls.end();++it) { - pControl pc=oe->getControl(*it, false); - - if (pc) - pwm->controlsSI.insert(pc->Numbers, pc->Numbers+pc->nNumbers); - } - } - updateSyncInfo(); - loadPage(gdi, false); - } - else if (bu.id=="StartPunch") { - - wstring minute=gdi.getText("Interval"); - int t=_wtoi(minute.c_str()); - - if (t<1 || t>7200) { - throw meosException(L"Ogiltigt antal sekunder: X#" + minute); - } - else { - PunchMachine *pm=dynamic_cast(getMachine(bu.getExtraInt())); - - if (pm) { - pm->interval=t; - pm->radio=gdi.getTextNo("Radio"); - setTimer(pm); - } - } - updateSyncInfo(); - loadPage(gdi, false); - } else if (bu.id == "Cancel") { loadPage(gdi, false); } @@ -474,6 +389,40 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu) updateSyncInfo(); loadPage(gdi, false); } + else if (bu.id == "SaveMachine") { + auto sm = getMachine(bu.getExtraInt()); + sm->save(*oe, gdi, false); + wstring iv; + if (gdi.hasWidget("Interval")) + iv = gdi.getText("Interval"); + sm->saveMachine(*oe, iv); + oe->updateChanged(); + oe->synchronize(false); + } + else if (bu.id == "Erase") { + auto sm = getMachine(bu.getExtraInt()); + if (sm) { + oe->getMachineContainer().erase(sm->getTypeString(), sm->getMachineName()); + oe->updateChanged(); + oe->synchronize(); + stopMachine(sm); + } + + updateSyncInfo(); + loadPage(gdi, false); + } + else if (bu.id == "CreateLoad") { + auto sm = oe->getMachineContainer().enumerate(); + int ix = bu.getExtraInt(); + if (ix < sm.size()) { + auto &m = sm[ix]; + Machines type = AutoMachine::getType(m.first); + AutoMachine *am = AutoMachine::construct(type); + machines.push_back(am); + am->loadMachine(*oe, m.second); + settings(gdi, am, AutoMachine::State::Load, am->getType()); + } + } else if (bu.id == "PrinterSetup") { PrintResultMachine *prm = dynamic_cast(getMachine(bu.getExtraInt())); @@ -548,13 +497,16 @@ bool TabAuto::stopMachine(AutoMachine *am) return false; } -void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, Machines ms) { +void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, AutoMachine::State state, Machines ms) { editMode=true; - bool createNew = (sm==0) || (ms == Machines::Unknown); if (sm) { + if (state == AutoMachine::State::Create) + state = AutoMachine::State::Edit; + ms = sm->getType(); } else { + state = AutoMachine::State::Create; sm = AutoMachine::construct(ms); machines.push_back(sm); } @@ -566,7 +518,7 @@ void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, Machines ms) { int d = gdi.scaleLength(6); gdi.setCX(cx + d); sm->setEditMode(true); - sm->settings(gdi, *oe, createNew); + sm->settings(gdi, *oe, state); int w = gdi.getWidth(); int h = gdi.getHeight(); @@ -592,6 +544,7 @@ void TabAuto::killMachines() bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast) { oe->checkDB(); + oe->synchronize(); tabAuto=this; editMode=false; gdi.selectTab(tabId); @@ -608,34 +561,74 @@ bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast) gdi.setData("AutoPage", 1); gdi.addString("", boldLarge, "Automater"); gdi.setRestorePoint(); + gdi.fillDown(); + gdi.pushX(); gdi.addString("", 10, "help:10000"); + + auto sm = oe->getMachineContainer().enumerate(); + + set> startedMachines; + for (auto &m : machines) { + string t; + m->getType(t); + startedMachines.emplace(t, m->machineName); + } + decltype(sm) sm2; + for (auto &m : sm) { + if (startedMachines.count(m) == 0) + sm2.push_back(m); + } + sm2.swap(sm); + + if (sm.size() > 0) { + gdi.dropLine(); + gdi.addString("", fontMediumPlus, "Sparade automater").setColor(colorDarkBlue); + gdi.dropLine(0.3); + gdi.fillRight(); + + for (int ix = 0; ix < sm.size(); ix++) { + if (ix > 0 && ix % 3 == 0) { + gdi.dropLine(2.5); + gdi.popX(); + } + + auto &m = sm[ix]; + Machines type = AutoMachine::getType(m.first); + if (m.second == L"default") + gdi.addButton("CreateLoad", AutoMachine::getDescription(type), AutomaticCB).setExtra(ix); + else + gdi.addButton("CreateLoad", L"#" + lang.tl(AutoMachine::getDescription(type)) + + L" (" + m.second + L")", AutomaticCB).setExtra(ix); + } + gdi.popX(); + gdi.dropLine(2); + gdi.fillDown(); + } gdi.dropLine(); gdi.addString("", fontMediumPlus, "Tillgängliga automater").setColor(colorDarkBlue); - gdi.dropLine(); + gdi.dropLine(0.3); gdi.fillRight(); - gdi.pushX(); - gdi.addButton("Result", "Resultatutskrift / export", AutomaticCB, "tooltip:resultprint"); - gdi.addButton("OnlineResults", "Resultat online", AutomaticCB, "Publicera resultat direkt pÃ¥ nätet"); - gdi.addButton("OnlineInput", "Inmatning online", AutomaticCB, "Hämta stämplingar m.m. frÃ¥n nätet"); + gdi.addButton("Result", AutoMachine::getDescription(Machines::mPrintResultsMachine), AutomaticCB, "tooltip:resultprint"); + gdi.addButton("OnlineResults", AutoMachine::getDescription(Machines::mOnlineResults), AutomaticCB, "Publicera resultat direkt pÃ¥ nätet"); + gdi.addButton("OnlineInput", AutoMachine::getDescription(Machines::mOnlineInput), AutomaticCB, "Hämta stämplingar m.m. frÃ¥n nätet"); gdi.popX(); gdi.dropLine(2.5); - gdi.addButton("SaveBackup", "Säkerhetskopiering", AutomaticCB); - gdi.addButton("InfoService", "Informationsserver", AutomaticCB); - gdi.addButton("Punches", "Stämplingstest", AutomaticCB, "Simulera inläsning av stämplar"); + gdi.addButton("SaveBackup", AutoMachine::getDescription(Machines::mSaveBackup), AutomaticCB); + gdi.addButton("InfoService", AutoMachine::getDescription(Machines::mInfoService), AutomaticCB); + gdi.addButton("Punches", AutoMachine::getDescription(Machines::mPunchMachine), AutomaticCB, "Simulera inläsning av stämplar"); gdi.popX(); gdi.dropLine(2.5); - gdi.addButton("Splits", "Sträcktider (WinSplits)", AutomaticCB, "Spara sträcktider till en fil för automatisk synkronisering med WinSplits"); - gdi.addButton("Prewarning", "Förvarningsröst", AutomaticCB, "tooltip:voice"); - + gdi.addButton("Splits", AutoMachine::getDescription(Machines::mSplitsMachine), AutomaticCB, "Spara sträcktider till en fil för automatisk synkronisering med WinSplits"); + gdi.addButton("Prewarning", AutoMachine::getDescription(Machines::mPrewarningMachine), AutomaticCB, "tooltip:voice"); gdi.fillDown(); gdi.dropLine(3); gdi.popX(); if (!machines.empty()) { - gdi.addString("", fontMediumPlus, "Startade automater").setColor(colorDarkBlue);; + gdi.addString("", fontMediumPlus, "Startade automater").setColor(colorDarkBlue); list::iterator it; int baseX = gdi.getCX(); @@ -666,30 +659,44 @@ bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast) gdi.setOffset(storedOY, storedOY, true); } if (showSettingsLast && !machines.empty()) - settings(gdi, *machines.rbegin(), Machines::Unknown); + settings(gdi, *machines.rbegin(), AutoMachine::State::Edit, Machines::Unknown); + gdi.refresh(); return true; } void AutoMachine::settingsTitle(gdioutput &gdi, char *title) { + gdi.fillDown(); gdi.dropLine(0.5); gdi.addString("", fontMediumPlus, title).setColor(colorDarkBlue); gdi.dropLine(0.5); } -void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool created, IntervalType type, const wstring &intervalIn) { +void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, State state, IntervalType type, const wstring &intervalIn) { gdi.pushX(); gdi.fillRight(); + + gdi.addInput("MachineName", machineName, 10, nullptr, L"Namn", L"Om du vill kan du namnge automaten"); + if (type == IntervalMinute) gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (MM:SS):"); else if (type == IntervalSecond) gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):"); + gdi.dropLine(1); - gdi.addButton(startCommand, created ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId()); - if (!created) - gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId()); + gdi.addButton(startCommand, + (state == State::Create || state == State::Load) ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId()); - gdi.addButton("Stop", created ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId()); + if (hasSaveMachine()) + gdi.addButton("SaveMachine", "Spara inställningar", AutomaticCB).setExtra(getId()); + + if (state == State::Load) + gdi.addButton("Erase", "Radera", AutomaticCB).setExtra(getId()); + + if (state == State::Edit) + gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId()); + + gdi.addButton("Stop", (state == State::Create || state == State::Load) ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId()); gdi.popX(); gdi.fillDown(); @@ -704,13 +711,12 @@ void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool c gdi.dropLine(); } - -void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { +void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, State state) { settingsTitle(gdi, "Resultatutskrift / export"); - wstring time = (created && interval <= 0) ? L"10:00" : getTimeMS(interval); - startCancelInterval(gdi, "StartResult", created, IntervalMinute, time); + wstring time = (state == State::Create && interval <= 0) ? L"10:00" : getTimeMS(interval); + startCancelInterval(gdi, "Save", state, IntervalMinute, time); - if (created) { + if (state == State::Create) { oe.getAllClasses(classesToPrint); } @@ -813,6 +819,55 @@ void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { } } +void PrintResultMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); + wstring minute = gdi.getText("Interval"); + int t = convertAbsoluteTimeMS(minute); + + if (t < 2 || t>7200) { + throw meosException("Intervallet mÃ¥ste anges pÃ¥ formen MM:SS."); + } + doExport = gdi.isChecked("DoExport"); + doPrint = gdi.isChecked("DoPrint"); + exportFile = gdi.getText("ExportFile"); + exportScript = gdi.getText("ExportScript"); + + if (!readOnly) { + structuredExport = gdi.isChecked("StructuredExport"); + htmlRefresh = gdi.isChecked("HTMLRefresh") ? t : 0; + + gdi.getSelection("Classes", classesToPrint); + + ListBoxInfo lbi; + if (gdi.getSelectedItem("ListType", lbi)) { + oListParam par; + par.selection = classesToPrint; + par.listCode = EStdListType(lbi.data); + par.pageBreak = gdi.isChecked("PageBreak"); + par.showHeader = gdi.isChecked("ShowHeader"); + par.showInterTimes = gdi.isChecked("ShowInterResults"); + par.splitAnalysis = gdi.isChecked("SplitAnalysis"); + int legNr = gdi.getSelectedItem("LegNumber").first; + if (legNr >= 0) + par.setLegNumberCoded(legNr); + else + par.setLegNumberCoded(0); + + oe.generateListInfo(par, listInfo); + } + } + po.onlyChanged = gdi.isChecked("OnlyChanged"); + pageBreak = gdi.isChecked("PageBreak"); + showHeader = gdi.isChecked("ShowHeader"); + + showInterResult = gdi.isChecked("ShowInterResults"); + splitAnalysis = gdi.isChecked("SplitAnalysis"); + if (doProcess) { + interval = t; + synchronize = true; //To force continuos data sync. + } +} + void PrintResultMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) { if (lock) @@ -876,7 +931,7 @@ void PrintResultMachine::status(gdioutput &gdi) { gdi.fillRight(); gdi.pushX(); - gdi.addString("", 0, name); + AutoMachine::status(gdi); gdi.addString("", 0, listInfo.getName()); gdi.dropLine(); if (doExport) { @@ -903,9 +958,9 @@ void PrintResultMachine::status(gdioutput &gdi) gdi.popX(); } -void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { +void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, State state) { settingsTitle(gdi, "Förvarningsröst"); - startCancelInterval(gdi, "StartPrewarning", created, IntervalNone, L""); + startCancelInterval(gdi, "Save", state, IntervalNone, L""); gdi.addString("", 10, "help:computer_voice"); @@ -930,6 +985,27 @@ void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { gdi.popX(); } +void PrewarningMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); + waveFolder = gdi.getText("WaveFolder"); + gdi.getSelection("Controls", controls); + + oe.synchronizeList(oListId::oLPunchId); + oe.clearPrewarningSounds(); + + controlsSI.clear(); + for (set::iterator it = controls.begin(); it != controls.end(); ++it) { + pControl pc = oe.getControl(*it, false); + if (pc) { + vector n; + pc->getNumbers(n); + controlsSI.insert(n.begin(), n.end()); + } + } + if (doProcess) + synchronizePunches = true; +} + void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) { oe->playPrewarningSounds(waveFolder, controlsSI); @@ -937,7 +1013,7 @@ void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) void PrewarningMachine::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); string info="Förvarning pÃ¥ (SI-kod): "; bool first=true; @@ -968,10 +1044,10 @@ void PrewarningMachine::status(gdioutput &gdi) gdi.popX(); } -void PunchMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { +void PunchMachine::settings(gdioutput &gdi, oEvent &oe, State state) { settingsTitle(gdi, "Test av stämplingsinläsningar"); - wstring time=created ? L"10" : itow(interval); - startCancelInterval(gdi, "StartPunch", created, IntervalSecond, time); + wstring time = state == State::Create ? L"10" : itow(interval); + startCancelInterval(gdi, "Save", state, IntervalSecond, time); gdi.addString("", 10, "help:simulate"); @@ -995,9 +1071,23 @@ void PunchMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { gdi.addButton("GenerateCMP", "Generera testtävling", AutomaticCB); } +void PunchMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); + wstring minute = gdi.getText("Interval"); + int t = _wtoi(minute.c_str()); + + if (t<1 || t>7200) { + throw meosException(L"Ogiltigt antal sekunder: X#" + minute); + } + else { + interval = t; + radio = gdi.getTextNo("Radio"); + } +} + void PunchMachine::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); gdi.fillRight(); gdi.pushX(); if (interval>0){ @@ -1066,15 +1156,15 @@ void PunchMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) #endif } -void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { +void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, State state) { wstring time; if (interval>0) time = itow(interval); - else if (created) + else if (state == State::Create) time = L"30"; settingsTitle(gdi, "Sträcktider / WinSplits"); - startCancelInterval(gdi, "StartSplits", created, IntervalSecond, time); + startCancelInterval(gdi, "Save", state, IntervalSecond, time); gdi.addString("", 0, "Intervall (sekunder). Lämna blankt för att uppdatera när " "tävlingsdata ändras."); @@ -1094,9 +1184,33 @@ void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { } +void SplitsMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); + wstring ivt = gdi.getText("Interval"); + + int iv = gdi.getTextNo("Interval"); + file = gdi.getText("FileName"); + + if (!ivt.empty() && (iv < 1 || iv > 7200)) { + throw meosException(L"Ogiltigt antal sekunder: X#" + gdi.getText("Interval")); + } + + if (file.empty()) { + throw meosException("Filnamnet fÃ¥r inte vara tomt"); + } + + if (doProcess) { + //Try exporting. + oe.exportIOFSplits(oEvent::IOF20, file.c_str(), true, false, + set(), -1, false, true, true, false); + interval = iv; + synchronize = true; + } +} + void SplitsMachine::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); if (!file.empty()) { gdi.fillRight(); gdi.pushX(); @@ -1133,7 +1247,8 @@ void SplitsMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) } void SaveMachine::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); + if (!baseFile.empty()) { gdi.fillRight(); gdi.pushX(); @@ -1165,10 +1280,10 @@ void SaveMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) { } } -void SaveMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { +void SaveMachine::settings(gdioutput &gdi, oEvent &oe, State state) { settingsTitle(gdi, "Säkerhetskopiering"); - wstring time=created ? L"10:00" : getTimeMS(interval); - startCancelInterval(gdi, "StartBackup", created, IntervalMinute, time); + wstring time=state == State::Create ? L"10:00" : getTimeMS(interval); + startCancelInterval(gdi, "Save", state, IntervalMinute, time); int cx = gdi.getCX(); gdi.addInput("BaseFile", baseFile, 32, 0, L"Mapp:"); @@ -1177,8 +1292,8 @@ void SaveMachine::settings(gdioutput &gdi, oEvent &oe, bool created) { gdi.setCX(cx); } -void SaveMachine::saveSettings(gdioutput &gdi) { - +void SaveMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); wstring minute=gdi.getText("Interval"); int t=convertAbsoluteTimeMS(minute); @@ -1193,23 +1308,83 @@ void SaveMachine::saveSettings(gdioutput &gdi) { if (*f.rbegin() != '\\' && *f.rbegin() != '/') f += L"\\"; - wstring sample = f + L"sample.txt"; - ofstream fout(sample.c_str(), ios_base::trunc|ios_base::out); - bool bad = false; - if (fout.bad()) - bad = true; - else { - fout << "foo" << endl; - fout.close(); - bad = fout.bad(); - _wremove(sample.c_str()); - } - if (bad) - throw meosException(L"Ogiltig destination X#" + f); + if (doProcess) { + wstring sample = f + L"sample.txt"; + ofstream fout(sample.c_str(), ios_base::trunc | ios_base::out); + bool bad = false; + if (fout.bad()) + bad = true; + else { + fout << "foo" << endl; + fout.close(); + bad = fout.bad(); + _wremove(sample.c_str()); + } + if (bad) + throw meosException(L"Ogiltig destination X#" + f); + interval = t; + } baseFile = f; - interval = t; } void TabAuto::clearCompetitionData() { } + +Machines AutoMachine::getType(const string &typeStr) { + if (typeStr == "onlineinput") + return Machines::mOnlineInput; + else if (typeStr == "onlineresults") + return Machines::mOnlineResults; + return Machines::Unknown; +} + +string AutoMachine::getDescription(Machines type) { + switch (type) { + case mPrintResultsMachine: + return "Resultatutskrift / export"; + case mPunchMachine: + return "Stämplingstest"; + case mSplitsMachine: + return "Sträcktider (WinSplits)"; + case mPrewarningMachine: + return "Förvarningsröst"; + case mOnlineResults: + return "Resultat online"; + case mOnlineInput: + return "Inmatning online"; + case mSaveBackup: + return "Säkerhetskopiering"; + case mInfoService: + return "Informationsserver"; + case mMySQLReconnect: + return "MySQL reconnect"; + default: + return "???"; + } +} + +string AutoMachine::getTypeString(Machines type) { + switch (type) { + case mPrintResultsMachine: + return "printresult"; + case mPunchMachine: + return "punchtest"; + case mSplitsMachine: + return "splits"; + case mPrewarningMachine: + return "prewarning"; + case mOnlineResults: + return "onlineresults"; + case mOnlineInput: + return "onlineinput"; + case mSaveBackup: + return "backup"; + case mInfoService: + return "infoserver"; + case mMySQLReconnect: + return "reconnect"; + default: + return "???"; + } +} diff --git a/code/TabAuto.h b/code/TabAuto.h index 71c968e..4f59b66 100644 --- a/code/TabAuto.h +++ b/code/TabAuto.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,6 +51,14 @@ enum Machines { class AutoMachine { +public: + + enum class State { + Edit, + Create, + Load + }; + private: int myid; static int uniqueId; @@ -61,21 +69,47 @@ protected: void settingsTitle(gdioutput &gdi, char *title); enum IntervalType {IntervalNone, IntervalMinute, IntervalSecond}; - void startCancelInterval(gdioutput &gdi, char *startCommand, bool created, IntervalType type, const wstring &interval); + void startCancelInterval(gdioutput &gdi, char *startCommand, State state, IntervalType type, const wstring &interval); + + virtual bool hasSaveMachine() const { + return false; + } public: + + virtual void saveMachine(oEvent &oe, const wstring &guiInterval) { + } + + virtual void loadMachine(oEvent &oe, const wstring &name) { + } + + // Return true to auto-remove + virtual bool removeMe() const { + return false; + } + static AutoMachine *getMachine(int id); static void resetGlobalId() {uniqueId = 1;} int getId() const {return myid;} static AutoMachine* construct(Machines); + static Machines getType(const string &typeStr); + static string getDescription(Machines type); + static string getTypeString(Machines type); + string getTypeString() const { return getTypeString(type); } + wstring getMachineName() const { + return machineName.empty() ? L"default" : machineName; + } + void setEditMode(bool em) {editMode = em;} string name; + wstring machineName; DWORD interval; //Interval seconds DWORD timeout; //Timeout (TickCount) bool synchronize; bool synchronizePunches; - virtual void settings(gdioutput &gdi, oEvent &oe, bool created) = 0; - virtual void save(oEvent &oe, gdioutput &gdi) {} + + virtual void settings(gdioutput &gdi, oEvent &oe, State state) = 0; + virtual void save(oEvent &oe, gdioutput &gdi, bool doProcess) = 0; virtual void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) = 0; virtual bool isEditMode() const {return editMode;} virtual void status(gdioutput &gdi) = 0; @@ -119,9 +153,10 @@ public: prm->errorLock = false; return prm; } - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); - void settings(gdioutput &gdi, oEvent &oe, bool created); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; + void settings(gdioutput &gdi, oEvent &oe, State state) final; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; void setHTML(const wstring &file, int timeout) { exportFile = file; @@ -176,10 +211,10 @@ public: return prm; } - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); - void settings(gdioutput &gdi, oEvent &oe, bool created); - void saveSettings(gdioutput &gdi); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; + void settings(gdioutput &gdi, oEvent &oe, State state) final; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; SaveMachine():AutoMachine("Säkerhetskopiera", Machines::mSaveBackup) , saveIter(0) { } @@ -194,10 +229,12 @@ protected: set controls; set controlsSI; public: - void settings(gdioutput &gdi, oEvent &oe, bool created); + void settings(gdioutput &gdi, oEvent &oe, State state); PrewarningMachine *clone() const {return new PrewarningMachine(*this);} - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; + PrewarningMachine():AutoMachine("Förvarningsröst", Machines::mPrewarningMachine) {} friend class TabAuto; }; @@ -210,12 +247,21 @@ protected: wstring timeError; wstring timeReconnect; HANDLE hThread; + bool toRemove = false; + public: - void settings(gdioutput &gdi, oEvent &oe, bool created); + void settings(gdioutput &gdi, oEvent &oe, State state); MySQLReconnect *clone() const {return new MySQLReconnect(*this);} - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; bool stop(); + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final { + } + + bool removeMe() const final { + return toRemove; + } + MySQLReconnect(const wstring &error); virtual ~MySQLReconnect(); friend class TabAuto; @@ -230,9 +276,11 @@ protected: int radio; public: PunchMachine *clone() const {return new PunchMachine(*this);} - void settings(gdioutput &gdi, oEvent &oe, bool created); - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void settings(gdioutput &gdi, oEvent &oe, State state) final; + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; + PunchMachine():AutoMachine("Stämplingsautomat", Machines::mPunchMachine), radio(0) {} friend class TabAuto; }; @@ -246,9 +294,11 @@ protected: int leg; public: SplitsMachine *clone() const {return new SplitsMachine(*this);} - void settings(gdioutput &gdi, oEvent &oe, bool created); - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void settings(gdioutput &gdi, oEvent &oe, State state) final; + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; + SplitsMachine() : AutoMachine("Sträcktider/WinSplits", Machines::mSplitsMachine), leg(-1) {} friend class TabAuto; }; @@ -273,20 +323,22 @@ private: void timerCallback(gdioutput &gdi); void syncCallback(gdioutput &gdi); - void settings(gdioutput &gdi, AutoMachine *sm, Machines type); + void settings(gdioutput &gdi, AutoMachine *sm, AutoMachine::State state, Machines type); protected: void clearCompetitionData(); + bool hasActiveReconnection() const; public: AutoMachine *getMachine(int id); - //AutoMachine *getMachine(const string &name); bool stopMachine(AutoMachine *am); void killMachines(); - void addMachine(const AutoMachine &am) { + + AutoMachine &addMachine(const AutoMachine &am) { machines.push_back(am.clone()); setTimer(machines.back()); + return *machines.back(); } int processButton(gdioutput &gdi, const ButtonInfo &bu); @@ -305,8 +357,10 @@ public: friend class AutoTask; friend void tabForceSync(gdioutput &gdi, pEvent oe); + + static void tabAutoKillMachines(); + static void tabAutoRegister(TabAuto* ta); + static AutoMachine& tabAutoAddMachinge(const AutoMachine& am); + static bool hasActiveReconnectionMachine(); }; -void tabAutoKillMachines(); -void tabAutoRegister(TabAuto *ta); -void tabAutoAddMachinge(const AutoMachine &am); diff --git a/code/TabBase.cpp b/code/TabBase.cpp index a5d376e..de04b7f 100644 --- a/code/TabBase.cpp +++ b/code/TabBase.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabBase.h b/code/TabBase.h index 2eea14b..66a02a2 100644 --- a/code/TabBase.h +++ b/code/TabBase.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabClass.cpp b/code/TabClass.cpp index 412b2f8..c8cae56 100644 --- a/code/TabClass.cpp +++ b/code/TabClass.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -310,89 +310,94 @@ int TabClass::multiCB(gdioutput &gdi, int type, void *data) else if (bi.id == "ShowForking") { if (!checkClassSelected(gdi)) return false; - pClass pc=oe->getClass(ClassId); + pClass pc = oe->getClass(ClassId); if (!pc) throw std::exception("Klassen finns ej."); - vector< vector > forks; - set< pair > unfairLegs; - vector< vector > legOrder; - - pc->checkForking(legOrder, forks, unfairLegs); - gdioutput *gdi_new = getExtraWindow("fork", true); wstring title = lang.tl(L"Forkings for X#" + pc->getName()); if (!gdi_new) gdi_new = createExtraWindow("fork", title, - gdi.scaleLength(1024) ); + gdi.scaleLength(1024)); else gdi_new->setWindowTitle(title); gdi_new->clearPage(false); - gdi_new->addString("", fontMediumPlus, "Forkings"); - for (size_t k = 0; k < forks.size(); k++) { - gdi_new->dropLine(0.7); - wstring ver = itow(k+1) + L": "; - for (size_t j = 0; j < legOrder[k].size(); j++) { - pCourse crs = oe->getCourse(legOrder[k][j]); - if (crs) { - if (j>0) - ver += L", "; - ver += crs->getName(); - } - } - gdi_new->addStringUT(1, ver); - gdi_new->pushX(); - gdi_new->fillRight(); - for (size_t j = 0; j < forks[k].size(); j++) { - wstring ctrl; - if (forks[k][j] > 0) - ctrl += itow(forks[k][j]); - else { - if (j == 0) - ctrl += lang.tl("Start"); - else if (j + 1 == forks[k].size()) - ctrl += lang.tl("MÃ¥l"); - else - ctrl += lang.tl("Växel"); - } - int next = -100; - if (j + 1 < forks[k].size()) { - ctrl += L","; - next = forks[k][j+1]; - } - int prev = j>0 ? forks[k][j-1] : -100; - - bool warn = unfairLegs.count(make_pair(prev, forks[k][j])) != 0;// || - //unfairLegs.count(make_pair(forks[k][j], next)) != 0; - - TextInfo &ti = gdi_new->addStringUT(italicText, ctrl); - if (warn) { - ti.setColor(colorRed); - ti.format = boldText; - } - gdi.setCX(gdi.getCX() - gdi.scaleLength(4)); - } - gdi_new->popX(); - gdi_new->fillDown(); - gdi_new->dropLine(); + if (pc->hasCoursePool()) { + gdi_new->addString("", fontMediumPlus, "Klassen använder banpool"); } + else { + vector< vector > forks; + set< pair > unfairLegs; + vector< vector > legOrder; - if (!unfairLegs.empty()) { - gdi_new->dropLine(); - gdi_new->addString("", fontMediumPlus, "Unfair control legs"); - gdi_new->dropLine(0.5); - for (set< pair >::const_iterator p = unfairLegs.begin(); - p != unfairLegs.end(); ++p) { + pc->checkForking(legOrder, forks, unfairLegs); - wstring f = p->first > 0 ? itow(p->first) : lang.tl("Växel"); - wstring s = p->second > 0 ? itow(p->second) : lang.tl("Växel"); - gdi_new->addStringUT(0, makeDash(f + L" - " + s)); + gdi_new->addString("", fontMediumPlus, "Forkings"); + + for (size_t k = 0; k < forks.size(); k++) { + gdi_new->dropLine(0.7); + wstring ver = itow(k + 1) + L": "; + for (size_t j = 0; j < legOrder[k].size(); j++) { + pCourse crs = oe->getCourse(legOrder[k][j]); + if (crs) { + if (j > 0) + ver += L", "; + ver += crs->getName(); + } + } + gdi_new->addStringUT(1, ver); + gdi_new->pushX(); + gdi_new->fillRight(); + for (size_t j = 0; j < forks[k].size(); j++) { + wstring ctrl; + if (forks[k][j] > 0) + ctrl += itow(forks[k][j]); + else { + if (j == 0) + ctrl += lang.tl("Start"); + else if (j + 1 == forks[k].size()) + ctrl += lang.tl("MÃ¥l"); + else + ctrl += lang.tl("Växel"); + } + int next = -100; + if (j + 1 < forks[k].size()) { + ctrl += L","; + next = forks[k][j + 1]; + } + int prev = j > 0 ? forks[k][j - 1] : -100; + + bool warn = unfairLegs.count(make_pair(prev, forks[k][j])) != 0;// || + //unfairLegs.count(make_pair(forks[k][j], next)) != 0; + + TextInfo &ti = gdi_new->addStringUT(italicText, ctrl); + if (warn) { + ti.setColor(colorRed); + ti.format = boldText; + } + gdi.setCX(gdi.getCX() - gdi.scaleLength(4)); + } + gdi_new->popX(); + gdi_new->fillDown(); + gdi_new->dropLine(); + } + + if (!unfairLegs.empty()) { + gdi_new->dropLine(); + gdi_new->addString("", fontMediumPlus, "Unfair control legs"); + gdi_new->dropLine(0.5); + for (set< pair >::const_iterator p = unfairLegs.begin(); + p != unfairLegs.end(); ++p) { + + wstring f = p->first > 0 ? itow(p->first) : lang.tl("Växel"); + wstring s = p->second > 0 ? itow(p->second) : lang.tl("Växel"); + gdi_new->addStringUT(0, makeDash(f + L" - " + s)); + } } } - gdi_new->dropLine(); gdi_new->addButton("CloseWindow", "Stäng", ClassesCB); gdi_new->refresh(); @@ -1923,7 +1928,37 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data) gdi.refresh(); return 0; } - else if (bi.id=="Split") { + else if (bi.id == "Duplicate") { + save(gdi, true); + if (!checkClassSelected(gdi)) + return false; + pClass pc = oe->getClass(ClassId); + if (!pc) + throw std::exception("Class not found"); + + oClass copyClass(*pc); + copyClass.clearDuplicate(); + wstring name = pc->getName(); + wstring dup = lang.tl(" (kopia)"); + size_t pos = name.find(dup); + wstring base; + if (pos > 0 && pos < string::npos) + base = name.substr(0, pos); + else + base = name; + + name = base + dup; + int cnt = 1; + while (oe->getClass(name) != nullptr) + name = base + dup + L" " + itow(++cnt); + + copyClass.setName(name, true); + pc = oe->addClass(copyClass); + oe->fillClasses(gdi, "Classes", oEvent::extraDrawn, oEvent::filterNone); + selectClass(gdi, pc->getId()); + gdi.setInputFocus("Name", true); + } + else if (bi.id == "Split") { save(gdi, true); if (!checkClassSelected(gdi)) return false; @@ -3463,7 +3498,7 @@ bool TabClass::loadPage(gdioutput &gdi) func.push_back(ButtonData("Merge", "SlÃ¥ ihop klasser...", false)); func.push_back(ButtonData("Split", "Dela klassen...", false)); } - + func.emplace_back("Duplicate", "Duplicera", false); if (showAdvanced && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Vacancy)) { vector rr; @@ -4185,11 +4220,18 @@ void TabClass::selectCourses(gdioutput &gdi, int legNo) { void TabClass::updateFairForking(gdioutput &gdi, pClass pc) const { if (!gdi.hasWidget("FairForking")) return; + BaseInfo *bi = gdi.setText("FairForking", gdi.getText("FairForking"), false); + TextInfo &text = dynamic_cast(*bi); + + if (pc->hasCoursePool()) { + text.setColor(colorBlack); + gdi.setText("FairForking", L"", true); + return; + } + vector< vector > forks; vector< vector > forksC; set< pair > unfairLegs; - BaseInfo *bi = gdi.setText("FairForking", gdi.getText("FairForking"), false); - TextInfo &text = dynamic_cast(*bi); if (pc->checkForking(forksC, forks, unfairLegs)) { text.setColor(colorGreen); gdi.setText("FairForking", lang.tl("The forking is fair."), true); diff --git a/code/TabClass.h b/code/TabClass.h index 80d57f3..598528c 100644 --- a/code/TabClass.h +++ b/code/TabClass.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabClub.cpp b/code/TabClub.cpp index 89c0067..10f87fc 100644 --- a/code/TabClub.cpp +++ b/code/TabClub.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabClub.h b/code/TabClub.h index a6bf1ce..8e9a1d7 100644 --- a/code/TabClub.h +++ b/code/TabClub.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabCompetition.cpp b/code/TabCompetition.cpp index ae74a60..f4290a5 100644 --- a/code/TabCompetition.cpp +++ b/code/TabCompetition.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -157,8 +157,8 @@ bool TabCompetition::save(gdioutput &gdi, bool write) bool TabCompetition::importFile(HWND hWnd, gdioutput &gdi) { vector< pair > ext; - ext.push_back(make_pair(L"xml-data", L"*.xml;*.bu?")); - wstring fileName = gdi.browseForOpen(ext, L"xml"); + ext.push_back(make_pair(L"MeOS-data", L"*.meosxml;*.xml;*.bu?")); + wstring fileName = gdi.browseForOpen(ext, L"meosxml"); if (fileName.empty()) return false; @@ -182,8 +182,8 @@ bool TabCompetition::exportFileAs(HWND hWnd, gdioutput &gdi) { int ix = 0; vector< pair > ext; - ext.push_back(make_pair(L"xml-data", L"*.xml")); - wstring fileName = gdi.browseForSave(ext, L"xml", ix); + ext.push_back(make_pair(L"MeOS-data", L"*.meosxml")); + wstring fileName = gdi.browseForSave(ext, L"meosxml", ix); if (fileName.empty()) return false; @@ -779,7 +779,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data) wstring base = constructBase(L"base", L""); wchar_t newBase[_MAX_PATH]; getUserFile(newBase, base.c_str()); - if (!fileExist(newBase)) + if (!fileExists(newBase)) oe->save(newBase); loadConnectionPage(gdi); @@ -1629,7 +1629,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data) } else if (bi.id == "Cancel"){ loadPage(gdi); - } + } else if (bi.id == "WelcomeOK") { gdi.setFont(oe->getPropertyInt("TextSize", 0), oe->getPropertyString("TextFont", L"Arial")); @@ -2382,7 +2382,7 @@ void TabCompetition::copyrightLine(gdioutput &gdi) const gdi.dropLine(0.4); gdi.fillDown(); - gdi.addString("", 0, makeDash(L"#Copyright © 2007-2020 Melin Software HB")); + gdi.addString("", 0, makeDash(L"#Copyright © 2007-2021 Melin Software HB")); gdi.dropLine(1); gdi.popX(); @@ -2412,7 +2412,7 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const gdi.dropLine(1.5); gdi.setCX(gdi.getCX() + gdi.scaleLength(20)); - gdi.addStringUT(1, makeDash(L"Copyright © 2007-2020 Melin Software HB")); + gdi.addStringUT(1, makeDash(L"Copyright © 2007-2021 Melin Software HB")); gdi.dropLine(); gdi.addStringUT(10, "The database connection used is MySQL++\nCopyright " "(c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by MySQL AB," @@ -2764,7 +2764,7 @@ void TabCompetition::textSizeControl(gdioutput &gdi) const } int TabCompetition::getOrganizer(bool updateEvent) { - wstring apikey = oe->getPropertyStringDecrypt("apikey", ""); + wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", "")); if (apikey.empty()) return 0; if (!isAscii(apikey)) @@ -2837,7 +2837,7 @@ int TabCompetition::getOrganizer(bool updateEvent) { } void TabCompetition::getAPIKey(vector< pair > &key) const { - wstring apikey = oe->getPropertyStringDecrypt("apikey", ""); + wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", "")); if (apikey.empty() || organizorId == 0) throw std::exception("Internal error"); @@ -2989,7 +2989,7 @@ void TabCompetition::getEventorCmpData(gdioutput &gdi, int id, pw.setProgress(1); vector< pair > key; - wstring apikey = oe->getPropertyStringDecrypt("apikey", ""); + wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", "")); key.push_back(pair(L"ApiKey", apikey)); gdi.fillRight(); diff --git a/code/TabCompetition.h b/code/TabCompetition.h index 71df33f..f8c0ad3 100644 --- a/code/TabCompetition.h +++ b/code/TabCompetition.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabControl.cpp b/code/TabControl.cpp index deacbaf..2557c5d 100644 --- a/code/TabControl.cpp +++ b/code/TabControl.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -108,10 +108,10 @@ void TabControl::selectControl(gdioutput &gdi, pControl pc) gdi.enableEditControls(true); oControl::ControlStatus st = pc->getStatus(); - if (st == oControl::StatusRogaining || st == oControl::StatusNoTiming) + if (st == oControl::StatusRogaining || st == oControl::StatusNoTiming || st == oControl::StatusBadNoTiming) gdi.disableInput("MinTime"); - if (st == oControl::StatusNoTiming) + if (st == oControl::StatusNoTiming || st == oControl::StatusBadNoTiming) gdi.disableInput("TimeAdjust"); if (gdi.hasWidget("Point") && st != oControl::StatusRogaining) @@ -164,7 +164,7 @@ void TabControl::save(gdioutput &gdi) pc->setStatus(oControl::ControlStatus(gdi.getSelectedItem("Status").first)); pc->setTimeAdjust(gdi.getText("TimeAdjust")); if (pc->getStatus() != oControl::StatusRogaining) { - if (pc->getStatus() != oControl::StatusNoTiming) + if (pc->getStatus() != oControl::StatusNoTiming && pc->getStatus() != oControl::StatusBadNoTiming) pc->setMinTime(gdi.getText("MinTime")); pc->setRogainingPoints(0); } @@ -416,9 +416,9 @@ int TabControl::controlCB(gdioutput &gdi, int type, void *data) selectControl(gdi, pc); } else if (bi.id == "Status" ) { - gdi.setInputStatus("MinTime", bi.data != oControl::StatusRogaining && bi.data != oControl::StatusNoTiming, true); + gdi.setInputStatus("MinTime", bi.data != oControl::StatusRogaining && bi.data != oControl::StatusNoTiming && bi.data != oControl::StatusBadNoTiming, true); gdi.setInputStatus("Point", bi.data == oControl::StatusRogaining, true); - gdi.setInputStatus("TimeAdjust", bi.data != oControl::StatusNoTiming, true); + gdi.setInputStatus("TimeAdjust", bi.data != oControl::StatusNoTiming && bi.data != oControl::StatusBadNoTiming, true); } } else if (type==GUI_CLEAR) { diff --git a/code/TabControl.h b/code/TabControl.h index aeb8dd6..d2c88d6 100644 --- a/code/TabControl.h +++ b/code/TabControl.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabCourse.cpp b/code/TabCourse.cpp index c758f48..8aac547 100644 --- a/code/TabCourse.cpp +++ b/code/TabCourse.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabCourse.h b/code/TabCourse.h index 863c658..a1ba2fd 100644 --- a/code/TabCourse.h +++ b/code/TabCourse.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabList.cpp b/code/TabList.cpp index 99e3adf..a1efe8b 100644 --- a/code/TabList.cpp +++ b/code/TabList.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -543,7 +543,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data) if (!htmlTarget.empty()) { prm.setHTML(htmlTarget, currentList.getParam().timePerPage / 1000); } - tabAutoAddMachinge(prm); + TabAuto::tabAutoAddMachinge(prm); dynamic_cast(gdi.getTabs().get(TAutoTab))->loadPage(gdi, true); } else if (bi.id == "WideFormat") { diff --git a/code/TabList.h b/code/TabList.h index 49624e1..3775827 100644 --- a/code/TabList.h +++ b/code/TabList.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabMulti.cpp b/code/TabMulti.cpp index 340fd2e..f88677c 100644 --- a/code/TabMulti.cpp +++ b/code/TabMulti.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabMulti.h b/code/TabMulti.h index acf0aab..50e578a 100644 --- a/code/TabMulti.h +++ b/code/TabMulti.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabRunner.cpp b/code/TabRunner.cpp index ac02777..e102f90 100644 --- a/code/TabRunner.cpp +++ b/code/TabRunner.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabRunner.h b/code/TabRunner.h index 4acad7a..2389ba7 100644 --- a/code/TabRunner.h +++ b/code/TabRunner.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabSI.cpp b/code/TabSI.cpp index cb58626..4d7ff02 100644 --- a/code/TabSI.cpp +++ b/code/TabSI.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,8 @@ #include #include +#include + #include #include "oEvent.h" @@ -134,7 +136,83 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) allowControl = gdi.isChecked(bi.id); else if (bi.id == "AllowFinish") allowFinish = gdi.isChecked(bi.id); - if (bi.id == "ClearMemory") { + else if (bi.id == "PlaySound") { + oe->setProperty("PlaySound", gdi.isChecked(bi.id) ? 1 : 0); + } + else if (bi.id == "SoundChoice") { + gdi.disableInput("SoundChoice"); + gdi.setRestorePoint("Sound"); + gdi.dropLine(); + gdi.fillDown(); + gdi.addString("", fontMediumPlus, "help:selectsound"); + gdi.dropLine(0.5); + gdi.pushX(); + gdi.fillRight(); + + auto addSoundWidget = [&gdi, this](const wchar_t *name, SND type, const wstring &label) { + string nname = gdioutput::narrow(name); + gdi.addInput(nname, oe->getPropertyString(nname.c_str(), L""), 32, nullptr, label); + gdi.dropLine(0.8); + gdi.addButton("BrowseSound", "Bläddra...", SportIdentCB).setExtra(name); + gdi.addButton("TestSound", "Testa", SportIdentCB).setExtra(int(type)); + gdi.dropLine(3); + gdi.popX(); + }; + + addSoundWidget(L"SoundOK", SND::OK, L"Status OK:"); + addSoundWidget(L"SoundNotOK", SND::NotOK, L"Status inte OK (röd utgÃ¥ng):"); + addSoundWidget(L"SoundLeader", SND::Leader, L"Ny ledare i klassen:"); + addSoundWidget(L"SoundAction", SND::ActionNeeded, L"Ã…tgärd krävs:"); + + gdi.addButton("CloseSound", "OK", SportIdentCB); + gdi.popX(); + gdi.dropLine(3); + gdi.scrollToBottom(); + gdi.refresh(); + /* + fn = oe->getPropertyString("SoundOK", L""); + res = 50; + break; + case SND::NotOK: + fn = oe->getPropertyString("SoundNotOK", L""); + res = 52; + break; + case SND::Leader: + fn = oe->getPropertyString("SoundLeader", L""); + res = 51; + break; + case SND::ActionNeeded: + fn = oe->getPropertyString("SoundAction", L""); + + + */ + } + else if (bi.id == "BrowseSound") { + vector< pair > ext; + ext.push_back(make_pair(L"Ljud (wav)", L"*.wav")); + + wstring file = gdi.browseForOpen(ext, L"wav"); + if (!file.empty()) { + wchar_t *type = bi.getExtra(); + string name = gdioutput::narrow(type); + gdi.setText(name, file); + oe->setProperty(name.c_str(), file); + } + } + else if (bi.id == "SoundOK" || bi.id == "SoundNotOK" || + bi.id == "SoundLeader" || bi.id == "SoundAction") { + oe->setProperty(bi.id.c_str(), bi.text); + } + else if (bi.id == "TestSound") { + oe->setProperty("PlaySound", 1); + gdi.check(bi.id, true); + playReadoutSound(SND(bi.getExtraInt())); + } + else if (bi.id == "CloseSound") { + gdi.restore("Sound", true); + gdi.enableInput("SoundChoice"); + } + else if (bi.id == "ClearMemory") { if (gdi.ask(L"Do you want to clear the card memory?")) { savedCards.clear(); loadPage(gdi); @@ -1678,7 +1756,7 @@ void TabSI::showReadCards(gdioutput &gdi, vector &cards) SportIdent &TabSI::getSI(const gdioutput &gdi) { if (!gSI) { HWND hWnd=gdi.getHWNDMain(); - gSI = new SportIdent(hWnd, 0, gEvent->getPropertyInt("ReadVoltageExp", 0) != 0); + gSI = new SportIdent(hWnd, 0, true); } return *gSI; } @@ -1787,11 +1865,19 @@ bool TabSI::loadPage(gdioutput &gdi) { gdi.selectItemByData("ReadType", mode); gdi.dropLine(-0.1); - gdi.addButton("LockFunction", "LÃ¥s funktion...", SportIdentCB); + gdi.addButton("LockFunction", "LÃ¥s funktion", SportIdentCB); readoutFunctionX = gdi.getCX(); readoutFunctionY = gdi.getCY(); gdi.dropLine(0.3); + gdi.addCheckbox("PlaySound", "Ljud", SportIdentCB, oe->getPropertyInt("PlaySound", 1) != 0, + "Spela upp ett ljud för att indikera resultatet av brickavläsningen."); + gdi.dropLine(-0.3); + + gdi.addButton("SoundChoice", "Ljudval...", SportIdentCB); + + gdi.dropLine(0.3); + gdi.addString("Allow", 0, "TillÃ¥t:"); gdi.addCheckbox("AllowStart", "Start", SportIdentCB, allowStart); gdi.addCheckbox("AllowControl", "Radio", SportIdentCB, allowControl); @@ -1883,6 +1969,8 @@ void TabSI::updateReadoutFunction(gdioutput &gdi) { gdi.hideWidget("AllowStart", hide); gdi.hideWidget("AllowControl", hide); gdi.hideWidget("AllowFinish", hide); + gdi.hideWidget("SoundChoice", hide); + gdi.hideWidget("PlaySound", hide); } void InsertSICard(gdioutput &gdi, SICard &sic) @@ -2054,6 +2142,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic) return; } + gEvent->synchronizeList({ oListId::oLCardId, oListId::oLRunnerId }); if (sic.punchOnly) { @@ -2092,6 +2181,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic) else { CardQueue.push_back(sic); gdi.addInfoBox("SIREAD", L"info:readout_action#" + gEvent->getCurrentTimeS()+L"#"+itow(sic.CardNumber), 0, SportIdentCB); + playReadoutSound(SND::ActionNeeded); return; } } @@ -2099,8 +2189,10 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic) if (!readBefore) { if (r && r->getClassId(false) && !sameCardNewRace) processCard(gdi, r, sic, true); - else + else { processUnmatched(gdi, sic, true); + playReadoutSound(SND::ActionNeeded); + } } else gdi.addInfoBox("SIREAD", L"Brickan redan inläst.", 0, SportIdentCB); @@ -2126,6 +2218,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic) name = itow(sic.CardNumber) + name; CardQueue.push_back(sic); gdi.addInfoBox("SIREAD", L"info:readout_queue#" + gEvent->getCurrentTimeS() + L"#" + name); + playReadoutSound(SND::ActionNeeded); return; } @@ -2166,6 +2259,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic) gdi.scrollToBottom(); gdi.refresh(); activeSIC.clear(0); + playReadoutSound(SND::ActionNeeded); checkMoreCardsInQueue(gdi); return; } @@ -2422,7 +2516,7 @@ bool TabSI::processUnmatched(gdioutput &gdi, const SICard &csic, bool silent) gdi.addInfoBox("SIINFO", L"#" + info, 10000); } gdi.makeEvent("DataUpdate", "sireadout", 0, 0, true); - + playReadoutSound(SND::ActionNeeded); checkMoreCardsInQueue(gdi); return true; } @@ -2619,6 +2713,11 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool runner->getTeam()->getLegPlaceS(runner->getLegNumber(), false) : runner->getPlaceS(); + if (placeS == L"1") + playReadoutSound(SND::Leader); + else + playReadoutSound(SND::OK); + if (!silent) { gdi.fillDown(); //gdi.dropLine(); @@ -2651,6 +2750,8 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool else { wstring msg=lang.tl(L"Status: ") + runner->getStatusS(true, true); + playReadoutSound(SND::NotOK); + if (!MP.empty()) { msg=msg + L", ("; vector::iterator it; @@ -4258,7 +4359,49 @@ void TabSI::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) { gdi.TabFocus(1); } - bool TabSI::showDatabase() const { return useDatabase && oe->useRunnerDb(); } +void TabSI::playReadoutSound(SND type) { + if (!oe->getPropertyInt("PlaySound", 0)) + return; + int res = -1; + wstring fn; + switch (type) { + case SND::OK: + fn = oe->getPropertyString("SoundOK", L""); + res = 50; + break; + case SND::NotOK: + fn = oe->getPropertyString("SoundNotOK", L""); + res = 52; + break; + case SND::Leader: + fn = oe->getPropertyString("SoundLeader", L""); + res = 51; + break; + case SND::ActionNeeded: + fn = oe->getPropertyString("SoundAction", L""); + res = 53; + break; + } + + if (checkedSound.count(fn) || (!fn.empty() && fileExists(fn))) { + playSoundFile(fn); + checkedSound.insert(fn); + } + else { + playSoundResource(res); + } +} + +void TabSI::playSoundResource(int res) const { + PlaySound(MAKEINTRESOURCE(res), GetModuleHandle(nullptr), SND_RESOURCE| SND_ASYNC); + //OutputDebugString((L"Play: " + itow(res)).c_str()); + +} + +void TabSI::playSoundFile(const wstring& file) const { + PlaySound(file.c_str(), nullptr, SND_FILENAME | SND_ASYNC); + //OutputDebugString(file.c_str()); +} diff --git a/code/TabSI.h b/code/TabSI.h index 9f8a299..536deb0 100644 --- a/code/TabSI.h +++ b/code/TabSI.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,6 +68,17 @@ private: list< pair > printPunchRunnerIdQueue; void addToPrintQueue(pRunner r); + enum class SND { + OK, + Leader, + NotOK, + ActionNeeded + }; + + set checkedSound; + + void playReadoutSound(SND type); + vector punches; vector cards; vector filterDate; @@ -206,6 +217,8 @@ private: int readoutFunctionX = 0; int readoutFunctionY = 0; + void playSoundResource(int res) const; + void playSoundFile(const wstring& file) const; protected: void clearCompetitionData(); diff --git a/code/TabSpeaker.cpp b/code/TabSpeaker.cpp index 9b70e6a..52b3fc0 100644 --- a/code/TabSpeaker.cpp +++ b/code/TabSpeaker.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1102,7 +1102,7 @@ bool TabSpeaker::loadPage(gdioutput &gdi) { if (getExtraWindows().size() == 1) { wstring sf = getSpeakerSettingsFile(); - if (fileExist(sf.c_str())) { + if (fileExists(sf)) { if ((cx + db) > basex && (cx + db + bw) >= limitX) { cx = basex; db = 0; cy += gdi.getButtonHeight() + 4; diff --git a/code/TabSpeaker.h b/code/TabSpeaker.h index ab66693..eb89905 100644 --- a/code/TabSpeaker.h +++ b/code/TabSpeaker.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TabTeam.cpp b/code/TabTeam.cpp index 88be705..0e0d505 100644 --- a/code/TabTeam.cpp +++ b/code/TabTeam.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1908,13 +1908,17 @@ void TabTeam::processChangeRunner(gdioutput &gdi, pTeam t, int leg, pRunner r) { void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) { vector mp; bool removeAnnonumousTeamMember = false; - + int crsIdR = r->getCourseId(); + int crsIdROld = oldR ? oldR->getCourseId() : 0; + if (r->getTeam()) { pTeam otherTeam = r->getTeam(); int otherLeg = r->getLegNumber(); otherTeam->setRunner(otherLeg, oldR, true); - if (oldR) + if (oldR) { + oldR->setCourseId(crsIdR); oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update); + } otherTeam->checkValdParSetup(); otherTeam->apply(oBase::ChangeType::Update, nullptr); otherTeam->synchronize(true); @@ -1927,11 +1931,13 @@ void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) { else oldR->setClassId(r->getClassId(false), true); removeAnnonumousTeamMember = oldR->isAnnonumousTeamMember(); + oldR->setCourseId(crsIdR); oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update); oldR->synchronize(true); } t->setRunner(leg, r, true); + r->setCourseId(crsIdROld); r->evaluateCard(true, mp, 0, oBase::ChangeType::Update); t->checkValdParSetup(); t->apply(oBase::ChangeType::Update, nullptr); diff --git a/code/TabTeam.h b/code/TabTeam.h index a584f90..ab97507 100644 --- a/code/TabTeam.h +++ b/code/TabTeam.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/Table.cpp b/code/Table.cpp index 7f4ed5f..7c67d84 100644 --- a/code/Table.cpp +++ b/code/Table.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -90,10 +90,8 @@ Table::~Table(void) } void Table::clearCellSelection(gdioutput *gdi) { - upperRow = -1; - lowerRow = -1; - upperCol = -1; - lowerCol = -1; + sel.reset(); + selScreen.reset(); if (gdi) { HDC hDC = GetDC(gdi->getHWNDTarget()); clearSelectionBitmap(gdi, hDC); @@ -183,6 +181,7 @@ void Table::addRow(int rowId, oBase *object) return; } + dataRowToIndex.clear(); TableRow tr(nTitles, object); tr.height=rowHeight; tr.id = rowId; @@ -244,7 +243,9 @@ void Table::filter(int col, const wstring &filt, bool forceFilter) if (filt==oldFilter && (!forceFilter || filt.empty())) return; - else if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) { + dataRowToIndex.clear(); + + if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) { if (sortIndex.empty()) return; //Filter more... @@ -252,6 +253,7 @@ void Table::filter(int col, const wstring &filt, bool forceFilter) baseIndex[0]=sortIndex[0]; baseIndex[1]=sortIndex[1]; swap(baseIndex, sortIndex); + sortIndex.reserve(baseIndex.size()); Titles[col].filter=filt; } else { @@ -293,16 +295,20 @@ bool Table::compareRow(int indexA, int indexB) const { //return Data[indexA].key < Data[indexB].key; } -void Table::sort(int col) +void Table::sort(int col, bool forceDirection) { + int origCol = col; bool reverse = col < 0; if (col < 0) col = -(10+col); if (sortIndex.size()<2) return; + + dataRowToIndex.clear(); + currentSortColumn=col; - if (PrevSort!=col && PrevSort!=-(10+col)) { + if (forceDirection || (PrevSort!=col && PrevSort!=-(10+col))) { if (Titles[col].isnumeric) { bool hasDeci = false; for(size_t k=2; kTables.empty()) return 0; @@ -451,7 +457,7 @@ int TablesCB(gdioutput *gdi, int type, void *data) { gdi->refresh(); return 0; -} +}*/ void Table::getDimension(gdioutput &gdi, int &dx, int &dy, bool filteredResult) const { @@ -507,7 +513,7 @@ void Table::restoreCell(HDC hDC, const TableCell &cell) } } -void Table::moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int dy) +void Table::moveCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, int dx, int dy) { RECT rc=cell.absPos; rc.left+=dx; rc.right+=dx; @@ -526,7 +532,7 @@ void Table::moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int dx=0; dy=0; } - highlightCell(hDC, gdi, cell, RGB(255, 0,0), dx, dy); + highlightCell(hDC, gdi, col, cell, RGB(255, 0,0), dx, dy); } void Table::stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy) @@ -554,94 +560,94 @@ void Table::stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy) bool Table::mouseMove(gdioutput &gdi, int x, int y) { - int row=getRow(y); - int col=-1; + int row = getRow(y); + int col = -1; - if (row!=-1) - col=getColumn(x); + if (row != -1) + col = getColumn(x); - HWND hWnd=gdi.getHWNDTarget(); + HWND hWnd = gdi.getHWNDTarget(); - if (colSelected!=-1) { - TableCell &cell=Data[0].cells[colSelected]; - HDC hDC=GetDC(hWnd); + if (colSelected != -1) { + TableCell &cell = Data[0].cells[colSelected]; + HDC hDC = GetDC(hWnd); restoreCell(hDC, cell); - if (col!=highCol) { - if (unsigned(highRow)=rc.right || yrc.bottom) - row=-1; + if (x <= rc.left || x >= rc.right || yrc.bottom) + row = -1; bool ret = false; if (startSelect) { int c = getColumn(x, true); if (c != -1) - upperCol = c; + sel.upperCol = c, selScreen.upperCol = -1; c = getRow(y, true); - if (c != -1 && c>=0) { - upperRow = max(c, 2); + if (c != -1 && c >= 0) { + sel.upperRow = max(c, 2), selScreen.upperRow = -1; } - HDC hDC=GetDC(hWnd); - if (unsigned(highRow)=0 && col>=0) { - POINT pt = {x, y}; + else if (row >= 0 && col >= 0) { + POINT pt = { x, y }; ClientToScreen(hWnd, &pt); HWND hUnder = WindowFromPoint(pt); if (hUnder == hWnd) { //int index=sortIndex[row].index; - TableRow &trow=Data[row]; - TableCell &cell=trow.cells[col]; + TableRow &trow = Data[row]; + TableCell &cell = trow.cells[col]; - if (highRow!=row || highCol!=col) { + if (highRow != row || highCol != col) { - HDC hDC=GetDC(hWnd); + HDC hDC = GetDC(hWnd); - if (unsigned(highRow)= 2) { DWORD c; if (cell.canEdit) - c=RGB(240, 240, 150); + c = RGB(240, 240, 150); else - c=RGB(240, 200, 140); + c = RGB(240, 200, 140); - highlightCell(hDC, gdi, cell, c, 0,0); + highlightCell(hDC, gdi, col, cell, c, 0, 0); } ReleaseDC(hWnd, hDC); SetCapture(hWnd); - highCol=col; - highRow=row; + highCol = col; + highRow = row; } ret = true; } @@ -650,33 +656,33 @@ bool Table::mouseMove(gdioutput &gdi, int x, int y) if (ret) return true; - if (unsigned(highRow)(data); Table &t = gdi->getTable(); @@ -744,9 +750,18 @@ bool Table::keyCommand(gdioutput &gdi, KeyCommandCode code) { exportClipboard(gdi); else if (code == KC_PASTE && hEdit == 0) { importClipboard(gdi); - }else if (code == KC_DELETE && hEdit == 0) { + } + else if (code == KC_DELETE && hEdit == 0) { deleteSelection(gdi); } + else if (code == KC_MARKALL && hEdit == 0) { + markAll(true); + gdi.refresh(); + } + else if (code == KC_CLEARALL && hEdit == 0) { + markAll(false); + gdi.refresh(); + } else if (code == KC_REFRESH) { gdi.setWaitCursor(true); update(); @@ -858,14 +873,11 @@ bool Table::mouseLeftDown(gdioutput &gdi, int x, int y) { colSelected=highCol; startX=x; startY=y; - //sort(highCol); - //gdi.refresh(); - //mouseMove(gdi, x, y); } else if (highRow==1) { - //filter(highCol, "lots"); + showFilter(gdi); + /* RECT rc=Data[1].cells[columns[0]].absPos; - //rc.right=rc.left+tableWidth; editRow=highRow; editCol=highCol; @@ -877,18 +889,158 @@ bool Table::mouseLeftDown(gdioutput &gdi, int x, int y) { SendMessage(hEdit, EM_SETSEL, 0, -1); SetFocus(hEdit); SendMessage(hEdit, WM_SETFONT, (WPARAM) gdi.getGUIFont(), 0); - gdi.refresh(); + gdi.refresh();*/ } else { SetFocus(gdi.getHWNDTarget()); SetCapture(gdi.getHWNDTarget()); - lowerCol = getColumn(x); - lowerRow = getRow(y); + sel.lowerCol = getColumn(x), selScreen.lowerCol = -1; + sel.lowerRow = getRow(y), selScreen.lowerRow = -1; startSelect = true; } return false; } +void Table::showFilter(gdioutput &gdi) { + RECT rc = Data[1].cells[columns[0]].absPos; + editRow = 1; + editCol = highCol; + + hEdit = CreateWindowEx(0, L"EDIT", Titles[highCol].filter.c_str(), + WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | WS_BORDER, + rc.left + 105, rc.top, tableWidth - 105, (rc.bottom - rc.top - 1), gdi.getHWNDTarget(), + 0, hInst, 0); + drawFilterLabel = true; + SendMessage(hEdit, EM_SETSEL, 0, -1); + SetFocus(hEdit); + SendMessage(hEdit, WM_SETFONT, (WPARAM)gdi.getGUIFont(), 0); + gdi.refresh(); + +} + +bool Table::mouseRightDown(gdioutput &gdi, int x, int y) { + //partialCell = true; + //clearCellSelection(&gdi); + + if (!destroyEditControl(gdi)) + return false; + + if (highRow == 0) { + colSelected = highCol; + } +// lowerCol = getColumn(x); +// lowerRow = getRow(y); + + return false; +} + +bool Table::mouseRightUp(gdioutput &gdi, int x, int y) { + + if (highRow == 0 && colSelected == highCol) { + colSelected = -1; + + vector> menu; + menu.emplace_back(L"Sortera stigande", 1); + menu.emplace_back(L"Sortera fallande", 2); + menu.emplace_back(L"", 0); + menu.emplace_back(L"Markera kolumn", 3); + menu.emplace_back(L"Filtrera", 5); + menu.emplace_back(L"Dölj", 4); + + int res = gdi.popupMenu(x, y, menu); + + switch (res) { + case 2: { + sort(-(highCol+10), true); + gdi.refresh(); + break; + } + case 1: { + sort(highCol, true); + gdi.refresh(); + break; + } + case 3: { + int col = highCol; + if (isFullColumnSelected()) { + sel.upperCol = max({ sel.upperCol, sel.lowerCol, col }); + sel.lowerCol = min({ sel.upperCol, sel.lowerCol, col }); + } + else { + sel.upperCol = sel.lowerCol = col; + } + if (sortIndex.size() > 2) { + sel.upperRow = sortIndex[2].index; + sel.lowerRow = sortIndex[sortIndex.size()-1].index; + } + selScreen.reset(); + gdi.refresh(); + break; + } + case 4: + columns.erase(find(columns.begin(), columns.end(), highCol)); + doAutoSelectColumns = false; + gdi.refresh(); + break; + case 5: + showFilter(gdi); + break; + default: + break; + } + /*POINT pt; + pt.x = x; + pt.y = y; + ClientToScreen(gdi.getHWNDTarget(), &pt); + + HMENU hm = CreatePopupMenu(); + AppendMenu(hm, MF_STRING, 1, lang.tl("Sortera stigande").c_str()); + AppendMenu(hm, MF_STRING, 2, L"Select"); + int res = TrackPopupMenuEx(hm, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + pt.x, pt.y, gdi.getHWNDTarget(), nullptr); + + DestroyMenu(hm);*/ + } + // lowerCol = getColumn(x); + // lowerRow = getRow(y); + + return false; +} + +bool Table::isFullColumnSelected() const { + if (sortIndex.size() < 2) + return false; + return (sel.upperRow == sortIndex[2].index && + sel.lowerRow == sortIndex[sortIndex.size() - 1].index) || + (sel.lowerRow == sortIndex[2].index && + sel.upperRow == sortIndex[sortIndex.size() - 1].index); +} + +void Table::markAll(bool doSelect) { + if (doSelect) { + sel.lowerCol = columns.front(); + sel.upperCol = columns.back(); + if (sortIndex.size() > 2) { + sel.upperRow = sortIndex[2].index; + sel.lowerRow = sortIndex.back().index; + } + selScreen.reset(); + } + else { + sel.reset(); + selScreen.reset(); + } +} + +bool Table::mouseMidDown(gdioutput &gdi, int x, int y) { + return false; +} + +bool Table::mouseMidUp(gdioutput &gdi, int x, int y) { + return false; +} + + bool Table::mouseLeftDblClick(gdioutput &gdi, int x, int y) { clearCellSelection(&gdi); @@ -1061,21 +1213,21 @@ void drawSymbol(gdioutput &gdi, HDC hDC, int height, } -void Table::highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD color, int dx, int dy) +void Table::highlightCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, DWORD color, int dx, int dy) { SelectObject(hDC, GetStockObject(DC_BRUSH)); SelectObject(hDC, GetStockObject(NULL_PEN)); SetDCBrushColor(hDC, color); - RECT rc=cell.absPos; - rc.left+=dx; - rc.right+=dx; - rc.top+=dy; - rc.bottom+=dy; + RECT rc = cell.absPos; + rc.left += dx; + rc.right += dx - 1; + rc.top += dy; + rc.bottom += dy; - Rectangle(hDC, rc.left+1, rc.top, - rc.right+2, rc.bottom); + Rectangle(hDC, rc.left + 2, rc.top+2, + rc.right + 1, rc.bottom-1); TextInfo ti; @@ -1090,9 +1242,13 @@ void Table::highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD else { gdi.formatString(ti, hDC); SetBkMode(hDC, TRANSPARENT); - rc.left+=4; - rc.top+=2; - DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_LEFT|DT_NOPREFIX); + rc.left += 4; + rc.top += 2; + rc.right -= 2; + if (Titles[col].formatRight) + DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_RIGHT | DT_NOPREFIX); + else + DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_LEFT | DT_NOPREFIX); } } @@ -1106,7 +1262,7 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen) table_yp=dy-gdi.OffsetY; if (currentSortColumn==-1) - sort(0); + sort(0, false); int wi, he; getDimension(gdi, wi, he, true); @@ -1129,7 +1285,7 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen) xpos[0]=dx-gdi.OffsetX; for (size_t i=1;i<=columns.size();i++) xpos[i]=xpos[i-1]+Titles[columns[i-1]].width+1; - + //xxx //Find first and last visible column while(firstCol= rLow && k1 <= rHigh && cLow !=-1 && cHigh != -1) { + Rectangle(hDC, max(xpos[firstCol], int(screen.left)), ydraw, + min(xpos[lastCol] + 1, int(screen.right + 2)), ydraw + rowHeight); + + + //wstring w = L"cL" + itow(cLow) + L", cH" + itow(cHigh) + L"\n"; + // OutputDebugString(w.c_str()); + + int lowHLC = max(cLow, firstCol); + int maxHLC = min(cHigh + 1, lastCol); + if (lowHLC < maxHLC) { + setBG(true); + + Rectangle(hDC, max(xpos[lowHLC], int(screen.left)), ydraw, + min(xpos[maxHLC] + 1, int(screen.right + 2)), ydraw + rowHeight); + + setBG(false); + } + } + else { + Rectangle(hDC, max(xpos[firstCol], int(screen.left)), ydraw, + min(xpos[lastCol] + 1, int(screen.right + 2)), ydraw + rowHeight); + } + SelectObject(hDC, GetStockObject(DC_PEN)); const int cy=yp+rowHeight-gdi.OffsetY-1; MoveToEx(hDC, xp, cy, 0); @@ -1351,7 +1559,6 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen) LineTo(hDC, xp, may); } - SelectObject(hDC, GetStockObject(NULL_BRUSH)); SelectObject(hDC, GetStockObject(DC_PEN)); SetDCPenColor(hDC, RGB(64,64,64)); @@ -1363,10 +1570,10 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen) SetDCPenColor(hDC, RGB(64,64,64)); Rectangle(hDC, dx-gdi.OffsetX-2, dy-gdi.OffsetY-2, dx+tableWidth-gdi.OffsetX+2, dy+tableHeight-gdi.OffsetY+2); - drawSelection(gdi, hDC, true); + if (!startSelect) + drawSelection(gdi, hDC, true); } - TableCell &Table::getCell(int row, int col) const { if (size_t(row) >= sortIndex.size()) throw std::exception("Index out of range"); @@ -1417,22 +1624,31 @@ void Table::restoreSelection(gdioutput &gdi, HDC hDC) { void Table::drawSelection(gdioutput &gdi, HDC hDC, bool forceDraw) { bool modified = false; - if (lowerColOld != lowerCol || upperCol != upperColOld || - lowerRow != lowerRowOld || upperRow != upperRowOld) { + if (forceDraw) { + partialCell = false; + } + else if (sel != oldSel) { modified = true; restoreSelection(gdi, hDC); } - if (lowerCol != -1 && upperCol != -1 && - lowerRow != -1 && upperRow != -1 && - (forceDraw || modified)) { - TableCell &c1 = Data[lowerRow].cells[lowerCol]; - TableCell &c2 = Data[upperRow].cells[upperCol]; + if (!sel.empty() && (forceDraw || modified)) { + int rh, rl, ch, cl; + getRowRange(rl, rh); + getColRange(cl, ch); + rl = max(rl, 2); + rh = max(rh, 2); + + if (isFullColumnSelected()) { + rl = 0; + } + RECT rc; - rc.top = min(c1.absPos.top, c2.absPos.top) + gdi.OffsetY; - rc.left = min(c1.absPos.left, c2.absPos.left) + gdi.OffsetX; - rc.right = max(c1.absPos.right, c2.absPos.right) + 1 + gdi.OffsetX; - rc.bottom = max(c1.absPos.bottom, c2.absPos.bottom) + gdi.OffsetY; + rc.left = xpos[cl] + gdi.OffsetX; + rc.right = xpos[ch + 1] + gdi.OffsetX; + + rc.top = table_yp + rowHeight * (rl + 1) + gdi.OffsetY; + rc.bottom = table_yp + rowHeight * (rh + 2) + gdi.OffsetY; if (modified) { int cx=rc.right-rc.left + 1; @@ -1462,14 +1678,14 @@ void Table::drawSelection(gdioutput &gdi, HDC hDC, bool forceDraw) { SelectObject(hDC, GetStockObject(NULL_BRUSH)); SelectObject(hDC, GetStockObject(DC_PEN)); - SetDCPenColor(hDC, RGB(0,0, 128)); + SetDCPenColor(hDC, RGB(50, 50, 128)); Rectangle(hDC, rc.left - gdi.OffsetX, rc.top - gdi.OffsetY, rc.right - gdi.OffsetX, rc.bottom - gdi.OffsetY); + SetDCPenColor(hDC, RGB(80, 60, 170)); + Rectangle(hDC, rc.left - gdi.OffsetX+1, rc.top - gdi.OffsetY+1, + rc.right - gdi.OffsetX-1, rc.bottom - gdi.OffsetY-1); - lowerColOld = lowerCol; - upperColOld = upperCol; - lowerRowOld = lowerRow; - upperRowOld = upperRow; + oldSel = sel; } } @@ -1830,7 +2046,7 @@ void Table::update() PrevSort = -1; if (oldSort != -1) - sort(oldSort); + sort(oldSort, false); commandLock = false; // Reset lock } @@ -1863,27 +2079,53 @@ void Table::getExportData(int col1, int col2, int row1, int row2, wstring &html, } void Table::getRowRange(int &rowLo, int &rowHi) const { - int row1 = -1, row2 = -1; - for (size_t k = 0; k < sortIndex.size(); k++) { - if (upperRow == sortIndex[k].index) - row1 = k; - if (lowerRow == sortIndex[k].index) - row2 = k; + if (sel.empty()) + return; + + if (selScreen.emptyRow()) { + if (dataRowToIndex.empty()) { + dataRowToIndex.resize(Data.size()); + for (size_t k = 0; k < sortIndex.size(); k++) { + dataRowToIndex[sortIndex[k].index] = k; + } + } + + int row1 = -1, row2 = -1; + row1 = dataRowToIndex[sel.upperRow]; + row2 = dataRowToIndex[sel.lowerRow]; + + rowLo = min(row1, row2); + rowHi = max(row1, row2); + selScreen.lowerRow = rowLo; + selScreen.upperRow = rowHi; + } + else { + rowLo = selScreen.lowerRow; + rowHi = selScreen.upperRow; } - rowLo = min(row1, row2); - rowHi = max(row1, row2); } void Table::getColRange(int &colLo, int &colHi) const { - int col1 = -1, col2 = -1; - for (size_t k = 0; k < columns.size(); k++) { - if (upperCol == columns[k]) - col1 = k; - if (lowerCol == columns[k]) - col2 = k; + if (sel.empty()) + return; + + if (selScreen.emptyCol()) { + int col1 = -1, col2 = -1; + for (size_t k = 0; k < columns.size(); k++) { + if (sel.upperCol == columns[k]) + col1 = k; + if (sel.lowerCol == columns[k]) + col2 = k; + } + colLo = min(col1, col2); + colHi = max(col1, col2); + selScreen.lowerCol = colLo; + selScreen.upperCol = colHi; + } + else { + colLo = selScreen.lowerCol; + colHi = selScreen.upperCol; } - colLo = min(col1, col2); - colHi = max(col1, col2); } void Table::exportClipboard(gdioutput &gdi) @@ -2047,7 +2289,7 @@ void Table::importClipboard(gdioutput &gdi) if (tw > columns.size()) throw meosException("Antalet kolumner i urklippet är större än antalet kolumner i tabellen."); - if (upperRow == -1) { + if (sel.emptyRow()) { if (!gdi.ask(L"Vill du klistra in X nya rader i tabellen?#"+itow(table.size()))) return; rowS = sortIndex.size(); // Add new rows diff --git a/code/Table.h b/code/Table.h index 122f914..512351d 100644 --- a/code/Table.h +++ b/code/Table.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -163,11 +163,13 @@ protected: size_t dataPointer; // Insertation pointer vector sortIndex; vector columns; + mutable vector dataRowToIndex; inthashmap idToRow; - //highlight int highRow; int highCol; + bool isFullColumnSelected() const; + // Selected columns. For drag/drop and sort int colSelected; int startX; @@ -178,16 +180,37 @@ protected: int editCol; // Selected rectangle - int upperRow; - int lowerRow; - int upperCol; - int lowerCol; + struct Range { + int upperRow; + int lowerRow; + int upperCol; + int lowerCol; + void reset() { + upperRow = -1; + lowerRow = -1; + upperCol = -1; + lowerCol = -1; + } + bool emptyRow() const { return upperRow < 0 || lowerRow < 0; } + bool emptyCol() const { return upperCol < 0 || lowerCol < 0; } + bool empty() const { return emptyRow() || emptyCol(); } - int upperRowOld; + Range() { reset(); } + ~Range() = default; + bool operator!=(const Range &other) const { + return upperRow != other.upperRow || lowerCol != other.lowerCol || + lowerRow != other.lowerRow || upperCol != other.upperCol; + } + }; + + Range sel; + mutable Range selScreen; + Range oldSel; +/* int upperRowOld; int lowerRowOld; int upperColOld; int lowerColOld; - +*/ bool startSelect; HWND hEdit; @@ -205,9 +228,9 @@ protected: bool partialCell; //static bool filterMatchString(const string &c, const char *filt); - void highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD color, int dx, int dy); + void highlightCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, DWORD color, int dx, int dy); - void moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int dy); + void moveCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, int dx, int dy); void startMoveCell(HDC hDC, const TableCell &cell); void stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy); void restoreCell(HDC hDC, const TableCell &cell); @@ -337,12 +360,20 @@ public: bool mouseLeftUp(gdioutput &gdi, int x, int y); bool mouseLeftDblClick(gdioutput &gdi, int x, int y); + bool mouseRightDown(gdioutput &gdi, int x, int y); + bool mouseRightUp(gdioutput &gdi, int x, int y); + bool mouseMidDown(gdioutput &gdi, int x, int y); + bool mouseMidUp(gdioutput &gdi, int x, int y); + + bool editCell(gdioutput &gdi, int row, int col); bool keyCommand(gdioutput &gdi, KeyCommandCode code); - void sort(int col); + void sort(int col, bool forceDirection); void filter(int col, const wstring &filt, bool forceFilter=false); + void showFilter(gdioutput &gdi); + int addColumn(const string &Title, int width, bool isnum, bool formatRight = false); int addColumn(const wstring &translatedTitle, int width, bool isnum, bool formatRight = false); @@ -355,6 +386,8 @@ public: void set(int column, oBase &owner, int id, const wstring &data, bool canEdit=true, CellType type=cellEdit); + void markAll(bool doSelect); + //Reload a row from data void reloadRow(int rowId); @@ -374,12 +407,9 @@ public: }; struct TableSortIndex { - //TableSortIndex(const Table &t) : table(&t) {} const static Table *table; int index; bool operator<(const TableSortIndex &t) const {return table->compareRow(index,t.index);} - //{return table->Data[index].key < table->Data[t.index].key;} - //bool operator<=(const TableSortIndex &t) const {return table->Data[index].key <= table->Data[t.index].key;} }; enum {TID_CLASSNAME, TID_COURSE, TID_NUM, TID_ID, TID_MODIFIED, diff --git a/code/TimeStamp.cpp b/code/TimeStamp.cpp index e834508..adfc925 100644 --- a/code/TimeStamp.cpp +++ b/code/TimeStamp.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/TimeStamp.h b/code/TimeStamp.h index 8cfd497..28cdce4 100644 --- a/code/TimeStamp.h +++ b/code/TimeStamp.h @@ -10,7 +10,7 @@ #endif // _MSC_VER > 1000 /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/animationdata.cpp b/code/animationdata.cpp index cc0d8d0..6cc19a1 100644 --- a/code/animationdata.cpp +++ b/code/animationdata.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/animationdata.h b/code/animationdata.h index d4df7b0..633fb09 100644 --- a/code/animationdata.h +++ b/code/animationdata.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/autocomplete.cpp b/code/autocomplete.cpp index d2c95b1..8957770 100644 --- a/code/autocomplete.cpp +++ b/code/autocomplete.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/autocomplete.h b/code/autocomplete.h index 8a47993..883d7ad 100644 --- a/code/autocomplete.h +++ b/code/autocomplete.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/autocompletehandler.h b/code/autocompletehandler.h index 81c4c18..3bc7587 100644 --- a/code/autocompletehandler.h +++ b/code/autocompletehandler.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/autotask.cpp b/code/autotask.cpp index de385ae..2859041 100644 --- a/code/autotask.cpp +++ b/code/autotask.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/autotask.h b/code/autotask.h index 7189065..fecd8ed 100644 --- a/code/autotask.h +++ b/code/autotask.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/bitmap1.bmp b/code/bitmap1.bmp index b750a47..9ba856a 100644 Binary files a/code/bitmap1.bmp and b/code/bitmap1.bmp differ diff --git a/code/classconfiginfo.cpp b/code/classconfiginfo.cpp index 02c00fc..8877a76 100644 --- a/code/classconfiginfo.cpp +++ b/code/classconfiginfo.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/classconfiginfo.h b/code/classconfiginfo.h index b198bed..b99b5d6 100644 --- a/code/classconfiginfo.h +++ b/code/classconfiginfo.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/csvparser.cpp b/code/csvparser.cpp index 290eeed..cba250b 100644 --- a/code/csvparser.cpp +++ b/code/csvparser.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/csvparser.h b/code/csvparser.h index ec4bf7e..ce80f53 100644 --- a/code/csvparser.h +++ b/code/csvparser.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/download.cpp b/code/download.cpp index 201b581..7dc058c 100644 --- a/code/download.cpp +++ b/code/download.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/download.h b/code/download.h index c3540a1..bd470f4 100644 --- a/code/download.h +++ b/code/download.h @@ -7,7 +7,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/english.lng b/code/english.lng index 1cd63e3..8c99a84 100644 --- a/code/english.lng +++ b/code/english.lng @@ -1528,10 +1528,10 @@ Exportformat = Export format Filnamnsprefix = Filename prefix Mapp = Folder Mappnamnet fÃ¥r inte vara tomt = Folder name cannot be empty -Onlineresultat = On-Line Results +Onlineresultat = Online Results Packa stora filer (zip) = Compress large files (zip) Publicera resultat direkt pÃ¥ nätet = Publish results directly on the web -Resultat online = Results On-Line +Resultat online = Results OnLine Skicka till webben = Send to the web Spara pÃ¥ disk = Save to disk Till exempel X = For example X @@ -1541,13 +1541,13 @@ URL mÃ¥ste anges = URL missing Tidsintervall (sekunder) = Time interval (seconds) Antal skickade uppdateringar X (Y kb) = Number of updates X (Y kb) Filen finns redan: X = Destination already exists: X -Misslyckades med att ladda upp onlineresultat = Failed to upload on-line results +Misslyckades med att ladda upp onlineresultat = Failed to upload online results Onlineservern svarade felaktigt = Remote server gave unexpected reply (Incorrect configuration?) Onlineservern svarade: ZIP stöds ej = Response from remote server: ZIP not supported. Onlineservern svarade: Serverfel = Response from remote server: Server error Onlineservern svarade: Felaktigt lösenord = Response from remote server: Wrong password Onlineservern svarade: Felaktigt tävlings-id = Response from remote server: Wrong competition id -Online Results Error X = On-Line Results Error X +Online Results Error X = Online Results Error X PDF = PDF ClassTeamLeg = Class, team, leg Okänd = Unknown @@ -2534,7 +2534,7 @@ RunnerStageTimeStatus = Competitor's time or status (on stage) EFilterIncludeNotParticipating = Include not participating RunnerStageNumber = Stage number earlier stage Begränsa bredd (klipp text) = Limit width (crop text) -HÃ¥ll ihop med = Keep together +HÃ¥ll ihop med = Keep columns close Justering i sidled = Line adjustment Minsta blockbredd = Least width Relation till föregÃ¥ende = Relation to previous @@ -2545,5 +2545,44 @@ prefsDatabaseEngine = Typ av databastabell för nya tävlingar (MySQL) Startgrupperna X och Y överlappar = Start groups X and Y are overlapping Batteristatus = Battery status Low = Low -prefsReadVoltageExp = Read SIAC battery voltage +Replace[battery] = Replace Spänning = Voltage +(kopia) = (copy) +Klassen använder banpool = The class has a course pool +Filen (X) innehÃ¥ller IOF-XML tävlingsdata och kan importeras i en existerande tävling = The file (X) contains IOF-XML competition data. You can import it into an existing competition. +Filen (X) är en listdefinition = The file (X) is a list definition +Filen (X) är en resultatmodul = The file (X) is a result module +Filen (X) är inte en MeOS-tävling = The file (X) is not a MeOS competition +MeOS-data = MeOS-data +List definition = List definition +ask:importcopy = A competition (X) with the same origin already exist. You can import the competition as a version of that competition or as a new independent copy. If it is the same event with modifications, it is best to import it as a version.\n\nWould you like to import it as a version? +RunnerCardVoltage = Card voltage +Applicera för specifik etapp = Apply for specific stage +Ljud = Sound +Ljudval = Sound selection +Markera allt (X) = Select all (X) +Markera inget (X) = Select none (X) +Ny ledare i klassen = New class leader +Sparade automater = Saved machines +Spela upp ett ljud för att indikera resultatet av brickavläsningen = Play a sound to indicate the result of the card readout. +Status inte OK (röd utgÃ¥ng) = Status not OK (red exit) +help:selectsound = Select sounds to play. By default MeOS builtin sounds are played. +prefsPlaySound = Play sounds +prefsSoundAction = Sound file, action needed +prefsSoundLeader = Sound file, class leader +prefsSoundNotOK = Sound file, status not OK +prefsSoundOK = Sound file, status OK. +Ã…tgärd krävs = Action needed +Alla tidigare etapper = All previous stages +Dölj = Hide +Exempel = Example +Filtrera = Filter +Markera kolumn = Select column +SlÃ¥ ihop text = Append text (share column) +Sortera fallande = Sort decreasing +Sortera stigande = Sort increasing +Sök symbol = Search for symbol +Testa = Test +Fel: Använd X i texten där värdet (Y) ska sättas in = Error: Use X in the text where the value (Y) should be used +info:teamcourseassignment = The imported file contains forking data for teams. To import this data you must prepare the competition to match the imported file: \n\n1. Ensure all classes are setup with the correct number of legs.\n2. Provide bib numbers in each class. Use Quick Settings on the page Classes and enter the first bib number in each class (meaning automatic bib setting). You can also import the teams first and assign bibs as usual.\n3. Import the courses. You can import this file several times if needed to update the forking. +Försvunnen = Missing diff --git a/code/french.lng b/code/french.lng index 864d756..db1f666 100644 --- a/code/french.lng +++ b/code/french.lng @@ -1,7 +1,8 @@ -encoding = ANSI %s m = %s m %s meter = %s mètres %s, block: %d = %s, bloc: %d +(har stämplat) = (a poinçonné) +(kopia) = (copy) (ledare) = (leader) (lokalt) = (local, pas de serveur) (okänd) stämplade vid = (inconnu) a poinçonné @@ -13,37 +14,58 @@ API-nyckel = clé API Accepterade elektroniska fakturor = Factures électroniques acceptées Adress = Adresse Adress och kontakt = Adresse et contact +Age (on last day of current year) = Age (au dernier jour de l'année en cours) +Age above or equal implies senior/pensioner = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition) +Age below or equal implies youth = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition) Aktivera = Activer la lecture +Aktivera stöd för tider över 24 timmar = Supporter les durées de course de plus de 24h. +Aktuell tid = Heure courante +AllPunches = Tous les poinçons Alla = Tous -Vuxna = Adultes -Ungdom = Jeunes Alla banfiler = Tous les fichiers de circuit Alla deltagare mÃ¥ste ha ett namn = Tous les concurrents doivent avoir un nom Alla fakturor = Toutes les factures +Alla funktioner = Toutes les fonctionnalités Alla händelser = Tous les évènements Alla lag mÃ¥ste ha ett namn = Toutes les équipes doivent avoir un nom Alla listor = Toutes les listes Alla lopp = Toutes les courses +Alla lopp som individuella = Toutes les courses sont individuelles +Alla sträckor = Toutes les variantes Alla sträckor/lopp i separata filer = Tous les partiels/courses dans des fichiers séparés +Alla tidigare etapper = Toutes les étapes précédentes Alla typer = Tous les types +Alla uthyrda brickor har bockats av = Toutes les puces louées ont été rendues Allmänna resultat = Résultats généraux Andel vakanser = Pourcentage de vacants +Ange en gruppstorlek (som repeteras) eller flera kommaseparerade gruppstorlekar = Fournir une taille de groupe (qui sera répétée) ou plusieurs tailles séparées par des virgules Ange första nummerlappsnummer eller lämna blankt för inga nummerlappar = Entrer le premier numéro de dossard, ou laisser vide en l'absence de dossard +Ange löpande numrering eller första nummer i klassen = Spécifier une numérotation consécutive entre catégories ou le premier numéro de la catégorie Ange om kontrollen fungerar och hur den ska användas = Indiquez si le boîtier est opérationnel et comment il doit être utilisé +Ange relation mellan lagets och deltagarnas nummerlappar = Spécifier la relation entre le dossard de l'équipe et les dossards des coureurs de l'équipe Ange startintervall för minutstart = Entrez l'intervalle de départ pour le départ Ange tiden relativt klassens första start = Entrez l'écart en temps par rapport au premier départ de la catégorie. +Animation = Animation Anm. avg. = Tarifs d'inscription Anm. avgift = Tarif d'inscription Anm. datum = Date d'inscription +Anm. tid = Heure d'inscription Anmäl = Entrer Anmäl X = Entrer X pour la compétition +Anmäl andra = Nouvelle inscription +Anmäl inga deltagare nu = Aucune inscription +Anmäl till efterföljande etapper = Entrer pour les étapes suivantes +Anmälan mottagen = Inscription acceptée +Anmälan mÃ¥ste hanteras manuellt = Votre inscription nécessite un traitement manuel Anmälda = Inscriptions Anmälda per distrikt = Inscriptions par région -Anmälningar = Inscriptions Anmälningar (IOF (xml) eller OE-CSV) = Inscriptions (IOF (xml) ou OE-CSV) +Anmälningar = Inscriptions Anmälningsavgift = Droits d'inscription +Anmälningsdatum = Date d'inscription Anmälningsläge = Mode saisie rapide Anmälningstid = Heure d'inscription +Anonymt namn = Nom anonyme Anslut = Connecter Anslut till en server = Connexion au serveur Ansluten till = Connecté à @@ -52,7 +74,12 @@ Anslutna klienter = Clients connectés Anslutningar = Connexions Anslutningsinställningar = Configuration de la connexion Antal = Nombre +Antal banor = Nombre de circuits Antal besökare X, genomsnittlig bomtid Y, största bomtid Z = Nombre de visiteurs X, temps moyen perdu Y, temps max perdu Z +Antal deltagare = Coureurs +Antal deltagare: X = Nombre de coureurs : X +Antal förfrÃ¥gningar: X = Nombre de requêtes +Antal hämtade uppdateringar X (Y kb) = Nombre de mise à jour reçues X (Y kb) Antal ignorerade: X = Nombre d'inscriptions ignorées: X Antal importerade = Nombre de données importées Antal kartor = Nombre de cartes @@ -60,56 +87,92 @@ Antal klasser = Nombre de catégorie Antal löpare = Nombre de coureurs Antal löpare pÃ¥ vanligaste banan X = Nombre de coureurs sur le circuit le plus utilisé: X Antal misslyckade: X = Nombre d'inscriptions +Antal reserverade nummerlappsnummer mellan klasser = Nombre de dossards réservés entre les catégories +Antal skickade uppdateringar X (Y kb) = Nombre de mise à jour X (Y kb) +Antal som inte importerades: X = Nombre d'inscriptions sautées : X Antal startande per block = Nombre de départ par bloc Antal startande per intervall (inklusive redan lottade) = Nombre de départs par intervalle (y compris ceux déjà affectés) Antal sträckor = Nombre de branches Antal vakanser = Nombre de vacants Antal: %d = Nombre: %d Antal: X = Nombre: X +Antalet kolumner i urklipp fÃ¥r inte plats i selektionen = Le nombre de colonnes copiées ne correspond pas à la sélection +Antalet kolumner i urklippet är större än antalet kolumner i tabellen = Le nombre de colonnes copiées est supérieur au nombre de colonnes du tableur Antalet rader i urklipp fÃ¥r inte plats i selektionen = Le nombre de ligne dans le presse-papier ne correspond pas à la sélection Använd Eventor = Utiliser Eventor +Använd ROC-protokoll = Utiliser le protocole ROC Använd banpool = Utiliser un jeu de circuits +Använd befintliga deltagare = Utiliser les coureurs déjà inscrits +Använd endast en bana i klassen = Utiliser uniquement un circuit pour la catégorie +Använd enhets-id istället för tävlings-id = Utiliser l'identifiant de l'appareil au lieu de l'identifiant de la compétition Använd funktioner för fleretappsklass = Utiliser les fonctions de courses à étape Använd första kontrollen som start = Utiliser le premier boîtier comme boîtier départ Använd löpardatabasen = Utiliser la base des coureurs +Använd om möjligt samma dator som användes vid senaste importen = Si possible, utilisez l'ordinateur qui a servi au dernier import Använd sista kontrollen som mÃ¥l = Utiliser le dernier boîtier comme boîtier d'arrivée Använd speakerstöd = Utiliser le module speaker Använd stor font = Utiliser une grande police Använd symbolen X där MeOS ska fylla i typens data = Utilisez le symbole X à l'emplacement où MeOS doit insérer les données Användarnamn = Nom de l'utilisateur +Anyone = N'importe qui +Applicera för specifik etapp = Appliquer pour une étape spécifique Applicera för specifik sträcka = Utiliser pour une branche spécifique +Applying rules to the current competition = Appliquer les règles à la compétition courante Arrangör = Organisateur +Assign courses and apply forking to X = affecter un circuit et appliquer la variation à X +Assign selected courses to selected legs = Affecter les circuits sélectionnés aux branches sélectionnées Att betala = A payer Att betala: X = A payer: X Automater = Services +Automatic rogaining point reduction = Réduction automatique du nombre de points pour la course au score Automatisera = Automatiser +Automatisk = Automatique Automatisk lottning = Tirage au sort automatique +Automatisk omladdning = Mise à jour automatique Automatisk skroll = Défilement automatique -Automatisk utskrift = Impression automatique Automatisk utskrift / export = Impression / export automatique +Automatisk utskrift = Impression automatique Av MeOS: www.melin.nu/meos = Par MeOS: www.melin.nu/meos +Available symbols = Symboles disponibles Avancerat = Personnalisation +Avbockade brickor = Puces rendues Avbryt = Annuler +Avdrag = Réduction Avgift = Frais Avgifter = Tarifs Inscription +Avgifter och valuta ställer du in under = Les tarifs et les monnaies sont changés depuis Avgiftshöjning (procent) = Majoration de tarif (pourcentage) Avgjorda klasser (prisutdelningslista) = Par catégories (Liste de remise de prix) Avgjorda placeringar - %s = Résultats définitifs - %s Avgörande händelser = Evènement décisif Avgörs X = Prêt à X Avgörs kl = Prêt à +Avkortad banvariant = Circuit raccourci associé +Avkortar: X = Raccourci: X +Avkortning = Raccourci Avläsning/radiotider = Lecture des puces/radio +Avmarkera 'X' för att hantera alla bricktildelningar samtidigt = Décocher 'X' pour gérer toutes les affectations de puces sur une seule page Avmarkera allt = Tout désélectionner Avrundad tävlingsavgift = Droits d'inscriptions, arrondis Avsluta = Quitter +Avstämning hyrbrickor = Compter les puces louées rendues +AvstÃ¥nd = Distance Bad file format = Mauvais format -Bana = Circuit +Bakgrund = Arrière plan +Bakgrundsfärg = Couleur de fond +BakÃ¥t = Retour Bana %d = Circuit %d +Bana = Circuit +Bana med slingor = Circuits avec boucles Banan används och kan inte tas bort = Le circuit est en cours d'utilisation Banan mÃ¥ste ha ett namn = Le circuit doit avoir un nom +Banan saknar rogainingkontroller = La compétition n'a pas de poste de type course au score +Banan saknas = Circuit manquant +Banans kontroller ger för fÃ¥ poäng för att täcka poängkravet = Les postes de type course au score n'attribuent pas assez de points +Bananvändning = Fréquentation des circuits Banmall = Circuit -Banor = Circuits Banor (antal kontroller) = Circuit (nombre de postes) +Banor = Circuits Banor för %s, sträcka %d = Circuit pour %s, branche %d Banor, IOF (xml) = Circuits, IOF (xml) Banor, OCAD semikolonseparerat = Circuits, format OCAD @@ -117,11 +180,15 @@ Banpool = Liste des circuits possibles Banpool, gemensam start = Liste de circuits, masse Banpool, lottad startlista = Liste de circuits, avec horaires Bantilldelning = Affectation de circuit +Bantilldelning hänvisar till en löpare (X) som saknas i laget (Y) = Les caractéristiques du circuit spécifient qu'un coureur (X) manque dans l'équipe (Y) Bantilldelning, individuell = Affectation de circuit, course individuelle Bantilldelning, stafett = Affectation de circuit, relais Bantilldelningslista - %s = Circuits affectés - %s Basintervall (min) = Intervalle de base (min) +Batteristatus = Statut de la batterie Begränsa antal per klass = Nombre max par catégorie +Begränsa antal rader per sida = Nombre max de lignes par page +Begränsa bredd (klipp text) = Largeur limite (texte rogné) Begränsa per klass = Limite par catégorie Begränsning, antal visade per klass = Nombre maximum de coureurs par catégorie Behandlar löpardatabasen = Traitement de la base de données des coureurs @@ -129,10 +196,14 @@ Behandlar tävlingsdata = Traitement des compétitions Behandlar: X = Traitement: X Bekräfta att %s byter klass till %s = Confirmez que %s passe dans la catégorie %s Bekräfta att deltagaren har lämnat Ã¥terbud = Confirmez l'annulation de ce coureur +Besökare = Visiteurs Betalat = Payé Betalningsinformation = Détails du paiement +Betalningsmetoder = Modes de paiement +Betalsätt = Mode de paiement Bevakar händelser i X = Moniteur d'évènement X Bevakningsprioritering = Sélectionner le coureur à surveiller +Bibs = Dossards Block = Bloc Blockbredd = Largeur de bloc Bläddra = Parcourir @@ -140,72 +211,168 @@ Bold = Gras BoldHuge = Gras, géant BoldLarge = Gras, grand BoldSmall = Gras, petit +Bomkvot = Pourcentage d'erreur Bommade kontroller = Erreurs de poste -Bomtid = Temps perdu Bomtid (max) = Temps perdu (max) Bomtid (medel) = Temps perdu (moyenne) Bomtid (median) = Temps perdu (médiane) +Bomtid = Temps perdu Bomtid: X = Temps perdu: X -Bricka = Puce +Borttagna: X = Supprimés : X Bricka %d används redan av %s och kan inte tilldelas = La puce %d est utilisé par %s et ne peut être réaffectée +Bricka = Puce +Bricka X = Puce X +Bricka X används ocksÃ¥ av = La puce X est aussi utilisée par +Brickan används av X = La puce est utilisée par X Brickan redan inläst = Puce déjà lue +Brickhantering = Gestion des poinçons Brickhyra = Loc. puce +Bricknr = Numéro de puce +Bricknummer = Numéro de puce Bricknummret är upptaget (X) = Puce utilisée (X) Brickor = Puces +Brickor markerade som bÃ¥de uthyrda och egna: X = Puces utilisées (personnelles ou louées) : X Bygg databaser = Création des bases de données +Byt till rätt klass (behÃ¥ll eventuell starttid) = Basculer vers la bonne catégorie (conserver l'heure de départ) +Byt till vakansplats i rätt klass (om möjligt) = Déplacer vers un horaire vacant dans la bonne catégorie (si possible) COM-Port = Port COM +Calculate and apply forking = Calculer et utiliser les variations +Cancel = Annuler +Centrera = Centrer Check = Vérifier +Check: X = Vérification : X +Check: X = Vérification : X +Choose result module = Choisir un module de résultat +ClassAvailableMaps = Cartes disponibles pour la catégorie ClassCourseResult = Catégorie, circuit, résultats +ClassDefaultResult = Catégorie, résultat par défaut ClassFinishTime = Catégorie, temps +ClassKnockoutTotalResult = Class, knock-out total result ClassLength = Longueur du circuit pour la catégorie +ClassLiveResult = Live results (temps radios), par catégorie ClassName = Catégorie +ClassNumEntries = Nombre d'inscrits dans la catégorie ClassPoints = Catégorie, points ClassResult = Catégorie, résultat ClassResultFraction = Pourcentage de la catégorie ayant terminé ClassStartName = Nom départ ClassStartTime = Catégorie, heure de départ, nom ClassStartTimeClub = Catégorie, heure de départ, club +ClassTeamLeg = Catégorie, équipe, relayeur +ClassTeamLegResult = Résultat par catégorie et relayeur +ClassTotalMaps = Nombre total de cartes pour la catégorie ClassTotalResult = Catégorie, résultats globaux +Classes together = Catégories regroupées +Clear Memory = Effacement de la mémoire +Clear selections = Effacer les sélections +Climb (m) = Dénivelé (m) Club = Club +Club and runner database = Base de donnée des clubs et coureurs +Club id number = Identifiant du club ClubName = Nom du club ClubRunner = Club / Coureur +Clubs = Clubs CmpDate = Date de la compétition CmpName = Nom de la compétition +Control = Poste +Control Overview = Aperçu général du poste +Control Statistics - X = Statistiques du poste - X +Control Statistics = Statistiques du poste +ControlClasses = Catégories du poste +ControlCodes = Numéros du poste +ControlCourses = Circuits du poste +ControlMaxLostTime = Poste, temps perdu, maximum +ControlMedianLostTime = Poste, temps perdu, médian +ControlMistakeQuotient = Poste, pourcentage de coureurs avec perte de temps +ControlName = Nom du poste +ControlPunches = Nombre de coureurs passant au poste +ControlRunnersLeft = Nombre de coureurs n'étant pas encore passé au poste +ControlVisitors = Nombre de coureurs attendus au poste +Could not load list 'X' = Impossible de charger la liste 'X' +Country = Pays +Course = Course +CourseClasses = Catégories du circuit CourseClimb = Dénivelé circuit CourseLength = Longueur circuit CourseName = Nom du circuit +CoursePunches = Poinçons (sur le circuit) CourseResult = Résultat du circuit +CourseShortening = Raccourcissement de course +CourseStartTime = Circuit, heure de départ +CourseUsage = Nombre de cartes nécessaires pour le circuit +CourseUsageNoVacant = Nombre de participant pour le circuit (vacants exclus) +Create Competition = Création de la compétition +Created X distinct forkings using Y courses = X variations distinctes ont été créées à partir de Y circuits CurrentTime = Heure actuelle +CustomSort = Ordre personnalisé +DATABASE ERROR = ERREUR DE BASE DE DONNEE +Data from result module (X) = Données fournies par le module de résultat (X) Databasanslutning = Connexion base de données +Database is used and cannot be deleted = La base de donnée est utilisée et ne peut être supprimée +Databaskälla = Base de donnée source Databasvarning: X = Base de donnée, attention : X Datorröst som läser upp förvarningar = Annonce vocale des coureurs +Datum (för första start) = Date (du premier départ) Datum = Date +Datumfilter = Filtrage par date +Debug = Debug +Debug Output = Sortie de debug +Debug X for Y = Debug X pour Y Decimalseparator = Séparateur décimal DefaultFont = Formatage standard +Define forking = Définir les variations +Definierade mappningar = Mappings définis Dela = Diviser +Dela efter placering = Diviser par résultat Dela efter ranking = Diviser par classement +Dela efter tid = Diviser par temps Dela klass: X = Diviser la catégorie: X Dela klassen = Diviser la catégorie Dela klubbvis = Diviser par club -Deltagare = Coureurs +Dela slumpmässigt = Diviser aléatoirement +Dela upp = Diviser Deltagare %d = Coureur %d +Deltagare (kvarvarande) = Coureurs (restants) +Deltagare = Coureurs Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- och resultatlistor kan därmed bli felaktiga = Le coureur 'X' est dans la catégorie d'équipe 'Y', mais n'a pas d'équipe. Les résultats dans cette catégorie pourraient être faussés. Deltagaren 'X' deltar i stafettklassen 'Y' men saknar lag. Klassens start- och resultatlistor kan därmed bli felaktiga = Le coureur 'X' est dans la catégorie de relais 'Y', mais n'a pas d'équipe. Les résultats dans cette catégorie pourraient être faussés Deltagaren 'X' saknar klass = Le coureur 'X' n'a pas de catégorie +Deltagarens klass styrs av laget = La catégorie est définie par l'équipe Deltar ej = Ne participe pas +Denna datakälla är aldrig tidigare infogad = Cette source de données n'a jamais été fusionnée Denna etapps nummer = Numéro d'étape +Description = Description +Destination: X = Destination: X Destinationskatalog = répertoire de destination +Det finns anmälningsdata för flera etapper = Il y a des données pour plusieurs étapes +Det finns multiplia Id-nummer för personer = Certains coureurs ont des identifiants multiples Det gÃ¥r endast att sätta in vakanser pÃ¥ sträcka 1 = Vous pouvez ajouter des places vacantes seulement sur la première branche Det här programmet levereras utan nÃ¥gon som helst garanti. Programmet är = Ce programme est fourni tel quel, sans aucune garantie. Ce programme est +Deviation +/- from expected time on course leg = Ecart +/- par rapport au temps estimé sur la branche +Direkt tidtagning = Chrono en direct Direktanmälan = Inscription rapide Disk. = Disq. +District id number = Identifiant de la région Distriktskod = Code de la Ligue +Do you want to clear the card memory? = Voulez-vous effacer la puce ? Don't know how to align with 'X' = Impossible d'aligner avec 'X' +Du kan använda en SI-enhet för att läsa in bricknummer = Vous pouvez utiliser un boîtier maître SI pour lire le numéro de la puce Du kan importera banor och klasser frÃ¥n OCADs exportformat = Vous pouvez importer des circuits et des catégories à partir d'un fichier exporté par OCAD Du mÃ¥ste välja en klass = Vous devez choisir une catégorie Duplicera = Dupliquer +Dölj = Masquer +Döp om = Renommer +Döp om X = Renommer X E-post = E-mail +EFilterAPIEntry = Inscriptions via API +EFilterIncludeNotParticipating = Inclut les coureurs qui ne participent pas +EFilterWrongFee = Frais d'inscription inattendu +Economy and fees = Gestion et frais d'inscription +Edit Clubs = Edition des clubs +Edit Result Modules = Edition des modules de résultats +Edit rule for = Editer la règle pour Efter = Après +Efter X = Après X Efteranm. avg. = Frais inscription tardives Efteranmälda (efter ordinarie) = Inscriptions tardives (Après) Efteranmälda (före ordinarie) = Inscriptions tardives (Avant) @@ -216,158 +383,292 @@ Egen text = Texte personnalisé Egenskaper = Propriétés Eget fönster = Nouvelle fenêtre Egna listor = Listes personnalisées +Egna textrader = Ligne de texte personnalisée Ej accepterade elektroniska fakturor = Factures électronique refusées Ej elektronisk = Pas électronique Ej lottade = Pas tiré au sort Ej lottade, efter = Tirés au sort restant après Ej lottade, före = Tirés au sort restant avant +Ej omstart = Pas de redémarrage Ej start = Non partant +Ej startstämpling = Ignorer le poinçon de départ Ej tidtagning = Non chronométré +Ekonomi = Comptabilité +Ekonomihantering, X = Gestion financière, X Ekonomisk sammanställning = Synthèse financière Elektronisk = Electronique Elektronisk godkänd = Accepté électroniquement Elit = Élite Elitavgift = Frais élites Elitklasser = Catégorie élite +En bana med slingor tillÃ¥ter deltagaren att ta slingorna i valfri ordning = Un circuit avec des boucles autorise le coureur à effectuer les boucles dans n'importe quel ordre. En gafflad sträcka = Circuit avec variations En klass kan inte slÃ¥s ihop med sig själv = Vous ne pouvez pas fusionner une catégorie avec elle-même En klubb kan inte slÃ¥s ihop med sig själv = Un club ne peut pas fusionner avec lui-même Endast en bana = Circuit individuel +Endast grundläggande (enklast möjligt) = Fonctionnalités de base +Endast grundläggande = Fonctionnalités de base +Endast pÃ¥ obligatoriska sträckor = Traiter uniquement les variations non optionnelles. +Endast tidtagning (utan banor) = Chronométrage seul (pas de circuits) +Endast tidtagning (utan banor), stafett = Chronométrage seul (pas de circuits), relais +Endast tidtagning = Chronométrage seul +Enhetens ID-nummer (MAC) = Identifiant de l'appareil (MAC) Enhetstyp = Type d'unité +EntryTime = Heure d'inscription +Error in result module X, method Y (Z) = Erreur dans le module de résultat 'X', méthode 'Y'\n\nZ Etapp = Etape Etapp X = Etape X Etappresultat = Résultats des étapes +Ett okänt fel inträffade = Une erreur inconnue s'est produite +Ett startblock spänner över flera starter: X/Y = Un bloc de départ couvre plus d'un départ: X/Y +Ett startintervall mÃ¥ste vara en multipel av basintervallet = Un intervalle de départ doit être un multiple de l'intervalle de base +Ett värde vars tolkning beror pÃ¥ listan = Une valeur ayant une interprétation dépendant d'une liste +Eventor server = Serveur Eventor Eventorkoppling = Connexion à Eventor +Eventors tider i UTC (koordinerad universell tid) = Heure UTC d'Eventor +Exempel = Exemple Export av resultat/sträcktider = Export résultats / temps intermédiaires -Exportera = Exporter +Export language = Langue +Export split times = Exporter les temps intermédiaires Exportera / Säkerhetskopiera = Export / Sauvegarde +Exportera = Exporter Exportera alla till HTML = Exporter tout en HTML +Exportera alla till PDF = Tout exporter en PDF Exportera datafil = Export des données Exportera elektroniska fakturor = Exporter les factures électroniques +Exportera ett kalkylblad med lottningsinställningar som du kan redigera och sedan läsa in igen = Exporter un tableur avec les paramètres de départ que vous pouvez éditer, puis réimporter +Exportera individuella lopp istället för lag = Exporter comme courses individuelles au lieu de courses par équipe Exportera inställningar och löpardatabaser = Export de la configuration et des bases de données +Exportera klubbar (IOF-XML) = Export des clubs (IOF-XML) Exportera löpardatabas = Export de la base des coureurs Exportera nu = Exporter maintenant +Exportera personer (IOF-XML) = Export des personnes (IOF-XML) Exportera pÃ¥ fil = Exporter dans un fichier Exportera resultat pÃ¥ fil = Exporter les résultats dans un fichier +Exportera startlista = Exporter les horaires de départ Exportera startlista pÃ¥ fil = Exporter les listes de départ dans un fichier Exportera sträcktider = Export des temps intermédiaires +Exportera tider i UTC = Heure UTC d'export +Exportera till fil = Exporter dans un fichier Exportera tävlingsdata = Export des données +Exporterar om = Export dans +Exportformat = Format d'export +Exporttyp = Type d'export +Exportval, IOF-XML = Configuration de l'export, IOF-XML +Externa adresser = Liens externes Externt Id = Identifiant externe Extra = Extra +Extra avstÃ¥nd ovanför textblock = Distance additionnelle Extra stämplingar = Poinçons supplémentaires Extralöparstafett = Relais avec Open +Extraplatser = Places supplémentaires FAKTURA = FACTURE FEL, inget svar = Erreur, pas de réponse FEL: Porten kunde inte öppnas = Erreur: le port ne peut pas être ouvert Failed to generate card = Impossible de lire la puce Failed to open 'X' for reading = Echec de l'ouverture de 'X' en lecture +Failed to read file = Echec lors de la lecture du fichier. Faktiskt startdjup: X minuter = Durée des départs: X minutes Faktura = Facture Faktura nr = Facture n° +Fakturadatum = Date de facturation +Fakturainställningar = Configuration de la facturation +Fakturanummer = Numéro de facture Faktureras = A facturer Fakturor = Factures +Familj = Famille +Fel: Använd X i texten där värdet (Y) ska sättas in = Erreur : Placez un X dans le champ Texte, où la valeur doit être affichée (Y) +Fel: Denna tävlingsversion är redan infogad = Erreur : cette version a déjà été fusionnée +Fel: En tävling kan inte slÃ¥s ihop med sig själv = Erreur : impossible de fusionner une compétition avec elle-même Fel: X = Erreur: X Fel: hittar inte filen X = Erreur. Fichier 'X' non trouvé Felaktig kontroll = Mauvais poinçon Felaktig nyckel = Clé incorrecte Felaktig sträcka = Numéro de relayeur incorrect +Felaktigt datum 'X' (Använd YYYY-MM-DD) = Date incorrecte (Mettre AAAA-MM-JJ) +Felaktigt datumformat 'X' (Använd Ã…Ã…Ã…Ã…-MM-DD) = Format de date incorrect 'X' (AAAA-MM-JJ) Felaktigt filformat = Format de fichier incorrect +Felaktigt rankingformat i X. Förväntat: Y = Format de classement incorrect pour X.\nY attendu +Felaktigt tidsformat 'X' (Använd TT:MM:SS) = Format d'heure incorrect 'X' (HH:MM:SS) Felst. = PM Fil att exportera till = Fichier à exporter vers Fil: X = Nom de fichier: X -Filnamn = Nom de fichier +Filen (X) innehÃ¥ller IOF-XML tävlingsdata och kan importeras i en existerande tävling = Le fichier (X) contient des données de compétition au format IOF-XML. Vous pouvez l'importer dans une compétition existante. +Filen (X) är en listdefinition = Le fichier (X) est un fichier définissant une liste +Filen (X) är en resultatmodul = Le fichier (X) est un module de résultat +Filen (X) är inte en MeOS-tävling = Le fichier (X) n'est pas une compétition MeOS +Filen finns redan: X = La destination existe déjà: X +Filename OE (csv) with runners and clubs = Nom de fichier OE (csv) avec coureurs et clubs Filnamn (OCAD banfil) = Nom de fichier (circuit OCAD) +Filnamn = Nom de fichier +Filnamn IOF (xml) eller OE (csv) med löpare = Fichier IOF (xml) ou OE (csv) avec coureurs Filnamn IOF (xml) med klubbar = Nom de fichier IOF (xml) avec clubs Filnamn IOF (xml) med löpare = Nom de fichier IOF (xml) avec coureurs Filnamnet fÃ¥r inte vara tomt = Le nom de fichier ne peut être vide +Filnamnsprefix = Préfixe du nom de fichier Filter = Filtrage +FilterAnyResult = Avec temps radios/résultats FilterHasCard = Avec puce +FilterNamedControl = Postes nommés +FilterNoCancel = Pas annulés FilterNoCard = Sans puce +FilterNotFinish = Uniquement les arrivés FilterNotVacant = Sans vacant FilterOnlyVacant = Uniquement les vacants +FilterPrelResult = Résultats prél. FilterRentCard = Puce louée FilterResult = Avec résultats +FilterSameParallel = Grouper les variations identiques +FilterSameParallelNotFirst = Grouper les variations identiques sauf la première FilterStarted = A démarré +Filtrera = Filtrer Filtrering = Filtrage +Finish order = Ordre d'arrivée +Finish time for each team member = Heure d'arrivée pour chaque équipier FinishTime = Heure d'arrivée, nom -Flera banor = Multi circuits +FinishTimeReverse = Temps inversés (le dernier en premier) +First to finish = Premier à finir Flera banor / stafett / patrull / banpool = Multi circuits/ Relais / Patrouille / Liste de circuits +Flera banor = Multi circuits Flera banor/stafett = Multi circuits / Relais +Flera lopp i valfri ordning = Somme de plusieurs circuits +Flytta deltagare frÃ¥n överfulla grupper = Déplacer les coureurs depuis les groupes entiers Flytta höger = Vers la droite +Flytta ner = Descendre +Flytta upp = Monter Flytta vänster = Vers la gauche +Forked individual courses = Circuit individuel avec variations +Forking setup = Configuration des variations +Forkings = Variations +Forkings for X = Variations pour X Format = Format Formaterat webbdokument (html) = Document web (html) +Formatering = Format Formateringsregler = Règles de formatage Formulärläge = Mode formulaire Fortsätt = Continue Fri anmälningsimport = Inscriptions en format libre Fri starttid = heure de départ libre Fria starttider = heures de départ libres +Fritt = Libre +FrÃ¥n den här listan kan man skapa etiketter att klistra pÃ¥ kartor = A partir de cette liste, vous pouvez créer les étiquettes à coller sur les cartes +FrÃ¥n första = Dép. au premier poste +FrÃ¥n klassen = de la catégorie +FrÃ¥n klubben = Du club FrÃ¥n kontroll = Du poste +FrÃ¥n lag = De l'équipe +FrÃ¥n laget = De l'équipe +FrÃ¥n löpardatabasen = De la base de donnée coureurs +FrÃ¥n löpardatabasen i befintliga klubbar = De la base de donnée coureurs dan les clubs existants +Fullskärm (rullande) = Plein écran (déroulant) +Fullskärm (sidvis) = Plein écran (page par page) Fullskärm = Plein écran +Funktion = Fonction Funktioner = Fonctions +Funktioner i MeOS = Fonctionnalités de MeOS +Fyll obesatta sträckor i alla lag med anonyma tillfälliga lagmedlemmar (N.N.) = Remplir les variations vacantes de toutes les équipes avec des membres temporaires anonymes (X) +Färg = Couleur +Färre slingor = Moins de boucles FödelseÃ¥r = Année de naissance Följande deltagare deltar ej = Les coureurs suivants ne participeront pas -Följande deltagare har bytt klass = Les coureurs suivants ont changé de catégorie Följande deltagare har bytt klass (inget totalresultat) = Les coureurs suivants ont changé de catégorie (pas de résultat total) +Följande deltagare har bytt klass = Les coureurs suivants ont changé de catégorie Följande deltagare har tilldelats en vakant plats = Les coureurs suivants ont pris une place vacante Följande deltagare är anmälda till nästa etapp men inte denna = Les coureurs suivants sont enregistrés pour l'étape suivante mais pas celle-ci Följande deltagare är nyanmälda = Les coureurs suivants générés de nouvelles inscriptions Följande deltagare överfördes ej = Les coureurs suivant ont été ignorés +Fönster (rullande) = Fenêtre (déroulant) +Fönster = Fenêtre +För att delta i en lagklass mÃ¥ste deltagaren ingÃ¥ i ett lag = Pour participer à une catégorie d'équipe vous devez affecter une équipe au coureur För att ändra mÃ¥ltiden mÃ¥ste löparens mÃ¥lstämplingstid ändras = Pour modifier le temps de course, l'heure de poinçonnage de l'arrivée doit être changée För muspekaren över en markering för att fÃ¥ mer information = Survoler avec le pointeur de la souris une zone pour obtenir plus d'information För mÃ¥nga kontroller = Trop de contrôles Förbered lottning = Préparation du tirage au sort Fördefinierade tävlingsformer = Compétitions prédéfinies Fördela starttider = Attribution des heures de départ +Före X = Avant X FöregÃ¥ende = Précédent FöregÃ¥ende etapp = Etape précédente +FöregÃ¥ende kontroll = Poste précédent +Förekomst = Occurrence Förhandsgranskning, import = Prévisualisation de l'import +Förhindra att laget deltar i nÃ¥gon omstart = Permet à l'équipe de ne pas prendre part au départ en masse des attardés +Förhindra omstart = Empêcher le redémarrage Förhöjd avgift = Frais supplémentaires +Först = En premier Först-i-mÃ¥l, gemensam = Du premier au dernier, commun Först-i-mÃ¥l, klassvis = Du premier au dernier, par catégorie Första (ordinarie) start = Premier départ (ordinaire) +Första fakturanummer = Premier numéro de facture Första kontrollen = Premier contrôle Första omstartstid = [First time for restart] Första ordinarie starttid = Première heure de départ normale Första start = Premier départ Första starttid = Premier horaire de départ Första sträckan kan inte vara parallell = La première branche ne peut pas être dédoublée +Första tillÃ¥tna starttid = Heure du premier départ possible Försöket misslyckades = L'opération a échoué Förvarning pÃ¥ (SI-kod): alla stämplingar = Pré-warning (code SI): tous les poinçons -Förvarningsröst = Pré-warning Voix +Förvarningsröst = Pré-warning vocal +Förväntad = Attendu Förväntad andel efteranmälda = Pourcentage d'inscriptions tardives attendu +Förväntat antal besökare: X = Nombre de visiteurs attendus : X +Gafflade banor = Circuits avec variations +Gafflingar i tabellformat = Combinaison au format table +Gafflingsnyckel = Clé de variation +Gafflingsnyckel X = Clé de variation X +Gamla brickor utan stöd för lÃ¥nga tider = Puces anciennes ne prenant pas en charge les longues courses Gata = Rue Gemensam start = Départ en masse +General = Général Generera = Générer Generera testtävling = Générer une compétition de test Genererad = Généré à +Genomsnittlig svarstid: X ms = Temps moyen de réponse : X Geografisk fördelning = Répartition géographique Global sorteringsordning = Ordre de tri global +Godkänd = OK Godkänd API-nyckel = Clé API acceptée Granska inmatning = Prévisualisation Grund avg. = Tarifs de base Grundavgift = Tarif de base Grundinställningar = Configuration de base +Gruppera = Groupe +Gräns för maxtid = Barrière horaire (OMT) +HTML Export = Export HTML +HTML Export för 'X' = Export HTML pour 'X' +HTML formaterad genom listinställningar = HTML formaté par les paramètres de la liste +HTML med AutoRefresh = HTML avec rafraîchissement automatique Hantera brickor = Gestion des puces +Hantera deltagare som bytt klass = Traitement des coureurs qui ont changé de catégorie +Hantera egna listor = Gérer les listes personnalisées Hantera flera etapper = Gestion courses à étapes Hantera jaktstart = Gestion départ en chasse +Hantera klubbar = Gestion des clubs Hantera klubbar och ekonomi = Gestion des clubs et du paiement Hantera kvar-i-skogen = Gestion des coureurs non rentrés +Hantera laget = Gérer l'équipe Hantera löparbrickor = Gestion des puces +Heat = Manche +Hela banan = Circuit entier Hemsida = Site web +Hindra att deltagare frÃ¥n samma klubb startar pÃ¥ angränsande tider = Empêcher que des coureurs du même club partent à des horaires consécutifs. +Hittar inte hjälpfilen, X = Documentation introuvable, X +Hittar inte klass X = Impossible de trouver la catégorie X Hjälp = Aide Hoppar över stafettklass: X = Sauter la catégorie de relais: X Huvudlista = Liste principale Hyravgift = Tarif de location Hyrbricka = Puces louées -Hyrbricksrapport = Rapport des puces louées Hyrbricksrapport - %s = Puces louées - %s +Hyrbricksrapport = Rapport des puces louées Hyrd = Louée Hämta (efter)anmälningar frÃ¥n Eventor = Rechercher les enregistrements récents dans Eventor Hämta data frÃ¥n Eventor = Rechercher des données dans Eventor Hämta efteranmälningar = Rechercher les enregistrements récents +Hämta inställningar frÃ¥n föregÃ¥ende lottning = Récupérer les paramètres des sessions précédentes Hämta löpardatabasen = Recherche dans la base des données des coureurs +Hämta stämplingar m.m. frÃ¥n nätet = Retrouver des poinçons etc... depuis Internet. Hämta svar om elektroniska fakturor = Données des factures acceptées Hämta tävlingsdata = Recherche des données en rapport avec la compétition Hämta tävlingsdata för X = Recherche des données en rapport pour la compétition X @@ -377,23 +678,27 @@ Hämtar klasser = Recherche de catégories Hämtar klubbar = Recherche de clubs Hämtar löpardatabasen = Recherche dans la base des coureurs Hämtar tävling = Recherche d'une compétition -Händelser = Evènement Händelser - tidslinje = Evènement - chronologie +Händelser = Evènement +HÃ¥ll ihop med = Laisser ensemble Hög avgift = Frais d'inscription tardive +Höger = Droite IOF (xml) = IOF (xml) +IOF Klubbdatabas, version 3.0 (xml) = Base de données des clubs IOF, version 3.0 (xml) +IOF Löpardatabas, version 3.0 (xml) = Base de données des coureurs IOF, version 3.0 (xml) IOF Resultat (xml) = Résultats IOF (xml) IOF Resultat, version 2.0.3 (xml) = Résultats IOF, version 2.0.3 (xml) IOF Resultat, version 3.0 (xml) = Résultats IOF, version 3.0 (xml) IOF Startlista (xml) = Horaires de départ IOF (xml) -IOF Startlista, version 3.0 (xml) = Horaires de départ IOF, version 3.0 (xml) IOF Startlista, version 2.0.3 (xml) = Horaires de départ IOF, version 2.0.3 (xml) -IOF Löpardatabas, version 3.0 (xml) = Base de données des coureurs IOF, version 3.0 (xml) -IOF Klubbdatabas, version 3.0 (xml) = Base de données des clubs IOF, version 3.0 (xml) +IOF Startlista, version 3.0 (xml) = Horaires de départ IOF, version 3.0 (xml) IP-adress eller namn pÃ¥ en MySQL-server = Adresse IP ou nom d'un serveur MySQL Id = Id Identifierar X unika inledningar pÃ¥ banorna = X débuts de circuits différents identifiés +Ignorera startstämpling = Ignorer le poinçon de départ Importera = Importer Importera IOF (xml) = Import IOF (xml) +Importera anmälda = Importer les inscriptions Importera anmälningar = Importation des inscriptions Importera banor = Importation des circuits Importera banor/klasser = Importation des circuits/catégories @@ -401,6 +706,7 @@ Importera en tävling frÃ¥n fil = Importer une compétition Importera fil = Importer un fichier Importera frÃ¥n OCAD = Importer depuis OCAD Importera frÃ¥n fil = Importer depuis un fichier +Importera laguppställningar = Importer des équipes depuis un fichier structuré Importera löpardatabas = Importer la base des coureurs Importera löpare = Importer des coureurs Importera löpare och klubbar / distriktsregister = Importer des coureurs et des clubs @@ -411,76 +717,131 @@ Importerar = En cours d'importation Importerar OCAD csv-fil = Importation OCAD CSV Importerar OE2003 csv-fil = Importation OE2003 CSV Importerar OS2003 csv-fil = Importation OS2003 CSV +Importerar RAID patrull csv-fil = Importer les données RAID en csv Importerar anmälningar (IOF, xml) = Importation des inscriptions (IOF, xml) Importerar banor (IOF, xml) = Importation des circuits (IOF, xml) Importerar klasser (IOF, xml) = Importation des catégories (IOF, xml) Importerar klubbar (IOF, xml) = Importation des clubs (IOF, xml) +Importerar lottningsinställningar = Importer les paramètres des listes de départ +Importerar ranking = Importer le classement Importerar tävlingsdata (IOF, xml) = Importation des données de compétition(IOF, xml) Importerbara = Importable +Importinställning = Préférences d'importation +Inconsistent qualification rule, X = Règle de qualification incohérente, X Index = Index +Index in X[index] = Index en X[index] +Individual Example = Exemple de course individuelle +Individual result by finish time = Résultat individuel sur l'heure d'arrivée +Individual results in a club = Résultats individuel au sein du club Individuell = par catégorie Individuell resultatlista, alla lopp = Liste de résultat par nom, toute les courses Individuell resultatlista, sammanställning av flera lopp = Liste de résultat par nom, résumé -Individuell resultatlista, visst lopp = Liste de résultat par nom, spécifique Individuell resultatlista, visst lopp (STOR) = Liste de résultat par nom, spécifique (GRAND) +Individuell resultatlista, visst lopp = Liste de résultat par nom, spécifique Individuell startlista, visst lopp = Liste de départ par nom, spécifique +Individuell tävling = Compétition individuelle Individuella deltagare = Coureurs individuels +Individuella resultat = Résultats individuels Individuella slutresultat = Résultats finaux individuels Individuella totalresultat = Résultats totaux individuels +Individuellt = Individuel +Individuellt, gafflat = Individuel, avec variations Info = Information +Infoga version: X = Version fusionnée : X +Informationsserver = MeOS Information Server Inga = Aucun +Inga bommar registrerade = Aucune erreur de poste détectée Inga deltagare = Pas de coureurs +Inga klasser tillÃ¥ter direktanmälan. PÃ¥ sidan klasser kan du ändra denna egenskap. = Aucune catégorie n'autorise les inscriptions rapides.\n\nVous pouvez modifier ce paramètre à la page 'Catégories'. Inga vakanser tillgängliga. Vakanser skapas vanligen vid lottning = Aucun vacant disponible. Les vacants sont généralement créés quand on tire au sort les horaires des catégories +Ingen / okänd = Aucun / inconnu Ingen = aucun Ingen bana = aucun circuit Ingen deltagare matchar sökkriteriet = Aucun coureur ne répond aux critères de recherche +Ingen deltagare vald = Aucun concurrent sélectionné Ingen klass = Pas de catégorie Ingen klass vald = Pas de catégorie sélectionnée Ingen löpare saknar bricka = tous les coureurs ont une puce Ingen matchar 'X' = Aucune correspondance pour 'X' +Ingen nummerlapp = No de dossard +Ingen parstart = Départ individuel Ingen rogaining = Pas de course au score +Inget filter = Pas de filtre +Inget nummer = Aucun nombre +Inkludera bana = Inclure le circuit +Inkludera information om flera lopp per löpare = Inclure les informations sur les courses multiples pour un coureur individuel. +Inkludera resultat frÃ¥n tidigare etapper = Inclure les résultats de toutes les étapes Inkommande = Arrivants Inläst bricka ställd i kö = La puce a été mise en file d'attente Inlästa brickor = Lecture de puces +Inlästa stämplar = Lire les poinçons Inmatning av mellantider = Entrez les temps intermédiaires +Inmatning online = Saisie à distance +Input Results - X = Résultats initiaux - X +Input Results = Résultats initiaux Inspekterar klasser = Visualisation des catégories Installera = Installation +Installerbara listor = Listes pouvant être installées Inställningar = Configuration Inställningar MeOS = Configuration de MeOS +Inställningar startbevis = Configuration de l'impression des tickets de départ +Inställningar sträcktidsutskrift = Configuration de l'impression des temps intermédiaires Interaktiv inläsning = Lecture interactive -Intervall = Intervalle +Internal Error, identifier not found: X = Erreur interne, identifiant X non trouvé Intervall (sekunder). Lämna blankt för att uppdatera när tävlingsdata ändras = Intervalle (secondes). Laisser vide pour une mise à jour quand les données de la course changent. +Intervall = Intervalle Intervallet mÃ¥ste anges pÃ¥ formen MM:SS = L'intervalle doit être de la forme MM:SS +Invalid filter X = Filtre X invalide +Invalid font X = Police X invalide +Invalid operator X = Opérateur invalide X Italic = Italique ItalicMediumPlus = Italique, un peu plus grand +Ja = Oui Jag sköter lottning själv = Je gère le tirage des horaires de départ moi-même Jaktstart = Départ en chasse Justera blockvis = Ajustement du bloc Justera mot = Aligner avec +Justera visningsinställningar = Ajuster les paramètres de visualisation +Justering i sidled = Ajustement de ligne +Jämna klasser (placering) = Faire des catégories égales (résultats) +Jämna klasser (ranking) = Faire des catégories égales (classement) +Jämna klasser (tid) = Faire des catégories égales (Temps) +Kalkylblad/csv = Tableur/csv +Kartor = Cartes Klart = Terminé Klart. Antal importerade: X = Terminé. Nombre d'inscriptions importées : X Klart. X deltagare importerade = Terminé. X coureurs importés Klart. X lag importerade = Terminé. X équipes importées Klart. X patruller importerade = Terminé. X patrouille importées +Klart. X värden tilldelade = Terminé. X valeurs affectées Klart: alla klasser lottade = Tirage de toutes les catégories terminé Klart: inga klasser behövde lottas = Terminé : aucune catégorie ne nécessite un nouveau tirage -Klass = Catégorie Klass %d = Catégorie %d -Klass saknad = Catégorie absente Klass / klasstyp = Catégorie / Type +Klass = Catégorie +Klass X = Catégorie X Klass att slÃ¥ ihop = Catégories à fusionner +Klass saknad = Catégorie absente Klassbyte = Modifier la catégorie Klassen 'X' har jaktstart/växling pÃ¥ första sträckan = La catégorie 'X' a une chasse/variation sur la première branche +Klassen X är individuell = La catégorie X est individuelle +Klassen X är listad flera gÃ¥nger = La catégorie X est listée plusieurs fois +Klassen använder banpool = La catégorie à un jeu de circuit d'attribué Klassen används och kan inte tas bort = La catégorie est utilisée et ne peut être supprimée Klassen lottas inte, startstämpling = Poinçon de départ uniquement Klassen mÃ¥ste ha ett namn = La catégorie doit avoir un nom +Klassen saknas = Catégorie absente +Klassen är full = La catégorie est déjà complète Klassens bana = Circuit de la catégorie -Klasser = Catégories Klasser (IOF, xml) = Catégories (IOF, xml) +Klasser = Catégories Klasser där nyanmälningar ska överföras = Catégories dans laquelle les nouvelles inscriptions vont être transférées +Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Les catégories X et Y ont le même identifiant externe. Utiliser le mode table pour corriger l'identifiant. Klassinställningar = Configuration des catégories Klassnamn = Nom de la catégorie Klasstyp = Type de la catégorie +Klassval = Sélection de catégorie +Klassval för 'X' = Sélection de la catégorie pour 'X' Klientnamn = Nom du client Klistra in = Coller Klistra in data frÃ¥n urklipp (X) = Coller depuis le presse papier (X) @@ -489,94 +850,149 @@ Klubb = Club Klubb att ta bort = Club à supprimer Klubb: X = Club : X KlubbId = Id du Club -Klubbar = Clubs Klubbar (IOF, xml) = Clubs (IOF, xml) +Klubbar = Clubs Klubbar som inte svarat = Clubs qui n'ont pas répondu Klubbdatabasen = Base de données des clubs Klubblös = Pas de club Klubbresultat = par club -Klubbresultatlista = Résultats par club Klubbresultatlista - %s = Résultats par club - %s -Klubbstartlista = par club +Klubbresultatlista = Résultats par club Klubbstartlista - %s = Horaire de départ par club - %s +Klubbstartlista = par club Klungstart = Départs groupés +Knockout sammanställning = Résumé des éliminations +Knockout total = Résumé des éliminations +Knyt automatiskt efter inläsning = Affectation automatique à la lecture de la puce +Knyt bricka / deltagare = Affecter une puce à un coureur Knyt löpare till sträckan = Affecter un coureur à une variation Knyt löparna till banor frÃ¥n en pool vid mÃ¥lgÃ¥ng = Rattacher un coureur à une course lors de la lecture +Knyt redan anmälda deltagare till laget (identifiera genom namn och/eller bricka) = Regrouper les coureurs existants à l'équipe (identifiés par le nom et/ou le numéro de puce) +Kod = Code +Kolumner = Colonnes Kom ihÃ¥g listan = Mémoriser la liste Kommentar / version = Commentaire / Version Kommunikation = Communication +Kommunikationen med en SI-enhet avbröts = Connection perdue à la base SI-master Kontant = Espèces Kontant betalning = Espèces Konto = Compte -Kontroll = Poste Kontroll %s = Poste %s +Kontroll = Poste Kontroll X = Poste X Kontroll inför tävlingen = Vérifier la compétition Kontrollen används och kan inte tas bort = Le poste est utilisé et ne peut être retiré Kontrollens ID-nummer = Numéro du poste Kontroller = Postes +Kontrollmappning = Mapping des postes Kontrollnamn = Nom du poste +Kontrollrapport - X = Rapport du poste - X +Koordinater (mm) för adressfält = Coordonnées (mm) du champ d'adresse +Kopia (X) = Copier (X) Kopia X = Copier X +Kopiera = Copier Kopiera länken till urklipp = Copier le lien Kopiera selektionen till urklipp (X) = Copier la sélection (X) +Kopiera till urklipp = Copier dans le presse papier Koppla ifrÃ¥n = Déconnecter Koppla ner databas = Déconnexion de la base de données Kopplar ifrÃ¥n SportIdent pÃ¥ = Déconnexion du boîtier SPORTident sur Kortast teoretiska startdjup utan krockar är X minuter = La plus petite durée de départs sans collision est X minutes Kortnamn = Nom court Kunde inte ansluta till Eventor = Connexion à Eventor impossible +Kunde inte ladda X\n\n(Y) = Chargement impossible de X\n\n(Y) +Kunde inte ladda upp löpardatabasen (X) = Impossible d'importer la base de données coureurs (X) Kunde inte ladda upp tävlingen (X) = Echec lors de la remonté de la compétition (X) +Kunde inte öppna databasen (X) = Impossible de se connecter à la base de données (X) +Kunde inte öppna tävlingen = Ouverture de la compétition impossible +Kval/final-schema = Schéma de qualifications/finale +Kvalschema = Procédé de qualification Kvar-i-skogen = Coureurs restants Kvinna = Femme Kvinnor = Femmes +Källa = Source Källkatalog = Répertoire source Kön = Sexe Kör kontroll inför tävlingen = Vérification de la compétition Ladda upp öppnad tävling pÃ¥ server = Upload de la compétition sur le serveur -Lag = Équipe Lag %d = Équipe %d +Lag + sträcka = Équipe + variation +Lag = Équipe +Lag och stafett = Équipe et relais Lag(flera) = Équipes Laget 'X' saknar klass = L'équipe 'X' n'a pas de catégorie Laget hittades inte = Équipe non trouvée +Lagmedlem = Membre de l'équipe Lagnamn = Nom de l'équipe +Lagra inställningar = Enregistrer les paramètres Lagrade säkerhetskopior = Copies sauvegardées +Laguppställning = Fichier structuré d'équipes +Laguppställningen hade fel, som har rättats = La constitution de l'équipe a été corrigée +Lagändringblankett = Modifications d'équipes Land = Pays LargeFont = Texte en grand +Latest Results = Résultats récents Latitud = Latitude +Leg X = Branche X +Leg X: Do not modify = Branche X: Ne pas modifier +Leg X: Use Y = La branche X: utilise Y +Leg number in team, zero indexed = Branche de équipe, indexé à partir de zéro +Legs = Branches +Length of course = Longueur du circuit +LineBreak = Saut de ligne +List Error: X = Erreur de liste : X +List definition = Définition de la liste Lista = Liste Lista av typ 'X' = Liste du type 'X' Lista med mellantider = Liste avec temps partiels Lista med sträcktider = Liste avec temps partiels Listan kan inte visas = Affichage de la liste impossible +Listan togs bort frÃ¥n tävlingen = La liste a été retirée de la compétition Listegenskaper = Liste des propriétés Listnamn = Nom de la liste Listor = Listes +Listor i tävlingen = Listes dans la compétition Listor och sammanställningar = Listes et résumés +Listparameter = Paramètre de la liste Listpost = Entrée de liste Listredigerare = Editeur de liste Listredigerare – X = Editeur de liste – X Listrubrik = Titre de liste Listtyp = Type de liste Listval = Choix de liste +Liveresultat = Résultats en direct +Liveresultat, deltagare = Résultats en direct, individuels +Liveresultat, radiotider = Résultats en direct avec radios +Ljud = Son Ljudfiler, baskatalog = Répertoire de base des fichiers sonores +Ljudval = Sélection des sons Lokalt = Localement +Long = Longue Longitud = Longitude Lopp %d = Course %d Lopp %s = Course %s Lopp X = Course X -Lotta = Tirage +Lopp-id = Identifiant de la course Lotta / starttider = Tirage / Gestion des horaires de départ +Lotta = Tirage Lotta flera klasser = Tirage de plusieurs catégories Lotta klassen = Tirage de la catégorie Lotta klassen X = Tirage de la catégorie 'X' +Lotta klasser med banan X = Définir les horaires de départ du circuit 'X' +Lotta klasser med samma bana gemensamt = Faire le tirage des catégories ayant le même circuit ensemble Lotta löpare som saknar starttid = Tirage des coureurs sans horaire de départ +Lotta med startgrupper = Répartir avec les groupes de départ Lotta om hela klassen = Retirage de la catégorie +Lotta starttider = Définir les horaires de départ Lottad = Tirage effectué Lottad startlista = Horaires de départ tirés Lottar efteranmälda = Tirage des inscriptions tardives Lottar: X = Tirage des heures de départ: X +Lottat = Répartis Lottning = Tirage aléatoire +Low = Bas Lyssna = Ecouter +Lyssnar pÃ¥ X = Ecoute de X Lägg till = Ajouter Lägg till alla = Tout ajouter Lägg till en ny rad i tabellen (X) = Ajout d'une ligne à la table (X) @@ -588,18 +1004,30 @@ Lägg till stämpling = Ajouter le poinçon Lägger till klubbar = Ajout de club Lägger till löpare = Ajout de participants Längd (m) = Distance (m) +Längd = Distance +Längsta svarstid: X ms = Temps de réponse maximal : X +Längsta tid i sekunder att vänta med utskrift = Délai maximum d'attente de l'impression en seconde Länk till resultatlistan = Lien vers les résultats Länk till startlistan = Lien vers les listes de départ Läs brickor = Lecture de puce Läser klubbar = Lecture de clubs Läser löpare = Lecture de coureurs LÃ¥ngt namn = Nom long +LÃ¥s funktion = Verr. fonction +LÃ¥s gafflingar = Verrouiller les variations +LÃ¥s startlista = Verrouiller la liste de départ +LÃ¥s upp = Déverouiller +LÃ¥st gaffling = Variations verrouillées +LÃ¥t de bästa start först = Faire partir le mieux classé en premier LÃ¥t klassen ha mer än en bana eller sträcka = Autoriser la catégorie à avoir plus d'une variation ou d'un circuit +Löpande = Consécutif Löpande information om viktiga händelser i tävlingen = Obtenir des notifications pour les évènements de la compétition Löparbricka %d = Puce % Löpardatabasen = Base de données coureurs Löpare = Coureur +Löpare per klass = Coureurs par catégorie Löpare saknar klass eller bana = Coureur sans catégorie ou circuit +Löpare saknas = Aucun coureur Löpare som förekommer i mer än ett lag = Coureur figurant dans plus d'une équipe Löpare utan SI-bricka: %d = Coureurs sans puce: %d Löpare utan bana: %d = Coureurs sans circuit: %d @@ -615,47 +1043,96 @@ Löparen hittades inte = Coureur non trouvé Löptid = Temps de course Lösenord = Mot de passe Man = Homme +Manual point reductions and adjustments = Réduction des points et ajustements +Manual time penalties and adjustments = Pénalités en temps et ajustements +Manuell = Manuel +Manuell inmatning = Saisie manuelle Manuell lottning = Tirage manuel Manuella avgifter = Frais d'inscription manuels +Manuellt gjorda justeringar = Ajustements manuels +Mapp = Répertoire +Mappa rootadressen (http:///localhost:port/) till funktion = Imposer l'adresse (http:///localhost:port/) pour fonctionner +Mappnamnet fÃ¥r inte vara tomt = Le nom du répertoire ne peut pas être vide +Marginal = Marge +Markera 'X' för att hantera deltagarna en och en = Cocher 'X' pour gérer les coureurs un par un +Markera allt (X) = Tout sélectionner (X) +Markera för att förhindra oavsiktlig ändring av gafflingsnycklar = Vérifier pour empêcher toute erreur dans la répartition des variations +Markera inget (X) = Désélectionner tout (X) +Markera kolumn = Sélectionner une colonne Mata in första nummerlappsnummer, eller blankt för att ta bort nummerlappar = Entrer le premier numéro de dossard, ou laisser vide pour supprimer le dossard Mata in radiotider manuellt = Saisir le temps de passage radio manuellement +Matched control ids (-1 for unmatched) for each team member = Postes corrects pour chaque équipier (-1 en cas de différence) +Max antal brickor per sida = Nombre maximum de puces par page Max antal gemensamma kontroller = Nombre max de contrôles communs Max parallellt startande = Nombre max de départs en parallèles Max. vakanser (per klass) = Nombre max de vacants (par catégorie) +Maxbom = Erreur maximale Maximal tid efter ledaren för att delta i jaktstart = Temps max après le leader pour participer au départ en chasse +Maximum allowed running time = Temps de course maximal autorisé Maxtid = Temps max Maxtid efter = Temps max après MeOS = MeOS +MeOS Features = Fonctionnalités de MeOS +MeOS Funktioner = Fonctionnalités MeOS +MeOS Informationsserver REST-API = MeOS Information Server REST-API +MeOS Three Days Race X = Les 3 jours MeOS X +MeOS Timing = MeOS Timing MeOS lokala datakatalog är = Le répertoire local des données MeOS est +MeOS utvecklinsstöd = Aide au développement de MeOS +MeOS – Funktioner = MeOS – Fonctionnalités MeOS – Resultatkiosk = MeOS – Kiosque de résultats +MeOS-data = données MeOS +Med anmälningsavgift (lagets klubb) = Avec les frais d'inscription (pour le club de l'équipe) +Med avkortning = Avec raccourci +Med direktanmälan = Avec inscription directe +Med km-tid = Inclure l'allure (min/km) +Med resultat = Avec les résultats Med stafettklasser = Avec relais Med sträcktidsanalys = Avec analyse des temps intermédiaires +Medianbom = Erreur médiane +Medium = Moyenne MediumFont = Texte moyen MediumPlus = Texte un peu plus grand Medlöpare = Open +Mellan X och Y = Entre X et Y Mellantider visas för namngivna kontroller = Les temps intermédiaires sont affichés pour les contrôles nommés Metod = Méthode Min. vakanser (per klass) = Nombre min. de vacant (par catégorie) Minitid = Temps min. Minst MySQL X krävs. Du använder version Y = MeOS nécessite MySQL X ou plus récent. Vous utilisez la version Y +Minsta blockbredd = Largeur minimale Minsta intabbning = Indentation minimale Minsta intervall i klass = Plus petit intervalle dans la catégorie Minsta startintervall = Plus petit intervalle de départ Minsta sträcktid = Partiel le plus court Minutstartlista = par heures de départ +Misslyckades med att ladda upp onlineresultat = Echec lors de la monté des résultats sur Internet Motion = Exercice Multipel = Multiple MySQL Server / IP-adress = Serveur MySQL / adresse IP Män = Hommes MÃ¥l = Arrivée +MÃ¥lfil = Fichier de destination MÃ¥lstämpling saknas = Poinçon d'arrivée manquant +MÃ¥lstämpling tillÃ¥ts inte (X) = Arrivée radio désactivée (x) [Finish punch disallowed] MÃ¥ltid = Heure d'arrivée MÃ¥ltid saknas = Heure d'arrivée manquante MÃ¥ltid: X = heure d'arrivée: X +N.N. = X +Name of result module = Nom du module de résultat Namn = Nom +Namn och tidpunkt = Nom et heure +Namnet kan inte vara tomt = Le nom ne peut pas être vide +Narrow Results = Réduire la liste des résultats Nationalitet = Nationalité +Nationality = Nationalité +Nej = Non +New Result Module = Nouveau module de résultat +New Set of Result Rules = Nouvel ensemble de règles de résultat +Nollställ = Effacer Nollställ avgifter = RAZ des frais d'inscription Nollställ databaser = RAZ base de données +Nollställ minnet; markera alla brickor som icke avbockade = Effacer la mémoire; Oublier toutes les puces rendues Nollställde avgift för X deltagare = Effacement des droits d'inscription pour X coureur(s) Nolltid = Heure zéro None = Aucun @@ -663,17 +1140,24 @@ Normal = Normal NormalFont = Texte normal Normalavgift = Frais normaux Not implemented = Non implémenté +Not yet implemented = Pas encore implémenté Nr = Dossard +Number of shortenings = Nombre de raccourcissements Nummerlapp = Dossard +Nummerlapp, SI eller Namn = Dossard, puce ou nom +Nummerlapp, lopp-id eller namn = Dossard, identifiant de la course ou nom Nummerlappar = Dossards Nummerlappar i X = Dossards pour X +Nummerlappshantering = Gestion des dossards Nuvarande innehavare: X = Détenteur : X Ny bana = Nouveau circuit Ny deltagare = Nouveau coureur Ny klass = Nouvelle catégorie Ny klubb = Nouveau club Ny kontroll = Nouveau poste +Ny ledare i klassen = Nouveau leader de la catégorie Ny lista = Nouvelle liste +Ny startgrupp = Nouveau groupe de départ Ny tävling = Nouvelle compétition Nyckel för Eventor = Clé Eventor Nytt fönster = Nouvelle fenêtre @@ -681,21 +1165,39 @@ Nytt lag = Nouvelle équipe Nästa = Suivant Nästa etapp = Prochaine étape Nästa försök = Nouvel essai +O = OK OE Semikolonseparerad (csv) = OE (csv) -OK = OK +OL-Skytte med tidstillägg = Orientation/Tir avec pénalité en temps +OL-Skytte stafettresultat = Relais Orientation/Tir +OL-Skytte utan tidstillägg = Orientation/Tir sans pénalité en temps +Oberoende = Indépendant Ogiltig banfil. Kontroll förväntad pÃ¥ position X, men hittade 'Y' = Fichier de course invalide. Un numéro de poste était attendu à la position X, mais 'Y' a été trouvé +Ogiltig destination X = Destination X invalide +Ogiltig funktion = Fonction invalide Ogiltig föregÃ¥ende/efterföljande etapp = Etape précédente/suivante invalide Ogiltig första starttid. MÃ¥ste vara efter nolltid = Heure du premier départ invalide. Doit être postérieure à l'heure zéro +Ogiltig kontrollkod = Code de poste invalide Ogiltig omstartstid = Heure de nouveau départ invalide Ogiltig repdragningstid = Temps d'arrêt des attardés invalide +Ogiltig starttid X = Heure de départ invalide : X Ogiltig starttid i 'X' pÃ¥ sträcka Y = Heure de départ dans 'X' invalide pour le relayeur Y Ogiltig starttid: X = Heure de départ invalide: X +Ogiltig storlek pÃ¥ seedningsgrupper X = Taille des groupes de répartition invalide : X Ogiltig tid = Heure invalide +Ogiltigt antal sekunder: X = Nombre de secondes invalide : X +Ogiltigt basintervall = Intervalle de base invalide +Ogiltigt bricknummer = Numéro de puce invalide Ogiltigt bricknummer X = Numéro de puce invalide X Ogiltigt filformat = Format de fichier invalide. +Ogiltigt lag pÃ¥ rad X = Équipe invalide ligne X +Ogiltigt maximalt intervall = Intervalle maximum invalide +Ogiltigt minimalt intervall = Intervalle minimum invalide +Ogiltigt startintervall X = Intervalle de départ invalide : X +Okänd = Inconnu Okänd bricka = Puce inconnue Okänd funktion = Mode inconnu Okänd klass = Catégorie inconnue +Okänd klass pÃ¥ rad X = Catégorie inconnue ligne X Okänd klubb med id X = Club avec identifiant X inconnu Om MeOS = A propos de MeOS Om MeOS – ett Mycket Enkelt OrienteringsSystem = A propos de MeOS – un logiciel de CO nettement plus simple @@ -703,92 +1205,189 @@ Omstart = Départ des attardés Omstart i stafettklasser = Redémarrage du relais Omstartstid = Heure de redémarrage Omvänd jaktstart = Chasse inversée +Online Input Error X = Erreur de saisie distante X +Online Results Error X = Erreur dans les résultats en ligne X +Onlineinput = Saisie distante +Onlineresultat = Résultats en ligne +Onlineservern svarade felaktigt = Le serveur distant a fourni une réponse inattendue (Configuration incorrecte ?) +Onlineservern svarade: Felaktigt lösenord = Réponse du serveur distant : Mot de passe incorrect +Onlineservern svarade: Felaktigt tävlings-id = Réponse du serveur distant : Identifiant de compétition incorrect +Onlineservern svarade: Serverfel = Réponse du serveur distant: Erreur du serveur +Onlineservern svarade: ZIP stöds ej = Réponse du serveur distant : ZIP non supporté. +Oordnade parallella = Unordered parallel ($2158) +Oordnade parallella sträckor = Branches parallèles dans n'importe quel ordre Oparad = Non appairés +Open = Ouvrir +Open X = Ouvrir X +Open a Copy = Ouvrir une copie Operationen misslyckades = Echec de l'opération Operationen stöds ej = Opération non supportée Optimerar startfördelning = Optimisation de la distribution des horaires de départ Ordinarie anmälningsdatum = Date de dernière inscription Ordinarie avgift = Frais d'inscription normaux +Ordnat = Trié Organisation = Organisation +Organisatör = Organisateur Oväntad kontroll 'X' i bana Y = Poste 'X' non prévu dans le circuit Y +PDF = PDF +Packa stora filer (zip) = Compresser les grands fichiers (zip) Packar upp löpardatabas = Extension de la base des coureurs +Pages with columns = Pages avec colonnes +Pages with columns, no header = Pages avec colonnes, sans titre Par- eller singelklass = Binôme ou individuel Para ihop = Appairage Para ihop bricka X med en deltagare = Association de la puce X avec un coureur Parallell = Parallèle +Parvis (tvÃ¥ och tvÃ¥) = Par paire (deux à deux) +Patrol Team Rogaining = Course au score en patrouille +Patrol overtime = Patrol overtime +Patrol score reduction = Réduction du score de l'équipe +Patrol score, rogaining = Score de l'équipe, course au score PatrolClubNameNames = Clubs des coureurs (ou de la patrouille) PatrolNameNames = Noms des coureurs (ou de la patrouille) +Patrols = Équipe Patrull = Patrouille Patrull, 1 SI-pinne = Patrouille, une puce Patrull, 2 SI-pinnar = Patrouille, deux puces +Patrullresultat (STOR) = Résultats de la patrouille (GRAND) Personer = Personnes Plac. = Place -Placering in = Place dans +Plac. E[stageno] = Place E +Place on course leg = Classement sur la branche +Placering = Place +Placering in = Place précédente Plats = Place +Plats att exportera till = Exporter vers +Point calculation for runner = Calcul du nombre de points pour un coureur +Point calculation for team = Calcul du nombre de points pour l'équipe +Points as computed by your point method = Points tels que calculés par votre méthode Port = Port Port för TCP = Port TCP +Portable Document Format (PDF) = Portable Document Format (PDF) Postadress = Adresse postale Postkod = Code postal Poäng = Points -Poäng in = Points dans +Poäng E[stageno] = Points E +Poäng in = Points précédents Poängavdrag (per minut) = Point de pénalité (par minute) +Poängavdrag = Réduction de point Poängavdrag per pÃ¥börjad minut = Point de pénalité pour toute minute entamée Poänggräns = Limite en points +Poängjustering = Ajustement des points +Poängreduktion = Réduction Prel. bomtid = Temps perdu (prélim.) Prel. placering = Place (prélim.) +Prepare start lists = Préparation des listes de départ +Press Enter to continue = Appuyez sur pour continuer +Print Card Data = Imprimer les données de la puce +Print card data = Imprimer les données de la puce +Printing failed (X: Y) Z = Port par défaut Prioritering = Priorisation Prisutdelningslista = Résultats pour la remise des prix Programinställningar = Configuration du programme Prolog + jaktstart = Prologue + chasse +Prologue + Pursuit = Prologue + Poursuite Publicera resultat = Publication des résultats +Publicera resultat direkt pÃ¥ nätet = Publier les résultats directement sur le web Publicera resultat och sträcktider pÃ¥ Eventor och WinSplits online = Publication des résultats et des temps intermédiaires sur Eventor et WinSplits en ligne Publicera startlista = Publication des horaires de départ Publicera startlistan pÃ¥ Eventor = Publication des horaires de départ sur Eventor Publicerar resultat = Publication des résultats Publicerar startlistan = Publication des horaires de départ +Punch codes for each team member = No de poinçon pour chaque équipier +Punch times for each team member = Heure de poinçonnage pour chaque équipier +PunchAbsTime = Poinçon, heure réelle +PunchControlCode = Numéro de poste +PunchControlNumber = Numéro de poinçon +PunchControlPlace = Place sur la branche vers le poste +PunchControlPlaceAcc = Place après le poste +PunchLostTime = Temps perdu au poste +PunchName = Poinçon, code du poste +PunchNamedSplit = Temps depuis le dernier poste nommé PunchNamedTime = Temps intermédiaires nommés +PunchSplitTime = Temps depuis le dernier poste (temps intermédiaire) PunchTime = Heure de poinçonnage +PunchTimeSinceLast = Temps entre les postes +PunchTotalTime = Temps au poste +PunchTotalTimeAfter = Temps passé au poste Punches = Poinçons +PÃ¥ banan = Sur le circuit +Rad X är ogiltig = La ligne X est invalide +Rader = Lignes +Rader markerade med (*) kommer frÃ¥n en lista i tävlingen = Les lignes avec une (*) proviennent d'une liste de la compétition Radera = Supprimer +Radera alla klubbar = Effacer tous les clubs +Radera alla klubbar och ta bort klubbtillhörighet = Effacer tous les clubs et les membres des clubs Radera listan frÃ¥n aktuell tävling = Supprimer la liste de cette compétition +Radera permanent = Suppression définitive Radera starttider = Effacer les heures de départ Radera tävlingen = Supprimer la compétition Radera vakanser = Supprimer les vacants +Radio = Postes +Radio tillÃ¥ts inte (X) = Postes de contrôle radios désactivés (X) Radiotider, kontroll = Heures radio, poste -Ranking = Classement Ranking (IOF, xml, csv) = Classement (IOF, xml, csv) +Ranking = Classement +Rapport = Rapport Rapport inför = Rapport pour Rapporter = Rapports Rapportläge = Mode rapport Red. avg. efteranm = Retardat. Réduit Red. avgift = Réduit +Redigera = Editer Redigera deltagaren = Editer le coureur Redigera lista = Editer la liste Redigera listpost = Editer une entrée dans la liste +Redigera sträcklängder = Modifier les distances +Redigera sträcklängder för X = Modifier les distances du circuit 'X' Reducerad avg = Frais d'inscription réduits Reduktionsmetod = Méthode de réduction +Referens = Référence Region = Région +Registrera hyrbrickor = Pré-inscrire les puces louées +Relation till föregÃ¥ende = Lien avec le précédent Relativ skalfaktor för typsnittets storlek i procent = Facteur d'échelle pour la police (pourcentage) +Relay Example (Lokal kopia frÃ¥n: localhost) = Exemple de relais (Copie locade depuis : localhost) +Relay Example = Exemple de relais +Relays = Relais Rep = Arrêt attardés Reparera vald tävling = Réparer la compétition sélectionnée Reparerar tävlingsdatabasen = Réparation de la base de données de la compétition Repdragningstid = Heure d'arrêt des attardés Repdragningstiden mÃ¥ste ligga före omstartstiden = L'heure d'arrêt doit précéder l'heure des re-départs +Replace[battery] = Remplacer Reserverade = Réservé -Resultat = Résultat +RestService = Service Rest +Result Calculation = Calcul du résultat +Result Module – X = Module résultat – X +Result Modules = Modules de résultat +Result at a control = Résultat au poste +Result module = Module de résultats +Result module identifier = Identifiant du module de résultat +Result score calculation for runner = Détermination du score pour un coureur +Result score calculation for team = Calcul du score pour l'équipe +ResultDescription = Nom du type de résultat +ResultModuleNumber = Module de résultat : Nombre +ResultModuleNumberTeam = Module de résultat : Nombre (pour l'équipe) +ResultModuleTime = Module de résultat : Temps +ResultModuleTimeTeam = Module de résultat : Temps (pour l'équipe) Resultat && sträcktider = Résultats / Temps interm. Resultat (STOR) = Résultats (GRAND) Resultat - %s = Résultats - %s Resultat - X = Résultats - X +Resultat = Résultat Resultat banvis per klass = Résultat des circuits par catégorie Resultat efter klass och bana - X = Résultats par catégorie et circuit - X Resultat efter sträcka %d = Résultats après le relayeur %d Resultat efter sträcka X = Résultats après le X ème relayeur Resultat efter sträckan = Résultats après le relayeur +Resultat frÃ¥n tidigare etapper = Résultats des étapes précédentes Resultat för ett visst lopp = Résultats pour une course donnée Resultat lopp X - Y = Résultats pour la course X - Y -Resultat per bana = Résultats par circuit +Resultat online = Résultats en ligne Resultat per bana - X = Résultats par circuit - X +Resultat per bana = Résultats par circuit +Resultat vid mÃ¥lstämpling = Résultat sur le poinçon d'arrivée Resultat, generell = Résultats général Resultat, individuell = Résultats individuel Resultat, patrull = Résultats, patrouille @@ -796,40 +1395,114 @@ Resultatkiosk = Kiosque de résultats Resultatlista - %s = Résultats - %s Resultatlista – inställningar = Résultats – configuration Resultatlistor = Résultats -Resultatutskrift = Imprimer les résultats +Resultatmodulen används i X = Le module de résultat est utilisé dans X +Resultatuträkning = Calcul des résultats Resultatutskrift / export = Imprimer / Exporter les résultats +Resultatutskrift = Imprimer les résultats Rogaining = Course au score +Rogaining points before automatic reduction = Points du circuit avant réduction automatique +Rogaining points for each team member = Points pour chaque équipier (course au score) +Rogaining results for a patrol = Résultats de course au score pour binôme (ou plus) +Rogaining results for a team, where each team member collects points individually = Résultats de course au score pour binôme où chaque membre collecte des points de façon individuelle Rogaining, individuell = Course au score individuelle Rogaining-poäng = Points (course au score) RogainingPunch = Poinçon (course au score) +Rogainingresultat - %s = Résultats de la course au score - %s Rubrik = Titre Rulla upp och ner automatiskt = Défilement vertical automatique Runner = Coureur +Runner check time = Heure de contrôle du coureur +Runner's card, matched control ids (-1 for unmatched punches) = La puce du coureur correspond aux n° de poste (-1 par poinçon différents) +Runner's card, punch codes = Puce du coureur, n° de poinçon +Runner's card, punch times = Puce du coureur, heure du poinçon +Runner's course = Circuit du coureur +Runner's course id = Identifiant de la course du coureur +Runner's method output numbers = Module de résultat en nombre pour chaque équipier +Runner's method output times = Module de résultat en temps pour chaque équipier +Runner's split times = Temps intermédiaires du coureurs +Runner's total running time to control = Temps total du coureur jusqu'au poste +Runner/team earlier stage places = Places du coureur/de l'équipe aux étapes précédentes +Runner/team earlier stage points = Points du coureur/de l'équipe aux étapes précédentes +Runner/team earlier stage running times = Temps du coureur/de l'équipe aux étapes précédentes +Runner/team earlier stage statuses = Statuts du coureur/de l'équipe aux étapes précédentes +Runner/team fee = Droit d'inscription coureur/équipe +Runner/team finish time = Heure d'arrivée coureur/équipe +Runner/team input place = Place initiale coureur/équipe +Runner/team input points = Points initiaux coureur/équipe +Runner/team input running time = Temps de course initial coureur/équipe +Runner/team input status = Statut initial coureur/équipe +Runner/team place = Place coureur/équipe +Runner/team rogaining overtime = Dépassement du temps pour coureur/équipe (course au score) +Runner/team rogaining points = Point coureur/équipe (course au score) +Runner/team rogaining points adjustment = Ajustement des points coureur/équipe (course au score) +Runner/team running time = Temps de course coureur/équipe +Runner/team start time = Heure de départ coureur/équipe +Runner/team status = Statut coureur/équipe +Runner/team time adjustment = Ajustement du temps coureur/équipe +Runner/team total place = Place finale coureur/équipe +Runner/team total running time = Temps total de course coureur/équipe +Runner/team total status = Statut final coureur/équipe +RunnerAge = Age du coureur RunnerBib = Dossard du coureur +RunnerBirthYear = Année de naissance du coureur RunnerCard = Puce du coureur +RunnerCardVoltage = Voltage puce +RunnerCheck = Heure de contrôle RunnerClassCoursePlace = Classement dans la catégorie pour le circuit RunnerClassCourseTimeAfter = Retard dans la catégorie pour le circuit RunnerClub = Club du coureur RunnerCompleteName = Nom complet du coureur RunnerCourse = Circuit du coureur +RunnerCoursePlace = Place du coureur dans la course +RunnerEntryDate = Date d'inscription +RunnerEntryTime = Heure d'inscription +RunnerExpectedFee = Tarif d'inscription attendu RunnerFamilyName = Nom de famille du coureur +RunnerFee = Prix payé par le coureur RunnerFinish = Heure d'arrivée du coureur +RunnerGeneralPlace = Place du coureur ou du relayeur +RunnerGeneralTimeAfter = Retard du coureur ou du relayeur +RunnerGeneralTimeStatus = Temps / statut du coureur ou du relayeur RunnerGivenName = Prénom du coureur -RunnerLegNumberAlpha = Numéro de relais exact du coureur +RunnerGlobal = Coureur (catégories regroupées) +RunnerGrossTime = Temps avant modifications +RunnerId = Licence/ID +RunnerLeg = Concurrent (variation spécifique) RunnerLegNumber = Numéro de relais groupé du coureur +RunnerLegNumberAlpha = Numéro de relais exact du coureur RunnerName = Nom du coureur +RunnerNationality = Nationalité du coureur +RunnerPaid = Payé +RunnerPayMethod = Méthode de payement +RunnerPhone = Numéro de téléphone du coureur RunnerPlace = Place du coureur RunnerPlaceDiff = Différence de place du coureur +RunnerPointAdjustment = Ajustement des points du coureur RunnerRank = Classement du coureur +RunnerRogainingOvertime = Dépassement de temps pour le coureur (course au score) RunnerRogainingPoint = Points de la course au score +RunnerRogainingPointGross = Points avant pénalités +RunnerRogainingPointTotal = Total des points du coureur +RunnerRogainingReduction = Réduction du nombre de points du coureur +RunnerSex = Sexe du coureur +RunnerStageNumber = Nombre du coureur sur l'étape (module de résultat) +RunnerStagePlace = Place du coureur sur l'étape +RunnerStagePoints = Points du coureur sur l'étape +RunnerStageStatus = Statut du coureur sur l'étape +RunnerStageTime = Temps du coureur sur l'étape +RunnerStageTimeStatus = Temps ou statut du coureur sur l'étape RunnerStart = Heure de départ du coureur +RunnerStartCond = Heure de départ du concurrent (si individuel) RunnerStartNo = Numéro de départ du coureur +RunnerStartZero = Heure de départ relative du coureur (heure zéro) RunnerTempTimeAfter = Temps du coureur après le poste sélectionné RunnerTempTimeStatus = Temps / statut du coureur au poste sélectionné RunnerTime = Temps du coureur +RunnerTimeAdjustment = Ajustement du temps du coureur RunnerTimeAfter = Retard du coureur RunnerTimeAfterDiff = Différence de retard du coureur RunnerTimeLost = Temps perdu par le coureur +RunnerTimePerKM = Allure min/km RunnerTimePlaceFixed = Instant à partir duquel la place du coureur n'a plus évolué RunnerTimeStatus = Temps / statut du coureur RunnerTotalPlace = Place consolidée du coureur @@ -837,6 +1510,7 @@ RunnerTotalTime = Temps consolidé du coureur RunnerTotalTimeAfter = Retard consolidé du coureur RunnerTotalTimeStatus = Temps / statut consolidé du coureur RunnerUMMasterPoint = Master points Uppsala möte +Running time for each team member = Temps de course pour chaque équipier SI X inläst. Brickan tillhör Y som saknar klass = La puce X a été lue. La puce appartient à Y, qui n'a pas de catégorie SI X inläst. Brickan är inte knuten till nÃ¥gon löpare (i skogen) = La puce X a été lue. La puce est associé à aucun coureur (en forêt) SI X är redan inläst. Använd interaktiv inläsning om du vill läsa brickan igen = La puce X a déjà été lue. Utiliser la lecture interactive pour la relire. @@ -845,22 +1519,46 @@ SI pÃ¥ = SI en marche SI-dubbletter: %d = SI dupliqué: %d SOFT-avgift = Frais d'inscription SOFT [SOFT fee] SOFT-lottning = Méthode de tirage suédoise +SRR Dongle = Dongle SRR Saknad starttid = Heure de départ manquante +Samlade poäng = Points acquis +Samma = Identique +Samma bastävling = Même compétition de base +Sammanfattning, uppdateradet poster = Résumé des données mises à jour +Sammanslagning fungerar om samma uppsättning banor/kontroller används = La fusion fonctionnera si les circuits et les postes des fichiers sont les mêmes +Sammanslagning klar = Fusion terminée Sammanställning = Résumé Sammanställning, ekonomi = Résumé financier Sammanställning, klasser = Résumé des catégories Samtliga deltagare tilldelades resultat = Tous les coureurs ont un résultat +Save = Enregistrer +Save changes = Enregistrer les changements +Save changes in rule code? = Enregistrer les changements dans le code de la règle ? Seedad lottning = Tirage au sort +Seedningsgrupper = Groupes de répartition +Seedningskälla = Données de répartition Sekundär typ = Type secondaire Selektionens storlek matchar inte urklippets storlek. Klistra in i alla fall? = La taille de la sélection ne correspond pas au contenu du presse-papier. Coller tout de même ? Semikolonseparerad (csv) = Fichier (csv) Sen avgift = Retardat. Sen red. avgift = Ret. réduit +Senast sedd: X vid Y = Dernières infos: à X au poste Y Server = Serveur +Server startad pÃ¥ X = Serveur sur le port X +Server startad pÃ¥ port X = Serveur sur le port X +Server version: X = Version du serveur : X Server: [X] Y = Serveur: [X] Y -Sidbrytning mellan klasser = Saut de page +Several MeOS Clients in a network = Plusieurs clients MeOS en réseau +Several races for a runner = Plusieurs circuits pour un coureur +Several stages = Plusieurs étapes +Short = Court +Shortest time in class = Meilleur temps de la catégorie +Show forking = Montrer les variations Sidbrytning mellan klasser / klubbar = Saut de page entre catégories / clubs +Sidbrytning mellan klasser = Saut de page +Sidor per skärm = Pages par écran Simulera inläsning av stämplar = Simuler la lecture de puce +Sist = En dernier Sista betalningsdatum = Paiements dûs au (AAAA-MM-JJ) Sista ordinarie anmälningsdatum = Date limite d'inscription au tarif normal Sista start (nu tilldelad) = Dernier départ (affecter maintenant) @@ -868,19 +1566,26 @@ Sista start (nu tilldelad): X = Dernier départ (affecté): X Sista sträckan = Dernier relais Ska X raderas frÃ¥n tävlingen? = Voulez-vous retirer X de la compétition ? Skalfaktor = Facteur d'échelle +Skapa = Créer +Skapa anonyma lagmedlemmar = Créer des membres d'équipe anonyme temporaires Skapa en ny tävling med data frÃ¥n Eventor = Créer une nouvelle compétition à partir des données de Eventor Skapa en ny, tom, tävling = Créer une nouvelle compétition vide Skapa fakturor = Générer les factures Skapa generell lista = Créer la liste générale Skapa listan = Créer la liste Skapa ny klass = Créer une nouvelle catégorie +Skapa tävlingen = Créer la compétition Skapad av = Créé par Skapade en bana för klassen %s med %d kontroller frÃ¥n brickdata (SI-%d) = Un circuit pour la catégorie %s avec %d poste dans la puce %d a été créée. Skapade en lokal kopia av tävlingen = Copie locale de la compétition créée +Skapade lokal säkerhetskopia (X) innan sammanslagning = Sauvegarde locale (X) créée avant fusion Skapar ny etapp = Créer une nouvelle étape Skapar ny tävling = Création d'une nouvelle compétition Skapar saknad klass = Catégorie manquante créée +Skapar tävling = Création de la compétition Skattad avgift = Frais d'inscription taxable +Skicka och ta emot snabb förhandsinformation om stämplingar och resultat = Envoyez et recevoir des pré-informations rapides sur les poinçons et résultats +Skicka till webben = Envoyer sur le web Skippar lottning = Ignorer le tirage au sort Skript = Script Skript att köra efter export = Script à exécuter après l'export @@ -896,70 +1601,111 @@ Skriv ut fakturan = Imprimer les factures Skriv ut listan = Imprimer la liste Skriv ut nu = Imprimer maintenant Skriv ut rapporten = Imprimer le rapport +Skriv ut startbevis = Ticket de départ +Skriv ut startbevis för deltagaren = Imprimer le ticket de départ du coureur Skriv ut sträcktider = Temps intermédiaires -Skriv ut tabellen = Imprimer la table Skriv ut tabellen (X) = Imprimer la table (X) +Skriv ut tabellen = Imprimer la table Skriv över existerande bricknummer? = Ecraser le numéro de puce existant ? Skrivare = Imprimante +Skrivarinställningar = Configuration de l'impression Skrivarinställningar för sträcktider = Configuration de l'imprimante +Skrivarinställningar för sträcktider och startbevis = Configuration de l'impression des tickets de temps intermédiaires et de départ +Skriver sträcktider när tävlingsdata ändras = Ecriture du fichier quand les données de la compétition changent Skriver sträcktider om = Impression dans +Slut = Fin Slutresultat = Résultats finaux +Sluttid = Temps final SlÃ¥ ihop = Fusionner -SlÃ¥ ihop klass: X = Fusionner la catégorie: X +SlÃ¥ ihop X = Fusionner X SlÃ¥ ihop klass: X (denna klass behÃ¥lls) = Fusionner la catégorie avec X (conserver cette catégorie) +SlÃ¥ ihop klass: X = Fusionner la catégorie: X SlÃ¥ ihop klasser = Fusionner les catégories SlÃ¥ ihop klubb = Fusionner le club +SlÃ¥ ihop med = Fusionner avec +SlÃ¥ ihop med befintlig lista = Fusionner avec une liste existante +SlÃ¥ ihop text = Fusionner le texte (partager la colonne) +SlÃ¥ ihop text med föregÃ¥ende = Fusionner avec le précédent +SlÃ¥ ihop tävlingar = Fusionner les compétitions SmallFont = Petit texte SmallItalic = Texte en petit et italique Snabbinställningar = Configuration rapide +SortLastNameOnly = Nom de famille SortNameOnly = Nom +Sortera fallande = Trier par ordre décroissant +Sortera stigande = Trier par ordre croissant Sortering = Tri Sortering: %s, antal rader: %d = Tri: %s, nombre de ligne: %d +Source code = Code source Spara = Enregistrer Spara anmälningar = Enregistrer les inscriptions Spara den här listan som en favoritlista = Enregistrer cette liste comme favori Spara fil = Enregistrer le fichier +Spara fönster- och speakerinställningar pÃ¥ datorn = Enregistrer la fenêtre et les paramètres sur cet ordinateur Spara för webben = Enregistrer le document web Spara i aktuell tävling = Enregistrer dans cette compétition +Spara inmatade tider i tävlingen utan att tilldela starttider = Enregistrer les paramètres et les heures de départ de chaque catégorie pour y revenir plus tard +Spara laguppställningar = Enregistrer les équipes +Spara pÃ¥ disk = Enregistrer sur disque Spara som = Enregistrer sous +Spara som PDF = Enregistrer en tant que PDF Spara som fil = Enregistrer le fichier sous +Spara starttider = Enregistrer les heures de départ Spara sträcktider till en fil för automatisk synkronisering med WinSplits = Enregistrer les temps intermédiaires pour synchronisation automatique avec WinSplits +Spara tid = Enregistrer +Sparade automater = Maxhines enregistrées Sparade listval = Listes enregistrées Speaker = Speaker Speakerstöd = Module Speaker +Spela upp ett ljud för att indikera resultatet av brickavläsningen = Lancer un son pour indiquer le résultat de la puce. SportIdent = SPORTident SprÃ¥k = Langue +Spänning = Voltage Stad = Ville -Stafett = Relais Stafett (sammanställning) = Relais (résumé) Stafett - sammanställning = Relais - résumé Stafett - sträcka = Relais - relayeur Stafett - total = Relais - total +Stafett = Relais Stafettklasser = Catégories pour le relais +Stafettresultat = Résultats de relais Stafettresultat, delsträckor = Résultats du relais, détail relayeurs Stafettresultat, lag = Résultats du relais, équipe -Stafettresultat, sträcka = Résultats du relais, par relayeur Stafettresultat, sträcka (STOR) = Résultats du relais, par relayeur (GRAND) +Stafettresultat, sträcka = Résultats du relais, par relayeur +Standard = Standard Start = Départ Start nr = Départ no. +Start time for each team member = Heure de départ pour chaque équipier +Start: X = Départ : X StartTime = Neure de départ, nom +StartTimeClass = Heure de départ, catégorie StartTimeForClass = Heure de départ commune, catégorie +StartTimeForClassRange = Plage d'heures de départ de la catégorie Starta = Démarrer Starta automaten = Démarrer le service Starta en guide som hjälper dig göra klassinställningar = Démarrer un guide pour vous aider à construire les catégories Startade automater = Services démarrés Startande = Démarrage Startar SI pÃ¥ = Démarrage du boîtier SI à +Startbevis = Ticket de départ +Startbevis X = Ticket de départ X Startblock = Couloir Startblock: %d = Couloir : %d -Startintervall = Intervalle de départ +Startgrupp = Groupe de départ +Startgrupp med id X tilldelad Y finns inte = Le groupe de départ numéro X défini pour Y n'existe pas +Startgrupper = Groupes de départs +Startgrupperna X och Y överlappar = Les groupes de départ X et Y se chevauchent Startintervall (min) = Intervalle de départ (min) -Startlista = Horaires de départ +Startintervall = Intervalle de départ +Startintervallet fÃ¥r inte vara kortare än basintervallet = L'intervalle entre départs ne doit pas être plus court que l'intervalle de base Startlista %%s - sträcka %d = Horaires de départ %%s - Combinaison %d Startlista - %s = Horaires de départ - %s Startlista - X = Horaires de départ - X +Startlista = Horaires de départ Startlista ett visst lopp = Horaires de départ pour la course Startlista lopp X - Y = Horaires de départ pour la course X - Y +Startlista, banvis = Liste de départ par circuit Startlista, individuell = Horaires de départ individuels Startlista, patrull = Horaires de départ, patrouille Startlista, stafett (lag) = Horaires de départ, relais (équipe) @@ -968,47 +1714,75 @@ Startlistor = Horaires de départ Startmetod = Méthode de départ Startnamn = Nom du départ Startnummer = Numéro de départ -Starttid = Heure de départ +Startstämpling tillÃ¥ts inte (X) = Départ radio désactivé (X) [Start punch disallowed] Starttid (HH:MM:SS) = Heure de départ (HH:MM:SS) +Starttid = Heure de départ Starttid: X = Heure de départ: X +Starttiden är definerad genom klassen eller löparens startstämpling = L'heure de départ est définie par la catégorie ou le poinçonnage d'un boîtier départ Starttiden är upptagen = L'heure de départ n'est pas disponible Starttyp = Type de départ Status = Statut +Status E[stageno] = Statut E Status OK = Statut OK -Status in = Saisie du statut +Status as computed by your status method = Statut tel que calculé par votre méthode +Status calculation for runner = Détermination du statut pour un coureur +Status calculation for team = Détermination du statut pour une équipe +Status code for a missing punch = Code de statut pour un poinçon manquant +Status code for a time over the maximum = Code de statut en cas de dépassement du temps +Status code for a valid result = Code de statut pour un résultat valide +Status code for an unknown result = Code de statut pour un résultat inconnu +Status code for cancelled entry = Code de statut pour une inscription annulée +Status code for disqualification = Code de statut pour une disqualification +Status code for no timing = Code de statut pour une course non chronométrée +Status code for not competing = Code de statut en cas d'absence +Status code for not finishing = Code de statut en cas d'abandon +Status code for not starting = Code de statut en cas de non prise de départ +Status code for running out-of-competition = Code de statut pour non classé (NC) +Status for each team member = Statut de chaque équipier +Status in = Statut précédent +Status inte OK (röd utgÃ¥ng) = Statut pas OK (rouge) +Status matchar inte data i löparbrickan = Le statut ne correspond pas au donnée contenues dans la puce. +Status matchar inte deltagarnas status = Le statut ne correspond pas au statut du coureur. +Stigning = Dénivellé Stoppa automaten = Arrêt du service Stor = Grand -Str. = Relais Str. %d = Relais %d +Str. = Relais +Str. X = Relayeur X String = Texte Struken = Annulé Struken med Ã¥terbetalning = Annulé, frais d'inscription remboursés Struken utan Ã¥terbetalning = Annulé, pas de remboursement des frais d'inscription Strukturerat exportformat = Format d'export structuré Strukturerat webbdokument (html) = Document web structuré (html) -Sträcka = Relayeur Sträcka %d = Relayeur %d +Sträcka = Relayeur Sträcka X = Relayeur X Sträcka att lotta = Partiel à tirer au sort Sträckans banor = Circuits du relais -Sträcktider = Temps intermédiaires Sträcktider (WinSplits) = Temps intermédiaires (WinSplits) Sträcktider / WinSplits = Temps intermédiaires / WinSplits +Sträcktider = Temps intermédiaires +Sträcktider i kolumner (för standardpapper) = Temps en colonnes (pour imprimante A4) Sträcktider/WinSplits = Temps intermédiaires/WinSplits Sträcktidsfil = Nom du fichier Sträcktidsutskrift = Imprimer les temps intermédiaires Sträcktidsutskrift[check] = Imprimer les temps intermédiaires automatiquement Sträcktilldelning, stafett = Affectation de la combinaison, relais Sträcktyp = Type de combinaison +Stämpelkod = Code du poste Stämpelkod(er) = Poinçons Stämpelkoder = Code de poinçon Stämplar om = Poinçonnage de +Stämpling = Poinçon Stämplingar = Poinçons Stämplingar saknas: X = Poinçons manquants : X Stämplingsautomat = Machine à poinçonner Stämplingsintervall (MM:SS) = Intervalle entre poinçons (MM:SS) +Stämplingsintervall, rogaining-patrull = Intervalle de poinçonnage maximal d'une patrouille Stämplingstest = Test de poinçonnage Stämplingstest [!] = Test de poinçonnage [!] +Stämplingstid = Heure de poinçonnage Stäng = Fermer Stäng tävlingen = Fermer la compétition Större = Plus grand @@ -1018,89 +1792,168 @@ Största intervall i klass = Plus grand intervalle dans la catégorie SubCounter = Compteur secondaire SubSubCounter = Compteur tertiaire Summera = Somme +Support intermediate legs = Supporter les variations spécifiques en relais +Support time from control = Temps depuis le poste +Support time to control = Temps jusqu'au poste +Symboler = Symboles Synkronisera med Eventor = Synchroniser avec Eventor Säkerhetskopiera = Enregistrer sous +Säkerhetskopierar om = Sauvegarde dans +Säkerhetskopiering = Sauvegarde périodique Sätt okända löpare utan registrering till = Définir le statut pour les coureurs non enregistrés Sätt som oparad = Non appairé Sätter reptid (X) och omstartstid (Y) för = Heure d'arrêt des attardés (X) et heure de redémarrage (Y) appliqués pour -Sök = Rechercher Sök (X) = Rechercher (X) +Sök = Rechercher Sök deltagare = Rechercher un coureur Sök och starta automatiskt = Recherche automatique boîtier lecture Sök pÃ¥ namn, bricka eller startnummer = Recherche d'un nom, d'une puce ou d'un numéro de départ +Sök symbol = Recherche de symbole Söker efter SI-enheter = Recherche du boîtier SPORTident TCP: Port %d, Nolltid: %s = TCP: Port %d, Heure initiale: %s TRASIG( = Défectueux( -Ta bort = Supprimer Ta bort / slÃ¥ ihop = Supprimer / Fusionner +Ta bort = Supprimer +Ta bort eventuella avanmälda deltagare = Supprimer les inscriptions annulées si nécessaire Ta bort listposten = Supprimer de la liste Ta bort markerad = Supprimer la sélection Ta bort stämpling = Supprimer le poinçon Ta bort valda rader frÃ¥n tabellen (X) = Supprimer les lignes sélectionnées de la table (X) Tabell = Table +Tabellverktyg = Outils table Tabelläge = Mode table +Tar bort X = Retrait de X Team = Équipe +Team Rogaining = Course au score en équipe TeamBib = Dossard de l'équipe TeamClub = Club de l'équipe +TeamFee = Prix payé par l'équipe +TeamGlobal = Équipe (catégories regroupées) +TeamGrossTime = Temps de l'équipe avant modification TeamLegTimeAfter = Retard de l'équipe au relayeur TeamLegTimeStatus = Temps / statut de l'équipe au relayeur TeamName = Nom de l'équipe TeamPlace = Place de l'équipe +TeamPlaceDiff = Ecart de place de l'équipe (étape courante) +TeamPointAdjustment = Ajustement des points de l'équipe +TeamRogainingOvertime = Dépassement de temps pour l'équipe (course au score) TeamRogainingPoint = Score de l'équipe +TeamRogainingPointTotal = Total des points de l'équipe +TeamRogainingReduction = Réduction du nombre de points pour l'équipe TeamRunner = Nom des membres de l'équipe TeamRunnerCard = Numéro de puce de l'équipe TeamStart = Heure de départ de l'équipe +TeamStartCond = Heure de départ de l'équipe (si individuel) TeamStartNo = Numéro de départ de l'équipe +TeamStartZero = Heure de départ relative de l'équipe (heure zéro) TeamStatus = Statut de l'équipe TeamTime = Temps de l'équipe +TeamTimeAdjustment = Ajustement du temps de l'équipe TeamTimeAfter = Retard de l'équipe TeamTimeStatus = Temps / statut de l'équipe +TeamTotalPlace = Place finale de l'équipe (toutes les étapes) +TeamTotalTime = Temps total de l'équipe (toutes les étapes) +TeamTotalTimeAfter = Retard total de l'équipe (toutes les étapes) +TeamTotalTimeDiff = Ecart total de l'équipe (étape courante) +TeamTotalTimeStatus = Temps total ou statut de l'équipe (toutes les étapes) +Teams and forking = Équipes et variations Telefon = Téléphone Test = Test +Test Result Module = Test du module Test av stämplingsinläsningar = Test de poinçonnage +Testa = Test Testa rösten = Test de synthèse vocale +Testa servern = Tester le serveur Text = Texte Text: X = Texte: X +Texten ska innehÃ¥lla tecknet X, som byts ut mot tävlingsspecifik data = Le texte doit inclure le symbole X, qui est remplacé par les données spécifiques à la compétition Textfiler = Fichiers texte +Textfärg = Couleur du texte +Textjustering = Ajustement du texte Textstorlek = Taille du texte +The forking is fair = Les variations sont équitables +The forking is not fair = Les variations ne sont pas équitables +There is no result module with X as identifier = Aucun module de résultat n'a X comme identifiant Tid = Temps +Tid E[stageno] = Temps E Tid efter: X = Retard: X Tid efter: X; har tagit in Y = Temps après: X; gagné Y Tid efter: X; har tappat Y = Temps après: X; perdu Y -Tid in = Temps à +Tid in = Temps précédent Tid: X, nuvarande placering Y/Z = Temps: X, place actuelle Y/Z +Tidpunkt = Temps +Tidsavdrag = Pénalités Tidsavdrag: X poäng = Pénalité : X points +Tidsförluster (kontroll-tid) = Temps perdu (poste-temps) Tidsgräns = Limite en temps Tidsinmatning = Temps manuels Tidsintervall (MM:SS) = Intervalle de temps (MM:SS) +Tidsintervall (sekunder) = Intervalle de temps (secondes) Tidsjustering = Ajustement de l'heure Tidslinje – X = Chronologie – X Tidsskalning = Echelle de temps +Tidstillägg = Pénalité (M:SS) +Tidszon = Fuseau horaire +Till exempel X = Par exemple X Till huvudsidan = Retour Till kontroll = Au poste +Till sista = Arr. au dernier poste +Till vilka klasser = Pour quelles catégories +Tillagda: X = Ajoutés : X Tilldela = Affecter Tilldela avgifter = Affecter les frais d'inscription Tilldela endast avgift till deltagare utan avgift = Affecter les frais d'inscription uniquement aux coureurs sans frais Tilldela hyrbrickor = Affecter les puces louées Tilldela nummerlappar = Affecter les dossards +Tilldela nya fakturanummer till alla klubbar? = Affecter un nouveau numéro de facture à tous les clubs ? +Tilldela starttider = Attribuer des heures de départ +Tilldelad = Affecté Tilldelning av hyrbrickor = Affecter les puces louées Tillgängliga automater = Services disponibles +Tillgängliga filer installerades. Starta om MeOS. = Les configurations ont été installées. Redémarrez MeOS S.V.P. +Tillgängliga listor = Listes disponibles Tillsatte vakans = Vacants utilisés +Tillsätt = Nommer +Tillsätt tillfälliga anonyma lagmedlemmar = Ajouter des membres d'équipe anonymes temporaires Tillsätt vakans = Remplir les vacants +Tillsätt ytterligare vakans = Remplir un autre vacant Tillämpa parstart = Appairage des départs +TillÃ¥t = Autoriser radios +TillÃ¥t anmälan = Autoriser les inscriptions +TillÃ¥t borttagning av löpare (med mera) som raderats i den importerade tävlingen = Autoriser la suppression de coureurs, etc... qui ont été supprimés dans le fichier importé TillÃ¥t decimaler = Autoriser les décimales TillÃ¥t direktanmälan = Autoriser la saisie rapide +TillÃ¥t gafflingsändringar = Déverrouiller les variations +TillÃ¥t löpare inom en parallell grupp att springa gruppens banor i godtycklig ordning = Autoriser les coureurs d'un groupe parallèle à courir les circuits du groupe dans un ordre quelconque +TillÃ¥t ny klass, behÃ¥ll resultat frÃ¥n annan klass = Autoriser de nouvelles catégories et conserver les résultats des autres catégories +TillÃ¥t ny klass, inget totalresultat = Autoriser de nouvelles catégories mais sans résultat global +TillÃ¥t samma bana inom basintervall = Autoriser le même circuit dans l'intervalle de base (entrelacer les catégories) TillÃ¥t valutauttryck med decimaler = Autoriser les expressions monétaires avec décimales +Time after leg winner = Temps après le vainqueur de la branche +Time as computed by your time method = Temps tel que calculé par votre méthode +Time calculation for runner = Calcul du temps pour un coureur +Time calculation for team = Calcul du temps pour une équipe +Time: X = Temps : X +Timekeeping = Chronométrage +TimingFrom = Nom du point de départ +TimingTo = Nom du point d'arrivée +Tips: ställ in rätt tid innan du lägger till fler grupper = Astuce : Renseignez les bons horaires avant de créer de nouveaux groupes +Tjänstebeställningar (IOF XML) = Service Requests (IOF XML) +Tjänster (IOF XML) = Services (IOF XML) Topplista, N bästa = Podiums, N meilleurs Total = Total Total tävlingsavgift = Recette totale +Total/team result at a control = Résultat total/de l'équipe à un poste TotalCounter = Compteur primaire -Totalresultat = Résultat total Totalresultat - X = Résultat total - X +Totalresultat = Résultat total Totalt = Total +Totalt antal etapper = Nombre total d'étapes +Totalt antal unika avbockade brickor: X = Nombre de puces rendues uniques : X Totalt faktureras = Facturation totale Totalt kontant = Total des espèces Totaltid = Temps total +Track runners in forest = Suivi des coureurs en forêt Trasig = Défectueux Träning = Entrainement TvÃ¥mannastafett = Relais Finlandais @@ -1111,85 +1964,145 @@ Typ av lista = Type de liste Typsnitt = Police Tävling = Compétition Tävling frÃ¥n Eventor = Compétition depuis Eventor +Tävling med lag = Compétition en équipe Tävlingen innehÃ¥ller inga resultat = Il n'y a pas encore de résultat +Tävlingen mÃ¥ste avgöras mellan X och Y = La compétition doit se dérouler entre le X et le Y Tävlingen mÃ¥ste ha ett namn = Un nom doit être donné à la compétition +Tävlingens ID-nummer = Identifiant de la compétition +Tävlingens namn = Nom de la compétition Tävlingens namn: X = Le nom de la compétition est : X Tävlingsdata har sparats = Les données de la compétition ont été sauvées -Tävlingsinställningar = Configuration de la compétition Tävlingsinställningar (IOF, xml) = Configuration de la compétition (IOF, xml) +Tävlingsinställningar = Configuration de la compétition Tävlingsnamn = Nom de la compétition Tävlingsrapport = Rapport sur la compétition Tävlingsregler = Règles de la compétition Tävlingsstatistik = Statistiques de la compétition +Töm = Effacer +Töm databasen = Effacement des données +URL = URL +URL mÃ¥ste anges = URL manquant +Ultra Long = Ultra Longue +Underfilter = Sous filtre Underlag för tävlingsavgift = Données pour les frais d'inscription de la compétition +Underlag saknas för bomanalys = Aucune donnée pour les erreurs de poste Underlista = Sous liste Underrubrik = Sous-titre Undre datumgräns = Première date limite Undre gräns (Ã¥r) = Limite basse (années) Undre Ã¥lder = Age minimal +Unexpected Fee = Tarifs d'inscription inattendus +Unfair control legs = Branche non équitable Ungdom = Jeune Ungdomsavgift = Tarif jeunes Ungdomsklasser = Catégories jeunes +Unknown symbol X = Symbole inconnu X +Unroll split times for loop courses = Dérouler les temps intermédiaires pour les circuits en boucle. Uppdatera = Mise à jour Uppdatera alla klubbar = Mise à jour de tous les clubs -Uppdatera alla värden i tabellen = Mise à jour de la table Uppdatera alla värden i tabellen (X) = Rafraîchir les valeurs de la table (X) +Uppdatera alla värden i tabellen = Mise à jour de la table Uppdatera frÃ¥n Eventor = Mise à jour depuis Eventor Uppdatera fördelning = Mise à jour de la distribution Uppdatera fördelningen av starttider med hänsyn till manuella ändringar ovan = Mise à jour de la diffusion des horaires de départ en prenant en compte les changements manuels +Uppdatera inte starttiden vid startstämpling = Ne pas mettre à jour l'horaire de départ avec le poinçon de départ Uppdatera klubbar && löpare = Mise à jour des clubs et coureurs Uppdatera klubbarnas och löparnas uppgifter med data frÃ¥n löpardatabasen/distriktsregistret = Mise à jour des clubs et coureurs en utilisant la base de données des coureurs Uppdatera klubbarnas uppgifter med data frÃ¥n löpardatabasen/distriktsregistret = Mise à jour des clubs en utilisant la base de données des coureurs Uppdatera klubbens uppgifter med data frÃ¥n löpardatabasen/distriktsregistret = Mise à jour du club en utilisant la base de données des coureurs Uppdatera löpardatabasen = Mise à jour de la base de données des coureurs -Urval = Filtrer +Uppdaterade: X = Modifiés : X Urval %c%s = Filtrer %c%s +Urval = Filtrer +Use French Federation of Orienteering mapping = Utiliser le format de la Fédération Française de CO +Use initials in names = Utiliser les initiales comme noms +User input number = Paramètre saisi par l'utilisateur Utan inställningar = Pas de configuration Utan tidtagning = Pas de chronométrage Utbyt tävlingsdata med Eventor = Echange des données de la compétition avec Eventor Utför lottning = Effectuer le tirage au sort Utfört = Fait Utg. = Aband. +UtgÃ¥tt = Aband. +Uthyrda brickor som inte avbockats = Puces louées non rendues +Uthyrda: X, Egna: Y, Avbockade uthyrda: Z = Puces louées : X, Puces personnelles : Y, Louées et rendues : Z +Utom tävlan = NC +Utrymme: X = Taille : X +Utseende = Affichage Utskrift / export = Imprimer / exporter +Utskrift = Imprimer Utskriftsintervall (MM:SS) = Intervalle d'impression (MM:SS) Utökat protokoll = Protocole étendu VALFRI( = UnParmis( +Vacancies and entry cancellations = Places disponibles et annulation des inscriptions Vak. ranking = Classement des vacants -Vakanser = Vacants +Vakanser - X = Vacants - X Vakanser / klassbyte = Changements tardifs +Vakanser = Vacants Vakanser och efteranmälda = Vacants et retardataires Vakanser stöds ej i stafett = Les vacants ne sont pas supporté en relais +Vakansplacering = Emplacement des vacants Vakant = Vacant Val av export = Choisir Export Valbar = Optionnel Vald bricka = Puce choisie +Valfri = Optionnel Valuta = Devise Valutakod = Code devise Valutasymbol = Symbole monétaire Valutasymbol före = Symbole monétaire devant la valeur -Varning: Deltagaren 'X' finns inte = Attention: Le coureur 'X' n'existe pas -Varning: Laget 'X' finns inte = Attention: L'équipe 'X' n'existe pas +Variabler = Variables Varning: Banan 'X' finns inte = Attention: le circuit 'X' n'existe pas Varning: Banan 'X' förekommer flera gÃ¥nger = Attention: Le circuit 'X' est définie plus d'une fois +Varning: Brickan X används redan av Y = Attention ! La puce X est déjà utilisée par Y +Varning: Deltagaren 'X' finns inte = Attention: Le coureur 'X' n'existe pas +Varning: Följande deltagare har ett osäkert resultat = Attention : les informations sur ce coureur ne sont pas claires Varning: Ingen organisatör/avsändare av fakturan angiven (Se tävlingsinställningar) = Attention: Aucun organisateur défini (Voir Configuration de la compétition) Varning: Inget kontonummer angivet (Se tävlingsinställningar) = Attention: Pas de compte défini (Voir Configuration de la compétition) Varning: Inget sista betalningsdatum angivet (Se tävlingsinställningar) = Attention: Aucune date limite de paiement définie (Voir Configuration de la compétition) +Varning: Kartorna är slut = Attention : plus de cartes disponibles +Varning: Kunde inte hitta föregÃ¥ende version av tävlingen (X) = Attention : impossible de trouver la version précédente de la compétition +Varning: Laget 'X' finns inte = Attention: L'équipe 'X' n'existe pas +Varning: Olika bastävlingar = Attention : la compétition de base n'est pas la même sur les fichiers +Varning: avgiften kan ej faktureras = Attention : impossible de générer de facture pour ce montant Varning: deltagare med blankt namn pÃ¥träffad. MeOS kräver att alla deltagare har ett namn, och tilldelar namnet 'N.N.' = Attention: Un coureur sans nom a été détecté. MeOS a besoin d'un nom, et a affecté le nom 'N.N.' Varning: lag utan namn pÃ¥träffat. MeOS kräver att alla lag har ett namn, och tilldelar namnet 'N.N.' = Attention: Une équipe sans nom a été détectée. MeOS a besoin d'un nom et a affecté le nom 'N.N.' +Varning: ändringar i X blev överskrivna = Attention: les changements dans X ont été écrasés +Varvningskontroll = Poste commun +Varvräkning = Compter les tours +Varvräkning med mellantid = Compter les tours en temps supplémentaire +Vem fÃ¥r anmäla sig = Qui peut s'inscrire Verkställ = Confirmer +Verktyg = Outils Version X = Version X Vi stöder MeOS = Nous soutenons MeOS Viktiga händelser = Evènements importants +Vill du använda den nya brickan till alla etapper? = Voulez-vous utiliser une nouvelle puce pour toutes les étapes ? +Vill du att X gÃ¥r in i laget? = Voulez-vous mettre X dans l'équipe ? +Vill du att X och Y byter sträcka? = Voulez-vous que X et Y changent de variation ? +Vill du att X tar sträckan istället för Y? = Voulez-vous que X courre cette variation à la place de Y ? +Vill du dumpa aktuellt tävling och skapa en testtävling? = Voulez-vous faire un dump de la compétition courante et créer une compétition de test ? Vill du flytta löpare frÃ¥n X till Y och ta bort Z? = Voulez-vous déplacer les coureurs de X vers Y et supprimer Z ? +Vill du göra om avbockningen frÃ¥n början igen? = Voulez-vous réinitialiser et tout recommencer ? Vill du klistra in X nya rader i tabellen? = Voulez-vous coller X nouvelles lignes dans la table ? +Vill du koppla isär X frÃ¥n inläst bricka Y? = Voulez-vous délier X de na puce numéro Y ? Vill du lägga till banan 'X' (Y)? = Souhaitez vous ajouter le circuit 'X' (Y)? Vill du lägga till deltagaren 'X'? = Souhaitez vous ajouter le coureur 'X'? Vill du lägga till klassen 'X'? = Souhaitez vous ajouter la catégorie 'X'? Vill du lägga till laget 'X'? = Souhaitez vous ajouter l'équipe 'X'? +Vill du nollställa alla manuellt tilldelade banor? = Voulez-vous effacer tous les circuits manuellement attribués ? Vill du radera X rader frÃ¥n tabellen? = Voulez-vous supprimer X lignes de la table ? Vill du radera alla vakanser frÃ¥n tävlingen? = Voulez-vous supprimer tous les vacants de la compétition ? Vill du skapa en ny klass? = Voulez-vous créer une nouvelle catégorie ? Vill du spara ändringar? = Voulez-vous enregistrer les changements ? +Vill du sätta hyrbricka pÃ¥ befintliga löpare med dessa brickor? = Voulez-vous distribuer les puces comptées comme louées à des coureurs déjà inscrits ? +Vill du sätta resultatet frÃ¥n tidigare etapper till ? = Voulez-vous modifier le résultat des étapes précédentes en ? +Vill du ta bort 'X'? = Voulez-vous supprimer 'X'? +Vill du ta bort alla klubbar frÃ¥n tävlingen? Alla deltagare blir klubblösa = Souhaitez-vous effacer tous les clubs de la compétition ? Aucun coureur n'aura de club. +Vill du ta bort brickan frÃ¥n hyrbrickslistan? = Voulez-vous retirer la puce de la liste des puces à louer ? +Vill du ta bort schemat? = Voulez-vous supprimer le schéma ? +Vill du tömma listan med hyrbrickor? = Voulez-vous supprimer la liste des puces à louer ? +Vill du uppdatera alla nummerlappar? = Voulez-vous mettre à jour tous les dossards ? Vill du verkligen radera alla starttider i X? = Voulez-vous vraiment effacer les horaires de départ dans X? Vill du verkligen radera starttider i X klasser? = Voulez-vous vraiment effacer les horaires de départ de la catégorie X ? Vill du verkligen radera tävlingen? = Souhaitez-vous supprimer la compétition ? @@ -1199,23 +2112,32 @@ Vill du verkligen ta bort löparen? = Souhaitez-vous supprimer le coureur ? Visa = Afficher Visa alla = Afficher tout Visa avancerade funktioner = Afficher en mode avancé +Visa detaljerad rapport för viss deltagare = Afficher le rapport détaillé pour un coureur spécifique Visa en tabell över alla stämplingar = Afficher la table avec les poinçons Visa klubbdatabasen = Afficher la base de données des clubs Visa listan i fullskärm = Afficher la liste en plein écran Visa löpardatabasen = Afficher la base de données des coureurs Visa mellantider = Afficher les temps intermédiaires Visa och hantera löpardatabasen = Afficher et gérer la base des coureurs +Visa rubrik = Afficher le titre +Visa rubrik mellan listorna = Afficher le titre entre les listes +Visa rullande tider mellan kontroller i helskärmsläge = Afficher les temps s'écoulant entre deux postes en mode plein écran Visa senast inlästa deltagare = Afficher le coureur de la dernière puce lue Visa startlistan = Afficher la liste des départs Visa tillgängliga säkerhetskopior = Afficher les sauvegardes disponibles Visa valda deltagare = Afficher les coureurs sélectionnés Visar de X bästa = Affichage des X meilleurs +Visning = Mode d'affichage +Visningsinställningar för 'X' = Paramètres d'affichage pour 'X' +Visningstid = Afficher le temps +Vissa inställningar kräver omstart av MeOS för att ha effekt = Certains paramètres nécessitent le redémarrage de MeOS pour prendre effet Visualisera startfältet = Visualisation des champs de départ Vuxen = Adulte Vuxenklasser = Catégories adultes Vuxna = Adultes Välj Spara för att lagra brickorna. Interaktiv inläsning är INTE aktiverad = Cliquer sur pour enregistrer les puces. La lecture interactive n'est pas activée Välj Spara för att lagra brickorna. Interaktiv inläsning är aktiverad = Cliquer sur pour enregistrer les puces. La lecture interactive est activée +Välj X = Sélectionner X Välj alla = Sélectionner tout Välj alla klasser = Sélectionner toutes les catégories Välj allt = Sélectionner tout @@ -1223,6 +2145,8 @@ Välj automatiskt = Sélection automatique Välj den etapp som föregÃ¥r denna tävling = Sélectionner l'étape précédente Välj den etapp som kommer efter denna tävling = Sélectionner l'étape suivante Välj en vakant plats nedan = Choisissez une place vacante ci-dessous +Välj etapp att importera = Sélectionner l'étape à importer +Välj frÃ¥n lista = Sélection détaillée Välj ingen = Désélectionner Välj inget = Désélectionner Välj klass = Sélectionner la catégorie @@ -1230,6 +2154,7 @@ Välj klass och starttid nedan = Choisissez la catégorie et l'heure de départ Välj klasser = Choisir les catégories Välj klasser där alla löpare saknar starttid = Sélectionner les catégories où aucun coureur n'a d'heure de départ Välj klasser där nÃ¥gon löpare saknar starttid = Sélectionner les catégories où des coureurs n'ont pas d'heure de départ +Välj klasser med nya anmälningar = Spécifiez les catégories pour lesquelles de nouvelles inscriptions sont autorisées Välj kolumner = Choisir les colonnes Välj kolumner att visa = Choisir les colonnes à afficher Välj kolumner för tabellen X = Choisir les colonnes pour le tableau X @@ -1240,34 +2165,55 @@ Välj löpare att prioritera bevakning för = Sélectionner les coureurs à priv Välj löpare för sträcka X = Définir le coureur pour la variation X Välj skrivare = Choisir une imprimante Välj tävling = Choisir une compétition +Välj vilka funktioner du vill använda = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition Välj vilka klasser och kontroller du vill bevaka = Choisir les catégories et les postes que vous souhaitez observer Välj vilka klasser och kontroller som bevakas = Sélectionner les catégories et les postes à observer Välj vilka kolumner du vill visa = Choisir les colonnes à afficher +Välj vilken typ du vill importera = Sélectionnez le type d'identifiant à importer Välj vy = Choisir la vue Välkommen till MeOS = Bienvenue dans MeOS Vänligen betala senast = Merci de régler avant le Vänligen Ã¥terlämna hyrbrickan = Merci de rendre votre puce de location +Vänster = Gauche +Växel = Passage Växling = Changement Webb = Document Web -Webbdokument = Document Web Webbdokument (html) = Document Web (html) +Webbdokument = Document Web Webben (html) = Le web (html) +Without courses = Sans circuit X (Saknar e-post) = X (n'a pas de courriel) X (Y deltagare, grupp Z, W) = X (Y coureurs, groupe Z, W) +X (press Ctrl+Space to confirm) = X (Appuyez sur + pour confirmer) +X anmälda = X inscrits +X gÃ¥r vidare, klass enligt ranking = X qualifiés, catégorie par le ranking +X har en tid (Y) som inte är kompatibel med förändringen = X a une heure de départ (Y) ce qui n'est pas compatible avec ce changement +X har redan bricknummer Y. Vill du ändra det? = X a déjà la puce Y. Voulez-vous la changer ? +X har redan ett resultat. Vi du fortsätta? = X a déjà un résultat. Souhaitez-vous continuer ? X har startat = X est parti X kontroller = X postes -X meter = X mètres X m = X m +X meter = X mètres +X och Y[N by N] = X par Y +X p = X p +X platser. Startar Y = X places. Départ de Y X poäng fattas = X points manquant X rader kunde inte raderas = X lignes ne peuvent être effacées X senaste = X derniers +X är inget giltigt index = X n'est pas un index valide +X är inget giltigt sträcknummer = X n'est pas un numéro de variation valide X: Y. Tryck för att spara = X: Y. Appuyez sur pour enregistrer +X:e = X:ème +Year of birth = Année de naissance +Youth Cup Special = Youth Cup Special +Youth Cup X = Youth Cup X Zooma in (Ctrl + '+') = Zoomer (Ctrl + '+') Zooma ut (Ctrl + '-') = Dézoomer (Ctrl + '-') [Bevaka] = [Observer] -[Flytta ner] = [Descendre] [Bort] = [Descendre] +[Flytta ner] = [Descendre] [Klassens bana] = [De la catégorie] +[Radera] = [Supprimer] [Uppdaterad anmälan] = [Mise à jour de l'inscription] [VARNING] ingen/okänd = [ATTENTION] aucun/inconnu [Ã…terställ] = [Restaurer] @@ -1275,21 +2221,41 @@ andra = seconde ask:addpunches = Aucune puce n'a été lue pour ce coureur. Voulez-vous ajouter des poinçons manuellement ? ask:changedclassfee = Le tarif a été modifié pour certaines catégories. Voulez-vous appliquer les nouveaux tarifs aux coureurs déjà présents dans ces catégories ?\n\nAttention: les frais d'inscription affectés manuellement seront écrasés. ask:changedcmpfee = Les tarifs ont été modifiés. Voulez-vous appliquer les nouveaux tarifs aux coureurs et classes existantes ?\n\nAttention les frais d'inscription affectés manuellement seront écrasés. +ask:cleardb = Voulez-vous effacer les données club et coureurs ? +ask:convert_to_patrol = Certaines catégories contiennent des requêtes pour que certains coureurs aient la même heure de départ. Voulez-vous convertir ces catégories en catégories en binôme (type raid) ? ask:firstasstart = Il existe des coureurs ayant des résultats pour ce circuit. Si vous utilisez le premier poste comme départ, les heures de départ seront écrasées.\n\nSouhaitez-vous continuer ? +ask:hasVacant = Il y a toujours des vacants.\n\nVoulez-vous retirer tous les vacants avant d'exporter les résultats ? +ask:importcopy = Une compétition (X) ayant la même origine existe déjà. Vous pouvez importer la compétition comme une version de celle xistante, ou comme une copie indépendante. S'il s'agit de la même compétition avec des modifications, il est préférable de l'importer en tant que version. ask:kiosk = Quand vous démarrez le kiosque de résultats, vous mettez MeOS dans un mode où il est uniquement possible d'afficher les résultats. Aucune autre opération n'est autorisée jusqu'à ce que le programme soir redémarré. S'il y a un boîtier SI actif raccordé à l'ordinateur, MeOS affichera automatiquement les résultats pour la dernière puce lue.\n\nVous devriez penser à protéger la base de donnée avec un mot de passe, si la diffusion est rendue publique.\n\nVoulez-vous démarrer la diffusion des résultats ? +ask:loadspeaker = Voulez-vous réorganiser les fenêtres et paramètres comme enregistré précédemment sur cet ordinateur ? ask:missingcourse = Des catégories (X) n'ont pas de circuit.\n\nMeOS utilise les circuits lors du tirage pour éviter que les coureurs ayant le même premier poste ne partent en même temps.\n\nVoulez-vous continuer tout de même ? +ask:outofmaps = Plus de cartes disponibles. Voulez-vous tout de même inscrire ce coureur ? ask:overwrite_server = La compétition est déjà sur le serveur. Voulez-vous écraser la compétition présente sur le serveur ? ask:overwriteconfirm = Vous avez choisi d'écraser la compétition. Vérifiez que personne d'autre n'est connecté.\n\nSouhaitez vous continuer ? +ask:overwriteresult = X a déjà des résultats. Voulez-vous les écraser ? +ask:removescheme = Si vous retirez le schéma de qualification, les résultats seront perdus. Voulez-vous continuer ? ask:repair = Effectuez une réparation de la base de données uniquement si vous rencontrez des problèmes.\n\nImportant:\n- Assurez-vous que personne d'autre n'est connecté à la base.\n- Si le serveur plante ou s'arrête pendant la réparation, vous devez le redémarrer et réessayer la réparation avant d'effectuer quoi que ce soit d'autre. Si vous faites d'autres opération avec la base de données toutes les données seront perdues.\n\nSouhaitez-vous essayer une réparation maintenant ? +ask:savespeaker = Voulez-vous sauvegarder les paramètres d'affichage et de catégorie sur cet ordinateur ? +ask:updatelegs = Les longueurs des variations individuelles peut nécessiter une mise à jour après ce changement.\n\nSouhaitez-vous corriger cela maintenant ? +ask:updatetimes = Voulez-vous conserver autant que possible les horaires de départ déjà affectés ? Répondez Non pour décaler la compétition dans le temps +ask:usecourseinclass = Le circuit n'est utilisé par aucun autre coureur dans cette catégorie\n\nVoulez-vous tout de même l'utiliser ? backup = sauvegarde +blue channel = Réseau bleu c/o = Représenté par check (X) = Vérification de (X) +classcourseresult = Résultats par catégorie et par circuit +delar placering med X = est à égalité avec X +documentation = meos_doc_eng.html +edit_in_forest = Gérer\nCompétiteurs en forêt ej aktiv = inactif elfte = onzième elva = onzième +encoding = codage +error:invalidmethod = La méthode sélectionnée ne génère pas de distribution. Les données de répartition sont insuffisantes. ett Mycket Enkelt OrienteringsSystem = un logiciel GEC bien plus simple eventor:help = Si vous utilisez MeOS pour la CO en Suède, nous recommandons que vous utilisiez les fonctionnalités de connexion Eventor. eventor:question = X\n\nSouhaitez-vous utiliser la connexion à Eventor ? +false[boolean] = faux femma = cinquième femte = cinquième fjärde = quatrième @@ -1299,6 +2265,7 @@ gÃ¥r i mÃ¥l pÃ¥ X plats med tiden Y = termine X en Y gÃ¥r i mÃ¥l pÃ¥ X plats, efter Y, pÃ¥ tiden Z = termine X, derrière Y, en Z gÃ¥r i mÃ¥l pÃ¥ delad X plats med tiden Y = finit ex-aequo en Xè place, en Y gÃ¥r upp i delad ledning med tiden X = partage la tête de la course en X +gÃ¥r upp i delad ledning vid X med tiden Y = partage la tête de la course au poste X, en Y handskakning = authentification har startat = a démarré help:10000 = Un service dans MeOS est un petit programme qui, de temps à autre ou lorsque les données de la compétition changent, fait des choses automatiquement. @@ -1333,59 +2300,182 @@ help:7620 = Intervalle (secondes). Laisser le champ vide pour qu'il soit mis à help:89064 = Pour chaque poste, vous devez spécifier un ou plusieurs numéro de code (codes SI). Dans un circuit, vous faites référence à un poste par son identifiant (ID). Habituellement vous n'avez pas besoin d'ajouter des postes manuellement puisque MeOS ajoute automatiquement tous les postes nécessaires.\n\nL'utilisation de plus d'un code SI est utile lorsque l'on veut remplacer un boîtier défectueux ou pour créer des fourches simples. Pour un poste ordinaire, il est exigé que le coureur poinçonne un des postes spécifiés. Si le statut du poste est , tous les postes spécifiés doivent être poinçonnés (dans un ordre quelconque). Si le statut est , le boîtier est ignoré.\n\nSi vous spécifiez un nom de poste, il est possible d'imprimer les résultats avec les temps intermédiaires aux postes nommés.\n\nUn réajustement de l'heure du poste peut être effectué s'il apparaît que le boîtier n'était pas à l'heure. Le format de l'heure est +/-MM:SS ou +/-HH:MM:SS.\n\nLe temps de branche le plus court définit le temps le plus court possible sur cette branche. Aucun concurrent n'aura un temps plus court pour aller à ce poste, aussi rapide soit-il. Cela peut être utilisé, par exemple, si une route dangereuse doit être traversée.\n\nLe statut signifie que le temps pour aller au poste est ignoré; le temps total sera le même quel que soit le temps réellement mis pour se rendre au poste. help:9373 = Donnez un ou plusieurs numéro de postes (codes SI) utilisés pour ce poste.\nExemple: 31, 32, 33. help:9615 = Aucune réponse reçue. Voulez-vous ouvrir le port en mode passif ? MeOS doit-il être à l'écoute de poinçons à venir ? +help:DirectResult = - S'il n'y a pas de circuit, le statut est mis à OK sur le poinçon d'arrivé.\n- S'il y a des circuits, les poinçons radio sont utilisés comme postes. Aucune lecture de puce n'est nécessaire. +help:LockStartList = MeOS ne va mas modifier les heures de départ d'une catégorie verrouillée, même si les résultats des qualifications sont modifiées +help:analyzecard = Cette fonction vous permet d'imprimer les données de la puce sans utiliser une quelconque compétition, comme le ferait une borne d'impression autonome. Sélectionner 'Imprimer les temps intermédiaires' pour choisir et configurer l'imprimante.\n\nLes puces sont également conservées en mémoire (mais pas dans la compétition). Vous pouvez éditer le nom et le club pour une puce en cliquant le nom (ou 'inconnu'). Vous pouvez également enregistrer les puces dans un fichier (Enregistrer) ou créer une nouvelle compétition à partir des données des puces. Notez que si une compétition est ouverte, vous devez la fermer pour rendre cette option disponible. +help:anonymous_team = Créer et nommer des membres (temporaires) d'équipe pour toutes les équipes, auxquels vous pouvez affecter une puce, un circuit, etc. help:assignfee = MeOS va prendre en charge automatiquement pour vous les droits d'inscription dans la plupart des cas. Le tarif est basé sur l'âge et la date d'inscription des coureurs (vous pouvez définir les limites dans Configuration de la compétition). Chaque catégorie définit un tarif. Vous fournissez une valeur par défaut pour différentes catégories dans Configuration de la Compétition, mais vous pouvez également reconfigurer la catégorie en utilisant Configuration Rapide pour cette catégorie.\n\nCette page vous permet d'utiliser différentes limites en âges et date limites d'inscription pour différents tarifs. Sur la page des Coureurs, vous pouvez ajuster manuellement le tarif pour chaque coureur en cas de besoin. +help:assignforking = Cette fonction calcule un jeu de variation optimal pour les circuits sélectionnés. Affecter un ou plusieurs circuits aux branches en sélectionnant les circuits et les branches à partir des listes ci-dessus. Tous les circuits peuvent avoir le même ensemble de circuits (même variation) ou bien utiliser divers jeux de circuits pour différentes variations. De même dans ce cas, MeOS va calculer les variations de ces circuits entre eux, si les circuits le permettent. help:baudrate = Vitesse de transmission (baudrate) : utilisez 4800 ou 38400. -help:computer_voice = Un poinçon arrivant est mis en correspondance avec un numéro de départ et joue le fichier où N est le numéro de départ. Les fichiers sont situés dans le répertoire ci-dessous. Si le coureur/équipe a une nationalité NAT d'affectée, MeOS essaie en priorité de jouer le fichier , qui se doit de contenir le nombre dans la version de langue appropriée. +help:bibs = Vous pouvez gérer les dossards manuellement ou automatiquement. Ici vous pouvez affecter les dossards manuellement pour une certaine catégorie en spécifiant la méthode Manuelle et en fournissant le premier numéro pour cette catégorie.\n\nLa méthode automatique fonctionne de la même façon, avec la différence que MeOS mettra à jour les dossards de toutes les catégories d'un coup. Bien qu'il soit possible de faire ce paramétrage ici, il est préférable d'utiliser le Paramétrage rapide pour les catégories afin d'avoir une vue d'ensemble de toutes les catégories.\n\nUtiliser la méthode Automatique avec les méthodes Aucun ou Consécutifs, qui indique que le dernier numéro de la catégorie précédente est utilisé comme premier numéro. Le nombre de dossards réservés définit le saut de numérotation entre catégories.\n\nPour les catégories d'équipes vous pouvez spécifier la relation existant entre les numéros de dossard des équipiers et celui de l'équipe. Il peut être Identique, Indépendant, Croissant (Équipe 1: 101, 102, 103, 104, Équipe 2: 111, 112, 113, 114 etc.) ou par Combinaison (100-1, 100-2, 100-3 etc). +help:checkcards = Utiliser cette fonction pour effectuer le suivi des puces louées et vérifier qu'elles ont toute été rendues. Raccorder un boîtier maître SI (de préférence configuré en tant que boîtier contrôle ou d'arrivée car cela est plus rapide qu'en mode lecture de puce), et poinçonner toutes les puces rendues. Cliquer sur le bouton Rapport pour voir si des puces sont manquantes.\n\n La vérification est locale à cet ordinateur et ne modifie pas les données de la compétition. +help:computer_voice = Un poinçon arrivant est mis en correspondance avec un numéro de départ et joue le fichier où N est le numéro de départ. Les fichiers sont situés dans le répertoire ci-dessous. Si le coureur/équipe a une nationalité NAT d'affectée, MeOS essaie en priorité de jouer le fichier , qui se doit de contenir le nom dans la version de langue appropriée. +help:custom_text_lines = Vous pouvez insérer du texte spécifique en ajoutant en dessous [DonnéeSpécifique]. Les infos disponibles sont visibles dans le tableau déroulant à droite.\n\nPar exemple : Bravo [RunnerName] ! help:dbage = La base de donnée des coureurs date de plus de deux mois. Souhaitez vous télécharger une nouvelle base à partir d'Eventor ? help:duplicate = Faire une copie locale de cette compétition. help:eventorkey = Entrez la clé Eventor de votre club (spécial Suède). Vous pouvez obtenir la clé auprès de l'administrateur Eventor de votre club. +help:exportdraw = Vous pouvez exporter un tableur en CSV avec les catégories, le nombre d'inscrits et les paramètres des listes de départ par catégories. Il est ensuite possible d'éditer ces données et de les ré-importer dans MeOS pour créer les listes de départ. help:fullscreen = Vous pouvez ajuster la vitesse de défilement en utilisant Ctrl+M (augmente) et Ctrl+N (diminue). Pour sortir du mode plein écran, appuyez sur Esc. help:import_entry_data = Vous pouvez importer des coureurs, des catégories, des clubs et des inscriptions à partir de divers formats texte et XML. Il n'est pas nécessaire de fournir tous les fichiers ci-dessous. Par exemple, un fichier CSV de OE avec les inscriptions contient les clubs et les catégories, aussi dans ce cas ces champs devraient-ils être laissés vides.\n\nSi le même coureur est importé plusieurs fois vous n'obtiendrez pas plusieurs copies de ce coureur, mais son inscription sera modifiée. Cela signifie qu'il est sans danger de ré-importer ou d'importer un fichier d'inscription qui a été étendu. help:importcourse = Vous pouvez importer des circuits et des catégories à partir (par exemple) d'exports OCAD ou Condes. +help:liveresultat = Cette méthode démarre un chronomètre en mode plein écran quand un coureur d'une catégorie sélectionnée poinçonne le poste , et mesure le temps jusqu'à ce que le poste soit atteint. Sinon la liste des meilleurs temps est affichée. Les deux postes doivent bien sûr être des postes radio et si vous utilisez un réseau, vérifiez bien que vous avez activé pour obtenir rapidement des temps les plus précis possibles. +help:long_times = La date de compétition est la date à laquelle toutes les catégories commencent. L'heure zéro est à minuit. +help:merge = Vous pouvez fusionner les compétitions et les résultats tant qu'ils sont issus des mêmes circuits et des mêmes postes. Différents groupes de coureurs peuvent être ajoutés à la compétition, ou même plusieurs fichiers course peuvent être fusionnés en une seule compétition pour n'avoir qu'une liste de résultat. De même, il est possible d'avoir des lieux de course différents en fonction des catégories, mais qu'il ne soit pas possible de mettre toutes les GEC dans un réseau unique. Vous pouvez alors échanger régulièrement les fichiers de chaque lieu de course pour mettre à jour la course.\n\n1. Préparez la compétition globale, pour toutes les catégories.\n\n2. Enregistrez une copie de la compétition et importez-là dans les GEC des différents lieux de course (sur un PC unique ou dans un réseau local).\n\n3. Pour transférer les modifications , exportez la compétition depuis chaque GEC sur site, et fusionnez les fichiers ici. Exportez ensuite une copie depuis la GEC globale et importez le fichier dans chaque GEC sur site.\n\n4. Cette procédure peut être répétée autant de fois que nécessaire pour mettre à jour la compétition.\n\nNote : Si vous faites des modifications, par exemple sur un coureur depuis plusieurs endroits différents, des données risquent d'être écrasées sans avertissement. Assurez-vous que chaque GEC locale ne traite que les informations qui la concerne directement.\n\nAstuce : Testez les transferts de données en amont de la compétition en modifiant quelques éléments bien déterminée pour vous assurer que la course a été paramétrée correctement. help:ocad13091 = Si vous avez accès aux circuits (par exemple à partir d'OCAD ou Condes) vous pouvez fournir les fichiers contenant les circuits ici. Autrement, vous pourrez ajouter les circuits ultérieurement. +help:onlineinput = Le service est utilisé pour recevoir les poinçons radio depuis Internet, par exemple un poste radio raccordé à l'aide d'un téléphone sans fil. Il est également possible de créer un formulaire en ligne où les numéros de dossard seront saisis manuellement au fur et à mesure des passages.\n\nLe protocole du service supporte également d'autres moyens de saisie, tels que les équipes [team line-up], des saisies directes, des changements de puce etc. Si vous voulez développer vos propres services, vous trouverez de la documentation et des exemples sur le site web de MeOS : www.melin.nu/meos. +help:onlineresult = Le service est utilisé pour envoyer automatiquement les résultats et les listes de départ sur Internet pour publication immédiate dans des formulaires. Vous devez créer des configurations adaptées au service distant que vous voulez utiliser : le fournisseur du service distant vous fournira tous les détails utiles.\n\nSi vous voulez développer vos propres services, vous trouverez de la documentation et des exemples sur le site web de MeOS : www.melin.nu/meos. +help:paymentmodes = Vous pouvez définir des modes de paiement personnalisés, en complément des informations de facturation, afin de faciliter la comptabilité. +help:registerhiredcards = Pré-inscrivez des puces comme puces louées pour affecter automatiquement le statut et le tarif correspondant quand cette puce est affectée. help:relaysetup = Utilisez le guide ci-dessous pour choisir parmi les formulaires de compétitions prédéfinis. Après avoir appliqué la configuration, il est possible d'adapter manuellement la configuration pour chaque branche et configurer les circuits.\n\nQuelques explications :\n- Relais est utilisé pour différent type de relais.\n- Relais par paire signifie que deux coureurs forme une équipe et courent à tour de rôle.\n- Un relais en avec un coureur Open est parfois utilisé dans les catégories jeunes et permet d'avoir plus d'un coureur sur certains partiels. (le premier coureur change d'une fois à l'autre).\n- Une patrouille peut s'effectuer avec une ou deux puces.\n- Prologue et poursuite est une compétition individuelle mais constitué de deux courses.\n- Un jeu de circuit signifie qu'il y a plusieurs variantes, mais qu'il n'est pas décidé à l'avance qui court sur quelle variante; la décision est prise automatiquement lorsque le coureur a terminé. +help:rest = MeOS REST API vous permet d'accéder à la compétition via le web. Vous pouvez afficher les résultats directement sur un navigateur, mais aussi exporter les données de la course en XML pour les envoyer vers d'autres applications et programmes. help:restore_backup = Choisissez une sauvegarde à restaurer en cliquant la date à laquelle la sauvegarde a été faite. help:runnerdatabase = En important une base de donnée de clubs et de coureurs, MeOS reconnaitra automatiquement les coureurs inconnus (par leur numéro de puce), et vous aurez les adresses et numéros de téléphone du club. help:save = MeOS sauve automatiquement toutes les configurations lorsque c'est nécessaire. +help:seeding_info = L'allocation répartie des heures de départ signifie qu'un résultat ou un classement précédent contrôle en partie le processus. Dans le champ Groupes de répartition, vous pouvez entrer une taille de groupe unique, ce qui indique que la catégorie entière est à partitionner dans des groupes de cette taille. La taille de groupe "1" indique que l'ordre de répartition est rigoureusement respecté. Vous pouvez également spécifier plusieurs tailles de groupes. "15, 1000" signifiera un groupe de répartition contenant les 15 coureurs les mieux placés et les autres coureurs (au plus 1000) seront placés dans un groupe non réparti. +help:selectsound = Sélectionnez les sons à lancer. Par défaut, les sons préinstallés de MeOS sont sélectionnés. +help:simulate = Ce service vous permet de simuler des lectures de puces. Des temps et des poinçons sont générés pour tous les participants. Même les postes radio peuvent être simulés.\n\nATTENTION: A n'utiliser que pour les tests. Si vous utilisez cette fonctionnalité sur une vraie course, elle sera corrompue. help:speaker_setup = Choisissez les catégories et circuits que vous voulez surveiller. help:speakerprio = Cochez les coureurs/équipes que vous souhaitez surveiller dès le départ et tant que tout va bien. Mettre deux coches pour surveiller même si le résultat n'est plus très bon. Aucune coche signifie que la surveillance n'est activée que si le coureur/l'équipe a de bons résultats (donc pas forcément depuis le départ). help:splitexport = Décidez si vous voulez exporter les résultats individuellement ou globalement pour chaque course. Si vous choisissez d'exporter toutes les courses, des fichiers numérotés seront créés. +help:startgroup = Les groupes de départ servent à contrôler la répartition des départs. Les coureurs d'un même groupe de départ, partiront qu'à partir de l'heure de départ du groupe. help:startmethod = MeOS utilisera automatiquement la méthode de départ choisie. Quoi que vous choisissiez ici, vous pourrez dans tous les cas changer la méthode de départ ou refaire le tirage plus tard. +help:teamlineup = Ici vous pouvez importer des équipes à partir d'un fichier texte structuré qu'il est facile de produire manuellement à partir d'un tableur. Le fichier doit avoir le format suivant :\n\nCatégorie;Nom de l'équipe;[Club]\nCompétiteur 1;[No de puce];[Club];[Circuit];[Catégorie du coureur]\nCompétiteur 2;[No de puce];[Club];[Circuit];[Catégorie du coureur]\n...\nCatégorie;Nom de l'équipe;[Club]\n...\n\nLes champs marqués entre crochets [] sont optionnels. Notez que les catégories et circuits utilisées doivent exister, et que le nombre de branches dans la catégorie doit correspondre au nombre de ligne définissant les coureurs après la catégorie. Des lignes vides peuvent être utilisées s'il n'y a pas de coureur. L'option signifie que seulement les coureurs déjà inscrits à la compétition sont ajoutés à l'équipe; les autres coureurs spécifiés sont ignorés. +help:teamwork = Les coureurs ont échangés leur place. Vous pouvez faire une succession d'échanges pour obtenir la nouvelle composition d'équipe. help:winsplits_auto = Ce service sauvegarde les temps intermédiaires dans un fichier IOF (xml) à intervalles réguliers. Si vous ouvrez ce fichier dans WinSplit, les temps intermédiaires seront mis à jour en temps réel. help:zero_time = Définissez l'heure zéro à une heure avant le premier départ prévu. -help:long_times = La date de compétition est la date à laquelle toutes les catégories commencent. L'heure zéro est à minuit. help_autodraw = Fournit une première heure de départ (ordinaire), un intervalle minimal (pour une catégorie) et le pourcentage de vacants. Vous pouvez également choisir la méthode utilisée pour le tirage au sort et si les personnes inscrites tardivement doivent partir avant ou après les autres coureurs. Le premier horaire de départ doit être supérieur à l'heure zéro de la compétition.\n\nSi vous cliquez sur , MeOS vérifie toutes les catégories. Si la catégorie n'a pas eu de tirage celui-ci est effectué. S'il y a des personnes inscrites tardivement sans horaires de départ dans une catégorie, leur horaire de départ sera tiré au sort.\n\nMeOS garantit que les coureurs ayant des circuits similaires ne partent pas simultanément, et de la place est réservée pour permettre l'accueil de coureurs inscrits tardivement dans les même conditions.\n\nSi au contraire vous cliquez sur vous pouvez contrôler exactement quelle catégories sont tirées au sort et avec quels paramètres. help_draw = Le tirage au sort des horaire de départ se fait en deux temps. Premièrement vous choisissez les catégories et entrez quelques paramètres. Quand vous appuyez sur MeOS utilise vos paramètres pour attribuer les plages d'horaires entre les catégories. MeOS garantit que les catégories ayant des circuits similaires ne partent pas ne même temps en prenant en compte toutes les catégories ayant déjà eu un tirage. L'objectif est une répartition uniforme des partants.\n\nLa répartition calculée se présente sous la forme d'une table dans laquelle vous pouvez effectuer vos propres modifications, ou laisser MeOS mettre à jour sa répartition en prenant en compte vos modifications. Lorsque vous êtes satisfaits avec la répartition, vous laisser MeOS faire le tirage au sort des catégories sélectionnées.\n\nLes paramétrages que vous devez effectuer consistent à fournir l'heure du premier départ possible, et le plus petit intervalle de temps entre coureur autorisé. Le nombre maximal de départ en parallèle détermine combien de coureurs peuvent prendre le départ en même temps. Une valeur plus importante conduit à une durée de départ plus faible.\n\nLe pourcentage de vacants détermine le nombre d'horaires laissés disponibles. Si vous n'en voulez aucune, entrez 0%. Le nombre prévu de retardataires réserve de la place pour ces derniers dans la liste de départ, avec la garantie qu'aucun coureur prenant le départ au même moment n'aura un circuit identique. +htmlhelp = Le HTML peut être exporté comme un tableur structuré ou comme un document formaté librement +info:advanceinfo = Le service de transfert instantané des résultats a planté. Les résultats seront reçus avec quelques secondes de délais. C'est ce qui risque d'arriver si plus d'un service est lancé depuis cet ordinateur. info:multieventnetwork = Pour prendre en charge plus d'une étape vous devez travailler localement. Faite une copie de sauvegarde de la compétition, ouvrez-la en local et transférez les résultats à l'étape suivante. Enfin, remontez l'étape suivante sur le serveur. +info:pageswithcolumns = Montrer la liste page par page, avec un nombre spécifié de colonnes. Les infos sont mises à jour à chaque bouclage. info:readout_action = X: Puce no. Y lue.\nDes actions manuelles sont requises. info:readout_queue = X: Puce no. Y lue.\nLa puce a été mise en file d'attente. +info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'éditer les bases de données club et coureurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML). +info:teamcourseassignment = Le fichier des circuits IOF XML 3.0 contient les variations des équipes. Pour importer ces données, vous devez préparer la compétition en fonction des données du fichier :\n\n1.Assurez-vous que les catégories de relais ont le bon nombre de branches.\n2. Affectez les dossards à chaque catégorie. Passez par la Configuration Rapide dans l'onglet Catégories et renseignez le premier dossard de chaque catégorie (avec la répartition automatique des dossards). Vous pouvez aussi importer les équipes et leur attribuer des dossards comme d'habitude.\n\n\n3. Importez les circuits. Vous pouvez importer plusieurs fois ce fichier si nécessaire pour mettre à jour les variations. +info_shortening = Sélectionnez un circuit existant qui raccourcit le circuit sélectionné. Plusieurs niveaux de raccourcissement sont possibles. inforestwarning = Aucun concurrent ne semble être encore en forêt. Comme les données qui ont servi à émettre cette conclusion peuvent être erronées, vous devez vérifier qu'aucun concurrent n'est encore en forêt par d'autres moyens. kartor = carte klar = établir kontroll = poste kontroll X (Y) = poste X (Y) +leder med X = est en tête avec X +leder med X; har tappat Y = est en tête avec X; a perdu Y +leder med X; sprang Y snabbare än de jagande = est en tête avec X; court Y plus vite que les autres +listinfo:inputresults = Afficher les résultats initiaux depuis les étapes précédentes. +listinfo:singleclub = Créer une liste de résultats pour un seul club.\nUtilisez le paramètre de saisi pour spécifier l'identifiant du club. localhost = machine locale lopp = course +min/km = min/km mÃ¥l = arrivée -mÃ¥let = l'arrivée mÃ¥let (X) = l'arrivée (X) +mÃ¥let = l'arrivée +newcmp:featuredesc = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition. Vous pouvez ajouter ou supprimer des fonctionnalités à tout moment en sélectionnant sur la page Compétition. nia = neuvième nionde = neuvième +olshooting:notimepunishment = Liste de résultats Orientation/Tir sans pénalité en temps.\n\nActiver les support pour la course au score et les ajustements manuels de points. Utilisez ensuite la réduction de points sur la page Coureurs pour spécifier les pénalités sous la forme LLSS, où LL est le nombre de tirs ratés allongé et SS est le nombre de tirs ratés debout. Exemple: 0201 signifie 2 tirs allongés et 1 tir debout ratés. +olshooting:timepunishment = Liste de résultats Orientation/Tir avec pénalité en temps.\n\nActiver les support pour la course au score et les ajustements manuels de points. Utilisez ensuite la réduction de points sur la page Coureurs pour spécifier les pénalités sous la forme PPPLLSS, où PPP est l'erreur de position en millimètres, LL est le nombre de tirs ratés allongé et SS est le nombre de tirs ratés debout. Exemple 30201 signifie 3 mm d'erreur, 2 tirs allongés et 1 tir debout ratés. +open_error = Impossible d'ouvrir X.\n\nY. +open_error_locked = Cette compétition est déjà ouverte dans MeOS.\n\nVous devez utiliser une base de données pour ouvrir plus d'un exemplaire d'une compétition. +prefsAccount = Numéro de compte par défaut +prefsAddress = Adresse par défaut +prefsAdvancedClassSettings = Afficher les paramètres avancés des catégories +prefsAutoSaveTimeOut = Intervalle de sauvegarde automatique (ms) +prefsAutoTie = Lier automatiquement coureur et puce +prefsCardFee = Tarif de location de puce par défaut +prefsClient = Nom du client sur le réseau +prefsCodePage = Code table pour l'import/export en 8 bits +prefsControlFrom = Temps depuis le poste radio... +prefsControlTo = Temps jusqu'au poste radio... +prefsCurrencyFactor = Facteur d'échelle monétaire +prefsCurrencyPreSymbol = Placer le symbole monétaire en premier +prefsCurrencySeparator = Séparateur décimal monétaire +prefsCurrencySymbol = Symbole monétaire +prefsDatabase = Utiliser la base de données des coureurs +prefsDatabaseEngine = Type de base de données pour les nouvelles compétitions (MySQL) +prefsDatabaseUpdate = Dernière mise à jour de la base des coureurs +prefsDefaultDrawMethod = Méthode de tirage par défaut +prefsDirectPort = Port réseau pour les poinçons radios +prefsDrawInterlace = Entrelacer catégorie/circuits dans la liste de départ +prefsEMail = E-mail +prefsEliteFee = Tarif par défaut pour les élites +prefsEntryFee = Tarif par défaut +prefsEventorBase = URL d'Eventor +prefsExportCSVSplits = Inclure les temps intermédiaires dans l'export csv +prefsExportFormat = Format d'exportation par défaut +prefsFirstInvoice = Premier numéro de facture +prefsFirstTime = Premier départ +prefsHomepage = Site web +prefsImportOptions = Options d'importation par défaut +prefsInteractive = Gestion interactive des puces +prefsLastExportTarget = Cible du dernier export +prefsLateEntryFactor = Coefficient pour les tarifs d'inscription tardive +prefsLiveResultFont = Police de caractère utilisée pour les résultats en direct +prefsMIPURL = URL du serveur MIP +prefsMOPFolderName = Répertoire MOP local +prefsMOPURL = URL du serveur MOP +prefsManualInput = Utiliser la saisie manuelle des temps +prefsMaximumSpeakerDelay = Délai maximum de mise à jour pour le speaker +prefsNameMode = Format du nom : X +prefsNumSplitsOnePage = Nombre de puces par page +prefsOrganizer = Organisateur +prefsPayModes = Modes de paiement +prefsPlaySound = Lancer les sons +prefsPort = Port réseau MySQL +prefsReadVoltageExp = Lire le niveau de batterie de la puce SIAC +prefsRentCard = Puce louée +prefsSeniorAge = Age sénior +prefsServer = Serveur réseau par défaut +prefsServicePort = Port par défaut X +prefsServiceRootMap = Fonctions standard pour la source du serveur Web +prefsSoundAction = Fichier son, action requise +prefsSoundLeader = Fichier son, leader de la catégorie +prefsSoundNotOK = Fichier son, statut pas OK +prefsSoundOK = Fichier son, statut OK +prefsSpeakerShortNames = Utiliser les initiales dans les noms +prefsSplitLateFees = Séparer les frais d'inscription en frais standards et frais d'inscription tardive pour l'exportation IOF XML +prefsSplitPrintMaxWait = Temps d'attente maximum lors de l'impression des temps intermédiaires +prefsStreet = Adresse club +prefsSynchronizationTimeOut = Délai d'attente de mise à jour réseau (ms) +prefsTextFont = Police utilisée par MeOS +prefsUseDirectSocket = Utiliser les données anticipées de poinçonnage +prefsUseEventor = Utiliser Eventor +prefsUseEventorUTC = Utiliser le temps UMT avec Eventor +prefsUseHourFormat = Utiliser le format HH:MM:SS au lieu de MMM:SS +prefsUserName = Identifiant MySQL +prefsVacantPercent = Pourcentage de vacants +prefsVacantPosition = Répartition des vacants +prefsWideSplitFormat = Imprimer les temps intermédiaires en grand format +prefsYouthAge = Limite tarif jeune +prefsYouthFee = Tarif réduit +prefsaddressxpos = Coordonnée x de l'adresse +prefsaddressypos = Coordonnée y de l'adresse +prefsclasslimit = Limiter le nombre de résultats affichés par catégorie +prefsintertime = Montrer les temps intermédiaires +prefspagebreak = Ajouter des sauts de page +prefsshowheader = Afficher les titres +prefssplitanalysis = Analyser les temps intermédiaires radio X = radio X +red channel = Réseau rouge +reused card = puce réutilisée saknas = manquant se license.txt som levereras med programmet = voir le fichier license.txt fourni avec le logiciel +sekund = seconde +sekunder = secondes serverbackup = sauvegarde du serveur sexa = sixième sjua = septième sjunde = septième sjätte = sixième skicka stämplar = envoyer les poinçons +skickar ut X = lance X sortering: X, antal rader: Y = ordre de tri: X, nombre de lignes: Y starten (X) = le départ (X) sträcka X = Partiel X stämplade vid = a poinçonné stämplar vid X som Y, pÃ¥ tiden Z = poinçonne à X en tant que Y, en Z tar ledningen med tiden X = prend la tête en X +tar ledningen vid X med tiden Y = prend la tête au poste X, en Y tia = dixième till = à tionde = dixième @@ -1398,9 +2488,15 @@ tooltip:inforest = Liste des coureurs en forêt et des coureurs n'ayant pas pris tooltip:paste = Coller depuis le presse papier tooltip:resultprint = Imprimer les résultats à l'écran tooltip:voice = Synthèse vocale des pré-annonces +tooltip_explain_status = - = Statut inconnu (Pas encore de résultat)\nOK = Résultat valide\nNon partant = Ne participe pas\nAnnulé = Inscription annulée (apparaît dans les listes de départ)\nPM = Poinçons Manquants\nAband. = Abandon\nDisq. = Disqualifié\nTemps max = Dépasse le temps ou l'heure maximale\nNC = Non classé trea = troisième tredje = troisième +true[boolean] = vrai tvÃ¥a = second +var först i mÃ¥l med tiden X = était le premier à terminer avec un temps de X +var först vid X med tiden Y = était le premier au poste X avec un temps de Y +var först vid växeln med tiden X = était le premier au passage de relais avec un temps de X +vid kontroll X = au poste X väntas till X om nÃ¥gon minut = est attendu sous peu au poste X väntas till X om nÃ¥gon minut, och kan i sÃ¥ fall ta en Y plats = est attendu au poste X dans la minute, et peut prendre la Y place. väntas till X om nÃ¥gon minut, och kan i sÃ¥ fall ta ledningen = est attendu au poste X dans la minute, et peut prendre la tête de la course. @@ -1409,35 +2505,54 @@ växlar pÃ¥ X plats med tiden Y = passage de relais au poste X avec un temps de växlar pÃ¥ X plats, efter Y, pÃ¥ tiden Z = passage de relais à la X place, après Y, avec un temps de Z växlar pÃ¥ delad X plats med tiden Y = devient X avec un temps de Y warn:changedtimezero = Changer l'heure zéro d'une compétition ayant des résultats n'est pas recommandé.\n\nVoulez-vous tout de même faire ce changement ? +warn:latestarttime = Utiliser des heures de départ plus de X heures après l'heure zéro n'est pas conseillé +warn:missingResult = X coureurs ne sont toujours pas rentrés et ne sont donc pas classés.\n\nVous pouvez aller dans l'onglet 'Coureurs restants' et les passer en statut +warn:mysqlbinlog = Avertissement : impossible de désactiver l'enregistrement binaire. La mise à jour peut être lente.\n\nX +warn:notextended = INFO: Programmez les boîtiers en protocole étendu avec SI. Config pour accélérer la lecture de puce. warn:olddbversion = La base de donnée est utilisée par une version postérieure de MeOS. Une mise à jour est recommandée. +warn:opennewversion = La compétition a été créée avec MeOS X. Les données peuvent être perdues si vous continuez.\n\nVoulez-vous continuer ? +warn:printmodeonly = Attention, notez bien que vous ne faites qu'imprimer les données de la puce sans l'enregistrer.\n\nPour l'intégrer à la course, utilisez la fonction Lecture des puces/Radios. +warn:updatelegs = Les longueurs des variations individuelles peut nécessiter une mise à jour après ce changement. warning:dbproblem = ATTENTION. Problèmes rencontrés avec la connexion à la base: 'X'. La connexion sera automatiquement restaurée. Vous pouvez continuer à travailler normalement. +warning:direct_result = Notez que l'utilisation de nécessite que tous les poinçons de tous les postes du circuit aient été transmis comme poste radio, ou que MeOS soit utilisé pour chronométrer uniquement sans tenir compte du circuit.\n\nUtiliser les résultats sur poinçon d'arrivée ? warning:drawresult = La catégorie a déjà des résultats, les heures de départ seront écrasées. Voulez-vous continuer ? warning:has_entries = La catégorie a déjà des coureurs. Changer la répartition des variations à ce stade peut entraîner une perte de données.\n\nVoulez-vous continuer ? warning:has_results = La catégorie a déjà des résultats. Changer la répartition des variations à ce stade est inhabituel.\n\nVoulez-vous continuer ? xml-data = données xml Äldre protokoll = Protocole périmé Ändra = Modifier +Ändra MeOS lokala systemegenskaper = Paramètres de MeOS +Ändra X = Change X Ändra grundläggande inställningar och gör en ny fördelning = Modifier les configuration de base et faire une nouvelle répartition Ändra inställningar = Modifier les configurations Ändra klassinställningar = Modifier les configurations de catégorie Ändra lag = Changer l'équipe +Ändra lagets gaffling = Changer les variations de l'équipe +Ändra lokala inställningar = Modifier les paramètres Ändra sträckindelning = Modifier la configuration des variations Ändrad = Modifié Ändrade avgift för X deltagare = Tarif modifié pour X coureur(s) Ã…ldersfilter = Filtrer suivant l'âge +Ã…ldersfiltrering = Filtrer par âge Ã…ldersgräns ungdom = Age minimal Ã…ldersgräns äldre = Age maximal Ã…ldersgränser, reducerad anmälningsavgift = Age limite pour tarif réduit Ã…ngra = Annuler la saisie Ã…teransluten mot databasen, tävlingen synkroniserad = Reconnecté à la base de donnée, compétition synchronisée Ã…terbud = Annuler l'inscription +Ã…terbud[status] = Annulé Ã…tergÃ¥ = Retour -Ã…terställ = Restaurer +Ã…terskapa = Réorganiser +Ã…terskapa tidigare sparade fönster- och speakerinställningar = Réorganiser les fenêtres et paramètres comme enregistré précédemment Ã…terställ / uppdatera klasstillhörighet = Réinitialiser / modifier la catégorie du coureur +Ã…terställ till = Remettre en +Ã…terställ = Restaurer Ã…terställ löpare med registrering till = Passer le statut à pour les coureurs inscrits Ã…terställ säkerhetskopia = Restaurer la sauvegarde Ã…terställ tabeldesignen och visa allt = Restaurer la présentation de la table +Ã…tgärd krävs = Action demandée Ã…Ã…Ã…Ã…-MM-DD = AAAA-MM-JJ +Ökande = Croissant Öppen = Open Öppen klass = Catégorie Open Öppna = Ouvrir @@ -1458,1042 +2573,26 @@ xml-data = données xml Överför resultat = Transférer les résultats Överför resultat till X = Transfert des résultats à X Överför resultat till nästa etapp = Transfert des résultats à l'étape suivante +Överföring = Transférer +Övertid = Dépassement en temps Övre datumgräns = Date au plus tard Övre gräns (Ã¥r) = Date au plus tard (années) Övre Ã¥lder = Age maxi Övriga = Autre +Övrigt = Divers +är X efter = est en retard de X +är X efter Y = est en retard de X derrière Y +är X efter; har tagit in Y = est en retard de X; a gagné Y +är X efter; har tappat Y = est en retard de X; a perdu Y +är X före Y = X est avant Y är först i mÃ¥l med tiden X = est premier à l'arrivée en X är först vid X med tiden Y = est premier au poste X en Y är först vid växeln med tiden X = est premier au passage de relais avec un temps de X är inte godkänd = est disqualifié +är nu pÃ¥ X plats med tiden Y = est maintenant à la X è place avec un temps de Y +är nu pÃ¥ delad X plats med tiden Y = est maintenant à égalité à la X è place avec un temps de Y Ã¥terställd = restauré Ã¥tta = huit Ã¥ttonde = huitième -Kopia (X) = Copier (X) -TillÃ¥t samma bana inom basintervall = Autoriser le même circuit dans l'intervalle de base (entrelacer les catégories) -Välj X = Sélectionner X -Ett startblock spänner över flera starter: X/Y = Un bloc de départ couvre plus d'un départ: X/Y -Bricka X = Puce X -RunnerTimePerKM = Allure min/km -X är inget giltigt sträcknummer = X n'est pas un numéro de variation valide -Listan togs bort frÃ¥n tävlingen = La liste a été retirée de la compétition -Töm = Effacer -Status matchar inte deltagarnas status = Le statut ne correspond pas au statut du coureur. -Status matchar inte data i löparbrickan = Le statut ne correspond pas au donnée contenues dans la puce. -Döp om = Renommer -gÃ¥r upp i delad ledning vid X med tiden Y = partage la tête de la course au poste X, en Y -X:e = X:ème -tar ledningen vid X med tiden Y = prend la tête au poste X, en Y -Eventor server = Serveur Eventor -(har stämplat) = (a poinçonné) -documentation = meos_doc_eng.html -Hittar inte hjälpfilen, X = Documentation introuvable, X -X har redan ett resultat. Vi du fortsätta? = X a déjà un résultat. Souhaitez-vous continuer ? -Aktuell tid = Heure courante -Godkänd = OK -Nummerlapp, SI eller Namn = Dossard, puce ou nom -UtgÃ¥tt = Aband. -Manuell inmatning = Saisie manuelle -Tilldelad = Affecté -Eventors tider i UTC (koordinerad universell tid) = Heure UTC d'Eventor -Exportera tider i UTC = Heure UTC d'export -Tidszon = Fuseau horaire -RunnerAge = Age du coureur -RunnerBirthYear = Année de naissance du coureur -RunnerFee = Prix payé par le coureur -RunnerNationality = Nationalité du coureur -RunnerPhone = Numéro de téléphone du coureur -RunnerSex = Sexe du coureur -TeamFee = Prix payé par l'équipe -Varning: ändringar i X blev överskrivna = Attention: les changements dans X ont été écrasés -help:simulate = Ce service vous permet de simuler des lectures de puces. Des temps et des poinçons sont générés pour tous les participants. Même les postes radio peuvent être simulés.\n\nATTENTION: A n'utiliser que pour les tests. Si vous utilisez cette fonctionnalité sur une vraie course, elle sera corrompue. -Rogainingresultat - %s = Résultats de la course au score - %s -TeamPlaceDiff = Ecart de place de l'équipe (étape courante) -TeamTotalPlace = Place finale de l'équipe (toutes les étapes) -TeamTotalTime = Temps total de l'équipe (toutes les étapes) -TeamTotalTimeAfter = Retard total de l'équipe (toutes les étapes) -TeamTotalTimeDiff = Ecart total de l'équipe (étape courante) -TeamTotalTimeStatus = Temps total ou statut de l'équipe (toutes les étapes) -Vill du dumpa aktuellt tävling och skapa en testtävling? = Voulez-vous faire un dump de la compétition courante et créer une compétition de test ? -Radera alla klubbar = Effacer tous les clubs -Radera alla klubbar och ta bort klubbtillhörighet = Effacer tous les clubs et les membres des clubs -Vill du ta bort alla klubbar frÃ¥n tävlingen? Alla deltagare blir klubblösa = Souhaitez-vous effacer tous les clubs de la compétition ? Aucun coureur n'aura de club. -Besökare = Visiteurs -FöregÃ¥ende kontroll = Poste précédent -Ja = Oui -Nej = Non -PÃ¥ banan = Sur le circuit -Stämpelkod = Code du poste -Tidpunkt = Temps -Antal deltagare = Coureurs -Förekomst = Occurrence -Exporterar om = Export dans -Exportformat = Format d'export -Filnamnsprefix = Préfixe du nom de fichier -Mapp = Répertoire -Mappnamnet fÃ¥r inte vara tomt = Le nom du répertoire ne peut pas être vide -Onlineresultat = Résultats en ligne -Packa stora filer (zip) = Compresser les grands fichiers (zip) -Publicera resultat direkt pÃ¥ nätet = Publier les résultats directement sur le web -Resultat online = Résultats en ligne -Skicka till webben = Envoyer sur le web -Spara pÃ¥ disk = Enregistrer sur disque -Till exempel X = Par exemple X -Tävlingens ID-nummer = Identifiant de la compétition -URL = URL -URL mÃ¥ste anges = URL manquant -Tidsintervall (sekunder) = Intervalle de temps (secondes) -Antal skickade uppdateringar X (Y kb) = Nombre de mise à jour X (Y kb) -Filename OE (csv) with runners and clubs = Nom de fichier OE (csv) avec coureurs et clubs -Filen finns redan: X = La destination existe déjà: X -Misslyckades med att ladda upp onlineresultat = Echec lors de la monté des résultats sur Internet -Onlineservern svarade felaktigt = Le serveur distant a fourni une réponse inattendue (Configuration incorrecte ?) -Onlineservern svarade: ZIP stöds ej = Réponse du serveur distant : ZIP non supporté. -Onlineservern svarade: Serverfel = Réponse du serveur distant: Erreur du serveur -Onlineservern svarade: Felaktigt lösenord = Réponse du serveur distant : Mot de passe incorrect -Onlineservern svarade: Felaktigt tävlings-id = Réponse du serveur distant : Identifiant de compétition incorrect -Online Results Error X = Erreur dans les résultats en ligne X -PDF = PDF -ClassTeamLeg = Catégorie, équipe, relayeur -Okänd = Inconnu -Antal hämtade uppdateringar X (Y kb) = Nombre de mise à jour reçues X (Y kb) -Använd ROC-protokoll = Utiliser le protocole ROC -Definierade mappningar = Mappings définis -Funktion = Fonction -Hämta stämplingar m.m. frÃ¥n nätet = Retrouver des poinçons etc... depuis Internet. -Inmatning online = Saisie à distance -Kod = Code -Kontrollmappning = Mapping des postes -Ogiltig funktion = Fonction invalide -Ogiltig kontrollkod = Code de poste invalide -Onlineinput = Saisie distante -Online Input Error X = Erreur de saisie distante X -Ekonomi = Comptabilité -Fakturainställningar = Configuration de la facturation -Hantera klubbar = Gestion des clubs -Spara som PDF = Enregistrer en tant que PDF -Avgifter och valuta ställer du in under = Les tarifs et les monnaies sont changés depuis -Fakturanummer = Numéro de facture -Formatering = Format -Första fakturanummer = Premier numéro de facture -Koordinater (mm) för adressfält = Coordonnées (mm) du champ d'adresse -Organisatör = Organisateur -Tilldela nya fakturanummer till alla klubbar? = Affecter un nouveau numéro de facture à tous les clubs ? -Exportera alla till PDF = Tout exporter en PDF -help:onlineresult = Le service est utilisé pour envoyer automatiquement les résultats et les listes de départ sur Internet pour publication immédiate dans des formulaires. Vous devez créer des configurations adaptées au service distant que vous voulez utiliser : le fournisseur du service distant vous fournira tous les détails utiles.\n\nSi vous voulez développer vos propres services, vous trouverez de la documentation et des exemples sur le site web de MeOS : www.melin.nu/meos. -help:onlineinput = Le service est utilisé pour recevoir les poinçons radio depuis Internet, par exemple un poste radio raccordé à l'aide d'un téléphone sans fil. Il est également possible de créer un formulaire en ligne où les numéros de dossard seront saisis manuellement au fur et à mesure des passages.\n\nLe protocole du service supporte également d'autres moyens de saisie, tels que les équipes [team line-up], des saisies directes, des changements de puce etc. Si vous voulez développer vos propres services, vous trouverez de la documentation et des exemples sur le site web de MeOS : www.melin.nu/meos. -Egna textrader = Ligne de texte personnalisée -Inga bommar registrerade = Aucune erreur de poste détectée -Inställningar sträcktidsutskrift = Configuration de l'impression des temps intermédiaires -Med km-tid = Inclure l'allure (min/km) -Tidsförluster (kontroll-tid) = Temps perdu (poste-temps) -Underlag saknas för bomanalys = Aucune donnée pour les erreurs de poste -min/km = min/km -X har redan bricknummer Y. Vill du ändra det? = X a déjà la puce Y. Voulez-vous la changer ? -Avmarkera 'X' för att hantera alla bricktildelningar samtidigt = Décocher 'X' pour gérer toutes les affectations de puces sur une seule page -Bricknr = Numéro de puce -Knyt automatiskt efter inläsning = Affectation automatique à la lecture de la puce -Knyt bricka / deltagare = Affecter une puce à un coureur -Nummerlapp, lopp-id eller namn = Dossard, identifiant de la course ou nom -Lopp-id = Identifiant de la course -Markera 'X' för att hantera deltagarna en och en = Cocher 'X' pour gérer les coureurs un par un -Installerbara listor = Listes pouvant être installées -Listor i tävlingen = Listes dans la compétition -Radera permanent = Suppression définitive -Tillgängliga listor = Listes disponibles -Vill du ta bort 'X'? = Voulez-vous supprimer 'X'? -classcourseresult = Résultats par catégorie et par circuit -Hantera egna listor = Gérer les listes personnalisées -Redigera = Editer -Skriver sträcktider när tävlingsdata ändras = Ecriture du fichier quand les données de la compétition changent -Bana med slingor = Circuits avec boucles -En bana med slingor tillÃ¥ter deltagaren att ta slingorna i valfri ordning = Un circuit avec des boucles autorise le coureur à effectuer les boucles dans n'importe quel ordre. -Varvningskontroll = Poste commun -warn:notextended = INFO: Programmez les boîtiers en protocole étendu avec SI. Config pour accélérer la lecture de puce. -help:DirectResult = - S'il n'y a pas de circuit, le statut est mis à OK sur le poinçon d'arrivé.\n- S'il y a des circuits, les poinçons radio sont utilisés comme postes. Aucune lecture de puce n'est nécessaire. -Resultat vid mÃ¥lstämpling = Résultat sur le poinçon d'arrivée -Stämpling = Poinçon -Skicka och ta emot snabb förhandsinformation om stämplingar och resultat = Envoyez et recevoir des pré-informations rapides sur les poinçons et résultats -Centrera = Centrer -Färg = Couleur -Höger = Droite -PunchControlCode = Numéro de poste -PunchControlNumber = Numéro de poinçon -PunchControlPlace = Place sur la branche vers le poste -PunchControlPlaceAcc = Place après le poste -PunchLostTime = Temps perdu au poste -SlÃ¥ ihop text med föregÃ¥ende = Fusionner avec le précédent -Textjustering = Ajustement du texte -Vänster = Gauche -X (press Ctrl+Space to confirm) = X (Appuyez sur + pour confirmer) -Press Enter to continue = Appuyez sur pour continuer -ask:overwriteresult = X a déjà des résultats. Voulez-vous les écraser ? -Brickan används av X = La puce est utilisée par X -DATABASE ERROR = ERREUR DE BASE DE DONNEE -Lyssnar pÃ¥ X = Ecoute de X -vid kontroll X = au poste X -info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'éditer les bases de données club et coureurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML). -ask:cleardb = Voulez-vous effacer les données club et coureurs ? -Banan saknar rogainingkontroller = La compétition n'a pas de poste de type course au score -Banans kontroller ger för fÃ¥ poäng för att täcka poängkravet = Les postes de type course au score n'attribuent pas assez de points -CustomSort = Ordre personnalisé -Brickhantering = Gestion des poinçons -HTML med AutoRefresh = HTML avec rafraîchissement automatique -Importera laguppställningar = Importer des équipes depuis un fichier structuré -MeOS Funktioner = Fonctionnalités MeOS -MÃ¥lfil = Fichier de destination -Spara tid = Enregistrer -Stämplingstid = Heure de poinçonnage -Data from result module (X) = Données fournies par le module de résultat (X) -Forkings = Variations -Forkings for X = Variations pour X -Gruppera = Groupe -Resultatuträkning = Calcul des résultats -RunnerRogainingPointTotal = Total des points du coureur -Show forking = Montrer les variations -Standard = Standard -TeamRogainingPointTotal = Total des points de l'équipe -The forking is fair = Les variations sont équitables -Underfilter = Sous filtre -Ogiltigt lag pÃ¥ rad X = Équipe invalide ligne X -Okänd klass pÃ¥ rad X = Catégorie inconnue ligne X -Klassen X är individuell = La catégorie X est individuelle -Använd befintliga deltagare = Utiliser les coureurs déjà inscrits -Knyt redan anmälda deltagare till laget (identifiera genom namn och/eller bricka) = Regrouper les coureurs existants à l'équipe (identifiés par le nom et/ou le numéro de puce) -Laguppställning = Fichier structuré d'équipes -BakÃ¥t = Retour -Bibs = Dossards -Club and runner database = Base de donnée des clubs et coureurs -Clubs = Clubs -Economy and fees = Gestion et frais d'inscription -Forked individual courses = Circuit individuel avec variations -General = Général -Manual point reductions and adjustments = Réduction des points et ajustements -Manual time penalties and adjustments = Pénalités en temps et ajustements -MeOS Features = Fonctionnalités de MeOS -MeOS – Funktioner = MeOS – Fonctionnalités -Patrols = Équipe -Prepare start lists = Préparation des listes de départ -Relays = Relais -Several MeOS Clients in a network = Plusieurs clients MeOS en réseau -Several races for a runner = Plusieurs circuits pour un coureur -Spara laguppställningar = Enregistrer les équipes -Teams and forking = Équipes et variations -Track runners in forest = Suivi des coureurs en forêt -Vacancies and entry cancellations = Places disponibles et annulation des inscriptions -Banan saknas = Circuit manquant -Klassen saknas = Catégorie absente -Alla lopp som individuella = Toutes les courses sont individuelles -Exportera individuella lopp istället för lag = Exporter comme courses individuelles au lieu de courses par équipe -Exportera startlista = Exporter les horaires de départ -Exporttyp = Type d'export -Exportval, IOF-XML = Configuration de l'export, IOF-XML -Failed to read file = Echec lors de la lecture du fichier. -Klassval = Sélection de catégorie -The forking is not fair = Les variations ne sont pas équitables -Unfair control legs = Branche non équitable -Växel = Passage -help:teamlineup = Ici vous pouvez importer des équipes à partir d'un fichier texte structuré qu'il est facile de produire manuellement à partir d'un tableur. Le fichier doit avoir le format suivant :\n\nCatégorie;Nom de l'équipe;[Club]\nCompétiteur 1;[No de puce];[Club];[Circuit];[Catégorie du coureur]\nCompétiteur 2;[No de puce];[Club];[Circuit];[Catégorie du coureur]\n...\nCatégorie;Nom de l'équipe;[Club]\n...\n\nLes champs marqués entre crochets [] sont optionnels. Notez que les catégories et circuits utilisées doivent exister, et que le nombre de branches dans la catégorie doit correspondre au nombre de ligne définissant les coureurs après la catégorie. Des lignes vides peuvent être utilisées s'il n'y a pas de coureur. L'option signifie que seulement les coureurs déjà inscrits à la compétition sont ajoutés à l'équipe; les autres coureurs spécifiés sont ignorés. -Poängjustering = Ajustement des points -Use initials in names = Utiliser les initiales comme noms -Exportera klubbar (IOF-XML) = Export des clubs (IOF-XML) -Exportera personer (IOF-XML) = Export des personnes (IOF-XML) -Töm databasen = Effacement des données -Several stages = Plusieurs étapes -Assign courses and apply forking to X = affecter un circuit et appliquer la variation à X -Assign selected courses to selected legs = Affecter les circuits sélectionnés aux branches sélectionnées -Calculate and apply forking = Calculer et utiliser les variations -Clear selections = Effacer les sélections -Define forking = Définir les variations -Forking setup = Configuration des variations -Leg X: Do not modify = Branche X: Ne pas modifier -Legs = Branches -help:assignforking = Cette fonction calcule un jeu de variation optimal pour les circuits sélectionnés. Affecter un ou plusieurs circuits aux branches en sélectionnant les circuits et les branches à partir des listes ci-dessus. Tous les circuits peuvent avoir le même ensemble de circuits (même variation) ou bien utiliser divers jeux de circuits pour différentes variations. De même dans ce cas, MeOS va calculer les variations de ces circuits entre eux, si les circuits le permettent. -Leg X = Branche X -Leg X: Use Y = La branche X: utilise Y -Created X distinct forkings using Y courses = X variations distinctes ont été créées à partir de Y circuits -Clear Memory = Effacement de la mémoire -Create Competition = Création de la compétition -Print Card Data = Imprimer les données de la puce -Print card data = Imprimer les données de la puce -help:analyzecard = Cette fonction vous permet d'imprimer les données de la puce sans utiliser une quelconque compétition, comme le ferait une borne d'impression autonome. Sélectionner 'Imprimer les temps intermédiaires' pour choisir et configurer l'imprimante.\n\nLes puces sont également conservées en mémoire (mais pas dans la compétition). Vous pouvez éditer le nom et le club pour une puce en cliquant le nom (ou 'inconnu'). Vous pouvez également enregistrer les puces dans un fichier (Enregistrer) ou créer une nouvelle compétition à partir des données des puces. Notez que si une compétition est ouverte, vous devez la fermer pour rendre cette option disponible. -Använd endast en bana i klassen = Utiliser uniquement un circuit pour la catégorie -Gafflade banor = Circuits avec variations -Unroll split times for loop courses = Dérouler les temps intermédiaires pour les circuits en boucle. -Löpare per klass = Coureurs par catégorie -Alla funktioner = Toutes les fonctionnalités -Anmäl inga deltagare nu = Aucune inscription -Datum (för första start) = Date (du premier départ) -Endast grundläggande = Fonctionnalités de base -Funktioner i MeOS = Fonctionnalités de MeOS -Första tillÃ¥tna starttid = Heure du premier départ possible -Importera anmälda = Importer les inscriptions -Individuell tävling = Compétition individuelle -Namn och tidpunkt = Nom et heure -Skapar tävling = Création de la compétition -Tävling med lag = Compétition en équipe -Tävlingen mÃ¥ste avgöras mellan X och Y = La compétition doit se dérouler entre le X et le Y -Tävlingens namn = Nom de la compétition -Välj frÃ¥n lista = Sélection détaillée -Välj vilka funktioner du vill använda = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition -Individuellt, gafflat = Individuel, avec variations -Skapa tävlingen = Créer la compétition -newcmp:featuredesc = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition. Vous pouvez ajouter ou supprimer des fonctionnalités à tout moment en sélectionnant sur la page Compétition. -Exportera till fil = Exporter dans un fichier -FilterPrelResult = Résultats prél. -FinishTimeReverse = Temps inversés (le dernier en premier) -Open a Copy = Ouvrir une copie -Point calculation for runner = Calcul du nombre de points pour un coureur -Point calculation for team = Calcul du nombre de points pour l'équipe -Result score calculation for runner = Détermination du score pour un coureur -Result score calculation for team = Détermination du score pour une équipe -ResultDescription = Nom du type de résultat -Skapa = Créer -Status calculation for runner = Détermination du statut pour un coureur -Status calculation for team = Détermination du statut pour une équipe -Support time from control = Temps depuis le poste -Support time to control = Temps jusqu'au poste -Time calculation for runner = Calcul du temps pour un coureur -Time calculation for team = Calcul du temps pour une équipe -TimingFrom = Nom du point de départ -TimingTo = Nom du point d'arrivée -Applying rules to the current competition = Appliquer les règles à la compétition courante -Available symbols = Symboles disponibles -Cancel = Annuler -Description = Description -Edit Clubs = Edition des clubs -Edit Result Modules = Edition des modules de résultats -Edit rule for = Editer la règle pour -Name of result module = Nom du module de résultat -New Result Module = Nouveau module de résultat -New Set of Result Rules = Nouvel ensemble de règles de résultat -Result Calculation = Calcul du résultat -Result Module – X = Module résultat – X -Result module identifier = Identifiant du module de résultat -Result Modules = Modules de résultats -Save = Enregistrer -Save changes = Enregistrer les changements -Source code = Code source -Test Result Module = Test du module -Result score calculation for team = Calcul du score pour l'équipe -Time: X = Temps : X -Start: X = Départ : X -Index in X[index] = Index en X[index] -X är inget giltigt index = X n'est pas un index valide -ResultModuleNumber = Module de résultat : Nombre -ResultModuleTime = Module de résultat : Temps -ResultModuleNumberTeam = Module de résultat : Nombre (pour l'équipe) -ResultModuleTimeTeam = Module de résultat : Temps (pour l'équipe) -RunnerRogainingOvertime = Dépassement de temps pour le coureur (course au score) -RunnerRogainingReduction = Réduction du nombre de points du coureur -TeamRogainingOvertime = Dépassement de temps pour l'équipe (course au score) -TeamRogainingReduction = Réduction du nombre de points pour l'équipe -Automatic rogaining point reduction = Réduction automatique du nombre de points pour la course au score -Choose result module = Choisir un module de résultat -Deviation +/- from expected time on course leg = Ecart +/- par rapport au temps estimé sur la branche -Leg number in team, zero indexed = Branche de équipe, indexé à partir de zéro -Length of course = Longueur du circuit -Maximum allowed running time = Temps de course maximal autorisé -Place on course leg = Classement sur la branche -Result Modules = Modules de résultat -Runner's card, matched control ids (-1 for unmatched punches) = La puce du coureur correspond aux n° de poste (-1 par poinçon différents) -Runner's card, punch codes = Puce du coureur, n° de poinçon -Runner's card, punch times = Puce du coureur, heure du poinçon -Runner's course = Circuit du coureur -Runner's split times = Temps intermédiaires du coureurs -Runner's total running time to control = Temps total du coureur jusqu'au poste -Runner/team fee = Droit d'inscription coureur/équipe -Runner/team finish time = Heure d'arrivée coureur/équipe -Runner/team input place = Place initiale coureur/équipe -Runner/team input points = Points initiaux coureur/équipe -Runner/team input running time = Temps de course initial coureur/équipe -Runner/team input status = Statut initial coureur/équipe -Runner/team place = Place coureur/équipe -Runner/team rogaining overtime = Dépassement du temps pour coureur/équipe (course au score) -Runner/team rogaining points = Point coureur/équipe (course au score) -Runner/team rogaining points adjustment = Ajustement des points coureur/équipe (course au score) -Runner/team running time = Temps de course coureur/équipe -Runner/team start time = Heure de départ coureur/équipe -Runner/team status = Statut coureur/équipe -Runner/team time adjustment = Ajustement du temps coureur/équipe -Runner/team total place = Place finale coureur/équipe -Runner/team total running time = Temps total de course coureur/équipe -Runner/team total status = Statut final coureur/équipe -Shortest time in class = Meilleur temps de la catégorie -Status as computed by your status method = Statut tel que calculé par votre méthode -Status code for a missing punch = Code de statut pour un poinçon manquant -Status code for a time over the maximum = Code de statut en cas de dépassement du temps -Status code for a valid result = Code de statut pour un résultat valide -Status code for an unknown result = Code de statut pour un résultat inconnu -Status code for disqualification = Code de statut pour une disqualification -Status code for not competing = Code de statut en cas d'absence -Status code for not finishing = Code de statut en cas d'abandon -Status code for not starting = Code de statut en cas de non prise de départ -Points as computed by your point method = Points tels que calculés par votre méthode -Time as computed by your time method = Temps tel que calculé par votre méthode -Time after leg winner = Temps après le vainqueur de la branche -Finish time for each team member = Heure d'arrivée pour chaque équipier -Matched control ids (-1 for unmatched) for each team member = Postes corrects pour chaque équipier (-1 en cas de différence) -Punch codes for each team member = No de poinçon pour chaque équipier -Punch times for each team member = Heure de poinçonnage pour chaque équipier -Result Modules = Modules de résultat -Rogaining points for each team member = Points pour chaque équipier (course au score) -Runner's method output numbers = Module de résultat en nombre pour chaque équipier -Runner's method output times = Module de résultat en temps pour chaque équipier -Running time for each team member = Temps de course pour chaque équipier -Start time for each team member = Heure de départ pour chaque équipier -Status for each team member = Statut de chaque équipier -Check: X = Vérification : X -Debug = Debug -Debug Output = Sortie de debug -Debug X for Y = Debug X pour Y -Do you want to clear the card memory? = Voulez-vous effacer la puce ? -Portable Document Format (PDF) = Portable Document Format (PDF) -Poängavdrag = Réduction de point -RunnerPointAdjustment = Ajustement des points du coureur -RunnerTimeAdjustment = Ajustement du temps du coureur -Save changes in rule code? = Enregistrer les changements dans le code de la règle ? -Symboler = Symboles -TeamPointAdjustment = Ajustement des points de l'équipe -TeamTimeAdjustment = Ajustement du temps de l'équipe -Variabler = Variables -Check: X = Vérification : X -Choose result module = Choisir le module de résultat -Result Modules = Modules de résultat -Error in result module X, method Y (Z) = Erreur dans le module de résultat 'X', méthode 'Y'\n\nZ -Invalid operator X = Opérateur invalide X -Unknown symbol X = Symbole inconnu X -RunnerGlobal = Coureur (catégories regroupées) -TeamGlobal = Équipe (catégories regroupées) -List Error: X = Erreur de liste : X -Rader markerade med (*) kommer frÃ¥n en lista i tävlingen = Les lignes avec une (*) proviennent d'une liste de la compétition -Resultatmodulen används i X = Le module de résultat est utilisé dans X -Valfri = Optionnel -Vill du sätta resultatet frÃ¥n tidigare etapper till ? = Voulez-vous modifier le résultat des étapes précédentes en ? -Hantera deltagare som bytt klass = Traitement des coureurs qui ont changé de catégorie -Välj klasser med nya anmälningar = Spécifiez les catégories pour lesquelles de nouvelles inscriptions sont autorisées -Byt till rätt klass (behÃ¥ll eventuell starttid) = Basculer vers la bonne catégorie (conserver l'heure de départ) -Byt till vakansplats i rätt klass (om möjligt) = Déplacer vers un horaire vacant dans la bonne catégorie (si possible) -TillÃ¥t ny klass, behÃ¥ll resultat frÃ¥n annan klass = Autoriser de nouvelles catégories et conserver les résultats des autres catégories -TillÃ¥t ny klass, inget totalresultat = Autoriser de nouvelles catégories mais sans résultat global -tooltip_explain_status = - = Statut inconnu (Pas encore de résultat)\nOK = Résultat valide\nNon partant = Ne participe pas\nAnnulé = Inscription annulée (apparaît dans les listes de départ)\nPM = Poinçons Manquants\nAband. = Abandon\nDisq. = Disqualifié\nTemps max = Dépasse le temps ou l'heure maximale\nNC = Non classé -Placering = Place -Resultat frÃ¥n tidigare etapper = Résultats des étapes précédentes -Input Results = Résultats initiaux -Input Results - X = Résultats initiaux - X -Individuella resultat = Résultats individuels -Avdrag = Réduction -Team Rogaining = Course au score en équipe -Övertid = Dépassement en temps -Kunde inte öppna tävlingen = Ouverture de la compétition impossible -warn:opennewversion = La compétition a été créée avec MeOS X. Les données peuvent être perdues si vous continuez.\n\nVoulez-vous continuer ? -District id number = Identifiant de la région -Kunde inte ladda X\n\n(Y) = Chargement impossible de X\n\n(Y) -Narrow Results = Réduire la liste des résultats -Club id number = Identifiant du club -User input number = Paramètre saisi par l'utilisateur -listinfo:singleclub = Créer une liste de résultats pour un seul club.\nUtilisez le paramètre de saisi pour spécifier l'identifiant du club. -listinfo:inputresults = Afficher les résultats initiaux depuis les étapes précédentes. -Ett värde vars tolkning beror pÃ¥ listan = Une valeur ayant une interprétation dépendant d'une liste -Listparameter = Paramètre de la liste -Individual results in a club = Résultats individuel au sein du club -OL-Skytte med tidstillägg = Orientation/Tir avec pénalité en temps -OL-Skytte utan tidstillägg = Orientation/Tir sans pénalité en temps -OL-Skytte stafettresultat = Relais Orientation/Tir -Sluttid = Temps final -olshooting:timepunishment = Liste de résultats Orientation/Tir avec pénalité en temps.\n\nActiver les support pour la course au score et les ajustements manuels de points. Utilisez ensuite la réduction de points sur la page Coureurs pour spécifier les pénalités sous la forme PPPLLSS, où PPP est l'erreur de position en millimètres, LL est le nombre de tirs ratés allongé et SS est le nombre de tirs ratés debout. Exemple 30201 signifie 3 mm d'erreur, 2 tirs allongés et 1 tir debout ratés. -olshooting:notimepunishment = Liste de résultats Orientation/Tir sans pénalité en temps.\n\nActiver les support pour la course au score et les ajustements manuels de points. Utilisez ensuite la réduction de points sur la page Coureurs pour spécifier les pénalités sous la forme LLSS, où LL est le nombre de tirs ratés allongé et SS est le nombre de tirs ratés debout. Exemple: 0201 signifie 2 tirs allongés et 1 tir debout ratés. -Namnet kan inte vara tomt = Le nom ne peut pas être vide -Ingen / okänd = Aucun / inconnu -Inget nummer = Aucun nombre -Stafettresultat = Résultats de relais -Döp om X = Renommer X -Gräns för maxtid = Barrière horaire (OMT) -Individual Example = Exemple de course individuelle -Long = Longue -MeOS Three Days Race X = Les 3 jours MeOS X -Medium = Moyenne -Open = Ouvrir -Open X = Ouvrir X -Prologue + Pursuit = Prologue + Poursuite -Relay Example = Exemple de relais -Short = Court -Ultra Long = Ultra Longue -Tillgängliga filer installerades. Starta om MeOS. = Les configurations ont été installées. Redémarrez MeOS S.V.P. -edit_in_forest = Gérer\nCompétiteurs en forêt -Latest Results = Résultats récents -warning:direct_result = Notez que l'utilisation de nécessite que tous les poinçons de tous les postes du circuit aient été transmis comme poste radio, ou que MeOS soit utilisé pour chronométrer uniquement sans tenir compte du circuit.\n\nUtiliser les résultats sur poinçon d'arrivée ? -Inställningar startbevis = Configuration de l'impression des tickets de départ -Skrivarinställningar = Configuration de l'impression -Skrivarinställningar för sträcktider och startbevis = Configuration de l'impression des tickets de temps intermédiaires et de départ -Startbevis = Ticket de départ -Startbevis X = Ticket de départ X -Skriv ut startbevis = Ticket de départ -Skriv ut startbevis för deltagaren = Imprimer le ticket de départ du coureur -Utskrift = Imprimer -FrÃ¥n klassen = de la catégorie -Tillsätt ytterligare vakans = Remplir un autre vacant -Överföring = Transférer -Anmäl till efterföljande etapper = Entrer pour les étapes suivantes -Totalt antal etapper = Nombre total d'étapes -Vill du använda den nya brickan till alla etapper? = Voulez-vous utiliser une nouvelle puce pour toutes les étapes ? -Avkortad banvariant = Circuit raccourci associé -Avkortning = Raccourci -Hantera laget = Gérer l'équipe -Med avkortning = Avec raccourci -info_shortening = Sélectionnez un circuit existant qui raccourcit le circuit sélectionné. Plusieurs niveaux de raccourcissement sont possibles. -Tilldela starttider = Attribuer des heures de départ -Avkortar: X = Raccourci: X -Vill du nollställa alla manuellt tilldelade banor? = Voulez-vous effacer tous les circuits manuellement attribués ? -Ange löpande numrering eller första nummer i klassen = Spécifier une numérotation consécutive entre catégories ou le premier numéro de la catégorie -Ange relation mellan lagets och deltagarnas nummerlappar = Spécifier la relation entre le dossard de l'équipe et les dossards des coureurs de l'équipe -Lagmedlem = Membre de l'équipe -Löpande = Consécutif -Oberoende = Indépendant -Samma = Identique -Ökande = Croissant -Manuell = Manuel -Vill du uppdatera alla nummerlappar? = Voulez-vous mettre à jour tous les dossards ? -Hela banan = Circuit entier -Ogiltigt maximalt intervall = Intervalle maximum invalide -Startintervallet fÃ¥r inte vara kortare än basintervallet = L'intervalle entre départs ne doit pas être plus court que l'intervalle de base -Ett startintervall mÃ¥ste vara en multipel av basintervallet = Un intervalle de départ doit être un multiple de l'intervalle de base -Ogiltigt minimalt intervall = Intervalle minimum invalide -Ogiltigt basintervall = Intervalle de base invalide -Country = Pays -CourseShortening = Raccourcissement de course -Nationality = Nationalité -Number of shortenings = Nombre de raccourcissements -Längd = Distance -Redigera sträcklängder = Modifier les distances -Redigera sträcklängder för X = Modifier les distances du circuit 'X' -Oordnade parallella sträckor = Branches parallèles dans n'importe quel ordre -TillÃ¥t löpare inom en parallell grupp att springa gruppens banor i godtycklig ordning = Autoriser les coureurs d'un groupe parallèle à courir les circuits du groupe dans un ordre quelconque -Laguppställningen hade fel, som har rättats = La constitution de l'équipe a été corrigée -ControlClasses = Catégories du poste -ControlCodes = Numéros du poste -ControlCourses = Circuits du poste -ControlMaxLostTime = Poste, temps perdu, maximum -ControlMedianLostTime = Poste, temps perdu, médian -ControlMistakeQuotient = Poste, pourcentage de coureurs avec perte de temps -ControlName = Nom du poste -ControlPunches = Nombre de coureurs passant au poste -ControlRunnersLeft = Nombre de coureurs n'étant pas encore passé au poste -ControlVisitors = Nombre de coureurs attendus au poste -CourseClasses = Catégories du circuit -CourseUsage = Nombre de cartes nécessaires pour le circuit -CourseUsageNoVacant = Nombre de participant pour le circuit (vacants exclus) -Bomkvot = Pourcentage d'erreur -Control = Poste -Control Statistics = Statistiques du poste -Control Statistics - X = Statistiques du poste - X -Course = Course -FilterSameParallel = Grouper les variations identiques -Kontrollrapport - X = Rapport du poste - X -Maxbom = Erreur maximale -Control Overview = Aperçu général du poste -Medianbom = Erreur médiane -N.N. = X -Endast pÃ¥ obligatoriska sträckor = Traiter uniquement les variations non optionnelles. -Fyll obesatta sträckor i alla lag med anonyma tillfälliga lagmedlemmar (N.N.) = Remplir les variations vacantes de toutes les équipes avec des membres temporaires anonymes (X) -Skapa anonyma lagmedlemmar = Créer des membres d'équipe anonyme temporaires -Tillsätt tillfälliga anonyma lagmedlemmar = Ajouter des membres d'équipe anonymes temporaires -Tillsätt = Nommer -help:anonymous_team = Créer et nommer des membres (temporaires) d'équipe pour toutes les équipes, auxquels vous pouvez affecter une puce, un circuit, etc. -Anonymt namn = Nom anonyme -Med anmälningsavgift (lagets klubb) = Avec les frais d'inscription (pour le club de l'équipe) -Tar bort X = Retrait de X -Källa = Source -Ta bort eventuella avanmälda deltagare = Supprimer les inscriptions annulées si nécessaire -Verktyg = Outils -Automatisk = Automatique -AvstÃ¥nd = Distance -Extra avstÃ¥nd ovanför textblock = Distance additionnelle -FilterSameParallelNotFirst = Grouper les variations identiques sauf la première -RunnerLeg = Concurrent (variation spécifique) -Texten ska innehÃ¥lla tecknet X, som byts ut mot tävlingsspecifik data = Le texte doit inclure le symbole X, qui est remplacé par les données spécifiques à la compétition -Tabellverktyg = Outils table -Antal reserverade nummerlappsnummer mellan klasser = Nombre de dossards réservés entre les catégories -help:bibs = Vous pouvez gérer les dossards manuellement ou automatiquement. Ici vous pouvez affecter les dossards manuellement pour une certaine catégorie en spécifiant la méthode Manuelle et en fournissant le premier numéro pour cette catégorie.\n\nLa méthode automatique fonctionne de la même façon, avec la différence que MeOS mettra à jour les dossards de toutes les catégories d'un coup. Bien qu'il soit possible de faire ce paramétrage ici, il est préférable d'utiliser le Paramétrage rapide pour les catégories afin d'avoir une vue d'ensemble de toutes les catégories.\n\nUtiliser la méthode Automatique avec les méthodes Aucun ou Consécutifs, qui indique que le dernier numéro de la catégorie précédente est utilisé comme premier numéro. Le nombre de dossards réservés définit le saut de numérotation entre catégories.\n\nPour les catégories d'équipes vous pouvez spécifier la relation existant entre les numéros de dossard des équipiers et celui de l'équipe. Il peut être Identique, Indépendant, Croissant (Équipe 1: 101, 102, 103, 104, Équipe 2: 111, 112, 113, 114 etc.) ou par Combinaison (100-1, 100-2, 100-3 etc). -RunnerGeneralPlace = Place du coureur ou du relayeur -RunnerGeneralTimeAfter = Retard du coureur ou du relayeur -RunnerGeneralTimeStatus = Temps / statut du coureur ou du relayeur -open_error = Impossible d'ouvrir X.\n\nY. -open_error_locked = Cette compétition est déjà ouverte dans MeOS.\n\nVous devez utiliser une base de données pour ouvrir plus d'un exemplaire d'une compétition. -Ogiltigt bricknummer = Numéro de puce invalide -ask:updatelegs = Les longueurs des variations individuelles peut nécessiter une mise à jour après ce changement.\n\nSouhaitez-vous corriger cela maintenant ? -warn:updatelegs = Les longueurs des variations individuelles peut nécessiter une mise à jour après ce changement. -Ingen deltagare vald = Aucun concurrent sélectionné -FrÃ¥n klubben = Du club -FrÃ¥n laget = De l'équipe -Gafflingsnyckel X = Clé de variation X -help:teamwork = Les coureurs ont échangés leur place. Vous pouvez faire une succession d'échanges pour obtenir la nouvelle composition d'équipe. -Ordnat = Trié -Str. X = Relayeur X -Vill du att X gÃ¥r in i laget? = Voulez-vous mettre X dans l'équipe ? -Vill du att X och Y byter sträcka? = Voulez-vous que X et Y changent de variation ? -Vill du att X tar sträckan istället för Y? = Voulez-vous que X courre cette variation à la place de Y ? -Ändra lagets gaffling = Changer les variations de l'équipe -Deltagarens klass styrs av laget = La catégorie est définie par l'équipe -För att delta i en lagklass mÃ¥ste deltagaren ingÃ¥ i ett lag = Pour participer à une catégorie d'équipe vous devez affecter une équipe au coureur -Dela upp = Diviser -Alla sträckor = Toutes les variantes -Liveresultat, deltagare = Résultats en direct, individuels -Använd enhets-id istället för tävlings-id = Utiliser l'identifiant de l'appareil au lieu de l'identifiant de la compétition -Enhetens ID-nummer (MAC) = Identifiant de l'appareil (MAC) -Antal deltagare: X = Nombre de coureurs : X -Dela efter placering = Diviser par résultat -Dela efter tid = Diviser par temps -Dela slumpmässigt = Diviser aléatoirement -Jämna klasser (placering) = Faire des catégories égales (résultats) -Jämna klasser (ranking) = Faire des catégories égales (classement) -Jämna klasser (tid) = Faire des catégories égales (Temps) -Klass X = Catégorie X -Not yet implemented = Pas encore implémenté -Tidstillägg = Pénalité (M:SS) -help:seeding_info = L'allocation répartie des heures de départ signifie qu'un résultat ou un classement précédent contrôle en partie le processus. Dans le champ Groupes de répartition, vous pouvez entrer une taille de groupe unique, ce qui indique que la catégorie entière est à partitionner dans des groupes de cette taille. La taille de groupe "1" indique que l'ordre de répartition est rigoureusement respecté. Vous pouvez également spécifier plusieurs tailles de groupes. "15, 1000" signifiera un groupe de répartition contenant les 15 coureurs les mieux placés et les autres coureurs (au plus 1000) seront placés dans un groupe non réparti. -Ange en gruppstorlek (som repeteras) eller flera kommaseparerade gruppstorlekar = Fournir une taille de groupe (qui sera répétée) ou plusieurs tailles séparées par des virgules -Hindra att deltagare frÃ¥n samma klubb startar pÃ¥ angränsande tider = Empêcher que des coureurs du même club partent à des horaires consécutifs. -LÃ¥t de bästa start först = Faire partir le mieux classé en premier -Seedningsgrupper = Groupes de répartition -Seedningskälla = Données de répartition -error:invalidmethod = La méthode sélectionnée ne génère pas de distribution. Les données de répartition sont insuffisantes. -Ogiltig storlek pÃ¥ seedningsgrupper X = Taille des groupes de répartition invalide : X -Bananvändning = Fréquentation des circuits -Antal banor = Nombre de circuits -Could not load list 'X' = Impossible de charger la liste 'X' -FrÃ¥n den här listan kan man skapa etiketter att klistra pÃ¥ kartor = A partir de cette liste, vous pouvez créer les étiquettes à coller sur les cartes -Gafflingar i tabellformat = Combinaison au format table -Vakanser - X = Vacants - X -Kopiera = Copier -Kopiera till urklipp = Copier dans le presse papier -RunnerStartCond = Heure de départ du concurrent (si individuel) -StartTimeForClassRange = Plage d'heures de départ de la catégorie -TeamStartCond = Heure de départ de l'équipe (si individuel) -Liveresultat = Résultats en direct -Visa rullande tider mellan kontroller i helskärmsläge = Afficher les temps s'écoulant entre deux postes en mode plein écran -help:liveresultat = Cette méthode démarre un chronomètre en mode plein écran quand un coureur d'une catégorie sélectionnée poinçonne le poste , et mesure le temps jusqu'à ce que le poste soit atteint. Sinon la liste des meilleurs temps est affichée. Les deux postes doivent bien sûr être des postes radio et si vous utilisez un réseau, vérifiez bien que vous avez activé pour obtenir rapidement des temps les plus précis possibles. -Result at a control = Résultat au poste -Total/team result at a control = Résultat total/de l'équipe à un poste -prefsAccount = Numéro de compte par défaut -prefsAddress = Adresse par défaut -prefsAdvancedClassSettings = Afficher les paramètres avancés des catégories -prefsAutoSaveTimeOut = Intervalle de sauvegarde automatique (ms) -prefsCardFee = Tarif de location de puce par défaut -prefsClient = Nom du client sur le réseau -Vissa inställningar kräver omstart av MeOS för att ha effekt = Certains paramètres nécessitent le redémarrage de MeOS pour prendre effet -prefsAutoTie = Lier automatiquement coureur et puce -prefsControlFrom = Temps depuis le poste radio... -prefsControlTo = Temps jusqu'au poste radio... -prefsCurrencyFactor = Facteur d'échelle monétaire -prefsCurrencyPreSymbol = Placer le symbole monétaire en premier -prefsCurrencySeparator = Séparateur décimal monétaire -prefsCurrencySymbol = Symbole monétaire -prefsDatabase = Utiliser la base de données des coureurs -prefsDatabaseUpdate = Dernière mise à jour de la base des coureurs -prefsDefaultDrawMethod = Méthode de tirage par défaut -prefsDirectPort = Port réseau pour les poinçons radios -prefsEMail = E-mail -prefsEliteFee = Tarif par défaut pour les élites -prefsEntryFee = Tarif par défaut -prefsEventorBase = URL d'Eventor -prefsFirstInvoice = Premier numéro de facture -prefsFirstTime = Premier départ -prefsHomepage = Site web -prefsInteractive = Gestion interactive des puces -prefsLateEntryFactor = Coefficient pour les tarifs d'inscription tardive -prefsLiveResultFont = Police de caractère utilisée pour les résultats en direct -prefsMIPURL = URL du serveur MIP -prefsMOPFolderName = Répertoire MOP local -prefsMOPURL = URL du serveur MOP -prefsManualInput = Utiliser la saisie manuelle des temps -prefsMaximumSpeakerDelay = Délai maximum de mise à jour pour le speaker -prefsOrganizer = Organisateur -prefsPort = Port réseau MySQL -prefsRentCard = Puce louée -prefsSeniorAge = Age sénior -prefsServer = Serveur réseau par défaut -prefsSpeakerShortNames = Utiliser les initiales dans les noms -prefsStreet = Adresse club -prefsSynchronizationTimeOut = Délai d'attente de mise à jour réseau (ms) -prefsTextFont = Police utilisée par MeOS -prefsUseDirectSocket = Utiliser les données anticipées de poinçonnage -prefsUseEventor = Utiliser Eventor -prefsUseEventorUTC = Utiliser le temps UMT avec Eventor -prefsUseHourFormat = Utiliser le format HH:MM:SS au lieu de MMM:SS -prefsUserName = Identifiant MySQL -prefsYouthAge = Limite tarif jeune -prefsYouthFee = Tarif réduit -prefsaddressxpos = Coordonnée x de l'adresse -prefsaddressypos = Coordonnée y de l'adresse -prefsclasslimit = Limiter le nombre de résultats affichés par catégorie -prefsintertime = Montrer les temps intermédiaires -prefspagebreak = Ajouter des sauts de page -prefssplitanalysis = Analyser les temps intermédiaires -Ändra MeOS lokala systemegenskaper = Paramètres de MeOS -true[boolean] = vrai -false[boolean] = faux -Ändra X = Change X -Ingen parstart = Départ individuel -Parvis (tvÃ¥ och tvÃ¥) = Par paire (deux à deux) -X och Y[N by N] = X par Y -Lotta klasser med samma bana gemensamt = Faire le tirage des catégories ayant le même circuit ensemble -Lotta starttider = Définir les horaires de départ -Lotta klasser med banan X = Définir les horaires de départ du circuit 'X' -MeOS Timing = MeOS Timing -Med resultat = Avec les résultats -Säkerhetskopiering = Sauvegarde périodique -Destination: X = Destination: X -Ogiltig destination X = Destination X invalide -Säkerhetskopierar om = Sauvegarde dans -Year of birth = Année de naissance -Ogiltigt antal sekunder: X = Nombre de secondes invalide : X -Du kan använda en SI-enhet för att läsa in bricknummer = Vous pouvez utiliser un boîtier maître SI pour lire le numéro de la puce -Ignorera startstämpling = Ignorer le poinçon de départ -Uppdatera inte starttiden vid startstämpling = Ne pas mettre à jour l'horaire de départ avec le poinçon de départ -Ändra lokala inställningar = Modifier les paramètres -Gafflingsnyckel = Clé de variation -Felaktigt datumformat 'X' (Använd Ã…Ã…Ã…Ã…-MM-DD) = Format de date incorrect 'X' (AAAA-MM-JJ) -Felaktigt tidsformat 'X' (Använd TT:MM:SS) = Format d'heure incorrect 'X' (HH:MM:SS) -Hämta inställningar frÃ¥n föregÃ¥ende lottning = Récupérer les paramètres des sessions précédentes -Ej startstämpling = Ignorer le poinçon de départ -Extraplatser = Places supplémentaires -Fritt = Libre -FrÃ¥n lag = De l'équipe -Lag + sträcka = Équipe + variation -Nummerlappshantering = Gestion des dossards -Oordnade parallella = Unordered parallel ($2158) -Spara starttider = Enregistrer les heures de départ -X platser. Startar Y = X places. Départ de Y övriga = autre -RunnerStartZero = Heure de départ relative du coureur (heure zéro) -TeamStartZero = Heure de départ relative de l'équipe (heure zéro) -Datumfilter = Filtrage par date -Inget filter = Pas de filtre -Inlästa stämplar = Lire les poinçons -Löpare saknas = Aucun coureur -Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Les catégories X et Y ont le même identifiant externe. Utiliser le mode table pour corriger l'identifiant. -Vill du koppla isär X frÃ¥n inläst bricka Y? = Voulez-vous délier X de na puce numéro Y ? -RunnerRogainingPointGross = Points avant pénalités -Samlade poäng = Points acquis -Tidsavdrag = Pénalités -X p = X p -Bricka X används ocksÃ¥ av = La puce X est aussi utilisée par -reused card = puce réutilisée -Varning: Brickan X används redan av Y = Attention ! La puce X est déjà utilisée par Y -Invalid filter X = Filtre X invalide -Invalid font X = Police X invalide -Aktivera stöd för tider över 24 timmar = Supporter les durées de course de plus de 24h. -Inkludera information om flera lopp per löpare = Inclure les informations sur les courses multiples pour un coureur individuel. -Alla uthyrda brickor har bockats av = Toutes les puces louées ont été rendues -Avbockade brickor = Puces rendues -Avstämning hyrbrickor = Compter les puces louées rendues -Brickor markerade som bÃ¥de uthyrda och egna: X = Puces utilisées (personnelles ou louées) : X -Nollställ = Effacer -Nollställ minnet; markera alla brickor som icke avbockade = Effacer la mémoire; Oublier toutes les puces rendues -Rapport = Rapport -Totalt antal unika avbockade brickor: X = Nombre de puces rendues uniques : X -Uthyrda brickor som inte avbockats = Puces louées non rendues -Uthyrda: X, Egna: Y, Avbockade uthyrda: Z = Puces louées : X, Puces personnelles : Y, Louées et rendues : Z -Vill du göra om avbockningen frÃ¥n början igen? = Voulez-vous réinitialiser et tout recommencer ? -help:checkcards = Utiliser cette fonction pour effectuer le suivi des puces louées et vérifier qu'elles ont toute été rendues. Raccorder un boîtier maître SI (de préférence configuré en tant que boîtier contrôle ou d'arrivée car cela est plus rapide qu'en mode lecture de puce), et poinçonner toutes les puces rendues. Cliquer sur le bouton Rapport pour voir si des puces sont manquantes.\n\n La vérification est locale à cet ordinateur et ne modifie pas les données de la compétition. -Betalningsmetoder = Modes de paiement -help:paymentmodes = Vous pouvez définir des modes de paiement personnalisés, en complément des informations de facturation, afin de faciliter la comptabilité. -Betalsätt = Mode de paiement -Förväntat antal besökare: X = Nombre de visiteurs attendus : X -Starttiden är definerad genom klassen eller löparens startstämpling = L'heure de départ est définie par la catégorie ou le poinçonnage d'un boîtier départ -sekunder = secondes -är X före Y = X est avant Y -var först i mÃ¥l med tiden X = était le premier à terminer avec un temps de X -var först vid X med tiden Y = était le premier au poste X avec un temps de Y -var först vid växeln med tiden X = était le premier au passage de relais avec un temps de X -är nu pÃ¥ X plats med tiden Y = est maintenant à la X è place avec un temps de Y -är nu pÃ¥ delad X plats med tiden Y = est maintenant à égalité à la X è place avec un temps de Y -är X efter = est en retard de X -är X efter Y = est en retard de X derrière Y -är X efter; har tappat Y = est en retard de X; a perdu Y -är X efter; har tagit in Y = est en retard de X; a gagné Y -leder med X; har tappat Y = est en tête avec X; a perdu Y -leder med X; sprang Y snabbare än de jagande = est en tête avec X; court Y plus vite que les autres -leder med X = est en tête avec X -delar placering med X = est à égalité avec X -sekund = seconde -skickar ut X = lance X -Export language = Langue -Use French Federation of Orienteering mapping = Utiliser le format de la Fédération Française de CO -Export split times = Exporter les temps intermédiaires -Climb (m) = Dénivelé (m) -Utrymme: X = Taille : X -[Radera] = [Supprimer] -prefsNumSplitsOnePage = Nombre de puces par page -prefsPayModes = Modes de paiement -prefsSplitPrintMaxWait = Temps d'attente maximum lors de l'impression des temps intermédiaires -prefsWideSplitFormat = Imprimer les temps intermédiaires en grand format -ClassTeamLegResult = Résultat par catégorie et relayeur -SortLastNameOnly = Nom de famille -Databaskälla = Base de donnée source -Filnamn IOF (xml) eller OE (csv) med löpare = Fichier IOF (xml) ou OE (csv) avec coureurs -Importinställning = Préférences d'importation -prefsExportCSVSplits = Inclure les temps intermédiaires dans l'export csv -prefsExportFormat = Format d'exportation par défaut -prefsImportOptions = Options d'importation par défaut -prefsSplitLateFees = Séparer les frais d'inscription en frais standards et frais d'inscription tardive pour l'exportation IOF XML -Längsta tid i sekunder att vänta med utskrift = Délai maximum d'attente de l'impression en seconde -Max antal brickor per sida = Nombre maximum de puces par page -Sträcktider i kolumner (för standardpapper) = Temps en colonnes (pour imprimante A4) -Spara inmatade tider i tävlingen utan att tilldela starttider = Enregistrer les paramètres et les heures de départ de chaque catégorie pour y revenir plus tard -SRR Dongle = Dongle SRR -red channel = Réseau rouge -blue channel = Réseau bleu -Printing failed (X: Y) Z = Port par défaut -prefsNameMode = Format du nom : X -Kommunikationen med en SI-enhet avbröts = Connection perdue à la base SI-master -Varning: avgiften kan ej faktureras = Attention : impossible de générer de facture pour ce montant -Gamla brickor utan stöd för lÃ¥nga tider = Puces anciennes ne prenant pas en charge les longues courses -ask:convert_to_patrol = Certaines catégories contiennent des requêtes pour que certains coureurs aient la même heure de départ. Voulez-vous convertir ces catégories en catégories en binôme (type raid) ? -Antal som inte importerades: X = Nombre d'inscriptions sautées : X -Det finns anmälningsdata för flera etapper = Il y a des données pour plusieurs étapes -Välj etapp att importera = Sélectionner l'étape à importer -ask:savespeaker = Voulez-vous sauvegarder les paramètres d'affichage et de catégorie sur cet ordinateur ? -Spara fönster- och speakerinställningar pÃ¥ datorn = Enregistrer la fenêtre et les paramètres sur cet ordinateur -ask:loadspeaker = Voulez-vous réorganiser les fenêtres et paramètres comme enregistré précédemment sur cet ordinateur ? -Ã…terskapa = Réorganiser -Ã…terskapa tidigare sparade fönster- och speakerinställningar = Réorganiser les fenêtres et paramètres comme enregistré précédemment -Inkludera resultat frÃ¥n tidigare etapper = Inclure les résultats de toutes les étapes -Animation = Animation -Bakgrund = Arrière plan -Bakgrundsfärg = Couleur de fond -Fullskärm (rullande) = Plein écran (déroulant) -Fullskärm (sidvis) = Plein écran (page par page) -Fönster = Fenêtre -Fönster (rullande) = Fenêtre (déroulant) -Justera visningsinställningar = Ajuster les paramètres de visualisation -Marginal = Marge -Sidor per skärm = Pages par écran -Textfärg = Couleur du texte -Utseende = Affichage -Visningsinställningar för 'X' = Paramètres d'affichage pour 'X' -Visningstid = Afficher le temps -Visning = Mode d'affichage -ask:hasVacant = Il y a toujours des vacants.\n\nVoulez-vous retirer tous les vacants avant d'exporter les résultats ? -warn:missingResult = X coureurs ne sont toujours pas rentrés et ne sont donc pas classés.\n\nVous pouvez aller dans l'onglet 'Coureurs restants' et les passer en statut -Ã…terställ till = Remettre en -Ã…terbud[status] = Annulé -LÃ¥s gafflingar = Verrouiller les variations -Markera för att förhindra oavsiktlig ändring av gafflingsnycklar = Vérifier pour empêcher toute erreur dans la répartition des variations -TillÃ¥t gafflingsändringar = Déverrouiller les variations -ask:updatetimes = Voulez-vous conserver autant que possible les horaires de départ déjà affectés ? Répondez Non pour décaler la compétition dans le temps -X har en tid (Y) som inte är kompatibel med förändringen = X a une heure de départ (Y) ce qui n'est pas compatible avec ce changement -warn:latestarttime = Utiliser des heures de départ plus de X heures après l'heure zéro n'est pas conseillé -Anm. tid = Heure d'inscription -RunnerEntryDate = Date d'inscription -RunnerEntryTime = Heure d'inscription -RunnerPaid = Payé -RunnerPayMethod = Méthode de payement -EntryTime = Heure d'inscription -Ekonomihantering, X = Gestion financière, X -Manuellt gjorda justeringar = Ajustements manuels -Antal förfrÃ¥gningar: X = Nombre de requêtes -Genomsnittlig svarstid: X ms = Temps moyen de réponse : X -Informationsserver = MeOS Information Server -Längsta svarstid: X ms = Temps de réponse maximal : X -MeOS Informationsserver REST-API = MeOS Information Server REST-API -Testa servern = Tester le serveur -help:rest = MeOS REST API vous permet d'accéder à la compétition via le web. Vous pouvez afficher les résultats directement sur un navigateur, mais aussi exporter les données de la course en XML pour les envoyer vers d'autres applications et programmes. -Server startad pÃ¥ X = Serveur sur le port X -Inconsistent qualification rule, X = Règle de qualification incohérente, X -help:LockStartList = MeOS ne va mas modifier les heures de départ d'une catégorie verrouillée, même si les résultats des qualifications sont modifiées -Kval/final-schema = Schéma de qualifications/finale -LÃ¥s startlista = Verrouiller la liste de départ -FilterNoCancel = Pas annulés -CourseStartTime = Circuit, heure de départ -Startlista, banvis = Liste de départ par circuit -Stämplingsintervall, rogaining-patrull = Intervalle de poinçonnage maximal d'une patrouille -Patrullresultat (STOR) = Résultats de la patrouille (GRAND) -Patrol Team Rogaining = Course au score en patrouille -Rogaining results for a patrol = Résultats de course au score pour binôme (ou plus) -Exportera ett kalkylblad med lottningsinställningar som du kan redigera och sedan läsa in igen = Exporter un tableur avec les paramètres de départ que vous pouvez éditer, puis réimporter -Kalkylblad/csv = Tableur/csv -Importerar lottningsinställningar = Importer les paramètres des listes de départ -help:exportdraw = Vous pouvez exporter un tableur en CSV avec les catégories, le nombre d'inscrits et les paramètres des listes de départ par catégories. Il est ensuite possible d'éditer ces données et de les ré-importer dans MeOS pour créer les listes de départ. -prefsDrawInterlace = Entrelacer catégorie/circuits dans la liste de départ -prefsServicePort = Port par défaut X -Ingen nummerlapp = No de dossard -Rogaining results for a team, where each team member collects points individually = Résultats de course au score pour binôme où chaque membre collecte des points de façon individuelle -prefsCodePage = Code table pour l'import/export en 8 bits -Inga klasser tillÃ¥ter direktanmälan. PÃ¥ sidan klasser kan du ändra denna egenskap. = Aucune catégorie n'autorise les inscriptions rapides.\n\nVous pouvez modifier ce paramètre à la page 'Catégories'. -Database is used and cannot be deleted = La base de donnée est utilisée et ne peut être supprimée -Classes together = Catégories regroupées -Finish order = Ordre d'arrivée -First to finish = Premier à finir -Individual result by finish time = Résultat individuel sur l'heure d'arrivée -Endast tidtagning = Chronométrage seul -AllPunches = Tous les poinçons -CoursePunches = Poinçons (sur le circuit) -FilterNamedControl = Postes nommés -FilterNotFinish = Uniquement les arrivés -LineBreak = Saut de ligne -PunchAbsTime = Poinçon, heure réelle -PunchTimeSinceLast = Temps entre les postes -PunchTotalTime = Temps au poste -PunchName = Poinçon, code du poste -PunchNamedSplit = Temps depuis le dernier poste nommé -PunchSplitTime = Temps depuis le dernier poste (temps intermédiaire) -ClassLiveResult = Live results (temps radios), par catégorie -Felaktigt datum 'X' (Använd YYYY-MM-DD) = Date incorrecte (Mettre AAAA-MM-JJ) -FilterAnyResult = Avec temps radios/résultats -Liveresultat, radiotider = Résultats en direct avec radios -PunchTotalTimeAfter = Temps passé au poste -RunnerCheck = Heure de contrôle -RunnerId = Licence/ID -StartTimeClass = Heure de départ, catégorie -ask:outofmaps = Plus de cartes disponibles. Voulez-vous tout de même inscrire ce coureur ? -Varning: Kartorna är slut = Attention : plus de cartes disponibles -X gÃ¥r vidare, klass enligt ranking = X qualifiés, catégorie par le ranking -Vill du ta bort schemat? = Voulez-vous supprimer le schéma ? -ask:removescheme = Si vous retirez le schéma de qualification, les résultats seront perdus. Voulez-vous continuer ? -ClassKnockoutTotalResult = Class, knock-out total result -Support intermediate legs = Supporter les variations spécifiques en relais -help:custom_text_lines = Vous pouvez insérer du texte spécifique en ajoutant en dessous [DonnéeSpécifique]. Les infos disponibles sont visibles dans le tableau déroulant à droite.\n\nPar exemple : Bravo [RunnerName] ! -Importerar ranking = Importer le classement -Klart. X värden tilldelade = Terminé. X valeurs affectées -Felaktigt rankingformat i X. Förväntat: Y = Format de classement incorrect pour X.\nY attendu -Importerar RAID patrull csv-fil = Importer les données RAID en csv -Varning: Följande deltagare har ett osäkert resultat = Attention : les informations sur ce coureur ne sont pas claires -Direkt tidtagning = Chrono en direct -Klassval för 'X' = Sélection de la catégorie pour 'X' -Endast tidtagning (utan banor) = Chronométrage seul (pas de circuits) -Knockout total = Résumé des éliminations -Varvräkning = Compter les tours -Varvräkning med mellantid = Compter les tours en temps supplémentaire -Without courses = Sans circuit -Timekeeping = Chronométrage -Endast grundläggande (enklast möjligt) = Fonctionnalités de base -Endast tidtagning (utan banor), stafett = Chronométrage seul (pas de circuits), relais -Individuellt = Individuel -Lag och stafett = Équipe et relais -Övrigt = Divers -htmlhelp = Le HTML peut être exporté comme un tableur structuré ou comme un document formaté librement -HTML Export = Export HTML -HTML Export för 'X' = Export HTML pour 'X' -Lagra inställningar = Enregistrer les paramètres -Kolumner = Colonnes -Rader = Lignes -HTML formaterad genom listinställningar = HTML formaté par les paramètres de la liste -Begränsa antal rader per sida = Nombre max de lignes par page -Färre slingor = Moins de boucles -RunnerGrossTime = Temps avant modifications -TeamGrossTime = Temps de l'équipe avant modification -Visa detaljerad rapport för viss deltagare = Afficher le rapport détaillé pour un coureur spécifique -Förhindra att laget deltar i nÃ¥gon omstart = Permet à l'équipe de ne pas prendre part au départ en masse des attardés -Förhindra omstart = Empêcher le redémarrage -Ej omstart = Pas de redémarrage -Visa rubrik mellan listorna = Afficher le titre entre les listes -SlÃ¥ ihop med befintlig lista = Fusionner avec une liste existante -FrÃ¥n löpardatabasen = De la base de donnée coureurs -FrÃ¥n löpardatabasen i befintliga klubbar = De la base de donnée coureurs dan les clubs existants -Med direktanmälan = Avec inscription directe -TillÃ¥t anmälan = Autoriser les inscriptions -Anyone = N'importe qui -Bricknummer = Numéro de puce -Anmäl andra = Nouvelle inscription -Anmälan mottagen = Inscription acceptée -Automatisk omladdning = Mise à jour automatique -Till vilka klasser = Pour quelles catégories -Vem fÃ¥r anmäla sig = Qui peut s'inscrire -Anmälan mÃ¥ste hanteras manuellt = Votre inscription nécessite un traitement manuel -EFilterAPIEntry = Inscriptions via API -Visa rubrik = Afficher le titre -Rad X är ogiltig = La ligne X est invalide -Klassen X är listad flera gÃ¥nger = La catégorie X est listée plusieurs fois -Ogiltig starttid X = Heure de départ invalide : X -Ogiltigt startintervall X = Intervalle de départ invalide : X -Hittar inte klass X = Impossible de trouver la catégorie X -MeOS utvecklinsstöd = Aide au développement de MeOS -info:pageswithcolumns = Montrer la liste page par page, avec un nombre spécifié de colonnes. Les infos sont mises à jour à chaque bouclage. -Pages with columns = Pages avec colonnes -Pages with columns, no header = Pages avec colonnes, sans titre -Externa adresser = Liens externes -info:advanceinfo = Le service de transfert instantané des résultats a planté. Les résultats seront reçus avec quelques secondes de délais. C'est ce qui risque d'arriver si plus d'un service est lancé depuis cet ordinateur. -Klassen är full = La catégorie est déjà complète -Flytta upp = Monter -Flytta ner = Descendre -EFilterWrongFee = Frais d'inscription inattendu -RunnerExpectedFee = Tarif d'inscription attendu -Unexpected Fee = Tarifs d'inscription inattendus -Anmälningsdatum = Date d'inscription -Förväntad = Attendu -Registrera hyrbrickor = Pré-inscrire les puces louées -Vill du sätta hyrbricka pÃ¥ befintliga löpare med dessa brickor? = Voulez-vous distribuer les puces comptées comme louées à des coureurs déjà inscrits ? -Vill du ta bort brickan frÃ¥n hyrbrickslistan? = Voulez-vous retirer la puce de la liste des puces à louer ? -Vill du tömma listan med hyrbrickor? = Voulez-vous supprimer la liste des puces à louer ? -prefsLastExportTarget = Cible du dernier export -prefsServiceRootMap = Fonctions standard pour la source du serveur Web -prefsshowheader = Afficher les titres -help:registerhiredcards = Pré-inscrivez des puces comme puces louées pour affecter automatiquement le statut et le tarif correspondant quand cette puce est affectée. -Lagändringblankett = Modifications d'équipes -Mappa rootadresssen (http:///localhost:port/) till funktion = Imposer l'adresse (http:///localhost:port/) pour fonctionner -ClassAvailableMaps = Cartes disponibles pour la catégorie -ClassTotalMaps = Nombre total de cartes pour la catégorie -Export split times = Exporter les temps intermédiaires - - -prefsVacantPercent = Pourcentage de vacants -ClassNumEntries = Nombre d'inscrits dans la catégorie -Före X = Avant X -Efter X = Après X -SlÃ¥ ihop X = Fusionner X -SlÃ¥ ihop med = Fusionner avec - - -Age (on last day of current year) = Age (au dernier jour de l'année en cours) -Age above or equal implies senior/pensioner = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition) -Age below or equal implies youth = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition) -ClassNumEntries = Nombres d'inscrits dans la catégorie -Endast tidtagning = chronométrage seul -Flera lopp i valfri ordning = Somme de plusieurs circuits -FrÃ¥n första = Dép. au premier poste -Heat = Manche -Inkludera bana = Inclure le circuit -Kartor = Cartes -Knockout sammanställning = Résumé des éliminations -Kunde inte ladda upp löpardatabasen (X) = Impossible d'importer la base de données coureurs (X) -Kunde inte öppna databasen (X) = Impossible de se connecter à la base de données (X) -Kvalschema = Procédé de qualification -LÃ¥s funktion = Verr. fonction -LÃ¥s upp = Déverouiller -LÃ¥st gaffling = Variations verrouillées -MÃ¥lstämpling tillÃ¥ts inte (X) = Arrivée radio désactivée (x) [Finish punch disallowed] -Plac. E[stageno] = Place E -Poäng E[stageno] = Points E -Poängreduktion = Réduction -Radio = Postes -Radio tillÃ¥ts inte (X) = Postes de contrôle radios désactivés (X) [Radio controls disallowed] -Referens = Référence -Result module = Module de résultats -Rogaining points before automatic reduction = Points du circuit avant réduction automatique -Runner check time = Heure de contrôle du coureur -Runner/team earlier stage places = Places du coureur/de l'équipe aux étapes précédentes -Runner/team earlier stage points = Points du coureur/de l'équipe aux étapes précédentes -Runner/team earlier stage running times = Temps du coureur/de l'équipe aux étapes précédentes -Runner/team earlier stage statuses = Statuts du coureur/de l'équipe aux étapes précédentes -Senast sedd: X vid Y = Dernières infos: à X au poste Y -Startstämpling tillÃ¥ts inte (X) = Départ radio désactivé (X) [Start punch disallowed] -Status E[stageno] = Statut E -Status code for cancelled entry = Code de statut pour une inscription annulée -Status code for no timing = Code de statut pour une course non chronométrée -Status code for running out-of-competition = Code de statut pour non classé (NC) -Stigning = Dénivellé -Tid E[stageno] = Temps E -Till sista = Arr. au dernier poste -TillÃ¥t = Autoriser radios -Utom tävlan = NC -X anmälda = X inscrits -ask:usecourseinclass = Le circuit n'est utilisé par aucun autre coureur dans cette catégorie\n\nVoulez-vous tout de même l'utiliser ? -warn:printmodeonly = Attention, notez bien que vous ne faites qu'imprimer les données de la puce sans l'enregistrer.\n\nPour l'intégrer à la course, utilisez la fonction Lecture des puces/Radios. -Ã…ldersfiltrering = Filtrer par âge -There is no result module with X as identifier = Aucun module de résultat n'a X comme identifiant -Vakansplacering = Emplacement des vacants -Lottat = Répartis -Först = En premier -Sist = En dernier \ No newline at end of file +Försvunnen = Manquant diff --git a/code/gdiconstants.h b/code/gdiconstants.h index 3dc8f9e..eae8668 100644 --- a/code/gdiconstants.h +++ b/code/gdiconstants.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,6 +38,8 @@ enum KeyCommandCode { KC_SPEEDUP, KC_SLOWDOWN, KC_AUTOCOMPLETE, + KC_MARKALL, + KC_CLEARALL }; /** Enum used to stack GUI command control, "command line wizard" */ diff --git a/code/gdifonts.h b/code/gdifonts.h index e7b2cb8..ff40bd7 100644 --- a/code/gdifonts.h +++ b/code/gdifonts.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/gdiimpl.h b/code/gdiimpl.h index c42e44c..c83d816 100644 --- a/code/gdiimpl.h +++ b/code/gdiimpl.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/gdioutput.cpp b/code/gdioutput.cpp index 22af2b9..932b58a 100644 --- a/code/gdioutput.cpp +++ b/code/gdioutput.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2376,13 +2376,13 @@ void gdioutput::processListMessage(ListBoxInfo &bi, WPARAM wParam) LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) { - if (iMessage==WM_COMMAND) { + if (iMessage == WM_COMMAND) { WORD hwParam = HIWORD(wParam); - HWND hWnd=(HWND)lParam; - if (hwParam==EN_CHANGE) { + HWND hWnd = (HWND)lParam; + if (hwParam == EN_CHANGE) { list::iterator tit; if (useTables) - for (tit=Tables.begin(); tit!=Tables.end(); ++tit) + for (tit = Tables.begin(); tit != Tables.end(); ++tit) if (tit->table->inputChange(*this, hWnd)) return 0; } @@ -2392,8 +2392,8 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) //for (it=BI.begin(); it != BI.end(); ++it) { unordered_map::iterator it = biByHwnd.find(HWND(lParam)); - // if (it->hWnd==hWnd) { - if ( it != biByHwnd.end() ) { + // if (it->hWnd==hWnd) { + if (it != biByHwnd.end()) { ButtonInfo &bi = *it->second; processButtonMessage(bi, wParam); return 0; @@ -2431,62 +2431,62 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) } } } - else if (iMessage==WM_MOUSEMOVE) { + else if (iMessage == WM_MOUSEMOVE) { POINT pt; - pt.x=(signed short)LOWORD(lParam); - pt.y=(signed short)HIWORD(lParam); + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); list::iterator tit; - bool GotCapture=false; + bool GotCapture = false; if (useTables) - for (tit=Tables.begin(); tit!=Tables.end(); ++tit) + for (tit = Tables.begin(); tit != Tables.end(); ++tit) GotCapture = tit->table->mouseMove(*this, pt.x, pt.y) || GotCapture; if (GotCapture) return 0; - list::iterator it=IBox.begin(); + list::iterator it = IBox.begin(); while (it != IBox.end()) { if (PtInRect(&it->TextRect, pt) && (it->callBack || it->hasEventHandler())) { SetCursor(LoadCursor(NULL, IDC_HAND)); - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawBoxText(hDC, it->TextRect, *it, true); ReleaseDC(hWndTarget, hDC); SetCapture(hWndTarget); - GotCapture=true; - it->HasTCapture=true; + GotCapture = true; + it->HasTCapture = true; } else { if (it->HasTCapture) { - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawBoxText(hDC, it->TextRect, *it, false); ReleaseDC(hWndTarget, hDC); if (!GotCapture) ReleaseCapture(); - it->HasTCapture=false; + it->HasTCapture = false; } } if (it->HasCapture) { - if (GetCapture()!=hWndTarget) { - HDC hDC=GetDC(hWndTarget); + if (GetCapture() != hWndTarget) { + HDC hDC = GetDC(hWndTarget); drawCloseBox(hDC, it->Close, false); ReleaseDC(hWndTarget, hDC); if (!GotCapture) ReleaseCapture(); - it->HasCapture=false; + it->HasCapture = false; } else if (!PtInRect(&it->Close, pt)) { - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawCloseBox(hDC, it->Close, false); ReleaseDC(hWndTarget, hDC); } else { - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawCloseBox(hDC, it->Close, true); ReleaseDC(hWndTarget, hDC); } @@ -2494,25 +2494,25 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) ++it; } - for (size_t k=0;k::iterator it=IBox.begin(); + list::iterator it = IBox.begin(); POINT pt; - pt.x=(signed short)LOWORD(lParam); - pt.y=(signed short)HIWORD(lParam); + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); list::iterator tit; - if (useTables) - for (tit=Tables.begin(); tit!=Tables.end(); ++tit) + if (useTables) { + for (tit = Tables.begin(); tit != Tables.end(); ++tit) if (tit->table->mouseLeftDown(*this, pt.x, pt.y)) return 0; + } - while(it!=IBox.end()) { + while (it != IBox.end()) { if (PtInRect(&it->Close, pt)) { - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawCloseBox(hDC, it->Close, true); ReleaseDC(hWndTarget, hDC); SetCapture(hWndTarget); - it->HasCapture=true; + it->HasCapture = true; } ++it; } //Handle links - for (size_t k=0;k::iterator tit; - list::iterator it=IBox.begin(); + list::iterator it = IBox.begin(); POINT pt; - pt.x=(signed short)LOWORD(lParam); - pt.y=(signed short)HIWORD(lParam); + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); - if (useTables) - for (tit=Tables.begin(); tit!=Tables.end(); ++tit) + if (useTables) { + for (tit = Tables.begin(); tit != Tables.end(); ++tit) if (tit->table->mouseLeftUp(*this, pt.x, pt.y)) return 0; - - while (it!=IBox.end()) { + } + while (it != IBox.end()) { if (it->HasCapture) { - HDC hDC=GetDC(hWndTarget); + HDC hDC = GetDC(hWndTarget); drawCloseBox(hDC, it->Close, false); ReleaseDC(hWndTarget, hDC); ReleaseCapture(); - it->HasCapture=false; + it->HasCapture = false; if (PtInRect(&it->Close, pt)) { IBox.erase(it); @@ -2602,7 +2603,7 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) } else if (it->HasTCapture) { ReleaseCapture(); - it->HasTCapture=false; + it->HasTCapture = false; if (PtInRect(&it->TextRect, pt)) { if (!it->handleEvent(*this, GUI_INFOBOX) && it->callBack) @@ -2614,12 +2615,12 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam) } //Handle links - for (size_t k=0;k::iterator tit; POINT pt; - pt.x=(signed short)LOWORD(lParam); - pt.y=(signed short)HIWORD(lParam); + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); if (useTables) - for (tit=Tables.begin(); tit!=Tables.end(); ++tit) + for (tit = Tables.begin(); tit != Tables.end(); ++tit) if (tit->table->mouseLeftDblClick(*this, pt.x, pt.y)) return 0; } + else if (iMessage == WM_RBUTTONDOWN) { + POINT pt; + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); + + if (useTables) { + for (auto tit = Tables.begin(); tit != Tables.end(); ++tit) + if (tit->table->mouseRightDown(*this, pt.x, pt.y)) + return 0; + } + } + else if (iMessage == WM_RBUTTONUP) { + POINT pt; + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); + + if (useTables) { + for (auto tit = Tables.begin(); tit != Tables.end(); ++tit) + if (tit->table->mouseRightUp(*this, pt.x, pt.y)) + return 0; + } + } + else if (iMessage == WM_MBUTTONDOWN) { + POINT pt; + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); + + if (useTables) { + for (auto tit = Tables.begin(); tit != Tables.end(); ++tit) + if (tit->table->mouseMidDown(*this, pt.x, pt.y)) + return 0; + } + } + else if (iMessage == WM_MBUTTONUP) { + POINT pt; + pt.x = (signed short)LOWORD(lParam); + pt.y = (signed short)HIWORD(lParam); + + if (useTables) { + for (auto tit = Tables.begin(); tit != Tables.end(); ++tit) + if (tit->table->mouseMidUp(*this, pt.x, pt.y)) + return 0; + } + } else if (iMessage == WM_CHAR) { /*list::iterator tit; if (useTables) @@ -3504,6 +3549,23 @@ void gdioutput::adjustDimension(int width, int height) } } +// Alert from main thread (via callback) +void gdioutput::delayAlert(const wstring& msg) { + if (!delayedAlert.empty()) + delayedAlert += L", "; + if (delayedAlert.length() > 1000) + delayedAlert = L""; + + delayedAlert += lang.tl(msg); + PostMessage(hWndAppMain, WM_USER + 6, 0, LPARAM(this)); +} + +wstring gdioutput::getDelayedAlert() { + wstring out = L"#" + delayedAlert; + delayedAlert.clear(); + return out; +} + void gdioutput::alert(const string &msg) const { alert(widen(msg)); @@ -4002,6 +4064,7 @@ void gdioutput::removeString(string id) Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); ReleaseDC(hWndTarget, hDC); TL.erase(it); + itTL = TL.end(); shownStrings.clear(); return; } @@ -4833,6 +4896,8 @@ bool gdioutput::removeWidget(const string &id) } ++iit; } + + removeString(id); return false; } @@ -5757,6 +5822,12 @@ void gdioutput::tableCB(ButtonInfo &bu, Table *t) t->updateDimension(*this); refresh(); } + else if (bu.id == "tblMarkAll") { + t->keyCommand(*this, KC_MARKALL); + } + else if (bu.id == "tblClearAll") { + t->keyCommand(*this, KC_CLEARALL); + } else if (bu.id=="tblUpdate") { t->keyCommand(*this, KC_REFRESH); } @@ -5799,6 +5870,8 @@ void gdioutput::enableTables() toolbar->addButton("tblPrint", 0, STD_PRINT, "Skriv ut tabellen (X)#Ctrl+P"); toolbar->addButton("tblUpdate", 1, 0, "Uppdatera alla värden i tabellen (X)#F5"); toolbar->addButton("tblReset", 1, 4, "Ã…terställ tabeldesignen och visa allt"); + toolbar->addButton("tblMarkAll", 1, 5, "Markera allt (X)#Ctrl+A"); + toolbar->addButton("tblClearAll", 1, 6, "Markera inget (X)#Ctrl+D"); toolbar->addButton("tblCopy", 0, STD_COPY, "Kopiera selektionen till urklipp (X)#Ctrl+C"); if (t->canPaste()) toolbar->addButton("tblPaste", 0, STD_PASTE, "Klistra in data frÃ¥n urklipp (X)#Ctrl+V"); @@ -7040,7 +7113,18 @@ DWORD gdioutput::selectColor(wstring &def, DWORD input) { } cc.lpCustColors = staticColor; - if (ChooseColor(&cc)) { + int res = 0; + setCommandLock(); + try { + res = ChooseColor(&cc); + liftCommandLock(); + } + catch (...) { + liftCommandLock(); + throw; + } + + if (res) { wstring co; for (int ix = 0; ix < 16; ix++) { wchar_t bf[16]; @@ -7053,7 +7137,6 @@ DWORD gdioutput::selectColor(wstring &def, DWORD input) { return -1; } - void gdioutput::setAnimationMode(shared_ptr &data) { if (animationData && animationData->takeOver(data)) return; @@ -7118,3 +7201,22 @@ int gdioutput::getPageX() const { else return max(MaxX, xlimit) + scaleLength(60); } + +int gdioutput::popupMenu(int x, int y, const vector> &menuItems) const { + POINT pt; + pt.x = x; + pt.y = y; + ClientToScreen(getHWNDTarget(), &pt); + HMENU hm = CreatePopupMenu(); + for (auto &me : menuItems) { + if (me.first.empty()) + AppendMenu(hm, MF_SEPARATOR, me.second, L""); + else + AppendMenu(hm, MF_STRING, me.second, lang.tl(me.first).c_str()); + } + int res = TrackPopupMenuEx(hm, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + pt.x, pt.y, getHWNDTarget(), nullptr); + + DestroyMenu(hm); + return res; +} diff --git a/code/gdioutput.h b/code/gdioutput.h index e7f646e..7942a6a 100644 --- a/code/gdioutput.h +++ b/code/gdioutput.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -289,6 +289,8 @@ protected: shared_ptr animationData; shared_ptr autoCompleteInfo; + + wstring delayedAlert; public: AutoCompleteInfo &addAutoComplete(const string &key); @@ -571,7 +573,11 @@ public: void alert(const string &msg) const; void alert(const wstring &msg) const; - + // Alert from main thread (via callback) + void delayAlert(const wstring& msg); + // Get and clear any delayed alert + wstring getDelayedAlert(); + void fillDown(){Direction=1;} void fillRight(){Direction=0;} void fillNone(){Direction=-1;} @@ -762,8 +768,9 @@ public: void closeWindow(); + int popupMenu(int x, int y, const vector> &menuItems) const; + void setDBErrorState(bool state); - friend int TablesCB(gdioutput *gdi, int type, void *data); friend class Table; friend gdioutput *createExtraWindow(const string &tag, const wstring &title, int max_x, int max_y, bool fixedSize); diff --git a/code/gdistructures.h b/code/gdistructures.h index 71307d1..01a8b83 100644 --- a/code/gdistructures.h +++ b/code/gdistructures.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/generalresult.cpp b/code/generalresult.cpp index f8a37bc..1a96302 100644 --- a/code/generalresult.cpp +++ b/code/generalresult.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/generalresult.h b/code/generalresult.h index 9668275..6bd0845 100644 --- a/code/generalresult.h +++ b/code/generalresult.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/guihandler.h b/code/guihandler.h index cc50c65..651aa7d 100644 --- a/code/guihandler.h +++ b/code/guihandler.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/image.cpp b/code/image.cpp index 512b431..392a1a7 100644 --- a/code/image.cpp +++ b/code/image.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/image.h b/code/image.h index 1bdff5c..463d46c 100644 --- a/code/image.h +++ b/code/image.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/importformats.cpp b/code/importformats.cpp index 2d597ac..7335ac0 100644 --- a/code/importformats.cpp +++ b/code/importformats.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/infoserver.cpp b/code/infoserver.cpp index 475ce56..86d1b86 100644 --- a/code/infoserver.cpp +++ b/code/infoserver.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -568,8 +568,19 @@ bool InfoCompetitor::synchronize(bool useTotalResults, bool useCourse, oRunner & s = r.getTotalStatusInput(); } else if (t && !isQF && r.getLegNumber() > 0) { - legInput = t->getLegRunningTime(r.getLegNumber() - 1, true, false) * 10; - s = t->getLegStatus(r.getLegNumber() - 1, true, false); + int ltu = r.getLegNumber(); + pClass cls = t->getClassRef(true); + if (cls) { + LegTypes lt = cls->getLegType(ltu); + while (ltu > 0 && (lt == LTParallelOptional || lt == LTParallel|| lt == LTExtra || lt == LTIgnore) ) { + ltu--; + lt = cls->getLegType(ltu); + } + } + if (ltu > 0) { + legInput = t->getLegRunningTime(ltu - 1, true, false) * 10; + s = t->getLegStatus(ltu - 1, true, false); + } } if (totalStatus != s) { diff --git a/code/infoserver.h b/code/infoserver.h index a29f9e7..eba08a4 100644 --- a/code/infoserver.h +++ b/code/infoserver.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/inthashmap.h b/code/inthashmap.h index 22c487c..c0cd112 100644 --- a/code/inthashmap.h +++ b/code/inthashmap.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/intkeymap.hpp b/code/intkeymap.hpp index 78715c0..490c9cb 100644 --- a/code/intkeymap.hpp +++ b/code/intkeymap.hpp @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/intkeymapimpl.hpp b/code/intkeymapimpl.hpp index 43e4123..65ed8ef 100644 --- a/code/intkeymapimpl.hpp +++ b/code/intkeymapimpl.hpp @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/iof30interface.cpp b/code/iof30interface.cpp index 768634c..5e4f10b 100644 --- a/code/iof30interface.cpp +++ b/code/iof30interface.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -509,6 +509,11 @@ pCourse IOF30Interface::findCourse(gdioutput &gdi, void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment, const map &courses) { + + gdi.dropLine(); + gdi.addString("", 10, "info:teamcourseassignment"); + gdi.dropLine(); + vector allT; oe.getTeams(0, allT, false); @@ -1394,6 +1399,102 @@ void IOF30Interface::readStartList(gdioutput &gdi, xmlobject &xo, int &entRead, } } + + +void IOF30Interface::readResultList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) { + string ver; + xo.getObjectString("iofVersion", ver); + if (!ver.empty() && ver > "3.0") + gdi.addString("", 0, "Varning, okänd XML-version X#" + ver); + + map > teamClassConfig; + + xmlobject xEvent = xo.getObject("Event"); + if (xEvent) { + readEvent(gdi, xEvent, teamClassConfig); + } + + xmlList cResults; + xo.getObjects("ClassResult", cResults); + + struct RaceInfo { + int courseId; + int length; + int climb; + wstring startName; + }; + + for (xmlobject &xClassResult : cResults) { + + pClass pc = readClass(xClassResult.getObject("Class"), + teamClassConfig); + int classId = pc ? pc->getId() : 0; + + map raceToInfo; + + xmlList courses; + xClassResult.getObjects("Course", courses); + for (size_t k = 0; k < courses.size(); k++) { + int raceNo = courses[k].getObjectInt("raceNumber"); + if (raceNo > 0) + raceNo--; + RaceInfo &raceInfo = raceToInfo[raceNo]; + + raceInfo.courseId = courses[k].getObjectInt("Id"); + raceInfo.length = courses[k].getObjectInt("Length"); + raceInfo.climb = courses[k].getObjectInt("Climb"); + } + + if (raceToInfo.size() == 1) { + RaceInfo &raceInfo = raceToInfo.begin()->second; + if (raceInfo.courseId > 0) { + if (pc->getCourse() == 0) { + pCourse crs = oe.addCourse(pc->getName(), raceInfo.length, raceInfo.courseId); + crs->setStart(raceInfo.startName, false); + crs->getDI().setInt("Climb", raceInfo.climb); + pc->setCourse(crs); + crs->synchronize(); + } + } + } + else if (raceToInfo.size() > 1) { + } + + xmlList xPResults; + xClassResult.getObjects("PersonResult", xPResults); + //map > bibPatterns; + //oClass::extractBibPatterns(oe, bibPatterns); + + for (size_t k = 0; k < xPResults.size(); k++) { + if (readPersonResult(gdi, pc, xPResults[k], 0, teamClassConfig)) + entRead++; + else + entFail++; + } + xmlList tEntries; + xClassResult.getObjects("TeamResult", tEntries); + for (size_t k = 0; k < tEntries.size(); k++) { + //setupClassConfig(classId, tEntries[k], teamClassConfig); + entFail++; // Teams not supported + } + /* + //setupRelayClasses(teamClassConfig); + if (pc && teamClassConfig.count(pc->getId()) && !teamClassConfig[pc->getId()].empty()) { + setupRelayClass(pc, teamClassConfig[pc->getId()]); + } + + for (size_t k = 0; k < tEntries.size(); k++) { + if (readTeamStart(gdi, pc, tEntries[k], bibPatterns, teamClassConfig)) + entRead++; + else + entFail++; + } + */ + pc->synchronize(); + } +} + + void IOF30Interface::readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) { string ver; xo.getObjectString("iofVersion", ver); @@ -2125,6 +2226,180 @@ pRunner IOF30Interface::readPersonStart(gdioutput &gdi, pClass pc, xmlobject &xo return r; } + +wstring formatStatus(RunnerStatus st, bool hasTime) { + switch (st) { + case StatusNoTiming: + if (!hasTime) + break; + case StatusOK: + return L"OK"; + case StatusDNS: + return L"DidNotStart"; + case StatusCANCEL: + return L"Cancelled"; + case StatusMP: + return L"MissingPunch"; + case StatusDNF: + return L"DidNotFinish"; + case StatusDQ: + return L"Disqualified"; + case StatusMAX: + return L"OverTime"; + case StatusOutOfCompetition: + if (!hasTime) + break; + case StatusNotCompetiting: + return L"NotCompeting"; + } + return L"Inactive"; +} + +RunnerStatus parseStatus(const wstring &status) { + if (status == L"OK") + return StatusOK; + else if (status == L"DidNotStart") + return StatusDNS; + else if (status == L"MissingPunch") + return StatusMP; + else if (status == L"Cancelled") + return StatusCANCEL; + else if (status == L"DidNotFinish") + return StatusDNF; + else if (status == L"Disqualified") + return StatusDQ; + else if (status == L"OverTime") + return StatusMAX; + else if (status == L"NotCompeting") + return StatusOutOfCompetition; + + return StatusUnknown; +} + +pRunner IOF30Interface::readPersonResult(gdioutput &gdi, pClass pc, xmlobject &xo, pTeam team, + const map > &teamClassConfig) { + xmlobject xPers = xo.getObject("Person"); + pRunner r = 0; + if (xPers) + r = readPerson(gdi, xPers); + if (r == 0) + return 0; + + if (pc && (r->getClassId(false) == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass))) + r->setClassId(pc->getId(), true); + + // Club + pClub c = readOrganization(gdi, xo.getObject("Organisation"), false); + if (!c) + c = readOrganization(gdi, xo.getObject("Organization"), false); + + if (c) + r->setClubId(c->getId()); + + xmlList results; + xo.getObjects("Result", results); + + for (size_t k = 0; k < results.size(); k++) { + int race = results[k].getObjectInt("raceNumber"); + pRunner rRace = r; + if (race > 1 && r->getNumMulti() > 0) { + pRunner rr = r->getMultiRunner(race - 1); + if (rr) + rRace = rr; + } + if (rRace) { + // Card + int cardNo = results[k].getObjectInt("ControlCard"); + if (cardNo > 0) + rRace->setCardNo(cardNo, false); + + wstring bib; + results[k].getObjectString("BibNumber", bib); + rRace->getDI().setString("Bib", bib); + + xmlobject startTime = results[k].getObject("StartTime"); + /* + if (team) { + int leg = starts[k].getObjectInt("Leg"); + int legorder = starts[k].getObjectInt("LegOrder"); + int legindex = max(0, leg - 1); + map >::const_iterator res = teamClassConfig.find(team->getClassId(false)); + if (res != teamClassConfig.end()) { + legindex = getIndexFromLegPos(leg, legorder, res->second); + } + team->setRunner(legindex, rRace, false); + if (rRace->getClubId() == 0) + rRace->setClubId(team->getClubId()); + + if (startTime && pc) { + pc->setStartType(legindex, STDrawn, false); + + } + }*/ + int st = parseISO8601Time(startTime); + rRace->setStartTime(st, true, oBase::ChangeType::Update); + + xmlobject finishTime = results[k].getObject("FinishTime"); + int ft = parseISO8601Time(finishTime); + rRace->setFinishTime(ft); + + wstring status; + results[k].getObjectString("Status", status); + rRace->setStatus(parseStatus(status), true, oBase::ChangeType::Update); + + xmlList splits; + results[k].getObjects("SplitTime", splits); + if (!splits.empty()) { + pCard card = oe.allocateCard(rRace); + card->setCardNo(cardNo); + vector controls; + wstring s; + for (auto &split : splits) { + int code = split.getObjectInt("ControlCode"); + int time = split.getObjectInt("Time"); + split.getObjectString("status", s); + if (s != L"missing") + card->addPunch(code, st + time, 0); + + if (s != L"additional") + controls.push_back(code); + } + + if (ft > 0) + card->addPunch(oPunch::PunchFinish, ft, 0); + + //Update to SQL-source + card->synchronize(); + + if (!controls.empty()) { + pCourse c = r->getCourse(true); + if (!c) + c = oe.addCourse(oe.getAutoCourseName()); + + if (c->getNumControls() == 0) { + for (int ctrl : controls) { + c->addControl(ctrl); + } + + c->synchronize(); + } + + if (pc) + pc->setCourse(c); + else + rRace->setCourseId(c->getId()); + } + + vector mp; + rRace->addPunches(card, mp); + } + } + } + + r->synchronize(); + return r; +} + void IOF30Interface::readId(const xmlobject &person, int &pid, __int64 &extId) const { wstring sid; pid = 0; @@ -3052,34 +3327,6 @@ void IOF30Interface::writeCourseInfo(xmlparser &xml, const oCourse &c) { xml.write("Climb", climb); } -wstring formatStatus(RunnerStatus st, bool hasTime) { - switch (st) { - case StatusNoTiming: - if (!hasTime) - break; - case StatusOK: - return L"OK"; - case StatusDNS: - return L"DidNotStart"; - case StatusCANCEL: - return L"Cancelled"; - case StatusMP: - return L"MissingPunch"; - case StatusDNF: - return L"DidNotFinish"; - case StatusDQ: - return L"Disqualified"; - case StatusMAX: - return L"OverTime"; - case StatusOutOfCompetition: - if (!hasTime) - break; - case StatusNotCompetiting: - return L"NotCompeting"; - } - return L"Inactive"; -} - void IOF30Interface::writePersonResult(xmlparser &xml, const oRunner &r, bool includeCourse, bool teamMember, bool hasInputTime) { if (!teamMember) @@ -4087,7 +4334,7 @@ pCourse IOF30Interface::readCourse(const xmlobject &xcrs) { for (size_t k = 0; k < xControls.size(); k++) { string type; xControls[k].getObjectString("type", type); - if (type == "Start") { + if (type == "Start" && startName.empty()) { wstring idStr; xControls[k].getObjectString("Control", idStr); pControl pStart = oe.getControl(getStartIndex(idStr), false); diff --git a/code/iof30interface.h b/code/iof30interface.h index dd41852..66bc24d 100644 --- a/code/iof30interface.h +++ b/code/iof30interface.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -176,6 +176,10 @@ class IOF30Interface { map > &bibPatterns, const map > &teamClassConfig); + + pRunner readPersonResult(gdioutput &gdi, pClass pc, xmlobject &xo, pTeam team, + const map > &teamClassConfig); + pTeam getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, int expectedClassId, bool &newTeam); static int getIndexFromLegPos(int leg, int legorder, const vector &setup); @@ -310,6 +314,8 @@ public: void readStartList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); + void readResultList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); + void readServiceRequestList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); void readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); diff --git a/code/listeditor.cpp b/code/listeditor.cpp index 450bb95..260d771 100644 --- a/code/listeditor.cpp +++ b/code/listeditor.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -328,20 +328,28 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { } else if (type == GUI_INPUTCHANGE) { InputInfo &ii = *(InputInfo *)(&data); - bool show = false; - if (ii.text.length() > 1) { - vector rec; - MetaList::getAutoComplete(ii.text, rec); - if (!rec.empty()) { - auto &ac = gdi.addAutoComplete(ii.id); - ac.setAutoCompleteHandler(this); - ac.setData(rec); - ac.show(); - show = true; + if (ii.id == "SearchText") { + bool show = false; + if (ii.text.length() > 1) { + vector rec; + MetaList::getAutoComplete(ii.text, rec); + if (!rec.empty()) { + auto &ac = gdi.addAutoComplete(ii.id); + ac.setAutoCompleteHandler(this); + ac.setData(rec); + ac.show(); + show = true; + } + } + if (!show) { + gdi.clearAutoComplete(ii.id); } } - if (!show) { - gdi.clearAutoComplete(ii.id); + } + else if (type == GUI_INPUT) { + InputInfo &ii = *(InputInfo *)(&data); + if (ii.id == "Text" && ii.text != lastShownExampleText) { + showExample(gdi); } } else if (type == GUI_BUTTON) { @@ -423,7 +431,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { makeDirty(gdi, MakeDirty, MakeDirty); show(gdi); } - else if ( bi.id == "Remove" ) { + else if (bi.id == "Remove") { DWORD id; gdi.getData("CurrentId", id); getPosFromId(id, groupIx, lineIx, ix); @@ -491,22 +499,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { mlp.setColor(GDICOLOR(gdi.getExtraInt("Color"))); - if (gdi.isChecked("UseLeg")) { - int leg = gdi.getTextNo("Leg"); - if (newType == lResultModuleNumber || newType == lResultModuleTime || - newType == lResultModuleNumberTeam || newType == lResultModuleTimeTeam) { - if (leg < 0 || leg > 1000) - throw meosException("X är inget giltigt index#" + itos(leg)); - mlp.setLeg(leg); - } - else { - if (leg < 1 || leg > 1000) - throw meosException("X är inget giltigt sträcknummer#" + itos(leg)); - mlp.setLeg(leg - 1); - } - } - else - mlp.setLeg(-1); + int leg = readLeg(gdi, newType, true); + mlp.setLeg(leg); if (gdi.hasWidget("UseResultModule") && gdi.isChecked("UseResultModule")) mlp.setResultModule(currentList->getResultModule()); @@ -625,8 +619,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { if (fileName.empty()) { int ix = 0; vector< pair > ext; - ext.push_back(make_pair(L"xml-data", L"*.xml")); - fileName = gdi.browseForSave(ext, L"xml", ix); + ext.push_back(make_pair(L"List definition", L"*.meoslist")); + fileName = gdi.browseForSave(ext, L"meoslist", ix); if (fileName.empty()) return 0; } @@ -643,8 +637,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { return 0; vector< pair > ext; - ext.push_back(make_pair(L"xml-data", L"*.xml")); - wstring fileName = gdi.browseForOpen(ext, L"xml"); + ext.push_back(make_pair(L"List definition", L"*.meoslist;*.xml")); + wstring fileName = gdi.browseForOpen(ext, L"meoslist"); if (fileName.empty()) return 0; @@ -822,18 +816,55 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) { else if (type==GUI_CLEAR) { return checkSave(gdi); } - return 0; } +int ListEditor::readLeg(gdioutput &gdi, EPostType newType, bool checkError) const { + if (MetaList::isResultModuleOutput(newType)) { + int leg = gdi.getTextNo("Leg"); + if (leg < 0 || leg > 1000) { + if (checkError) + throw meosException("X är inget giltigt index#" + itos(leg)); + else + leg = -1; + } + return leg; + } + else if (MetaList::isAllStageType(newType)) { + int leg = gdi.getSelectedItem("LegSel").first; + if (leg >= 1) + return leg - 1; + else + return -1; + } + else { + if (gdi.isChecked("UseLeg")) { + int leg = gdi.getTextNo("Leg"); + if (leg < 1 || leg > 1000) { + if (checkError) + throw meosException("X är inget giltigt sträcknummer#" + itos(leg)); + else + leg = -1; + } + return leg - 1; + } + else + return -1; + } +} + void ListEditor::updateType(int iType, gdioutput & gdi) { EPostType type = EPostType(iType); - gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true); - if (type == lResultModuleNumber || type == lResultModuleTime || - type == lResultModuleNumberTeam || type == lResultModuleTimeTeam) { - gdi.check("UseLeg", true); - gdi.disableInput("UseLeg"); + int leg = -1; + if (gdi.hasWidget("leg")) + leg = gdi.getTextNo("Leg"); + gdi.restore("Example", false); + + if (legStageTypeIndex(gdi, type, leg)) { + gdi.setRestorePoint("Example"); + } + if (MetaList::isResultModuleOutput(type)) { if (gdi.hasWidget("UseResultModule")) { gdi.check("UseResultModule", true); gdi.disableInput("UseResultModule"); @@ -841,10 +872,12 @@ void ListEditor::updateType(int iType, gdioutput & gdi) { gdi.enableInput("Leg"); if (gdi.getText("Leg").empty()) gdi.setText("Leg", L"0"); + } + else if (MetaList::isAllStageType(type)) { + } else { - gdi.enableInput("UseLeg"); - if (gdi.getTextNo("Leg") == 0) { + if (leg == 0) { gdi.setText("Leg", L""); gdi.enableInput("UseLeg"); gdi.enableInput("UseResultModule", true); @@ -852,11 +885,8 @@ void ListEditor::updateType(int iType, gdioutput & gdi) { gdi.disableInput("Leg"); } } - - gdi.restore("Example", false); - int margin = gdi.scaleLength(10); - showExample(gdi, margin, type); - gdi.refreshFast(); + + showExample(gdi, type); } void ListEditor::checkUnsaved(gdioutput &gdi) { @@ -886,10 +916,8 @@ void ListEditor::updateAlign(gdioutput &gdi, int val) { gdi.setInputStatus("Color", val != 1); gdi.setInputStatus("Fonts", val != 1); - - - } + void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { checkUnsaved(gdi); gdi.restore("EditList", false); @@ -918,7 +946,10 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { if (ix + 1 == currentList->getNumPostsOnLine(groupIx, lineIx)) gdi.setInputStatus("MoveRight", false); - gdi.dropLine(3); + gdi.dropLine(1); + int boxY = gdi.getCY(); + gdi.dropLine(2); + gdi.popX(); vector< pair > types; int currentType; @@ -940,7 +971,6 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { sort(types.begin(), types.end()); gdi.pushX(); - int boxY = gdi.getCY(); gdi.fillRight(); gdi.addString("", 0, L"Typ:"); gdi.fillDown(); @@ -958,7 +988,8 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { gdi.dropLine(-1); gdi.addItem("Type", types); gdi.selectItemByData("Type", currentType); - gdi.addInput("Text", mlp.getText(), 16, 0, L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data."); + gdi.addInput("Text", mlp.getText(), 16, editListCB, + L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data."); gdi.setInputFocus("Text", true); ((InputInfo *)gdi.setText("SearchText", getSearchString()))->setFgColor(colorGreyBlue); int boxX = gdi.getCX(); @@ -972,21 +1003,28 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { gdi.popX(); } + xpUseLeg = gdi.getCX(); + ypUseLeg = gdi.getCY(); + int leg = mlp.getLeg(); - gdi.addCheckbox("UseLeg", getIndexDescription(storedType), editListCB, leg != -1); - gdi.dropLine(-0.2); - gdi.setCX(gdi.getCX() + gdi.getLineHeight() * 5); - if (storedType == lResultModuleNumber || storedType == lResultModuleTime || storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam) - gdi.addInput("Leg", leg >= 0 ? itow(leg) : L"0", 4); + + legStageTypeIndex(gdi, storedType, leg); + /*gdi.addCheckbox(xpUseLeg, ypUseLeg, "UseLeg", getIndexDescription(storedType), editListCB, leg != -1); + //gdi.dropLine(-0.2); + int dx = gdi.scaleLength(250); + int dy = -gdi.getLineHeight() / 5; + + //gdi.setCX(gdi.getCX() + gdi.scaleLength(100)); + if (MetaList::isResultModuleOutput(storedType)) + gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", leg >= 0 ? itow(leg) : L"0", 4); else - gdi.addInput("Leg", leg >= 0 ? itow(leg + 1) : L"", 4); + gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", leg >= 0 ? itow(leg + 1) : L"", 4); - gdi.enableInput("Leg", leg != -1); - - if (storedType == lResultModuleNumber || storedType == lResultModuleTime || - storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam) { - gdi.check("UseLeg", true); - gdi.disableInput("UseLeg"); + gdi.setInputStatus("Leg", leg != -1); + */ + if (MetaList::isResultModuleOutput(storedType)) { + //gdi.check("UseLeg", true); + //gdi.disableInput("UseLeg"); if (gdi.hasWidget("UseResultModule")) { gdi.check("UseResultModule", true); gdi.disableInput("UseResultModule"); @@ -1023,10 +1061,13 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { int maxY = gdi.getCY(); gdi.popX(); gdi.fillDown(); + int innerBoxUpperCX = boxX + gdi.scaleLength(18); + int innerBoxUpperCY = boxY; + gdi.setCX(boxX + gdi.scaleLength(24)); - gdi.setCY(boxY); + gdi.setCY(boxY + gdi.scaleLength(6)); gdi.pushX(); - gdi.addString("", 1, "Formateringsregler"); + gdi.addString("", fontMediumPlus, "Formateringsregler"); gdi.dropLine(0.5); gdi.fillRight(); int val = 0; @@ -1069,10 +1110,15 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { gdi.dropLine(); gdi.addButton("Color", "Färg...", editListCB).setExtra(mlp.getColorValue()); - maxX = max(maxX, gdi.getCX()); - gdi.popX(); + int innerBoxLowerCX = maxX + gdi.scaleLength(6); + maxX += gdi.scaleLength(12); + + gdi.setCX(boxX - gdi.scaleLength(6)); gdi.dropLine(3); + int innerBoxLowerCY = gdi.getCY(); + + gdi.dropLine(); gdi.setData("CurrentId", id); gdi.addButton("Remove", "Radera", editListCB, "Ta bort listposten"); @@ -1086,29 +1132,63 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) { maxX = max(gdi.getCX(), maxX); RECT rc; + rc.top = y1; rc.left = x1; rc.right = maxX + gdi.scaleLength(6); rc.bottom = maxY + gdi.scaleLength(6) + gdi.getLineHeight()*4; - gdi.addRectangle(rc, colorLightBlue, true); + gdi.addRectangle(rc, colorLightBlue, true, false); + + rc.top = innerBoxUpperCY; + rc.left = innerBoxUpperCX; + rc.right = innerBoxLowerCX; + rc.bottom = innerBoxLowerCY; + + gdi.addRectangle(rc, colorLightYellow, true, false); + gdi.setData("IsEditing", 1); gdi.setCX(x1); gdi.setCY(maxY); - showExample(gdi, margin, mlp); + gdi.scrollToBottom(); + + showExample(gdi, mlp); updateAlign(gdi, val); - gdi.scrollToBottom(); gdi.refresh(); } -void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp) { +void ListEditor::showExample(gdioutput &gdi, EPostType type) { + if (type == EPostType::lLastItem) { + type = EPostType(gdi.getSelectedItem("Type").first); + } + + gdi.restore("Example", false); + + MetaListPost mlp(type); + // Has not effect + //mlp.setLeg(readLeg(gdi, type, false)); + mlp.setText(gdi.getText("Text", false)); + showExample(gdi, mlp); + gdi.refreshFast(); +} + +void ListEditor::showExample(gdioutput &gdi, const MetaListPost &mlp) { int x1 = gdi.getCX(); + int margin = gdi.scaleLength(10); RECT rrInner; rrInner.left = x1 + margin; rrInner.top = gdi.getCY(); + bool hasSymbol; + lastShownExampleText = mlp.getText(); + GDICOLOR color = GDICOLOR::colorLightGreen; + wstring text = MetaList::encode(mlp.getTypeRaw(), lastShownExampleText, hasSymbol); + if (!hasSymbol) { + text = lang.tl("Fel: Använd X i texten där värdet (Y) ska sättas in.#X#%s"); + color = GDICOLOR::colorLightRed; + } gdi.setRestorePoint("Example"); gdi.fillDown(); @@ -1127,6 +1207,12 @@ void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp wstring s = oe->formatListString(mlp.getTypeRaw(), rr[i]); if (used.insert(s).second) { int xb = gdi.getCX(); + if (!text.empty()) { + wchar_t st[300]; + swprintf_s(st, text.c_str(), s.c_str()); + s = st; + } + gdi.addStringUT(italicText, s + L" "); int xa = gdi.getCX(); int delta = xa - xb; @@ -1142,7 +1228,7 @@ void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp gdi.fillDown(); gdi.popX(); - gdi.addRectangle(rrInner, colorLightGreen, true); + gdi.addRectangle(rrInner, color, true); } const wchar_t *ListEditor::getIndexDescription(EPostType type) { @@ -1150,10 +1236,88 @@ const wchar_t *ListEditor::getIndexDescription(EPostType type) { return L"Index in X[index]#OutputTimes"; else if (type == lResultModuleNumber || type == lResultModuleNumberTeam) return L"Index in X[index]#OutputNumbers"; - else + else if (MetaList::isAllStageType(type)) + return L"Applicera för specifik etapp:"; + else return L"Applicera för specifik sträcka:"; } +bool ListEditor::legStageTypeIndex(gdioutput &gdi, EPostType type, int leg) { + int dx = gdi.scaleLength(250); + int dy = -gdi.getLineHeight() / 5; + + if (MetaList::isResultModuleOutput(type)) { + if (gdi.hasWidget("UseLeg")) + gdi.removeWidget("UseLeg"); + + if (gdi.hasWidget("LegSel")) + gdi.removeWidget("LegSel"); + + if (gdi.hasWidget("TUseLeg")) + gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true); + else + gdi.addString("TUseLeg", ypUseLeg, xpUseLeg, 0, getIndexDescription(type)); + + wstring legW = leg >= 0 ? itow(leg) : L"0"; + if (!gdi.hasWidget("Leg")) + gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", legW, 4, editListCB); + else { + if (gdi.getText("Leg").empty()) + gdi.setText("Leg", legW); + } + } + else if (MetaList::isAllStageType(type)) { + if (gdi.hasWidget("UseLeg")) + gdi.removeWidget("UseLeg"); + + if (gdi.hasWidget("Leg")) + gdi.removeWidget("Leg"); + + if (gdi.hasWidget("TUseLeg")) + gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true); + else + gdi.addString("TUseLeg", ypUseLeg, xpUseLeg, 0, getIndexDescription(type)); + + if (!gdi.hasWidget("LegSel")) { + gdi.addSelection(xpUseLeg + dx, ypUseLeg + dy, "LegSel", 160, gdi.scaleLength(300), editListCB); + vector> items; + items.emplace_back(lang.tl("Alla tidigare etapper"), -2); + for (int j = 1; j < 20; j++) { + items.emplace_back(lang.tl("Etapp X#" + itos(j)), j); + } + gdi.addItem("LegSel", items); + gdi.selectItemByData("LegSel", leg >= 0 ? leg + 1 : -2); + } + } + else { + if (gdi.hasWidget("LegSel")) + gdi.removeWidget("LegSel"); + + if (!gdi.hasWidget("UseLeg")) { + if (gdi.hasWidget("TUseLeg")) + gdi.removeWidget("TUseLeg"); + + gdi.addCheckbox(xpUseLeg, ypUseLeg, "UseLeg", getIndexDescription(type), editListCB, leg != -1); + + wstring ix = leg >= 0 ? itow(leg + 1) : L""; + if (!gdi.hasWidget("Leg")) + gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", ix, 4, editListCB); + else { + int leg = gdi.getTextNo("Leg"); + gdi.setText("Leg", ix); + } + gdi.setInputStatus("Leg", leg != -1); + } + } + + /* + if (MetaList::isResultModuleOutput(type)) { + gdi.check("UseLeg", true); + gdi.disableInput("UseLeg"); + }*/ + return true; +} + void ListEditor::editListProp(gdioutput &gdi, bool newList) { checkUnsaved(gdi); diff --git a/code/listeditor.h b/code/listeditor.h index 52821e3..70fa4f4 100644 --- a/code/listeditor.h +++ b/code/listeditor.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,6 +34,7 @@ class TabBase; #include #include "autocompletehandler.h" +#include "oListInfo.h" class ListEditor : public AutoCompleteHandler { private: @@ -47,7 +48,7 @@ private: bool dirtyInt; SaveType lastSaved; const wchar_t *getIndexDescription(EPostType type); - + wstring lastShownExampleText; void showLine(gdioutput &gdi, const vector &line, int ix) const; int editList(gdioutput &gdi, int type, BaseInfo &data); void updateType(int iType, gdioutput &gdi); @@ -56,7 +57,12 @@ private: int lineIx, int ix) const; void editListPost(gdioutput &gdi, const MetaListPost &mlp, int id); - void showExample(gdioutput &gdi, int margin, const MetaListPost &mlp); + + void showExample(gdioutput &gdi, EPostType type = EPostType::lLastItem); + + void showExample(gdioutput &gdi, const MetaListPost &mlp); + + int readLeg(gdioutput &gdi, EPostType newType, bool checkError) const; void editListProp(gdioutput &gdi, bool newList); @@ -78,6 +84,12 @@ private: TabBase *origin = nullptr; void show(gdioutput &gdi); + int xpUseLeg; + int ypUseLeg; + + bool legStageTypeIndex(gdioutput &gdi, EPostType type, int leg); + + public: ListEditor(oEvent *oe); virtual ~ListEditor(); diff --git a/code/liveresult.cpp b/code/liveresult.cpp index f77d8d3..33233e2 100644 --- a/code/liveresult.cpp +++ b/code/liveresult.cpp @@ -1,6 +1,6 @@ /********************i**************************************************** MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/liveresult.h b/code/liveresult.h index dc88b07..6014ded 100644 --- a/code/liveresult.h +++ b/code/liveresult.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/localizer.cpp b/code/localizer.cpp index d86c6e4..7e6777c 100644 --- a/code/localizer.cpp +++ b/code/localizer.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/localizer.h b/code/localizer.h index 85aab30..5a81880 100644 --- a/code/localizer.h +++ b/code/localizer.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/machinecontainer.cpp b/code/machinecontainer.cpp new file mode 100644 index 0000000..de1802a --- /dev/null +++ b/code/machinecontainer.cpp @@ -0,0 +1,202 @@ +#include "StdAfx.h" + +#include "machinecontainer.h" +#include "meos_util.h" +#include "xmlparser.h" +#include "gdioutput.h" +int MachineContainer::AbstractMachine::getInt(const string &v) const { + return _wtoi(getString(v).c_str()); +} + +const wstring &MachineContainer::AbstractMachine::getString(const string &v) const { + auto res = props.find(v); + if (res != props.end()) + return res->second; + return _EmptyWString; +} + +vector MachineContainer::AbstractMachine::getVectorInt(const string &v) const { + auto &s = getString(v); + vector sp; + split(s, L",", sp); + vector res(sp.size()); + for (int j = 0; j < sp.size(); j++) + res[j] = _wtoi(sp[j].c_str()); + return res; +} + +set MachineContainer::AbstractMachine::getSetInt(const string &v) const { + std::set res; + for (int i : getVectorInt(v)) { + res.insert(i); + } + return res; +} + +void MachineContainer::AbstractMachine::set(const string &name, int v) { + if (v != 0) + props[name] = itow(v); +} + +void MachineContainer::AbstractMachine::set(const string &name, const vector &v) { + wstring &r = props[name]; + for (int j = 0; j < v.size(); j++) { + if (j == 0) + r = itow(v[j]); + else + r += L"," + itow(v[j]); + } +} + +void MachineContainer::AbstractMachine::load(const xmlobject &data) { + xmlList out; + data.getObjects(out); + for (auto &x : out) { + props[x.getName()] = x.getw(); + } +} + +void MachineContainer::AbstractMachine::save(xmlparser &data) const { + for (auto &p : props) { + data.write(p.first.c_str(), p.second); + } +} + +namespace { + string encode(const string &in) { + string out; + out.reserve(in.length()); + for (int j = 0; j < in.length(); j++) { + if (in[j] == '|' || in[j] == '$' || in[j] == '%') { + out.push_back('%'); + if (in[j] == '|') + out.push_back('1'); + else if (in[j] == '$') + out.push_back('2'); + else if (in[j] == '%') + out.push_back('3'); + } + else + out.push_back(in[j]); + } + return out; + } + + string decode(const string &in) { + string out; + out.reserve(in.length()); + for (int j = 0; j < in.length(); j++) { + if (in[j] == '%') { + j++; + if (j < in.length()) { + if (in[j] == '1') + out.push_back('|'); + else if (in[j] == '2') + out.push_back('§'); + else if (in[j] == '3') + out.push_back('%'); + } + } + else + out.push_back(in[j]); + } + return out; + } +} + +void MachineContainer::AbstractMachine::load(const string &data) { + vector parts; + split(data, "|", parts); + for (int j = 0; j < parts.size(); j+=2) { + const wstring &w = gdioutput::fromUTF8(decode(parts[j + 1])); + props[parts[j]] = w; + } +} + +string MachineContainer::AbstractMachine::save() const { + string out; + for (auto &p : props) { + if (!out.empty()) + out += "|"; + out.append(p.first); + out += "|"; + out.append(encode(gdioutput::toUTF8(p.second))); + } + return out; +} + +void MachineContainer::AbstractMachine::set(const string &name, const wstring &v) { + if (!v.empty()) + props[name] = v; +} + +vector> MachineContainer::enumerate() const { + vector> res; + for (auto v : machines) + res.push_back(v.first); + + return res; +} + +void MachineContainer::load(const xmlobject &data) { + xmlList out; + data.getObjects("Machine", out); + + for (auto &m : out) { + string type; + wstring tag; + m.getObjectString("type", type); + m.getObjectString("name", tag); + if (!type.empty() && !tag.empty()) { + auto res = machines.emplace(make_pair(type, tag), MachineContainer::AbstractMachine()); + if (res.second) + res.first->second.load(m); + } + } +} + +void MachineContainer::save(xmlparser &data) { + for (auto &m : machines) { + vector p({ wstring(L"type"), gdioutput::widen(m.first.first), + wstring(L"name"), m.first.second }); + data.startTag("Machine", p); + m.second.save(data); + data.endTag(); + } +} + +void MachineContainer::load(const string &data) { + vector parts; + split(data, "$", parts); + for (int j = 0; j + 2 < parts.size(); j++) { + const string &type = parts[j]; + wstring tag = gdioutput::fromUTF8(decode(parts[j + 1])); + auto res = machines.emplace(make_pair(type, tag), MachineContainer::AbstractMachine()); + if (res.second) + res.first->second.load(parts[j+2]); + } +} + +string MachineContainer::save() { + vector ml; + ml.reserve(machines.size() * 3); + size_t tSize = 0; + for (auto &m : machines) { + ml.push_back(m.first.first); + tSize += ml.back().length() + 2; + ml.push_back(encode(gdioutput::toUTF8(m.first.second))); + tSize += ml.back().length() + 2; + ml.push_back(m.second.save()); + tSize += ml.back().length() + 2; + } + + string out; + out.reserve(tSize); + + for (const string & m : ml) { + if (!out.empty()) + out.append("$"); + out.append(m); + } + return out; +} diff --git a/code/machinecontainer.h b/code/machinecontainer.h new file mode 100644 index 0000000..d571f47 --- /dev/null +++ b/code/machinecontainer.h @@ -0,0 +1,79 @@ +#pragma once + +#include +#include +#include +#include + +class xmlparser; +class xmlobject; +using namespace std; + +class MachineContainer { + +public: + + class AbstractMachine { + map props; + public: + void clear() { + props.clear(); + } + + int getInt(const string &v) const; + const wstring &getString(const string &v) const; + vector getVectorInt(const string &v) const; + set getSetInt(const string &v) const; + + void set(const string &name, int v); + void set(const string &name, const vector &v); + void set(const string &name, const wstring &v); + void set(const string &name, bool v) { + set(name, int(v)); + } + + template + void set(const string &name, const T &v) { + vector vv; + for (auto x : v) + vv.push_back(x); + set(name, vv); + } + + protected: + void load(const xmlobject &data); + void load(const string &data); + void save(xmlparser &data) const; + string save() const; + friend class MachineContainer; + }; + +private: + map, AbstractMachine> machines; + +public: + const AbstractMachine *get(const string &type, const wstring &name) const { + auto res = machines.find(make_pair(type, name)); + if (res != machines.end()) + return &res->second; + + return nullptr; + } + + void erase(const string &type, const wstring &name) { + machines.erase(make_pair(type, name)); + } + + AbstractMachine &set(const string &type, const wstring &name) { + auto &m = machines[make_pair(type, name)]; + m.clear(); + return m; + } + + vector> enumerate() const; + + void load(const xmlobject &data); + void save(xmlparser &data); + void load(const string &data); + string save(); +}; diff --git a/code/meos.cpp b/code/meos.cpp index 7f1e31c..d6a99c1 100644 --- a/code/meos.cpp +++ b/code/meos.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -198,7 +198,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable - + atexit(dumpLeaks); // _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); @@ -294,7 +294,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, return 0; } - if (fileExist(settings)) { + if (fileExists(settings)) { gEvent->loadProperties(settings); } else { @@ -314,13 +314,13 @@ int APIENTRY WinMain(HINSTANCE hInstance, lang.get().addLangResource(L"Español", L"111"); lang.get().addLangResource(L"Russian", L"107"); - if (fileExist(L"extra.lng")) { + if (fileExists(L"extra.lng")) { lang.get().addLangResource(L"ExtrasprÃ¥k", L"extra.lng"); } else { wchar_t lpath[260]; getUserFile(lpath, L"extra.lng"); - if (fileExist(lpath)) + if (fileExists(lpath)) lang.get().addLangResource(L"ExtrasprÃ¥k", lpath); } @@ -479,7 +479,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, // Main message loop: mainMessageLoop(hAccelTable, 0); - tabAutoRegister(0); + TabAuto::tabAutoRegister(nullptr); tabList->clear(); delete tabList; tabList = nullptr; @@ -730,6 +730,14 @@ LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) gdi->keyCommand(KC_FINDBACK); } } + else if (wParam == 'A' && ctrlPressed) { + if (gdi) + gdi->keyCommand(KC_MARKALL); + } + else if (wParam == 'D' && ctrlPressed) { + if (gdi) + gdi->keyCommand(KC_CLEARALL); + } else if (wParam == VK_DELETE) { if (gdi) gdi->keyCommand(KC_DELETE); @@ -1072,6 +1080,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; + static bool connectionAlert = false; switch (message) { @@ -1084,7 +1093,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { TabAuto *ta = (TabAuto *)gdi_main->getTabs().get(TAutoTab); tabList->push_back(TabObject(ta, "Automater")); - tabAutoRegister(ta); + TabAuto::tabAutoRegister(ta); } tabList->push_back(TabObject(gdi_main->getTabs().get(TSpeakerTab), "Speaker")); tabList->push_back(TabObject(gdi_main->getTabs().get(TClassTab), "Klasser")); @@ -1248,9 +1257,20 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_USER + 5: if (gdi_main) gdi_main->addInfoBox("ainfo", L"info:advanceinfo", 10000); - break; - + + case WM_USER + 6: + if (gdi_main && lParam) { + gdioutput* g = (gdioutput*)lParam; + wstring msg = g->getDelayedAlert(); + if (!connectionAlert) { + connectionAlert = true; + gdi_main->alert(msg); + connectionAlert = false; + } + } + break; + case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); diff --git a/code/meos.rc b/code/meos.rc index 213e8f3..d1a9dfc 100644 --- a/code/meos.rc +++ b/code/meos.rc @@ -149,8 +149,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,1,0,1 - PRODUCTVERSION 3,1,0,1 + FILEVERSION 3,8,0,1 + PRODUCTVERSION 3,8,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -167,12 +167,12 @@ BEGIN BEGIN VALUE "CompanyName", "Melin Software HB" VALUE "FileDescription", "meos" - VALUE "FileVersion", "3.7.0.1" + VALUE "FileVersion", "3.8.0.1" VALUE "InternalName", "meos" - VALUE "LegalCopyright", "Copyright © 2007-2020" + VALUE "LegalCopyright", "Copyright © 2007-2021" VALUE "OriginalFilename", "meos.exe" VALUE "ProductName", " meos" - VALUE "ProductVersion", "3.7.0.1" + VALUE "ProductVersion", "3.8.0.1" END END BLOCK "VarFileInfo" diff --git a/code/meos_util.cpp b/code/meos_util.cpp index c0e31fd..5c90713 100644 --- a/code/meos_util.cpp +++ b/code/meos_util.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -882,9 +882,9 @@ wstring trim(const wstring &s) { else return L""; } -bool fileExist(const wchar_t *file) +bool fileExists(const wstring &file) { - return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES; + return GetFileAttributes(file.c_str()) != INVALID_FILE_ATTRIBUTES; } bool stringMatch(const wstring &a, const wstring &b) { diff --git a/code/meos_util.h b/code/meos_util.h index c7c133b..1a3d025 100644 --- a/code/meos_util.h +++ b/code/meos_util.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -158,7 +158,7 @@ int countWords(const wchar_t *p); wstring trim(const wstring &s); string trim(const string &s); -bool fileExist(const wchar_t *file); +bool fileExists(const wstring &file); bool stringMatch(const wstring &a, const wstring &b); diff --git a/code/meosexception.h b/code/meosexception.h index 228f93e..6f6a379 100644 --- a/code/meosexception.h +++ b/code/meosexception.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/meoslang.rc b/code/meoslang.rc index 08f30e0..64857a4 100644 --- a/code/meoslang.rc +++ b/code/meoslang.rc @@ -7,6 +7,10 @@ #define IDR_3007 109 #define IDR_3008 110 #define IDR_3011 111 +#define SND_OK 50 +#define SND_LEADER 51 +#define SND_NOTOK 52 +#define SND_NEEDACTION 53 IDR_3001 300 DISCARDABLE "swedish.lng" IDR_3002 300 DISCARDABLE "english.lng" @@ -18,3 +22,7 @@ IDR_3008 300 DISCARDABLE "french.lng" IDR_3011 300 DISCARDABLE "spanish.lng" ///////////////////////////////////////////////////////////////////////////// +SND_OK WAVE DISCARDABLE "./sound/ok.wav" +SND_LEADER WAVE DISCARDABLE "./sound/leader.wav" +SND_NOTOK WAVE DISCARDABLE "./sound/notok.wav" +SND_NEEDACTION WAVE DISCARDABLE "./sound/needaction.wav" diff --git a/code/meosvc15.vcxproj b/code/meosvc15.vcxproj index a1b7aea..744b86f 100644 --- a/code/meosvc15.vcxproj +++ b/code/meosvc15.vcxproj @@ -489,6 +489,7 @@ + %(PreprocessorDefinitions) %(PreprocessorDefinitions) @@ -683,6 +684,7 @@ + diff --git a/code/meosversion.cpp b/code/meosversion.cpp index 42f26a8..bd8e649 100644 --- a/code/meosversion.cpp +++ b/code/meosversion.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,17 +25,17 @@ //ABCDEFGHIJKLMNO int getMeosBuild() { - string revision("$Rev: 1081 $"); + string revision("$Rev: 1103 $"); return 174 + atoi(revision.substr(5, string::npos).c_str()); } wstring getMeosDate() { - wstring date(L"$Date: 2021-07-12 17:51:51 +0200 (mÃ¥n, 12 jul 2021) $"); + wstring date(L"$Date: 2021-12-11 15:54:57 +0100 (lör, 11 dec 2021) $"); return date.substr(7,10); } wstring getBuildType() { - return L"Beta"; // No parantheses (...) + return L"Beta II"; // No parantheses (...) } wstring getMajorVersion() { @@ -90,7 +90,6 @@ void getSupporters(vector &supp, vector &developSupp) supp.emplace_back(L"OK Tjärnen"); supp.emplace_back(L"Leksands OK"); supp.emplace_back(L"O-Travel"); - supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice"); developSupp.emplace_back(L"KOB Kysak"); supp.emplace_back(L"Ingemar Carlsson"); supp.emplace_back(L"Tolereds AIK"); @@ -149,6 +148,20 @@ void getSupporters(vector &supp, vector &developSupp) supp.emplace_back(L"IFK Kiruna"); supp.emplace_back(L"Smedjebackens OK"); supp.emplace_back(L"Gunnar Persson, Svanesunds GIF"); + supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice"); + supp.emplace_back(L"Køge Orienteringsklub"); + supp.emplace_back(L"Simrishamns OK"); + supp.emplace_back(L"OK Fryksdalen"); + supp.emplace_back(L"Magnus Asplund, Sundbybergs IK"); + supp.emplace_back(L"Frölunda OL"); + supp.emplace_back(L"Hjobygdens OK"); + supp.emplace_back(L"OK Malmia"); + supp.emplace_back(L"Säterbygdens OK"); + supp.emplace_back(L"OK Orinto"); + supp.emplace_back(L"Trosabygdens OK"); + supp.emplace_back(L"Järla Orientering"); + supp.emplace_back(L"Hans Wilhelmsson, Säffle OK"); + supp.emplace_back(L"Cent Vallées Orientation 12 (C.V.O. 12)"); reverse(supp.begin(), supp.end()); } diff --git a/code/metalist.cpp b/code/metalist.cpp index 71b1bb8..fcc1535 100644 --- a/code/metalist.cpp +++ b/code/metalist.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -485,17 +485,25 @@ void MetaList::initUniqueIndex() const { uniqueIndex = "A" + itos(ix) + "B" + itos(yx); } -bool MetaList::isBreak(int x) const { +bool MetaList::isBreak(int x) { return isspace(x) || x == '.' || x == ',' || x == '-' || x == ':' || x == ';' || x == '(' || x == ')' || x=='/' || (x>30 && x < 127 && !isalnum(x)); } -wstring MetaList::encode(const wstring &input_) const { +wstring MetaList::encode(EPostType type, const wstring &inputS, bool &foundSymbol) { + if (inputS.empty()) { + foundSymbol = true; // No symbol needed + return inputS; + } wstring out; - wstring input = lang.tl(input_); + wstring input = lang.tl(inputS); + out.reserve(input.length() + 5); - + int sCount = 0; + if (type == EPostType::lString) + sCount = 1; // No symbols expected in string + for (size_t k = 0; k 0 ? input[k-1] : ' '; @@ -505,20 +513,22 @@ wstring MetaList::encode(const wstring &input_) const { out.push_back('%'); out.push_back('%'); } - else if (c == 'X' && isBreak(n) && isBreak(p) ) { + else if (c == 'X' && isBreak(n) && isBreak(p) && sCount == 0) { out.push_back('%'); out.push_back('s'); + sCount++; } else out.push_back(c); } + + foundSymbol = sCount > 0; return out; } MetaListPost &MetaList::add(ListIndex ix, const MetaListPost &post) { if (data[ix].empty()) addRow(ix); - // data[ix].resize(1); vector &d = data[ix].back(); d.push_back(post); @@ -636,9 +646,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par } auto isAllStageType = [](const MetaListPost &mp) { - return ((mp.type == lRunnerStagePlace || mp.type == lRunnerStageStatus - || mp.type == lRunnerStageTime || mp.type == lRunnerStageTimeStatus || - mp.type == lRunnerStagePoints || mp.type == lRunnerStageNumber) && mp.leg == -1); + return MetaList::isAllStageType(mp.type) && mp.leg == -1; }; for (size_t j = 0; j > typeFormats; - typeFormats.push_back(make_pair(mp.type, encode(mp.text))); + bool dmy; + vector> typeFormats; + typeFormats.push_back(make_pair(mp.type, encode(mp.type, mp.text, dmy))); size_t kk = k+1; //Add merged entities while (kk < cline.size() && cline[kk].mergeWithPrevious) { - typeFormats.push_back(make_pair(cline[kk].type, encode(cline[kk].text))); + typeFormats.push_back(make_pair(cline[kk].type, encode(cline[kk].type, cline[kk].text, dmy))); kk++; } @@ -838,7 +847,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par continue; string label = "P" + itos(0*1000 + j*100 + k); - wstring text = makeDash(encode(cline[k].text)); + bool dmy; + wstring text = makeDash(encode(cline[k].type, cline[k].text, dmy)); if (capitalizeTitle) capitalizeWords(text); @@ -899,8 +909,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par gdiFonts font = header; if (mp.font != formatIgnore) font = mp.font; - - wstring text = encode(mp.text); + bool dmy; + wstring text = encode(mp.type, mp.text, dmy); if (capitalizeTitle) capitalizeWords(text); @@ -949,7 +959,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par font = mp.font; next_dy = max(next_dy, fontHeight[make_pair(font, MLList)]); - oPrintPost &added = li.addListPost(oPrintPost(mp.type, encode(mp.text), font|mp.textAdjust, + bool dmy; + oPrintPost &added = li.addListPost(oPrintPost(mp.type, encode(mp.type, mp.text, dmy), font|mp.textAdjust, pos.get(label, s_factor), dy + list_dy, cline[k].leg == -1 ? parLegNumber : make_pair(cline[k].leg, true))). setFontFace(fontFaces[MLList].font, @@ -1000,7 +1011,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par xp = pos.get(label, s_factor); next_dy = max(next_dy, fontHeight[make_pair(font, MLSubList)]); - oPrintPost &added = li.addSubListPost(oPrintPost(mp.type, encode(mp.text), font|mp.textAdjust, + bool dmy; + oPrintPost &added = li.addSubListPost(oPrintPost(mp.type, encode(mp.type, mp.text, dmy), font|mp.textAdjust, xp, dy+sublist_dy, mp.leg == -1 ? parLegNumber : make_pair(mp.leg, true))). setFontFace(fontFaces[MLSubList].font, fontFaces[MLSubList].scale); @@ -1979,7 +1991,8 @@ void MetaList::initSymbols() { typeToSymbol[lRunnerTimeAdjustment] = L"RunnerTimeAdjustment"; typeToSymbol[lRunnerPointAdjustment] = L"RunnerPointAdjustment"; typeToSymbol[lRunnerRogainingPointGross] = L"RunnerRogainingPointGross"; - + typeToSymbol[lRunnerCardVoltage] = L"RunnerCardVoltage"; + typeToSymbol[lRunnerStageTime] = L"RunnerStageTime"; typeToSymbol[lRunnerStageStatus] = L"RunnerStageStatus"; typeToSymbol[lRunnerStageTimeStatus] = L"RunnerStageTimeStatus"; diff --git a/code/metalist.h b/code/metalist.h index 4d38592..5251bdd 100644 --- a/code/metalist.h +++ b/code/metalist.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,7 +50,6 @@ class Position void update(int ix, const string &newname, int width, bool alignBlock, bool alignLock); public: - int getWidth() const; bool postAdjust(); @@ -207,9 +206,7 @@ private: enum ListIndex {MLHead = 0, MLSubHead = 1, MLList = 2, MLSubList=3}; MetaListPost &add(ListIndex ix, const MetaListPost &post); void addRow(int ix); - wstring encode(const wstring &input) const; - bool isBreak(int x) const; - + static map typeToSymbol; static map symbolToType; @@ -237,15 +234,28 @@ private: int getResultModuleIndex(oEvent *oe, oListInfo &li, const MetaListPost &lp) const; mutable map resultToIndex; + static bool isBreak(int x); + public: + static wstring encode(EPostType type, const wstring &input, bool &foundSymbol); + static void getAutoComplete(const wstring &w, vector &records); MetaList(); virtual ~MetaList() {} - bool supportClasses() const; + static constexpr bool isAllStageType(EPostType type) { + return type == lRunnerStagePlace || type == lRunnerStageStatus || + type == lRunnerStageTime || type == lRunnerStageTimeStatus || + type == lRunnerStagePoints || type == lRunnerStageNumber; + } + static constexpr bool isResultModuleOutput(EPostType type) { + return type == lResultModuleNumber || type == lResultModuleTime || + type == lResultModuleTimeTeam || type == lResultModuleNumberTeam; + } + bool supportClasses() const; const wstring &getListInfo(const oEvent &oe) const; void clearTag() {tag.clear();} diff --git a/code/methodeditor.cpp b/code/methodeditor.cpp index de45538..c613114 100644 --- a/code/methodeditor.cpp +++ b/code/methodeditor.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -971,7 +971,7 @@ bool MethodEditor::resultIsInstalled() const { return false; // Used in a list in this competition //string path = getInternalPath(currentResult->getTag()); - return fileExist(fileNameSource.c_str()); + return fileExists(fileNameSource); } void MethodEditor::debug(gdioutput &gdi_in, int id, bool isTeam) { diff --git a/code/methodeditor.h b/code/methodeditor.h index 0a03029..8d46a3e 100644 --- a/code/methodeditor.h +++ b/code/methodeditor.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/mysqldaemon.cpp b/code/mysqldaemon.cpp index cfbadac..95ac271 100644 --- a/code/mysqldaemon.cpp +++ b/code/mysqldaemon.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -86,7 +86,7 @@ unsigned __stdcall reconnectThread(void *v) { return 0; } -void MySQLReconnect::settings(gdioutput &gdi, oEvent &oe, bool created) { +void MySQLReconnect::settings(gdioutput &gdi, oEvent &oe, State state) { } void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) @@ -111,6 +111,7 @@ void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) gdi.setDBErrorState(false); gdi.setWindowTitle(oe->getTitleName()); interval=0; + toRemove = true; } } else if (mysqlStatus==-1) { @@ -138,9 +139,7 @@ void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) int AutomaticCB(gdioutput *gdi, int type, void *data); void MySQLReconnect::status(gdioutput &gdi) { - gdi.dropLine(0.5); - gdi.addString("", 1, name); - gdi.pushX(); + AutoMachine::status(gdi); if (interval>0){ gdi.addStringUT(1, timeError + L": " + lang.tl("DATABASE ERROR")).setColor(colorDarkRed); gdi.fillRight(); diff --git a/code/newcompetition.cpp b/code/newcompetition.cpp index e9fb75d..6f7e68f 100644 --- a/code/newcompetition.cpp +++ b/code/newcompetition.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oBase.cpp b/code/oBase.cpp index a0888d0..580586a 100644 --- a/code/oBase.cpp +++ b/code/oBase.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -278,3 +278,17 @@ void oBase::update(SqlUpdated &info) const { info.updated = max(sqlUpdated, info.updated); info.counter = max(counter, info.counter); } + +void oBase::clearDuplicateBase(int newId) { + Id = newId; + Modified.update(); + sqlUpdated = ""; //SQL TIMESTAMP + myReference.reset(); + counter = 0; + Removed = false; + implicitlyAdded = false; + addedToEvent = false; + changed = true; + transientChanged = false; + localObject = false; +} diff --git a/code/oBase.h b/code/oBase.h index 95c7ec9..0725069 100644 --- a/code/oBase.h +++ b/code/oBase.h @@ -1,17 +1,11 @@ // oBase.h: interface for the oBase class. // ////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OBASE_H__C950D806_EEC7_4C56_B298_132C67FCF719__INCLUDED_) -#define AFX_OBASE_H__C950D806_EEC7_4C56_B298_132C67FCF719__INCLUDED_ - -#if _MSC_VER > 1000 #pragma once -#endif // _MSC_VER > 1000 /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -98,10 +92,6 @@ private: bool localObject; protected: - - /// Mark the object as changed (on client) and that it needs synchronize to server - void updateChanged(ChangeType ct = ChangeType::Update); - /// Mark the object as "changed" (locally or remotely), eg lists and other views may need update virtual void changedObject() = 0; @@ -117,8 +107,13 @@ protected: // Merge into this entity virtual void merge(const oBase &input, const oBase *base) = 0; + void clearDuplicateBase(int newId); + public: + /// Mark the object as changed (on client) and that it needs synchronize to server + void updateChanged(ChangeType ct = ChangeType::Update); + void update(SqlUpdated &info) const; // Get a safe reference to this object @@ -208,5 +203,3 @@ public: }; typedef oBase * pBase; - -#endif // !defined(AFX_OBASE_H__C950D806_EEC7_4C56_B298_132C67FCF719__INCLUDED_) diff --git a/code/oCard.cpp b/code/oCard.cpp index c6c0cdf..69f12ac 100644 --- a/code/oCard.cpp +++ b/code/oCard.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -798,7 +798,12 @@ wstring oCard::getCardVoltage() const { return bf; } -bool oCard::isCriticalCardVoltage() const { - return miliVolt > 0 && miliVolt < 2445; +oCard::BatteryStatus oCard::isCriticalCardVoltage() const { + if (miliVolt > 0 && miliVolt < 2445) + return BatteryStatus::Bad; + else if (miliVolt > 0 && miliVolt <= 2710) + return BatteryStatus::Warning; + + return BatteryStatus::OK; } diff --git a/code/oCard.h b/code/oCard.h index da3619d..9058061 100644 --- a/code/oCard.h +++ b/code/oCard.h @@ -11,7 +11,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -75,7 +75,12 @@ public: void setMeasuredVoltage(int miliVolt) { this->miliVolt = miliVolt; } wstring getCardVoltage() const; - bool isCriticalCardVoltage() const; + enum class BatteryStatus { + OK, + Warning, + Bad + }; + BatteryStatus isCriticalCardVoltage() const; static const shared_ptr &getTable(oEvent *oe); diff --git a/code/oClass.cpp b/code/oClass.cpp index 4842dbe..97c5766 100644 --- a/code/oClass.cpp +++ b/code/oClass.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -93,6 +93,13 @@ oClass::oClass(oEvent *poe, int id): oBase(poe) parentClass = 0; } +void oClass::clearDuplicate() { + int id = oe->getFreeClassId(); + clearDuplicateBase(id); + oe->qFreeClassId = max(id % MaxClassId, oe->qFreeClassId); + getDI().setInt("SortIndex", tSortIndex); +} + oClass::~oClass() { if (tLegTimeToPlace) @@ -1715,8 +1722,12 @@ int oClass::getNumDistinctRunnersMinimal() const } void oClass::resetLeaderTime() const { - for (size_t k = 0; k= tLeaderTime.size()) tLeaderTime.resize(leg + 1); @@ -1919,6 +1934,7 @@ void oClass::updateLeaderTimes() const { else if (r->tLeg > leg) needupdate = true; } + tLeaderTime[leg].setComplete(); leg++; } leaderTimeVersion = oe->dataRevision; @@ -1957,8 +1973,10 @@ int oClass::LeaderInfo::getLeader(Type t, bool computed) const { case Type::TotalInput: if (computed && totalLeaderTimeInputComputed > 0) return totalLeaderTimeInputComputed; - else + else if (totalLeaderTimeInput > 0) return totalLeaderTimeInput; + else + return inputTime; } return 0; @@ -2009,6 +2027,10 @@ int oClass::getTotalLegLeaderTime(AllowRecompute recompute, int leg, bool comput int res = -1; int iter = -1; + bool mayUseOld = recompute == AllowRecompute::NoUseOld; + if (mayUseOld) + recompute = AllowRecompute::No; + while (res == -1 && ++iter<2) { if (includeInput) res = getLeaderInfo(recompute, leg).getLeader(LeaderInfo::Type::TotalInput, computedTime); @@ -2019,6 +2041,8 @@ int oClass::getTotalLegLeaderTime(AllowRecompute recompute, int leg, bool comput recompute = AllowRecompute::No; updateLeaderTimes(); } + else if (res == -1 && mayUseOld) + recompute = AllowRecompute::NoUseOld; } return res; } diff --git a/code/oClass.h b/code/oClass.h index 7b92fa3..bdb0ba7 100644 --- a/code/oClass.h +++ b/code/oClass.h @@ -1,17 +1,7 @@ -// oClass.h: interface for the oClass class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OCLASS_H__63E948E3_3C06_4404_8E72_2185582FF30F__INCLUDED_) -#define AFX_OCLASS_H__63E948E3_3C06_4404_8E72_2185582FF30F__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - +#pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -154,7 +144,7 @@ class oClass : public oBase { public: enum class ClassStatus {Normal, Invalid, InvalidRefund}; - enum class AllowRecompute {Yes, No }; + enum class AllowRecompute {Yes, No, NoUseOld }; static void getSplitMethods(vector< pair > &methods); static void getSeedingMethods(vector< pair > &methods); @@ -180,6 +170,8 @@ protected: int totalLeaderTimeInputComputed; //Team total including input int inputTime; + + bool complete = false; public: LeaderInfo() { reset(); @@ -195,6 +187,26 @@ protected: inputTime = -1; totalLeaderTimeInput = -1; totalLeaderTimeInputComputed = -1; + complete = false; + } + + void updateFrom(const LeaderInfo& i) { + if (i.complete) { + if (i.bestTimeOnLeg != -1) + bestTimeOnLeg = i.bestTimeOnLeg; + if (i.bestTimeOnLegComputed != -1) + bestTimeOnLegComputed = i.bestTimeOnLegComputed; + if (i.totalLeaderTime != -1) + totalLeaderTime = i.totalLeaderTime; + if (i.totalLeaderTimeComputed != -1) + totalLeaderTimeComputed = i.totalLeaderTimeComputed; + if (i.inputTime != -1) + inputTime = i.inputTime; + if (i.totalLeaderTimeInput != -1) + totalLeaderTimeInput = i.totalLeaderTimeInput; + if (i.totalLeaderTimeInputComputed != -1) + totalLeaderTimeInputComputed = i.totalLeaderTimeInputComputed; + } } enum class Type { @@ -208,11 +220,17 @@ protected: return inputTime; } - void resetComputed(Type t); - + void resetComputed(Type t); bool update(int rt, Type t); bool updateComputed(int rt, Type t); int getLeader(Type t, bool computed) const; + + void setComplete() { + complete = true; + } + + // For non-team classes, input is the same as total input and computed total input + void copyInputToTotalInput(); }; void updateLeaderTimes() const; @@ -221,6 +239,7 @@ protected: mutable int leaderTimeVersion = -1; mutable vector tLeaderTime; + mutable vector tLeaderTimeOld; mutable map tBestTimePerCourse; int tSplitRevision; @@ -712,6 +731,7 @@ public: oClass(oEvent *poe); oClass(oEvent *poe, int id); virtual ~oClass(); + void clearDuplicate(); friend class oAbstractRunner; friend class oEvent; @@ -724,5 +744,3 @@ public: static const oClass::DrawSpecified DrawKeys[4] = { oClass::DrawSpecified::FixedTime, oClass::DrawSpecified::Vacant, oClass::DrawSpecified::Extra }; - -#endif // !defined(AFX_OCLASS_H__63E948E3_3C06_4404_8E72_2185582FF30F__INCLUDED_) diff --git a/code/oClub.cpp b/code/oClub.cpp index def789a..0061314 100644 --- a/code/oClub.cpp +++ b/code/oClub.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oClub.h b/code/oClub.h index 719bae1..2ec5fb7 100644 --- a/code/oClub.h +++ b/code/oClub.h @@ -11,7 +11,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oControl.cpp b/code/oControl.cpp index 2546f5b..7d0dfd2 100644 --- a/code/oControl.cpp +++ b/code/oControl.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -369,30 +369,32 @@ const vector< pair > &oEvent::fillControls(vector< pairRemoved){ b.clear(); - if (type==oEvent::CTAll) { + if (type == oEvent::CTAll) { if (it->Status == oControl::StatusFinish || it->Status == oControl::StatusStart) { b += it->Name; } else { if (it->Status == oControl::StatusOK || it->Status == oControl::StatusNoTiming) b += L"[OK]\t"; - else if (it->Status==oControl::StatusMultiple) + else if (it->Status == oControl::StatusMultiple) b += L"[M]\t"; - else if (it->Status==oControl::StatusRogaining) + else if (it->Status == oControl::StatusRogaining) b += L"[R]\t"; - else if (it->Status==oControl::StatusBad) + else if (it->Status == oControl::StatusBad) b += makeDash(L"[-]\t"); - else if (it->Status==oControl::StatusOptional) - b += makeDash(L"[O]\t"); + else if (it->Status == oControl::StatusBadNoTiming) + b += L"[!]\t"; + else if (it->Status == oControl::StatusOptional) + b += L"[O]\t"; else b += L"[ ]\t"; swprintf_s(bf, L" %s", it->codeNumbers(' ').c_str()); - b+=bf; + b += bf; - if (it->Status==oControl::StatusRogaining) - b+=L"\t(" + itow(it->getRogainingPoints()) + L"p)"; - else if (it->Name.length()>0) { - b+=L"\t(" + it->Name + L")"; + if (it->Status == oControl::StatusRogaining) + b += L"\t(" + itow(it->getRogainingPoints()) + L"p)"; + else if (it->Name.length() > 0) { + b += L"\t(" + it->Name + L")"; } } out.push_back(make_pair(b, it->Id)); @@ -474,7 +476,7 @@ void oControl::setupCache() const { int oControl::getMinTime() const { - if (Status == StatusNoTiming) + if (Status == StatusNoTiming || Status == StatusBadNoTiming) return 0; setupCache(); return tCache.minTime; @@ -768,6 +770,8 @@ const wstring oControl::getStatusS() const { return lang.tl("MÃ¥l"); case StatusNoTiming: return lang.tl("Utan tidtagning"); + case StatusBadNoTiming: + return lang.tl("Försvunnen"); default: return lang.tl("Okänd"); } @@ -791,6 +795,7 @@ const vector< pair > &oEvent::fillControlStatus(vector< pairisRogaining(hasRogaining()) || Controls[k]->getStatus() == oControl::StatusBad || - Controls[k]->getStatus() == oControl::StatusOptional) + Controls[k]->getStatus() == oControl::StatusOptional || + Controls[k]->getStatus() == oControl::StatusBadNoTiming) continue; if (Controls[k]->getStatus() == oControl::StatusMultiple) { diff --git a/code/oCourse.h b/code/oCourse.h index cd6dc35..90d4c1d 100644 --- a/code/oCourse.h +++ b/code/oCourse.h @@ -11,7 +11,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oDataContainer.cpp b/code/oDataContainer.cpp index da59b66..4bd291a 100644 --- a/code/oDataContainer.cpp +++ b/code/oDataContainer.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oDataContainer.h b/code/oDataContainer.h index ea1a82d..d5fbb55 100644 --- a/code/oDataContainer.h +++ b/code/oDataContainer.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oEvent.cpp b/code/oEvent.cpp index d9cba11..63e331d 100644 --- a/code/oEvent.cpp +++ b/code/oEvent.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,10 +48,12 @@ #include "intkeymapimpl.hpp" #include "socket.h" +#include "machinecontainer.h" #include "MeOSFeatures.h" #include "generalresult.h" #include "oEventDraw.h" #include "MeosSQL.h" +#include "TabAuto.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -63,7 +65,7 @@ #include "Table.h" //Version of database -int oEvent::dbVersion = 86; +int oEvent::dbVersion = 87; class RelativeTimeFormatter : public oDataDefiner { string name; @@ -410,6 +412,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi) oEventData->addVariableString("PreEvent", 64, ""); oEventData->addVariableString("PostEvent", 64, ""); + oEventData->addVariableString("ImportStamp", 14, "Stamp"); // Positive number -> stage number, negative number -> no stage number. Zero = unknown oEventData->addVariableInt("EventNumber", oDataContainer::oIS8, ""); @@ -440,8 +443,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi) oEventData->addVariableString("StartGroups", "Startgrupper"); oEventData->addVariableString("MergeTag", 12, "Tag"); oEventData->addVariableString("MergeInfo", "MergeInfo"); - oEventData->addVariableString("ImportStamp", 14, "Stamp"); - + oEventData->initData(this, dataSize); oClubData=new oDataContainer(oClub::dataSize); @@ -654,7 +656,6 @@ void oEvent::initProperties() { getPropertyInt("UseEventorUTC", 0); getPropertyInt("UseHourFormat", 1); getPropertyInt("NameMode", FirstLast); - getPropertyInt("ReadVoltageExp", 0); } void oEvent::listProperties(bool userProps, vector< pair > &propNames) const { @@ -675,6 +676,7 @@ void oEvent::listProperties(bool userProps, vector< pair > filter.insert("Email"); filter.insert("TextSize"); filter.insert("PayModes"); + filter.insert("ReadVoltageExp"); } // Boolean and integer properties @@ -702,8 +704,7 @@ void oEvent::listProperties(bool userProps, vector< pair > b.insert("FirstTime"); b.insert("ExportCSVSplits"); b.insert("DrawInterlace"); - b.insert("ReadVoltageExp"); - + // Integers i.insert("YouthFee"); i.insert("YouthAge"); @@ -729,6 +730,8 @@ void oEvent::listProperties(bool userProps, vector< pair > propNames.clear(); for(map::const_iterator it = eventProperties.begin(); it != eventProperties.end(); ++it) { + if (it->first.size() > 1 && it->first[0] == '@') + continue; if (!filter.count(it->first)) { if (b.count(it->first)) { assert(!i.count(it->first)); @@ -1146,6 +1149,12 @@ bool oEvent::save(const wstring &fileIn) { listContainer->save(MetaListContainer::ExternalList, xml, this); xml.endTag(); + if (machineContainer) { + xml.startTag("Machines"); + machineContainer->save(xml); + xml.endTag(); + } + xml.closeOut(); pw.setProgress(p[i++]); updateRunnerDatabase(); @@ -1236,6 +1245,34 @@ static void toc(const string &str) { timer = t; } +namespace { + void getNewFileName(wstring &fn, wstring &nameId) { + SYSTEMTIME st; + GetLocalTime(&st); + + wchar_t file[260]; + wchar_t filename[64]; + swprintf_s(filename, 64, L"meos_%d%02d%02d_%02d%02d%02d_%X.meos", + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + + //strcpy_s(CurrentNameId, filename); + getUserFile(file, filename); + + wchar_t CurrentNameId[64]; + _wsplitpath_s(file, NULL, 0, NULL, 0, CurrentNameId, 64, NULL, 0); + int i = 0; + while (CurrentNameId[i]) { + if (CurrentNameId[i] == '.') { + CurrentNameId[i] = 0; + break; + } + i++; + } + + fn = file; + nameId = CurrentNameId; + } +} bool oEvent::open(const wstring &file, bool Import, bool forMerge) { if (!Import) @@ -1247,6 +1284,21 @@ bool oEvent::open(const wstring &file, bool Import, bool forMerge) { string log; xml.read(file); + string tag = xml.getObject(0).getName(); + wstring iof; + xml.getObject(0).getObjectString("iofVersion", iof); + if (tag == "EntryList" || tag == "StartList" || iof.length() > 0) + throw meosException(L"Filen (X) innehÃ¥ller IOF-XML tävlingsdata och kan importeras i en existerande tävling#" + file); + + if (tag == "MeOSListDefinition") + throw meosException(L"Filen (X) är en listdefinition#" + file); + + if (tag == "MeOSResultCalculationSet") + throw meosException(L"Filen (X) är en resultatmodul#" + file); + + if (tag != "meosdata") + throw meosException(L"Filen (X) är inte en MeOS-tävling#" + file); + xmlattrib ver = xml.getObject(0).getAttrib("version"); if (ver) { wstring vs = ver.wget(); @@ -1280,6 +1332,18 @@ bool oEvent::open(const wstring &file, bool Import, bool forMerge) { if (res && !Import) openFileLock->lockFile(file); + if (Import) { + for (auto &cmp : cinfo) { + if (cmp.NameId == currentNameId) { + if (!gdibase.ask(L"ask:importcopy#" + cmp.Name + L", " + cmp.Date)) { + wstring fn; + getNewFileName(fn, currentNameId); + } + break; + } + } + } + getMergeTag(Import && !forMerge); if (Import && !forMerge) { @@ -1540,8 +1604,26 @@ bool oEvent::open(const xmlparser &xml) { if (err.empty()) err = gdibase.widen(ex.what()); } + getMeOSFeatures().deserialize(getDCI().getString("Features"), *this); + + try { + xmlobject xMachine = xml.getObject("Machines"); + if (xMachine) { + getMachineContainer().load(xMachine); + } + } + catch (const meosException &ex) { + if (err.empty()) + err = ex.wwhat(); + } + catch (const std::exception &ex) { + if (err.empty()) + err = gdibase.widen(ex.what()); + } + + if (!err.empty()) throw meosException(err); @@ -1571,13 +1653,13 @@ bool oEvent::openRunnerDatabase(const wchar_t* filename) wcscat_s(fwrunner, L".wpersons"); try { - if ((fileExist(fwclub) || fileExist(fclub)) && (fileExist(frunner) || fileExist(fwrunner)) ) { - if (fileExist(fwclub)) + if ((fileExists(fwclub) || fileExists(fclub)) && (fileExists(frunner) || fileExists(fwrunner)) ) { + if (fileExists(fwclub)) runnerDB->loadClubs(fwclub); else runnerDB->loadClubs(fclub); - if (fileExist(fwrunner)) + if (fileExists(fwrunner)) runnerDB->loadRunners(fwrunner); else runnerDB->loadRunners(frunner); @@ -1706,7 +1788,7 @@ void oEvent::updateRunnerDatabase() wstring uid = gdibase.widen(ml.getUniqueId()) + L".meoslist"; wchar_t file[260]; getUserFile(file, uid.c_str()); - if (!fileExist(file)) { + if (!fileExists(file)) { ml.save(file, this); } } @@ -1717,7 +1799,7 @@ void oEvent::updateRunnerDatabase() wstring uid = gdibase.widen(freeMod[k].first) + L".rules"; wchar_t file[260]; getUserFile(file, uid.c_str()); - if (!fileExist(file)) { + if (!fileExists(file)) { freeMod[k].second->save(file); } } @@ -3396,7 +3478,7 @@ bool oEvent::enumerateCompetitions(const wchar_t *file, const wchar_t *filetype) xmlparser xp; try { - xp.read(FullPathFile, 8); + xp.read(FullPathFile, 30); const xmlobject date=xp.getObject("Date"); @@ -3419,6 +3501,20 @@ bool oEvent::enumerateCompetitions(const wchar_t *file, const wchar_t *filetype) if (nameid) ci.NameId = nameid.getw(); + auto oData = xp.getObject("oData"); + if (oData) { + auto preEvent = oData.getObject("PreEvent"); + if (preEvent) + ci.preEvent = preEvent.getw(); + + auto postEvent = oData.getObject("PostEvent"); + if (postEvent) + ci.postEvent = postEvent.getw(); + + auto importStamp = oData.getObject("ImportStamp"); + if (importStamp) + ci.importTimeStamp = importStamp.getw(); + } cinfo.push_front(ci); } catch (std::exception &) { @@ -3438,6 +3534,19 @@ bool oEvent::enumerateCompetitions(const wchar_t *file, const wchar_t *filetype) it->Name = lang.tl(it->Name.substr(1)); } +/* + vector> cc; + for (auto &c : cinfo) { + cc.emplace_back(c.NameId, c.Date + L": " + c.Name); + } + sort(cc.begin(), cc.end()); + for (auto &c : cc) { + OutputDebugString(c.first.c_str()); + OutputDebugString(L", "); + OutputDebugString(c.second.c_str()); + OutputDebugString(L"\n"); + } +*/ return true; } @@ -3635,10 +3744,32 @@ bool oEvent::fillCompetitions(gdioutput &gdi, cinfo.sort(); cinfo.reverse(); list::iterator it; + const CompetitionInfo *bestMatch = nullptr; + + auto accept = [this, &bestMatch](const CompetitionInfo &ci) { + if (bestMatch == nullptr) + bestMatch = &ci; + else { + bool matchPrevNextId = bestMatch->preEvent == currentNameId || bestMatch->postEvent == currentNameId; + bool ciMatchPrevNextId = ci.preEvent == currentNameId || ci.postEvent == currentNameId; + if (matchPrevNextId != ciMatchPrevNextId) { + if (ciMatchPrevNextId) + bestMatch = &ci; + } + else { + if (ci.Date > bestMatch->Date) { + bestMatch = &ci; + } + else { + if (ci.importTimeStamp > bestMatch->importTimeStamp) + bestMatch = &ci; + } + } + } + }; gdi.clearList(name); string b; - int idSel = -1; //char bf[128]; for (it=cinfo.begin(); it!=cinfo.end(); ++it) { wstring annotation; @@ -3647,14 +3778,14 @@ bool oEvent::fillCompetitions(gdioutput &gdi, if (it->Server.length()==0) { if (type==0 || type==1) { if (it->NameId == select && !select.empty()) - idSel = it->Id; + accept(*it); wstring bf = L"[" + it->Date + L"] " + it->Name; gdi.addItem(name, bf + annotation, it->Id); } } else if (type==0 || type==2) { if (it->NameId == select && !select.empty()) - idSel = it->Id; + accept(*it); wstring bf; if (type==0) bf = lang.tl(L"Server: [X] Y#" + it->Date + L"#" + it->Name); @@ -3665,13 +3796,12 @@ bool oEvent::fillCompetitions(gdioutput &gdi, } } - if (idSel != -1) - gdi.selectItemByData(name.c_str(), idSel); + if (bestMatch) + gdi.selectItemByData(name.c_str(), bestMatch->Id); + return true; } -void tabAutoKillMachines(); - void oEvent::checkDB() { if (hasDBConnection()) { @@ -3723,7 +3853,7 @@ void oEvent::clear() Annotation.clear(); //Make sure no daemon is hunting us. - tabAutoKillMachines(); + TabAuto::tabAutoKillMachines(); delete directSocket; directSocket = 0; @@ -3790,6 +3920,8 @@ void oEvent::clear() // Cleanup user interface gdibase.getTabs().clearCompetitionData(); + machineContainer.release(); + MeOSUtil::useHourFormat = getPropertyInt("UseHourFormat", 1) != 0; currentNameMode = (NameMode) getPropertyInt("NameMode", FirstLast); @@ -3824,7 +3956,6 @@ void oEvent::newCompetition(const wstring &name) openFileLock->unlockFile(); clear(); - SYSTEMTIME st; GetLocalTime(&st); @@ -3862,26 +3993,10 @@ void oEvent::newCompetition(const wstring &name) setCurrency(-1, L"", L"", 0); - wchar_t file[260]; - wchar_t filename[64]; - swprintf_s(filename, 64, L"meos_%d%02d%02d_%02d%02d%02d_%X.meos", - st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + wstring file; + getNewFileName(file, currentNameId); + wcscpy_s(CurrentFile, MAX_PATH, file.c_str()); - //strcpy_s(CurrentNameId, filename); - getUserFile(file, filename); - - wcscpy_s(CurrentFile, MAX_PATH, file); - wchar_t CurrentNameId[64]; - _wsplitpath_s(CurrentFile, NULL, 0, NULL,0, CurrentNameId, 64, NULL, 0); - int i=0; - while (CurrentNameId[i]) { - if (CurrentNameId[i]=='.') { - CurrentNameId[i]=0; - break; - } - i++; - } - currentNameId = CurrentNameId; oe->updateTabs(); } @@ -3970,6 +4085,13 @@ void oEvent::reEvaluateAll(const set &cls, bool doSync) leg++; } + // Mark info as complete + for (auto& c : Classes) { + if (!c.isRemoved() && (cls.empty() || cls.count(c.Id))) + for (auto &i : c.tLeaderTime) + i.setComplete(); + } + // Update team start times etc. for(oTeamList::iterator tit=Teams.begin();tit!=Teams.end();++tit) { if (!tit->isRemoved()) { @@ -4015,6 +4137,7 @@ void oEvent::reEvaluateChanged() it->resetLeaderTime(); it->reinitialize(true); resetClasses[it->getId()] = it->hasClassGlobalDependence(); + it->updateLeaderTimes(); } } @@ -4037,8 +4160,8 @@ void oEvent::reEvaluateChanged() if (it->isRemoved()) continue; int clz = it->getClassId(true); - if (resetClasses.count(clz)) - it->storeTimes(); + //if (resetClasses.count(clz)) + // it->storeTimes(); if (!it->wasSQLChanged() && !resetClasses[clz]) continue; @@ -4785,13 +4908,13 @@ const string &oEvent::getPropertyString(const char *name, const string &def) } } -wstring oEvent::getPropertyStringDecrypt(const char *name, const string &def) +string oEvent::getPropertyStringDecrypt(const char *name, const string &def) { wchar_t bf[MAX_COMPUTERNAME_LENGTH + 1]; DWORD len = MAX_COMPUTERNAME_LENGTH + 1; GetComputerName(bf, &len); string prop = getPropertyString(name, def); - wstring prop2; + string prop2; int code = 0; const int s = 337; @@ -6456,3 +6579,10 @@ StartGroupInfo oEvent::getStartGroup(int id) const { else return StartGroupInfo(L"", -1, -1); } + +MachineContainer &oEvent::getMachineContainer() { + if (!machineContainer) + machineContainer = make_unique(); + + return *machineContainer; +} diff --git a/code/oEvent.h b/code/oEvent.h index a317cd3..cd3dead 100644 --- a/code/oEvent.h +++ b/code/oEvent.h @@ -6,7 +6,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -70,6 +70,7 @@ struct SpeakerString; struct ClassDrawSpecification; class ImportFormats; class MeosSQL; +class MachineContainer; struct oCounter { int level1; @@ -149,6 +150,11 @@ struct CompetitionInfo { wstring Annotation; wstring Date; wstring NameId; + + wstring postEvent; + wstring preEvent; + wstring importTimeStamp; + wstring FullPath; string Server; string ServerUser; @@ -162,10 +168,12 @@ struct CompetitionInfo { int ServerPort; int numConnected; // Number of connected entities int backupId; // Used to identify backups - bool operator<(const CompetitionInfo &ci) - { + + bool operator<(const CompetitionInfo &ci) { if (Date != ci.Date) - return Date machineContainer; + public: enum class ResultType { @@ -701,7 +711,7 @@ public: const string &getPropertyString(const char *name, const string &def); const wstring &getPropertyString(const char *name, const wstring &def); - wstring getPropertyStringDecrypt(const char *name, const string &def); + string getPropertyStringDecrypt(const char *name, const string &def); void setProperty(const char *name, int prop); //void setProperty(const char *name, const string &prop); @@ -855,6 +865,8 @@ public: vector getHiredCards() const; void clearHiredCards(); + MachineContainer &getMachineContainer(); + protected: // Returns hash key for punch based on control id, and leg. Class is marked as changed if oldHashKey != newHashKey. int getControlIdFromPunch(int time, int type, int card, diff --git a/code/oEventDraw.cpp b/code/oEventDraw.cpp index 965d4e5..7d487c3 100644 --- a/code/oEventDraw.cpp +++ b/code/oEventDraw.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oEventDraw.h b/code/oEventDraw.h index f3016b9..e85b5e2 100644 --- a/code/oEventDraw.h +++ b/code/oEventDraw.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oEventResult.cpp b/code/oEventResult.cpp index c771d76..3976e58 100644 --- a/code/oEventResult.cpp +++ b/code/oEventResult.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oEventSQL.cpp b/code/oEventSQL.cpp index e3cb97c..050a86b 100644 --- a/code/oEventSQL.cpp +++ b/code/oEventSQL.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,7 +57,7 @@ bool oEvent::connectToServer() void oEvent::startReconnectDaemon() { - if (isThreadReconnecting()) + if (isThreadReconnecting() || TabAuto::hasActiveReconnectionMachine()) return; string err; @@ -66,13 +66,14 @@ void oEvent::startReconnectDaemon() MySQLReconnect msqlr(lang.tl("warning:dbproblem#" + err)); msqlr.interval=5; hasPendingDBConnection = true; - tabAutoAddMachinge(msqlr); + TabAuto::tabAutoAddMachinge(msqlr); gdibase.setDBErrorState(false); gdibase.setWindowTitle(oe->getTitleName()); + isConnectedToServer = false; if (!isReadOnly()) { // Do not show in kiosk-mode - gdibase.alert("warning:dbproblem#" + err); + gdibase.delayAlert(L"warning:dbproblem#" + gdibase.widen(err)); } } @@ -243,7 +244,7 @@ void oEvent::resetSQLChanged(bool resetAllTeamsRunners, bool cleanClasses) { it->sqlChangedLegControl.clear(); } globalModification = false; - } + } } bool BaseIsRemoved(const oBase &ob){return ob.isRemoved();} diff --git a/code/oEventSpeaker.cpp b/code/oEventSpeaker.cpp index 578a113..71d6c86 100644 --- a/code/oEventSpeaker.cpp +++ b/code/oEventSpeaker.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oFreeImport.cpp b/code/oFreeImport.cpp index 6949bcb..ccaf83d 100644 --- a/code/oFreeImport.cpp +++ b/code/oFreeImport.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oFreeImport.h b/code/oFreeImport.h index e768c98..da9cc33 100644 --- a/code/oFreeImport.h +++ b/code/oFreeImport.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oFreePunch.cpp b/code/oFreePunch.cpp index bc9da97..ba00f27 100644 --- a/code/oFreePunch.cpp +++ b/code/oFreePunch.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oFreePunch.h b/code/oFreePunch.h index a60fc59..6b94ade 100644 --- a/code/oFreePunch.h +++ b/code/oFreePunch.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oImportExport.cpp b/code/oImportExport.cpp index c627413..5fd2444 100644 --- a/code/oImportExport.cpp +++ b/code/oImportExport.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -432,6 +432,25 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file, gdi.refreshFast(); } + xo = xml.getObject("ResultList"); + + if (xo) { + + int ent = 0, fail = 0; + if (xo.getAttrib("iofVersion")) { + gdi.addString("", 0, "Importerar resultat (IOF, xml)"); + gdi.refreshFast(); + IOF30Interface reader(this, false); + reader.readResultList(gdi, xo, ent, fail); + } + gdi.addString("", 0, "Klart. Antal importerade: X#" + itos(ent)); + if (fail>0) + gdi.addString("", 0, "Antal som inte importerades: X#" + itos(fail)).setColor(colorRed); + gdi.dropLine(); + gdi.refreshFast(); + + } + xo = xml.getObject("ClassData"); if (!xo) diff --git a/code/oListInfo.cpp b/code/oListInfo.cpp index 87057c7..79fd0c9 100644 --- a/code/oListInfo.cpp +++ b/code/oListInfo.cpp @@ -1,6 +1,6 @@ /********************i**************************************************** MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -315,6 +315,9 @@ int oListInfo::getMaxCharWidth(const oEvent *oe, for (size_t k = 0; k < pps.size(); k++) { wstring extra; switch (pps[k].type) { + case lRunnerCardVoltage: + extra = L"3.00 V"; + break; case lPunchName: case lControlName: case lPunchNamedTime: { @@ -1020,9 +1023,8 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara }; bool invalidClass = pc && pc->getClassStatus() != oClass::ClassStatus::Normal; int legIndex = pp.legIndex; - if(pc && pp.type != lResultModuleNumber && pp.type != lResultModuleNumberTeam - && pp.type != lResultModuleTime && pp.type != lResultModuleTimeTeam) - legIndex = pc->getLinearIndex(pp.legIndex, pp.linearLegIndex); + if(pc && !MetaList::isResultModuleOutput(pp.type) && !MetaList::isAllStageType(pp.type)) + legIndex = pc->getLinearIndex(pp.legIndex, pp.linearLegIndex); switch ( pp.type ) { case lClassName: @@ -1462,6 +1464,12 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara } break; + case lRunnerCardVoltage: + if (r && r->getCard()) { + wcscpy_s(wbf, r->getCard()->getCardVoltage().c_str()); + } + break; + case lRunnerStageNumber: if (pp.legIndex >= 0) swprintf_s(wbf, L"%d", pp.legIndex + 1); diff --git a/code/oListInfo.h b/code/oListInfo.h index 0d4d420..24f4095 100644 --- a/code/oListInfo.h +++ b/code/oListInfo.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -106,6 +106,7 @@ enum EPostType lRunnerRogainingPointGross, lRunnerTimeAdjustment, lRunnerPointAdjustment, + lRunnerCardVoltage, lRunnerStageTime, lRunnerStageStatus, diff --git a/code/oPunch.cpp b/code/oPunch.cpp index 763b2c7..69796c6 100644 --- a/code/oPunch.cpp +++ b/code/oPunch.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oPunch.h b/code/oPunch.h index a7bbcaa..44bcb4e 100644 --- a/code/oPunch.h +++ b/code/oPunch.h @@ -7,7 +7,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oReport.cpp b/code/oReport.cpp index 4d60365..16bb310 100644 --- a/code/oReport.cpp +++ b/code/oReport.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oRunner.cpp b/code/oRunner.cpp index cab51f4..a5f27d7 100644 --- a/code/oRunner.cpp +++ b/code/oRunner.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1359,7 +1359,9 @@ bool oRunner::evaluateCard(bool doApply, vector & MissingPunches, } } - if (ctrl->getStatus() == oControl::StatusBad || ctrl->getStatus() == oControl::StatusOptional) { + if (ctrl->getStatus() == oControl::StatusBad || + ctrl->getStatus() == oControl::StatusOptional || + ctrl->getStatus() == oControl::StatusBadNoTiming) { // The control is marked "bad" but we found it anyway in the card. Mark it as used. if (tp_it!=Card->punches.end() && ctrl->hasNumberUnchecked(tp_it->Type)) { tp_it->isUsed=true; //Show that this is used when splittimes are calculated. @@ -1676,31 +1678,40 @@ void oRunner::doAdjustTimes(pCourse course) { if (!ctrl) continue; + pControl ctrlPrev = n > 0 ? course->Controls[n - 1] : nullptr; + while (it != Card->punches.end() && !it->isUsed) { it->setTimeAdjust(adjustment); ++it; } int minTime = ctrl->getMinTime(); - if (ctrl->getStatus() == oControl::StatusNoTiming) { + int pN = n -1; + + while (pN >= 0 && (course->Controls[pN]->getStatus() == oControl::ControlStatus::StatusBad || + course->Controls[pN]->getStatus() == oControl::ControlStatus::StatusBadNoTiming)) { + pN--; // Skip bad controls + } + + if (ctrl->getStatus() == oControl::StatusNoTiming || (ctrlPrev && ctrlPrev->getStatus() == oControl::StatusBadNoTiming)) { int t = 0; - if (n>0 && splitTimes[n].time>0 && splitTimes[n-1].time>0) { - t = splitTimes[n].time + adjustment - splitTimes[n-1].time; + if (n>0 && pN>=0 && splitTimes[n].time>0 && splitTimes[pN].time>0) { + t = splitTimes[n].time + adjustment - splitTimes[pN].time; } - else if (n == 0 && splitTimes[n].time>0) { + else if (pN < 0 && splitTimes[n].time>0) { t = splitTimes[n].time - tStartTime; } adjustment -= t; } - else if (minTime>0) { + else if (minTime > 0) { int t = 0; - if (n>0 && splitTimes[n].time>0 && splitTimes[n-1].time>0) { - t = splitTimes[n].time + adjustment - splitTimes[n-1].time; + if (n > 0 && pN >= 0 && splitTimes[n].time > 0 && splitTimes[pN].time > 0) { + t = splitTimes[n].time + adjustment - splitTimes[pN].time; } - else if (n == 0 && splitTimes[n].time>0) { + else if (pN < 0 && splitTimes[n].time>0) { t = splitTimes[n].time - tStartTime; } - int maxadjust = max(minTime-t, 0); + int maxadjust = max(minTime - t, 0); adjustment += maxadjust; } @@ -1862,16 +1873,10 @@ bool oRunner::storeTimesAux(pClass targetClass) { if (targetClass && dupLeg < targetClass->tLeaderTime.size()) { if (tStatus == StatusOK) { int rt = getRunningTime(false); - /*int &bt = targetClass->tLeaderTime[dupLeg].bestTimeOnLeg; - if (rt > 0 && (bt <= 0 || rt < bt)) { - bt = rt; - updated = true; - }*/ if (targetClass->tLeaderTime[dupLeg].update(rt, oClass::LeaderInfo::Type::Leg)) updated = true; - - } + if (getStatusComputed() == StatusOK) { int rt = getRunningTime(true); if (targetClass->tLeaderTime[dupLeg].updateComputed(rt, oClass::LeaderInfo::Type::Leg)) @@ -1886,6 +1891,16 @@ bool oRunner::storeTimesAux(pClass targetClass) { if (targetClass->tLeaderTime[dupLeg].updateComputed(rt, oClass::LeaderInfo::Type::Total)) updated = true; + if (getTotalStatus() == StatusOK) { + rt = getTotalRunningTime(getFinishTime(), false, true); + if (targetClass->tLeaderTime[dupLeg].update(rt, oClass::LeaderInfo::Type::TotalInput)) + updated = true; + + rt = getTotalRunningTime(getFinishTime(), true, true); + if (targetClass->tLeaderTime[dupLeg].updateComputed(rt, oClass::LeaderInfo::Type::TotalInput)) + updated = true; + } + /*int &bt = targetClass->tLeaderTime[dupLeg].totalLeaderTime; if (rt > 0 && (bt <= 0 || rt < bt)) { bt = rt; @@ -1898,14 +1913,10 @@ bool oRunner::storeTimesAux(pClass targetClass) { size_t mappedLeg = targetClass->mapLeg(tLeg); // Best input time if (mappedLegtLeaderTime.size()) { - /*int &it = targetClass->tLeaderTime[mappedLeg].inputTime; - if (inputTime > 0 && inputStatus == StatusOK && (it <= 0 || inputTime < it) ) { - it = inputTime; - updated = true; - }*/ if (inputStatus == StatusOK) { - if (targetClass->tLeaderTime[mappedLeg].update(inputTime, oClass::LeaderInfo::Type::Input)) + if (targetClass->tLeaderTime[mappedLeg].update(inputTime, oClass::LeaderInfo::Type::Input)) { updated = true; + } } } @@ -3631,7 +3642,7 @@ void oRunner::apply(ChangeType changeType, pRunner src) { if (r && r->FinishTime > 0 && r->statusOK(false)) { int rt = r->getRaceRunningTime(false, tDuplicateLeg - 1); - int timeAfter = rt - pc->getTotalLegLeaderTime(oClass::AllowRecompute::No, r->tDuplicateLeg, false, true); + int timeAfter = rt - pc->getTotalLegLeaderTime(oClass::AllowRecompute::NoUseOld, r->tDuplicateLeg, false, true); if (rt > 0 && timeAfter >= 0) lastStart = pc->getStartData(tDuplicateLeg) + timeAfter; } @@ -3704,7 +3715,7 @@ const shared_ptr
&oRunner::getTable(oEvent *oe) { table->addColumn("Lag", 120, false); table->addColumn("Sträcka", 70, true); - table->addColumn("SI", 90, true, false); + table->addColumn("Bricka", 90, true, false); table->addColumn("Start", 70, false, true); table->addColumn("Mål", 70, false, true); @@ -4217,8 +4228,7 @@ void oRunner::getSplitTime(int courseControlId, RunnerStatus &stat, int &rt) con stat = StatusUnknown; int cardno = getCardNo(); - if (courseControlId==oPunch::PunchFinish && - FinishTime>0 && tStatus!=StatusUnknown) { + if (courseControlId==oPunch::PunchFinish && FinishTime>0) { stat = tStatus; rt = getFinishTimeAdjusted(); } @@ -5065,7 +5075,14 @@ void oRunner::printSplits(gdioutput& gdi) const { gdi.dropLine(0.7); if (getCard() && getCard()->miliVolt > 0) { - wstring warning = getCard()->isCriticalCardVoltage() ? lang.tl("Low") : lang.tl("OK"); + auto stat = getCard()->isCriticalCardVoltage(); + wstring warning; + if (stat == oCard::BatteryStatus::Bad) + warning = lang.tl("Replace"); + else if (stat == oCard::BatteryStatus::Warning) + warning = lang.tl("Low"); + else + warning = lang.tl("OK"); gdi.fillRight(); gdi.addString("", fontSmall, L"Batteristatus:"); gdi.addStringUT(boldSmall, getCard()->getCardVoltage()); diff --git a/code/oRunner.h b/code/oRunner.h index c3242f9..120b66d 100644 --- a/code/oRunner.h +++ b/code/oRunner.h @@ -11,7 +11,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oTeam.cpp b/code/oTeam.cpp index 3cfd18e..1b18e4c 100644 --- a/code/oTeam.cpp +++ b/code/oTeam.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1212,7 +1212,7 @@ void oTeam::apply(ChangeType changeType, pRunner source) { if (rt>0) setStart = true; - int leaderTime = pc->getTotalLegLeaderTime(oClass::AllowRecompute::No, i-1, false, false); + int leaderTime = pc->getTotalLegLeaderTime(oClass::AllowRecompute::NoUseOld, i-1, false, false); int timeAfter = leaderTime > 0 ? rt - leaderTime : 0; if (rt>0 && timeAfter>=0) diff --git a/code/oTeam.h b/code/oTeam.h index 879f317..6f891fd 100644 --- a/code/oTeam.h +++ b/code/oTeam.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oTeamEvent.cpp b/code/oTeamEvent.cpp index bb8ef06..23a5724 100644 --- a/code/oTeamEvent.cpp +++ b/code/oTeamEvent.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/oevent_transfer.cpp b/code/oevent_transfer.cpp index 491a66c..c38aea4 100644 --- a/code/oevent_transfer.cpp +++ b/code/oevent_transfer.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/onlineinput.cpp b/code/onlineinput.cpp index c2721d1..f757799 100644 --- a/code/onlineinput.cpp +++ b/code/onlineinput.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,6 +43,7 @@ #include "xmlparser.h" #include "progress.h" #include "csvparser.h" +#include "machinecontainer.h" #include "SportIdent.h" #include "TabSI.h" @@ -69,7 +70,7 @@ OnlineInput::~OnlineInput() { int OnlineInput::processButton(gdioutput &gdi, ButtonInfo &bi) { if (bi.id == "SaveMapping") { int ctrl = gdi.getTextNo("Code"); - if (ctrl<10) + if (ctrl<1) throw meosException("Ogiltig kontrollkod"); ListBoxInfo lbi; if (!gdi.getSelectedItem("Function", lbi)) @@ -116,9 +117,9 @@ void OnlineInput::fillMappings(gdioutput &gdi) const{ } -void OnlineInput::settings(gdioutput &gdi, oEvent &oe, bool created) { +void OnlineInput::settings(gdioutput &gdi, oEvent &oe, State state) { int iv = interval; - if (created) { + if (state == State::Create) { iv = 10; url = oe.getPropertyString("MIPURL", L""); } @@ -128,7 +129,7 @@ void OnlineInput::settings(gdioutput &gdi, oEvent &oe, bool created) { time = itow(iv); settingsTitle(gdi, "Inmatning online"); - startCancelInterval(gdi, "Save", created, IntervalSecond, time); + startCancelInterval(gdi, "Save", state, IntervalSecond, time); gdi.addInput("URL", url, 40, 0, L"URL:", L"Till exempel X#http://www.input.org/online.php"); gdi.addCheckbox("UseROC", "Använd ROC-protokoll", OnlineCB, useROCProtocol).setExtra(getId()); @@ -160,7 +161,8 @@ void OnlineInput::settings(gdioutput &gdi, oEvent &oe, bool created) { gdi.addString("", 10, "help:onlineinput"); } -void OnlineInput::save(oEvent &oe, gdioutput &gdi) { +void OnlineInput::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); int iv=gdi.getTextNo("Interval"); const wstring &xurl=gdi.getText("URL"); @@ -175,16 +177,17 @@ void OnlineInput::save(oEvent &oe, gdioutput &gdi) { } url = xurl; - process(gdi, &oe, SyncNone); - interval = iv; + if (doProcess) { + process(gdi, &oe, SyncNone); + interval = iv; + } } void OnlineInput::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); gdi.fillRight(); - gdi.pushX(); - + gdi.addString("", 0, "URL:"); gdi.addStringUT(0, url); gdi.popX(); @@ -208,6 +211,46 @@ void OnlineInput::status(gdioutput &gdi) gdi.popX(); } +void OnlineInput::saveMachine(oEvent &oe, const wstring &guiInterval) { + auto &cnt = oe.getMachineContainer().set(getTypeString(), getMachineName()); + + cnt.set("url", url); + cnt.set("cmpId", cmpId); + cnt.set("unitId", unitId); + cnt.set("ROC", useROCProtocol); + cnt.set("useId", useUnitId); + + int iv = _wtoi(guiInterval.c_str()); + cnt.set("interval", iv); + + vector pm; + for (auto &v : specialPunches) { + pm.push_back(v.first); + pm.push_back(v.second); + } + cnt.set("map", pm); +} + +void OnlineInput::loadMachine(oEvent &oe, const wstring &name) { + auto *cnt = oe.getMachineContainer().get(getTypeString(), name); + if (!cnt) + return; + + url = cnt->getString("url"); + cmpId = cnt->getInt("cmpId"); + unitId = cnt->getString("unitId"); + + useROCProtocol = cnt->getInt("ROC") != 0; + useUnitId = cnt->getInt("useId") != 0; + interval = cnt->getInt("interval"); + + specialPunches.clear(); + vector pm = cnt->getVectorInt("map"); + for (int j = 0; j + 1 < pm.size(); j+=2) { + specialPunches[pm[j]] = oPunch::SpecialPunch(pm[j + 1]); + } +} + void OnlineInput::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) { oe->autoSynchronizeLists(true); diff --git a/code/onlineinput.h b/code/onlineinput.h index 1f557b2..d0abaa1 100644 --- a/code/onlineinput.h +++ b/code/onlineinput.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,15 +59,23 @@ protected: void processPunches(oEvent &oe, const xmlList &punches); void processPunches(oEvent &oe, list< vector > &rocData); + + bool hasSaveMachine() const final { + return true; + } + + void saveMachine(oEvent &oe, const wstring &guiInterval) final; + void loadMachine(oEvent &oe, const wstring &name) final; + public: int processButton(gdioutput &gdi, ButtonInfo &bi); - void save(oEvent &oe, gdioutput &gdi); - void settings(gdioutput &gdi, oEvent &oe, bool created); + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; + void settings(gdioutput &gdi, oEvent &oe, State state) final; OnlineInput *clone() const {return new OnlineInput(*this);} - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; OnlineInput() : AutoMachine("Onlineinput", Machines::mOnlineInput), cmpId(0), importCounter(1), bytesImported(0), lastSync(0), lastImportedId(0), useROCProtocol(false), useUnitId(false) {} ~OnlineInput(); diff --git a/code/onlineresults.cpp b/code/onlineresults.cpp index 3319d40..10ba61c 100644 --- a/code/onlineresults.cpp +++ b/code/onlineresults.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,6 +41,7 @@ #include "Download.h" #include "xmlparser.h" #include "progress.h" +#include "machinecontainer.h" int AutomaticCB(gdioutput *gdi, int type, void *data); @@ -95,9 +96,9 @@ int OnlineResults::processButton(gdioutput &gdi, ButtonInfo &bi) { return 0; } -void OnlineResults::settings(gdioutput &gdi, oEvent &oe, bool created) { +void OnlineResults::settings(gdioutput &gdi, oEvent &oe, State state) { int iv = interval; - if (created) { + if (state == State::Create) { iv = 10; url = oe.getPropertyString("MOPURL", L""); file = oe.getPropertyString("MOPFolderName", L""); @@ -109,7 +110,7 @@ void OnlineResults::settings(gdioutput &gdi, oEvent &oe, bool created) { time = itow(iv); settingsTitle(gdi, "Resultat online"); - startCancelInterval(gdi, "Save", created, IntervalSecond, time); + startCancelInterval(gdi, "Save", state, IntervalSecond, time); int basex = gdi.getCX(); gdi.pushY(); @@ -209,7 +210,7 @@ void OnlineResults::settings(gdioutput &gdi, oEvent &oe, bool created) { int xp = gdi.getCX(); int yp = gdi.getCY(); for (size_t k = 0; k< ctrlP.size(); k++) { - if (created && ctrlP[k].first->isValidRadio()) + if (state == State::Create && ctrlP[k].first->isValidRadio()) controls.insert(ctrlP[k].second); wstring name = L"#" + (ctrlP[k].first->hasName() ? ctrlP[k].first->getName() : ctrlP[k].first->getString()); if (ctrlP[k].first->getNumberDuplicates() > 1) @@ -245,10 +246,17 @@ void OnlineResults::enableFile(gdioutput &gdi, bool state) { gdi.setInputStatus("BrowseScript", state); } -void OnlineResults::save(oEvent &oe, gdioutput &gdi) { +void OnlineResults::save(oEvent &oe, gdioutput &gdi, bool doProcess) { + AutoMachine::save(oe, gdi, doProcess); int iv=gdi.getTextNo("Interval"); wstring folder=gdi.getText("FolderName"); const wstring &xurl=gdi.getText("URL"); + wstring px = gdi.getText("Prefix"); + + if (folder != file || px != prefix) { + exportCounter = 1; + sessionNumberOffset = 0; + } if (!folder.empty()) oe.setProperty("MOPFolderName", folder); @@ -261,7 +269,7 @@ void OnlineResults::save(oEvent &oe, gdioutput &gdi) { cmpId = gdi.getTextNo("CmpID"); passwd = gdi.getText("Password"); - prefix = gdi.getText("Prefix"); + prefix = px; exportScript = gdi.getText("ExportScript"); zipFile = gdi.isChecked("Zip"); includeTotal = gdi.hasWidget("IncludeTotal") && gdi.isChecked("IncludeTotal"); @@ -284,9 +292,26 @@ void OnlineResults::save(oEvent &oe, gdioutput &gdi) { folder = folder.substr(0, folder.size() - 1); file = folder; - wstring exp = getExportFileName(); - if (fileExist(exp.c_str())) - throw meosException(wstring(L"Filen finns redan: X#") + exp); + if (doProcess) { + wstring exp = getExportFileName(); + if (fileExists(exp)) { + sessionNumberOffset = 1; + int lastOffset = sessionNumberOffset; + while (fileExists(exp = getExportFileName())) { + lastOffset = sessionNumberOffset; + sessionNumberOffset *= 2; + } + while (lastOffset + 1 < sessionNumberOffset) { + int midOffset = (lastOffset + sessionNumberOffset) / 2; + int oldOffset = sessionNumberOffset; + sessionNumberOffset = midOffset; + if (fileExists(exp = getExportFileName())) { + lastOffset = midOffset; + sessionNumberOffset = oldOffset; + } + } + } + } } if (sendToURL) { @@ -316,18 +341,18 @@ void OnlineResults::save(oEvent &oe, gdioutput &gdi) { } } - process(gdi, &oe, SyncNone); - - interval = iv; - synchronize = true; - synchronizePunches = true; + if (doProcess) { + process(gdi, &oe, SyncNone); + interval = iv; + synchronize = true; + synchronizePunches = true; + } } void OnlineResults::status(gdioutput &gdi) { - gdi.addString("", 1, name); + AutoMachine::status(gdi); gdi.fillRight(); - gdi.pushX(); if (sendToFile) { gdi.addString("", 0, "Mapp:"); gdi.addStringUT(0, file); @@ -556,6 +581,62 @@ InfoCompetition &OnlineResults::getInfoServer() const { wstring OnlineResults::getExportFileName() const { wchar_t bf[260]; - swprintf_s(bf, L"%s\\%s%04d.xml", file.c_str(), prefix.c_str(), exportCounter);//WCS + if (prefix.empty()) + swprintf_s(bf, L"%s\\exp_%04d.xml", file.c_str(), exportCounter + sessionNumberOffset); + else + swprintf_s(bf, L"%s\\%s%04d.xml", file.c_str(), prefix.c_str(), exportCounter + sessionNumberOffset); + return bf; } + +void OnlineResults::saveMachine(oEvent &oe, const wstring &guiInterval) { + auto &cnt = oe.getMachineContainer().set(getTypeString(), getMachineName()); + cnt.set("file", file); + cnt.set("url", url); + cnt.set("prefix", prefix); + int iv = _wtoi(guiInterval.c_str()); + cnt.set("interval", iv); + + string pwProp = "@respwd" + gdioutput::narrow(getMachineName()); + oe.setPropertyEncrypt(pwProp.c_str(), gdioutput::toUTF8(passwd)); + + cnt.set("cmp", cmpId); + + cnt.set("classes", classes); + cnt.set("controls", controls); + + cnt.set("dt", int(dataType)); + cnt.set("zip", zipFile); + cnt.set("tot", includeTotal); + cnt.set("crs", includeCourse); + cnt.set("doURL", sendToURL); + cnt.set("doFile", sendToFile); + cnt.set("script", exportScript); +} + +void OnlineResults::loadMachine(oEvent &oe, const wstring &name) { + auto *cnt = oe.getMachineContainer().get(getTypeString(), name); + if (!cnt) + return; + + file = cnt->getString("file"); + url = cnt->getString("url"); + prefix = cnt->getString("prefix"); + interval = cnt->getInt("interval"); + + string pwProp = "@respwd" + gdioutput::narrow(getMachineName()); + passwd = gdioutput::fromUTF8(oe.getPropertyStringDecrypt(pwProp.c_str(), "")); + + cmpId = cnt->getInt("cmp"); + + classes = cnt->getSetInt("classes"); + controls = cnt->getSetInt("controls"); + + dataType = DataType(cnt->getInt("dt")); + zipFile = cnt->getInt("zip") != 0; + includeTotal = cnt->getInt("tot") != 0; + includeCourse = cnt->getInt("crs") != 0; + sendToURL = cnt->getInt("doURL") != 0; + sendToFile = cnt->getInt("doFile") != 0; + exportScript = cnt->getString("script"); +} diff --git a/code/onlineresults.h b/code/onlineresults.h index 36f4bfc..a41788b 100644 --- a/code/onlineresults.h +++ b/code/onlineresults.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -53,6 +53,7 @@ protected: mutable InfoCompetition *infoServer; wstring exportScript; int exportCounter; + int sessionNumberOffset = 0; void enableURL(gdioutput &gdi, bool state); void enableFile(gdioutput &gdi, bool state); @@ -63,16 +64,23 @@ protected: vector errorLines; void formatError(gdioutput &gdi); + bool hasSaveMachine() const override { + return true; + } + + void saveMachine(oEvent &oe, const wstring &guiInterval) final; + void loadMachine(oEvent &oe, const wstring &name) final; + public: int processButton(gdioutput &gdi, ButtonInfo &bi); InfoCompetition &getInfoServer() const; - void save(oEvent &oe, gdioutput &gdi); - void settings(gdioutput &gdi, oEvent &oe, bool created); + void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; + void settings(gdioutput &gdi, oEvent &oe, State state) final; OnlineResults *clone() const {return new OnlineResults(*this);} - void status(gdioutput &gdi); - void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast); + void status(gdioutput &gdi) final; + void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final; OnlineResults(); ~OnlineResults(); friend class TabAuto; diff --git a/code/ospeaker.h b/code/ospeaker.h index 5336d64..07dfa37 100644 --- a/code/ospeaker.h +++ b/code/ospeaker.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/parser.cpp b/code/parser.cpp index 236435c..a670b6d 100644 --- a/code/parser.cpp +++ b/code/parser.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/parser.h b/code/parser.h index 5ef26fc..6d2f360 100644 --- a/code/parser.h +++ b/code/parser.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/pdfwriter.cpp b/code/pdfwriter.cpp index 157ef51..24d8e80 100644 --- a/code/pdfwriter.cpp +++ b/code/pdfwriter.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/pdfwriter.h b/code/pdfwriter.h index 4d067ba..1979526 100644 --- a/code/pdfwriter.h +++ b/code/pdfwriter.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/prefseditor.cpp b/code/prefseditor.cpp index a66f62e..72e92f4 100644 --- a/code/prefseditor.cpp +++ b/code/prefseditor.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/prefseditor.h b/code/prefseditor.h index 14de302..ab3c4c2 100644 --- a/code/prefseditor.h +++ b/code/prefseditor.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/printer.cpp b/code/printer.cpp index bf07127..2a546bf 100644 --- a/code/printer.cpp +++ b/code/printer.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/progress.cpp b/code/progress.cpp index 2a04f84..c81eefd 100644 --- a/code/progress.cpp +++ b/code/progress.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/progress.h b/code/progress.h index 882443d..b298117 100644 --- a/code/progress.h +++ b/code/progress.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/qualification_final.cpp b/code/qualification_final.cpp index f5a9bc2..a470c47 100644 --- a/code/qualification_final.cpp +++ b/code/qualification_final.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/qualification_final.h b/code/qualification_final.h index 81d2f87..f6102a7 100644 --- a/code/qualification_final.h +++ b/code/qualification_final.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/random.cpp b/code/random.cpp index bd71143..a5f0a45 100644 --- a/code/random.cpp +++ b/code/random.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/random.h b/code/random.h index 96f22aa..24b268b 100644 --- a/code/random.h +++ b/code/random.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/recorder.cpp b/code/recorder.cpp index c20ed90..24504e2 100644 --- a/code/recorder.cpp +++ b/code/recorder.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/recorder.h b/code/recorder.h index 4191723..10a7ec8 100644 --- a/code/recorder.h +++ b/code/recorder.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/restserver.cpp b/code/restserver.cpp index 2b1ac30..607a511 100644 --- a/code/restserver.cpp +++ b/code/restserver.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/restserver.h b/code/restserver.h index ebd0531..ee33dda 100644 --- a/code/restserver.h +++ b/code/restserver.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/socket.cpp b/code/socket.cpp index ca04a4a..6b4cadc 100644 --- a/code/socket.cpp +++ b/code/socket.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/socket.h b/code/socket.h index fa643b8..f657fb2 100644 --- a/code/socket.h +++ b/code/socket.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/sound/leader.wav b/code/sound/leader.wav new file mode 100644 index 0000000..8dc9882 Binary files /dev/null and b/code/sound/leader.wav differ diff --git a/code/sound/needaction.wav b/code/sound/needaction.wav new file mode 100644 index 0000000..4fa9281 Binary files /dev/null and b/code/sound/needaction.wav differ diff --git a/code/sound/notok.wav b/code/sound/notok.wav new file mode 100644 index 0000000..d0089cd Binary files /dev/null and b/code/sound/notok.wav differ diff --git a/code/sound/ok.wav b/code/sound/ok.wav new file mode 100644 index 0000000..6ce80c8 Binary files /dev/null and b/code/sound/ok.wav differ diff --git a/code/speakermonitor.cpp b/code/speakermonitor.cpp index 5cf52b6..aea63c2 100644 --- a/code/speakermonitor.cpp +++ b/code/speakermonitor.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/speakermonitor.h b/code/speakermonitor.h index 8c1eb38..ad1b247 100644 --- a/code/speakermonitor.h +++ b/code/speakermonitor.h @@ -1,7 +1,7 @@ #pragma once /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/subcommand.h b/code/subcommand.h index 4588d61..5ffc61e 100644 --- a/code/subcommand.h +++ b/code/subcommand.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software -Copyright (C) 2009-2020 Melin Software HB +Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/swedish.lng b/code/swedish.lng index 6ffb7e2..b8ab4e6 100644 --- a/code/swedish.lng +++ b/code/swedish.lng @@ -2532,8 +2532,8 @@ Använd om möjligt samma dator som användes vid senaste importen = Använd om Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen Varning: Kunde inte hitta föregående version av tävlingen (X) = Varning: Kunde inte hitta föregående version av tävlingen (X) ClassDefaultResult = Klass, Standardresultat -RunnerCoursePlace = Deltagars placering på banan -RunnerStagePlace = Deltagares placerings på etapp +RunnerCoursePlace = Deltagares placering på banan +RunnerStagePlace = Deltagares placering på etapp RunnerStagePoints = Deltagares poäng på etapp RunnerStageTime = Deltagares tid på etapp RunnerStageStatus = Deltagares status på etapp @@ -2541,7 +2541,7 @@ RunnerStageTimeStatus = Deltagares tid eller status på etapp EFilterIncludeNotParticipating = Inkludera deltar ej RunnerStageNumber = Etappnummer tidigare etapp Begränsa bredd (klipp text) = Begränsa bredd (klipp text) -Håll ihop med = Håll ihop med +Håll ihop med = Håll ihop kolumner Justering i sidled = Justering i sidled Minsta blockbredd = Minsta blockbredd Relation till föregående = Relation till föregående @@ -2552,5 +2552,45 @@ prefsDatabaseEngine = Default database engine (MySQL) Startgrupperna X och Y överlappar = Startgrupperna X och Y överlappar Batteristatus = Batteristatus Low = Lågt -prefsReadVoltageExp = Läs SIAC batterispänning +Replace[battery] = Byt ut Spänning = Spänning +(kopia) = (kopia) +Klassen använder banpool = Klassen använder banpool +Filen (X) innehåller IOF-XML tävlingsdata och kan importeras i en existerande tävling = Filen (X) innehåller IOF-XML tävlingsdata och kan importeras i en existerande tävling +Filen (X) är en listdefinition = Filen (X) är en listdefinition +Filen (X) är en resultatmodul = Filen (X) är en resultatmodul +Filen (X) är inte en MeOS-tävling = Filen (X) är inte en MeOS-tävling +MeOS-data = MeOS-data +List definition = Listdefinition +ask:importcopy = En tävling (X) med samma ursprung finns redan. Du kan importera tävlingen som en version av denna eller som en ny oberoende tävling.\n\nVill du importera den som en ny tävling? +RunnerCardVoltage = Brickans batterispänning +Applicera för specifik etapp = Tillämpa för specifik etapp +Ljud = Ljud +Ljudval = Ljudval +Markera allt (X) = Markera allt (X) +Markera inget (X) = Markera inget (X) +Ny ledare i klassen = Ny ledare i klassen +Sparade automater = Sparade automater +Spela upp ett ljud för att indikera resultatet av brickavläsningen = Spela upp ett ljud för att indikera resultatet av brickavläsningen +Status inte OK (röd utgång) = Status inte OK (röd utgång) +help:selectsound = Välj ljudfiler att spela. Är inget valt spelas MeOS inbyggda ljud. +prefsPlaySound = prefsPlaySound +prefsSoundAction = prefsSoundAction +prefsSoundLeader = prefsSoundLeader +prefsSoundNotOK = prefsSoundNotOK +prefsSoundOK = prefsSoundOK +prefsTestPath = prefsTestPath +Åtgärd krävs = Åtgärd krävs +Alla tidigare etapper = Alla tidigare etapper +Dölj = Dölj +Exempel = Exempel +Filtrera = Filtrera +Markera kolumn = Markera kolumn +Slå ihop text = Slå ihop text (dela kolumn) +Sortera fallande = Sortera fallande +Sortera stigande = Sortera stigande +Sök symbol = Sök symbol +Testa = Testa +Fel: Använd X i texten där värdet (Y) ska sättas in = Fel: Använd X i texten där värdet (Y) ska sättas in +info:teamcourseassignment = Den importerade filen innehåller gafflingsdata för lag. För att importera gafflingarna måste tävlingen förberedas så den matchar laginformationen i filen: \n\n1. Se till att alla klasser är uppsatta med korrekt antal sträckor.\n2. Ställ in nummerlappsnummer för varje klass. Använd snabbinställningar på sidan klasser för att mata in första nummerlappsnummer i varje klass (automatisk inställning). Alternativt kan du importera lagen och tilldela nummerlappar som vanligt först.\n3. Importera banorna. Du kan importera den här filen flera gånger för att uppdatera lottningen. +Försvunnen = Försvunnen diff --git a/code/testmeos.cpp b/code/testmeos.cpp index cb6a359..87e7eef 100644 --- a/code/testmeos.cpp +++ b/code/testmeos.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/testmeos.h b/code/testmeos.h index f916270..c3f078e 100644 --- a/code/testmeos.h +++ b/code/testmeos.h @@ -2,7 +2,7 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/toolbar.cpp b/code/toolbar.cpp index 21fb7ce..5350b6f 100644 --- a/code/toolbar.cpp +++ b/code/toolbar.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/toolbar.h b/code/toolbar.h index b999e4b..b04edea 100644 --- a/code/toolbar.h +++ b/code/toolbar.h @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/code/xmlparser.cpp b/code/xmlparser.cpp index cfb567c..dfec585 100644 --- a/code/xmlparser.cpp +++ b/code/xmlparser.cpp @@ -1,6 +1,6 @@ /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -542,7 +542,7 @@ void xmlparser::read(const wstring &file, int maxobj) xbf.resize(asize+1); xmlinfo.clear(); - xbf.reserve(xbf.size() / 30); // Guess number of tags + xmlinfo.reserve(xbf.size() / 30); // Guess number of tags parseStack.clear(); diff --git a/code/xmlparser.h b/code/xmlparser.h index ffdcca5..8c918b4 100644 --- a/code/xmlparser.h +++ b/code/xmlparser.h @@ -10,7 +10,7 @@ #endif // _MSC_VER > 1000 /************************************************************************ MeOS - Orienteering Software - Copyright (C) 2009-2020 Melin Software HB + Copyright (C) 2009-2021 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by