MeOS version 3.9.1437 Update 1

This commit is contained in:
Erik Melin 2023-05-14 22:03:57 +02:00
parent 032a39ab1e
commit 16272ffa20
60 changed files with 8563 additions and 5640 deletions

View File

@ -989,8 +989,8 @@ OpFailStatus MeosSQL::uploadRunnerDB(oEvent *oe)
pw.init(); pw.init();
size_t tz = cdb.size() + rdb.size(); size_t tz = cdb.size() + rdb.size();
int s1 = (1000 * cdb.size())/tz; int s1 = tz > 0 ? (1000 * cdb.size())/tz : 0;
int s2 = (1000 * rdb.size())/tz; int s2 = tz > 0 ? (1000 * rdb.size())/tz : 0;
// Reset databases // Reset databases
con->query().exec("DELETE FROM dbClub"); con->query().exec("DELETE FROM dbClub");

View File

@ -906,7 +906,6 @@ int SportIdent::MonitorTCPSI(WORD port, int localZeroTime)
card.FinishPunch.Code = -1; card.FinishPunch.Code = -1;
card.CardNumber = op.SICardNo; card.CardNumber = op.SICardNo;
for (int k = 0; k < nPunch; k++) { for (int k = 0; k < nPunch; k++) {
punches[k].Time /= 10;
if (punches[k].Code == oPunch::PunchStart) if (punches[k].Code == oPunch::PunchStart)
card.StartPunch = punches[k]; card.StartPunch = punches[k];
else if (punches[k].Code == oPunch::PunchFinish) else if (punches[k].Code == oPunch::PunchFinish)
@ -2049,8 +2048,11 @@ void SportIdent::addPunch(DWORD Time, int Station, int Card, int Mode) {
int unit = 0; int unit = 0;
if (mappedCode != code) if (mappedCode != code)
unit = code; unit = code;
else else {
unit = (Station >> 16) & 0xFFFF; unit = (Station >> 16) & 0xFFFF;
if (unit == 0)
unit = code;
}
if (mappedCode > 30) { if (mappedCode > 30) {
sic.Punch[0].Code = Station; sic.Punch[0].Code = Station;

View File

@ -856,7 +856,7 @@ void PrintResultMachine::save(oEvent& oe, gdioutput& gdi, bool doProcess) {
else else
par.setLegNumberCoded(0); par.setLegNumberCoded(0);
oe.generateListInfo(par, listInfo); oe.generateListInfo(gdi, par, listInfo);
} }
} }
po.onlyChanged = gdi.isChecked("OnlyChanged"); po.onlyChanged = gdi.isChecked("OnlyChanged");

View File

@ -770,9 +770,9 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
gdi.pushX(); gdi.pushX();
gdi.fillRight(); gdi.fillRight();
oe->updateComputerTime(); oe->updateComputerTime();
int t=oe->getComputerTime()-(oe->getComputerTime()%60)+60; int t=oe->getComputerTime()-(oe->getComputerTime()%timeConstMinute)+timeConstMinute;
gdi.addInput("Rope", oe->getAbsTime(t), 6, 0, L"Repdragningstid"); gdi.addInput("Rope", oe->getAbsTime(t), 6, 0, L"Repdragningstid");
gdi.addInput("Restart", oe->getAbsTime(t+600), 6, 0, L"Omstartstid"); gdi.addInput("Restart", oe->getAbsTime(t+10 * timeConstMinute), 6, 0, L"Omstartstid");
gdi.dropLine(0.9); gdi.dropLine(0.9);
gdi.addButton("DoRestart","OK", ClassesCB); gdi.addButton("DoRestart","OK", ClassesCB);
gdi.addButton("Cancel","Stäng", ClassesCB); gdi.addButton("Cancel","Stäng", ClassesCB);
@ -992,7 +992,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
for (size_t k=0; k<cInfo.size(); k++) for (size_t k=0; k<cInfo.size(); k++)
par.selection.insert(cInfo[k].classId); par.selection.insert(cInfo[k].classId);
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
} }
@ -1181,7 +1181,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.dropLine(); gdi.dropLine();
gdi.addButton("Cancel", "Återgå", ClassesCB); gdi.addButton("Cancel", "Återgå", ClassesCB);
@ -1470,7 +1470,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
par.selection = classes; par.selection = classes;
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
} }
@ -1693,7 +1693,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
par.setLegNumberCoded(leg); par.setLegNumberCoded(leg);
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
@ -1949,7 +1949,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
par.listCode = EStdStartList; par.listCode = EStdStartList;
} }
} }
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
@ -2110,7 +2110,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
par.selection.insert(outClass.begin(), outClass.end()); par.selection.insert(outClass.begin(), outClass.end());
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
} }
else if (bi.id == "LockAllForks" || bi.id == "UnLockAllForks") { else if (bi.id == "LockAllForks" || bi.id == "UnLockAllForks") {
@ -2226,7 +2226,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
par.selection.insert(ClassId); par.selection.insert(ClassId);
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
} }

View File

@ -1542,7 +1542,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
if (importHiredCard) if (importHiredCard)
importDefaultHiredCards(gdi); importDefaultHiredCards(gdi);
oe->importXML_EntryData(gdi, tEvent, false, false, noFilter, noType); oe->importXML_EntryData(gdi, tEvent, false, false, noFilter, 0, 0, noType);
oe->setZeroTime(formatTimeHMS(zeroTime), false); oe->setZeroTime(formatTimeHMS(zeroTime), false);
oe->getDI().setDate("OrdinaryEntry", lastEntry); oe->getDI().setDate("OrdinaryEntry", lastEntry);
if (ci) { if (ci) {
@ -1555,13 +1555,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
} }
removeTempFile(tEvent); removeTempFile(tEvent);
oe->importXML_EntryData(gdi, tClass.c_str(), false, false, noFilter, noType); oe->importXML_EntryData(gdi, tClass.c_str(), false, false, noFilter, 0, 0, noType);
removeTempFile(tClass); removeTempFile(tClass);
set<int> stageFilter; set<int> stageFilter;
string preferredIdType; string preferredIdType;
checkStageFilter(gdi, tEntry, stageFilter, preferredIdType); checkStageFilter(gdi, tEntry, stageFilter, preferredIdType);
oe->importXML_EntryData(gdi, tEntry.c_str(), false, removeRemoved, stageFilter, preferredIdType); oe->importXML_EntryData(gdi, tEntry.c_str(), false, removeRemoved, stageFilter, 0, 0, preferredIdType);
removeTempFile(tEntry); removeTempFile(tEntry);
if (!course.empty()) { if (!course.empty()) {
@ -1803,7 +1803,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
save.c_str(), useUTC, allTransfer, individual, includeStage, false, false); save.c_str(), useUTC, allTransfer, individual, includeStage, false, false);
} }
else if (filterIndex == ImportFormats::OE) { else if (filterIndex == ImportFormats::OE) {
oe->exportOECSV(save.c_str(), cSVLanguageHeaderIndex, false); oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, false);
} }
else { else {
oListParam par; oListParam par;
@ -1811,8 +1811,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
par.setLegNumberCoded(-1); par.setLegNumberCoded(-1);
oListInfo li; oListInfo li;
par.selection = allTransfer; par.selection = allTransfer;
oe->generateListInfo(par, li);
gdioutput tGdi("temp", gdi.getScale()); gdioutput tGdi("temp", gdi.getScale());
oe->generateListInfo(tGdi, par, li);
oe->generateList(tGdi, true, li, false); oe->generateList(tGdi, true, li, false);
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0); HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
tGdi.openDoc(save.c_str()); tGdi.openDoc(save.c_str());
@ -1895,7 +1895,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
} }
} }
else if (filterIndex == ImportFormats::OE) { else if (filterIndex == ImportFormats::OE) {
oe->exportOECSV(save.c_str(), cSVLanguageHeaderIndex, includeSplits); oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, includeSplits);
} }
else { else {
oListParam par; oListParam par;
@ -1903,8 +1903,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
par.showSplitTimes = true; par.showSplitTimes = true;
par.setLegNumberCoded(-1); par.setLegNumberCoded(-1);
oListInfo li; oListInfo li;
oe->generateListInfo(par, li);
gdioutput tGdi("temp", gdi.getScale()); gdioutput tGdi("temp", gdi.getScale());
oe->generateListInfo(tGdi, par, li);
oe->generateList(tGdi, true, li, false); oe->generateList(tGdi, true, li, false);
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0); HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
tGdi.openDoc(save.c_str()); tGdi.openDoc(save.c_str());
@ -2049,12 +2049,6 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
entryForm(gdi, false); entryForm(gdi, false);
gdi.pushX();
gdi.fillRight();
gdi.addButton("DoImport", "Importera", CompetitionCB);
gdi.fillDown();
gdi.addButton("Cancel", "Avbryt", CompetitionCB);
gdi.popX();
gdi.refresh(); gdi.refresh();
} }
else if (bi.id=="DoImport") { else if (bi.id=="DoImport") {
@ -2063,9 +2057,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
gdi.disableInput("Cancel"); gdi.disableInput("Cancel");
gdi.disableInput("BrowseEntries"); gdi.disableInput("BrowseEntries");
bool removeRemoved = gdi.isChecked("RemoveRemoved"); bool removeRemoved = gdi.isChecked("RemoveRemoved");
int classOffset = 0;
if (gdi.hasWidget("ClassOffset")) {
classOffset = gdi.getTextNo("ClassOffset");
}
try { try {
gdi.autoRefresh(true); gdi.autoRefresh(true);
FlowOperation res = saveEntries(gdi, removeRemoved, false); FlowOperation res = saveEntries(gdi, removeRemoved, classOffset, false);
if (res != FlowContinue) { if (res != FlowContinue) {
if (res == FlowCancel) if (res == FlowCancel)
@ -2463,6 +2461,7 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
"\n\nMore French translations and documentation by Titouan Savart" "\n\nMore French translations and documentation by Titouan Savart"
"\n\nCzech Translation by Marek Kustka" "\n\nCzech Translation by Marek Kustka"
"\n\nSpanish Translation by Manuel Pedre" "\n\nSpanish Translation by Manuel Pedre"
"\n\nUkranian Translation by Oleg Rozhko"
"\n\nHelp with English documentation: Torbjörn Wikström"); "\n\nHelp with English documentation: Torbjörn Wikström");
gdi.dropLine(); gdi.dropLine();
@ -2500,7 +2499,7 @@ void TabCompetition::updateWarning(gdioutput &gdi) const {
} }
else if (n.length() >= limit && w.empty()) { else if (n.length() >= limit && w.empty()) {
gdi.setText("warningicon", L"514", true); gdi.setText("warningicon", L"514", true);
gdi.setText("cmpwarning", L"Ett långt tävlingsnamn kan ge oväntad nerskalning av utskrifter.", true); gdi.setTextTranslate("cmpwarning", L"Ett långt tävlingsnamn kan ge oväntad nerskalning av utskrifter.", true);
} }
} }
@ -3512,7 +3511,15 @@ void TabCompetition::entryForm(gdioutput &gdi, bool isGuide) {
gdi.addString("", 10, "help:import_entry_data"); gdi.addString("", 10, "help:import_entry_data");
gdi.dropLine(); gdi.dropLine();
if (!isGuide) {
gdi.pushX(); gdi.pushX();
gdi.fillRight();
gdi.addButton("DoImport", "Importera", CompetitionCB).setDefault();
gdi.fillDown();
gdi.addButton("Cancel", "Avbryt", CompetitionCB).setCancel();
gdi.popX();
gdi.dropLine(0.5);
}
gdi.fillRight(); gdi.fillRight();
gdi.addInput("FileNameCmp", L"", 48, 0, L"Tävlingsinställningar (IOF, xml)"); gdi.addInput("FileNameCmp", L"", 48, 0, L"Tävlingsinställningar (IOF, xml)");
@ -3550,23 +3557,31 @@ void TabCompetition::entryForm(gdioutput &gdi, bool isGuide) {
gdi.addButton("BrowseEntries", "Bläddra...", CompetitionCB).setExtra(L"FileNameServiceReq"); gdi.addButton("BrowseEntries", "Bläddra...", CompetitionCB).setExtra(L"FileNameServiceReq");
gdi.popX(); gdi.popX();
gdi.dropLine(3.2); gdi.dropLine(2.8);
if (!isGuide && oe->getNumRunners() > 0) { if (!isGuide && oe->getNumRunners() > 0) {
gdi.addCheckbox("RemoveRemoved", "Ta bort eventuella avanmälda deltagare", 0, true); gdi.addCheckbox("RemoveRemoved", "Ta bort eventuella avanmälda deltagare", 0, true);
gdi.dropLine(0.4);
} }
gdi.popX(); gdi.popX();
gdi.dropLine(2.5); gdi.dropLine(2);
gdi.addInput("FileNameRank", L"", 48, 0, L"Ranking (IOF, xml, csv)"); gdi.addInput("FileNameRank", L"", 48, 0, L"Ranking (IOF, xml, csv)");
gdi.dropLine(); gdi.dropLine();
gdi.addButton("BrowseEntries", "Bläddra...", CompetitionCB).setExtra(L"FileNameRank"); gdi.addButton("BrowseEntries", "Bläddra...", CompetitionCB).setExtra(L"FileNameRank");
gdi.popX(); gdi.popX();
gdi.fillDown(); gdi.fillDown();
gdi.dropLine(3); gdi.dropLine(3);
if (!isGuide) {
gdi.addString("", 10, "info:offsetclassid");
gdi.dropLine(0.5);
gdi.addInput("ClassOffset", L"0", 10, nullptr, L"Förskjutning av klassers Id:");
gdi.dropLine();
}
} }
FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, bool isGuide) { FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, int classOffset, bool isGuide) {
vector<string> fields = { "FileNameCmp", "FileNameCls", "FileNameClb", "FileName", vector<string> fields = { "FileNameCmp", "FileNameCls", "FileNameClb", "FileName",
"FileNameRank", "FileNameService", "FileNameServiceReq"}; "FileNameRank", "FileNameService", "FileNameServiceReq"};
@ -3645,7 +3660,9 @@ FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, bo
if (res != FlowContinue) if (res != FlowContinue)
return res; return res;
oe->importXML_EntryData(gdi, filename[i], false, removeRemoved, stageFilter, preferredIdType); const int courseIdOffset = 0;
oe->importXML_EntryData(gdi, filename[i], false, removeRemoved, stageFilter,
classOffset, courseIdOffset, preferredIdType);
} }
if (!isGuide) { if (!isGuide) {
gdi.setWindowTitle(oe->getTitleName()); gdi.setWindowTitle(oe->getTitleName());

View File

@ -123,7 +123,7 @@ class TabCompetition :
void createNewCmp(gdioutput &gdi, bool useExisting); void createNewCmp(gdioutput &gdi, bool useExisting);
void entryForm(gdioutput &gdi, bool isGuide); void entryForm(gdioutput &gdi, bool isGuide);
FlowOperation saveEntries(gdioutput &gdi, bool removeRemoved, bool isGuide); FlowOperation saveEntries(gdioutput &gdi, bool removeRemoved, int classOffset, bool isGuide);
FlowOperation checkStageFilter(gdioutput &gdi, const wstring &fname, set<int> &filter, string &preferredIdProvider); FlowOperation checkStageFilter(gdioutput &gdi, const wstring &fname, set<int> &filter, string &preferredIdProvider);

View File

@ -590,7 +590,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
for (size_t k=0; k<courseDrawClasses.size(); k++) for (size_t k=0; k<courseDrawClasses.size(); k++)
par.selection.insert(courseDrawClasses[k].classID); par.selection.insert(courseDrawClasses[k].classID);
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
gdi.refresh(); gdi.refresh();
} }
@ -925,10 +925,16 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
if (strlen(bf) < 2) if (strlen(bf) < 2)
continue; continue;
if (0 == line && uint8_t(bf[0]) == 0xEF && uint8_t(bf[1]) == 0xBB && uint8_t(bf[2]) == 0xBF) if (0 == line && uint8_t(bf[0]) == 0xEF && uint8_t(bf[1]) == 0xBB && uint8_t(bf[2]) == 0xBF) {
split(bf+3, " ;,", sw); split(bf + 3, "\t;,", sw);
else if (sw.size() == 1)
split(bf, " ;,", sw); split(bf + 3, " ", sw);
}
else {
split(bf, "\t;,", sw);
if (sw.size() == 1)
split(bf, " ", sw);
}
line++; line++;
if (sw.size() <= 1) if (sw.size() <= 1)
@ -965,7 +971,10 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
else { else {
set<int> noFilter; set<int> noFilter;
string noType; string noType;
oe->importXML_EntryData(gdi, filename.c_str(), addToClasses, false, noFilter, noType); int classIdOffset = 0;
int courseIdOffset = 0;
oe->importXML_EntryData(gdi, filename.c_str(), addToClasses, false,
noFilter, classIdOffset, courseIdOffset, noType);
} }
if (addToClasses) { if (addToClasses) {
// There is specific course-class matching inside the import of each format, // There is specific course-class matching inside the import of each format,

View File

@ -232,6 +232,7 @@ void TabList::generateList(gdioutput &gdi, bool forceUpdate)
par.bgImage); par.bgImage);
try { try {
oe->generateList(gdi, !noReEvaluate, currentList, false); oe->generateList(gdi, !noReEvaluate, currentList, false);
gdi.updatePosTight(gdi.getWidth(), gdi.getHeight(), gdi.scaleLength(10), gdi.scaleLength(30), 0, 0);
} }
catch (const meosException &ex) { catch (const meosException &ex) {
wstring err = lang.tl(ex.wwhat()); wstring err = lang.tl(ex.wwhat());
@ -449,7 +450,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (gdi.getSelectedItem("SavedInstance", lbi)) { if (gdi.getSelectedItem("SavedInstance", lbi)) {
oListParam &par = oe->getListContainer().getParam(lbi.data); oListParam &par = oe->getListContainer().getParam(lbi.data);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.getParam().sourceParam = lbi.data; currentList.getParam().sourceParam = lbi.data;
generateList(gdi); generateList(gdi);
} }
@ -570,7 +571,8 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else if (bi.id=="CancelPS") { else if (bi.id=="CancelPS") {
gdi.getTabs().get(TabType(bi.getExtraInt()))->loadPage(gdi); gdi.getTabs().get(TabType(bi.getExtraInt()))->loadPage(gdi);
} }
else if (bi.id == "SavePS") { else if (bi.id == "SavePS" || bi.id == "EditPS") {
bool edit = bi.id == "EditPS";
string ctype; string ctype;
gdi.getData("Type", ctype); gdi.getData("Type", ctype);
saveExtraLines(*oe, ctype.c_str(), gdi); saveExtraLines(*oe, ctype.c_str(), gdi);
@ -584,8 +586,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (gdi.hasWidget("SplitPrintList")) { if (gdi.hasWidget("SplitPrintList")) {
auto res = gdi.getSelectedItem("SplitPrintList"); auto res = gdi.getSelectedItem("SplitPrintList");
if (res.second) { if (res.second) {
if (res.first == -10) if (res.first == -11)
oe->getDI().setString("SplitPrint", L""); oe->getDI().setString("SplitPrint", L""); // Automatisk
else if (res.first == -10)
oe->getDI().setString("SplitPrint", L"*"); // Standard
else { else {
EStdListType type = oe->getListContainer().getType(res.first); EStdListType type = oe->getListContainer().getType(res.first);
string id = oe->getListContainer().getUniqueId(type); string id = oe->getListContainer().getUniqueId(type);
@ -608,6 +612,21 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
oe->setProperty("SplitPrintMaxWait", no); oe->setProperty("SplitPrintMaxWait", no);
} }
} }
if (edit) {
auto res = gdi.getSelectedItem("SplitPrintList");
gdi.clearPage(false);
auto &li = getListEditor();
auto& lc = oe->getListContainer();
int ix = li.load(oe->getListContainer(), res.first, true);
EStdListType type = oe->getListContainer().getType(ix);
string id = oe->getListContainer().getUniqueId(type);
oe->getDI().setString("SplitPrint", gdioutput::widen(id));
li.show(this, gdi);
gdi.refresh();
}
else
gdi.getTabs().get(TabType(bi.getExtraInt()))->loadPage(gdi); gdi.getTabs().get(TabType(bi.getExtraInt()))->loadPage(gdi);
} }
else if (bi.id == "PrinterSetup") { else if (bi.id == "PrinterSetup") {
@ -659,7 +678,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
lastSplitState = par.showSplitTimes; lastSplitState = par.showSplitTimes;
lastLargeSize = par.useLargeSize; lastLargeSize = par.useLargeSize;
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -689,7 +708,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getIndividual(par.selection, false); cnf.getIndividual(par.selection, false);
readSettings(gdi, par, true); readSettings(gdi, par, true);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -705,7 +724,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.showSplitTimes = true; par.showSplitTimes = true;
par.setLegNumberCoded(-1); par.setLegNumberCoded(-1);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -717,7 +736,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartIndividual(par, cnf); getStartIndividual(par, cnf);
readSettings(gdi, par, false); readSettings(gdi, par, false);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -728,7 +747,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartClub(par); getStartClub(par);
readSettings(gdi, par, false); readSettings(gdi, par, false);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -743,7 +762,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
readSettings(gdi, par, false); readSettings(gdi, par, false);
par.splitAnalysis = gdi.isChecked("SplitAnalysis"); par.splitAnalysis = gdi.isChecked("SplitAnalysis");
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -775,7 +794,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartTeam(par, cnf); getStartTeam(par, cnf);
readSettings(gdi, par, false); readSettings(gdi, par, false);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -791,7 +810,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
cnf.getRaceNStart(race, par.selection); cnf.getRaceNStart(race, par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -807,7 +826,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
cnf.getLegNStart(race, par.selection); cnf.getLegNStart(race, par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -819,7 +838,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
getResultTeam(par, cnf); getResultTeam(par, cnf);
readSettings(gdi, par, true); readSettings(gdi, par, true);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -831,7 +850,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
cnf.getRaceNRes(0, par.selection); cnf.getRaceNRes(0, par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -846,7 +865,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
cnf.getRaceNRes(race, par.selection); cnf.getRaceNRes(race, par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -861,7 +880,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
cnf.getLegNRes(race, par.selection); cnf.getLegNRes(race, par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -874,7 +893,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getResultRogaining(par, cnf); getResultRogaining(par, cnf);
readSettings(gdi, par, true); readSettings(gdi, par, true);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -904,7 +923,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getIndividual(par.back().selection, true); cnf.getIndividual(par.back().selection, true);
} }
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -915,7 +934,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.listCode = EStdRentedCard; par.listCode = EStdRentedCard;
par.showHeader = gdi.isChecked("ShowHeader"); par.showHeader = gdi.isChecked("ShowHeader");
par.setLegNumberCoded(-1); par.setLegNumberCoded(-1);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -927,7 +946,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.listCode = EIndPriceList; par.listCode = EIndPriceList;
par.showHeader = gdi.isChecked("ShowHeader"); par.showHeader = gdi.isChecked("ShowHeader");
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first; par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
} }
@ -997,7 +1016,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getPatrol(par.selection); cnf.getPatrol(par.selection);
} }
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -1012,7 +1031,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf; ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf); oe->getClassConfigurationInfo(cnf);
par.selection = set<int>(cnf.knockout.begin(), cnf.knockout.end()); par.selection = set<int>(cnf.knockout.begin(), cnf.knockout.end());
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -1032,7 +1051,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else else
par.selection = set<int>(cnf.lapcountsingle.begin(), cnf.lapcountsingle.end()); par.selection = set<int>(cnf.lapcountsingle.begin(), cnf.lapcountsingle.end());
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -1056,7 +1075,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (oListInfo::addTeams(type)) if (oListInfo::addTeams(type))
cnf.getTeamClass(par.selection); cnf.getTeamClass(par.selection);
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB); currentList.setCallback(openRunnerTeamCB);
generateList(gdi); generateList(gdi);
gdi.refresh(); gdi.refresh();
@ -1193,7 +1212,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else if (type==GUI_LISTBOX) { else if (type==GUI_LISTBOX) {
ListBoxInfo lbi=*(ListBoxInfo *)data; ListBoxInfo lbi=*(ListBoxInfo *)data;
if (lbi.id == "NumPerPage") { if (lbi.id == "SplitPrintList") {
gdi.setInputStatus("EditPS", int(lbi.data) > 0);
}
else if (lbi.id == "NumPerPage") {
enableWideFormat(gdi, true); enableWideFormat(gdi, true);
} }
else if (lbi.id == "SavedInstance") { else if (lbi.id == "SavedInstance") {
@ -1290,7 +1312,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (!listEditor) if (!listEditor)
listEditor = make_shared<ListEditor>(oe); listEditor = make_shared<ListEditor>(oe);
gdi.clearPage(false); gdi.clearPage(false);
listEditor->load(oe->getListContainer(), ix); listEditor->load(oe->getListContainer(), ix, false);
listEditor->show(this, gdi); listEditor->show(this, gdi);
gdi.refresh(); gdi.refresh();
} }
@ -2562,23 +2584,28 @@ bool TabList::loadPage(gdioutput &gdi)
MetaListContainer &lc = oe->getListContainer(); MetaListContainer &lc = oe->getListContainer();
if (lc.getNumLists(MetaListContainer::ExternalList) > 0) { if (lc.getNumLists(MetaListContainer::ExternalList) > 0) {
gdi.addString("", fontMediumPlus, "Egna listor").setColor(colorDarkGrey); bool init = false;
gdi.fillRight();
gdi.pushX();
for (int k = 0; k < lc.getNumLists(); k++) { for (int k = 0; k < lc.getNumLists(); k++) {
if (lc.isExternal(k)) { if (lc.isExternal(k) && !lc.isSplitPrintList(k)) {
if (!init) {
gdi.addString("", fontMediumPlus, "Egna listor").setColor(colorDarkGrey);
gdi.fillRight();
gdi.pushX();
init = true;
}
MetaList &mc = lc.getList(k); MetaList &mc = lc.getList(k);
checkWidth(gdi); checkWidth(gdi);
gdi.addButton("CustomList", mc.getListName(), ListsCB).setExtra(k); gdi.addButton("CustomList", mc.getListName(), ListsCB).setExtra(k);
} }
} }
if (init) {
gdi.popX(); gdi.popX();
gdi.dropLine(3); gdi.dropLine(3);
gdi.fillDown(); gdi.fillDown();
} }
}
vector< pair<wstring, size_t> > savedParams; vector< pair<wstring, size_t> > savedParams;
lc.getListParam(savedParams); lc.getListParam(savedParams);
@ -2762,28 +2789,38 @@ void TabList::splitPrintSettings(oEvent &oe, gdioutput &gdi, bool setupPrinter,
if (!oe.empty() && type == Splits) { if (!oe.empty() && type == Splits) {
gdi.fillRight(); gdi.fillRight();
gdi.addSelection("SplitPrintList", 200, 200, nullptr, L"Sträcktidslista:"); gdi.addSelection("SplitPrintList", 200, 200, ListsCB, L"Sträcktidslista:");
if (setupPrinter) {
gdi.dropLine(0.9); vector<pair<wstring, size_t>> lists;
oe.getListContainer().getLists(lists, false, false, false, true);
lists.insert(lists.begin(), make_pair(lang.tl("Standard"), -10));
lists.insert(lists.begin(), make_pair(lang.tl("Automatisk"), -11));
gdi.addItem("SplitPrintList", lists);
gdi.autoGrow("SplitPrintList");
gdi.dropLine(0.8);
gdi.addButton("EditPS", "Redigera...", ListsCB);
if (setupPrinter)
gdi.addButton("PrinterSetup", "Skrivare...", ListsCB, "Skrivarinställningar"); gdi.addButton("PrinterSetup", "Skrivare...", ListsCB, "Skrivarinställningar");
gdi.dropLine(2.8); gdi.dropLine(2.8);
}
else {
gdi.dropLine(3);
}
gdi.fillDown(); gdi.fillDown();
gdi.popX(); gdi.popX();
gdi.addString("", 10, "info:customsplitprint"); gdi.addString("", 10, "info:customsplitprint");
gdi.dropLine(); gdi.dropLine();
vector<pair<wstring, size_t>> lists;
oe.getListContainer().getLists(lists, false, false, false, true);
lists.insert(lists.begin(), make_pair(lang.tl("Standard"), -10));
gdi.addItem("SplitPrintList", lists);
wstring listId = oe.getDCI().getString("SplitPrint"); wstring listId = oe.getDCI().getString("SplitPrint");
EStdListType type = oe.getListContainer().getCodeFromUnqiueId(gdioutput::narrow(listId)); EStdListType type = EStdListType::EStdNone;
if (type == EStdListType::EStdNone) if (listId.length() > 1)
gdi.selectFirstItem("SplitPrintList"); type = oe.getListContainer().getCodeFromUnqiueId(gdioutput::narrow(listId));
gdi.setInputStatus("EditPS", type != EStdListType::EStdNone);
if (listId == L"*")
gdi.selectItemByData("SplitPrintList", -10); // Standard
else if (type == EStdListType::EStdNone)
gdi.selectFirstItem("SplitPrintList"); // Automatisk
else { else {
for (auto& t : lists) { for (auto& t : lists) {
if (type == oe.getListContainer().getType(t.second)) if (type == oe.getListContainer().getType(t.second))

View File

@ -1999,7 +1999,7 @@ void TabRunner::showVacancyList(gdioutput &gdi, const string &method, int classI
par.selection.insert(classId); par.selection.insert(classId);
oListInfo info; oListInfo info;
par.listCode = EStdStartList; par.listCode = EStdStartList;
oe->generateListInfo(par, info); oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true); oe->generateList(gdi, false, info, true);
} }
} }
@ -3067,6 +3067,21 @@ TabRunner::EconomyHandler *TabRunner::getEconomyHandler(oRunner &r) {
return ecoHandler.get(); return ecoHandler.get();
} }
void TabRunner::EconomyHandler::updateColor(gdioutput& gdi) {
int paid = oe->interpretCurrency(gdi.getText("PaidAmount"));
int fee = oe->interpretCurrency(gdi.getText("Fee"));
int cf = oe->interpretCurrency(gdi.getText("Card"));
bool invoice = gdi.getSelectedItem("PayMode").first == 1000;
auto& ii = ((InputInfo&)gdi.getBaseInfo("PaidAmount"));
if ((!invoice && paid == cf + fee) || (invoice && paid == 0))
ii.setBgColor(GDICOLOR::colorDefault);
else
ii.setBgColor(GDICOLOR::colorLightRed);
ii.refresh();
}
void TabRunner::EconomyHandler::handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) { void TabRunner::EconomyHandler::handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) {
if (type == GuiEventType::GUI_BUTTON) { if (type == GuiEventType::GUI_BUTTON) {
ButtonInfo &bi = dynamic_cast<ButtonInfo &>(info); ButtonInfo &bi = dynamic_cast<ButtonInfo &>(info);
@ -3086,10 +3101,35 @@ void TabRunner::EconomyHandler::handle(gdioutput &gdi, BaseInfo &info, GuiEventT
InputInfo &ii = dynamic_cast<InputInfo &>(info); InputInfo &ii = dynamic_cast<InputInfo &>(info);
if (ii.id == "Fee") { if (ii.id == "Fee") {
gdi.check("ModFee", ii.changed() || getRunner().hasFlag(oAbstractRunner::FlagFeeSpecified)); gdi.check("ModFee", ii.changed() || getRunner().hasFlag(oAbstractRunner::FlagFeeSpecified));
updateColor(gdi);
}
else if (ii.id == "Card") {
updateColor(gdi);
} }
else if (ii.id == "PaidAmount") { else if (ii.id == "PaidAmount") {
int paid = oe->interpretCurrency(ii.text); int paid = oe->interpretCurrency(ii.text);
gdi.setInputStatus("PayMode", paid != 0); if (paid == 0) {
gdi.selectItemByData("PayMode", 1000);
} else {
if (gdi.getSelectedItem("PayMode").first == 1000)
gdi.selectItemByData("PayMode", 0);
}
updateColor(gdi);
}
}
else if (type == GuiEventType::GUI_LISTBOX) {
ListBoxInfo& lbi = dynamic_cast<ListBoxInfo&>(info);
if (lbi.id == "PayMode") {
if (lbi.data != 1000) {
int paid = oe->interpretCurrency(gdi.getText("PaidAmount"));
if (paid == 0) {
int fee = oe->interpretCurrency(gdi.getText("Fee"));
int cf = oe->interpretCurrency(gdi.getText("Card"));
paid = cf + fee;
gdi.setText("PaidAmount", oe->formatCurrency(paid), true);
}
}
updateColor(gdi);
} }
} }
} }
@ -3108,7 +3148,7 @@ void TabRunner::EconomyHandler::save(gdioutput &gdi) {
} }
r.getDI().setInt("Fee", fee); r.getDI().setInt("Fee", fee);
int cf = oe->interpretCurrency(gdi.getText("Card")); int cf = oe->interpretCurrency(gdi.getText("Card"));
if (cf > 0 || cf == 0 && r.getDCI().getInt("CardFee") != -1) if (cf > 0 || (cf == 0 && r.getDCI().getInt("CardFee") != -1))
r.getDI().setInt("CardFee", cf); r.getDI().setInt("CardFee", cf);
int paid = oe->interpretCurrency(gdi.getText("PaidAmount")); int paid = oe->interpretCurrency(gdi.getText("PaidAmount"));
r.getDI().setInt("Paid", paid); r.getDI().setInt("Paid", paid);
@ -3138,24 +3178,26 @@ void TabRunner::loadEconomy(gdioutput &gdi, oRunner &r) {
gdi.dropLine(); gdi.dropLine();
gdi.fillRight(); gdi.fillRight();
gdi.addInput("Fee", oe->formatCurrency(r.getDCI().getInt("Fee")), 5, 0, L"Avgift:").setHandler(h); gdi.addInput("Fee", oe->formatCurrency(r.getDCI().getInt("Fee")), 6, 0, L"Avgift:").setHandler(h);
int cf = r.getDCI().getInt("CardFee"); int cf = r.getDCI().getInt("CardFee");
if (cf == -1) // Borrowed, zero fee if (cf == -1) // Borrowed, zero fee
cf = 0; cf = 0;
gdi.addInput("Card", oe->formatCurrency(cf), 5, 0, L"Brickhyra:"); gdi.addInput("Card", oe->formatCurrency(cf), 6, 0, L"Brickhyra:").setHandler(h);
int paid = r.getDCI().getInt("Paid"); int paid = r.getDCI().getInt("Paid");
gdi.addInput("PaidAmount", oe->formatCurrency(paid), 5, 0, L"Betalat:").setHandler(h); gdi.addInput("PaidAmount", oe->formatCurrency(paid), 6, 0, L"Betalat:").setHandler(h);
gdi.fillDown(); gdi.fillDown();
gdi.dropLine(); gdi.dropLine();
vector< pair<wstring, size_t> > pm; vector< pair<wstring, size_t> > pm;
oe->getPayModes(pm); oe->getPayModes(pm);
int mypm = r.getDCI().getInt("PayMode"); int mypm = r.getDCI().getInt("PayMode");
//pm.insert(pm.begin(), make_pair(lang.tl(L"Faktureras"), 1000)); if (paid == 0)
gdi.addSelection("PayMode", 110, 100, SportIdentCB); mypm = 1000;
pm.insert(pm.begin(), make_pair(lang.tl(L"Faktureras"), 1000));
gdi.addSelection("PayMode", 110, 100).setHandler(h);
gdi.addItem("PayMode", pm); gdi.addItem("PayMode", pm);
gdi.selectItemByData("PayMode", mypm);
gdi.autoGrow("PayMode"); gdi.autoGrow("PayMode");
gdi.setInputStatus("PayMode", paid != 0); gdi.selectItemByData("PayMode", mypm);
gdi.dropLine(); gdi.dropLine();
gdi.popX(); gdi.popX();

View File

@ -99,6 +99,7 @@ private:
int runnerId; int runnerId;
oEvent *oe; oEvent *oe;
oRunner &getRunner() const; oRunner &getRunner() const;
void updateColor(gdioutput& gdi);
public: public:
void init(oRunner &r); void init(oRunner &r);
void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type); void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type);

View File

@ -634,6 +634,7 @@ int TabSI::siCB(gdioutput& gdi, int type, void* data)
gdi.addButton("SavePunches", "Spara", SportIdentCB).setExtra(origin); gdi.addButton("SavePunches", "Spara", SportIdentCB).setExtra(origin);
gdi.addButton("Cancel", "Avbryt", SportIdentCB).setExtra(origin); gdi.addButton("Cancel", "Avbryt", SportIdentCB).setExtra(origin);
gdi.fillDown(); gdi.fillDown();
gdi.scrollToBottom();
gdi.popX(); gdi.popX();
} }
else { else {
@ -1853,25 +1854,33 @@ void TabSI::showReadPunches(gdioutput& gdi, vector<PunchInfo>& punches, set<stri
int yp = gdi.getCY(); int yp = gdi.getCY();
int xp = gdi.getCX(); int xp = gdi.getCX();
dates.clear(); dates.clear();
vector<int> off = { 40, 100, 280, 360 };
int margin = gdi.scaleLength(5);
for (int& o : off)
o = gdi.scaleLength(o);
for (size_t k = 0; k < punches.size(); k++) { for (size_t k = 0; k < punches.size(); k++) {
if (k % 5 == 0)
yp += gdi.scaleLength(6);
sprintf_s(bf, "%d.", int(k + 1)); sprintf_s(bf, "%d.", int(k + 1));
gdi.addStringUT(yp, xp, 0, bf); gdi.addStringUT(yp, xp, 0, bf);
pRunner r = oe->getRunnerByCardNo(punches[k].card, punches[k].time, oEvent::CardLookupProperty::Any); pRunner r = oe->getRunnerByCardNo(punches[k].card, punches[k].time, oEvent::CardLookupProperty::Any);
sprintf_s(bf, "%d", punches[k].card); sprintf_s(bf, "%d", punches[k].card);
gdi.addStringUT(yp, xp + 40, 0, bf, 240); gdi.addStringUT(yp, xp + off[0], 0, bf, off[1]-off[0] + margin);
if (r != 0) if (r != 0)
gdi.addStringUT(yp, xp + 100, 0, r->getName(), 170); gdi.addStringUT(yp, xp + off[1], 0, r->getName(), off[2] - off[1] + margin);
if (punches[k].date[0] != 0) { if (punches[k].date[0] != 0) {
gdi.addStringUT(yp, xp + 280, 0, punches[k].date, 75); gdi.addStringUT(yp, xp + off[2], 0, punches[k].date, off[3] - off[2] + margin);
dates.insert(punches[k].date); dates.insert(punches[k].date);
} }
if (punches[k].time > 0) if (punches[k].time > 0)
gdi.addStringUT(yp, xp + 360, 0, oe->getAbsTime(punches[k].time)); gdi.addStringUT(yp, xp + off[3], 0, oe->getAbsTime(punches[k].time));
else else
gdi.addStringUT(yp, xp + 360, 0, makeDash(L"-")); gdi.addStringUT(yp, xp + off[3], 0, makeDash(L"-"));
yp += gdi.getLineHeight(); yp += gdi.getLineHeight();
} }
@ -1882,18 +1891,25 @@ void TabSI::showReadCards(gdioutput& gdi, vector<SICard>& cards)
char bf[64]; char bf[64];
int yp = gdi.getCY(); int yp = gdi.getCY();
int xp = gdi.getCX(); int xp = gdi.getCX();
vector<int> off = { 40, 100, 300 };
int margin = gdi.scaleLength(5);
for (int& o : off)
o = gdi.scaleLength(o);
for (size_t k = 0; k < cards.size(); k++) { for (size_t k = 0; k < cards.size(); k++) {
if (k % 5 == 0)
yp += gdi.scaleLength(6);
sprintf_s(bf, "%d.", int(k + 1)); sprintf_s(bf, "%d.", int(k + 1));
gdi.addStringUT(yp, xp, 0, bf); gdi.addStringUT(yp, xp, 0, bf);
pRunner r = oe->getRunnerByCardNo(cards[k].CardNumber, 0, oEvent::CardLookupProperty::Any); pRunner r = oe->getRunnerByCardNo(cards[k].CardNumber, 0, oEvent::CardLookupProperty::Any);
sprintf_s(bf, "%d", cards[k].CardNumber); sprintf_s(bf, "%d", cards[k].CardNumber);
gdi.addStringUT(yp, xp + 40, 0, bf, 240); gdi.addStringUT(yp, xp + off[0], 0, bf, off[1] - off[0] + margin);
if (r != 0) if (r != 0)
gdi.addStringUT(yp, xp + 100, 0, r->getName(), 240); gdi.addStringUT(yp, xp + off[1], 0, r->getName(), off[2] - off[1] + margin);
gdi.addStringUT(yp, xp + 300, 0, oe->getAbsTime(cards[k].FinishPunch.Time)); gdi.addStringUT(yp, xp + off[2], 0, oe->getAbsTime(cards[k].FinishPunch.Time));
yp += gdi.getLineHeight(); yp += gdi.getLineHeight();
} }
} }
@ -1914,10 +1930,16 @@ bool TabSI::loadPage(gdioutput& gdi) {
oe->checkDB(); oe->checkDB();
gdi.setData("SIPageLoaded", 1); gdi.setData("SIPageLoaded", 1);
if (!gSI) { if (!gSI)
getSI(gdi); getSI(gdi);
if (oe->isClient())
if (firstLoadedAfterNew) {
if (oe->getNumRunners() == 0)
interactiveReadout = true;
else if (oe->isClient())
interactiveReadout = false; interactiveReadout = false;
firstLoadedAfterNew = false;
} }
#ifdef _DEBUG #ifdef _DEBUG
gdi.fillRight(); gdi.fillRight();
@ -3904,6 +3926,11 @@ void TabSI::EditCardData::handle(gdioutput& gdi, BaseInfo& info, GuiEventType ty
} }
void TabSI::printCard(gdioutput& gdi, int lineBreak, int cardId, SICard* crdRef, bool forPrinter) const { void TabSI::printCard(gdioutput& gdi, int lineBreak, int cardId, SICard* crdRef, bool forPrinter) const {
const bool wideFormat = oe->getPropertyInt("WideSplitFormat", 0) == 1;
if (!wideFormat && forPrinter)
gdi.setCX(10);
if (crdRef == nullptr) if (crdRef == nullptr)
crdRef = &getCard(cardId); crdRef = &getCard(cardId);
@ -4242,6 +4269,7 @@ void TabSI::StoredStartInfo::clear() {
} }
void TabSI::clearCompetitionData() { void TabSI::clearCompetitionData() {
firstLoadedAfterNew = true;
printSplits = false; printSplits = false;
interactiveReadout = oe->getPropertyInt("Interactive", 1) != 0; interactiveReadout = oe->getPropertyInt("Interactive", 1) != 0;
useDatabase = oe->getPropertyInt("Database", 1) != 0; useDatabase = oe->getPropertyInt("Database", 1) != 0;

View File

@ -46,9 +46,6 @@ public:
void setMode(SIMode m) { mode = m; } void setMode(SIMode m) { mode = m; }
private: private:
/** Try to automatcally assign a class to runner (if none is given) /** Try to automatcally assign a class to runner (if none is given)
Return true if runner has a class on exist */ Return true if runner has a class on exist */
bool autoAssignClass(pRunner r, const SICard &sic); bool autoAssignClass(pRunner r, const SICard &sic);
@ -70,6 +67,7 @@ private:
bool manualInput; bool manualInput;
bool multipleStarts = false; bool multipleStarts = false;
bool firstLoadedAfterNew = true;
PrinterObject splitPrinter; PrinterObject splitPrinter;
list< pair<unsigned, int> > printPunchRunnerIdQueue; list< pair<unsigned, int> > printPunchRunnerIdQueue;
void addToPrintQueue(pRunner r); void addToPrintQueue(pRunner r);

View File

@ -461,7 +461,7 @@ void TabSpeaker::drawTimeLine(gdioutput &gdi) {
gdi.addItem("WatchNumber", lang.tl("X senaste#10"), 10); gdi.addItem("WatchNumber", lang.tl("X senaste#10"), 10);
gdi.addItem("WatchNumber", lang.tl("X senaste#20"), 20); gdi.addItem("WatchNumber", lang.tl("X senaste#20"), 20);
gdi.addItem("WatchNumber", lang.tl("X senaste#50"), 50); gdi.addItem("WatchNumber", lang.tl("X senaste#50"), 50);
gdi.addItem("WatchNumber", L"Alla", 0); gdi.addItem("WatchNumber", lang.tl("Alla"), 0);
gdi.selectItemByData("WatchNumber", watchNumber); gdi.selectItemByData("WatchNumber", watchNumber);
gdi.dropLine(2); gdi.dropLine(2);
gdi.popX(); gdi.popX();

View File

@ -525,8 +525,34 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
return true; return true;
} }
int TabTeam::teamCB(gdioutput &gdi, int type, void *data) wstring getForking(pClass pc, int key, int maxLen) {
{ wstring crsList;
bool hasCrs = false;
for (size_t k = 0; k < pc->getNumStages(); k++) {
pCourse crs = pc->getCourse(k, key);
wstring cS;
if (crs != 0) {
cS = crs->getName();
hasCrs = true;
}
else
cS = makeDash(L"-");
if (!crsList.empty())
crsList += L", ";
crsList += cS;
if (hasCrs && crsList.length() > maxLen) {
return crsList;
}
}
if (!hasCrs)
crsList.clear();
return crsList;
}
int TabTeam::teamCB(gdioutput &gdi, int type, void *data) {
if (type==GUI_BUTTON) { if (type==GUI_BUTTON) {
ButtonInfo bi=*(ButtonInfo *)data; ButtonInfo bi=*(ButtonInfo *)data;
@ -712,12 +738,14 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
gdi.dropLine(); gdi.dropLine();
gdi.addSelection("ForkKey", 100, 400, 0, L"Gafflingsnyckel:"); gdi.addSelection("ForkKey", 100, 400, 0, L"Gafflingsnyckel:");
int nf = pc->getNumForks(); int nf = pc->getNumForks();
vector< pair<wstring, size_t> > keys; vector<pair<wstring, size_t>> keys;
keys.reserve(nf);
for (int f = 0; f < nf; f++) { for (int f = 0; f < nf; f++) {
keys.push_back( make_pair(itow(f+1), f)); keys.push_back(make_pair(itow(f+1) + L": " + getForking(pc, f+1, 30), f));
} }
int currentKey = max(t->getStartNo()-1, 0) % nf; int currentKey = max(t->getStartNo()-1, 0) % nf;
gdi.addItem("ForkKey", keys); gdi.addItem("ForkKey", keys);
gdi.autoGrow("ForkKey");
gdi.selectItemByData("ForkKey", currentKey); gdi.selectItemByData("ForkKey", currentKey);
gdi.dropLine(0.9); gdi.dropLine(0.9);
@ -1315,8 +1343,8 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
if (numF>1 && t) { if (numF>1 && t) {
gdi.addString ("", 1, "Gafflingsnyckel X#" + itos(1+(max(t->getStartNo()-1, 0) % numF))).setColor(colorGreen); gdi.addString ("", 1, "Gafflingsnyckel X#" + itos(1+(max(t->getStartNo()-1, 0) % numF))).setColor(colorGreen);
wstring crsList; wstring crsList = getForking(pc, t->getStartNo(), 50);
bool hasCrs = false; /*bool hasCrs = false;
for (size_t k = 0; k < pc->getNumStages(); k++) { for (size_t k = 0; k < pc->getNumStages(); k++) {
pCourse crs = pc->getCourse(k, t->getStartNo()); pCourse crs = pc->getCourse(k, t->getStartNo());
wstring cS; wstring cS;
@ -1338,9 +1366,10 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
} }
if (hasCrs && !crsList.empty()) { if (hasCrs && !crsList.empty()) {
gdi.addStringUT(0, crsList); gdi.addStringUT(0, crsList);
} }*/
if (hasCrs) { if (!crsList.empty()) {
gdi.addStringUT(0, crsList);
gdi.dropLine(0.5); gdi.dropLine(0.5);
gdi.setRestorePoint("ChangeKey"); gdi.setRestorePoint("ChangeKey");
gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB); gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB);

View File

@ -53,15 +53,28 @@ extern gdioutput *gdi_main;
static int wtoi(const wstring &sp) { static int wtoi(const wstring &sp) {
return _wtoi(sp.c_str()); return _wtoi(sp.c_str());
} }
csvparser::csvparser() csvparser::csvparser() {
{
LineNumber=0; LineNumber=0;
} }
csvparser::~csvparser() class CSVLineWrapper {
{ const vector<wstring> &data;
int row;
public:
CSVLineWrapper(int row, const vector<wstring>& data) : data(data), row(row) {
}
} const wstring& operator[](int i) const {
if (i < 0 || i >= data.size()) {
throw meosException("Invalid CSV file. Incorrect data specification on line X" + itos(row));
}
return data[i];
}
size_t size() const { return data.size(); }
};
csvparser::~csvparser() = default;
csvparser::CSV csvparser::iscsv(const wstring &file) { csvparser::CSV csvparser::iscsv(const wstring &file) {
ifstream fin(file); ifstream fin(file);
@ -121,8 +134,7 @@ RunnerStatus ConvertOEStatus(int i)
//Stno;Descr;Block;nc;Start;Time;Classifier;Club no.;Cl.name;City;Nat;Cl. no.;Short;Long;Legs;Num1;Num2;Num3;Text1;Text2;Text3;Start fee;Paid;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;(may be more) ... //Stno;Descr;Block;nc;Start;Time;Classifier;Club no.;Cl.name;City;Nat;Cl. no.;Short;Long;Legs;Num1;Num2;Num3;Text1;Text2;Text3;Start fee;Paid;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;Surname;First name;YB;S;Start;Finish;Time;Classifier;Chip;Rented;Database Id;(may be more) ...
bool csvparser::importOS_CSV(oEvent &event, const wstring &file) bool csvparser::importOS_CSV(oEvent &oe, const wstring &file) {
{
enum {OSstno=0, OSdesc=1, OSstart=4, OStime=5, OSstatus=6, OSclubno=7, OSclub=9, enum {OSstno=0, OSdesc=1, OSstart=4, OStime=5, OSstatus=6, OSclubno=7, OSclub=9,
OSnat=10, OSclassno=11, OSclass=12, OSlegs=14, OSfee=21, OSpaid=22}; OSnat=10, OSclassno=11, OSclass=12, OSlegs=14, OSfee=21, OSpaid=22};
@ -132,102 +144,112 @@ bool csvparser::importOS_CSV(oEvent &event, const wstring &file)
enum {OSRsname=0, OSRfname=1, OSRyb=2, OSRsex=3, OSRstart=4, enum {OSRsname=0, OSRfname=1, OSRyb=2, OSRsex=3, OSRstart=4,
OSRfinish=5, OSRstatus=7, OSRcard=8, OSRrentcard=9}; OSRfinish=5, OSRstatus=7, OSRcard=8, OSRrentcard=9};
nimport=0;
list< vector<wstring> > allLines;
parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin();
oe.noReevaluateOperation([&]() {
nimport = 0;
list<vector<wstring>> allLines;
parse(file, allLines);
auto it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
int line = 1;
set<wstring> matchedClasses; set<wstring> matchedClasses;
// Skip first line // Skip first line
while (++it != allLines.end()) { while (++it != allLines.end()) {
//fin.getline(bf, 1024); CSVLineWrapper sp(++line, *it);
//split(bf, sp);
const vector<wstring> &sp = *it;
if (sp.size()>20 && sp[OSclub].size()>0) if (sp.size() > 20 && sp[OSclub].size() > 0)
{ {
nimport++; nimport++;
//Create club with this club number... //Create club with this club number...
int ClubId=wtoi(sp[OSclubno]); int ClubId = wtoi(sp[OSclubno]);
pClub pclub=event.getClubCreate(ClubId, sp[OSclub]); pClub pclub = oe.getClubCreate(ClubId, sp[OSclub]);
if (pclub){ if (pclub) {
pclub->getDI().setString("Nationality", sp[OSnat]); pclub->getDI().setString("Nationality", sp[OSnat]);
pclub->synchronize(true); pclub->synchronize(true);
} }
//Create class with this class number... //Create class with this class number...
int ClassId=wtoi(sp[OSclassno]); int ClassId = wtoi(sp[OSclassno]);
event.getClassCreate(ClassId, sp[OSclass], matchedClasses); oe.getClassCreate(ClassId, sp[OSclass], matchedClasses);
//Club is autocreated... //Club is autocreated...
pTeam team=event.addTeam(sp[OSclub] + L" " + sp[OSdesc], ClubId, ClassId); pTeam team = oe.addTeam(sp[OSclub] + L" " + sp[OSdesc], ClubId, ClassId);
team->setEntrySource(externalSourceId); team->setEntrySource(externalSourceId);
team->setStartNo(wtoi(sp[OSstno]), oBase::ChangeType::Update); team->setStartNo(wtoi(sp[OSstno]), oBase::ChangeType::Update);
if (sp[12].length()>0) if (sp[12].length() > 0)
team->setStatus( ConvertOEStatus( wtoi(sp[OSstatus]) ), true, oBase::ChangeType::Update); team->setStatus(ConvertOEStatus(wtoi(sp[OSstatus])), true, oBase::ChangeType::Update);
team->setStartTime(event.convertAbsoluteTime(sp[OSstart]), true, oBase::ChangeType::Update); team->setStartTime(oe.convertAbsoluteTime(sp[OSstart]), true, oBase::ChangeType::Update);
if (sp[OStime].length()>0) if (sp[OStime].length() > 0)
team->setFinishTime( event.convertAbsoluteTime(sp[OSstart])+event.convertAbsoluteTime(sp[OStime])-event.getZeroTimeNum() ); team->setFinishTime(oe.convertAbsoluteTime(sp[OSstart]) + oe.convertAbsoluteTime(sp[OStime]) - oe.getZeroTimeNum());
if (team->getStatus()==StatusOK && team->getFinishTime()==0) if (team->getStatus() == StatusOK && team->getFinishTime() == 0)
team->setStatus(StatusUnknown, true, oBase::ChangeType::Update); team->setStatus(StatusUnknown, true, oBase::ChangeType::Update);
unsigned rindex=Offset; unsigned rindex = Offset;
oDataInterface teamDI=team->getDI(); oDataInterface teamDI = team->getDI();
teamDI.setInt("Fee", wtoi(sp[OSfee])); teamDI.setInt("Fee", wtoi(sp[OSfee]));
teamDI.setInt("Paid", wtoi(sp[OSpaid])); teamDI.setInt("Paid", wtoi(sp[OSpaid]));
teamDI.setString("Nationality", sp[OSnat]); teamDI.setString("Nationality", sp[OSnat]);
//Import runners! //Import runners!
int runner=0; int runner = 0;
while( (rindex+OSRrentcard)<sp.size() && sp[rindex+OSRfname].length()>0 ){ while ((rindex + OSRrentcard) < sp.size() && sp[rindex + OSRfname].length() > 0) {
int cardNo = wtoi(sp[rindex+OSRcard]); int cardNo = wtoi(sp[rindex + OSRcard]);
wstring sname = sp[rindex+OSRsname] + L", " + sp[rindex+OSRfname]; wstring sname = sp[rindex + OSRsname] + L", " + sp[rindex + OSRfname];
pRunner r = event.addRunner(sname, ClubId, pRunner r = oe.addRunner(sname, ClubId,
ClassId, cardNo, sp[rindex + OSRyb], false); ClassId, cardNo, sp[rindex + OSRyb], false);
r->setEntrySource(externalSourceId); r->setEntrySource(externalSourceId);
oDataInterface DI=r->getDI(); oDataInterface DI = r->getDI();
r->setSex(interpretSex(sp[rindex + OSRsex])); r->setSex(interpretSex(sp[rindex + OSRsex]));
DI.setString("Nationality", sp[OSnat]); DI.setString("Nationality", sp[OSnat]);
if (sp[rindex+OSRrentcard].length() > 0) if (sp[rindex + OSRrentcard].length() > 0)
DI.setInt("CardFee", event.getDCI().getInt("CardFee")); DI.setInt("CardFee", oe.getDCI().getInt("CardFee"));
//r->setCardNo(atoi(sp[rindex+OSRcard]), false); //r->setCardNo(atoi(sp[rindex+OSRcard]), false);
r->setStartTime(event.convertAbsoluteTime(sp[rindex+OSRstart]), true, oBase::ChangeType::Update); r->setStartTime(oe.convertAbsoluteTime(sp[rindex + OSRstart]), true, oBase::ChangeType::Update);
r->setFinishTime( event.convertAbsoluteTime(sp[rindex+OSRfinish]) ); r->setFinishTime(oe.convertAbsoluteTime(sp[rindex + OSRfinish]));
if (sp[rindex+OSRstatus].length()>0) if (sp[rindex + OSRstatus].length() > 0)
r->setStatus( ConvertOEStatus( wtoi(sp[rindex+OSRstatus]) ), true, oBase::ChangeType::Update, false); r->setStatus(ConvertOEStatus(wtoi(sp[rindex + OSRstatus])), true, oBase::ChangeType::Update, false);
if (r->getStatus()==StatusOK && r->getRunningTime(false)==0) if (r->getStatus() == StatusOK && r->getRunningTime(false) == 0)
r->setStatus(StatusUnknown, true, oBase::ChangeType::Update, false); r->setStatus(StatusUnknown, true, oBase::ChangeType::Update, false);
r->addClassDefaultFee(false); r->addClassDefaultFee(false);
team->setRunner(runner++, r, true); team->setRunner(runner++, r, true);
rindex+=PostSize; rindex += PostSize;
} }
//int nrunners=team->GetNumRunners(); //int nrunners=team->GetNumRunners();
pClass pc=event.getClass(ClassId); pClass pc = oe.getClass(ClassId);
int teamId = team->getId();
if (pc && runner>(int)pc->getNumStages()) if (pc && runner > (int)pc->getNumStages()) {
pc->setNumStages(runner); oe.setupRelay(*pc, oEvent::PRelay, runner, oe.getAbsTime(timeConstHour));
}
team = oe.getTeam(teamId);
if (team)
team->evaluate(oBase::ChangeType::Update); team->evaluate(oBase::ChangeType::Update);
} }
} }
fin.close(); fin.close();
});
oe.reEvaluateAll({}, true);
return true; return true;
} }
@ -241,15 +263,20 @@ bool csvparser::importOE_CSV(oEvent &event, const wstring &file) {
OErent=35, OEfee=36, OEpaid=37, OEcourseno=38, OEcourse=39, OErent=35, OEfee=36, OEpaid=37, OEcourseno=38, OEcourse=39,
OElength=40}; OElength=40};
list< vector<wstring> > allLines; list<vector<wstring>> allLines;
parse(file, allLines); parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin(); auto it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
int line = 0;
set<wstring> matchedClasses; set<wstring> matchedClasses;
// Skip first line // Skip first line
nimport=0; nimport=0;
while (++it != allLines.end()) { while (++it != allLines.end()) {
const vector<wstring> &sp = *it; CSVLineWrapper sp(++line, *it);
if (sp.size()>20) { if (sp.size()>20) {
nimport++; nimport++;
@ -535,10 +562,10 @@ int csvparser::split(wchar_t *line, vector<wchar_t *> &split_vector)
bool csvparser::importOCAD_CSV(oEvent &event, const wstring &file, bool addClasses) { bool csvparser::importOCAD_CSV(oEvent &event, const wstring &file, bool addClasses) {
list< vector<wstring> > allLines; list< vector<wstring> > allLines;
parse(file, allLines); parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin(); auto it = allLines.begin();
int line = 0;
while(it != allLines.end()) { while(it != allLines.end()) {
const vector<wstring> &sp = *it; CSVLineWrapper sp(++line, *it);
++it; ++it;
if (sp.size()>7) { if (sp.size()>7) {
@ -660,14 +687,18 @@ bool csvparser::importRAID(oEvent &event, const wstring &file)
enum {RAIDid=0, RAIDteam=1, RAIDcity=2, RAIDedate=3, RAIDclass=4, enum {RAIDid=0, RAIDteam=1, RAIDcity=2, RAIDedate=3, RAIDclass=4,
RAIDclassid=5, RAIDrunner1=6, RAIDrunner2=7, RAIDcanoe=8}; RAIDclassid=5, RAIDrunner1=6, RAIDrunner2=7, RAIDcanoe=8};
list< vector<wstring> > allLines; list<vector<wstring>> allLines;
parse(file, allLines); parse(file, allLines);
set<wstring> matchedClasses; set<wstring> matchedClasses;
list< vector<wstring> >::iterator it = allLines.begin(); list<vector<wstring>>::iterator it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
nimport=0; nimport=0;
int line = 1;
while (++it != allLines.end()) { while (++it != allLines.end()) {
const vector<wstring> &sp = *it; CSVLineWrapper sp(++line, *it);
if (sp.size()>7) { if (sp.size()>7) {
nimport++; nimport++;
@ -710,7 +741,7 @@ bool csvparser::importRAID(oEvent &event, const wstring &file)
return true; return true;
} }
int csvparser::selectPunchIndex(const wstring &competitionDate, const vector<wstring> &sp, int csvparser::selectPunchIndex(const wstring &competitionDate, const CSVLineWrapper &sp,
int &cardIndex, int &timeIndex, int &dateIndex, int &cardIndex, int &timeIndex, int &dateIndex,
wstring &processedTime, wstring &processedDate) { wstring &processedTime, wstring &processedDate) {
int ci = -1; int ci = -1;
@ -768,22 +799,11 @@ int csvparser::selectPunchIndex(const wstring &competitionDate, const vector<wst
bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<PunchInfo> &punches) bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<PunchInfo> &punches)
{ {
punches.clear(); punches.clear();
/* fin.clear(); list<vector<wstring>> allLines;
fin.open(file);
if (!fin.good())
return false;
*/
list< vector<wstring> > allLines;
parse(file, allLines); parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin(); auto it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
//const size_t siz = 1024 * 1;
//char bf[siz];
//string bfs;
//fin.getline(bf, siz);
//std::getline(fin, bfs);
nimport=0; nimport=0;
int cardIndex = -1; int cardIndex = -1;
@ -792,19 +812,9 @@ bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<Punc
wstring processedTime, processedDate; wstring processedTime, processedDate;
const wstring date = oe.getDate(); const wstring date = oe.getDate();
//vector<char *> sp; int line = 0;
while (++it != allLines.end()) { while (++it != allLines.end()) {
const vector<wstring> &sp = *it; CSVLineWrapper sp(++line, *it);
//if (fin.fail())
// throw meosException("Reading file failed.");
//fin.getline(bf, siz);
//std::getline(fin, bfs);
/*sp.clear();
char *bf = (char *)bfs.c_str();
split(bf, sp);
*/
int ret = selectPunchIndex(date, sp, cardIndex, timeIndex, dateIndex, int ret = selectPunchIndex(date, sp, cardIndex, timeIndex, dateIndex,
processedTime, processedDate); processedTime, processedDate);
@ -818,7 +828,6 @@ bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<Punc
PunchInfo pi; PunchInfo pi;
pi.card = card; pi.card = card;
pi.time = time; pi.time = time;
//string pd(processedDate.begin(), processedDate.end());
string pd = gdioutput::narrow(processedDate); string pd = gdioutput::narrow(processedDate);
strncpy_s(pi.date, pd.c_str(), 26); strncpy_s(pi.date, pd.c_str(), 26);
pi.date[26] = 0; pi.date[26] = 0;
@ -840,7 +849,7 @@ int analyseSITime(const wchar_t *dow, const wchar_t *time, bool &is12Hour)
return t; return t;
} }
void csvparser::checkSIConfigHeader(const vector<wstring> &sp) { void csvparser::checkSIConfigHeader(const CSVLineWrapper &sp) {
siconfigmap.clear(); siconfigmap.clear();
if (sp.size() < 200) if (sp.size() < 200)
return; return;
@ -902,7 +911,7 @@ void csvparser::checkSIConfigHeader(const vector<wstring> &sp) {
} }
} }
const wchar_t *csvparser::getSIC(SIConfigFields sic, const vector<wstring> &sp) const { const wchar_t *csvparser::getSIC(SIConfigFields sic, const CSVLineWrapper &sp) const {
map<SIConfigFields, int>::const_iterator res = siconfigmap.find(sic); map<SIConfigFields, int>::const_iterator res = siconfigmap.find(sic);
if (res == siconfigmap.end() || size_t(res->second) >= sp.size()) if (res == siconfigmap.end() || size_t(res->second) >= sp.size())
return L""; return L"";
@ -910,7 +919,7 @@ const wchar_t *csvparser::getSIC(SIConfigFields sic, const vector<wstring> &sp)
return sp[res->second].c_str(); return sp[res->second].c_str();
} }
bool csvparser::checkSIConfigLine(const oEvent &oe, const vector<wstring> &sp, SICard &card) { bool csvparser::checkSIConfigLine(const oEvent &oe, const CSVLineWrapper &sp, SICard &card) {
if (siconfigmap.empty()) if (siconfigmap.empty())
return false; return false;
@ -998,7 +1007,7 @@ bool csvparser::checkSIConfigLine(const oEvent &oe, const vector<wstring> &sp, S
} }
bool csvparser::checkSimanLine(const oEvent &oe, const vector<wstring> &sp, SICard &card) { bool csvparser::checkSimanLine(const oEvent &oe, const CSVLineWrapper &sp, SICard &card) {
if (sp.size() <= 11) if (sp.size() <= 11)
return false; return false;
@ -1058,32 +1067,19 @@ bool csvparser::checkSimanLine(const oEvent &oe, const vector<wstring> &sp, SICa
bool csvparser::importCards(const oEvent &oe, const wstring &file, vector<SICard> &cards) bool csvparser::importCards(const oEvent &oe, const wstring &file, vector<SICard> &cards)
{ {
cards.clear(); cards.clear();
list< vector<wstring> > allLines; list<vector<wstring>> allLines;
parse(file, allLines); parse(file, allLines);
//vector<wchar_t *> sp; auto it = allLines.begin();
list< vector<wstring> >::iterator it = allLines.begin();
if (it == allLines.end()) if (it == allLines.end())
return false; return false;
// fin.clear();
// fin.open(file);
// if (!fin.good()) checkSIConfigHeader(CSVLineWrapper(1, *it));
// return false;
//[1024*16];
//int s = 1024*256;
//vector<char> bbf(s);
//char *bf = &bbf[0];
//fin.getline(bf, s);
//vector<char *> sp;
//split(bf, sp);
checkSIConfigHeader(*it);
nimport=0; nimport=0;
int line = 1;
while (++it != allLines.end()) { while (++it != allLines.end()) {
//fin.getline(bf, s); //fin.getline(bf, s);
//split(bf, sp); //split(bf, sp);
const vector<wstring> &sp = *it; CSVLineWrapper sp(++line, *it);
SICard card(ConvertedTimeStatus::Unknown); SICard card(ConvertedTimeStatus::Unknown);
@ -1192,7 +1188,7 @@ void csvparser::parseUnicode(const wstring &file, list< vector<wstring> > &data)
} }
} }
void csvparser::parse(const wstring &file, list< vector<wstring> > &data) { void csvparser::parse(const wstring &file, list<vector<wstring>> &data) {
data.clear(); data.clear();
fin.open(file); fin.open(file);

View File

@ -24,12 +24,7 @@
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#if !defined(AFX_CSVPARSER_H__FD04656A_1D2A_4E6C_BE23_BD66052E276E__INCLUDED_)
#define AFX_CSVPARSER_H__FD04656A_1D2A_4E6C_BE23_BD66052E276E__INCLUDED_
#if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000
#include <vector> #include <vector>
#include <map> #include <map>
@ -38,6 +33,8 @@ class oEvent;
struct SICard; struct SICard;
class ImportFormats; class ImportFormats;
class CSVLineWrapper;
struct PunchInfo { struct PunchInfo {
int code; int code;
int card; int card;
@ -71,13 +68,13 @@ protected:
string ErrorMessage; string ErrorMessage;
// Returns true if a SI-manager line is identified // Returns true if a SI-manager line is identified
bool checkSimanLine(const oEvent &oe, const vector<wstring> &sp, SICard &cards); bool checkSimanLine(const oEvent &oe, const CSVLineWrapper &sp, SICard &cards);
// Check and setup header for SIConfig import // Check and setup header for SIConfig import
void checkSIConfigHeader(const vector<wstring> &sp); void checkSIConfigHeader(const CSVLineWrapper &sp);
// Return true if SIConfig line was detected // Return true if SIConfig line was detected
bool checkSIConfigLine(const oEvent &oe, const vector<wstring> &sp, SICard &card); bool checkSIConfigLine(const oEvent &oe, const CSVLineWrapper &sp, SICard &card);
enum SIConfigFields { enum SIConfigFields {
sicSIID, sicSIID,
@ -97,12 +94,12 @@ protected:
}; };
map<SIConfigFields, int> siconfigmap; map<SIConfigFields, int> siconfigmap;
const wchar_t *getSIC(SIConfigFields sic, const vector<wstring> &sp) const; const wchar_t *getSIC(SIConfigFields sic, const CSVLineWrapper&sp) const;
void parseUnicode(const wstring &file, list< vector<wstring> > &data); void parseUnicode(const wstring &file, list<vector<wstring>> &data);
// Check and process a punch line // Check and process a punch line
static int selectPunchIndex(const wstring &competitionDate, const vector<wstring> &sp, static int selectPunchIndex(const wstring &competitionDate, const CSVLineWrapper &sp,
int &cardIndex, int &timeIndex, int &dateIndex, int &cardIndex, int &timeIndex, int &dateIndex,
wstring &processedTime, wstring &date); wstring &processedTime, wstring &date);
@ -153,5 +150,3 @@ public:
virtual ~csvparser(); virtual ~csvparser();
}; };
#endif // !defined(AFX_CSVPARSER_H__FD04656A_1D2A_4E6C_BE23_BD66052E276E__INCLUDED_)

View File

@ -20,6 +20,7 @@ Age above or equal implies senior/pensioner = Věk vyšší nebo roven značí s
Age below or equal implies youth = Věk nižší nebo roven značí mládež Age below or equal implies youth = Věk nižší nebo roven značí mládež
Aktivera = Aktivovat Aktivera = Aktivovat
Aktivera stöd för tider över 24 timmar = Aktivuj podporu pro běžecké časy přes 24 hodin. Aktivera stöd för tider över 24 timmar = Aktivuj podporu pro běžecké časy přes 24 hodin.
Aktivera stöd för tiondels sekunder = Aktivuj podporu sub-sekundové časomíry.
Aktuell tid = Aktuální čas Aktuell tid = Aktuální čas
AllPunches = Všechna ražení AllPunches = Všechna ražení
Alla = Vše Alla = Vše
@ -65,6 +66,7 @@ Anmälningar (IOF (xml) eller OE-CSV) = Přihlášky (IOF (xml) nebo OE-CSV)
Anmälningsavgift = Startovné Anmälningsavgift = Startovné
Anmälningsdatum = Datum přihlášky Anmälningsdatum = Datum přihlášky
Anmälningsläge = Rychlé zadávání Anmälningsläge = Rychlé zadávání
Anmälningstid = Čas přihlášení
Anonymt namn = Anonymní jméno Anonymt namn = Anonymní jméno
Anslut = Spoj Anslut = Spoj
Anslut till en server = Spoj se servrem Anslut till en server = Spoj se servrem
@ -110,6 +112,7 @@ Använd endast en bana i klassen = Použij jen jednu trať v kategorii
Använd enhets-id istället för tävlings-id = Použij ID zařízení místo ID závodu Använd enhets-id istället för tävlings-id = Použij ID zařízení místo ID závodu
Använd funktioner för fleretappsklass = Použij funkce pro více-etapové kategorie Använd funktioner för fleretappsklass = Použij funkce pro více-etapové kategorie
Använd första kontrollen som start = Použij první kontrolu jako start Använd första kontrollen som start = Použij první kontrolu jako start
Använd listan för sträcktidsutskrift = Použij sestavu pro tisk mezičasů
Använd löpardatabasen = Použij databázi závodníků Använd löpardatabasen = Použij databázi závodníků
Använd om möjligt samma dator som användes vid senaste importen = Pokud možno, použij stejný počítač, který byl použit k importu posledně Använd om möjligt samma dator som användes vid senaste importen = Pokud možno, použij stejný počítač, který byl použit k importu posledně
Använd sista kontrollen som mål = Použíj poslední kontrolu jako cíl Använd sista kontrollen som mål = Použíj poslední kontrolu jako cíl
@ -130,6 +133,7 @@ Automater = Služby
Automatic rogaining point reduction = Automatická bodová srážka pro rogaining Automatic rogaining point reduction = Automatická bodová srážka pro rogaining
Automatisera = Automatizovat Automatisera = Automatizovat
Automatisk = Automatický Automatisk = Automatický
Automatisk hyrbrickshantering genom registrerade hyrbrickor = Automatická správa půjčených čipů s použitím zaznamenaných čísel
Automatisk lottning = Losuj automaticky Automatisk lottning = Losuj automaticky
Automatisk omladdning = Automatický update Automatisk omladdning = Automatický update
Automatisk skroll = Automatický posuv Automatisk skroll = Automatický posuv
@ -141,6 +145,7 @@ Available symbols = Dostupné symboly
Avancerat = Pokročilý Avancerat = Pokročilý
Avbockade brickor = Zaškrtnuté čipy Avbockade brickor = Zaškrtnuté čipy
Avbryt = Zruš Avbryt = Zruš
Avbryt inläsning = Zruš vyčtení
Avdrag = Srážka Avdrag = Srážka
Avgift = Vklad Avgift = Vklad
Avgifter = Vklady Avgifter = Vklady
@ -188,7 +193,10 @@ Bantilldelning hänvisar till en löpare (X) som saknas i laget (Y) = Přidělen
Bantilldelning, individuell = Přiřazení tratě, jednotlivci Bantilldelning, individuell = Přiřazení tratě, jednotlivci
Bantilldelning, stafett = Přiřazení tratě, štafeta Bantilldelning, stafett = Přiřazení tratě, štafeta
Bantilldelningslista - %s = Přiřazené tratě - %s Bantilldelningslista - %s = Přiřazené tratě - %s
Basera på en tidigare tävling = Na základě předchozí soutěže
Baserad på X = Založeno na X
Basintervall (min) = Základní interval (min) Basintervall (min) = Základní interval (min)
Batteridatum = Datum baterie
Batteristatus = Stav baterie Batteristatus = Stav baterie
Begränsa antal per klass = Max. počet v kategorii Begränsa antal per klass = Max. počet v kategorii
Begränsa antal rader per sida = Limit řádek na stránce Begränsa antal rader per sida = Limit řádek na stránce
@ -231,6 +239,7 @@ Bricka X = Čip X
Bricka X används också av = Čip X je také používán Bricka X används också av = Čip X je také používán
Brickan används av X = Čip je používán X Brickan används av X = Čip je používán X
Brickan redan inläst = Čip byl již vyčten Brickan redan inläst = Čip byl již vyčten
Brickavläsning = Vyčtení čipu
Brickhantering = Spravuj čipy Brickhantering = Spravuj čipy
Brickhyra = Vklad za čip Brickhyra = Vklad za čip
Bricknr = Číslo čipu Bricknr = Číslo čipu
@ -244,9 +253,11 @@ Byt till vakansplats i rätt klass (om möjligt) = Přepni do vakantu ve správn
COM-Port = COM-Port COM-Port = COM-Port
Calculate and apply forking = Spočítej a použij větvení Calculate and apply forking = Spočítej a použij větvení
Cancel = Zrušit Cancel = Zrušit
Cannot represent ID X = Nemohu zobrazit ID 'X'
Centrera = Centrum Centrera = Centrum
Check = Check Check = Check
Check: X = Check: X Check: X = Check: X
Checkenhet = Zkontroluj jednotku
Choose result module = Zvol výsledkový modul Choose result module = Zvol výsledkový modul
ClassAvailableMaps = Dostupné mapy pro kategorii ClassAvailableMaps = Dostupné mapy pro kategorii
ClassCourseResult = Kategorie, trať, výsledek ClassCourseResult = Kategorie, trať, výsledek
@ -274,8 +285,10 @@ Climb (m) = Stoupání (m)
Club = Oddíl Club = Oddíl
Club and runner database = Databáze oddílů a závodníků Club and runner database = Databáze oddílů a závodníků
Club id number = ID číslo oddílu Club id number = ID číslo oddílu
ClubClassStartTime = Oddíl, kategorie, čas startu
ClubName = Oddíl ClubName = Oddíl
ClubRunner = Oddíl (závodník) ClubRunner = Oddíl (závodník)
ClubTeam = Oddíl (Týmy)
Clubs = Oddíly Clubs = Oddíly
CmpDate = Datum závodu CmpDate = Datum závodu
CmpName = Název závodu CmpName = Název závodu
@ -300,6 +313,7 @@ CourseClasses = Trať - kategorie
CourseClimb = Stoupání trati CourseClimb = Stoupání trati
CourseLength = Délka trati, specifická trat CourseLength = Délka trati, specifická trat
CourseName = Název trati CourseName = Název trati
CourseNumber = Číslo trati
CoursePunches = Ražení (na trati) CoursePunches = Ražení (na trati)
CourseResult = Trať, výsledek CourseResult = Trať, výsledek
CourseShortening = Zkrácení trati CourseShortening = Zkrácení trati
@ -353,6 +367,7 @@ Det finns anmälningsdata för flera etapper = Jsou zde data pro více etap
Det finns multiplia Id-nummer för personer = Pro osoby existuje několik ID Det finns multiplia Id-nummer för personer = Pro osoby existuje několik ID
Det går endast att sätta in vakanser på sträcka 1 = Můžeš přidat vakanty jen pro první úsek Det går endast att sätta in vakanser på sträcka 1 = Můžeš přidat vakanty jen pro první úsek
Det här programmet levereras utan någon som helst garanti. Programmet är = Tento program je bez záruky, poskytován tak jak je (as is). Je Det här programmet levereras utan någon som helst garanti. Programmet är = Tento program je bez záruky, poskytován tak jak je (as is). Je
Det uppskattade antalet startade lag i klassen är ett lämpligt värde = Odhadovaný počet týmů v kategorii je přijatelný
Deviation +/- from expected time on course leg = Odchylka +/- od očekávaného času na úseku trati Deviation +/- from expected time on course leg = Odchylka +/- od očekávaného času na úseku trati
Direkt tidtagning = Časomíra živě Direkt tidtagning = Časomíra živě
Direktanmälan = Rychlé zadání Direktanmälan = Rychlé zadání
@ -363,8 +378,11 @@ Do you want to clear the card memory? = Chceš vymazat obsah paměti čipu?
Don't know how to align with 'X' = Nevím jak zarovnat dle 'X' Don't know how to align with 'X' = Nevím jak zarovnat dle 'X'
Du kan använda en SI-enhet för att läsa in bricknummer = Ke čtení čísla čipu můžeš použít SI jednotku Du kan använda en SI-enhet för att läsa in bricknummer = Ke čtení čísla čipu můžeš použít SI jednotku
Du kan importera banor och klasser från OCADs exportformat = Můžeš imporovat tratě a kategorie z OCAD exportu Du kan importera banor och klasser från OCADs exportformat = Můžeš imporovat tratě a kategorie z OCAD exportu
Du kan justera tiden för en viss enhet = Můžeš upravit čas samostatné jednotky
Du måste ange minst två gafflingsvarienater = Je nutné uvést alespoň 2 varianty
Du måste välja en klass = Musíš zvolit kategorii Du måste välja en klass = Musíš zvolit kategorii
Duplicera = Kopíruj Duplicera = Kopíruj
Duplicerad nummerlapp: X, Y = Duplicitní startovní číslo: X, Y
Dölj = Schovat Dölj = Schovat
Döp om = Přejmenuj Döp om = Přejmenuj
Döp om X = Přejmenuj X Döp om X = Přejmenuj X
@ -417,13 +435,16 @@ Endast på obligatoriska sträckor = Zpracuj jen povinné úseky.
Endast tidtagning = Jen časomíra Endast tidtagning = Jen časomíra
Endast tidtagning (utan banor) = Jen časomíra (bez tratí) Endast tidtagning (utan banor) = Jen časomíra (bez tratí)
Endast tidtagning (utan banor), stafett = Jen časomíra (bez tratí), štafety Endast tidtagning (utan banor), stafett = Jen časomíra (bez tratí), štafety
Enhet = Jednotka
Enhetens ID-nummer (MAC) = ID zařízení (MAC) Enhetens ID-nummer (MAC) = ID zařízení (MAC)
Enhetskod = Kód zařízení
Enhetstyp = Typ Enhetstyp = Typ
EntryTime = Čas přihlášky EntryTime = Čas přihlášky
Error in result module X, method Y (Z) = Chyba ve výsledkovém modulu 'X', metoda 'Y'\n\nZ Error in result module X, method Y (Z) = Chyba ve výsledkovém modulu 'X', metoda 'Y'\n\nZ
Etapp = Etapa Etapp = Etapa
Etapp X = Etapa X Etapp X = Etapa X
Etappresultat = Výsledky etapy Etappresultat = Výsledky etapy
Ett långt tävlingsnamn kan ge oväntad nerskalning av utskrifter = Dlouhý název závodu může způsobit neočekávané zmenšení výtisků
Ett okänt fel inträffade = Nastala neznámá chyba Ett okänt fel inträffade = Nastala neznámá chyba
Ett startblock spänner över flera starter: X/Y = Startovní blok obsahuje vícero startů: X/Y Ett startblock spänner över flera starter: X/Y = Startovní blok obsahuje vícero startů: X/Y
Ett startintervall måste vara en multipel av basintervallet = Startovní interval musí být násobkem základního intervalu Ett startintervall måste vara en multipel av basintervallet = Startovní interval musí být násobkem základního intervalu
@ -536,6 +557,7 @@ Flera banor = Vícero tratí
Flera banor / stafett / patrull / banpool = Vícero tratí / Štafeta / Družstvo / Fond tratí Flera banor / stafett / patrull / banpool = Vícero tratí / Štafeta / Družstvo / Fond tratí
Flera banor/stafett = Vícero tratí / Štafeta Flera banor/stafett = Vícero tratí / Štafeta
Flera lopp i valfri ordning = Vícero závodů v libovolném pořadí Flera lopp i valfri ordning = Vícero závodů v libovolném pořadí
Flera starter per deltagare = Několik startů na účastníka
Flytta deltagare från överfulla grupper = Přesuň závodníky z přeplněných skupin Flytta deltagare från överfulla grupper = Přesuň závodníky z přeplněných skupin
Flytta höger = Vpravo Flytta höger = Vpravo
Flytta ner = Přesuň dolů Flytta ner = Přesuň dolů
@ -701,6 +723,8 @@ IP-adress eller namn på en MySQL-server = IP addresa nebo jméno MySQL serveru
Id = Id Id = Id
Identifierar X unika inledningar på banorna = Nalezeno X jedinečných začátků tratí Identifierar X unika inledningar på banorna = Nalezeno X jedinečných začátků tratí
Ignorera startstämpling = Ignoruj ražení startu Ignorera startstämpling = Ignoruj ražení startu
Ignorerade X duplikat = Ignorováno X duplicit
Image = Obraz
Importera = Import Importera = Import
Importera IOF (xml) = Import IOF (xml) Importera IOF (xml) = Import IOF (xml)
Importera anmälda = Importuj přihlášky Importera anmälda = Importuj přihlášky
@ -770,12 +794,18 @@ Ingen löpare saknar bricka = Všichni běžci mají čip
Ingen matchar 'X' = Není shoda pro 'X' Ingen matchar 'X' = Není shoda pro 'X'
Ingen nummerlapp = Bez startovního čísla Ingen nummerlapp = Bez startovního čísla
Ingen parstart = Individualní start Ingen parstart = Individualní start
Ingen reducerad avgift = Bez sníženého poplatku
Ingen rogaining = Není rogaining Ingen rogaining = Není rogaining
Ingen[competition] = Žádný
Inget filter = Žadný filtr Inget filter = Žadný filtr
Inget nummer = žádné číslo Inget nummer = žádné číslo
Inkludera bana = Včetně trati Inkludera bana = Včetně trati
Inkludera bomanalys = S analýzou ztrátových časů
Inkludera individuellt resultat = Zahrň výsledky jednotlivců
Inkludera information om flera lopp per löpare = Zahrň informaci o vícero závodech na jednoho běžce. Inkludera information om flera lopp per löpare = Zahrň informaci o vícero závodech na jednoho běžce.
Inkludera resultat från tidigare etapper = Zahrň výsledky ze všech etap Inkludera resultat från tidigare etapper = Zahrň výsledky ze všech etap
Inkludera sträcktider = Zahrň mezičasy
Inkludera tempo = Zahrň tempo
Inkommande = Příchozí Inkommande = Příchozí
Inläst bricka ställd i kö = Čip byl zařazen do fronty Inläst bricka ställd i kö = Čip byl zařazen do fronty
Inlästa brickor = Vyčítej čipy Inlästa brickor = Vyčítej čipy
@ -923,6 +953,7 @@ Lag = Tým
Lag %d = Tým %d Lag %d = Tým %d
Lag + sträcka = Tým + úsek Lag + sträcka = Tým + úsek
Lag och stafett = Tým a štafeta Lag och stafett = Tým a štafeta
Lag utan nummerlapp: X = Tým bez start. čísla: X
Lag(flera) = Týmy Lag(flera) = Týmy
Laget 'X' saknar klass = Tým 'X' je bez kategorie Laget 'X' saknar klass = Tým 'X' je bez kategorie
Laget hittades inte = Tým nenalezen Laget hittades inte = Tým nenalezen
@ -1002,6 +1033,7 @@ Lyssna = Poslouchat
Lyssnar på X = Naslouchám X Lyssnar på X = Naslouchám X
Lägg till = Přidat Lägg till = Přidat
Lägg till alla = Přidat vše Lägg till alla = Přidat vše
Lägg till bild = Přidat obrázek
Lägg till en ny rad i tabellen (X) = Přidat řádek do tabulky (X) Lägg till en ny rad i tabellen (X) = Přidat řádek do tabulky (X)
Lägg till klasser = Přidat/Obnovit kategorie Lägg till klasser = Přidat/Obnovit kategorie
Lägg till ny = Přidat nový Lägg till ny = Přidat nový
@ -1070,6 +1102,7 @@ Mata in första nummerlappsnummer, eller blankt för att ta bort nummerlappar =
Mata in radiotider manuellt = Zadej časy rádia Mata in radiotider manuellt = Zadej časy rádia
Matched control ids (-1 for unmatched) for each team member = Spárovaná id kontrol (-1 pro chybná) u každého člena týmu Matched control ids (-1 for unmatched) for each team member = Spárovaná id kontrol (-1 pro chybná) u každého člena týmu
Max antal brickor per sida = Maximální počet čipů na stránku Max antal brickor per sida = Maximální počet čipů na stránku
Max antal gaffllingsvarianter att skapa = Maximální počet klíčů větvení
Max antal gemensamma kontroller = Maximální počet společných kontrol Max antal gemensamma kontroller = Maximální počet společných kontrol
Max parallellt startande = Max. počet souběžných startů Max parallellt startande = Max. počet souběžných startů
Max. vakanser (per klass) = Max. rezerva (pro kategorii) Max. vakanser (per klass) = Max. rezerva (pro kategorii)
@ -1119,6 +1152,7 @@ Multipel = Násobná
MySQL Server / IP-adress = MySQL Server / IP-adresa MySQL Server / IP-adress = MySQL Server / IP-adresa
Män = Muži Män = Muži
Mål = Cíl Mål = Cíl
Målenhet = Cílová jednotka
Målfil = Cílový soubor Målfil = Cílový soubor
Målstämpling saknas = Chybějící cílové ražení Målstämpling saknas = Chybějící cílové ražení
Målstämpling tillåts inte (X) = Cílové ražení zamítnuto (X) Målstämpling tillåts inte (X) = Cílové ražení zamítnuto (X)
@ -1149,6 +1183,8 @@ Normalavgift = Normální vklad
Not implemented = Není implementováno Not implemented = Není implementováno
Not yet implemented = Dosud neimplementováno Not yet implemented = Dosud neimplementováno
Nr = Číslo Nr = Číslo
NumEntries = Počet přihlášek
NumStarts = Počet startů
Number of shortenings = Počet zkrácení Number of shortenings = Počet zkrácení
Nummerlapp = Startovní číslo Nummerlapp = Startovní číslo
Nummerlapp, SI eller Namn = Startovní číslo, číslo čipu nebo jméno Nummerlapp, SI eller Namn = Startovní číslo, číslo čipu nebo jméno
@ -1294,6 +1330,7 @@ Printing failed (X: Y) Z = Tisk selhal (X: Y) Z
Prioritering = Upřednostnění Prioritering = Upřednostnění
Prisutdelningslista = Protokol vyhlášení výsledků Prisutdelningslista = Protokol vyhlášení výsledků
Programinställningar = Nastavení programu Programinställningar = Nastavení programu
Programmera stationen utan AUTOSEND = Nastav na jednotce vypnutý AUTO SEND
Prolog + jaktstart = Prolog + hendikep Prolog + jaktstart = Prolog + hendikep
Prologue + Pursuit = Prolog + hendikep Prologue + Pursuit = Prolog + hendikep
Publicera resultat = Zveřejnit výsledky Publicera resultat = Zveřejnit výsledky
@ -1350,6 +1387,8 @@ Redigera listpost = Edituj protokol
Redigera sträcklängder = Edituj délky úseků Redigera sträcklängder = Edituj délky úseků
Redigera sträcklängder för X = Edituj délky úseků pro 'X' Redigera sträcklängder för X = Edituj délky úseků pro 'X'
Reducerad avg = Snížený vkl. Reducerad avg = Snížený vkl.
Reducerad avgift = Snížený poplatek
Reducerad avgift för = Snížený poplatek za
Reduktionsmetod = Metoda snížení Reduktionsmetod = Metoda snížení
Referens = Reference Referens = Reference
Region = Oblast Region = Oblast
@ -1450,6 +1489,7 @@ Runner/team total running time = Závodník/tým celkový čas
Runner/team total status = Závodník/tým celkový status Runner/team total status = Závodník/tým celkový status
RunnerAge = Závodníkův věk RunnerAge = Závodníkův věk
RunnerBib = Závodník: Startovní číslo RunnerBib = Závodník: Startovní číslo
RunnerBirthDate = Datum narození
RunnerBirthYear = Závodníkovo datum narození RunnerBirthYear = Závodníkovo datum narození
RunnerCard = Závodník: Číslo čipu RunnerCard = Závodník: Číslo čipu
RunnerCardVoltage = Napětí karty/čipu RunnerCardVoltage = Napětí karty/čipu
@ -1527,6 +1567,7 @@ SOFT-avgift = SOFT vklad
SOFT-lottning = Švédská losovací metoda SOFT-lottning = Švédská losovací metoda
SRR Dongle = SRR dongl SRR Dongle = SRR dongl
Saknad starttid = Chybějící čas startu Saknad starttid = Chybějící čas startu
Saknat lag mellan X och Y = Chybějící tým mezi X and Y
Samlade poäng = Nasbírané body Samlade poäng = Nasbírané body
Samma = Stejný Samma = Stejný
Samma bastävling = Stejný základní závod Samma bastävling = Stejný základní závod
@ -1573,6 +1614,7 @@ Ska X raderas från tävlingen? = Chceš odebrat X ze závodu?
Skalfaktor = Měřítko Skalfaktor = Měřítko
Skapa = Vytvoř Skapa = Vytvoř
Skapa anonyma lagmedlemmar = Dosaď anonymní členy týmu Skapa anonyma lagmedlemmar = Dosaď anonymní členy týmu
Skapa en klass för varje bana = Vytvoř kategorii pro každou trať
Skapa en ny tävling med data från Eventor = Založit nový závod s daty z Eventoru Skapa en ny tävling med data från Eventor = Založit nový závod s daty z Eventoru
Skapa en ny, tom, tävling = Založit nový, prázdný závod Skapa en ny, tom, tävling = Založit nový, prázdný závod
Skapa fakturor = Vytvoř faktury Skapa fakturor = Vytvoř faktury
@ -1652,6 +1694,7 @@ Spara i aktuell tävling = Ulož v tomto závodě
Spara inmatade tider i tävlingen utan att tilldela starttider = Ulož časy a nastavení pro každou kategorii pro pozdější pokračování Spara inmatade tider i tävlingen utan att tilldela starttider = Ulož časy a nastavení pro každou kategorii pro pozdější pokračování
Spara inställningar = Ulož nastavení Spara inställningar = Ulož nastavení
Spara laguppställningar = Ulož složení týmů Spara laguppställningar = Ulož složení týmů
Spara oparad bricka = Ulož nespárovaný čip
Spara på disk = Ulož na disk Spara på disk = Ulož na disk
Spara som = Ulož jako Spara som = Ulož jako
Spara som PDF = Ulož do PDF Spara som PDF = Ulož do PDF
@ -1698,6 +1741,7 @@ Startbevis = Startovní certifikát
Startbevis X = Startovní certifikát X Startbevis X = Startovní certifikát X
Startblock = Startovní blok Startblock = Startovní blok
Startblock: %d = Startovní blok: %d Startblock: %d = Startovní blok: %d
Startenhet = Spustit jednotku
Startgrupp = Startovní skupina Startgrupp = Startovní skupina
Startgrupp med id X tilldelad Y finns inte = Startovní skupina s ID X definovaným pro Y neexistuje Startgrupp med id X tilldelad Y finns inte = Startovní skupina s ID X definovaným pro Y neexistuje
Startgrupper = Startovní skupiny Startgrupper = Startovní skupiny
@ -1773,6 +1817,7 @@ Sträcktider / WinSplits = Mezičasy / WinSplits
Sträcktider i kolumner (för standardpapper) = Časy ve sloupcích (pro standardní papír) Sträcktider i kolumner (för standardpapper) = Časy ve sloupcích (pro standardní papír)
Sträcktider/WinSplits = Mezičasy/WinSplits Sträcktider/WinSplits = Mezičasy/WinSplits
Sträcktidsfil = Jméno souboru Sträcktidsfil = Jméno souboru
Sträcktidslista = Výpis mezičasů
Sträcktidsutskrift = Tiskni mezičasy Sträcktidsutskrift = Tiskni mezičasy
Sträcktidsutskrift[check] = Tiskni mezičasy automaticky Sträcktidsutskrift[check] = Tiskni mezičasy automaticky
Sträcktilldelning, stafett = Přiřazení úseku, štafeta Sträcktilldelning, stafett = Přiřazení úseku, štafeta
@ -1835,9 +1880,12 @@ Team Rogaining = Týmový rogaining
Team Rogaining Collect Points = Týmový Rogaining - Nashromážděné body Team Rogaining Collect Points = Týmový Rogaining - Nashromážděné body
TeamBib = Startovní číslo týmu TeamBib = Startovní číslo týmu
TeamClub = Oddíl týmu TeamClub = Oddíl týmu
TeamCourseName = Jméno trati pro tým
TeamCourseNumber = Číslo trati pro tým
TeamFee = Startovné týmu TeamFee = Startovné týmu
TeamGlobal = Tým (kategorie spolu) TeamGlobal = Tým (kategorie spolu)
TeamGrossTime = Čas týmu před úpravou TeamGrossTime = Čas týmu před úpravou
TeamLegName = Jméno úseku
TeamLegTimeAfter = Ztráta týmu na úseku TeamLegTimeAfter = Ztráta týmu na úseku
TeamLegTimeStatus = Čas týmu / status na úseku TeamLegTimeStatus = Čas týmu / status na úseku
TeamName = Jméno týmu TeamName = Jméno týmu
@ -1948,11 +1996,14 @@ TimingTo = Jméno posl. kontroly
Tips: ställ in rätt tid innan du lägger till fler grupper = Nápověda: Vlož správné časy před přidáním dalších skupin. Tips: ställ in rätt tid innan du lägger till fler grupper = Nápověda: Vlož správné časy před přidáním dalších skupin.
Tjänstebeställningar (IOF XML) = Požadavky služeb (IOF XML) Tjänstebeställningar (IOF XML) = Požadavky služeb (IOF XML)
Tjänster (IOF XML) = Služby (IOF XML) Tjänster (IOF XML) = Služby (IOF XML)
Tolkning av radiostämplingar med okänd typ = Interpretace ražení neznámého typu
Topplista, N bästa = Top list, N nejlepších Topplista, N bästa = Top list, N nejlepších
Total = Celkem Total = Celkem
Total tävlingsavgift = Celkové vklady závodu Total tävlingsavgift = Celkové vklady závodu
Total/team result at a control = Celkový/týmový výsledek na kontrole Total/team result at a control = Celkový/týmový výsledek na kontrole
TotalCounter = Primární čítač TotalCounter = Primární čítač
TotalRunLength = Celková běžecká vzdálenost
TotalRunTime = Celková doba běhue
Totalresultat = Celkové výsledky Totalresultat = Celkové výsledky
Totalresultat - X = Celkové výsledky - X Totalresultat - X = Celkové výsledky - X
Totalt = Celkem Totalt = Celkem
@ -2001,7 +2052,9 @@ Undre gräns (år) = Od věku (roky)
Undre ålder = Nižší věk Undre ålder = Nižší věk
Unexpected Fee = Neočekávané vklady Unexpected Fee = Neočekávané vklady
Unfair control legs = Nespravedlivé úseky Unfair control legs = Nespravedlivé úseky
Unga, till och med X år = Mládež, do X let
Ungdom = Mládež Ungdom = Mládež
Ungdomar och äldre kan få reducerad avgift = Veterání a mládež mohou mít snížený poplatek
Ungdomsavgift = Vklad mládeže Ungdomsavgift = Vklad mládeže
Ungdomsklasser = mládežnické kategorie Ungdomsklasser = mládežnické kategorie
Unknown symbol X = Neznámý symbol X Unknown symbol X = Neznámý symbol X
@ -2075,6 +2128,7 @@ Varning: avgiften kan ej faktureras = Varování: nemohu vytvořit fakturu pro t
Varning: deltagare med blankt namn påträffad. MeOS kräver att alla deltagare har ett namn, och tilldelar namnet 'N.N.' = Varování: Nalezen závodník beze jména. MeOS vyžaduje jméno a přiřadil jméno 'N.N.' Varning: deltagare med blankt namn påträffad. MeOS kräver att alla deltagare har ett namn, och tilldelar namnet 'N.N.' = Varování: Nalezen závodník beze jména. MeOS vyžaduje jméno a přiřadil jméno 'N.N.'
Varning: lag utan namn påträffat. MeOS kräver att alla lag har ett namn, och tilldelar namnet 'N.N.' = Varování: Nalezen tým beze jména. MeOS vyžaduje jméno a přiřadil jméno 'N.N.' Varning: lag utan namn påträffat. MeOS kräver att alla lag har ett namn, och tilldelar namnet 'N.N.' = Varování: Nalezen tým beze jména. MeOS vyžaduje jméno a přiřadil jméno 'N.N.'
Varning: ändringar i X blev överskrivna = Varování: Změny v X byly přepsány Varning: ändringar i X blev överskrivna = Varování: Změny v X byly přepsány
Varningar i X = Varování pro X
Varvningskontroll = Společná kontrola Varvningskontroll = Společná kontrola
Varvräkning = Počet kol Varvräkning = Počet kol
Varvräkning med mellantid = Počet kol s časem navíc Varvräkning med mellantid = Počet kol s časem navíc
@ -2149,6 +2203,7 @@ Välj alla = Vyber vše
Välj alla klasser = Vyber všechny kategorie Välj alla klasser = Vyber všechny kategorie
Välj allt = Vyber vše Välj allt = Vyber vše
Välj automatiskt = Automatický výběr Välj automatiskt = Automatický výběr
Välj deltagare för förhandsgranskning = Zvol závodníka pro náhled
Välj den etapp som föregår denna tävling = Zvol předcházející etapu Välj den etapp som föregår denna tävling = Zvol předcházející etapu
Välj den etapp som kommer efter denna tävling = Zvol následující etapu Välj den etapp som kommer efter denna tävling = Zvol následující etapu
Välj en vakant plats nedan = Níže zvol pozici vakantu Välj en vakant plats nedan = Níže zvol pozici vakantu
@ -2207,6 +2262,7 @@ X platser. Startar Y = X míst. Startuje Y
X poäng fattas = X bodů chybí X poäng fattas = X bodů chybí
X rader kunde inte raderas = X řádků nemůže být smazáno X rader kunde inte raderas = X řádků nemůže být smazáno
X senaste = X nejnovějších X senaste = X nejnovějších
X stämplingar = X ražení
X är inget giltigt index = X není platný index X är inget giltigt index = X není platný index
X är inget giltigt sträcknummer = X není platné číslo úseku X är inget giltigt sträcknummer = X není platné číslo úseku
X: Y. Tryck <Enter> för att spara = X: Y. Stiskni <Enter> pro uložení X: Y. Tryck <Enter> för att spara = X: Y. Stiskni <Enter> pro uložení
@ -2295,7 +2351,6 @@ help:33940 = Importuj přihlášky ve volném textovém formátu. Uveď jméno,
help:41072 = Ke změně či odstranění ražení vyber patřičnou položku v seznamu. Můžeš doplnit chybějící ražení podle předlohy tratě. Pokud chybí cílový čas, závodník dostane status <DNF>. Pokud chybí kontrola, status je <MP>. Není možné přiřadit status odporující ražení. Pokud je naražen cíl, musíš jej změnit pro vlastní cílový čas. Podobně pro ražení startu. help:41072 = Ke změně či odstranění ražení vyber patřičnou položku v seznamu. Můžeš doplnit chybějící ražení podle předlohy tratě. Pokud chybí cílový čas, závodník dostane status <DNF>. Pokud chybí kontrola, status je <MP>. Není možné přiřadit status odporující ražení. Pokud je naražen cíl, musíš jej změnit pro vlastní cílový čas. Podobně pro ražení startu.
help:41641 = Vlož čas prvního startu a interval. Náhodné losování dává bezpodmínečně náhodné pořadí startu. ˇvédská metoda používá zvláštní pravidla k rozdělení závodníků ze stejného oddílu. Skupinový start znamená že celá kategorie startuje v malých skupinách v průběhu uvedeného intervalu (rozšířený hromadný start). V poli úsek můžeš uvést který úsek má být losován, pokud jich má kategorie vícero. help:41641 = Vlož čas prvního startu a interval. Náhodné losování dává bezpodmínečně náhodné pořadí startu. ˇvédská metoda používá zvláštní pravidla k rozdělení závodníků ze stejného oddílu. Skupinový start znamená že celá kategorie startuje v malých skupinách v průběhu uvedeného intervalu (rozšířený hromadný start). V poli úsek můžeš uvést který úsek má být losován, pokud jich má kategorie vícero.
help:425188 = Závodníky kteří neodstartovali můžeš automaticky pořešit vyčtením SI stanic (nulování/check/start) v SportIdent Config+. Ulož vyčtené jako středníkem oddělovaný textový soubor a naimportuj tento soubor do MeOSu. Závodníci z tohoto importu budou zapamatováni. Pak můžeš dát DNS status všem ostatním. Když později znova naimportuješ závodníky, můžeš u právě importovaných závodníků resetovat status (z DNS na Neznámý). help:425188 = Závodníky kteří neodstartovali můžeš automaticky pořešit vyčtením SI stanic (nulování/check/start) v SportIdent Config+. Ulož vyčtené jako středníkem oddělovaný textový soubor a naimportuj tento soubor do MeOSu. Závodníci z tohoto importu budou zapamatováni. Pak můžeš dát DNS status všem ostatním. Když později znova naimportuješ závodníky, můžeš u právě importovaných závodníků resetovat status (z DNS na Neznámý).
info:readoutbase = Aktivuj jednotku SI zvolením odpovídajícího COM-portu nebo hledáním připojených SI jednotek. Zvol Informace pro status zvoleného portu.\n\nInteraktivní vyčtení umožňuje přímé řešení problémů, jako třeba chybné číslo čipu. Nepoužívej tuto možnost, pokud jsou závodníci s potížemi obsluhováni zvlášť.\n\nKdyž chceš automaticky přidat nové závodníky, je použita databáze závodníků. Ražení je použito k nalezení (odhadnutí) správné kategorie.
help:50431 = Nyní jsi připojen k serveru. K otevření závodu na serveru - vyber jej v seznamu a klikni otevřít. K přidání závodu na server - otevři jej lokálně a zvol "pošli". Pokud jsi otevřel závod na serveru, uvidíš ostatní MeOS klienty. help:50431 = Nyní jsi připojen k serveru. K otevření závodu na serveru - vyber jej v seznamu a klikni otevřít. K přidání závodu na server - otevři jej lokálně a zvol "pošli". Pokud jsi otevřel závod na serveru, uvidíš ostatní MeOS klienty.
help:52726 = Připoj se k serveru níže.\n\nInstalace\nStáhni a nainstaluj MySQL 5 (Community Edition) z www.mysql.com. Můžeš použít výchozí nastavení. MySQL je nezbytné nainstalovat pouze na počítači hrajícím roli serveru. Když je MySQL nainstalována, spusť MySQL Command Line Client a založ uživatelský účet pro MeOS. Příkaz vypadá jako:\n\n> CREATE USER meos;\nGRANT ALL ON *.* TO meos;\n\nNyní jsi založil uživatele meos bez hesla. Níže zadej jméno serveru (možná bude nutné nakonfigurovat firewally).\n\nJako alternativu můžeš použít výchozí root účet MySQL - uživatelské jméno je 'root' a heslo je to, které bylo zadáno při instalaci MySQL. help:52726 = Připoj se k serveru níže.\n\nInstalace\nStáhni a nainstaluj MySQL 5 (Community Edition) z www.mysql.com. Můžeš použít výchozí nastavení. MySQL je nezbytné nainstalovat pouze na počítači hrajícím roli serveru. Když je MySQL nainstalována, spusť MySQL Command Line Client a založ uživatelský účet pro MeOS. Příkaz vypadá jako:\n\n> CREATE USER meos;\nGRANT ALL ON *.* TO meos;\n\nNyní jsi založil uživatele meos bez hesla. Níže zadej jméno serveru (možná bude nutné nakonfigurovat firewally).\n\nJako alternativu můžeš použít výchozí root účet MySQL - uživatelské jméno je 'root' a heslo je to, které bylo zadáno při instalaci MySQL.
help:5422 = SI jednotka nenalezena. Je připojená a spuštěná? help:5422 = SI jednotka nenalezena. Je připojená a spuštěná?
@ -2353,10 +2408,17 @@ help_autodraw = Uveď první (řádný) čas startu a nejkratší interval (v ka
help_draw = Startovky se losují ve dvou krocích. První zvolíš, které kategorie losovat a uděláš základní nastavení. Když zvolíš <Rozděl Časy>, MeOS použije tvá nastavení k rozdělení startovních úseků/slotů mezi kategoriemi. MeOS zajistí, že kategorie s podobnými tartěmi nestartují zároveň, berouc v úvahu již nalsované kategorie. Cílem je rovnoměrné rozdělení startovního pole.\n\nSpočtené rozdělení je ukázáno v tabulce, kde můžeš udělat vlastní změny nebo ponechat MeOS upravit rozdělení s ohledem na tvé změny. Pokud jsi s rozdělením spokojen, ponechej MeOS nalosovat vybrané kategorie.\n\nZákladní nastavení, které je třeba udělat, spočívá v uvedení času prvního startu a nejkratší možný interval. Maximální počet souběžně startujících určuje počet závodníků startujících ve stejný čas - větší číslo dává kratší dobu (menší hloubku) startu závodu.\n\nPodíl vakantů určuje nepřímo jejich počet. Pokud nepotřebuješ vakanty, zadej 0%. Počet očekávaných pozdních přihlášek rezervuje prostor ve startovce se zárukou, že žádný ze souběžně startujících závodníků nebude mít stejnou trať. help_draw = Startovky se losují ve dvou krocích. První zvolíš, které kategorie losovat a uděláš základní nastavení. Když zvolíš <Rozděl Časy>, MeOS použije tvá nastavení k rozdělení startovních úseků/slotů mezi kategoriemi. MeOS zajistí, že kategorie s podobnými tartěmi nestartují zároveň, berouc v úvahu již nalsované kategorie. Cílem je rovnoměrné rozdělení startovního pole.\n\nSpočtené rozdělení je ukázáno v tabulce, kde můžeš udělat vlastní změny nebo ponechat MeOS upravit rozdělení s ohledem na tvé změny. Pokud jsi s rozdělením spokojen, ponechej MeOS nalosovat vybrané kategorie.\n\nZákladní nastavení, které je třeba udělat, spočívá v uvedení času prvního startu a nejkratší možný interval. Maximální počet souběžně startujících určuje počet závodníků startujících ve stejný čas - větší číslo dává kratší dobu (menší hloubku) startu závodu.\n\nPodíl vakantů určuje nepřímo jejich počet. Pokud nepotřebuješ vakanty, zadej 0%. Počet očekávaných pozdních přihlášek rezervuje prostor ve startovce se zárukou, že žádný ze souběžně startujících závodníků nebude mít stejnou trať.
htmlhelp = HTML může být exportováno jako strukturovaná tabulka nebo jako volně formátovaný dokument (spíše podobný protokolům MeOSu). Můžeš také použít exportní šablony pro vlastní formátování: sloupce, JavaScriptové převracení stránek, automatické rolování, atd. Je možné přidat vlastní šablony přidáním '.template' souborů do datové složky MeOSu. Pokud použiješ šablonu, pak je třeba níže nastavit řadu parametrů. Přesná interpretace závisí na šabloně.\n\nPokud zvolíš <Ulož Nastavení>, protokol a jeho nastavení jsou trvale uloženy v závodě. Pak jej můžeš použít s MeOSem coby webovým servrem (Služba 'Informační Server') nebo exportovat protokol automaticky v pravidelných intervalech. htmlhelp = HTML může být exportováno jako strukturovaná tabulka nebo jako volně formátovaný dokument (spíše podobný protokolům MeOSu). Můžeš také použít exportní šablony pro vlastní formátování: sloupce, JavaScriptové převracení stránek, automatické rolování, atd. Je možné přidat vlastní šablony přidáním '.template' souborů do datové složky MeOSu. Pokud použiješ šablonu, pak je třeba níže nastavit řadu parametrů. Přesná interpretace závisí na šabloně.\n\nPokud zvolíš <Ulož Nastavení>, protokol a jeho nastavení jsou trvale uloženy v závodě. Pak jej můžeš použít s MeOSem coby webovým servrem (Služba 'Informační Server') nebo exportovat protokol automaticky v pravidelných intervalech.
info:advanceinfo = Start služby pro okamžitý přenos výsledků selhal. Výsledky budou přijaty s několika-vteřinovým zpožděním. Toto je očekávané chování když je na počítači spuštěno vícero MeOS procesů. info:advanceinfo = Start služby pro okamžitý přenos výsledků selhal. Výsledky budou přijaty s několika-vteřinovým zpožděním. Toto je očekávané chování když je na počítači spuštěno vícero MeOS procesů.
info:customsplitprint = Pro tisk mezičasů můžeš použít přizpůsobený výpis. V editoru sestav jej navrhni a použij funkci 'Pro Mezičasy'.\n\nV tabulkovém režimu můžeš zvolit, kterou sestavu má která kategorie používat.
info:mapcontrol = MeOS nemůže rozpoznat režim jednotky, dokud není přímo připojena k počítači. Tudíž k určení typu je použit zaznamenaný kód ražení. Interpretaci můžeš upravit níže. Čísla přes 30 jsou vždy interpretovány jako kontroly.\n\nDej pozor se startovním ražením; může trvale přepsat nalosované startovací časy.
info:multieventnetwork = K nastavení více než jedné etapy musíš pracovat lokálně. Ulož kopii závodu, otevři ji lokálně a převeď výsledky do další etapy. Pak uploaduj další etapu na server. info:multieventnetwork = K nastavení více než jedné etapy musíš pracovat lokálně. Ulož kopii závodu, otevři ji lokálně a převeď výsledky do další etapy. Pak uploaduj další etapu na server.
info:multiple_start = Závodník může startovat se stejným čipem vícekrát. Automatický nový záznam pro každé vyčtení.
info:nosplitprint = Nemohu otevřít danou sestavu.\n\nPoužije se výchozí.
info:pageswithcolumns = Zobraz protokol po stránkách, s udaným počtem sloupců. Automaticky obnov data po každém kole. info:pageswithcolumns = Zobraz protokol po stránkách, s udaným počtem sloupců. Automaticky obnov data po každém kole.
info:readout_action = X: Čip č. Y byl vyčten.\nRuční zásah potřebný. info:readout_action = X: Čip č. Y byl vyčten.\nRuční zásah potřebný.
info:readout_queue = X: Čip č. Y byl vyčten.\nZařazen ke zpracování. info:readout_queue = X: Čip č. Y byl vyčten.\nZařazen ke zpracování.
info:readoutbase = Aktivuj jednotku SI zvolením odpovídajícího COM-portu nebo hledáním připojených SI jednotek. Zvol Informace pro status zvoleného portu.\n\nInteraktivní vyčtení umožňuje přímé řešení problémů, jako třeba chybné číslo čipu. Nepoužívej tuto možnost, pokud jsou závodníci s potížemi obsluhováni zvlášť.\n\nKdyž chceš automaticky přidat nové závodníky, je použita databáze závodníků. Ražení je použito k nalezení (odhadnutí) správné kategorie.
info:readoutmore = Zamkni funkci aby nedošlo k nechtěným změnám.\n\nVýběr zvuku umožní signalizaci přehrávanou při vyčtení čipu.\n\nOtevři Vyčítací Okno ukáže nové okno navržené k zobrazení závodníkovi při vyčítání, ukazuje informace o posledním vyčtení.\n\nVícero startů na závodníka může být použito, pokud je na trati povoleno vícero pokusů. Nový další výsledek je vytvořen s každým vyčtením.
info:readoutwindow = Vyčítací okno zobrazuje informace z naposled vyčteného čipu.
info:runnerdbonline = Jelikož jsi připojen k serveru, není možné editovat databázi oddílů a závodníků ručně. Proveď změny dříve, než odešleš závod na server. Také je možné nahradit stávající databázi na serveru importem nové databáze (z IOF XML). info:runnerdbonline = Jelikož jsi připojen k serveru, není možné editovat databázi oddílů a závodníků ručně. Proveď změny dříve, než odešleš závod na server. Také je možné nahradit stávající databázi na serveru importem nové databáze (z IOF XML).
info:teamcourseassignment = Importovaný soubor obsahuje data větvení týmů. K jeho importu potřebuješ přípravit kompatibilní závod: \n\n1. Ujisti se, že kategorie mají správný počet kol.\n2. Zadej startovní čísla pro všechny kategorie. Použij Rychlá Nastavení na stránce Kategorie a vlož první startovní číslo v každé kategorii (při automatické volbě startovních čísel). Také můžeš napřed importovat týmy a přířadit startovní čísla jako obvykle.\n3. Naimportuje tratě. Můžeš i několikrát, pokud potřebuješ aktualizovat větvení. info:teamcourseassignment = Importovaný soubor obsahuje data větvení týmů. K jeho importu potřebuješ přípravit kompatibilní závod: \n\n1. Ujisti se, že kategorie mají správný počet kol.\n2. Zadej startovní čísla pro všechny kategorie. Použij Rychlá Nastavení na stránce Kategorie a vlož první startovní číslo v každé kategorii (při automatické volbě startovních čísel). Také můžeš napřed importovat týmy a přířadit startovní čísla jako obvykle.\n3. Naimportuje tratě. Můžeš i několikrát, pokud potřebuješ aktualizovat větvení.
info_shortening = Zvol stávající trať která zkracuje současnou trať. Vícero úrovní zkrácení je možné. info_shortening = Zvol stávající trať která zkracuje současnou trať. Vícero úrovní zkrácení je možné.
@ -2388,6 +2450,7 @@ prefsAddress = Výchozí adresa
prefsAdvancedClassSettings = Ukaž pokročilá nastavení kategorie prefsAdvancedClassSettings = Ukaž pokročilá nastavení kategorie
prefsAutoSaveTimeOut = Interval automatického zálohování (ms) prefsAutoSaveTimeOut = Interval automatického zálohování (ms)
prefsAutoTie = Spoj závodníka/čip automaticky prefsAutoTie = Spoj závodníka/čip automaticky
prefsAutoTieRent = Automatická správa zapůjčených čipů
prefsCardFee = Výchozí poplatek za čip prefsCardFee = Výchozí poplatek za čip
prefsClient = Jméno klienta v síti prefsClient = Jméno klienta v síti
prefsCodePage = Kódová tabulka pro 8-bitový text při importu/exportu. prefsCodePage = Kódová tabulka pro 8-bitový text při importu/exportu.
@ -2407,6 +2470,9 @@ prefsEMail = e-mail
prefsEliteFee = Výchozí vklad elity prefsEliteFee = Výchozí vklad elity
prefsEntryFee = Výchozí vklad prefsEntryFee = Výchozí vklad
prefsEventorBase = URL Eventoru prefsEventorBase = URL Eventoru
prefsExpResFilename = Výchozí jméno exportního souboru
prefsExpTypeIOF = Výchozí typ exportu
prefsExpWithRaceNo = Při exportu zahrň číslo závodu
prefsExportCSVSplits = Zahrň mezičasy do csv exportu prefsExportCSVSplits = Zahrň mezičasy do csv exportu
prefsExportFormat = Preferovaný exportní formát prefsExportFormat = Preferovaný exportní formát
prefsFirstInvoice = První číslo faktury prefsFirstInvoice = První číslo faktury
@ -2511,6 +2577,7 @@ växlar på X plats med tiden Y = předává jako X s časem Y
växlar på X plats, efter Y, på tiden Z = předává na X místě, po Y, s časem Z växlar på X plats, efter Y, på tiden Z = předává na X místě, po Y, s časem Z
växlar på delad X plats med tiden Y = předává jako X s časem Y växlar på delad X plats med tiden Y = předává jako X s časem Y
warn:changedtimezero = Změna počátečního času závodu s výsledky se nedoporučuje.\n\nPřeješ si přesto pokračovat? warn:changedtimezero = Změna počátečního času závodu s výsledky se nedoporučuje.\n\nPřeješ si přesto pokračovat?
warn:changeid = Položka External Id se většinou používá pro spojení s ostatními databázemi (např. přihláškové, výsledkové, ekonomické systémy). Pokud uděláš nesourodé změny, mohou vzniknout těžko pochopitelné potíže.
warn:latestarttime = Užití startovních časů více než X hodin po čase nula není doporučeno, sic starší SI čipy podporují pouze 12 hodin.\n\nChceš přesto pokračovat? warn:latestarttime = Užití startovních časů více než X hodin po čase nula není doporučeno, sic starší SI čipy podporují pouze 12 hodin.\n\nChceš přesto pokračovat?
warn:missingResult = X závodníků stále nemá výsledky a proto nejsou zahrnuti.\n\nMěl bys pořešit závodníky v lese a zbytku dát status <DNS>. warn:missingResult = X závodníků stále nemá výsledky a proto nejsou zahrnuti.\n\nMěl bys pořešit závodníky v lese a zbytku dát status <DNS>.
warn:mysqlbinlog = Výkonostní varování: Nebylo možno vypnout binární logování. Odesílání dat může být pomalé.\n\nX warn:mysqlbinlog = Výkonostní varování: Nebylo možno vypnout binární logování. Odesílání dat může být pomalé.\n\nX
@ -2526,6 +2593,7 @@ warning:has_entries = Kategorie již má své závodníky. Změna v rozdělení
warning:has_results = Kategorie již má výsledky. Změna v rozdělení úseků je v této fázi neobvyklá.\n\nChceš pokračovat? warning:has_results = Kategorie již má výsledky. Změna v rozdělení úseků je v této fázi neobvyklá.\n\nChceš pokračovat?
xml-data = xml data xml-data = xml data
Äldre protokoll = Starý protokol Äldre protokoll = Starý protokol
Äldre, från och med X år = Veteráni, X let a víc
Ändra = Změna Ändra = Změna
Ändra MeOS lokala systemegenskaper = Změň lokální systémová nastavení MeOSu Ändra MeOS lokala systemegenskaper = Změň lokální systémová nastavení MeOSu
Ändra X = Změň X Ändra X = Změň X
@ -2562,6 +2630,7 @@ xml-data = xml data
Öppen = Otevřená Öppen = Otevřená
Öppen klass = Otevřená kategorie Öppen klass = Otevřená kategorie
Öppna = Otevřít Öppna = Otevřít
Öppna avläsningsfönster = Otevři vyčítací okno
Öppna fil = Otevři soubor Öppna fil = Otevři soubor
Öppna från aktuell tävling = Otevři z tohoto závodu Öppna från aktuell tävling = Otevři z tohoto závodu
Öppna föregående = Otevři předešlý Öppna föregående = Otevři předešlý

View File

@ -19,6 +19,7 @@ Age above or equal implies senior/pensioner = Aldersgrænse for seniorer
Age below or equal implies youth = Aldersgrænse for ungdom Age below or equal implies youth = Aldersgrænse for ungdom
Aktivera = Aktivér Aktivera = Aktivér
Aktivera stöd för tider över 24 timmar = Understøt løb der varer mere end 24 timer Aktivera stöd för tider över 24 timmar = Understøt løb der varer mere end 24 timer
Aktivera stöd för tiondels sekunder = Aktiver uderstøttelse af tiendedels sekund.
Aktuell tid = Aktuel tid Aktuell tid = Aktuel tid
AllPunches = Alle stemplinger AllPunches = Alle stemplinger
Alla = Alle Alla = Alle
@ -59,11 +60,12 @@ Anmälan mottagen = Tilmelding modtaget
Anmälan måste hanteras manuellt = Tilmelding skal håndteres manuelt. Anmälan måste hanteras manuellt = Tilmelding skal håndteres manuelt.
Anmälda = Tilmeldte Anmälda = Tilmeldte
Anmälda per distrikt = Tilmeldte pr. kreds Anmälda per distrikt = Tilmeldte pr. kreds
Anmälningar (IOF (xml) eller OE-CSV) = Tilmeldinger (IOF-XML) eller OE-CSV)
Anmälningar = Tilmeldinger Anmälningar = Tilmeldinger
Anmälningar (IOF (xml) eller OE-CSV) = Tilmeldinger (IOF-XML) eller OE-CSV)
Anmälningsavgift = Startafgift Anmälningsavgift = Startafgift
Anmälningsdatum = Tilmeldingsdato Anmälningsdatum = Tilmeldingsdato
Anmälningsläge = Hurtig tilmelding Anmälningsläge = Hurtig tilmelding
Anmälningstid = Tilmeldingtidspunkt
Anonymt namn = Anonymt navn Anonymt namn = Anonymt navn
Anslut = Forbind Anslut = Forbind
Anslut till en server = Forbind til en server Anslut till en server = Forbind til en server
@ -107,6 +109,7 @@ Använd endast en bana i klassen = Brug kun en bane i klassen
Använd enhets-id istället för tävlings-id = Brug enheds-id i stedet for konkurrence-id Använd enhets-id istället för tävlings-id = Brug enheds-id i stedet for konkurrence-id
Använd funktioner för fleretappsklass = Brug funktioner for klasser med flere etapper Använd funktioner för fleretappsklass = Brug funktioner for klasser med flere etapper
Använd första kontrollen som start = Brug første postenhed som start Använd första kontrollen som start = Brug første postenhed som start
Använd listan för sträcktidsutskrift = Brug listen for stræktidsudskrift
Använd löpardatabasen = Brug løberdatabasen Använd löpardatabasen = Brug løberdatabasen
Använd om möjligt samma dator som användes vid senaste importen = Brug om muligt samme computer som blev brugt senest der blev importeret Använd om möjligt samma dator som användes vid senaste importen = Brug om muligt samme computer som blev brugt senest der blev importeret
Använd sista kontrollen som mål = Brug sidste postenhed som målpost Använd sista kontrollen som mål = Brug sidste postenhed som målpost
@ -127,16 +130,19 @@ Automater = Autofunktioner
Automatic rogaining point reduction = Beregnet pointreduktion ved rogaining Automatic rogaining point reduction = Beregnet pointreduktion ved rogaining
Automatisera = Automatiser Automatisera = Automatiser
Automatisk = Automatisk Automatisk = Automatisk
Automatisk hyrbrickshantering genom registrerade hyrbrickor = Automatisk håndtering af lejebrikker med præ-registrerede lejebrikker
Automatisk lottning = Automatisk lodtrækning Automatisk lottning = Automatisk lodtrækning
Automatisk omladdning = Automatisk opdatering Automatisk omladdning = Automatisk opdatering
Automatisk skroll = Automatisk rulning Automatisk skroll = Automatisk rulning
Automatisk utskrift / export = Automatisk udskrift / eksport
Automatisk utskrift = Automatisk udskrift Automatisk utskrift = Automatisk udskrift
Automatisk utskrift / export = Automatisk udskrift / eksport
Automatnamn = Navn på autofunktion
Av MeOS: www.melin.nu/meos = Af MeOS: www.melin.nu/meos Av MeOS: www.melin.nu/meos = Af MeOS: www.melin.nu/meos
Available symbols = Tilgængelige symboler Available symbols = Tilgængelige symboler
Avancerat = Avanceret Avancerat = Avanceret
Avbockade brickor = Afkrydsede brikker Avbockade brickor = Afkrydsede brikker
Avbryt = Afbryd Avbryt = Afbryd
Avbryt inläsning = afbryd indlæsning
Avdrag = Fradrag Avdrag = Fradrag
Avgift = Afgift Avgift = Afgift
Avgifter = Afgifter Avgifter = Afgifter
@ -161,8 +167,8 @@ Bad file format = Forkert filformat
Bakgrund = Baggrund Bakgrund = Baggrund
Bakgrundsfärg = Baggrundsfarve Bakgrundsfärg = Baggrundsfarve
Bakåt = Tilbage Bakåt = Tilbage
Bana %d = Bane %d
Bana = Bane Bana = Bane
Bana %d = Bane %d
Bana med slingor = Bane med sløjfer Bana med slingor = Bane med sløjfer
Banan används och kan inte tas bort = Banen er i brug og kan ikke fjernes Banan används och kan inte tas bort = Banen er i brug og kan ikke fjernes
Banan måste ha ett namn = Banen skal have et navn Banan måste ha ett namn = Banen skal have et navn
@ -171,8 +177,8 @@ Banan saknas = Banen mangler
Banans kontroller ger för få poäng för att täcka poängkravet = Banens poster giver ikke tilstrækkeligt med points til at dække pointkravet Banans kontroller ger för få poäng för att täcka poängkravet = Banens poster giver ikke tilstrækkeligt med points til at dække pointkravet
Bananvändning = Brug af bane Bananvändning = Brug af bane
Banmall = Baneskabelon Banmall = Baneskabelon
Banor (antal kontroller) = Baner (antal poster)
Banor = Baner Banor = Baner
Banor (antal kontroller) = Baner (antal poster)
Banor för %s, sträcka %d = Baner for %s, tur %d Banor för %s, sträcka %d = Baner for %s, tur %d
Banor, IOF (xml) = Baner, (IOF-XML) Banor, IOF (xml) = Baner, (IOF-XML)
Banor, OCAD semikolonseparerat = Baner, OCAD semikolonsepareret Banor, OCAD semikolonseparerat = Baner, OCAD semikolonsepareret
@ -184,7 +190,10 @@ Bantilldelning hänvisar till en löpare (X) som saknas i laget (Y) = Tildelning
Bantilldelning, individuell = Banetildeling, individuel Bantilldelning, individuell = Banetildeling, individuel
Bantilldelning, stafett = Banetildeling, stafet Bantilldelning, stafett = Banetildeling, stafet
Bantilldelningslista - %s = Banetildelingsliste - %s Bantilldelningslista - %s = Banetildelingsliste - %s
Basera på en tidigare tävling = Baser på et tidligere løb
Baserad på X = Baseret på X
Basintervall (min) = Basisinterval (min) Basintervall (min) = Basisinterval (min)
Batteridatum = Batteridato
Batteristatus = Batteristatus Batteristatus = Batteristatus
Begränsa antal per klass = Begræns antal pr. klasse Begränsa antal per klass = Begræns antal pr. klasse
Begränsa antal rader per sida = Begræns antal rækker per side Begränsa antal rader per sida = Begræns antal rækker per side
@ -213,18 +222,19 @@ BoldLarge = Fed, stor
BoldSmall = Fed, lille BoldSmall = Fed, lille
Bomkvot = Bom kvotient Bomkvot = Bom kvotient
Bommade kontroller = Poster med tidstab Bommade kontroller = Poster med tidstab
Bomtid = Tidstab
Bomtid (max) = Tidstab (max) Bomtid (max) = Tidstab (max)
Bomtid (medel) = Tidstab (gennemsnit) Bomtid (medel) = Tidstab (gennemsnit)
Bomtid (median) = Tidstab (median) Bomtid (median) = Tidstab (median)
Bomtid = Tidstab
Bomtid: X = Tidstab: X Bomtid: X = Tidstab: X
Borttagna: X = Fjernede: X Borttagna: X = Fjernede: X
Bricka %d används redan av %s och kan inte tilldelas = Brik %d bruges af %s og kan ikke tildeles
Bricka = Brik Bricka = Brik
Bricka %d används redan av %s och kan inte tilldelas = Brik %d bruges af %s og kan ikke tildeles
Bricka X = Brik X Bricka X = Brik X
Bricka X används också av = Brik X bruges også af Bricka X används också av = Brik X bruges også af
Brickan används av X = Brikken bruges af X Brickan används av X = Brikken bruges af X
Brickan redan inläst = Brikken er allerede aflæst Brickan redan inläst = Brikken er allerede aflæst
Brickavläsning = Brikaflæsning
Brickhantering = Brikhåndtering Brickhantering = Brikhåndtering
Brickhyra = Leje af brik Brickhyra = Leje af brik
Bricknr = Brik nummer Bricknr = Brik nummer
@ -238,12 +248,15 @@ Byt till vakansplats i rätt klass (om möjligt) = Skift til vakant plads i korr
COM-Port = COM-Port COM-Port = COM-Port
Calculate and apply forking = Beregn og brug gafling Calculate and apply forking = Beregn og brug gafling
Cancel = Annuller Cancel = Annuller
Cannot represent ID X = Kan ikke repræsentere ID 'X'
Centrera = Centrer Centrera = Centrer
Check = Check Check = Check
Check: X = Check: X Check: X = Check: X
Checkenhet = Check enhed
Choose result module = Vælg resultatmodul Choose result module = Vælg resultatmodul
ClassAvailableMaps = Tilgængelige kort for klasse ClassAvailableMaps = Tilgængelige kort for klasse
ClassCourseResult = Klasse, bane, resultater ClassCourseResult = Klasse, bane, resultater
ClassDefaultResult = Klasse, standardresultater
ClassFinishTime = Klasse, måltid ClassFinishTime = Klasse, måltid
ClassKnockoutTotalResult = Klasse, knock-out, samlet resultat ClassKnockoutTotalResult = Klasse, knock-out, samlet resultat
ClassLength = Banelængde for klasse ClassLength = Banelængde for klasse
@ -267,16 +280,17 @@ Climb (m) = Stigning (m)
Club = Klub Club = Klub
Club and runner database = Klub og løber database Club and runner database = Klub og løber database
Club id number = Klub id nummer Club id number = Klub id nummer
ClubClassStartTime = Klub, klasse, starttid
ClubName = Klub ClubName = Klub
ClubRunner = Klub / løber ClubRunner = Klub / løber
ClubTeam = Klub (Teams)
Clubs = Klubber Clubs = Klubber
CmpDate = Løbsdato CmpDate = Løbsdato
CmpName = Løbsnavn CmpName = Løbsnavn
Control = Post Control = Post
Control = Post
Control Overview = Post oversigt Control Overview = Post oversigt
Control Statistics - X = Post statistik - X
Control Statistics = Post statistik Control Statistics = Post statistik
Control Statistics - X = Post statistik - X
ControlClasses = Klasser for post ControlClasses = Klasser for post
ControlCodes = koder for post ControlCodes = koder for post
ControlCourses = Baner for post ControlCourses = Baner for post
@ -294,6 +308,7 @@ CourseClasses = Banes klasser
CourseClimb = Banens højdemeter CourseClimb = Banens højdemeter
CourseLength = Banelængde, specifik bane CourseLength = Banelængde, specifik bane
CourseName = Banens navn CourseName = Banens navn
CourseNumber = Bane nummer
CoursePunches = Stemplinger (for bane) CoursePunches = Stemplinger (for bane)
CourseResult = Bane, resultater CourseResult = Bane, resultater
CourseShortening = Baneafkortninger CourseShortening = Baneafkortninger
@ -311,8 +326,8 @@ Database is used and cannot be deleted = Databasen er i brug og kan ikke slettes
Databaskälla = Databaskilde Databaskälla = Databaskilde
Databasvarning: X = Database advarsel: X Databasvarning: X = Database advarsel: X
Datorröst som läser upp förvarningar = Computerstemme der læser forvarslinger op Datorröst som läser upp förvarningar = Computerstemme der læser forvarslinger op
Datum (för första start) = Dato (for første start)
Datum = Dato Datum = Dato
Datum (för första start) = Dato (for første start)
Datumfilter = Datofilter Datumfilter = Datofilter
Debug = Afprøv Debug = Afprøv
Debug Output = Resultat af afprøvning Debug Output = Resultat af afprøvning
@ -330,9 +345,9 @@ Dela klassen = Del klassen
Dela klubbvis = Del klubbvis Dela klubbvis = Del klubbvis
Dela slumpmässigt = Del tilfældigt Dela slumpmässigt = Del tilfældigt
Dela upp = Del op Dela upp = Del op
Deltagare = Deltagere
Deltagare %d = Deltagere %d Deltagare %d = Deltagere %d
Deltagare (kvarvarande) = Deltagere (tilbage) Deltagare (kvarvarande) = Deltagere (tilbage)
Deltagare = Deltagere
Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- och resultatlistor kan därmed bli felaktiga = Deltageren 'X' deltager i patruljeklassen 'Y' men savner patrulje. Klassens start- och resultatlister kan derfor blive fejlbehæftede Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- och resultatlistor kan därmed bli felaktiga = Deltageren 'X' deltager i patruljeklassen 'Y' men savner patrulje. Klassens start- och resultatlister kan derfor blive fejlbehæftede
Deltagaren 'X' deltar i stafettklassen 'Y' men saknar lag. Klassens start- och resultatlistor kan därmed bli felaktiga = Deltageren 'X' deltager i stafettklasse 'Y' men savner hold. Klassens start- och resultatlister kan derfor blive fejlbehæftede Deltagaren 'X' deltar i stafettklassen 'Y' men saknar lag. Klassens start- och resultatlistor kan därmed bli felaktiga = Deltageren 'X' deltager i stafettklasse 'Y' men savner hold. Klassens start- och resultatlister kan derfor blive fejlbehæftede
Deltagaren 'X' saknar klass = Deltagar 'X' savner klasse Deltagaren 'X' saknar klass = Deltagar 'X' savner klasse
@ -347,6 +362,7 @@ Det finns anmälningsdata för flera etapper = Det findes timeldingsdata for fle
Det finns multiplia Id-nummer för personer = Der findes multiple Id-numre for personer Det finns multiplia Id-nummer för personer = Der findes multiple Id-numre for personer
Det går endast att sätta in vakanser på sträcka 1 = Der kan kun indsættes vakante pladser på første tur Det går endast att sätta in vakanser på sträcka 1 = Der kan kun indsættes vakante pladser på første tur
Det här programmet levereras utan någon som helst garanti. Programmet är = Dette program leveres uden nogen som helst garanti. Programmet er Det här programmet levereras utan någon som helst garanti. Programmet är = Dette program leveres uden nogen som helst garanti. Programmet er
Det uppskattade antalet startade lag i klassen är ett lämpligt värde = Det skønnede antal hold i klassen er en passende værdi
Deviation +/- from expected time on course leg = Afvigelse +/- fra forventet tid på strækket Deviation +/- from expected time on course leg = Afvigelse +/- fra forventet tid på strækket
Direkt tidtagning = Direkte tidtagning Direkt tidtagning = Direkte tidtagning
Direktanmälan = Tilmelding på stævnepladsen Direktanmälan = Tilmelding på stævnepladsen
@ -357,8 +373,11 @@ Do you want to clear the card memory? = Vil du slette indlæste brikdata?
Don't know how to align with 'X' = Kan ikke justeres i forhold til 'X' Don't know how to align with 'X' = Kan ikke justeres i forhold til 'X'
Du kan använda en SI-enhet för att läsa in bricknummer = Du kan bruge en SI enhed til at indlæse nummeret på brikken Du kan använda en SI-enhet för att läsa in bricknummer = Du kan bruge en SI enhed til at indlæse nummeret på brikken
Du kan importera banor och klasser från OCADs exportformat = Du kan importere baner og klasser i OCAD's eksportformat Du kan importera banor och klasser från OCADs exportformat = Du kan importere baner og klasser i OCAD's eksportformat
Du kan justera tiden för en viss enhet = Du kan justere tiden for en enkelt enhed
Du måste ange minst två gafflingsvarienater = Der skal angives mindst to gafflingsvarianter
Du måste välja en klass = Du skal vælge en plads Du måste välja en klass = Du skal vælge en plads
Duplicera = Dupliker Duplicera = Dupliker
Duplicerad nummerlapp: X, Y = Duplikeret brystnummer: X, Y
Dölj = Skjul Dölj = Skjul
Döp om = Døb om Döp om = Døb om
Döp om X = Døb X om Döp om X = Døb X om
@ -405,19 +424,22 @@ En gafflad sträcka = En gaflet tur
En klass kan inte slås ihop med sig själv = En klasse kan ikke slås sammen med sig selv En klass kan inte slås ihop med sig själv = En klasse kan ikke slås sammen med sig selv
En klubb kan inte slås ihop med sig själv = En klub kan ikke slås sammen med sig selv En klubb kan inte slås ihop med sig själv = En klub kan ikke slås sammen med sig selv
Endast en bana = Kun en bane Endast en bana = Kun en bane
Endast grundläggande (enklast möjligt) = Kund grundlæggende(så simpelt som muligt)
Endast grundläggande = Grundfunktioner Endast grundläggande = Grundfunktioner
Endast grundläggande (enklast möjligt) = Kund grundlæggende(så simpelt som muligt)
Endast på obligatoriska sträckor = Håndter kun obligatoriske stræk. Endast på obligatoriska sträckor = Håndter kun obligatoriske stræk.
Endast tidtagning = Kun tidtagning
Endast tidtagning (utan banor) = Kun tidtagning (uden baner) Endast tidtagning (utan banor) = Kun tidtagning (uden baner)
Endast tidtagning (utan banor), stafett = Kun tidtagning (uden baner), stafet Endast tidtagning (utan banor), stafett = Kun tidtagning (uden baner), stafet
Endast tidtagning = Kun tidtagning Enhet = Enhed
Enhetens ID-nummer (MAC) = Enhedens ID (MAC) Enhetens ID-nummer (MAC) = Enhedens ID (MAC)
Enhetskod = Enhedskode
Enhetstyp = Enhedstype Enhetstyp = Enhedstype
EntryTime = Tilmeldingstidspunkt EntryTime = Tilmeldingstidspunkt
Error in result module X, method Y (Z) = Fejl i resultatmodul 'X', metode 'Y'\n\nZ Error in result module X, method Y (Z) = Fejl i resultatmodul 'X', metode 'Y'\n\nZ
Etapp = Etape Etapp = Etape
Etapp X = Etape X Etapp X = Etape X
Etappresultat = Etaperesultater Etappresultat = Etaperesultater
Ett långt tävlingsnamn kan ge oväntad nerskalning av utskrifter = Et langt løbsnavn kan medføre en uønsket nedskalering af udskrevne lister
Ett okänt fel inträffade = Der er opstået en ukendt fejl Ett okänt fel inträffade = Der er opstået en ukendt fejl
Ett startblock spänner över flera starter: X/Y = En startblok spænder over flere starter: X/Y Ett startblock spänner över flera starter: X/Y = En startblok spænder over flere starter: X/Y
Ett startintervall måste vara en multipel av basintervallet = Et startinterval skal være et multiplum af basisinterval Ett startintervall måste vara en multipel av basintervallet = Et startinterval skal være et multiplum af basisinterval
@ -429,8 +451,8 @@ Exempel = Eksempel
Export av resultat/sträcktider = Eksport af resultater / stræktider Export av resultat/sträcktider = Eksport af resultater / stræktider
Export language = Eksportsprog Export language = Eksportsprog
Export split times = Eksporter mellemtider Export split times = Eksporter mellemtider
Exportera / Säkerhetskopiera = Eksporter / Sikkerhedskopi
Exportera = Eksporter Exportera = Eksporter
Exportera / Säkerhetskopiera = Eksporter / Sikkerhedskopi
Exportera alla till HTML = Eksporter alle som HTML Exportera alla till HTML = Eksporter alle som HTML
Exportera alla till PDF = Eksporter alt som PDF Exportera alla till PDF = Eksporter alt som PDF
Exportera datafil = Eksporter datafil Exportera datafil = Eksporter datafil
@ -497,8 +519,8 @@ Filen (X) är en listdefinition = Filen (X) er en definition af en liste
Filen (X) är en resultatmodul = Filen (X) er et resultatmodul Filen (X) är en resultatmodul = Filen (X) er et resultatmodul
Filen (X) är inte en MeOS-tävling = Filen (X) är ikke et MeOS-løb Filen (X) är inte en MeOS-tävling = Filen (X) är ikke et MeOS-løb
Filen finns redan: X = Filen findes allerede: X Filen finns redan: X = Filen findes allerede: X
Filnamn (OCAD banfil) = Filnavn (OCAD banefil)
Filnamn = Filnavn Filnamn = Filnavn
Filnamn (OCAD banfil) = Filnavn (OCAD banefil)
Filnamn IOF (xml) eller OE (csv) med löpare = Filenavn (IOF-XML) eller (OE-CSV) med løbere Filnamn IOF (xml) eller OE (csv) med löpare = Filenavn (IOF-XML) eller (OE-CSV) med løbere
Filnamn IOF (xml) med klubbar = Filnavn (IOF-XML) med klubber Filnamn IOF (xml) med klubbar = Filnavn (IOF-XML) med klubber
Filnamn IOF (xml) med löpare = Filnavn (IOF-XML) med løbere Filnamn IOF (xml) med löpare = Filnavn (IOF-XML) med løbere
@ -526,10 +548,11 @@ Finish time for each team member = Måltid for hvert holdmedlem
FinishTime = Måltid, navn FinishTime = Måltid, navn
FinishTimeReverse = Omvendt måltid (sidste først) FinishTimeReverse = Omvendt måltid (sidste først)
First to finish = Først gennemført First to finish = Først gennemført
Flera banor / stafett / patrull / banpool = Flere baner / Stafet / Patrulje / Frit banevalg
Flera banor = Flere baner Flera banor = Flere baner
Flera banor / stafett / patrull / banpool = Flere baner / Stafet / Patrulje / Frit banevalg
Flera banor/stafett = Flere baner / Stafet Flera banor/stafett = Flere baner / Stafet
Flera lopp i valfri ordning = Flere løb i vilkårlig rækkefølge Flera lopp i valfri ordning = Flere løb i vilkårlig rækkefølge
Flera starter per deltagare = Flere starter for hver deltager
Flytta deltagare från överfulla grupper = Flyt deltagere væk fra overfulde grupper Flytta deltagare från överfulla grupper = Flyt deltagere væk fra overfulde grupper
Flytta höger = Flyt til højre Flytta höger = Flyt til højre
Flytta ner = Flyt ned Flytta ner = Flyt ned
@ -558,9 +581,9 @@ Från lag = Fra hold
Från laget = Fra holdet Från laget = Fra holdet
Från löpardatabasen = Fra løberdatabase Från löpardatabasen = Fra løberdatabase
Från löpardatabasen i befintliga klubbar = Fra løberdatabase fra klubber der er kendt Från löpardatabasen i befintliga klubbar = Fra løberdatabase fra klubber der er kendt
Fullskärm = Fuldskærm
Fullskärm (rullande) = Fuldskærm (rullende) Fullskärm (rullande) = Fuldskærm (rullende)
Fullskärm (sidvis) = Fuldskærm (side for side) Fullskärm (sidvis) = Fuldskærm (side for side)
Fullskärm = Fuldskærm
Funktion = Funktion Funktion = Funktion
Funktioner = Funktioner Funktioner = Funktioner
Funktioner i MeOS = Funktioner i MeOS Funktioner i MeOS = Funktioner i MeOS
@ -569,14 +592,14 @@ Färg = Farve
Färre slingor = Færre sløjfer Färre slingor = Færre sløjfer
Födelseår = Fødselsår Födelseår = Fødselsår
Följande deltagare deltar ej = Følgende deltagere deltager ikke Följande deltagare deltar ej = Følgende deltagere deltager ikke
Följande deltagare har bytt klass (inget totalresultat) = Følgende deltagere har skiftet klasse (intet samlet resultat)
Följande deltagare har bytt klass = Følgende deltagere har skiftet klasse Följande deltagare har bytt klass = Følgende deltagere har skiftet klasse
Följande deltagare har bytt klass (inget totalresultat) = Følgende deltagere har skiftet klasse (intet samlet resultat)
Följande deltagare har tilldelats en vakant plats = Følgende deltagere er tildelt en vakant plads Följande deltagare har tilldelats en vakant plats = Følgende deltagere er tildelt en vakant plads
Följande deltagare är anmälda till nästa etapp men inte denna = Følgende deltagere er tilmeldt næste etape, men ikke denne Följande deltagare är anmälda till nästa etapp men inte denna = Følgende deltagere er tilmeldt næste etape, men ikke denne
Följande deltagare är nyanmälda = Følgende deltagere er nytilmeldte Följande deltagare är nyanmälda = Følgende deltagere er nytilmeldte
Följande deltagare överfördes ej = Følgende deltagere blev ikke overført Följande deltagare överfördes ej = Følgende deltagere blev ikke overført
Fönster (rullande) = Vindue (rullende)
Fönster = Vindue Fönster = Vindue
Fönster (rullande) = Vindue (rullende)
För att delta i en lagklass måste deltagaren ingå i ett lag = En deltager skal være på et hold for at kunne deltage i en holdklasse. För att delta i en lagklass måste deltagaren ingå i ett lag = En deltager skal være på et hold for at kunne deltage i en holdklasse.
För att ändra måltiden måste löparens målstämplingstid ändras = For at ændre måltid, skal løberens målstemplingstid ændres För att ändra måltiden måste löparens målstämplingstid ändras = For at ændre måltid, skal løberens målstemplingstid ændres
För muspekaren över en markering för att få mer information = Før cursoren hen over en markering for at få mere information För muspekaren över en markering för att få mer information = Før cursoren hen over en markering for at få mere information
@ -659,8 +682,8 @@ Hoppar över stafettklass: X = Spring stafetklasse over: X
Huvudlista = Hovedliste Huvudlista = Hovedliste
Hyravgift = Lejeafgift Hyravgift = Lejeafgift
Hyrbricka = Lejebrik Hyrbricka = Lejebrik
Hyrbricksrapport - %s = Lejebriksrapport - %s
Hyrbricksrapport = Lejebriksrapport Hyrbricksrapport = Lejebriksrapport
Hyrbricksrapport - %s = Lejebriksrapport - %s
Hyrd = Lejet Hyrd = Lejet
Hämta (efter)anmälningar från Eventor = Hent (efter)tilmeldinger fra Eventor Hämta (efter)anmälningar från Eventor = Hent (efter)tilmeldinger fra Eventor
Hämta data från Eventor = Hent data fra Eventor Hämta data från Eventor = Hent data fra Eventor
@ -677,8 +700,8 @@ Hämtar klasser = Henter klasser
Hämtar klubbar = Henter klubber Hämtar klubbar = Henter klubber
Hämtar löpardatabasen = Henter løberdatabasen Hämtar löpardatabasen = Henter løberdatabasen
Hämtar tävling = Henter løb Hämtar tävling = Henter løb
Händelser - tidslinje = Begivenheder - tidslinje
Händelser = Begivenheder Händelser = Begivenheder
Händelser - tidslinje = Begivenheder - tidslinje
Håll ihop med = Hold kolonner samlet Håll ihop med = Hold kolonner samlet
Hög avgift = Forhøjet afgift Hög avgift = Forhøjet afgift
Höger = Højre Höger = Højre
@ -695,6 +718,8 @@ IP-adress eller namn på en MySQL-server = IP addresse eller navn på en MySQL s
Id = Id Id = Id
Identifierar X unika inledningar på banorna = Identificerer X unikke indledninger på banerne Identifierar X unika inledningar på banorna = Identificerer X unikke indledninger på banerne
Ignorera startstämpling = Ignorer startstempling Ignorera startstämpling = Ignorer startstempling
Ignorerade X duplikat = Ignorerede X duplikater
Image = Image
Importera = Importer Importera = Importer
Importera IOF (xml) = Importer (IOF-XML) Importera IOF (xml) = Importer (IOF-XML)
Importera anmälda = Importer tilmeldte Importera anmälda = Importer tilmeldte
@ -735,8 +760,8 @@ Individual results in a club = Individuelle resultater indenfor klub.
Individuell = Individuel Individuell = Individuel
Individuell resultatlista, alla lopp = Individuel resultatliste, alle løb Individuell resultatlista, alla lopp = Individuel resultatliste, alle løb
Individuell resultatlista, sammanställning av flera lopp = Individuel resultatliste, sammentælling af flere løb Individuell resultatlista, sammanställning av flera lopp = Individuel resultatliste, sammentælling af flere løb
Individuell resultatlista, visst lopp (STOR) = Individuel resultatliste, bestemt løb (STOR)
Individuell resultatlista, visst lopp = Individuel resultatliste, bestemt løb Individuell resultatlista, visst lopp = Individuel resultatliste, bestemt løb
Individuell resultatlista, visst lopp (STOR) = Individuel resultatliste, bestemt løb (STOR)
Individuell startlista, visst lopp = Individuel startliste, bestemt løb Individuell startlista, visst lopp = Individuel startliste, bestemt løb
Individuell tävling = Individuelt løb Individuell tävling = Individuelt løb
Individuella deltagare = Individuelle deltagere Individuella deltagare = Individuelle deltagere
@ -749,12 +774,12 @@ Info = Information
Infoga version: X = Tilføj version: X Infoga version: X = Tilføj version: X
Informationsserver = Informationsserver Informationsserver = Informationsserver
Inga = Ingen Inga = Ingen
Inga bommar registrerade = Inga bommar registrerade = Ingen tidstab detekteret på strækkene
Inga deltagare = Ingen deltagere Inga deltagare = Ingen deltagere
Inga klasser tillåter direktanmälan. På sidan klasser kan du ändra denna egenskap. = Ingen klasser tillader tilmeldong på stævneplads.\n\nDu kan ændre dette på siden klasser. Inga klasser tillåter direktanmälan. På sidan klasser kan du ändra denna egenskap. = Ingen klasser tillader tilmeldong på stævneplads.\n\nDu kan ændre dette på siden klasser.
Inga vakanser tillgängliga. Vakanser skapas vanligen vid lottning = Ingen vakante. Vakante pladser oprettes normalt ved lodtrækning Inga vakanser tillgängliga. Vakanser skapas vanligen vid lottning = Ingen vakante. Vakante pladser oprettes normalt ved lodtrækning
Ingen / okänd = Ingen / ukendt
Ingen = Ingen Ingen = Ingen
Ingen / okänd = Ingen / ukendt
Ingen bana = Ingen bane Ingen bana = Ingen bane
Ingen deltagare matchar sökkriteriet = Ingen deltagere matcher søgekriteriet Ingen deltagare matchar sökkriteriet = Ingen deltagere matcher søgekriteriet
Ingen deltagare vald = Ingen deltagere valgt Ingen deltagare vald = Ingen deltagere valgt
@ -764,20 +789,26 @@ Ingen löpare saknar bricka = Ingen løbere mangler SI-brik
Ingen matchar 'X' = Ingen matcher 'X' Ingen matchar 'X' = Ingen matcher 'X'
Ingen nummerlapp = Intet brystnummer Ingen nummerlapp = Intet brystnummer
Ingen parstart = Individuel start Ingen parstart = Individuel start
Ingen reducerad avgift = Ikke reduceret afgift
Ingen rogaining = Intet pointløb Ingen rogaining = Intet pointløb
Ingen[competition] = Ingen [løb]
Inget filter = Intet filter Inget filter = Intet filter
Inget nummer = Intet nummer Inget nummer = Intet nummer
Inkludera bana = Inkluder bane Inkludera bana = Inkluder bane
Inkludera bomanalys = Inkluder analyse af tidstab
Inkludera individuellt resultat = Inkluder individuelt resultat
Inkludera information om flera lopp per löpare = Inkluder information om flere løb for den enkelte løber Inkludera information om flera lopp per löpare = Inkluder information om flere løb for den enkelte løber
Inkludera resultat från tidigare etapper = Inkluder resultater fra forudgående etapper Inkludera resultat från tidigare etapper = Inkluder resultater fra forudgående etapper
Inkludera sträcktider = Inkluder stræktider
Inkludera tempo = Inkluder tempo
Inkommande = Indkommende Inkommande = Indkommende
Inläst bricka ställd i kö = Aflæst brik sat i kø Inläst bricka ställd i kö = Aflæst brik sat i kø
Inlästa brickor = Aflæste brikker Inlästa brickor = Aflæste brikker
Inlästa stämplar = Indlæs stemplinger Inlästa stämplar = Indlæs stemplinger
Inmatning av mellantider = Indtastning af mellemtider Inmatning av mellantider = Indtastning af mellemtider
Inmatning online = Online indlæsning Inmatning online = Online indlæsning
Input Results - X = Input resultater - X
Input Results = Input resultater Input Results = Input resultater
Input Results - X = Input resultater - X
Inspekterar klasser = Undersøger klasser Inspekterar klasser = Undersøger klasser
Installera = Installer Installera = Installer
Installerbara listor = Installerbare lister Installerbara listor = Installerbare lister
@ -787,8 +818,8 @@ Inställningar startbevis = Instilliger for udskrift af startkvittering
Inställningar sträcktidsutskrift = Indstilling af stræktidsudskrifter Inställningar sträcktidsutskrift = Indstilling af stræktidsudskrifter
Interaktiv inläsning = Interaktiv indlæsning Interaktiv inläsning = Interaktiv indlæsning
Internal Error, identifier not found: X = Intern fejl, identifier not found: X Internal Error, identifier not found: X = Intern fejl, identifier not found: X
Intervall (sekunder). Lämna blankt för att uppdatera när tävlingsdata ändras = Interval (sekunder). Efterlad blank for at opdatere når løbsdata ændres
Intervall = Interval Intervall = Interval
Intervall (sekunder). Lämna blankt för att uppdatera när tävlingsdata ändras = Interval (sekunder). Efterlad blank for at opdatere når løbsdata ændres
Intervallet måste anges på formen MM:SS = Intervallet skal angives som MM:SS Intervallet måste anges på formen MM:SS = Intervallet skal angives som MM:SS
Invalid filter X = Ugyldigt filter X Invalid filter X = Ugyldigt filter X
Invalid font X = Ugyldig tegnsæt X Invalid font X = Ugyldig tegnsæt X
@ -815,9 +846,9 @@ Klart. X patruller importerade = Færdig. X patruljer importeret
Klart. X värden tilldelade = Klar, X værdier er tildelt. Klart. X värden tilldelade = Klar, X værdier er tildelt.
Klart: alla klasser lottade = Færdig. Alle klasser er lodtrukne. Klart: alla klasser lottade = Færdig. Alle klasser er lodtrukne.
Klart: inga klasser behövde lottas = Færdig: Ingen klasser behøvede lodtrækning Klart: inga klasser behövde lottas = Færdig: Ingen klasser behøvede lodtrækning
Klass = Klasse
Klass %d = Klasse %d Klass %d = Klasse %d
Klass / klasstyp = Klasse / Klassetype Klass / klasstyp = Klasse / Klassetype
Klass = Klasse
Klass X = Klasse X Klass X = Klasse X
Klass att slå ihop = Klasser der slås sammen Klass att slå ihop = Klasser der slås sammen
Klass saknad = Manglende klasse Klass saknad = Manglende klasse
@ -832,8 +863,8 @@ Klassen måste ha ett namn = Klassen skal have et navn
Klassen saknas = Klassen mangler Klassen saknas = Klassen mangler
Klassen är full = Klassen er fuld Klassen är full = Klassen er fuld
Klassens bana = Klassens bane Klassens bana = Klassens bane
Klasser (IOF, xml) = Klasser (IOF-XML)
Klasser = Klasser Klasser = Klasser
Klasser (IOF, xml) = Klasser (IOF-XML)
Klasser där nyanmälningar ska överföras = Klasser hvortil nytilmeldinger skal overføres Klasser där nyanmälningar ska överföras = Klasser hvortil nytilmeldinger skal overføres
Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Klasserne X og Y har samme eksterne id. Brug tabeltilstand til at rette id Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Klasserne X og Y har samme eksterne id. Brug tabeltilstand til at rette id
Klassinställningar = Klasseindstillinger Klassinställningar = Klasseindstillinger
@ -849,16 +880,16 @@ Klubb = Klub
Klubb att ta bort = Klub der fjernes Klubb att ta bort = Klub der fjernes
Klubb: X = Klub: X Klubb: X = Klub: X
KlubbId = Klub Id KlubbId = Klub Id
Klubbar (IOF, xml) = Klubber (IOF-XML)
Klubbar = Klubber Klubbar = Klubber
Klubbar (IOF, xml) = Klubber (IOF-XML)
Klubbar som inte svarat = Klubber som ikke har svaret Klubbar som inte svarat = Klubber som ikke har svaret
Klubbdatabasen = Klubdatabasen Klubbdatabasen = Klubdatabasen
Klubblös = Uden klub Klubblös = Uden klub
Klubbresultat = Klubresultater Klubbresultat = Klubresultater
Klubbresultatlista - %s = Klubresultatliste - %s
Klubbresultatlista = Klubresultatliste Klubbresultatlista = Klubresultatliste
Klubbstartlista - %s = Klubstartliste - %s Klubbresultatlista - %s = Klubresultatliste - %s
Klubbstartlista = Klubstartliste Klubbstartlista = Klubstartliste
Klubbstartlista - %s = Klubstartliste - %s
Klungstart = Gruppevis start Klungstart = Gruppevis start
Knockout sammanställning = Knock-out opsummering Knockout sammanställning = Knock-out opsummering
Knockout total = Knock-out samlet Knockout total = Knock-out samlet
@ -876,8 +907,8 @@ Kommunikationen med en SI-enhet avbröts = Kommunikationen med en SI-enhed blev
Kontant = Kontant Kontant = Kontant
Kontant betalning = Kontant betaling Kontant betalning = Kontant betaling
Konto = Konto Konto = Konto
Kontroll %s = Post %s
Kontroll = Post Kontroll = Post
Kontroll %s = Post %s
Kontroll X = Post X Kontroll X = Post X
Kontroll inför tävlingen = Kontrol før løbet Kontroll inför tävlingen = Kontrol før løbet
Kontrollen används och kan inte tas bort = Posten er i brug og kan ikke fjernes Kontrollen används och kan inte tas bort = Posten er i brug og kan ikke fjernes
@ -914,10 +945,11 @@ Källkatalog = Mappe at hente fra
Kön = Køn Kön = Køn
Kör kontroll inför tävlingen = Foretag kontrol før løbet Kör kontroll inför tävlingen = Foretag kontrol før løbet
Ladda upp öppnad tävling på server = Upload åbnet løb til server Ladda upp öppnad tävling på server = Upload åbnet løb til server
Lag = Hold
Lag %d = Hold %d Lag %d = Hold %d
Lag + sträcka = Hold + tur Lag + sträcka = Hold + tur
Lag = Hold
Lag och stafett = Hold og stafet Lag och stafett = Hold og stafet
Lag utan nummerlapp: X = Hold uden brystnummer: X
Lag(flera) = Hold Lag(flera) = Hold
Laget 'X' saknar klass = Der er ikke angivet klasse for holdet 'X' Laget 'X' saknar klass = Der er ikke angivet klasse for holdet 'X'
Laget hittades inte = Holdet blev ikke fundet Laget hittades inte = Holdet blev ikke fundet
@ -972,8 +1004,8 @@ Lopp %d = Løb %d
Lopp %s = Løb %s Lopp %s = Løb %s
Lopp X = Løb X Lopp X = Løb X
Lopp-id = Løbs ID Lopp-id = Løbs ID
Lotta / starttider = Lodtrækning / starttider
Lotta = Træk lod Lotta = Træk lod
Lotta / starttider = Lodtrækning / starttider
Lotta flera klasser = Lodtrækning flere klasser Lotta flera klasser = Lodtrækning flere klasser
Lotta klassen = Lodtrækning, klasse Lotta klassen = Lodtrækning, klasse
Lotta klassen X = Lodtrækning, klasse 'X' Lotta klassen X = Lodtrækning, klasse 'X'
@ -994,6 +1026,7 @@ Lyssna = Lyt
Lyssnar på X = Lytter på X Lyssnar på X = Lytter på X
Lägg till = Tilføj Lägg till = Tilføj
Lägg till alla = Tilføj alle Lägg till alla = Tilføj alle
Lägg till bild = Tilføj billede
Lägg till en ny rad i tabellen (X) = Tilføj række i tabellen (X) Lägg till en ny rad i tabellen (X) = Tilføj række i tabellen (X)
Lägg till klasser = Tilføj klasser Lägg till klasser = Tilføj klasser
Lägg till ny = Tilføj ny Lägg till ny = Tilføj ny
@ -1002,8 +1035,8 @@ Lägg till rad = Tilføj række
Lägg till stämpling = Tilføj stempling Lägg till stämpling = Tilføj stempling
Lägger till klubbar = Tilføjer klubber Lägger till klubbar = Tilføjer klubber
Lägger till löpare = Tilføjer løbere Lägger till löpare = Tilføjer løbere
Längd (m) = Længde (m)
Längd = Længde Längd = Længde
Längd (m) = Længde (m)
Längsta svarstid: X ms = Længste svarstid: X ms Längsta svarstid: X ms = Længste svarstid: X ms
Längsta tid i sekunder att vänta med utskrift = Det længste, i sekunder, der ventes med udskrift Längsta tid i sekunder att vänta med utskrift = Det længste, i sekunder, der ventes med udskrift
Länk till resultatlistan = Link til resultatlisten Länk till resultatlistan = Link til resultatlisten
@ -1062,6 +1095,7 @@ Mata in första nummerlappsnummer, eller blankt för att ta bort nummerlappar =
Mata in radiotider manuellt = Indtast radiotider manuelt Mata in radiotider manuellt = Indtast radiotider manuelt
Matched control ids (-1 for unmatched) for each team member = Matchende kontrol id'er (-1 for umatchet) for hvert holdmedlem Matched control ids (-1 for unmatched) for each team member = Matchende kontrol id'er (-1 for umatchet) for hvert holdmedlem
Max antal brickor per sida = Max antal Si-brikker per side Max antal brickor per sida = Max antal Si-brikker per side
Max antal gaffllingsvarianter att skapa = Maksimalt antal gafflinger der skal dannes
Max antal gemensamma kontroller = Maks. antal fælles poster Max antal gemensamma kontroller = Maks. antal fælles poster
Max parallellt startande = Maks. antal samtidigt startende Max parallellt startande = Maks. antal samtidigt startende
Max. vakanser (per klass) = Maks. vakante (pr klasse) Max. vakanser (per klass) = Maks. vakante (pr klasse)
@ -1111,6 +1145,7 @@ Multipel = Multiple
MySQL Server / IP-adress = MySQL Server / IP-addresse MySQL Server / IP-adress = MySQL Server / IP-addresse
Män = Mænd Män = Mænd
Mål = Mål Mål = Mål
Målenhet = Målenhed
Målfil = Destinationsfil Målfil = Destinationsfil
Målstämpling saknas = Manglende målstempling Målstämpling saknas = Manglende målstempling
Målstämpling tillåts inte (X) = Målstempling ikke tilladt (X) Målstämpling tillåts inte (X) = Målstempling ikke tilladt (X)
@ -1141,6 +1176,8 @@ Normalavgift = Normal afgift
Not implemented = Ikke implementeret Not implemented = Ikke implementeret
Not yet implemented = Endnu ikke tilgægelig Not yet implemented = Endnu ikke tilgægelig
Nr = Nummer Nr = Nummer
NumEntries = Antal tilmeldinger
NumStarts = Antal startende
Number of shortenings = Antal afkortninger af baner Number of shortenings = Antal afkortninger af baner
Nummerlapp = Brystnummer Nummerlapp = Brystnummer
Nummerlapp, SI eller Namn = Brystnummer, SI-brik eller Navn Nummerlapp, SI eller Namn = Brystnummer, SI-brik eller Navn
@ -1269,8 +1306,8 @@ Postkod = Postnummer
Poäng = Points Poäng = Points
Poäng E[stageno] = Point E Poäng E[stageno] = Point E
Poäng in = Points i Poäng in = Points i
Poängavdrag (per minut) = Pointfradrag (pr minut)
Poängavdrag = Pointfradrag Poängavdrag = Pointfradrag
Poängavdrag (per minut) = Pointfradrag (pr minut)
Poängavdrag per påbörjad minut = Pointfradrag for hvert påbegyndt minut Poängavdrag per påbörjad minut = Pointfradrag for hvert påbegyndt minut
Poänggräns = Pointgrænse Poänggräns = Pointgrænse
Poängjustering = Pointjustering Poängjustering = Pointjustering
@ -1285,6 +1322,7 @@ Printing failed (X: Y) Z = Utskrivning fejlede (X: Y) Z
Prioritering = Prioritering Prioritering = Prioritering
Prisutdelningslista = Prisuddelingsliste Prisutdelningslista = Prisuddelingsliste
Programinställningar = Programindstillinger Programinställningar = Programindstillinger
Programmera stationen utan AUTOSEND = Slå AUTO SEND fra i SPORTident enheden
Prolog + jaktstart = Prolog + jagtstart Prolog + jaktstart = Prolog + jagtstart
Prologue + Pursuit = Prolog + Jagtstart Prologue + Pursuit = Prolog + Jagtstart
Publicera resultat = Offentliggør resultat Publicera resultat = Offentliggør resultat
@ -1326,8 +1364,8 @@ Radera vakanser = Slet vakante
Radio = Radio Radio = Radio
Radio tillåts inte (X) = Radioposter ikke tilladt (X) Radio tillåts inte (X) = Radioposter ikke tilladt (X)
Radiotider, kontroll = Radiotider, post Radiotider, kontroll = Radiotider, post
Ranking (IOF, xml, csv) = Rangliste (IOF, XML, CSV)
Ranking = Rangliste Ranking = Rangliste
Ranking (IOF, xml, csv) = Rangliste (IOF, XML, CSV)
Rapport = Rapport Rapport = Rapport
Rapport inför = Rapport før Rapport inför = Rapport før
Rapporter = Rapporter Rapporter = Rapporter
@ -1341,6 +1379,8 @@ Redigera listpost = Ret listepost
Redigera sträcklängder = Ret længde af stræk Redigera sträcklängder = Ret længde af stræk
Redigera sträcklängder för X = Ret længder af stræk for 'X' Redigera sträcklängder för X = Ret længder af stræk for 'X'
Reducerad avg = Reduceret afgift Reducerad avg = Reduceret afgift
Reducerad avgift = Nedsat avgift
Reducerad avgift för = Nedsat afgift for
Reduktionsmetod = Reduktionsmetode Reduktionsmetod = Reduktionsmetode
Referens = Reference Referens = Reference
Region = Region Region = Region
@ -1371,11 +1411,11 @@ ResultModuleNumber = Resultatmodul: Nummer
ResultModuleNumberTeam = Resultat Modul: Placering (for hold) ResultModuleNumberTeam = Resultat Modul: Placering (for hold)
ResultModuleTime = Resultmodul: Tid ResultModuleTime = Resultmodul: Tid
ResultModuleTimeTeam = Resultat Modul: Samlet tid (for hold) ResultModuleTimeTeam = Resultat Modul: Samlet tid (for hold)
Resultat = Resultater
Resultat && sträcktider = Resultater && stræktider Resultat && sträcktider = Resultater && stræktider
Resultat (STOR) = Resultater (STOR) Resultat (STOR) = Resultater (STOR)
Resultat - %s = Resultater - %s Resultat - %s = Resultater - %s
Resultat - X = Resultater - X Resultat - X = Resultater - X
Resultat = Resultater
Resultat banvis per klass = Resultater banevis pr klasse Resultat banvis per klass = Resultater banevis pr klasse
Resultat efter klass och bana - X = Resultat efter klasse og bane - X Resultat efter klass och bana - X = Resultat efter klasse og bane - X
Resultat efter sträcka X = Resultat efter tur X Resultat efter sträcka X = Resultat efter tur X
@ -1384,8 +1424,8 @@ Resultat från tidigare etapper = Resultater fra tidligere etaper
Resultat för ett visst lopp = Resultater for et bestemt løb Resultat för ett visst lopp = Resultater for et bestemt løb
Resultat lopp X - Y = Resultater løb X - Y Resultat lopp X - Y = Resultater løb X - Y
Resultat online = Resultater online Resultat online = Resultater online
Resultat per bana - X = Resultater pr bane - X
Resultat per bana = Resultater pr bane Resultat per bana = Resultater pr bane
Resultat per bana - X = Resultater pr bane - X
Resultat vid målstämpling = Resultater efter målstempling Resultat vid målstämpling = Resultater efter målstempling
Resultat, generell = Resultater, generelt Resultat, generell = Resultater, generelt
Resultat, individuell = Resultater, individuelle Resultat, individuell = Resultater, individuelle
@ -1396,9 +1436,8 @@ Resultatlista inställningar = Resultatliste indstillinger
Resultatlistor = Resultatlister Resultatlistor = Resultatlister
Resultatmodulen används i X = Resultatmodulet bruges i X Resultatmodulen används i X = Resultatmodulet bruges i X
Resultatuträkning = Resultatberegning Resultatuträkning = Resultatberegning
Resultatutskrift / export = Udskriv resultater / eksporter
Resultatutskrift = Udskriv resultater Resultatutskrift = Udskriv resultater
Rogaining = Pointløb Resultatutskrift / export = Udskriv resultater / eksporter
Rogaining = Rogaining Rogaining = Rogaining
Rogaining points before automatic reduction = Rogaining point før automatisk reduktion Rogaining points before automatic reduction = Rogaining point før automatisk reduktion
Rogaining points for each team member = Pointløbs points for hvert holdmedlem Rogaining points for each team member = Pointløbs points for hvert holdmedlem
@ -1444,6 +1483,7 @@ Runner/team total running time = Løber/hold samlet løbstid
Runner/team total status = Løber/hold samlet status Runner/team total status = Løber/hold samlet status
RunnerAge = Løbers alder RunnerAge = Løbers alder
RunnerBib = Løbers brystnummer RunnerBib = Løbers brystnummer
RunnerBirthDate = Fødselsdato
RunnerBirthYear = Løbers fødselsår RunnerBirthYear = Løbers fødselsår
RunnerCard = Briknummer RunnerCard = Briknummer
RunnerCardVoltage = SIAC batterispænding RunnerCardVoltage = SIAC batterispænding
@ -1521,6 +1561,7 @@ SOFT-avgift = DO-F afgift
SOFT-lottning = Svensk lodtrækning SOFT-lottning = Svensk lodtrækning
SRR Dongle = SRR Dongle SRR Dongle = SRR Dongle
Saknad starttid = Manglende starttid Saknad starttid = Manglende starttid
Saknat lag mellan X och Y = Mangler hold mellem X og Y
Samlade poäng = Samlet antal point Samlade poäng = Samlet antal point
Samma = Samme Samma = Samme
Samma bastävling = Samme basisløb Samma bastävling = Samme basisløb
@ -1546,6 +1587,7 @@ Senast sedd: X vid Y = Sidst set: X ved Y
Server = Server Server = Server
Server startad på X = Server startet på X Server startad på X = Server startet på X
Server startad på port X = Server er startet på port X Server startad på port X = Server er startet på port X
Server version: X = Server version: X
Server: [X] Y = Server: [X] Y Server: [X] Y = Server: [X] Y
Several MeOS Clients in a network = Flere MeOS-klienter i et netværk Several MeOS Clients in a network = Flere MeOS-klienter i et netværk
Several races for a runner = Flere løb for en løber Several races for a runner = Flere løb for en løber
@ -1553,10 +1595,11 @@ Several stages = Flere etaper
Short = Kort Short = Kort
Shortest time in class = Korteste tid i klassen Shortest time in class = Korteste tid i klassen
Show forking = Vis gaflinger Show forking = Vis gaflinger
Sidbrytning mellan klasser / klubbar = Sideskift mellem klasser / klubber
Sidbrytning mellan klasser = Sideskift mellem klasser Sidbrytning mellan klasser = Sideskift mellem klasser
Sidbrytning mellan klasser / klubbar = Sideskift mellem klasser / klubber
Sidor per skärm = Sider per skærm Sidor per skärm = Sider per skærm
Simulera inläsning av stämplar = Simuler aflæsning af stemplinger Simulera inläsning av stämplar = Simuler aflæsning af stemplinger
Sist = Sidst
Sista betalningsdatum = Sidste betalingsdato Sista betalningsdatum = Sidste betalingsdato
Sista ordinarie anmälningsdatum = Sidste ordinære tilmeldingsdato Sista ordinarie anmälningsdatum = Sidste ordinære tilmeldingsdato
Sista start (nu tilldelad) = Sidste start (nu tildelt) Sista start (nu tilldelad) = Sidste start (nu tildelt)
@ -1566,6 +1609,7 @@ Ska X raderas från tävlingen? = Skal X fjernes fra løbet?
Skalfaktor = Skaleringsfaktor Skalfaktor = Skaleringsfaktor
Skapa = Opret Skapa = Opret
Skapa anonyma lagmedlemmar = Opret anonyme deltagere på hold Skapa anonyma lagmedlemmar = Opret anonyme deltagere på hold
Skapa en klass för varje bana = Dan en klasse for hver bane
Skapa en ny tävling med data från Eventor = Dan et nyt løb med data fra Eventor Skapa en ny tävling med data från Eventor = Dan et nyt løb med data fra Eventor
Skapa en ny, tom, tävling = Opret et nyt, tomt, løb Skapa en ny, tom, tävling = Opret et nyt, tomt, løb
Skapa fakturor = Dan fakturaer Skapa fakturor = Dan fakturaer
@ -1576,6 +1620,7 @@ Skapa tävlingen = Opret løb
Skapad av = Oprettet af Skapad av = Oprettet af
Skapade en bana för klassen %s med %d kontroller från brickdata (SI-%d) = Oprettede en bane for klassen %s med %d poster ud fra SI-%d Skapade en bana för klassen %s med %d kontroller från brickdata (SI-%d) = Oprettede en bane for klassen %s med %d poster ud fra SI-%d
Skapade en lokal kopia av tävlingen = Oprettede en lokal kopi af løbet Skapade en lokal kopia av tävlingen = Oprettede en lokal kopi af løbet
Skapade lokal säkerhetskopia (X) innan sammanslagning = Dan en lokal sikkerhedskopi før sammenlægning
Skapar ny etapp = Opretter ny etape Skapar ny etapp = Opretter ny etape
Skapar ny tävling = Opretter nyt løb Skapar ny tävling = Opretter nyt løb
Skapar saknad klass = Opretter manglende klasse Skapar saknad klass = Opretter manglende klasse
@ -1601,8 +1646,8 @@ Skriv ut rapporten = Udskriv rapporten
Skriv ut startbevis = Udskriv Startkvittering Skriv ut startbevis = Udskriv Startkvittering
Skriv ut startbevis för deltagaren = Udskriv startkvittering for løber Skriv ut startbevis för deltagaren = Udskriv startkvittering for løber
Skriv ut sträcktider = Udskriv stræktider Skriv ut sträcktider = Udskriv stræktider
Skriv ut tabellen (X) = Udskriv tabellen (X)
Skriv ut tabellen = Udskriv tabellen Skriv ut tabellen = Udskriv tabellen
Skriv ut tabellen (X) = Udskriv tabellen (X)
Skriv över existerande bricknummer? = Overskriv eksisterende briknummer? Skriv över existerande bricknummer? = Overskriv eksisterende briknummer?
Skrivare = Printer Skrivare = Printer
Skrivarinställningar = Printer indstilling Skrivarinställningar = Printer indstilling
@ -1615,8 +1660,8 @@ Slutresultat = Endelige resultater
Sluttid = Sluttid Sluttid = Sluttid
Slå ihop = Slå sammen Slå ihop = Slå sammen
Slå ihop X = Slå X sammen Slå ihop X = Slå X sammen
Slå ihop klass: X (denna klass behålls) = Slå klasse X sammen: (behold denne klasse)
Slå ihop klass: X = Slå klasse X sammen Slå ihop klass: X = Slå klasse X sammen
Slå ihop klass: X (denna klass behålls) = Slå klasse X sammen: (behold denne klasse)
Slå ihop klasser = Slå klasser sammen Slå ihop klasser = Slå klasser sammen
Slå ihop klubb = Slå klub sammen Slå ihop klubb = Slå klub sammen
Slå ihop med = Slå sammen med Slå ihop med = Slå sammen med
@ -1644,6 +1689,7 @@ Spara i aktuell tävling = Gem i aktuelt løb
Spara inmatade tider i tävlingen utan att tilldela starttider = Gem indlæste tider i løbet uden at tildele starttid Spara inmatade tider i tävlingen utan att tilldela starttider = Gem indlæste tider i løbet uden at tildele starttid
Spara inställningar = Gem indstillinger Spara inställningar = Gem indstillinger
Spara laguppställningar = Gem holdopstillinger Spara laguppställningar = Gem holdopstillinger
Spara oparad bricka = Gem uparret Si brik
Spara på disk = Gem på disk Spara på disk = Gem på disk
Spara som = Gem som Spara som = Gem som
Spara som PDF = Gem som PDF Spara som PDF = Gem som PDF
@ -1651,6 +1697,7 @@ Spara som fil = Gem som fil
Spara starttider = Gem starttider Spara starttider = Gem starttider
Spara sträcktider till en fil för automatisk synkronisering med WinSplits = Gem stræktider i en fil for automatisk synkronisering med WinSplits Spara sträcktider till en fil för automatisk synkronisering med WinSplits = Gem stræktider i en fil for automatisk synkronisering med WinSplits
Spara tid = Gem tid Spara tid = Gem tid
Sparade automater = Gemte Autofunktioner (Tjenester)
Sparade listval = Gemte listevalg Sparade listval = Gemte listevalg
Speaker = Speaker Speaker = Speaker
Speakerstöd = Speaker funktion Speakerstöd = Speaker funktion
@ -1659,17 +1706,17 @@ SportIdent = SPORTident
Språk = Sprog Språk = Sprog
Spänning = Spænding Spänning = Spænding
Stad = By Stad = By
Stafett = Stafet
Stafett (sammanställning) = Stafet (sammenfatning) Stafett (sammanställning) = Stafet (sammenfatning)
Stafett - sammanställning = Stafet - sammenfatning Stafett - sammanställning = Stafet - sammenfatning
Stafett - sträcka = Stafet - tur Stafett - sträcka = Stafet - tur
Stafett - total = Stafet - total Stafett - total = Stafet - total
Stafett = Stafet
Stafettklasser = Stafetklasser Stafettklasser = Stafetklasser
Stafettresultat = Stafet Resultater Stafettresultat = Stafet Resultater
Stafettresultat, delsträckor = Stafetresultater, delstræk Stafettresultat, delsträckor = Stafetresultater, delstræk
Stafettresultat, lag = Stafetresulater, hold Stafettresultat, lag = Stafetresulater, hold
Stafettresultat, sträcka (STOR) = Stafetresultater, tur (STOR)
Stafettresultat, sträcka = Stafetresultater, tur Stafettresultat, sträcka = Stafetresultater, tur
Stafettresultat, sträcka (STOR) = Stafetresultater, tur (STOR)
Standard = Standard Standard = Standard
Start = Start Start = Start
Start nr = Start nr Start nr = Start nr
@ -1689,17 +1736,18 @@ Startbevis = Startkvittering
Startbevis X = Startkvittering X Startbevis X = Startkvittering X
Startblock = Startblok Startblock = Startblok
Startblock: %d = Startblok: %d Startblock: %d = Startblok: %d
Startenhet = Start enhed
Startgrupp = Startgruppe Startgrupp = Startgruppe
Startgrupp med id X tilldelad Y finns inte = Startgruppe med id X defineret for Y findes ikke Startgrupp med id X tilldelad Y finns inte = Startgruppe med id X defineret for Y findes ikke
Startgrupper = Startgrupper Startgrupper = Startgrupper
Startgrupperna X och Y överlappar = Startgrupperne X och Y overlapper hinanden Startgrupperna X och Y överlappar = Startgrupperne X och Y overlapper hinanden
Startintervall (min) = Startinterval (min)
Startintervall = Startinterval Startintervall = Startinterval
Startintervall (min) = Startinterval (min)
Startintervallet får inte vara kortare än basintervallet = Startinterval må ikkke være kortere end basisinterval Startintervallet får inte vara kortare än basintervallet = Startinterval må ikkke være kortere end basisinterval
Startlista = Startliste
Startlista %%s - sträcka %d = Startlista %%s - stræk %d Startlista %%s - sträcka %d = Startlista %%s - stræk %d
Startlista - %s = Startliste - %s Startlista - %s = Startliste - %s
Startlista - X = Startliste - X Startlista - X = Startliste - X
Startlista = Startliste
Startlista ett visst lopp = Startliste for et specifikt løb Startlista ett visst lopp = Startliste for et specifikt løb
Startlista lopp X - Y = Startliste løb X - Y Startlista lopp X - Y = Startliste løb X - Y
Startlista, banvis = Startliste, banevis Startlista, banvis = Startliste, banevis
@ -1712,8 +1760,8 @@ Startmetod = Startmetode
Startnamn = Startnavn Startnamn = Startnavn
Startnummer = Startnummer Startnummer = Startnummer
Startstämpling tillåts inte (X) = Startstempling ikke tilladt (X) Startstämpling tillåts inte (X) = Startstempling ikke tilladt (X)
Starttid (HH:MM:SS) = Starttid (HH:MM:SS)
Starttid = Starttid Starttid = Starttid
Starttid (HH:MM:SS) = Starttid (HH:MM:SS)
Starttid: X = Starttid: X Starttid: X = Starttid: X
Starttiden är definerad genom klassen eller löparens startstämpling = Starttiden er defineret ud fra klassen eller ud fra løberens startstempling Starttiden är definerad genom klassen eller löparens startstämpling = Starttiden er defineret ud fra klassen eller ud fra løberens startstempling
Starttiden är upptagen = Starttiden er optaget Starttiden är upptagen = Starttiden er optaget
@ -1737,6 +1785,7 @@ Status code for not starting = Statuskode for ikke startet
Status code for running out-of-competition = Statuskode for udenfor konkurrance (OOC) Status code for running out-of-competition = Statuskode for udenfor konkurrance (OOC)
Status for each team member = Status for hvert holdmedlem Status for each team member = Status for hvert holdmedlem
Status in = Status ind Status in = Status ind
Status inte OK (röd utgång) = Status er ikke OK (rød udgang)
Status matchar inte data i löparbrickan = Status matcher ikke data i SI-brikken. Status matchar inte data i löparbrickan = Status matcher ikke data i SI-brikken.
Status matchar inte deltagarnas status = Status matcher ikke deltagerens status. Status matchar inte deltagarnas status = Status matcher ikke deltagerens status.
Stigning = Stigning Stigning = Stigning
@ -1751,17 +1800,18 @@ Struken med återbetalning = Afbud med tilbagebetaling
Struken utan återbetalning = Afbud uden tilbagebetaling Struken utan återbetalning = Afbud uden tilbagebetaling
Strukturerat exportformat = Struktureret eksportformat Strukturerat exportformat = Struktureret eksportformat
Strukturerat webbdokument (html) = Struktureret webdokument (html) Strukturerat webbdokument (html) = Struktureret webdokument (html)
Sträcka %d = Tur %d
Sträcka = Tur Sträcka = Tur
Sträcka %d = Tur %d
Sträcka X = Tur X Sträcka X = Tur X
Sträcka att lotta = Ture til lodtrækning Sträcka att lotta = Ture til lodtrækning
Sträckans banor = Strækkets baner Sträckans banor = Strækkets baner
Sträcktider = Stræktider
Sträcktider (WinSplits) = Stræktider (WinSplits) Sträcktider (WinSplits) = Stræktider (WinSplits)
Sträcktider / WinSplits = Stræktider / WinSplits Sträcktider / WinSplits = Stræktider / WinSplits
Sträcktider = Stræktider
Sträcktider i kolumner (för standardpapper) = Stræktider i kolonner (på standard papirformat) Sträcktider i kolumner (för standardpapper) = Stræktider i kolonner (på standard papirformat)
Sträcktider/WinSplits = Stræktider/WinSplits Sträcktider/WinSplits = Stræktider/WinSplits
Sträcktidsfil = Stræktidsfil Sträcktidsfil = Stræktidsfil
Sträcktidslista = Stræktidsliste
Sträcktidsutskrift = Udskriv stræktider Sträcktidsutskrift = Udskriv stræktider
Sträcktidsutskrift[check] = Udskriv stræktider automatisk Sträcktidsutskrift[check] = Udskriv stræktider automatisk
Sträcktilldelning, stafett = Turtildeling, stafet Sträcktilldelning, stafett = Turtildeling, stafet
@ -1799,8 +1849,8 @@ Säkerhetskopiering = Interval Backup
Sätt okända löpare utan registrering till <Ej Start> = Sæt ukendte løbere uden registrering til <Ikke startet> Sätt okända löpare utan registrering till <Ej Start> = Sæt ukendte løbere uden registrering til <Ikke startet>
Sätt som oparad = Sæt som uparret Sätt som oparad = Sæt som uparret
Sätter reptid (X) och omstartstid (Y) för = Sætter sidste skiftetid (X) og omstarttid (Y) for Sätter reptid (X) och omstartstid (Y) för = Sætter sidste skiftetid (X) og omstarttid (Y) for
Sök (X) = Søg (X)
Sök = Søg Sök = Søg
Sök (X) = Søg (X)
Sök deltagare = Søg deltagere Sök deltagare = Søg deltagere
Sök och starta automatiskt = Søg og start automatisk Sök och starta automatiskt = Søg og start automatisk
Sök på namn, bricka eller startnummer = Søg efter et navn, en brik eller et startnummer Sök på namn, bricka eller startnummer = Søg efter et navn, en brik eller et startnummer
@ -1808,8 +1858,8 @@ Sök symbol = Søg symbol
Söker efter SI-enheter = Søger efter SI-enheder Söker efter SI-enheter = Søger efter SI-enheder
TCP: Port %d, Nolltid: %s = TCP: Port %d, Nultid: %s TCP: Port %d, Nolltid: %s = TCP: Port %d, Nultid: %s
TRASIG( = DEFEKT( TRASIG( = DEFEKT(
Ta bort / slå ihop = Fjern / slå sammen
Ta bort = Fjern Ta bort = Fjern
Ta bort / slå ihop = Fjern / slå sammen
Ta bort eventuella avanmälda deltagare = Fjern evt. afmeldte deltagere Ta bort eventuella avanmälda deltagare = Fjern evt. afmeldte deltagere
Ta bort listposten = Fjern listeposten Ta bort listposten = Fjern listeposten
Ta bort markerad = Fjern valgte Ta bort markerad = Fjern valgte
@ -1823,9 +1873,12 @@ Team = Hold
Team Rogaining = Hold pointløb Team Rogaining = Hold pointløb
TeamBib = Holdets startnummer TeamBib = Holdets startnummer
TeamClub = Holdets klub TeamClub = Holdets klub
TeamCourseName = Banenavn for hold/tur
TeamCourseNumber = Banenummer for hold/tur
TeamFee = Holdafgift TeamFee = Holdafgift
TeamGlobal = Hold (klasser sammen) TeamGlobal = Hold (klasser sammen)
TeamGrossTime = Holdets tid før korrektion TeamGrossTime = Holdets tid før korrektion
TeamLegName = Navn på tur
TeamLegTimeAfter = Holdets tid efter på tur TeamLegTimeAfter = Holdets tid efter på tur
TeamLegTimeStatus = Holdets tid / status på tur TeamLegTimeStatus = Holdets tid / status på tur
TeamName = Holdets navn TeamName = Holdets navn
@ -1857,6 +1910,7 @@ Telefon = Telefon
Test = Test Test = Test
Test Result Module = Test resultatmodul Test Result Module = Test resultatmodul
Test av stämplingsinläsningar = Test af stemplingsindlæsninger Test av stämplingsinläsningar = Test af stemplingsindlæsninger
Testa = Test
Testa rösten = Afprøv stemme Testa rösten = Afprøv stemme
Testa servern = Test serveren Testa servern = Test serveren
Text = Tekst Text = Tekst
@ -1894,6 +1948,7 @@ Till huvudsidan = Til hovedside
Till kontroll = Til post Till kontroll = Til post
Till sista = Til sidste Till sista = Til sidste
Till vilka klasser = Til hvilke klasser Till vilka klasser = Til hvilke klasser
Tillagda: X = Tilføjede: X
Tilldela = Tildel Tilldela = Tildel
Tilldela avgifter = Tildel afgifter Tilldela avgifter = Tildel afgifter
Tilldela endast avgift till deltagare utan avgift = Tildel kun afgift til deltagere uden afgift Tilldela endast avgift till deltagare utan avgift = Tildel kun afgift til deltagere uden afgift
@ -1931,14 +1986,19 @@ Time: X = Tid: X
Timekeeping = Tidtagning Timekeeping = Tidtagning
TimingFrom = Navn på startpunkt TimingFrom = Navn på startpunkt
TimingTo = Navn på målpunkt TimingTo = Navn på målpunkt
Tips: ställ in rätt tid innan du lägger till fler grupper = Tip: Sæt korrekt tid ind, inden du tilføjer flere grupper
Tjänstebeställningar (IOF XML) = Bestilling af ydelser (IOF XML)
Tjänster (IOF XML) = Ydelser (IOF XML)
Tolkning av radiostämplingar med okänd typ = Fortolkning af stemplinger fra radiopost af ukendt type
Topplista, N bästa = Topliste, N bedste Topplista, N bästa = Topliste, N bedste
Total = Total Total = Total
Total tävlingsavgift = Total løbsafgift Total tävlingsavgift = Total løbsafgift
Total/team result at a control = Hold- og samlet resultat ved post
Total/team result at a control = Samlet/hold resultat ved en post Total/team result at a control = Samlet/hold resultat ved en post
TotalCounter = Primær tæller TotalCounter = Primær tæller
Totalresultat - X = Totalresultat - X TotalRunLength = Samlet løbsdistance
TotalRunTime = Samlet løbstid
Totalresultat = Totalresultat Totalresultat = Totalresultat
Totalresultat - X = Totalresultat - X
Totalt = Total Totalt = Total
Totalt antal etapper = Totalt antal etapper Totalt antal etapper = Totalt antal etapper
Totalt antal unika avbockade brickor: X = Samlet antal (unikke) afkrydsede brikker: X Totalt antal unika avbockade brickor: X = Samlet antal (unikke) afkrydsede brikker: X
@ -1964,8 +2024,8 @@ Tävlingens ID-nummer = Konkurrencens ID nummer
Tävlingens namn = Løbsnavn Tävlingens namn = Løbsnavn
Tävlingens namn: X = Løbets navn: X Tävlingens namn: X = Løbets navn: X
Tävlingsdata har sparats = Løbsdata er gemt Tävlingsdata har sparats = Løbsdata er gemt
Tävlingsinställningar (IOF, xml) = Løbsindstillinger (IOF, XML)
Tävlingsinställningar = Løbsopsætninger Tävlingsinställningar = Løbsopsætninger
Tävlingsinställningar (IOF, xml) = Løbsindstillinger (IOF, XML)
Tävlingsnamn = Løbsnavn Tävlingsnamn = Løbsnavn
Tävlingsrapport = Løbsrapport Tävlingsrapport = Løbsrapport
Tävlingsregler = Løbsreglement Tävlingsregler = Løbsreglement
@ -1985,15 +2045,17 @@ Undre gräns (år) = Nedre grænse (år)
Undre ålder = Laveste alder Undre ålder = Laveste alder
Unexpected Fee = Uventet tilmeldingsgebyr Unexpected Fee = Uventet tilmeldingsgebyr
Unfair control legs = Uretfærdige stræk Unfair control legs = Uretfærdige stræk
Unga, till och med X år = Unge op til (og med) X år
Ungdom = Ungdom Ungdom = Ungdom
Ungdomar och äldre kan få reducerad avgift = Unge og ældre kan få nedsat startafgift
Ungdomsavgift = Ungdomsafgift Ungdomsavgift = Ungdomsafgift
Ungdomsklasser = Ungdomsklasser Ungdomsklasser = Ungdomsklasser
Unknown symbol X = Ukendt symbol X Unknown symbol X = Ukendt symbol X
Unroll split times for loop courses = Udjævn splittider for loops Unroll split times for loop courses = Udjævn splittider for loops
Uppdatera = Opdater Uppdatera = Opdater
Uppdatera alla klubbar = Opdater alle klubber Uppdatera alla klubbar = Opdater alle klubber
Uppdatera alla värden i tabellen (X) = Opdater alle værdier i tabellen (X)
Uppdatera alla värden i tabellen = Opdater alle værdier i tabellen Uppdatera alla värden i tabellen = Opdater alle værdier i tabellen
Uppdatera alla värden i tabellen (X) = Opdater alle værdier i tabellen (X)
Uppdatera från Eventor = Opdater fra Eventor Uppdatera från Eventor = Opdater fra Eventor
Uppdatera fördelning = Opdater fordeling Uppdatera fördelning = Opdater fordeling
Uppdatera fördelningen av starttider med hänsyn till manuella ändringar ovan = Opdater fordelingen af starttider med hensyn til manuelle ændringer ovenfor Uppdatera fördelningen av starttider med hänsyn till manuella ändringar ovan = Opdater fordelingen af starttider med hensyn til manuelle ændringer ovenfor
@ -2004,8 +2066,8 @@ Uppdatera klubbarnas uppgifter med data från löpardatabasen/distriktsregistret
Uppdatera klubbens uppgifter med data från löpardatabasen/distriktsregistret = Opdater oplysninger om klub med data fra løberdatabasen Uppdatera klubbens uppgifter med data från löpardatabasen/distriktsregistret = Opdater oplysninger om klub med data fra løberdatabasen
Uppdatera löpardatabasen = Opdater løberdatabasen Uppdatera löpardatabasen = Opdater løberdatabasen
Uppdaterade: X = Oppdaterede: X Uppdaterade: X = Oppdaterede: X
Urval %c%s = Udvælg %c%s
Urval = Sorter efter Urval = Sorter efter
Urval %c%s = Udvælg %c%s
Use initials in names = Brug initialer i navne Use initials in names = Brug initialer i navne
User input number = Bruger defineret input parameter User input number = Bruger defineret input parameter
Utan inställningar = Uden indstillinger Utan inställningar = Uden indstillinger
@ -2020,16 +2082,16 @@ Uthyrda: X, Egna: Y, Avbockade uthyrda: Z = Lejede: X, Private: Y, Lejede/afkryd
Utom tävlan = Udenfor konkurrance OOC Utom tävlan = Udenfor konkurrance OOC
Utrymme: X = Plads: X Utrymme: X = Plads: X
Utseende = Udseende Utseende = Udseende
Utskrift / export = Udskrift / Eksport
Utskrift = Udskrift Utskrift = Udskrift
Utskrift / export = Udskrift / Eksport
Utskriftsintervall (MM:SS) = Udskriftsinterval (MM:SS) Utskriftsintervall (MM:SS) = Udskriftsinterval (MM:SS)
Utökat protokoll = Udvidet protokol Utökat protokoll = Udvidet protokol
VALFRI( = VALGFRI( VALFRI( = VALGFRI(
Vacancies and entry cancellations = Vakante og sletning af tilmeldinger Vacancies and entry cancellations = Vakante og sletning af tilmeldinger
Vak. ranking = Vak. rangliste Vak. ranking = Vak. rangliste
Vakanser = Vakante
Vakanser - X = Vakante - X Vakanser - X = Vakante - X
Vakanser / klassbyte = Vakante / skift klasse Vakanser / klassbyte = Vakante / skift klasse
Vakanser = Vakante
Vakanser och efteranmälda = Vakante og eftertilmeldte Vakanser och efteranmälda = Vakante og eftertilmeldte
Vakanser stöds ej i stafett = Vakante understøttes ikke i stafet Vakanser stöds ej i stafett = Vakante understøttes ikke i stafet
Vakansplacering = Vacansplacering Vakansplacering = Vacansplacering
@ -2060,6 +2122,7 @@ Varning: avgiften kan ej faktureras = Advarsel: gebyr kan ikke faktureres
Varning: deltagare med blankt namn påträffad. MeOS kräver att alla deltagare har ett namn, och tilldelar namnet 'N.N.' = Advarsel: Der er fundet en løber uden tildelt navn. MeOS kræver at alle løbere har et navn. MeOS har tildelt navnet 'N.N.' Varning: deltagare med blankt namn påträffad. MeOS kräver att alla deltagare har ett namn, och tilldelar namnet 'N.N.' = Advarsel: Der er fundet en løber uden tildelt navn. MeOS kræver at alle løbere har et navn. MeOS har tildelt navnet 'N.N.'
Varning: lag utan namn påträffat. MeOS kräver att alla lag har ett namn, och tilldelar namnet 'N.N.' = Advarsel: Der er fundet et hold uden tildelt navn. MeOS kræver at hold har et navn og har tildelt navnet 'N.N.' Varning: lag utan namn påträffat. MeOS kräver att alla lag har ett namn, och tilldelar namnet 'N.N.' = Advarsel: Der er fundet et hold uden tildelt navn. MeOS kræver at hold har et navn og har tildelt navnet 'N.N.'
Varning: ändringar i X blev överskrivna = Advarsel: ændringerne i X blev overskrevet Varning: ändringar i X blev överskrivna = Advarsel: ændringerne i X blev overskrevet
Varningar i X = Advarsel i X
Varvningskontroll = Sløjfepost Varvningskontroll = Sløjfepost
Varvräkning = Tæl omgange Varvräkning = Tæl omgange
Varvräkning med mellantid = Tæl omgange med mellemtider Varvräkning med mellantid = Tæl omgange med mellemtider
@ -2134,6 +2197,7 @@ Välj alla = Vælg alle
Välj alla klasser = Vælg alle klasser Välj alla klasser = Vælg alle klasser
Välj allt = Vælg alle Välj allt = Vælg alle
Välj automatiskt = Vælg automatisk Välj automatiskt = Vælg automatisk
Välj deltagare för förhandsgranskning = Vælg deltagere for forhåndsundersøgelse
Välj den etapp som föregår denna tävling = Vælg den etape der går forud for dette løb Välj den etapp som föregår denna tävling = Vælg den etape der går forud for dette løb
Välj den etapp som kommer efter denna tävling = Vælg den etape som følger efter dette løb Välj den etapp som kommer efter denna tävling = Vælg den etape som følger efter dette løb
Välj en vakant plats nedan = Vælg en vakant plads nedenfor Välj en vakant plats nedan = Vælg en vakant plads nedenfor
@ -2170,8 +2234,8 @@ Vänster = Venstre
Växel = Skifte Växel = Skifte
Växling = Veksling Växling = Veksling
Webb = Web Webb = Web
Webbdokument (html) = Webdokument (html)
Webbdokument = Webdokument Webbdokument = Webdokument
Webbdokument (html) = Webdokument (html)
Webben (html) = Webben (html) Webben (html) = Webben (html)
Without courses = Uden baner Without courses = Uden baner
X (Saknar e-post) = X (Mangler email) X (Saknar e-post) = X (Mangler email)
@ -2192,11 +2256,13 @@ X platser. Startar Y = X pladser. Starter Y
X poäng fattas = X points mangler X poäng fattas = X points mangler
X rader kunde inte raderas = X rækker kunne ikke slettes X rader kunde inte raderas = X rækker kunne ikke slettes
X senaste = X seneste X senaste = X seneste
X stämplingar = X stemplinger
X är inget giltigt index = X er ikke et gyldigt indeks X är inget giltigt index = X er ikke et gyldigt indeks
X är inget giltigt sträcknummer = X er ikke et gyldigt turnummer X är inget giltigt sträcknummer = X er ikke et gyldigt turnummer
X: Y. Tryck <Enter> för att spara = X: Y. Tryk <Enter> for at gemme X: Y. Tryck <Enter> för att spara = X: Y. Tryk <Enter> for at gemme
X:e = X'e X:e = X'e
Year of birth = Førdselsår Year of birth = Førdselsår
Youth Cup X = Ungdoms Cup X
Zooma in (Ctrl + '+') = Zoom ind (Ctrl + '+') Zooma in (Ctrl + '+') = Zoom ind (Ctrl + '+')
Zooma ut (Ctrl + '-') = Zoom ud (Ctrl + '-') Zooma ut (Ctrl + '-') = Zoom ud (Ctrl + '-')
[Bevaka] = [Overvåg] [Bevaka] = [Overvåg]
@ -2278,7 +2344,6 @@ help:33940 = Importer tilmeldingsdata i fritekstformat. Angiv Navn, Klub, Klasse
help:41072 = Marker i listen af stemplinger for at slette eller ændre tiden. Manglende stemplinger kan tilføjes fra baneskabelon. Mangler måltid får løberen status udgået. Mangler stempling får løberen status fejlstempling. Det er ikke muligt at sætte en status på en løber som ikke passer med løberens stemplingsdata. Hvis der er en målstempling skal tiden for denne ændres for at ændre måltiden; det samme gælder for startstempling. help:41072 = Marker i listen af stemplinger for at slette eller ændre tiden. Manglende stemplinger kan tilføjes fra baneskabelon. Mangler måltid får løberen status udgået. Mangler stempling får løberen status fejlstempling. Det er ikke muligt at sætte en status på en løber som ikke passer med løberens stemplingsdata. Hvis der er en målstempling skal tiden for denne ændres for at ændre måltiden; det samme gælder for startstempling.
help:41641 = Udfyld første starttid og startinterval. Lodtrækning indebærer tilfældig lodtrækning, SOFT-lodtrækning en lodtrækning i overensstemmelse med SOFT:s klubfordelingsregler. Klyngestart indebærer at hele klassen starter i småklynger med det interval du angiver ("forlænget" fællesstart). \n\nAngiv interval 0 for samlet start.\n\nStartnumre: Angiv første nummer eller efterlad blankt for ingen startnumre. I feltet ture (Tur) angiver du hvilken tur der skal lodtrækkes (hvis klassen har flere ture). help:41641 = Udfyld første starttid og startinterval. Lodtrækning indebærer tilfældig lodtrækning, SOFT-lodtrækning en lodtrækning i overensstemmelse med SOFT:s klubfordelingsregler. Klyngestart indebærer at hele klassen starter i småklynger med det interval du angiver ("forlænget" fællesstart). \n\nAngiv interval 0 for samlet start.\n\nStartnumre: Angiv første nummer eller efterlad blankt for ingen startnumre. I feltet ture (Tur) angiver du hvilken tur der skal lodtrækkes (hvis klassen har flere ture).
help:425188 = Du kan automatisk håndtere <Ikke startet> ved at indlæse fra SI-enhed(er) (Clear, Check eller Start post) i SportIdent Config+ (Read out Station), gemme indlæsningen som en semikolonsepareret tekstfil og importere denne i MeOS. De løbere som forekommer i denne import får en registrering. Derefter kan du sætte <Ikke Startet> på løbere uden registrering. Indlæser du senere flere løbere kan du ændre de løbere som tidligere har fået <Ikke Startet> men nu har fået registrering.\n\nDu kan også løbende få indlæst status af løberne ved at lade dine Check enheder i starten være radioposter. Det kommer så løbende ind i programmet. Husk postnummer for Check skal være '3'. help:425188 = Du kan automatisk håndtere <Ikke startet> ved at indlæse fra SI-enhed(er) (Clear, Check eller Start post) i SportIdent Config+ (Read out Station), gemme indlæsningen som en semikolonsepareret tekstfil og importere denne i MeOS. De løbere som forekommer i denne import får en registrering. Derefter kan du sætte <Ikke Startet> på løbere uden registrering. Indlæser du senere flere løbere kan du ændre de løbere som tidligere har fået <Ikke Startet> men nu har fået registrering.\n\nDu kan også løbende få indlæst status af løberne ved at lade dine Check enheder i starten være radioposter. Det kommer så løbende ind i programmet. Husk postnummer for Check skal være '3'.
info:readoutbase = Aktivér SI-enheden ved at vælge den rette COM-port, eller ved at søge efter installerede SI-enheder. Info giver dig information om den valgte enhed/port. For at aflæse brikker skal enheden være programmeret uden autosend (for radioposter bruges dog autosend). Udvidet protokol anbefales, da det giver en mere stabil forbindelse. Enheden programmeres med SPORTidents program SportIdent Config+.\n\nHvis du bruger SPORTident SRR radioposter gælder der følgende reggler for postnumre:\nNormale poster skal have et nummer fra 31 til 255.\nStartpost(er) skal have postnummer=1.\nPostenhed med Check skal have postnummer =3\nPoster med numrene 2 samt 4-30 håndteres som Mål.\n\nInteraktiv aflæsning anvendes hvis du vil håndtere eventuelle problemer med forkerte briknumre ved aflæsningen; afmarker hvis det i stedet skal foregå f.eks. ved 'Klagemuren' eller på på stævnekontoret.\n\nLøberdatabasen bruges hvis du automatisk vil tilføje indkomne løbere ved hjælp af løberdatabasen. Løberens stemplinger bruges til at vælge den rigtige klasse.
help:50431 = Du er nu koblet op mod en server. For at åbne et løb fra serveren, marker det i listen og vælg åbn. For at tilføje et løb til serveren, åbn først løbet lokalt, og brug derefter knappen upload løb. Når du har åbnet et løb på på serveren ser du hvilke andre MeOS-klienter som er tilsluttet til serveren.\n\nHvis der efter løbet står (på server) er løbet åbnet på en server og kan deles af andre MeOS-klienter. Står der (lokalt) kan man kun tilgå løbet fra den aktuelle computer. help:50431 = Du er nu koblet op mod en server. For at åbne et løb fra serveren, marker det i listen og vælg åbn. For at tilføje et løb til serveren, åbn først løbet lokalt, og brug derefter knappen upload løb. Når du har åbnet et løb på på serveren ser du hvilke andre MeOS-klienter som er tilsluttet til serveren.\n\nHvis der efter løbet står (på server) er løbet åbnet på en server og kan deles af andre MeOS-klienter. Står der (lokalt) kan man kun tilgå løbet fra den aktuelle computer.
help:52726 = Tilslut til en server, se nedenfor. \n\nInstallation:\nHent og installer MySQL 5 (Community Edition) fra www.mysql.com, standardindstillinger anbefales. MySQL behøver kun at være installeret på den computer der skal være server. Start derefter et MySQL Administrationsprogram som phpMyAdmin og opret en brugerkonto for MeOS. Hvis du bruger MySQL Command Line Client og vil oprette en brugerkonto for MeOS er kommandoerne:\n\n> CREATE USER meos;\n> GRANT ALL ON *.* TO meos;\n\nDu har nu oprettet en bruger meos (med blankt password). Angiv serverens navn nedenfor (hvis du ikke kan få forbindelse så kontroller evt. firewall).\n\nEt alternativ er at bruge MySQL's indbyggede rodkonto, det vil sige, brugernavn 'root' og det password du angav ved installationen af MySQL. help:52726 = Tilslut til en server, se nedenfor. \n\nInstallation:\nHent og installer MySQL 5 (Community Edition) fra www.mysql.com, standardindstillinger anbefales. MySQL behøver kun at være installeret på den computer der skal være server. Start derefter et MySQL Administrationsprogram som phpMyAdmin og opret en brugerkonto for MeOS. Hvis du bruger MySQL Command Line Client og vil oprette en brugerkonto for MeOS er kommandoerne:\n\n> CREATE USER meos;\n> GRANT ALL ON *.* TO meos;\n\nDu har nu oprettet en bruger meos (med blankt password). Angiv serverens navn nedenfor (hvis du ikke kan få forbindelse så kontroller evt. firewall).\n\nEt alternativ er at bruge MySQL's indbyggede rodkonto, det vil sige, brugernavn 'root' og det password du angav ved installationen af MySQL.
help:5422 = Fandt ingen SI-enhed(er). Er de(n) tilsluttet og startet? help:5422 = Fandt ingen SI-enhed(er). Er de(n) tilsluttet og startet?
@ -2336,11 +2401,19 @@ help_autodraw = Indtast første (ordinære) starttid, mindste startinterval (ind
help_draw = Lodtrækning udføres i to trin. Først angiver du hvilke klasser du vil lodtrække og foretager de grundlæggende indstillinger. Når du trykker på <Fordel starttider> anvender MeOS indstillingerne til at fordele starttiderne mellem klasserne. MeOS sørger for at klasser med baner der ligner hinanden ikke starter samtidigt og tager hensyn til allerede lodtrukne klasser. Målet er et jævnt flow af startende.\n\nFordelingen præsenteres i en tabel, hvor du kan tilføje dine egne ændringer og eventuelt lade MeOS foretage en ny fordeling i fohold til dine ændringer. Når du er tilfreds med fordelingen lader du MeOS trække lod blandt de valgte klasser.\n\nDe grundlæggende indstillinger som skal foretages er første starttid og mindste startinterval. Indstillingen maks. samtidigt startende angiver hvormange løbere som må starte samtidigt. En større værdi giver en kortere startdybde.\n\nAndel vakante angiver om MeOS skal lodtrække vakante pladser ind i startfeltet. Angiv 0% for ingen vakante. Forventet antal eftertilmeldte bruges til at reservere plads i startfeltet for eftertilmeldte. Ingen vakante pladser indsættes, men der efterlades plads i startlisten med garanti for at ingen samtidigt startende skal have samme bane. help_draw = Lodtrækning udføres i to trin. Først angiver du hvilke klasser du vil lodtrække og foretager de grundlæggende indstillinger. Når du trykker på <Fordel starttider> anvender MeOS indstillingerne til at fordele starttiderne mellem klasserne. MeOS sørger for at klasser med baner der ligner hinanden ikke starter samtidigt og tager hensyn til allerede lodtrukne klasser. Målet er et jævnt flow af startende.\n\nFordelingen præsenteres i en tabel, hvor du kan tilføje dine egne ændringer og eventuelt lade MeOS foretage en ny fordeling i fohold til dine ændringer. Når du er tilfreds med fordelingen lader du MeOS trække lod blandt de valgte klasser.\n\nDe grundlæggende indstillinger som skal foretages er første starttid og mindste startinterval. Indstillingen maks. samtidigt startende angiver hvormange løbere som må starte samtidigt. En større værdi giver en kortere startdybde.\n\nAndel vakante angiver om MeOS skal lodtrække vakante pladser ind i startfeltet. Angiv 0% for ingen vakante. Forventet antal eftertilmeldte bruges til at reservere plads i startfeltet for eftertilmeldte. Ingen vakante pladser indsættes, men der efterlades plads i startlisten med garanti for at ingen samtidigt startende skal have samme bane.
htmlhelp = HTML kan eksporteres som en struktureret tabel eller som et frit formateret dokument (mere i stil med MeOS lister). Du kan også bruge eksporter skabeloner med egen formatering: kolonner, JavaScript base page flips, automatisk rulning, o.s.v. Det er muligt at tilføje egne skabeloner ved at tilføje '.template' filer i MeOS mappen. Hvis du bruger skabeloner er der et antal parametre der skal angives, se nedenfor. Den præcise fortolkning af parametrene afhænger af skabelonen.\n\nHvis du vælger <Store Settings> bliver listen og dens opsætning gemt permanent i løbet. Du kan så tilgå listen ved at bruge MeOS som Web server (Tjenesten 'Information Server') eller ved at eksportere listen ved jævne mellemrum. htmlhelp = HTML kan eksporteres som en struktureret tabel eller som et frit formateret dokument (mere i stil med MeOS lister). Du kan også bruge eksporter skabeloner med egen formatering: kolonner, JavaScript base page flips, automatisk rulning, o.s.v. Det er muligt at tilføje egne skabeloner ved at tilføje '.template' filer i MeOS mappen. Hvis du bruger skabeloner er der et antal parametre der skal angives, se nedenfor. Den præcise fortolkning af parametrene afhænger af skabelonen.\n\nHvis du vælger <Store Settings> bliver listen og dens opsætning gemt permanent i løbet. Du kan så tilgå listen ved at bruge MeOS som Web server (Tjenesten 'Information Server') eller ved at eksportere listen ved jævne mellemrum.
info:advanceinfo = Det var ikke muligt at starte tjesten for forhåndsinformation om resultat. Resultatet vil komme med nogle skunders forsinkelse. Dette kan forventes hvis der kører flere udgaver at MeOS på maskinen samtidigt. info:advanceinfo = Det var ikke muligt at starte tjesten for forhåndsinformation om resultat. Resultatet vil komme med nogle skunders forsinkelse. Dette kan forventes hvis der kører flere udgaver at MeOS på maskinen samtidigt.
info:customsplitprint = Man kan lave sine egne lister for udskrift af stræktider. Design listen og brug funktionen Split time list i Ret liste... for at ændre udskriften af stræktider.\n\n Man kan styre valget af liste for hver klasse ved at bruge Tabelindstilling.
info:mapcontrol = MeOS kan ikke afgøre typen af SPORTident enhed med mindre den er direkte forbundet til computeren. Derfor bruges postnummeret til at bestemme typen af enhed. Dy kan styre fortolkningen nedenfor. Postnumre over 30 fortolkes altis som postenheder. \n\n Vær forsigtig med at bruge start Si-enheder. En stempling heri vil automatisk overskrive starttiden fra løbsprogrammet.
info:multieventnetwork = For at administrere flere etaper skal du arbejde lokalt. Gem en kopi af løbet, åbn den lokalt og overfør resultat til næste etape. Derefter uploader du næste etape til serveren for at afvikle den derfra. info:multieventnetwork = For at administrere flere etaper skal du arbejde lokalt. Gem en kopi af løbet, åbn den lokalt og overfør resultat til næste etape. Derefter uploader du næste etape til serveren for at afvikle den derfra.
info:multiple_start = En løber kan foretage flere løb med den samme brik. Der dannes en ny tilmelding efter hver aflæsning.
info:nosplitprint = Kan ikke finde den angivne stræktidsliste.\n\nI stedet for bruges standardlisten.
info:pageswithcolumns = Vis listen en side af gangen med det angivne antal kolonner. Genindlæs listen automatisk efter hvert gennemløb. info:pageswithcolumns = Vis listen en side af gangen med det angivne antal kolonner. Genindlæs listen automatisk efter hvert gennemløb.
info:readout_action = X: Brik Y aflæst.\nManuel behandling er nødvendig. info:readout_action = X: Brik Y aflæst.\nManuel behandling er nødvendig.
info:readout_queue = X: Brik Y aflæst.\nBrikken er sat i kø. info:readout_queue = X: Brik Y aflæst.\nBrikken er sat i kø.
info:readoutbase = Aktivér SI-enheden ved at vælge den rette COM-port, eller ved at søge efter installerede SI-enheder. Info giver dig information om den valgte enhed/port. For at aflæse brikker skal enheden være programmeret uden autosend (for radioposter bruges dog autosend). Udvidet protokol anbefales, da det giver en mere stabil forbindelse. Enheden programmeres med SPORTidents program SportIdent Config+.\n\nHvis du bruger SPORTident SRR radioposter gælder der følgende reggler for postnumre:\nNormale poster skal have et nummer fra 31 til 255.\nStartpost(er) skal have postnummer=1.\nPostenhed med Check skal have postnummer =3\nPoster med numrene 2 samt 4-30 håndteres som Mål.\n\nInteraktiv aflæsning anvendes hvis du vil håndtere eventuelle problemer med forkerte briknumre ved aflæsningen; afmarker hvis det i stedet skal foregå f.eks. ved 'Klagemuren' eller på på stævnekontoret.\n\nLøberdatabasen bruges hvis du automatisk vil tilføje indkomne løbere ved hjælp af løberdatabasen. Løberens stemplinger bruges til at vælge den rigtige klasse.
info:readoutmore = Lås funktionen for at undgå at den ændres ved et uheld. \n\nMed Valg af lyd kan du vælge hvilken lyd der skal spilles når en brik aflæses.\n\n Åbn Aflæsningsvindue viser information i et nyt vindue, vendt mod løberen, der viser information om seneste aflæsning.\n\nFlere løb per deltager kan bruges hvis løberen har lov til at foretage flere forsøg. Der dannes en ny tilmelding for hver aflæsning af brikken.
info:readoutwindow = Aflæsningsvinduet viser information fra den seneste aflæsning af en Si-brik
info:runnerdbonline = Da du er tilsluttet en server er det ikke muligt at redigere klub og løberdatabase manuelt. Foretag ændringer før løbet uploades til serveren. Det er muligt at erstatte den eksisterende database på serveren ved at importere en ny database (fra IOF-XML). info:runnerdbonline = Da du er tilsluttet en server er det ikke muligt at redigere klub og løberdatabase manuelt. Foretag ændringer før løbet uploades til serveren. Det er muligt at erstatte den eksisterende database på serveren ved at importere en ny database (fra IOF-XML).
info:teamcourseassignment = Den importerede fil indeholder information om gafflinger. Løbet er nødt til at svare til gafflingerne for at filoen kan importeres: \n\n1. Sørg for at alle klasser er sat op med det rette antal ture. \n2. Sørg for brystnumre i alle klasser. brug 'Hurtigindstillinger' på faneblad 'Klasser' og intast første brystnummer for hver klasse (det giver automatisk tildeling af brystnumre). Det er også muligt først at importere hold og derefter tildele brystnumre på normal vis. \n3. Importer banerne. Det kan gøres flere gange hvis gafflingerne skal opdateres.
info_shortening = Vælg en eksisterende bane der afkortes til den nuværende bane. Det er muligt med flere niveauer af afkortning. info_shortening = Vælg en eksisterende bane der afkortes til den nuværende bane. Det er muligt med flere niveauer af afkortning.
inforestwarning = Der skulle ikke være flere løbere i skoven. De de data analysen er baseret på kan være forkerte, bør du som arrangør dog også checke dette på anden måde. inforestwarning = Der skulle ikke være flere løbere i skoven. De de data analysen er baseret på kan være forkerte, bør du som arrangør dog også checke dette på anden måde.
kartor = kort kartor = kort
@ -2348,7 +2421,6 @@ klar = færdig
kontroll = post kontroll = post
kontroll X (Y) = post X (Y) kontroll X (Y) = post X (Y)
leder med X = fører med X leder med X = fører med X
leder med X = fører med X
leder med X; har tappat Y = fører med X; har tabt Y leder med X; har tappat Y = fører med X; har tabt Y
leder med X; sprang Y snabbare än de jagande = fører med X; løb Y hurtigere end de efterfølgende leder med X; sprang Y snabbare än de jagande = fører med X; løb Y hurtigere end de efterfølgende
listinfo:inputresults = Vis resultater af tidligere dele. listinfo:inputresults = Vis resultater af tidligere dele.
@ -2357,8 +2429,8 @@ localhost = localhost
lopp = løb lopp = løb
min/km = min/km min/km = min/km
mål = mål mål = mål
målet (X) = målet (X)
målet = målet målet = målet
målet (X) = målet (X)
newcmp:featuredesc = Vælg hvilke funktioner i MeOS du har brug for i dette løb. Du kan fjerne eller tilføje faciliteter nårsomhelst ved at vælge <MeOS Faciliteter> på siden Løb. newcmp:featuredesc = Vælg hvilke funktioner i MeOS du har brug for i dette løb. Du kan fjerne eller tilføje faciliteter nårsomhelst ved at vælge <MeOS Faciliteter> på siden Løb.
nia = ni nia = ni
nionde = niende nionde = niende
@ -2371,6 +2443,7 @@ prefsAddress = Forvalgt adresse
prefsAdvancedClassSettings = Vis avancerade klassindstillninger prefsAdvancedClassSettings = Vis avancerade klassindstillninger
prefsAutoSaveTimeOut = Interval for automatisk backup (ms) prefsAutoSaveTimeOut = Interval for automatisk backup (ms)
prefsAutoTie = Knyt automatisk Si brik til løber prefsAutoTie = Knyt automatisk Si brik til løber
prefsAutoTieRent = Automatisk håndtering af lejebiler.
prefsCardFee = Forvalgt Si brik leje prefsCardFee = Forvalgt Si brik leje
prefsClient = Klientnavn i netværket prefsClient = Klientnavn i netværket
prefsCodePage = Tegnsæt for 8-bits text vid im- og export prefsCodePage = Tegnsæt for 8-bits text vid im- og export
@ -2390,6 +2463,9 @@ prefsEMail = Arrangør email
prefsEliteFee = Standard elite startgebyr prefsEliteFee = Standard elite startgebyr
prefsEntryFee = Standard startgebyr prefsEntryFee = Standard startgebyr
prefsEventorBase = URL til Eventor prefsEventorBase = URL til Eventor
prefsExpResFilename = Standard eksport filnavn
prefsExpTypeIOF = Standard eksport type
prefsExpWithRaceNo = Inkluder løbsnummer ved eksport
prefsExportCSVSplits = Inkluder mellemtider i csv export prefsExportCSVSplits = Inkluder mellemtider i csv export
prefsExportFormat = Foretrukket eksportformat prefsExportFormat = Foretrukket eksportformat
prefsFirstInvoice = Nummmer på næste faktura prefsFirstInvoice = Nummmer på næste faktura
@ -2493,6 +2569,7 @@ växlar på X plats med tiden Y = skifter på X plads med tiden Y
växlar på X plats, efter Y, på tiden Z = skifter på X plads, efter Y, med tiden Z växlar på X plats, efter Y, på tiden Z = skifter på X plads, efter Y, med tiden Z
växlar på delad X plats med tiden Y = skifter på en delt X plads med tiden Y växlar på delad X plats med tiden Y = skifter på en delt X plads med tiden Y
warn:changedtimezero = Ændrer nultiden for et løb der er i gang, hvilket ikke kan anbefales.\n\nVil du fortsætte alligevel? warn:changedtimezero = Ændrer nultiden for et løb der er i gang, hvilket ikke kan anbefales.\n\nVil du fortsætte alligevel?
warn:changeid = Advarsel, feltet External ID bruges normalt til at matche registreringer mod andre databaser (så som tilmeldings- resultat og økonomisystemer). Hvis du laver ændringer her kan der opstå uforståelige problemer.
warn:latestarttime = At bruge en starttid mere end X timer efter nulltid bør undgås da ældre Si-brikker kun har et 12 timers ur.\n\nVil du alligevel bruge starttiden? warn:latestarttime = At bruge en starttid mere end X timer efter nulltid bør undgås da ældre Si-brikker kun har et 12 timers ur.\n\nVil du alligevel bruge starttiden?
warn:missingResult = X deltagere savner stadigvæk registreringer og medtages derfor ikke.\n\nDu kan bruge løbere-i-skoven til at tildele resterende deltagare status <Ej Startet>. warn:missingResult = X deltagere savner stadigvæk registreringer og medtages derfor ikke.\n\nDu kan bruge løbere-i-skoven til at tildele resterende deltagare status <Ej Startet>.
warn:mysqlbinlog = Ydelsesadvarsel: Kunne inte lukke for binær loggning hvilket kan gøre overførslen langsom.\n\nX warn:mysqlbinlog = Ydelsesadvarsel: Kunne inte lukke for binær loggning hvilket kan gøre overførslen langsom.\n\nX
@ -2508,6 +2585,7 @@ warning:has_entries = Klassen har allerede løbere. Hvis du ændrer turfordeling
warning:has_results = Klassen har allerede resultater. Ændring af turfordelingen er usædvanligt.\n\nVil du fortsætte? warning:has_results = Klassen har allerede resultater. Ændring af turfordelingen er usædvanligt.\n\nVil du fortsætte?
xml-data = XML data xml-data = XML data
Äldre protokoll = Ældre protokol Äldre protokoll = Ældre protokol
Äldre, från och med X år = Ældre X år eller mere
Ändra = Skift Ändra = Skift
Ändra MeOS lokala systemegenskaper = Skift MeOS lokale systemegenskaber Ändra MeOS lokala systemegenskaper = Skift MeOS lokale systemegenskaber
Ändra X = Ændr X Ändra X = Ændr X
@ -2532,18 +2610,19 @@ xml-data = XML data
Återgå = Gå tilbage Återgå = Gå tilbage
Återskapa = Gendan Återskapa = Gendan
Återskapa tidigare sparade fönster- och speakerinställningar = Gendan vidues- og speakerindstillinger. Återskapa tidigare sparade fönster- och speakerinställningar = Gendan vidues- og speakerindstillinger.
Återställ = Fortryd
Återställ / uppdatera klasstillhörighet = Gendan / opdater klassetilhørsforhold Återställ / uppdatera klasstillhörighet = Gendan / opdater klassetilhørsforhold
Återställ <Ej Start> till <Status Okänd> = Tilbagefør <Ej Startet> till <Status ukendt> Återställ <Ej Start> till <Status Okänd> = Tilbagefør <Ej Startet> till <Status ukendt>
Återställ = Fortryd
Återställ löpare <Ej Start> med registrering till <Status Okänd> = Gendan løber med status <Ikke startet> til <Status ukendt> Återställ löpare <Ej Start> med registrering till <Status Okänd> = Gendan løber med status <Ikke startet> til <Status ukendt>
Återställ säkerhetskopia = Gendan fra sikkerhedskopi Återställ säkerhetskopia = Gendan fra sikkerhedskopi
Återställ tabeldesignen och visa allt = Gendan tabeldesign og vis alt Återställ tabeldesignen och visa allt = Gendan tabeldesign og vis alt
Åtgärd krävs = Handling påkrævet
ÅÅÅÅ-MM-DD = ÅÅÅÅ-MM-DD ÅÅÅÅ-MM-DD = ÅÅÅÅ-MM-DD
Ökande = Stigende Ökande = Stigende
Öppen = Åben Öppen = Åben
Öppen klass = Åben klasse Öppen klass = Åben klasse
Öppna = Åbn Öppna = Åbn
Öppna = Åbne Öppna avläsningsfönster = Åbn aflæsningsvindue
Öppna fil = Åbn fil Öppna fil = Åbn fil
Öppna från aktuell tävling = Åbn fra aktuelt løb Öppna från aktuell tävling = Åbn fra aktuelt løb
Öppna föregående = Åbn foregående Öppna föregående = Åbn foregående

View File

@ -126,7 +126,7 @@ void Download::initInternet() {
throw meosException(error); throw meosException(error);
} }
DWORD dwTimeOut = 180 * 1000; DWORD dwTimeOut = 60 * 10 * 1000;
InternetSetOption(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwTimeOut, sizeof(DWORD)); InternetSetOption(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwTimeOut, sizeof(DWORD));
InternetSetOption(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &dwTimeOut, sizeof(DWORD)); InternetSetOption(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &dwTimeOut, sizeof(DWORD));
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -748,7 +748,7 @@ TextInfo &gdioutput::addTimer(int yp, int xp, int format, DWORD zeroTime, int xl
GUICALLBACK cb, int timeOut, const wchar_t *fontFace) { GUICALLBACK cb, int timeOut, const wchar_t *fontFace) {
hasAnyTimer = true; hasAnyTimer = true;
DWORD zt=GetTickCount()-1000*zeroTime; DWORD zt=GetTickCount()-1000*zeroTime;
wstring text = getTimerText(zeroTime, format); wstring text = getTimerText(zeroTime, format, true);
addStringUT(yp, xp, format, text, xlimit, cb, fontFace); addStringUT(yp, xp, format, text, xlimit, cb, fontFace);
TextInfo &ti=TL.back(); TextInfo &ti=TL.back();
@ -996,12 +996,14 @@ TextInfo& gdioutput::addStringUT(int yp, int xp, int format, const wstring& text
calcStringSize(TI, hDC); calcStringSize(TI, hDC);
if (xlimit == 0 || (format & (textRight | textCenter)) == 0) { if (xlimit == 0 || (format & (textRight | textCenter)) == 0) {
updatePos(TI.textRect.right + OffsetX, TI.yp, scaleLength(10), updatePosTight(TI.textRect.left, TI.yp,
TI.textRect.bottom - TI.textRect.top + scaleLength(2)); TI.realWidth, TI.textRect.bottom - TI.textRect.top,
scaleLength(10), scaleLength(2));
} }
else { else {
updatePos(TI.xp, TI.yp, TI.realWidth + scaleLength(10), updatePosTight(TI.xp, TI.yp,
TI.textRect.bottom - TI.textRect.top + scaleLength(2)); TI.realWidth, TI.textRect.bottom - TI.textRect.top,
scaleLength(10), scaleLength(2));
} }
ReleaseDC(hWndTarget, hDC); ReleaseDC(hWndTarget, hDC);
maxTextBlockHeight = max<int>(maxTextBlockHeight, 1 + TI.textRect.bottom - TI.textRect.top); maxTextBlockHeight = max<int>(maxTextBlockHeight, 1 + TI.textRect.bottom - TI.textRect.top);
@ -1191,12 +1193,6 @@ ButtonInfo &ButtonInfo::setDefault()
} }
void ButtonInfo::moveButton(gdioutput &gdi, int nxp, int nyp) { void ButtonInfo::moveButton(gdioutput &gdi, int nxp, int nyp) {
/*WINDOWPLACEMENT wpl;
GetWindowPlacement(hWnd, &wpl);
wpl.
SetWindowPos*/
//SetWindowPos(hWnd, NULL, xp, yp, 0, 0,
xp = nxp; xp = nxp;
yp = nyp; yp = nyp;
int w, h; int w, h;
@ -2140,7 +2136,7 @@ bool gdioutput::autoGrow(const char *id) {
ReleaseDC(hWndTarget, hDC); ReleaseDC(hWndTarget, hDC);
size += scaleLength(20); size += scaleLength(30);
if (size > it->width) { if (size > it->width) {
it->width = size; it->width = size;
SetWindowPos(it->hWnd, 0, 0, 0, (int)it->width, (int)it->height, SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOMOVE); SetWindowPos(it->hWnd, 0, 0, 0, (int)it->width, (int)it->height, SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOMOVE);
@ -2173,7 +2169,7 @@ bool gdioutput::autoGrow(const char *id) {
} }
ReleaseDC(hWndTarget, hDC); ReleaseDC(hWndTarget, hDC);
size += scaleLength(20); size += scaleLength(30);
if (size > it->width) { if (size > it->width) {
it->width = size; it->width = size;
SetWindowPos(it->hWnd, 0, 0, 0, (int)it->width, (int)it->height, SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOMOVE); SetWindowPos(it->hWnd, 0, 0, 0, (int)it->width, (int)it->height, SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOMOVE);
@ -3618,8 +3614,7 @@ bool gdioutput::hasData(const char *id) const {
return getData(id, dummy); return getData(id, dummy);
} }
bool gdioutput::updatePosTight(int x, int y, int width, int height, int marginx, int marginy) {
bool gdioutput::updatePos(int x, int y, int width, int height) {
int ox = MaxX; int ox = MaxX;
int oy = MaxY; int oy = MaxY;
@ -3646,14 +3641,19 @@ bool gdioutput::updatePos(int x, int y, int width, int height) {
} }
if (flowDirection == FlowDirection::Down) { if (flowDirection == FlowDirection::Down) {
CurrentY = max(y + height, CurrentY); CurrentY = max(y + height + marginy, CurrentY);
} }
else if (flowDirection == FlowDirection::Right) { else if (flowDirection == FlowDirection::Right) {
CurrentX = max(x + width, CurrentX); CurrentX = max(x + width + marginx, CurrentX);
} }
return changed; return changed;
} }
bool gdioutput::updatePos(int x, int y, int width, int height) {
return updatePosTight(x, y, width, height, 0, 0);
}
void gdioutput::adjustDimension(int width, int height) void gdioutput::adjustDimension(int width, int height)
{ {
int ox = MaxX; int ox = MaxX;
@ -4924,13 +4924,15 @@ bool gdioutput::RemoveFirstInfoBox(const string &id)
} }
wstring gdioutput::getTimerText(int zeroTime, int format) wstring gdioutput::getTimerText(int zeroTime, int format, bool timeInSeconds) {
{
TextInfo temp; TextInfo temp;
temp.zeroTime=0; temp.zeroTime=0;
//memset(&temp, 0, sizeof(TextInfo)); //memset(&temp, 0, sizeof(TextInfo));
temp.format=format; temp.format=format;
if (timeInSeconds)
return getTimerText(&temp, 1000*zeroTime); return getTimerText(&temp, 1000*zeroTime);
else
return getTimerText(&temp, (1000/timeUnitsPerSecond) * zeroTime);
} }
wstring gdioutput::getTimerText(TextInfo *tit, DWORD T) wstring gdioutput::getTimerText(TextInfo *tit, DWORD T)

View File

@ -531,7 +531,7 @@ public:
void formatString(const TextInfo& ti, HDC hDC) const; void formatString(const TextInfo& ti, HDC hDC) const;
static wstring getTimerText(TextInfo* tit, DWORD T); static wstring getTimerText(TextInfo* tit, DWORD T);
static wstring getTimerText(int ZeroTime, int format); static wstring getTimerText(int ZeroTime, int format, bool timeInSeconds);
void fadeOut(string Id, int ms); void fadeOut(string Id, int ms);
void setWaitCursor(bool wait); void setWaitCursor(bool wait);
@ -629,6 +629,8 @@ public:
void popY() { CurrentY = SY; } void popY() { CurrentY = SY; }
bool updatePos(int x, int y, int width, int height); bool updatePos(int x, int y, int width, int height);
bool updatePosTight(int x, int y, int width, int height, int marginx, int marginy);
void adjustDimension(int width, int height); void adjustDimension(int width, int height);
/** Return a selected item*/ /** Return a selected item*/

View File

@ -333,7 +333,7 @@ void IOF30Interface::classCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
xmlList xClsId; xmlList xClsId;
xClsAssignment.getObjects("ClassId", xClsId); xClsAssignment.getObjects("ClassId", xClsId);
for (size_t j = 0; j <xClsId.size(); j++) { for (size_t j = 0; j <xClsId.size(); j++) {
int id = xClsId[j].getInt(); int id = xClsId[j].getInt() + classIdOffset;
if (oe.getClass(id) == 0) { if (oe.getClass(id) == 0) {
gdi.addString("", 0, "Klass saknad").setColor(colorRed); gdi.addString("", 0, "Klass saknad").setColor(colorRed);
} }
@ -1145,7 +1145,7 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
t->synchronize(true); t->synchronize(true);
} }
// If multi, for each class, store how the legs was multiplied // If multi, for each class, store how the legs were multiplied
if (hasMulti) { if (hasMulti) {
vector<int> key(it->second.size()); vector<int> key(it->second.size());
for (size_t j = 0; j < key.size(); j++) for (size_t j = 0; j < key.size(); j++)
@ -2898,10 +2898,14 @@ void IOF30Interface::FeeInfo::add(IOF30Interface::FeeInfo &fi) {
} }
pClass IOF30Interface::readClass(const xmlobject &xclass, pClass IOF30Interface::readClass(const xmlobject &xclass,
map<int, vector<LegInfo> > &teamClassConfig) { map<int, vector<LegInfo>> &teamClassConfig) {
if (!xclass) if (!xclass)
return 0; return 0;
int classId = xclass.getObjectInt("Id"); int classId = xclass.getObjectInt("Id");
int origId = classId;
if (classId > 0)
classId += classIdOffset;
wstring name, shortName, longName; wstring name, shortName, longName;
xclass.getObjectString("Name", name); xclass.getObjectString("Name", name);
xclass.getObjectString("ShortName", shortName); xclass.getObjectString("ShortName", shortName);
@ -2911,7 +2915,7 @@ pClass IOF30Interface::readClass(const xmlobject &xclass,
name = shortName; name = shortName;
} }
pClass pc = 0; pClass pc = nullptr;
if (classId) { if (classId) {
pc = oe.getClass(classId); pc = oe.getClass(classId);
@ -2921,8 +2925,12 @@ pClass IOF30Interface::readClass(const xmlobject &xclass,
pc = oe.addClass(c); pc = oe.addClass(c);
} }
} }
else else {
pc = oe.addClass(name); pc = oe.addClass(name);
}
if (origId > 0)
pc->setExtIdentifier(origId);
oDataInterface DI = pc->getDI(); oDataInterface DI = pc->getDI();
if (!pc->hasFlag(oClass::TransferFlags::FlagManualName)) { if (!pc->hasFlag(oClass::TransferFlags::FlagManualName)) {
@ -3657,7 +3665,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
} }
void IOF30Interface::writeFees(xmlparser &xml, const oRunner &r) const { void IOF30Interface::writeFees(xmlparser &xml, const oRunner &r) const {
int cardFee = r.getDCI().getInt("CardFee"); int cardFee = max(0, r.getDCI().getInt("CardFee"));
bool paidCard = r.getDCI().getInt("Paid") >= cardFee; bool paidCard = r.getDCI().getInt("Paid") >= cardFee;
writeAssignedFee(xml, r, paidCard ? cardFee : 0); writeAssignedFee(xml, r, paidCard ? cardFee : 0);

View File

@ -74,6 +74,9 @@ class IOF30Interface {
// Include data on stage number // Include data on stage number
bool includeStageRaceInfo; bool includeStageRaceInfo;
int classIdOffset = 0;
int courseIdOffset = 0;
const IOF30Interface &operator=(const IOF30Interface &) = delete; const IOF30Interface &operator=(const IOF30Interface &) = delete;
set<wstring> matchedClasses; set<wstring> matchedClasses;
@ -302,7 +305,14 @@ class IOF30Interface {
public: public:
IOF30Interface(oEvent *oe, bool forceSplitFee, bool useEventorQuirks); IOF30Interface(oEvent *oe, bool forceSplitFee, bool useEventorQuirks);
virtual ~IOF30Interface() {} virtual ~IOF30Interface() = default;
void setIdOffset(int classIdOffsetIn, int courseIdOffsetIn) {
classIdOffset = classIdOffsetIn;
assert(courseIdOffsetIn == 0);
courseIdOffset = courseIdOffsetIn;
}
static void getLocalDateTime(const wstring &datetime, wstring &dateOut, wstring &timeOut); static void getLocalDateTime(const wstring &datetime, wstring &dateOut, wstring &timeOut);

View File

@ -66,7 +66,7 @@ void ListEditor::setCurrentList(MetaList *lst) {
currentList = lst; currentList = lst;
} }
void ListEditor::load(const MetaListContainer &mlc, int index) { int ListEditor::load(const MetaListContainer &mlc, int index, bool autoSaveCopy) {
const MetaList &mc = mlc.getList(index); const MetaList &mc = mlc.getList(index);
setCurrentList(new MetaList()); setCurrentList(new MetaList());
*currentList = mc; *currentList = mc;
@ -74,6 +74,14 @@ void ListEditor::load(const MetaListContainer &mlc, int index) {
if (mlc.isInternal(index)) { if (mlc.isInternal(index)) {
currentIndex = -1; currentIndex = -1;
currentList->clearTag(); currentList->clearTag();
wstring cpy = lang.tl(L" Kopia (X)#" + getLocalDate());
currentList->setListName(currentList->getListName() + cpy);
if (autoSaveCopy) {
oe->getListContainer().addExternal(*currentList);
currentIndex = oe->getListContainer().getNumLists() - 1;
oe->getListContainer().saveList(currentIndex, *currentList);
}
} }
else else
currentIndex = index; currentIndex = index;
@ -81,6 +89,7 @@ void ListEditor::load(const MetaListContainer &mlc, int index) {
dirtyExt = true; dirtyExt = true;
dirtyInt = false; dirtyInt = false;
savedFileName.clear(); savedFileName.clear();
return currentIndex;
} }
void ListEditor::show(TabBase *dst, gdioutput &gdi) { void ListEditor::show(TabBase *dst, gdioutput &gdi) {
@ -101,7 +110,7 @@ void ListEditor::show(gdioutput &gdi) {
int bx = gdi.getCX(); int bx = gdi.getCX();
int by = gdi.getCY(); int by = gdi.getCY();
gdi.fillDown();
if (currentList) if (currentList)
gdi.addString("", boldLarge, makeDash(L"Listredigerare - X#") + currentList->getListName()); gdi.addString("", boldLarge, makeDash(L"Listredigerare - X#") + currentList->getListName());
else else
@ -655,6 +664,10 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
spInfo->withSpeed = gdi.isChecked("Speed"); spInfo->withSpeed = gdi.isChecked("Speed");
spInfo->withResult = gdi.isChecked("Result"); spInfo->withResult = gdi.isChecked("Result");
spInfo->withAnalysis = gdi.isChecked("Analysis"); spInfo->withAnalysis = gdi.isChecked("Analysis");
auto res = gdi.getSelectedItem("NumResult");
if (res.second)
spInfo->numClassResults = res.first;
list.setSplitPrintInfo(spInfo); list.setSplitPrintInfo(spInfo);
} }
@ -781,7 +794,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
else if (bi.id == "DoOpen" || bi.id == "DoOpenCopy" ) { else if (bi.id == "DoOpen" || bi.id == "DoOpenCopy" ) {
ListBoxInfo lbi; ListBoxInfo lbi;
if (gdi.getSelectedItem("OpenList", lbi)) { if (gdi.getSelectedItem("OpenList", lbi)) {
load(oe->getListContainer(), lbi.data); load(oe->getListContainer(), lbi.data, false);
} }
if (bi.id == "DoOpenCopy") { if (bi.id == "DoOpenCopy") {
@ -1405,7 +1418,7 @@ void ListEditor::editImage(gdioutput& gdi, const MetaListPost& mlp, int id) {
gdi.addString("", 0, "Förskjutning:"); gdi.addString("", 0, "Förskjutning:");
gdi.dropLine(-1); gdi.dropLine(-1);
gdi.addInput("ImgOffsetX", xoff, 5, editListCB, L"Horizontell:"); gdi.addInput("ImgOffsetX", xoff, 5, editListCB, L"Horisontell:");
gdi.addInput("ImgOffsetY", yoff, 5, editListCB, L"Vertikal:"); gdi.addInput("ImgOffsetY", yoff, 5, editListCB, L"Vertikal:");
gdi.popX(); gdi.popX();
@ -1842,7 +1855,7 @@ void ListEditor::editListProp(gdioutput &gdi, bool newList) {
gdi.setCX(gdi.getCX()+20); gdi.setCX(gdi.getCX()+20);
int f = list.getFontFaceFactor(k); int f = list.getFontFaceFactor(k);
wstring ff = f == 0 ? L"100 %" : itow(f) + L" %"; wstring ff = f == 0 ? L"100 %" : itow(f) + L" %";
gdi.addInput("FontFactor" + itos(k), ff, 4, 0, L"Skalfaktor", L"Relativ skalfaktor för typsnittets storlek i procent"); gdi.addInput("FontFactor" + itos(k), ff, 5, 0, L"Skalfaktor", L"Relativ skalfaktor för typsnittets storlek i procent");
f = list.getExtraSpace(k); f = list.getExtraSpace(k);
gdi.addInput("ExtraSpace" + itos(k), itow(f), 4, 0, L"Avstånd", L"Extra avstånd ovanför textblock"); gdi.addInput("ExtraSpace" + itos(k), itow(f), 4, 0, L"Avstånd", L"Extra avstånd ovanför textblock");
if (k == 1) { if (k == 1) {
@ -1892,6 +1905,7 @@ void ListEditor::statusSplitPrint(gdioutput& gdi, bool status) {
gdi.setInputStatus("Speed", status); gdi.setInputStatus("Speed", status);
gdi.setInputStatus("Result", status); gdi.setInputStatus("Result", status);
gdi.setInputStatus("Analysis", status); gdi.setInputStatus("Analysis", status);
gdi.setInputStatus("NumResult", status);
} }
void ListEditor::splitPrintList(gdioutput& gdi) { void ListEditor::splitPrintList(gdioutput& gdi) {
@ -1934,16 +1948,32 @@ void ListEditor::splitPrintList(gdioutput& gdi) {
gdi.addCheckbox("Result", "Inkludera individuellt resultat", nullptr, isSP ? sp->withResult : true); gdi.addCheckbox("Result", "Inkludera individuellt resultat", nullptr, isSP ? sp->withResult : true);
gdi.addCheckbox("Analysis", "Inkludera bomanalys", nullptr, isSP ? sp->withAnalysis : true); gdi.addCheckbox("Analysis", "Inkludera bomanalys", nullptr, isSP ? sp->withAnalysis : true);
int maxX = gdi.getCX();
gdi.setCX(x1 + margin);
gdi.dropLine(2);
gdi.addSelection("NumResult", 200, 400, nullptr, L"Topplista, N bästa");
vector<pair<wstring, size_t>> items;
for (int i = 1; i <= 10; i++)
items.emplace_back(itow(i), i);
for (int i = 15; i <= 50; i+=5)
items.emplace_back(itow(i), i);
for (int i = 60; i <= 100; i += 10)
items.emplace_back(itow(i), i);
items.emplace_back(lang.tl("Alla"), 1000);
gdi.addItem("NumResult", items);
gdi.selectItemByData("NumResult", isSP ? sp->numClassResults : 3);
statusSplitPrint(gdi, isSP); statusSplitPrint(gdi, isSP);
gdi.dropLine(0.8); gdi.dropLine(0.8);
gdi.setCX(gdi.getCX() + 20); gdi.setCX(gdi.getCX() + gdi.scaleLength(40));
gdi.addButton("ApplySplitList", "OK", editListCB); gdi.addButton("ApplySplitList", "OK", editListCB);
gdi.addButton("Cancel", "Avbryt", editListCB); gdi.addButton("Cancel", "Avbryt", editListCB);
gdi.dropLine(3); gdi.dropLine(3);
int maxY = gdi.getCY(); int maxY = gdi.getCY();
int maxX = gdi.getCX(); maxX = max(maxX, gdi.getCX());
gdi.fillDown(); gdi.fillDown();
gdi.popX(); gdi.popX();

View File

@ -112,7 +112,7 @@ public:
ListEditor(oEvent *oe); ListEditor(oEvent *oe);
virtual ~ListEditor(); virtual ~ListEditor();
void load(const MetaListContainer &mlc, int index); int load(const MetaListContainer &mlc, int index, bool autoSaveCopy);
void show(TabBase *dst, gdioutput &gdi); void show(TabBase *dst, gdioutput &gdi);
bool isShown(TabBase *tab) const { return origin == tab; } bool isShown(TabBase *tab) const { return origin == tab; }
MetaList *getCurrentList() const {return currentList;}; MetaList *getCurrentList() const {return currentList;};

View File

@ -1,6 +1,6 @@
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2023 Melin Software HB Copyright (C) 2009-2022 Melin Software HB
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -457,21 +457,43 @@ void LocalizerImpl::loadTable(const vector<string> &raw, const wstring &language
string nline = "\n"; string nline = "\n";
for (size_t k=0;k<raw.size();k++) { for (size_t k=0;k<raw.size();k++) {
const string &s = raw[order[k]]; const string &s = raw[order[k]];
int pos = s.find_first_of('='); size_t pos = s.find_first_of('=');
if (pos==string::npos) if (pos==string::npos)
throw std::exception("Bad file format."); throw std::exception("Bad file format.");
int spos = pos; size_t spos = pos;
int epos = pos+1; size_t epos = pos+1;
while (spos>0 && s[spos-1]==' ') const unsigned char *udata = (const unsigned char*)s.data();
spos--;
while (unsigned(epos)<s.size() && s[epos]==' ') // Trim spaces
while (spos > 0) {
if (isspace(udata[spos - 1]))
spos--;
else if (udata[spos - 1] == 0xC2 && spos > 1 && udata[spos - 2] == 0xA0) //NBSP
spos -= 2;
else
break;
}
while (epos < s.size()) {
if (isspace(udata[epos]))
epos++; epos++;
else if (udata[epos] == 0xC2 && epos + 1 < s.size() && udata[epos + 1] == 0xA0) //NBSP
epos += 2;
else
break;
}
string key = s.substr(0, spos); string key = s.substr(0, spos);
string value = s.substr(epos); string value = s.substr(epos);
if (value.empty())
throw std::exception("Bad file format.");
if (value.size() > 1 && value[0] == 'Â') {
value = value.substr(2);
}
int nl = value.find("\\n"); int nl = value.find("\\n");
while (nl!=string::npos) { while (nl!=string::npos) {
value.replace(nl, 2, nline); value.replace(nl, 2, nline);

View File

@ -313,6 +313,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
lang.get().addLangResource(L"Français", L"110"); lang.get().addLangResource(L"Français", L"110");
lang.get().addLangResource(L"Español", L"111"); lang.get().addLangResource(L"Español", L"111");
lang.get().addLangResource(L"Russian", L"107"); lang.get().addLangResource(L"Russian", L"107");
lang.get().addLangResource(L"Ukrainian", L"112");
if (fileExists(L"extra.lng")) { if (fileExists(L"extra.lng")) {
lang.get().addLangResource(L"Extraspråk", L"extra.lng"); lang.get().addLangResource(L"Extraspråk", L"extra.lng");

View File

@ -159,8 +159,8 @@ __int64 SystemTimeToInt64TenthSecond(const SYSTEMTIME &st) {
ULARGE_INTEGER u; ULARGE_INTEGER u;
u.HighPart = ft.dwHighDateTime; u.HighPart = ft.dwHighDateTime;
u.LowPart = ft.dwLowDateTime; u.LowPart = ft.dwLowDateTime;
__int64 qp = u.QuadPart; __int64 qp = u.QuadPart; // Time resolution 100 ns
qp /= __int64(1000 * 1000 * timeUnitsPerSecond); qp /= __int64(1000 * 1000 * 10 / timeUnitsPerSecond);
return qp; return qp;
} }
@ -168,8 +168,8 @@ SYSTEMTIME Int64TenthSecondToSystemTime(__int64 time) {
SYSTEMTIME st; SYSTEMTIME st;
FILETIME ft; FILETIME ft;
ULARGE_INTEGER u; ULARGE_INTEGER u; // Time resolution 100 ns
u.QuadPart = time * __int64(1000 * 1000 * timeUnitsPerSecond); u.QuadPart = time * __int64(1000 * 1000 * 10 / timeUnitsPerSecond);
ft.dwHighDateTime = u.HighPart; ft.dwHighDateTime = u.HighPart;
ft.dwLowDateTime = u.LowPart; ft.dwLowDateTime = u.LowPart;
@ -680,9 +680,6 @@ const wstring &formatTime(int rt, SubSecond mode) {
swprintf_s(bf, L"%d:%02d:%02d.%d", rt / timeConstHour, (rt / timeConstMinute) % 60, (rt / timeConstSecond) % 60, rt%timeConstSecond); swprintf_s(bf, L"%d:%02d:%02d.%d", rt / timeConstHour, (rt / timeConstMinute) % 60, (rt / timeConstSecond) % 60, rt%timeConstSecond);
else else
swprintf_s(bf, L"%d:%02d.%d", (rt / timeConstMinute), (rt / timeConstSecond) % 60, rt%timeConstSecond); swprintf_s(bf, L"%d:%02d.%d", (rt / timeConstMinute), (rt / timeConstSecond) % 60, rt%timeConstSecond);
} }
res = bf; res = bf;
return res; return res;

View File

@ -7,6 +7,7 @@
#define IDR_3007 109 #define IDR_3007 109
#define IDR_3008 110 #define IDR_3008 110
#define IDR_3011 111 #define IDR_3011 111
#define IDR_3012 112
#define SND_OK 50 #define SND_OK 50
#define SND_LEADER 51 #define SND_LEADER 51
#define SND_NOTOK 52 #define SND_NOTOK 52
@ -20,6 +21,8 @@ IDR_3005 300 DISCARDABLE "russian.lng"
IDR_3006 300 DISCARDABLE "czech.lng" IDR_3006 300 DISCARDABLE "czech.lng"
IDR_3008 300 DISCARDABLE "french.lng" IDR_3008 300 DISCARDABLE "french.lng"
IDR_3011 300 DISCARDABLE "spanish.lng" IDR_3011 300 DISCARDABLE "spanish.lng"
IDR_3012 300 DISCARDABLE "ukrainian.lng"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
SND_OK WAVE DISCARDABLE "./sound/ok.wav" SND_OK WAVE DISCARDABLE "./sound/ok.wav"

View File

@ -25,17 +25,17 @@
//ABCDEFGHIJKLMNOP //ABCDEFGHIJKLMNOP
int getMeosBuild() { int getMeosBuild() {
string revision("$Rev: 1225 $"); string revision("$Rev: 1263 $");
return 174 + atoi(revision.substr(5, string::npos).c_str()); return 174 + atoi(revision.substr(5, string::npos).c_str());
} }
wstring getMeosDate() { wstring getMeosDate() {
wstring date(L"$Date: 2023-02-08 19:30:10 +0100 (ons, 08 feb 2023) $"); wstring date(L"$Date: 2023-05-12 16:11:34 +0200 (fre, 12 maj 2023) $");
return date.substr(7,10); return date.substr(7,10);
} }
wstring getBuildType() { wstring getBuildType() {
return L"Beta 1"; // No parantheses (...) return L"U1"; // No parantheses (...)
} }
wstring getMajorVersion() { wstring getMajorVersion() {
@ -103,7 +103,6 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
supp.emplace_back(L"Säterbygdens OK"); supp.emplace_back(L"Säterbygdens OK");
supp.emplace_back(L"OK Orinto"); supp.emplace_back(L"OK Orinto");
supp.emplace_back(L"Trosabygdens OK"); 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"Hans Wilhelmsson, Säffle OK");
supp.emplace_back(L"Cent Vallées Orientation 12 (C.V.O. 12)"); supp.emplace_back(L"Cent Vallées Orientation 12 (C.V.O. 12)");
supp.emplace_back(L"OK Tyr, Karlstad"); supp.emplace_back(L"OK Tyr, Karlstad");
@ -129,13 +128,19 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
supp.emplace_back(L"Mats Kågeson"); supp.emplace_back(L"Mats Kågeson");
supp.emplace_back(L"Lerums SOK"); supp.emplace_back(L"Lerums SOK");
supp.emplace_back(L"OSC Hamburg"); supp.emplace_back(L"OSC Hamburg");
supp.emplace_back(L"HEYRIES, ACA Aix en Provence");
developSupp.emplace_back(L"IFK Mora OK"); developSupp.emplace_back(L"IFK Mora OK");
supp.emplace_back(L"OK Rodhen"); supp.emplace_back(L"OK Rodhen");
supp.emplace_back(L"Big Foot Orienteers"); supp.emplace_back(L"Big Foot Orienteers");
developSupp.emplace_back(L"OK Måsen"); developSupp.emplace_back(L"OK Måsen");
supp.emplace_back(L"Ligue PACA"); supp.emplace_back(L"Ligue PACA");
supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice"); supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice");
supp.emplace_back(L"Foothills Wanderers Orienteering Club");
supp.emplace_back(L"Per Eklöf / PE Design / PE Timing");
supp.emplace_back(L"HEYRIES, ACA Aix en Provence");
supp.emplace_back(L"Järla Orientering");
supp.emplace_back(L"Kvarnsvedens GOIF OK");
supp.emplace_back(L"Ingemar Lindström, OK Österåker");
supp.emplace_back(L"OK Österåker");
reverse(supp.begin(), supp.end()); reverse(supp.begin(), supp.end());
} }

View File

@ -398,7 +398,7 @@ void oListParam::getCustomTitle(wchar_t *t) const
} }
bool oListParam::filterInclude(int count, const oAbstractRunner *r) const { bool oListParam::filterInclude(int count, const oAbstractRunner *r) const {
return filterMaxPer == 0 || count <= filterMaxPer || (r != nullptr && r == alwaysInclude); return filterMaxPer == 0 || count <= filterMaxPer || (r != nullptr && r->matchAbstractRunner(alwaysInclude));
} }
const wstring &oListParam::getCustomTitle(const wstring &t) const const wstring &oListParam::getCustomTitle(const wstring &t) const
@ -591,7 +591,8 @@ void MetaList::addRow(int ix) {
data[ix].push_back(vector<MetaListPost>()); data[ix].push_back(vector<MetaListPost>());
} }
static void setFixedWidth(oPrintPost &added, static void setFixedWidth(const gdioutput &gdi,
oPrintPost &added,
const map<tuple<int,int,int>, int> &indexPosToWidth, const map<tuple<int,int,int>, int> &indexPosToWidth,
int type, int j, int k, int type, int j, int k,
const MetaListPost &mlp) { const MetaListPost &mlp) {
@ -606,7 +607,7 @@ static void setFixedWidth(oPrintPost &added,
else { else {
map<tuple<int, int, int>, int>::const_iterator res = indexPosToWidth.find(tuple<int, int, int>(type, j, k)); map<tuple<int, int, int>, int>::const_iterator res = indexPosToWidth.find(tuple<int, int, int>(type, j, k));
if (res != indexPosToWidth.end()) if (res != indexPosToWidth.end())
added.fixedWidth = res->second; added.fixedWidth = int (res->second / gdi.getScale());
else else
added.fixedWidth = 0; added.fixedWidth = 0;
} }
@ -975,7 +976,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
fontFaces[MLHead].scale); fontFaces[MLHead].scale);
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLHead, j, k, mp); setFixedWidth(gdi, added, indexPosToWidth, MLHead, j, k, mp);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLHead, j, k)]; added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLHead, j, k)];
added.color = mp.color; added.color = mp.color;
if (!mp.mergeWithPrevious && mp.type != lImage) if (!mp.mergeWithPrevious && mp.type != lImage)
@ -1034,7 +1035,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
fontFaces[MLSubHead].scale); fontFaces[MLSubHead].scale);
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLSubHead, j, k, mp); setFixedWidth(gdi, added, indexPosToWidth, MLSubHead, j, k, mp);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubHead, j, k)]; added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubHead, j, k)];
added.color = mp.color; added.color = mp.color;
if (!mp.mergeWithPrevious && mp.type != lImage) if (!mp.mergeWithPrevious && mp.type != lImage)
@ -1096,7 +1097,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
fontFaces[MLList].scale); fontFaces[MLList].scale);
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLList, j, k, mp); setFixedWidth(gdi, added, indexPosToWidth, MLList, j, k, mp);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLList, j, k)]; added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLList, j, k)];
added.useStrictWidth = mp.getLimitBlockWidth(); added.useStrictWidth = mp.getLimitBlockWidth();
if (added.useStrictWidth) if (added.useStrictWidth)
@ -1160,7 +1161,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
base = &added; base = &added;
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLSubList, j, k, mp); setFixedWidth(gdi, added, indexPosToWidth, MLSubList, j, k, mp);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubList, j, k)]; added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubList, j, k)];
added.useStrictWidth = mp.getLimitBlockWidth(); added.useStrictWidth = mp.getLimitBlockWidth();
if (added.useStrictWidth) if (added.useStrictWidth)
@ -2201,6 +2202,7 @@ void MetaList::initSymbols() {
typeToSymbol[lRunnerName] = L"RunnerName"; typeToSymbol[lRunnerName] = L"RunnerName";
typeToSymbol[lRunnerGivenName] = L"RunnerGivenName"; typeToSymbol[lRunnerGivenName] = L"RunnerGivenName";
typeToSymbol[lRunnerFamilyName] = L"RunnerFamilyName"; typeToSymbol[lRunnerFamilyName] = L"RunnerFamilyName";
typeToSymbol[lRunnerLegTeamLeaderName] = L"RunnerLegTeamLeaderName";
typeToSymbol[lRunnerCompleteName] = L"RunnerCompleteName"; typeToSymbol[lRunnerCompleteName] = L"RunnerCompleteName";
typeToSymbol[lPatrolNameNames] = L"PatrolNameNames"; typeToSymbol[lPatrolNameNames] = L"PatrolNameNames";
typeToSymbol[lPatrolClubNameNames] = L"PatrolClubNameNames"; typeToSymbol[lPatrolClubNameNames] = L"PatrolClubNameNames";
@ -2870,6 +2872,10 @@ EStdListType MetaListContainer::getType(const int index) const {
return EStdListType(index + EFirstLoadedList); return EStdListType(index + EFirstLoadedList);
} }
bool MetaListContainer::isSplitPrintList(int index) const {
return data[index].second.isSplitPrintList();
}
void MetaListContainer::getLists(vector<pair<wstring, size_t> > &lists, bool markBuiltIn, void MetaListContainer::getLists(vector<pair<wstring, size_t> > &lists, bool markBuiltIn,
bool resultListOnly, bool noTeamList, bool onlyForSplitPrint) const { bool resultListOnly, bool noTeamList, bool onlyForSplitPrint) const {
lists.clear(); lists.clear();

View File

@ -500,6 +500,7 @@ public:
void saveList(int index, const MetaList &ml); void saveList(int index, const MetaList &ml);
bool isInternal(int index) const {return data[index].first == InternalList;} bool isInternal(int index) const {return data[index].first == InternalList;}
bool isExternal(int index) const {return data[index].first == ExternalList;} bool isExternal(int index) const {return data[index].first == ExternalList;}
bool isSplitPrintList(int index) const;
void updateGeneralResult(string tag, const shared_ptr<DynamicResult> &res); void updateGeneralResult(string tag, const shared_ptr<DynamicResult> &res);
void getGeneralResults(vector<DynamicResultRef> &resMod); void getGeneralResults(vector<DynamicResultRef> &resMod);

View File

@ -74,7 +74,7 @@ int TabCompetition::newGuideCB(gdioutput &gdi, int type, void *data)
try { try {
gdi.autoRefresh(true); gdi.autoRefresh(true);
FlowOperation res = saveEntries(gdi, false, true); FlowOperation res = saveEntries(gdi, false, 0, true);
if (res != FlowContinue) { if (res != FlowContinue) {
if (res == FlowCancel) if (res == FlowCancel)
newCompetitionGuide(gdi, 1); newCompetitionGuide(gdi, 1);

View File

@ -1513,6 +1513,24 @@ void oClass::getParallelRange(int leg, int &parLegRangeMin, int &parLegRangeMax)
} }
} }
void oClass::getParallelOptionalRange(int leg, int& parLegRangeMin, int& parLegRangeMax) const {
parLegRangeMin = leg;
while (parLegRangeMin > 0 && size_t(parLegRangeMin) < legInfo.size()) {
if (legInfo[parLegRangeMin].isParallel() || legInfo[parLegRangeMin].isOptional())
parLegRangeMin--;
else
break;
}
parLegRangeMax = leg;
while (size_t(parLegRangeMax + 1) < legInfo.size()) {
if (legInfo[parLegRangeMax + 1].isParallel() || legInfo[parLegRangeMax + 1].isOptional())
parLegRangeMax++;
else
break;
}
}
void oClass::getParallelCourseGroup(int leg, int startNo, vector< pair<int, pCourse> > &group) const { void oClass::getParallelCourseGroup(int leg, int startNo, vector< pair<int, pCourse> > &group) const {
group.clear(); group.clear();
// Assume hasUnorderedLegs // Assume hasUnorderedLegs
@ -4260,14 +4278,48 @@ pair<int, int> oClass::autoForking(const vector<vector<int>> &inputCourses, int
break; break;
} }
// Determine first bib in class (if defined)
wstring bibInfo = getDCI().getString("Bib");
wchar_t pattern[32];
int firstNumber = extractBibPattern(bibInfo, pattern);
if (firstNumber == 0) {
// Not explicitly defined. Look at any teams
vector<pTeam> tl;
oe->getTeams(getId(), tl);
int minBib = 10000000;
int minSN = 10000000;
for (pTeam t : tl) {
t->getBib();
int n = extractBibPattern(bibInfo, pattern);
if (n > 0)
minBib = std::min(minBib, n);
int no = t->getStartNo();
if (no > 0)
minSN = std::min(minSN, no);
}
if (minBib > 0)
firstNumber = minBib;
else if (minSN > 0)
firstNumber = minSN;
}
unsigned int off = 0;
if (firstNumber > 0) {
// index = (index-1) % courses.size();
unsigned firstCourse = unsigned(firstNumber - 1) % fperm.size();
off = fperm.size() - firstCourse;
}
set<int> coursesUsed; set<int> coursesUsed;
int lastSet = -1; int lastSet = -1;
for (int j = 0; j < legs; j++) { for (int j = 0; j < legs; j++) {
if (nf[j] > 0) { if (nf[j] > 0) {
lastSet = j; lastSet = j;
for (size_t k = 0; k < fperm.size(); k++) { for (size_t k = 0; k < fperm.size(); k++) {
coursesUsed.insert(courseMatrix[j][fperm[k]]->getId()); int kk = unsigned(k + off) % fperm.size();
addStageCourse(j, courseMatrix[j][fperm[k]], -1); coursesUsed.insert(courseMatrix[j][fperm[kk]]->getId());
addStageCourse(j, courseMatrix[j][fperm[kk]], -1);
} }
} }
else if (lastSet >= 0 && getLegType(j) == LTExtra) { else if (lastSet >= 0 && getLegType(j) == LTExtra) {
@ -4441,8 +4493,14 @@ pair<int, wstring> oClass::getNextBib() {
} }
} }
if (bibs.empty()) if (bibs.empty()) {
wstring bibInfo = getDCI().getString("Bib");
int firstNumber = extractBibPattern(bibInfo, pattern);
if (firstNumber > 0)
return make_pair(firstNumber, bibInfo);
return make_pair(0, _EmptyWString); return make_pair(0, _EmptyWString);
}
int candidate = -1; int candidate = -1;
for (set<int>::iterator it = bibs.begin(); it != bibs.end(); ++it) { for (set<int>::iterator it = bibs.begin(); it != bibs.end(); ++it) {
if (candidate > 0 && *it != candidate) { if (candidate > 0 && *it != candidate) {
@ -4702,11 +4760,14 @@ set<oClass::DrawSpecified> oClass::getDrawSpecification() const {
return res; return res;
} }
void oClass::initClassId(oEvent &oe) { void oClass::initClassId(oEvent &oe, const set<int>& classes) {
vector<pClass> cls; vector<pClass> cls;
oe.getClasses(cls, true); oe.getClasses(cls, true);
map<long long, wstring> id2Cls; map<long long, wstring> id2Cls;
for (size_t k = 0; k < cls.size(); k++) { for (size_t k = 0; k < cls.size(); k++) {
if (!classes.empty() && !classes.count(cls[k]->getId()))
continue;
long long extId = cls[k]->getExtIdentifier(); long long extId = cls[k]->getExtIdentifier();
if (extId > 0) { if (extId > 0) {
if (id2Cls.count(extId)) { if (id2Cls.count(extId)) {
@ -4718,8 +4779,11 @@ void oClass::initClassId(oEvent &oe) {
} }
// Generate external identifiers when not set // Generate external identifiers when not set
for (size_t k = 0; k < cls.size(); k++) { for (size_t k = 0; k < cls.size(); k++) {
if (!classes.empty() && !classes.count(cls[k]->getId()))
continue;
long long extId = cls[k]->getExtIdentifier(); long long extId = cls[k]->getExtIdentifier();
if (extId <= 0) { if (extId == 0) {
long long id = cls[k]->getId(); long long id = cls[k]->getId();
while (id2Cls.count(id)) { while (id2Cls.count(id)) {
id += 100000; id += 100000;

View File

@ -408,7 +408,7 @@ public:
void updateFinalClasses(oRunner *causingResult, bool updateStartNumbers); void updateFinalClasses(oRunner *causingResult, bool updateStartNumbers);
static void initClassId(oEvent &oe); static void initClassId(oEvent &oe, const set<int>& classes);
// Return true if forking in the class is locked // Return true if forking in the class is locked
bool lockedForking() const; bool lockedForking() const;
@ -730,6 +730,8 @@ public:
// Returns 0 for no parallel selection (= normal mode) // Returns 0 for no parallel selection (= normal mode)
pCourse selectParallelCourse(const oRunner &r, const SICard &sic); pCourse selectParallelCourse(const oRunner &r, const SICard &sic);
void getParallelRange(int leg, int &parLegRangeMin, int &parLegRangeMax) const; void getParallelRange(int leg, int &parLegRangeMin, int &parLegRangeMax) const;
void getParallelOptionalRange(int leg, int& parLegRangeMin, int& parLegRangeMax) const;
bool hasAnyCourse(const set<int> &crsId) const; bool hasAnyCourse(const set<int> &crsId) const;
GeneralResult *getResultModule() const; GeneralResult *getResultModule() const;

View File

@ -750,11 +750,11 @@ void oClub::generateInvoice(gdioutput &gdi, int &toPay, int &hasPaid,
for (map<int,int>::iterator it = data.paidPerMode.begin(); it != data.paidPerMode.end(); ++it) { for (map<int,int>::iterator it = data.paidPerMode.begin(); it != data.paidPerMode.end(); ++it) {
paidPerMode[it->first] += it->second; paidPerMode[it->first] += it->second;
} }
gdi.addString("", yp, xs, boldText, L"Att betala: X#" + oe->formatCurrency(toPay)); gdi.addString("", yp, xs, fontMediumPlus, L"Att betala: X#" + oe->formatCurrency(toPay));
gdi.updatePos(gdi.scaleLength(710),0,0,0); gdi.updatePos(gdi.scaleLength(710),0,0,0);
yp+=lh*2; yp+=int(lh*2.5);
gdi.addStringUT(yp, xs, normalText, lang.tl(L"Vänligen betala senast ") gdi.addStringUT(yp, xs, normalText, lang.tl(L"Vänligen betala senast ")
+ pdate + lang.tl(L" till ") + account + L"."); + pdate + lang.tl(L" till ") + account + L".");

View File

@ -452,11 +452,11 @@ const vector<pair<wstring, size_t>>& oEvent::fillControls(vector< pair<wstring,
if (res == existingTypeUnits.end()) { if (res == existingTypeUnits.end()) {
wstring name; wstring name;
if (tu.first == oPunch::SpecialPunch::PunchFinish) if (tu.first == oPunch::SpecialPunch::PunchFinish)
name = lang.tl("Målenhet") + L" " + itow(tu.second); name = lang.tl(L"Målenhet", true) + L" " + itow(tu.second);
else if (tu.first == oPunch::SpecialPunch::PunchStart) else if (tu.first == oPunch::SpecialPunch::PunchStart)
name = lang.tl("Startenhet") + L" " + itow(tu.second); name = lang.tl(L"Startenhet", true) + L" " + itow(tu.second);
else if (tu.first == oPunch::SpecialPunch::PunchCheck) else if (tu.first == oPunch::SpecialPunch::PunchCheck)
name = lang.tl("Checkenhet") + L" " + itow(tu.second); name = lang.tl(L"Checkenhet", true) + L" " + itow(tu.second);
out.emplace_back(name, tu.first * 1100000 + tu.second); out.emplace_back(name, tu.first * 1100000 + tu.second);
} }
else { else {

View File

@ -399,10 +399,8 @@ bool oDataContainer::setDate(void *data, const char *Name, const wstring &V)
else return false;//Not modified else return false;//Not modified
} }
const wstring& oDataContainer::getDate(const void* data, const wstring& oDataContainer::getDate(const void* data, const char* name) const {
const char* Name) const const oDataInfo* odi = findVariable(name);
{
const oDataInfo* odi = findVariable(Name);
if (!odi) if (!odi)
throw std::exception("oDataContainer: Variable not found."); throw std::exception("oDataContainer: Variable not found.");
@ -435,6 +433,31 @@ const wstring& oDataContainer::getDate(const void* data,
return res; return res;
} }
int oDataContainer::getYear(const void* data, const char *name) const {
const oDataInfo* odi = findVariable(name);
if (!odi)
throw std::exception("oDataContainer: Variable not found.");
if (odi->Type != oDTInt)
throw std::exception("oDataContainer: Variable of wrong type.");
LPBYTE vd = LPBYTE(data) + odi->Index;
int C = *((int*)vd);
if (odi->SubType == oISDateOrYear) {
if (C > 9999)
return C / 10000;
else if (C > 1900)
return C;
else
return 0;
}
else {
return C / 10000;
}
}
bool oDataContainer::write(const oBase *ob, xmlparser &xml) const { bool oDataContainer::write(const oBase *ob, xmlparser &xml) const {
void *data, *oldData; void *data, *oldData;
vector< vector<wstring> > *strptr; vector< vector<wstring> > *strptr;

View File

@ -180,7 +180,8 @@ public:
const wstring &formatString(const oBase *ob, const char *name) const; const wstring &formatString(const oBase *ob, const char *name) const;
bool setDate(void *data, const char *Name, const wstring &V); bool setDate(void *data, const char *Name, const wstring &V);
const wstring &getDate(const void *data, const char *Name) const; const wstring &getDate(const void *data, const char *name) const;
int getYear(const void* data, const char* name) const;
bool write(const oBase *ob, xmlparser &xml) const; bool write(const oBase *ob, xmlparser &xml) const;
void set(oBase *ob, const xmlobject &xo); void set(oBase *ob, const xmlobject &xo);
@ -298,8 +299,12 @@ public:
else return false; else return false;
} }
inline const wstring &getDate(const char *Name) const inline const wstring &getDate(const char *name) const
{return oDC->getDate(Data, Name);} {return oDC->getDate(Data, name);}
inline int getYear(const char* name) const {
return oDC->getYear(Data, name);
}
inline vector<InputInfo *> buildDataFields(gdioutput &gdi, int maxFieldSize) const inline vector<InputInfo *> buildDataFields(gdioutput &gdi, int maxFieldSize) const
{return oDC->buildDataFields(gdi, maxFieldSize);} {return oDC->buildDataFields(gdi, maxFieldSize);}
@ -398,9 +403,12 @@ public:
return oDC->formatString(oB, name); return oDC->formatString(oB, name);
} }
inline const wstring &getDate(const char *Name) const inline const wstring &getDate(const char *name) const
{return oDC->getDate(Data, Name);} {return oDC->getDate(Data, name);}
inline int getYear(const char* name) const {
return oDC->getYear(Data, name);
}
inline __int64 getInt64(const string &name) const inline __int64 getInt64(const string &name) const
{return oDC->getInt64(Data, name.c_str());} {return oDC->getInt64(Data, name.c_str());}

View File

@ -778,10 +778,10 @@ public:
void formatHeader(gdioutput& gdi, const oListInfo& li, const pRunner rInput); void formatHeader(gdioutput& gdi, const oListInfo& li, const pRunner rInput);
void generateList(gdioutput &gdi, bool reEvaluate, const oListInfo &li, bool updateScrollBars); void generateList(gdioutput &gdi, bool reEvaluate, const oListInfo &li, bool updateScrollBars);
void generateListInfo(oListParam &par, oListInfo &li); void generateListInfo(const gdioutput& target, oListParam &par, oListInfo &li);
void generateListInfo(vector<oListParam> &par, oListInfo &li); void generateListInfo(const gdioutput& target, vector<oListParam> &par, oListInfo &li);
void generateListInfo(EStdListType lt, const gdioutput &gdi, int classId, oListInfo &li); void generateListInfo(const gdioutput& target, EStdListType lt, int classId, oListInfo &li);
void generateListInfoAux(oListParam &par, oListInfo &li, const wstring &name); void generateListInfoAux(const gdioutput &target, oListParam &par, oListInfo &li, const wstring &name);
/** Format a string for a list. Returns true of output is not empty*/ /** Format a string for a list. Returns true of output is not empty*/
const wstring &formatListString(const oPrintPost &pp, const oListParam &par, const wstring &formatListString(const oPrintPost &pp, const oListParam &par,
@ -826,7 +826,7 @@ public:
//Speaker functions. //Speaker functions.
void speakerList(gdioutput &gdi, int classId, int leg, int controlId, void speakerList(gdioutput &gdi, int classId, int leg, int controlId,
int previousControlId, bool totalResults, bool shortNames); int previousControlId, bool totalResults, bool shortNames);
int getComputerTime() const {return (computerTime+500)/1000;} int getComputerTime() const {return timeConstSecond * ((computerTime+500)/1000);}
int getComputerTimeMS() const {return computerTime;} int getComputerTimeMS() const {return computerTime;}
void updateComputerTime(); void updateComputerTime();
@ -1023,7 +1023,7 @@ public:
bool forceSplitFee, bool forceSplitFee,
bool useEventorQuirks); bool useEventorQuirks);
bool exportOECSV(const wchar_t *file, int LanguageTypeIndex, bool includeSplits); bool exportOECSV(const wchar_t *file, const set<int> &classes, int LanguageTypeIndex, bool includeSplits);
bool save(); bool save();
void duplicate(const wstring &annotation, bool keepTags = false); void duplicate(const wstring &annotation, bool keepTags = false);
@ -1340,7 +1340,8 @@ public:
/** Import entry data */ /** Import entry data */
void importXML_EntryData(gdioutput &gdi, const wstring &file, void importXML_EntryData(gdioutput &gdi, const wstring &file,
bool updateClass, bool removeNonexisting, bool updateClass, bool removeNonexisting,
const set<int> &filter, const string &preferredIdType); const set<int> &filter, int classIdOffset,
int courseIdOffset, const string &preferredIdType);
protected: protected:
pClass getXMLClass(const xmlobject &xentry); pClass getXMLClass(const xmlobject &xentry);
@ -1376,6 +1377,21 @@ protected:
public: public:
/** Do some operation and disable (global) reevaluate/update */
template<typename OP>
void noReevaluateOperation(OP& operation) {
bool origState = disableRecalculate;
disableRecalculate = true;
try {
operation();
}
catch (...) {
disableRecalculate = origState;
throw;
}
disableRecalculate = origState;
}
/** Return true if subseconds are used*/ /** Return true if subseconds are used*/
bool useSubSecond() const; bool useSubSecond() const;

View File

@ -867,7 +867,7 @@ void oEvent::optimizeStartOrder(vector<pair<int, wstring>> &outLines, DrawInfo &
outLines.emplace_back(0, L"Identifierar X unika inledningar på banorna.#" + itow(di.numDistinctInit)); outLines.emplace_back(0, L"Identifierar X unika inledningar på banorna.#" + itow(di.numDistinctInit));
outLines.emplace_back(0, L"Största gruppen med samma inledning har X platser.#" + itow(di.numRunnerSameInitMax)); outLines.emplace_back(0, L"Största gruppen med samma inledning har X platser.#" + itow(di.numRunnerSameInitMax));
outLines.emplace_back(0, L"Antal löpare på vanligaste banan X.#" + itow(di.numRunnerSameCourseMax)); outLines.emplace_back(0, L"Antal löpare på vanligaste banan X.#" + itow(di.numRunnerSameCourseMax));
outLines.emplace_back(0, L"Kortast teoretiska startdjup utan krockar är X minuter.#" + itow(di.minimalStartDepth/60)); outLines.emplace_back(0, L"Kortast teoretiska startdjup utan krockar är X minuter.#" + itow(di.minimalStartDepth/timeConstMinute));
outLines.emplace_back(0, L""); outLines.emplace_back(0, L"");
//Find last starter //Find last starter
int last = opt.last; int last = opt.last;
@ -878,7 +878,7 @@ void oEvent::optimizeStartOrder(vector<pair<int, wstring>> &outLines, DrawInfo &
laststart=max(laststart, ci.firstStart+(ci.nRunners-1)*ci.interval); laststart=max(laststart, ci.firstStart+(ci.nRunners-1)*ci.interval);
} }
outLines.emplace_back(0, L"Faktiskt startdjup: X minuter.#" + itow(((last+1) * di.baseInterval)/60)); outLines.emplace_back(0, L"Faktiskt startdjup: X minuter.#" + itow(((last+1) * di.baseInterval)/timeConstMinute));
outLines.emplace_back(1, L"Sista start (nu tilldelad): X.#" + outLines.emplace_back(1, L"Sista start (nu tilldelad): X.#" +
oe->getAbsTime(laststart*di.baseInterval+di.firstStart)); oe->getAbsTime(laststart*di.baseInterval+di.firstStart));
@ -1553,7 +1553,7 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
int leg = spec[0].leg; int leg = spec[0].leg;
VacantPosition vp = VacantPosition::Mixed; VacantPosition vp = VacantPosition::Mixed;
DrawInfo di; DrawInfo di;
di.baseInterval = 60; di.baseInterval = timeConstMinute;
di.allowNeighbourSameCourse = true; di.allowNeighbourSameCourse = true;
di.extraFactor = 0; di.extraFactor = 0;
@ -1826,7 +1826,7 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
spec[k].interval = baseInterval; spec[k].interval = baseInterval;
if (last[k] == 0 || spec[k].firstStart<=0 || baseInterval == 10*60) { if (last[k] == 0 || spec[k].firstStart<=0 || baseInterval == 10*timeConstMinute) {
// Fallback if incorrect specification. // Fallback if incorrect specification.
spec[k].firstStart = timeConstHour; spec[k].firstStart = timeConstHour;
spec[k].interval = 2*timeConstMinute; spec[k].interval = 2*timeConstMinute;
@ -1949,9 +1949,9 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
Vacances--; Vacances--;
} }
for (it=Runners.begin(); it != Runners.end(); ++it) for (it = Runners.begin(); it != Runners.end(); ++it) {
if (it->Class && it->Class->Id==ClassID) nRunners++; if (it->Class && it->Class->Id == ClassID && !it->isRemoved()) nRunners++;
}
if (nRunners==0) return; if (nRunners==0) return;
int *stimes=new int[nRunners]; int *stimes=new int[nRunners];
@ -1962,28 +1962,29 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
int ginterval; int ginterval;
if (nRunners>=Interval) if (nRunners>=Interval)
ginterval=10; ginterval=10 * timeConstSecond;
else if (Interval/nRunners>60){ else if (Interval/nRunners>60*timeConstSecond){
ginterval=40; ginterval=40 * timeConstSecond;
} }
else if (Interval/nRunners>30){ else if (Interval/nRunners>30 * timeConstSecond){
ginterval=20; ginterval=20 * timeConstSecond;
} }
else if (Interval/nRunners>20){ else if (Interval/nRunners>20 * timeConstSecond){
ginterval=15; ginterval=15 * timeConstSecond;
} }
else if (Interval/nRunners>10){ else if (Interval/nRunners>10 * timeConstSecond){
ginterval=1; ginterval=12 * timeConstSecond;
} }
else ginterval=10; else ginterval=10 * timeConstSecond;
int nGroups=Interval/ginterval+1; //15 s. per interval. int nGroups=Interval/ginterval+1; //15 s. per interval.
nGroups = min(nGroups, 2*nRunners+1);
int k; int k;
if (nGroups>0){ if (nGroups>0){
int MaxRunnersGroup=max((2*nRunners)/nGroups, 4)+GetRandomNumber(2); int MaxRunnersGroup=max((2*nRunners)/nGroups, 4)+GetRandomNumber(2);
int *sgroups=new int[nGroups]; vector<int> sgroups(nGroups);
for(k=0;k<nGroups; k++) for(k=0;k<nGroups; k++)
sgroups[k]=FirstStart+((ginterval*k+2)/5)*5; sgroups[k]=FirstStart+((ginterval*k+2)/5)*5;
@ -2015,11 +2016,11 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
} }
} }
//Permute some of the groups (not first and last group) //Permute some of the groups (not first and last group = group 0 and 1)
if (nGroups>5){ if (nGroups>5){
permute(sgroups+2, nGroups-2); permute(sgroups.data() + 2, nGroups - 2);
//Remove some random groups (except first and last). //Remove some random groups (except first and last = group 0 and 1).
for(k=2;k<nGroups; k++){ for(k=2;k<nGroups; k++){
if ((nRunners/nGroups)<MaxRunnersGroup && nGroups>5){ if ((nRunners/nGroups)<MaxRunnersGroup && nGroups>5){
sgroups[k]=sgroups[nGroups-1]; sgroups[k]=sgroups[nGroups-1];
@ -2029,10 +2030,9 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
} }
//Premute all groups; //Premute all groups;
permute(sgroups, nGroups); permute(sgroups.data(), nGroups);
int *counters=new int[nGroups]; vector<int> counters(nGroups);
memset(counters, 0, sizeof(int)*nGroups);
stimes[0]=FirstStart; stimes[0]=FirstStart;
stimes[1]=FirstStart+Interval; stimes[1]=FirstStart+Interval;
@ -2066,10 +2066,6 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
stimes[k]=sgroups[g]; stimes[k]=sgroups[g];
counters[g]++; counters[g]++;
} }
delete[] sgroups;
delete[] counters;
} }
else{ else{
for(k=0;k<nRunners; k++) stimes[k]=FirstStart; for(k=0;k<nRunners; k++) stimes[k]=FirstStart;
@ -2081,7 +2077,7 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
k=0; k=0;
for (it = Runners.begin(); it != Runners.end(); ++it) { for (it = Runners.begin(); it != Runners.end(); ++it) {
if (it->Class && it->Class->Id == ClassID) { if (it->Class && it->Class->Id == ClassID && !it->isRemoved()) {
it->setStartTime(stimes[k++], true, oBase::ChangeType::Update, false); it->setStartTime(stimes[k++], true, oBase::ChangeType::Update, false);
it->StartNo = k; it->StartNo = k;
it->synchronize(); it->synchronize();
@ -2130,7 +2126,7 @@ void oEvent::automaticDrawAll(gdioutput &gdi,
return; return;
} }
if (baseInterval<1 || baseInterval>60*60) if (baseInterval<timeConstSecond || baseInterval>timeConstHour)
throw std::exception("Felaktigt tidsformat för intervall"); throw std::exception("Felaktigt tidsformat för intervall");
int iFirstStart = getRelativeTime(firstStart); int iFirstStart = getRelativeTime(firstStart);

View File

@ -42,6 +42,8 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
extern gdioutput *gdi_main; extern gdioutput *gdi_main;
constexpr int constNoLeaderTime = 10000000;
constexpr int highlightNewResultTime = 20;
oTimeLine::oTimeLine(int time_, TimeLineType type_, Priority priority_, int classId_, int ID_, oAbstractRunner *source) : oTimeLine::oTimeLine(int time_, TimeLineType type_, Priority priority_, int classId_, int ID_, oAbstractRunner *source) :
time(time_), type(type_), priority(priority_), classId(classId_), ID(ID_) time(time_), type(type_), priority(priority_), classId(classId_), ID(ID_)
@ -274,8 +276,9 @@ int MovePriorityCB(gdioutput *gdi, int type, void *data) {
return true; return true;
} }
void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r, void renderRowSpeakerList(const oSpeakerObject& r, const oSpeakerObject* next_r,
int leaderTime, int type, vector<SpeakerString> &row, bool shortName) { int leaderTime, int type, vector<SpeakerString>& row,
bool shortName, bool useSubSecond) {
if (r.place > 0) if (r.place > 0)
row.push_back(SpeakerString(textRight, itow(r.place))); row.push_back(SpeakerString(textRight, itow(r.place)));
@ -299,7 +302,7 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
split(r.names[k], L" ", splt); split(r.names[k], L" ", splt);
for (size_t j = 0; j < splt.size(); j++) { for (size_t j = 0; j < splt.size(); j++) {
if (j == 0) { if (j == 0) {
if (splt.size()>1 && splt[j].length() > 1) if (splt.size() > 1 && splt[j].length() > 1)
names += splt[j].substr(0, 1) + L"."; names += splt[j].substr(0, 1) + L".";
else else
names += splt[j]; names += splt[j];
@ -327,10 +330,10 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
} }
else { else {
vector<wstring> splt; vector<wstring> splt;
split( r.outgoingnames[k], L" ", splt); split(r.outgoingnames[k], L" ", splt);
for (size_t j = 0; j < splt.size(); j++) { for (size_t j = 0; j < splt.size(); j++) {
if (j == 0) { if (j == 0) {
if (splt.size()>1 && splt[j].length() > 1) if (splt.size() > 1 && splt[j].length() > 1)
names += splt[j].substr(0, 1) + L"."; names += splt[j].substr(0, 1) + L".";
else else
names += splt[j]; names += splt[j];
@ -341,24 +344,29 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
} }
} }
if (r.finishStatus<=1 || r.finishStatus==r.status) if (r.finishStatus <= 1 || r.finishStatus == r.status)
row.push_back(SpeakerString(normalText, names)); row.push_back(SpeakerString(normalText, names));
else else
row.push_back(SpeakerString(normalText, names + L" ("+ oEvent::formatStatus(r.finishStatus, true) +L")")); row.push_back(SpeakerString(normalText, names + L" (" + oEvent::formatStatus(r.finishStatus, true) + L")"));
row.push_back(SpeakerString(normalText, r.club)); row.push_back(SpeakerString(normalText, r.club));
auto ssMode = useSubSecond ? SubSecond::On : SubSecond::Auto;
if (r.status == StatusOK || (r.status == StatusUnknown && r.runningTime.time > 0)) { if (r.status == StatusOK || (r.status == StatusUnknown && r.runningTime.time > 0)) {
row.push_back(SpeakerString(textRight, formatTime(r.runningTime.preliminary))); row.push_back(SpeakerString(textRight, formatTime(r.runningTime.preliminary, ssMode)));
if (r.runningTime.time != r.runningTimeLeg.time) if (r.runningTime.time != r.runningTimeLeg.time)
row.push_back(SpeakerString(textRight, formatTime(r.runningTimeLeg.time))); row.push_back(SpeakerString(textRight, formatTime(r.runningTimeLeg.time, ssMode)));
else else
row.push_back(SpeakerString()); row.push_back(SpeakerString());
if (leaderTime!=100000 && leaderTime>0){ if (leaderTime != constNoLeaderTime && leaderTime > 0) {
row.push_back(SpeakerString(textRight, gdioutput::getTimerText(r.runningTime.time-leaderTime, int flag = timerCanBeNegative;
timerCanBeNegative))); if (useSubSecond)
flag |= timeWithTenth;
row.push_back(SpeakerString(textRight, gdioutput::getTimerText(r.runningTime.time - leaderTime,
flag, false)));
} }
else else
row.push_back(SpeakerString()); row.push_back(SpeakerString());
@ -373,55 +381,52 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
}*/ }*/
} }
else if (r.status == StatusUnknown) { else if (r.status == StatusUnknown) {
DWORD TimeOut=NOTIMEOUT; DWORD timeOut = NOTIMEOUT;
if (r.runningTimeLeg.preliminary>0 && !r.missingStartTime) { if (r.runningTimeLeg.preliminary > 0 && !r.missingStartTime) {
if (next_r && next_r->status==StatusOK && next_r->runningTime.preliminary > r.runningTime.preliminary) if (next_r && next_r->status == StatusOK && next_r->runningTime.preliminary > r.runningTime.preliminary)
TimeOut = next_r->runningTime.preliminary; timeOut = next_r->runningTime.preliminary / timeConstSecond;
row.push_back(SpeakerString(textRight, r.runningTime.preliminary, TimeOut)); row.push_back(SpeakerString(textRight, r.runningTime.preliminary, timeOut));
if (r.runningTime.preliminary != r.runningTimeLeg.preliminary) if (r.runningTime.preliminary != r.runningTimeLeg.preliminary)
row.push_back(SpeakerString(textRight, r.runningTimeLeg.preliminary)); row.push_back(SpeakerString(textRight, r.runningTimeLeg.preliminary));
else else
row.push_back(SpeakerString()); row.push_back(SpeakerString());
if (leaderTime != 100000) if (leaderTime != constNoLeaderTime)
row.push_back(SpeakerString(timerCanBeNegative|textRight, r.runningTime.preliminary - leaderTime)); row.push_back(SpeakerString(timerCanBeNegative | textRight, r.runningTime.preliminary - leaderTime));
else else
row.push_back(SpeakerString()); row.push_back(SpeakerString());
//gdi.addTimer(y, x+dx[5], timerCanBeNegative|textRight, r.runningTime.preliminary - leaderTime);
} }
else{ else {
//gdi.addStringUT(y, x+dx[4], textRight, "["+r.startTimeS+"]"); row.push_back(SpeakerString(textRight, L"[" + r.startTimeS + L"]"));
row.push_back(SpeakerString(textRight, L"["+r.startTimeS+L"]"));
if (!r.missingStartTime) if (!r.missingStartTime) {
row.push_back(SpeakerString(timerCanBeNegative|textRight, r.runningTimeLeg.preliminary)); row.push_back(SpeakerString(timerCanBeNegative | textRight,
//gdi.addTimer(y, x+dx[5], timerCanBeNegative|textRight, r.runningTimeLeg.preliminary, 0, SpeakerCB, NOTIMEOUT); r.runningTimeLeg.preliminary, 0)); // Timeout on start
}
else else
row.push_back(SpeakerString()); row.push_back(SpeakerString());
row.push_back(SpeakerString()); row.push_back(SpeakerString());
} }
} }
else{ else {
//gdi.addStringUT(y, x+dx[4], textRight, oEvent::formatStatus(r.status)).setColor(colorDarkRed);
row.push_back(SpeakerString()); row.push_back(SpeakerString());
row.push_back(SpeakerString(textRight, oEvent::formatStatus(r.status, true))); row.push_back(SpeakerString(textRight, oEvent::formatStatus(r.status, true)));
row.back().color = colorDarkRed; row.back().color = colorDarkRed;
row.push_back(SpeakerString()); row.push_back(SpeakerString());
} }
int ownerId = r.owner ? r.owner->getId(): 0; int ownerId = r.owner ? r.owner->getId() : 0;
if (type==1) { if (type == 1) {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bort]"))); row.push_back(SpeakerString(normalText, lang.tl(L"[Bort]")));
row.back().color = colorRed; row.back().color = colorRed;
row.back().moveKey = "D" + itos(ownerId); row.back().moveKey = "D" + itos(ownerId);
} }
else if (type==2) { else if (type == 2) {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]"))); row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]")));
row.back().color = colorGreen; row.back().color = colorGreen;
row.back().moveKey = "U" + itos(ownerId); row.back().moveKey = "U" + itos(ownerId);
@ -436,7 +441,7 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
row.push_back(SpeakerString(normalText, lang.tl(L"[Återställ]"))); row.push_back(SpeakerString(normalText, lang.tl(L"[Återställ]")));
row.back().moveKey = "M" + itos(ownerId); row.back().moveKey = "M" + itos(ownerId);
} }
else{ else {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]"))); row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]")));
row.back().moveKey = "U" + itos(ownerId); row.back().moveKey = "U" + itos(ownerId);
} }
@ -448,7 +453,7 @@ void renderRowSpeakerList(gdioutput &gdi, int type, const oSpeakerObject &r, int
const vector<SpeakerString> &row, const vector<int> &pos) { const vector<SpeakerString> &row, const vector<int> &pos) {
int lh=gdi.getLineHeight(); int lh=gdi.getLineHeight();
bool highlight = false; bool highlight = false;
if (r.timeSinceChange < 20 && r.timeSinceChange>=0) { if (r.timeSinceChange < highlightNewResultTime * timeConstSecond && r.timeSinceChange>=0) {
RECT rc; RECT rc;
rc.left = x+pos[1] - 4; rc.left = x+pos[1] - 4;
rc.right=x+pos.back()+gdi.scaleLength(60); rc.right=x+pos.back()+gdi.scaleLength(60);
@ -456,6 +461,7 @@ void renderRowSpeakerList(gdioutput &gdi, int type, const oSpeakerObject &r, int
rc.bottom=y+lh+1; rc.bottom=y+lh+1;
gdi.addRectangle(rc, colorLightGreen, false); gdi.addRectangle(rc, colorLightGreen, false);
highlight = true; highlight = true;
gdi.addTimeout(highlightNewResultTime + 5, SpeakerCB);
} }
for (size_t k = 0; k < row.size(); k++) { for (size_t k = 0; k < row.size(); k++) {
@ -480,8 +486,8 @@ void renderRowSpeakerList(gdioutput &gdi, int type, const oSpeakerObject &r, int
} }
} }
else { else {
gdi.addTimer(y, x + pos[k], row[k].format, row[k].timer, limit, gdi.addTimer(y, x + pos[k], row[k].format, row[k].timer / timeConstSecond, limit,
row[k].timeout != NOTIMEOUT ? SpeakerCB : 0, row[k].timeout); row[k].timeout != NOTIMEOUT ? SpeakerCB : nullptr, row[k].timeout);
} }
} }
} }
@ -625,6 +631,7 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
//char bf2[64]=""; //char bf2[64]="";
wstring legName, cname = pCls->getName(); wstring legName, cname = pCls->getName();
size_t istage = -1; size_t istage = -1;
bool useSS = useSubSecond(); // Only for finish time??
for (size_t k = 0; k < stages.size(); k++) { for (size_t k = 0; k < stages.size(); k++) {
if (stages[k].first >= leg) { if (stages[k].first >= leg) {
istage = k; istage = k;
@ -648,20 +655,17 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
int lh=gdi.getLineHeight(); int lh=gdi.getLineHeight();
y+=lh*2; y+=lh*2;
int LeaderTime=100000; int leaderTime = constNoLeaderTime;
//Calculate leader-time //Calculate leader-time
for(sit=speakerList.begin(); sit != speakerList.end(); ++sit) { for (sit = speakerList.begin(); sit != speakerList.end(); ++sit) {
int rt = sit->runningTime.time; int rt = sit->runningTime.time;
if ((sit->status==StatusOK || sit->status == StatusUnknown) && rt>0) if ((sit->status == StatusOK || sit->status == StatusUnknown) && rt > 0)
LeaderTime=min(LeaderTime, rt); leaderTime = min(leaderTime, rt);
} }
vector< pair<oSpeakerObject *, vector<SpeakerString> > > toRender(speakerList.size()); vector< pair<oSpeakerObject *, vector<SpeakerString> > > toRender(speakerList.size());
/*const int dx_c[8]={0, 40, 280, 530-40, 590-40, 650-40, 660-40, 730-40};
vector<int> dx;
for (int k=0;k<8;k++)
dx.push_back(gdi.scaleLength(dx_c[k]));*/
int ix = 0; int ix = 0;
sit = speakerList.begin(); sit = speakerList.begin();
size_t maxRow = 0; size_t maxRow = 0;
@ -675,7 +679,8 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
else if (so->status == StatusUnknown && so->priority==0) else if (so->status == StatusUnknown && so->priority==0)
type = 2; type = 2;
renderRowSpeakerList(*toRender[ix].first, next, LeaderTime, type, toRender[ix].second, shortNames); renderRowSpeakerList(*toRender[ix].first, next, leaderTime,
type, toRender[ix].second, shortNames, useSS);
maxRow = max(maxRow, toRender[ix].second.size()); maxRow = max(maxRow, toRender[ix].second.size());
ix++; ix++;
} }

View File

@ -61,12 +61,8 @@ FlowOperation importFilterGUI(oEvent *oe,
set<int> & filter, set<int> & filter,
string &preferredIdProvider); string &preferredIdProvider);
string conv_is(int i) string conv_is(int i) {
{
char bf[256]; char bf[256];
// if (i==0)
// return "";
//else
if (_itoa_s(i, bf, 10)==0) if (_itoa_s(i, bf, 10)==0)
return bf; return bf;
return ""; return "";
@ -108,7 +104,7 @@ wstring &getFirst(wstring &inout, int maxNames) {
return inout; return inout;
} }
bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includeSplits) bool oEvent::exportOECSV(const wchar_t *file, const set<int>& classes, int languageTypeIndex, bool includeSplits)
{ {
enum { enum {
OEstno = 0, OEcard = 1, OEid = 2, OEsurname = 3, OEfirstname = 4, OEstno = 0, OEcard = 1, OEid = 2, OEsurname = 3, OEfirstname = 4,
@ -120,12 +116,12 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
csvparser csv; csvparser csv;
oClass::initClassId(*this); oClass::initClassId(*this, classes);
if (!csv.openOutput(file)) if (!csv.openOutput(file))
return false; return false;
calculateResults({}, ResultType::ClassResult); calculateResults(classes, ResultType::ClassResult);
sortRunners(SortOrder::ClassResult); sortRunners(SortOrder::ClassResult);
oRunnerList::iterator it; oRunnerList::iterator it;
string maleString; string maleString;
@ -171,6 +167,11 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
char bf[256]; char bf[256];
for (it = Runners.begin(); it != Runners.end(); ++it) { for (it = Runners.begin(); it != Runners.end(); ++it) {
if (it->isRemoved())
continue;
if (!classes.empty() && !classes.count(it->getClassId(true)))
continue;
vector<string> row; vector<string> row;
row.resize(46); row.resize(46);
oDataInterface di = it->getDI(); oDataInterface di = it->getDI();
@ -226,7 +227,10 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
row[OEclubcity] = gdibase.recodeToNarrow(it->getClub()); row[OEclubcity] = gdibase.recodeToNarrow(it->getClub());
} }
row[OEnat] = gdibase.recodeToNarrow(di.getString("Nationality")); row[OEnat] = gdibase.recodeToNarrow(di.getString("Nationality"));
row[OEclassno] = conv_is(it->getClassId(true)); {
pClass pc = it->getClassRef(true);
row[OEclassno] = pc ? gdibase.recodeToNarrow(pc->getExtIdentifierString()) : "0";
}
row[OEclassshortname] = gdibase.recodeToNarrow(it->getClass(true)); row[OEclassshortname] = gdibase.recodeToNarrow(it->getClass(true));
row[OEclassname] = gdibase.recodeToNarrow(it->getClass(true)); row[OEclassname] = gdibase.recodeToNarrow(it->getClass(true));
@ -305,8 +309,10 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file, void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
bool updateClass, bool removeNonexisting, bool updateClass, bool removeNonexisting,
const set<int> &filter, const set<int> &filter,
int classIdOffset,
int courseIdOffset,
const string &preferredIdType) { const string &preferredIdType) {
vector< pair<int, int> > runnersInTeam; vector<pair<int, int>> runnersInTeam;
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) { for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
if (!it->isRemoved() && it->tInTeam) { if (!it->isRemoved() && it->tInTeam) {
runnersInTeam.push_back(make_pair(it->getId(), it->getClassId(false)) ); runnersInTeam.push_back(make_pair(it->getId(), it->getClassId(false)) );
@ -327,6 +333,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
if (xo.getAttrib("iofVersion")) { if (xo.getAttrib("iofVersion")) {
IOF30Interface reader(this, false, false); IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.setPreferredIdType(preferredIdType); reader.setPreferredIdType(preferredIdType);
reader.readEntryList(gdi, xo, removeNonexisting, filter, ent, fail, removed); reader.readEntryList(gdi, xo, removeNonexisting, filter, ent, fail, removed);
@ -392,6 +399,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
if (xo.getAttrib("iofVersion")) { if (xo.getAttrib("iofVersion")) {
IOF30Interface reader(this, false, false); IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readStartList(gdi, xo, ent, fail); reader.readStartList(gdi, xo, ent, fail);
} }
else { else {
@ -441,6 +449,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
gdi.addString("", 0, "Importerar resultat (IOF, xml)"); gdi.addString("", 0, "Importerar resultat (IOF, xml)");
gdi.refreshFast(); gdi.refreshFast();
IOF30Interface reader(this, false, false); IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readResultList(gdi, xo, ent, fail); reader.readResultList(gdi, xo, ent, fail);
} }
gdi.addString("", 0, "Klart. Antal importerade: X#" + itos(ent)); gdi.addString("", 0, "Klart. Antal importerade: X#" + itos(ent));
@ -463,6 +472,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
if (xo.getAttrib("iofVersion")) { if (xo.getAttrib("iofVersion")) {
IOF30Interface reader(this, false, false); IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readClassList(gdi, xo, imp, fail); reader.readClassList(gdi, xo, imp, fail);
} }
else { else {
@ -569,6 +579,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
if (xo && xo.getAttrib("iofVersion")) { if (xo && xo.getAttrib("iofVersion")) {
IOF30Interface reader(this, false, false); IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readCourseData(gdi, xo, updateClass, imp, fail); reader.readCourseData(gdi, xo, updateClass, imp, fail);
} }
else { else {
@ -2678,7 +2689,7 @@ void oEvent::exportIOFSplits(IOFVersion version, const wchar_t *file,
xmlparser xml; xmlparser xml;
xml.openOutput(file, false); xml.openOutput(file, false);
oClass::initClassId(*this); oClass::initClassId(*this, classes);
reEvaluateAll(classes, true); reEvaluateAll(classes, true);
if (version != IOF20) if (version != IOF20)
calculateResults(classes, ResultType::ClassCourseResult); calculateResults(classes, ResultType::ClassCourseResult);
@ -2708,7 +2719,7 @@ void oEvent::exportIOFStartlist(IOFVersion version, const wchar_t *file, bool us
bool useEventorQuirks) { bool useEventorQuirks) {
xmlparser xml; xmlparser xml;
oClass::initClassId(*this); oClass::initClassId(*this, classes);
xml.openOutput(file, false); xml.openOutput(file, false);
if (version == IOF20) if (version == IOF20)

View File

@ -429,7 +429,8 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|| type == lTeamRunner || type == lTeamClub) || type == lTeamRunner || type == lTeamClub)
extras[k].add(L"IK Friskus Varberg"); extras[k].add(L"IK Friskus Varberg");
if (type == lRunnerGivenName || type == lRunnerFamilyName || type == lRunnerNationality) if (type == lRunnerGivenName || type == lRunnerFamilyName ||
type == lRunnerNationality || type == lRunnerLegTeamLeaderName)
extras[k].add(L"Karl-Gunnar"); extras[k].add(L"Karl-Gunnar");
if (type == lRunnerCompleteName || type == lPatrolNameNames || type == lPatrolClubNameNames) if (type == lRunnerCompleteName || type == lPatrolNameNames || type == lPatrolClubNameNames)
@ -1254,6 +1255,17 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
case lRunnerCompleteName: case lRunnerCompleteName:
if (r) wcscpy_s(wbf, r->getCompleteIdentification().c_str()); if (r) wcscpy_s(wbf, r->getCompleteIdentification().c_str());
break; break;
case lRunnerLegTeamLeaderName: {
pRunner rr = r;
if (t && r)
rr = t->getRunnerBestTimePar(r->getLegNumber());
else if (t)
rr = t->getRunnerBestTimePar(legIndex);
if (rr)
swprintf_s(wbf, L"%s", rr->formatName(oRunner::NameFormat::InitLast).c_str());
}
break;
case lPatrolNameNames: case lPatrolNameNames:
if (t) { if (t) {
pRunner r1 = t->getRunner(0); pRunner r1 = t->getRunner(0);
@ -1459,7 +1471,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
int len = pc->getLength(); int len = pc->getLength();
if (len > 0 && t > 0) { if (len > 0 && t > 0) {
int sperkm = (1000 * t) / len; int sperkm = (1000 * t) / len;
wsptr = &formatTime(sperkm); wsptr = &formatTime(sperkm, SubSecond::Off);
} }
} }
} }
@ -2570,25 +2582,26 @@ bool oEvent::formatPrintPost(const list<oPrintPost> &ppli, PrintPostInfo &ppi,
TextInfo *ti = 0; TextInfo *ti = 0;
if (!text.empty()) { if (!text.empty()) {
int tightBBFlag = ppi.par.tightBoundingBox ? 0 : skipBoundingBox;
pdy = ppi.gdi.scaleLength(pp.dy); pdy = ppi.gdi.scaleLength(pp.dy);
pdx = ppi.gdi.scaleLength(pp.dx); pdx = ppi.gdi.scaleLength(pp.dx);
if ((pp.type == lRunnerName || pp.type == lRunnerCompleteName || if ((pp.type == lRunnerName || pp.type == lRunnerCompleteName ||
pp.type == lRunnerFamilyName || pp.type == lRunnerGivenName || pp.type == lRunnerFamilyName || pp.type == lRunnerGivenName ||
pp.type == lTeamRunner || (pp.type == lPatrolNameNames && !t)) && rr) { pp.type == lTeamRunner || (pp.type == lPatrolNameNames && !t)) && rr) {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | skipBoundingBox, text, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | tightBBFlag, text,
ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str()); ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str());
ti->setExtra(rr->getId()); ti->setExtra(rr->getId());
ti->id = "R"; ti->id = "R";
} }
else if ((pp.type == lTeamName || pp.type == lPatrolNameNames) && t) { else if ((pp.type == lTeamName || pp.type == lPatrolNameNames) && t) {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | skipBoundingBox, text, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | tightBBFlag, text,
ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str()); ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str());
ti->setExtra(t->getId()); ti->setExtra(t->getId());
ti->id = "T"; ti->id = "T";
} }
else { else {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx,
pp.format | skipBoundingBox, text, ppi.gdi.scaleLength(limit), 0, pp.fontFace.c_str()); pp.format | tightBBFlag, text, ppi.gdi.scaleLength(limit), 0, pp.fontFace.c_str());
} }
if (ti && ppi.keepToghether) if (ti && ppi.keepToghether)
ti->lineBreakPrioity = -1; ti->lineBreakPrioity = -1;
@ -3975,16 +3988,13 @@ void oEvent::getListTypes(map<EStdListType, oListInfo> &listMap, int filterResul
} }
void oEvent::generateListInfo(EStdListType lt, const gdioutput &gdi, int classId, oListInfo &li) void oEvent::generateListInfo(const gdioutput& target, EStdListType lt, int classId, oListInfo &li) {
{
oListParam par; oListParam par;
if (classId!=0) if (classId!=0)
par.selection.insert(classId); par.selection.insert(classId);
par.listCode=lt; par.listCode=lt;
generateListInfo(target, par, li);
generateListInfo(par, li);
} }
int openRunnerTeamCB(gdioutput *gdi, int type, void *data); int openRunnerTeamCB(gdioutput *gdi, int type, void *data);
@ -4087,12 +4097,12 @@ void oListInfo::setCallback(GUICALLBACK cb) {
} }
} }
void oEvent::generateListInfo(oListParam &par, oListInfo &li) { void oEvent::generateListInfo(const gdioutput& target, oListParam &par, oListInfo &li) {
vector<oListParam> parV(1, par); vector<oListParam> parV(1, par);
generateListInfo(parV, li); generateListInfo(target, parV, li);
} }
void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) { void oEvent::generateListInfo(const gdioutput& target, vector<oListParam> &par, oListInfo &li) {
li.getParam().sourceParam = -1;// Reset source li.getParam().sourceParam = -1;// Reset source
loadGeneralResults(false, false); loadGeneralResults(false, false);
for (size_t k = 0; k < par.size(); k++) { for (size_t k = 0; k < par.size(); k++) {
@ -4103,7 +4113,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
getListTypes(listMap, false); getListTypes(listMap, false);
if (par.size() == 1) { if (par.size() == 1) {
generateListInfoAux(par[0], li, listMap[par[0].listCode].Name); generateListInfoAux(target, par[0], li, listMap[par[0].listCode].Name);
set<int> used; set<int> used;
// Add linked lists // Add linked lists
oListParam *cPar = &par[0]; oListParam *cPar = &par[0];
@ -4115,7 +4125,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
oListParam &nextPar = oe->getListContainer().getParam(cPar->nextList-1); oListParam &nextPar = oe->getListContainer().getParam(cPar->nextList-1);
li.next.push_back(oListInfo()); li.next.push_back(oListInfo());
nextPar.cb = 0; nextPar.cb = 0;
generateListInfoAux(nextPar, li.next.back(), L""); generateListInfoAux(target, nextPar, li.next.back(), L"");
cPar = &nextPar; cPar = &nextPar;
} }
} }
@ -4124,7 +4134,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
if (k > 0) { if (k > 0) {
li.next.push_back(oListInfo()); li.next.push_back(oListInfo());
} }
generateListInfoAux(par[k], k == 0 ? li : li.next.back(), generateListInfoAux(target, par[k], k == 0 ? li : li.next.back(),
li.Name = listMap[par[0].listCode].Name); li.Name = listMap[par[0].listCode].Name);
} }
} }
@ -4132,7 +4142,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
extern Image image; extern Image image;
void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &name) { void oEvent::generateListInfoAux(const gdioutput& target, oListParam &par, oListInfo &li, const wstring &name) {
const int lh=14; const int lh=14;
const int vspace=lh/2; const int vspace=lh/2;
int bib; int bib;
@ -4600,7 +4610,7 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
mList.addToSubList(lRunnerName); mList.addToSubList(lRunnerName);
mList.addToSubList(lRunnerCard).align(lClassStartName); mList.addToSubList(lRunnerCard).align(lClassStartName);
mList.interpret(this, gdibase, par, li); mList.interpret(this, target, par, li);
} }
li.listType=li.EBaseTypeTeam; li.listType=li.EBaseTypeTeam;
li.listSubType=li.EBaseTypeRunner; li.listSubType=li.EBaseTypeRunner;
@ -4849,7 +4859,7 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
mList.setListType(li.EBaseTypeTeam); mList.setListType(li.EBaseTypeTeam);
mList.setSortOrder(ClassStartTime); mList.setSortOrder(ClassStartTime);
mList.addFilter(EFilterExcludeDNS); mList.addFilter(EFilterExcludeDNS);
mList.interpret(this, gdibase, par, li); mList.interpret(this, target, par, li);
break; break;
} }
case EStdPatrolResultList: case EStdPatrolResultList:
@ -5059,10 +5069,10 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
continue; continue;
par.setLegNumberCoded(out[k].second); par.setLegNumberCoded(out[k].second);
if (k == 0) if (k == 0)
generateListInfo(par, li); generateListInfo(target, par, li);
else { else {
li.next.push_back(oListInfo()); li.next.push_back(oListInfo());
generateListInfo(par, li.next.back()); generateListInfo(target, par, li.next.back());
} }
} }
} }
@ -5080,7 +5090,7 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
break; break;
default: default:
if (!getListContainer().interpret(this, gdibase, par, li)) if (!getListContainer().interpret(this, target, par, li))
throw meosException("Could not load list 'X'#L" + itos(par.listCode)); throw meosException("Could not load list 'X'#L" + itos(par.listCode));
} }
} }

View File

@ -65,6 +65,7 @@ enum EPostType {
lRunnerGivenName, lRunnerGivenName,
lRunnerFamilyName, lRunnerFamilyName,
lRunnerCompleteName, lRunnerCompleteName,
lRunnerLegTeamLeaderName, // The runner on the (parallell) leg (in the team) with best result
lPatrolNameNames, // Single runner's name or both names in a patrol lPatrolNameNames, // Single runner's name or both names in a patrol
lPatrolClubNameNames, // Single runner's club or combination of patrol clubs lPatrolClubNameNames, // Single runner's club or combination of patrol clubs
lRunnerFinish, lRunnerFinish,
@ -484,6 +485,8 @@ struct oListParam {
int sourceParam = -1; int sourceParam = -1;
bool tightBoundingBox = false;
private: private:
int legNumber; int legNumber;
}; };
@ -507,6 +510,14 @@ public:
bool isTeamList() const {return listType == EBaseTypeTeam;} bool isTeamList() const {return listType == EBaseTypeTeam;}
bool isSplitPrintList() const { return splitPrintInfo != nullptr; } bool isSplitPrintList() const { return splitPrintInfo != nullptr; }
/** Return true, if includeHeader is set, also considers the header. */
bool empty(bool includeHeader = true) const {
if (includeHeader)
return head.empty() && subHead.empty() && listPost.empty() && subListPost.empty();
else
return subHead.empty() && listPost.empty() && subListPost.empty();
}
enum ResultType { enum ResultType {
Global, Global,
Classwise, Classwise,
@ -551,9 +562,10 @@ protected:
list<oPrintPost> head; list<oPrintPost> head;
list<oPrintPost> subHead; list<oPrintPost> subHead;
list<oPrintPost> listPost; list<oPrintPost> listPost;
list<oPrintPost> subListPost;
vector<char> listPostFilter; vector<char> listPostFilter;
vector<char> listPostSubFilter; vector<char> listPostSubFilter;
list<oPrintPost> subListPost;
bool fixedType; bool fixedType;
PunchMode needPunches; PunchMode needPunches;

View File

@ -2838,17 +2838,21 @@ const wstring &oRunner::getName() const {
return tRealName; return tRealName;
} }
const wstring &oRunner::getNameLastFirst() const { const wstring& getNameLastFirst(const wstring &sName) {
if (sName.find_first_of(',') != sName.npos) if (sName.find_first_of(',') != sName.npos)
return sName; // Already "Fiske, Eric" return sName; // Already "Fiske, Eric"
if (sName.find_first_of(' ') == sName.npos) if (sName.find_first_of(' ') == sName.npos)
return sName; // No space "Vacant", "Eric" return sName; // No space "Vacant", "Eric"
wstring &res = StringCache::getInstance().wget(); wstring& res = StringCache::getInstance().wget();
res = getFamilyName() + L", " + getGivenName(); res = getFamilyName(sName) + L", " + getGivenName(sName);
return res; return res;
} }
const wstring &oRunner::getNameLastFirst() const {
return ::getNameLastFirst(sName);
}
void oRunner::getRealName(const wstring &input, wstring &output) const { void oRunner::getRealName(const wstring &input, wstring &output) const {
bool wasSpace = false; bool wasSpace = false;
wstring n = input; wstring n = input;
@ -2883,7 +2887,7 @@ void oRunner::getRealName(const wstring &input, wstring &output) const {
if (comma != string::npos) if (comma != string::npos)
output = n; output = n;
else else
output = getNameLastFirst(); output = ::getNameLastFirst(n);
} }
} }
@ -4353,11 +4357,18 @@ void oRunner::fillSpeakerObject(int leg, int courseControlId, int previousContro
spk.status = getStatus(); spk.status = getStatus();
} }
if (courseControlId == oPunch::PunchFinish) if (courseControlId == oPunch::PunchFinish) {
if (FinishTime > 0)
spk.timeSinceChange = oe->getComputerTime() - FinishTime; spk.timeSinceChange = oe->getComputerTime() - FinishTime;
else else
spk.timeSinceChange = -1;
}
else {
if (spk.runningTime.time > timeConstSecond * 10)
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTime.time + tStartTime); spk.timeSinceChange = oe->getComputerTime() - (spk.runningTime.time + tStartTime);
else
spk.timeSinceChange = -1;
}
spk.bib = getBib(); spk.bib = getBib();
spk.names.push_back(getName()); spk.names.push_back(getName());
@ -4770,9 +4781,21 @@ void oRunner::printSplits(gdioutput& gdi) const {
string listId; string listId;
if (wListId.empty()) { if (wListId.empty()) {
if (cls1) { if (cls1) {
if (cls1->getClassType() == ClassType::oClassIndividual) if (cls1->getClassType() == ClassType::oClassIndividual) {
listId = "split_indivudual"; if (cls1->isRogaining())
listId = "Tsplit_result_rogaining";
else
listId = "Tsplit_result_individual";
} }
else if (cls1->getClassType() == ClassType::oClassRelay) {
if (cls1->isRogaining())
listId = "Tsplit_result_team_rogaining";
else
listId = "Tsplit_result_team";
}
}
}
else if (wListId == L"*") { // Standarad, no list
} }
else { else {
listId = gdioutput::narrow(wListId); listId = gdioutput::narrow(wListId);
@ -4791,15 +4814,18 @@ void oRunner::printSplits(gdioutput& gdi) const {
oListInfo currentList; oListInfo currentList;
par.listCode = oe->getListContainer().getCodeFromUnqiueId(listId); par.listCode = oe->getListContainer().getCodeFromUnqiueId(listId);
//auto &metaList = oe->getListContainer().getList(par.listCode);
par.showInterTimes = false; par.showInterTimes = false;
par.setLegNumberCoded(getLegNumber()); int legNo = getLegNumber(), legOrd;
if (Class)
Class->splitLegNumberParallel(getLegNumber(), legNo, legOrd);
par.setLegNumberCoded(legNo);
par.filterMaxPer = 3; par.filterMaxPer = 3;
par.alwaysInclude = this; par.alwaysInclude = this;
par.showHeader = false; par.showHeader = false;
par.tightBoundingBox = true;
try { try {
oe->generateListInfo(par, currentList); oe->generateListInfo(gdi, par, currentList);
} }
catch (const meosException&) { catch (const meosException&) {
oe->gdiBase().addInfoBox("load_id_list", L"info:nosplitprint", 10000); oe->gdiBase().addInfoBox("load_id_list", L"info:nosplitprint", 10000);
@ -4823,6 +4849,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
bool withAnalysis = (oe->getDI().getInt("Analysis") & 1) == 0; bool withAnalysis = (oe->getDI().getInt("Analysis") & 1) == 0;
bool withSpeed = (oe->getDI().getInt("Analysis") & 2) == 0; bool withSpeed = (oe->getDI().getInt("Analysis") & 2) == 0;
bool withResult = (oe->getDI().getInt("Analysis") & 4) == 0; bool withResult = (oe->getDI().getInt("Analysis") & 4) == 0;
bool includeStandardHeading = true; bool includeStandardHeading = true;
bool includeDefaultTitle = true; bool includeDefaultTitle = true;
bool includeSplitTimes = true; bool includeSplitTimes = true;
@ -4834,6 +4861,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
withSpeed = sp.withSpeed; withSpeed = sp.withSpeed;
withResult = sp.withResult; withResult = sp.withResult;
withAnalysis = sp.withAnalysis; withAnalysis = sp.withAnalysis;
includeSplitTimes = sp.includeSplitTimes;
} }
const bool wideFormat = oe->getPropertyInt("WideSplitFormat", 0) == 1; const bool wideFormat = oe->getPropertyInt("WideSplitFormat", 0) == 1;
@ -4952,7 +4980,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
if (headerPos.count(cx) == 0) { if (headerPos.count(cx) == 0) {
headerPos.insert(cx); headerPos.insert(cx);
gdi.addString("", cyHead, cx, italicSmall, "Kontroll"); gdi.addString("", cyHead, cx, italicSmall, "Kontroll");
gdi.addString("", cyHead, cx + c2 - gdi.scaleLength(spW/2), italicSmall, "Tid"); gdi.addString("", cyHead, cx + c2 - gdi.scaleLength(spW / 2), italicSmall, "Tid");
if (withSpeed) if (withSpeed)
gdi.addString("", cyHead, cx + c5, italicSmall | textRight, "min/km"); gdi.addString("", cyHead, cx + c5, italicSmall | textRight, "min/km");
} }
@ -4962,7 +4990,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
const pControl c = pc->getControl(it->tRogainingIndex); const pControl c = pc->getControl(it->tRogainingIndex);
string point = c ? itos(c->getRogainingPoints()) + "p." : ""; string point = c ? itos(c->getRogainingPoints()) + "p." : "";
gdi.addStringUT(cy, cx + c1 + gdi.scaleLength(10/2), fontSmall, point); gdi.addStringUT(cy, cx + c1 + gdi.scaleLength(10 / 2), fontSmall, point);
any = true; any = true;
sprintf_s(bf, "%d", it->type); sprintf_s(bf, "%d", it->type);
@ -5158,7 +5186,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
if (headerPos.count(cx) == 0) { if (headerPos.count(cx) == 0) {
headerPos.insert(cx); headerPos.insert(cx);
gdi.addString("", cyHead, cx, italicSmall, "Kontroll"); gdi.addString("", cyHead, cx, italicSmall, "Kontroll");
gdi.addString("", cyHead, cx + c2 - gdi.scaleLength(55/2), italicSmall, "Tid"); gdi.addString("", cyHead, cx + c2 - gdi.scaleLength(55 / 2), italicSmall, "Tid");
} }
bool any = false; bool any = false;
@ -5213,6 +5241,10 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
} }
} }
}
if (getStatus() != StatusUnknown && getFinishTime() > 0) {
oe->calculateResults({ getClassId(true) }, oEvent::ResultType::ClassResult); oe->calculateResults({ getClassId(true) }, oEvent::ResultType::ClassResult);
if (hasInputData()) if (hasInputData())
oe->calculateResults({ getClassId(true) }, oEvent::ResultType::TotalResult); oe->calculateResults({ getClassId(true) }, oEvent::ResultType::TotalResult);
@ -5243,8 +5275,9 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
gdi.addString("", normal, place + timestatus + after); gdi.addString("", normal, place + timestatus + after);
gdi.popX(); gdi.popX();
} }
}
if (Card->miliVolt > 0) { if (Card && Card->miliVolt > 0) {
gdi.dropLine(0.7); gdi.dropLine(0.7);
auto stat = Card->isCriticalCardVoltage(); auto stat = Card->isCriticalCardVoltage();
wstring warning; wstring warning;
@ -5262,14 +5295,14 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
gdi.addStringUT(fontSmall, L"(" + warning + L")"); gdi.addStringUT(fontSmall, L"(" + warning + L")");
gdi.popX(); gdi.popX();
} }
}
gdi.dropLine(0.7);
if (li && !li->empty(false)) {
if (li) {
oe->generateList(gdi, false, *li, false); oe->generateList(gdi, false, *li, false);
gdi.dropLine(); gdi.dropLine();
} }
else {
gdi.dropLine(0.7);
}
vector< pair<wstring, int> > lines; vector< pair<wstring, int> > lines;
oe->getExtraLines("SPExtra", lines); oe->getExtraLines("SPExtra", lines);
@ -5282,7 +5315,6 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
gdi.addString("", fontSmall, "Av MeOS: www.melin.nu/meos"); gdi.addString("", fontSmall, "Av MeOS: www.melin.nu/meos");
} }
void oRunner::printStartInfo(gdioutput &gdi) const { void oRunner::printStartInfo(gdioutput &gdi) const {
gdi.setCX(10); gdi.setCX(10);
gdi.fillDown(); gdi.fillDown();
@ -5464,7 +5496,7 @@ void oRunner::setBirthYear(int year)
int oRunner::getBirthYear() const int oRunner::getBirthYear() const
{ {
return getDCI().getInt("BirthYear"); return getDCI().getYear("BirthYear");
} }
void oRunner::setBirthDate(const wstring& date) { void oRunner::setBirthDate(const wstring& date) {
@ -6817,7 +6849,7 @@ bool oRunner::startTimeAvailable() const {
if (st == restart && Class->getStartType(tLeg) == STChange) { if (st == restart && Class->getStartType(tLeg) == STChange) {
int currentTime = oe->getComputerTime(); int currentTime = oe->getComputerTime();
int rope = Class->getRopeTime(tLeg); int rope = Class->getRopeTime(tLeg);
return rope != 0 && currentTime + 600 > rope; return rope != 0 && currentTime + 10 * timeConstMinute > rope;
} }
return true; return true;
@ -7110,3 +7142,93 @@ bool oAbstractRunner::isStatusUnknown(bool computed, bool allowUpdate) const {
} }
return false; return false;
} }
bool oRunner::matchAbstractRunner(const oAbstractRunner* target) const {
if (target == nullptr)
return false;
if (target == this)
return true;
const oTeam* t = dynamic_cast<const oTeam*>(target);
if (t != nullptr)
return getTeam() == t;
return false;
}
/** Format the name according to the style. */
wstring oRunner::formatName(NameFormat style) const {
switch (style) {
case NameFormat::Default:
return getName();
case NameFormat::FirstLast: {
size_t comma = sName.find_first_of(',');
if (comma == string::npos)
return sName;
else
return trim(sName.substr(comma + 1) + L" " + trim(sName.substr(0, comma)));
}
case NameFormat::LastFirst:
return getNameLastFirst();
case NameFormat::First:
return getGivenName();
case NameFormat::Last:
return getFamilyName();
case NameFormat::Init: {
wstring given = getGivenName();
wstring family = getFamilyName();
wchar_t out[5];
int ix = 0;
auto append = [&out, &ix](wchar_t w) {
out[ix++] = w;
};
if (!given.empty()) {
append(given[0]);
append('.');
}
if (!family.empty()) {
append(family[0]);
append('.');
}
append(0);
return out;
}
case NameFormat::InitLast: {
wstring given = getGivenName();
if (!given.empty()) {
given.resize(1);
given.append(L". ");
}
given.append(getFamilyName());
return given;
}
}
throw meosException("Unknown name style");
}
/** Get available name styles. */
void oRunner::getNameFormats(vector<pair<wstring, size_t>> & out) {
/*enum class NameFormat {
Default,
FirstLast,
LastFirst,
Last,
First,
Init,
InitLast
};
*/
out.clear();
auto add = [&out](NameFormat f, const string& w) {
out.emplace_back(lang.tl(w), size_t(f));
};
add(NameFormat::Default, "Standard");
add(NameFormat::FirstLast, "Förnamn Efternamn");
add(NameFormat::LastFirst, "Efternamn, Förnamn");
add(NameFormat::Last, "Efternamn");
add(NameFormat::First, "Förnamn");
add(NameFormat::Init, "F.E.");
add(NameFormat::InitLast, "F. Efternamn");
}

View File

@ -118,6 +118,9 @@ protected:
vector<vector<wstring>> dynamicData; vector<vector<wstring>> dynamicData;
public: public:
/** Return true if this and target are the same, or target is in this team, or this is in the target team.*/
virtual bool matchAbstractRunner(const oAbstractRunner *target) const = 0;
/** Encode status as a two-letter code, non-translated*/ /** Encode status as a two-letter code, non-translated*/
static const wstring &encodeStatus(RunnerStatus st, bool allowError = false); static const wstring &encodeStatus(RunnerStatus st, bool allowError = false);
@ -712,6 +715,8 @@ protected:
int getBuiltinAdjustment() const override; int getBuiltinAdjustment() const override;
public: public:
bool matchAbstractRunner(const oAbstractRunner* target) const override;
static const shared_ptr<Table> &getTable(oEvent *oe); static const shared_ptr<Table> &getTable(oEvent *oe);
oRunner *getMainRunner() { return tParentRunner != nullptr ? tParentRunner : this; } oRunner *getMainRunner() { return tParentRunner != nullptr ? tParentRunner : this; }
@ -754,6 +759,30 @@ public:
const wstring &getNameLastFirst() const; const wstring &getNameLastFirst() const;
void getRealName(const wstring &input, wstring &output) const; void getRealName(const wstring &input, wstring &output) const;
enum class NameFormat {
Default,
FirstLast,
LastFirst,
Last,
First,
Init,
InitLast
};
/** Format the name according to the style. */
wstring formatName(NameFormat style) const;
/** Get available name styles. */
static void getNameFormats(vector<pair<wstring, size_t>>& out);
static constexpr int encodeNameFormst(NameFormat f) {
return int(f);
}
static constexpr NameFormat decodeNameFormst(int f) {
return NameFormat(f);
}
/** Returns true if this runner can use the specified card, /** Returns true if this runner can use the specified card,
or false if it conflicts with the card of the other runner. */ or false if it conflicts with the card of the other runner. */
bool canShareCard(const pRunner other, int newCardNumber) const; bool canShareCard(const pRunner other, int newCardNumber) const;

View File

@ -1494,7 +1494,8 @@ void oTeam::fillSpeakerObject(int leg, int courseControlId, int previousControlC
bool totalResult, oSpeakerObject &spk) const { bool totalResult, oSpeakerObject &spk) const {
if (leg==-1) if (leg==-1)
leg = Runners.size()-1; leg = Runners.size()-1;
oTeam *ths = (oTeam *)this;
ths->apply(oBase::ChangeType::Quiet, leg < Runners.size() ? Runners[leg] : nullptr);
spk.club = getName(); spk.club = getName();
spk.missingStartTime = true; spk.missingStartTime = true;
//Defaults (if early return) //Defaults (if early return)
@ -1600,7 +1601,10 @@ void oTeam::fillSpeakerObject(int leg, int courseControlId, int previousControlC
} }
} }
if (spk.runningTimeLeg.time > 10)
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTimeLeg.time + Runners[leg]->tStartTime); spk.timeSinceChange = oe->getComputerTime() - (spk.runningTimeLeg.time + Runners[leg]->tStartTime);
else
spk.timeSinceChange = -1;
spk.owner=Runners[leg]; spk.owner=Runners[leg];
spk.finishStatus=getLegStatus(specifiedLeg, true, totalResult); spk.finishStatus=getLegStatus(specifiedLeg, true, totalResult);
@ -2590,3 +2594,45 @@ void oTeam::changedObject() {
sqlChanged = true; sqlChanged = true;
oe->sqlTeams.changed = true; oe->sqlTeams.changed = true;
} }
bool oTeam::matchAbstractRunner(const oAbstractRunner* target) const {
if (target == nullptr)
return false;
if (target == this)
return true;
const oRunner* r = dynamic_cast<const oRunner*>(target);
if (r != nullptr)
return r->getTeam() == this;
return false;
}
pRunner oTeam::getRunnerBestTimePar(int linearLegInput) const {
if (!Class)
return getRunner(linearLegInput);
if (linearLegInput < 0)
linearLegInput = Runners.size() - 1;
int minL, maxL;
Class->getParallelOptionalRange(linearLegInput, minL, maxL);
int ft = numeric_limits<int>::max();
pRunner res = nullptr;
for (int i = minL; i <= maxL; i++) {
if (size_t(i) < Runners.size())
continue;
if (res == nullptr)
res = Runners[i]; // Ensure any
if (i < Runners.size() && Runners[i] && Runners[i]->prelStatusOK(false, false, false)) {
int f = Runners[i]->getFinishTime();
if (f > 0 && f < ft) {
ft = f;
res = Runners[i];
}
}
}
return res;
}

View File

@ -141,6 +141,8 @@ protected:
public: public:
bool matchAbstractRunner(const oAbstractRunner* target) const override;
/** Deduce from computed runner times.*/ /** Deduce from computed runner times.*/
RunnerStatus deduceComputedStatus() const; RunnerStatus deduceComputedStatus() const;
int deduceComputedRunningTime() const; int deduceComputedRunningTime() const;
@ -230,6 +232,10 @@ public:
return cnt; return cnt;
} }
/** For legs with many parallel / extra runner, get the runner with the
first finish time */
pRunner getRunnerBestTimePar(int linearLegInput) const;
void decodeRunners(const string &rns, vector<int> &rid); void decodeRunners(const string &rns, vector<int> &rid);
void importRunners(const vector<int> &rns); void importRunners(const vector<int> &rns);
void importRunners(const vector<pRunner> &rns); void importRunners(const vector<pRunner> &rns);

View File

@ -692,17 +692,12 @@ void oEvent::adjustTeamMultiRunners(pClass cls)
tr.pop_back(); tr.pop_back();
} }
} }
disableRecalculate = true;
try { noReevaluateOperation([&]() {
for (auto &t : Teams) { for (auto& t : Teams) {
t.adjustMultiRunners(); t.adjustMultiRunners();
} }
} });
catch(...) {
disableRecalculate = false;
throw;
}
disableRecalculate = false;
} }
void oTeam::adjustMultiRunners() { void oTeam::adjustMultiRunners() {

View File

@ -100,13 +100,18 @@ int OnlineInput::processButton(gdioutput &gdi, ButtonInfo &bi) {
} }
else if (bi.id == "UseUnitId") { else if (bi.id == "UseUnitId") {
useUnitId = gdi.isChecked(bi.id); useUnitId = gdi.isChecked(bi.id);
updateLabel(gdi);
}
return 0;
}
void OnlineInput::updateLabel(gdioutput& gdi)
{
if (useUnitId) if (useUnitId)
gdi.setTextTranslate("CmpID_label", L"Enhetens ID-nummer (MAC):", true); gdi.setTextTranslate("CmpID_label", L"Enhetens ID-nummer (MAC):", true);
else else
gdi.setTextTranslate("CmpID_label", L"Tävlingens ID-nummer:", true); gdi.setTextTranslate("CmpID_label", L"Tävlingens ID-nummer:", true);
}
return 0;
} }
void OnlineInput::fillMappings(gdioutput &gdi) const{ void OnlineInput::fillMappings(gdioutput &gdi) const{
@ -134,6 +139,10 @@ void OnlineInput::settings(gdioutput &gdi, oEvent &oe, State state) {
gdi.addCheckbox("UseROC", "Använd ROC-protokoll", OnlineCB, useROCProtocol).setExtra(getId()); gdi.addCheckbox("UseROC", "Använd ROC-protokoll", OnlineCB, useROCProtocol).setExtra(getId());
gdi.addCheckbox("UseUnitId", "Använd enhets-id istället för tävlings-id", OnlineCB, useROCProtocol && useUnitId).setExtra(getId()); gdi.addCheckbox("UseUnitId", "Använd enhets-id istället för tävlings-id", OnlineCB, useROCProtocol && useUnitId).setExtra(getId());
gdi.setInputStatus("UseUnitId", useROCProtocol); gdi.setInputStatus("UseUnitId", useROCProtocol);
if (useROCProtocol && useUnitId)
gdi.addInput("CmpID", unitId, 10, 0, L"Enhetens ID-nummer (MAC):");
else
gdi.addInput("CmpID", itow(cmpId), 10, 0, L"Tävlingens ID-nummer:"); gdi.addInput("CmpID", itow(cmpId), 10, 0, L"Tävlingens ID-nummer:");
gdi.dropLine(1); gdi.dropLine(1);

View File

@ -71,6 +71,8 @@ public:
int processButton(gdioutput &gdi, ButtonInfo &bi); int processButton(gdioutput &gdi, ButtonInfo &bi);
void updateLabel(gdioutput& gdi);
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final; void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
void settings(gdioutput &gdi, oEvent &oe, State state) final; void settings(gdioutput &gdi, oEvent &oe, State state) final;
static void controlMappingView(gdioutput& gdi, GUICALLBACK cb, int widgetId); static void controlMappingView(gdioutput& gdi, GUICALLBACK cb, int widgetId);

View File

@ -29,8 +29,8 @@ struct SpeakerString {
wstring str; wstring str;
int format; int format;
bool hasTimer; bool hasTimer;
int timer; int timer; // Timer time (in normal time units)
int timeout; int timeout; // Timeout time (in seconds)
string moveKey; string moveKey;
GDICOLOR color; GDICOLOR color;
SpeakerString() : format(0), hasTimer(false), timer(0), timeout(NOTIMEOUT), color(colorDefault) {} SpeakerString() : format(0), hasTimer(false), timer(0), timeout(NOTIMEOUT), color(colorDefault) {}

View File

@ -443,7 +443,7 @@ void RestServer::computeInternal(oEvent &ref, shared_ptr<RestServer::EventReques
if (!res->second.second) { if (!res->second.second) {
res->second.second = make_shared<oListInfo>(); res->second.second = make_shared<oListInfo>();
ref.generateListInfo(res->second.first, *res->second.second); ref.generateListInfo(gdiPrint, res->second.first, *res->second.second);
} }
ref.generateList(gdiPrint, true, *res->second.second, false); ref.generateList(gdiPrint, true, *res->second.second, false);
//wstring exportFile = getTempFile(); //wstring exportFile = getTempFile();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1888
code/ukrainian.lng Normal file

File diff suppressed because it is too large Load Diff