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();
size_t tz = cdb.size() + rdb.size();
int s1 = (1000 * cdb.size())/tz;
int s2 = (1000 * rdb.size())/tz;
int s1 = tz > 0 ? (1000 * cdb.size())/tz : 0;
int s2 = tz > 0 ? (1000 * rdb.size())/tz : 0;
// Reset databases
con->query().exec("DELETE FROM dbClub");

View File

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

View File

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

View File

@ -770,9 +770,9 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
gdi.pushX();
gdi.fillRight();
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("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.addButton("DoRestart","OK", 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++)
par.selection.insert(cInfo[k].classId);
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
}
@ -1181,7 +1181,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info;
par.listCode = EStdStartList;
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.dropLine();
gdi.addButton("Cancel", "Återgå", ClassesCB);
@ -1470,7 +1470,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info;
par.listCode = EStdStartList;
par.selection = classes;
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
}
@ -1693,7 +1693,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
oListInfo info;
par.listCode = EStdStartList;
par.setLegNumberCoded(leg);
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
@ -1949,7 +1949,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
par.listCode = EStdStartList;
}
}
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
@ -2110,7 +2110,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
par.selection.insert(outClass.begin(), outClass.end());
oListInfo info;
par.listCode = EStdStartList;
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
}
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);
oListInfo info;
par.listCode = EStdStartList;
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
}

View File

@ -1542,7 +1542,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
if (importHiredCard)
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->getDI().setDate("OrdinaryEntry", lastEntry);
if (ci) {
@ -1555,13 +1555,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
}
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);
set<int> stageFilter;
string 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);
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);
}
else if (filterIndex == ImportFormats::OE) {
oe->exportOECSV(save.c_str(), cSVLanguageHeaderIndex, false);
oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, false);
}
else {
oListParam par;
@ -1811,8 +1811,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
par.setLegNumberCoded(-1);
oListInfo li;
par.selection = allTransfer;
oe->generateListInfo(par, li);
gdioutput tGdi("temp", gdi.getScale());
oe->generateListInfo(tGdi, par, li);
oe->generateList(tGdi, true, li, false);
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
tGdi.openDoc(save.c_str());
@ -1895,7 +1895,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
}
}
else if (filterIndex == ImportFormats::OE) {
oe->exportOECSV(save.c_str(), cSVLanguageHeaderIndex, includeSplits);
oe->exportOECSV(save.c_str(), allTransfer, cSVLanguageHeaderIndex, includeSplits);
}
else {
oListParam par;
@ -1903,8 +1903,8 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
par.showSplitTimes = true;
par.setLegNumberCoded(-1);
oListInfo li;
oe->generateListInfo(par, li);
gdioutput tGdi("temp", gdi.getScale());
oe->generateListInfo(tGdi, par, li);
oe->generateList(tGdi, true, li, false);
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
tGdi.openDoc(save.c_str());
@ -2049,12 +2049,6 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
entryForm(gdi, false);
gdi.pushX();
gdi.fillRight();
gdi.addButton("DoImport", "Importera", CompetitionCB);
gdi.fillDown();
gdi.addButton("Cancel", "Avbryt", CompetitionCB);
gdi.popX();
gdi.refresh();
}
else if (bi.id=="DoImport") {
@ -2063,9 +2057,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
gdi.disableInput("Cancel");
gdi.disableInput("BrowseEntries");
bool removeRemoved = gdi.isChecked("RemoveRemoved");
int classOffset = 0;
if (gdi.hasWidget("ClassOffset")) {
classOffset = gdi.getTextNo("ClassOffset");
}
try {
gdi.autoRefresh(true);
FlowOperation res = saveEntries(gdi, removeRemoved, false);
FlowOperation res = saveEntries(gdi, removeRemoved, classOffset, false);
if (res != FlowContinue) {
if (res == FlowCancel)
@ -2463,6 +2461,7 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
"\n\nMore French translations and documentation by Titouan Savart"
"\n\nCzech Translation by Marek Kustka"
"\n\nSpanish Translation by Manuel Pedre"
"\n\nUkranian Translation by Oleg Rozhko"
"\n\nHelp with English documentation: Torbjörn Wikström");
gdi.dropLine();
@ -2500,7 +2499,7 @@ void TabCompetition::updateWarning(gdioutput &gdi) const {
}
else if (n.length() >= limit && w.empty()) {
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.dropLine();
gdi.pushX();
if (!isGuide) {
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.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.popX();
gdi.dropLine(3.2);
gdi.dropLine(2.8);
if (!isGuide && oe->getNumRunners() > 0) {
gdi.addCheckbox("RemoveRemoved", "Ta bort eventuella avanmälda deltagare", 0, true);
gdi.dropLine(0.4);
}
gdi.popX();
gdi.dropLine(2.5);
gdi.dropLine(2);
gdi.addInput("FileNameRank", L"", 48, 0, L"Ranking (IOF, xml, csv)");
gdi.dropLine();
gdi.addButton("BrowseEntries", "Bläddra...", CompetitionCB).setExtra(L"FileNameRank");
gdi.popX();
gdi.fillDown();
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",
"FileNameRank", "FileNameService", "FileNameServiceReq"};
@ -3645,7 +3660,9 @@ FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, bo
if (res != FlowContinue)
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) {
gdi.setWindowTitle(oe->getTitleName());

View File

@ -123,7 +123,7 @@ class TabCompetition :
void createNewCmp(gdioutput &gdi, bool useExisting);
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);

View File

@ -590,7 +590,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
for (size_t k=0; k<courseDrawClasses.size(); k++)
par.selection.insert(courseDrawClasses[k].classID);
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
gdi.refresh();
}
@ -925,10 +925,16 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
if (strlen(bf) < 2)
continue;
if (0 == line && uint8_t(bf[0]) == 0xEF && uint8_t(bf[1]) == 0xBB && uint8_t(bf[2]) == 0xBF)
split(bf+3, " ;,", sw);
else
split(bf, " ;,", sw);
if (0 == line && uint8_t(bf[0]) == 0xEF && uint8_t(bf[1]) == 0xBB && uint8_t(bf[2]) == 0xBF) {
split(bf + 3, "\t;,", sw);
if (sw.size() == 1)
split(bf + 3, " ", sw);
}
else {
split(bf, "\t;,", sw);
if (sw.size() == 1)
split(bf, " ", sw);
}
line++;
if (sw.size() <= 1)
@ -965,7 +971,10 @@ void TabCourse::runCourseImport(gdioutput& gdi, const wstring &filename,
else {
set<int> noFilter;
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) {
// 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);
try {
oe->generateList(gdi, !noReEvaluate, currentList, false);
gdi.updatePosTight(gdi.getWidth(), gdi.getHeight(), gdi.scaleLength(10), gdi.scaleLength(30), 0, 0);
}
catch (const meosException &ex) {
wstring err = lang.tl(ex.wwhat());
@ -449,7 +450,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (gdi.getSelectedItem("SavedInstance", lbi)) {
oListParam &par = oe->getListContainer().getParam(lbi.data);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.getParam().sourceParam = lbi.data;
generateList(gdi);
}
@ -570,7 +571,8 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else if (bi.id=="CancelPS") {
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;
gdi.getData("Type", ctype);
saveExtraLines(*oe, ctype.c_str(), gdi);
@ -584,8 +586,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (gdi.hasWidget("SplitPrintList")) {
auto res = gdi.getSelectedItem("SplitPrintList");
if (res.second) {
if (res.first == -10)
oe->getDI().setString("SplitPrint", L"");
if (res.first == -11)
oe->getDI().setString("SplitPrint", L""); // Automatisk
else if (res.first == -10)
oe->getDI().setString("SplitPrint", L"*"); // Standard
else {
EStdListType type = oe->getListContainer().getType(res.first);
string id = oe->getListContainer().getUniqueId(type);
@ -608,7 +612,22 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
oe->setProperty("SplitPrintMaxWait", no);
}
}
gdi.getTabs().get(TabType(bi.getExtraInt()))->loadPage(gdi);
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);
}
else if (bi.id == "PrinterSetup") {
((TabSI *)gdi.getTabs().get(TSITab))->printerSetup(gdi);
@ -659,7 +678,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
lastSplitState = par.showSplitTimes;
lastLargeSize = par.useLargeSize;
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
@ -689,7 +708,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getIndividual(par.selection, false);
readSettings(gdi, par, true);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -705,7 +724,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.showSplitTimes = true;
par.setLegNumberCoded(-1);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -717,7 +736,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartIndividual(par, cnf);
readSettings(gdi, par, false);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -728,7 +747,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartClub(par);
readSettings(gdi, par, false);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -743,7 +762,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
readSettings(gdi, par, false);
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -775,7 +794,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getStartTeam(par, cnf);
readSettings(gdi, par, false);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -791,7 +810,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
cnf.getRaceNStart(race, par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -807,7 +826,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
cnf.getLegNStart(race, par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -819,7 +838,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
oe->getClassConfigurationInfo(cnf);
getResultTeam(par, cnf);
readSettings(gdi, par, true);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -831,7 +850,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
cnf.getRaceNRes(0, par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -846,7 +865,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
cnf.getRaceNRes(race, par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -861,7 +880,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
cnf.getLegNRes(race, par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -874,7 +893,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
getResultRogaining(par, cnf);
readSettings(gdi, par, true);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -904,7 +923,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getIndividual(par.back().selection, true);
}
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -915,7 +934,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.listCode = EStdRentedCard;
par.showHeader = gdi.isChecked("ShowHeader");
par.setLegNumberCoded(-1);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -927,7 +946,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
par.listCode = EIndPriceList;
par.showHeader = gdi.isChecked("ShowHeader");
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
generateList(gdi);
gdi.refresh();
}
@ -997,7 +1016,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
cnf.getPatrol(par.selection);
}
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -1012,7 +1031,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
ClassConfigInfo cnf;
oe->getClassConfigurationInfo(cnf);
par.selection = set<int>(cnf.knockout.begin(), cnf.knockout.end());
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -1032,7 +1051,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else
par.selection = set<int>(cnf.lapcountsingle.begin(), cnf.lapcountsingle.end());
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -1056,7 +1075,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (oListInfo::addTeams(type))
cnf.getTeamClass(par.selection);
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
currentList.setCallback(openRunnerTeamCB);
generateList(gdi);
gdi.refresh();
@ -1193,7 +1212,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
else if (type==GUI_LISTBOX) {
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);
}
else if (lbi.id == "SavedInstance") {
@ -1290,7 +1312,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
if (!listEditor)
listEditor = make_shared<ListEditor>(oe);
gdi.clearPage(false);
listEditor->load(oe->getListContainer(), ix);
listEditor->load(oe->getListContainer(), ix, false);
listEditor->show(this, gdi);
gdi.refresh();
}
@ -2562,22 +2584,27 @@ bool TabList::loadPage(gdioutput &gdi)
MetaListContainer &lc = oe->getListContainer();
if (lc.getNumLists(MetaListContainer::ExternalList) > 0) {
gdi.addString("", fontMediumPlus, "Egna listor").setColor(colorDarkGrey);
gdi.fillRight();
gdi.pushX();
bool init = false;
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);
checkWidth(gdi);
gdi.addButton("CustomList", mc.getListName(), ListsCB).setExtra(k);
}
}
gdi.popX();
gdi.dropLine(3);
gdi.fillDown();
if (init) {
gdi.popX();
gdi.dropLine(3);
gdi.fillDown();
}
}
vector< pair<wstring, size_t> > savedParams;
@ -2762,28 +2789,38 @@ void TabList::splitPrintSettings(oEvent &oe, gdioutput &gdi, bool setupPrinter,
if (!oe.empty() && type == Splits) {
gdi.fillRight();
gdi.addSelection("SplitPrintList", 200, 200, nullptr, L"Sträcktidslista:");
if (setupPrinter) {
gdi.dropLine(0.9);
gdi.addSelection("SplitPrintList", 200, 200, ListsCB, L"Sträcktidslista:");
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.dropLine(2.8);
}
else {
gdi.dropLine(3);
}
gdi.dropLine(2.8);
gdi.fillDown();
gdi.popX();
gdi.addString("", 10, "info:customsplitprint");
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");
EStdListType type = oe.getListContainer().getCodeFromUnqiueId(gdioutput::narrow(listId));
if (type == EStdListType::EStdNone)
gdi.selectFirstItem("SplitPrintList");
EStdListType type = EStdListType::EStdNone;
if (listId.length() > 1)
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 {
for (auto& t : lists) {
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);
oListInfo info;
par.listCode = EStdStartList;
oe->generateListInfo(par, info);
oe->generateListInfo(gdi, par, info);
oe->generateList(gdi, false, info, true);
}
}
@ -3067,6 +3067,21 @@ TabRunner::EconomyHandler *TabRunner::getEconomyHandler(oRunner &r) {
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) {
if (type == GuiEventType::GUI_BUTTON) {
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);
if (ii.id == "Fee") {
gdi.check("ModFee", ii.changed() || getRunner().hasFlag(oAbstractRunner::FlagFeeSpecified));
updateColor(gdi);
}
else if (ii.id == "Card") {
updateColor(gdi);
}
else if (ii.id == "PaidAmount") {
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);
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);
int paid = oe->interpretCurrency(gdi.getText("PaidAmount"));
r.getDI().setInt("Paid", paid);
@ -3138,24 +3178,26 @@ void TabRunner::loadEconomy(gdioutput &gdi, oRunner &r) {
gdi.dropLine();
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");
if (cf == -1) // Borrowed, zero fee
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");
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.dropLine();
vector< pair<wstring, size_t> > pm;
oe->getPayModes(pm);
int mypm = r.getDCI().getInt("PayMode");
//pm.insert(pm.begin(), make_pair(lang.tl(L"Faktureras"), 1000));
gdi.addSelection("PayMode", 110, 100, SportIdentCB);
if (paid == 0)
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.selectItemByData("PayMode", mypm);
gdi.autoGrow("PayMode");
gdi.setInputStatus("PayMode", paid != 0);
gdi.selectItemByData("PayMode", mypm);
gdi.dropLine();
gdi.popX();

View File

@ -99,6 +99,7 @@ private:
int runnerId;
oEvent *oe;
oRunner &getRunner() const;
void updateColor(gdioutput& gdi);
public:
void init(oRunner &r);
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("Cancel", "Avbryt", SportIdentCB).setExtra(origin);
gdi.fillDown();
gdi.scrollToBottom();
gdi.popX();
}
else {
@ -1853,25 +1854,33 @@ void TabSI::showReadPunches(gdioutput& gdi, vector<PunchInfo>& punches, set<stri
int yp = gdi.getCY();
int xp = gdi.getCX();
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++) {
if (k % 5 == 0)
yp += gdi.scaleLength(6);
sprintf_s(bf, "%d.", int(k + 1));
gdi.addStringUT(yp, xp, 0, bf);
pRunner r = oe->getRunnerByCardNo(punches[k].card, punches[k].time, oEvent::CardLookupProperty::Any);
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)
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) {
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);
}
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
gdi.addStringUT(yp, xp + 360, 0, makeDash(L"-"));
gdi.addStringUT(yp, xp + off[3], 0, makeDash(L"-"));
yp += gdi.getLineHeight();
}
@ -1882,18 +1891,25 @@ void TabSI::showReadCards(gdioutput& gdi, vector<SICard>& cards)
char bf[64];
int yp = gdi.getCY();
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++) {
if (k % 5 == 0)
yp += gdi.scaleLength(6);
sprintf_s(bf, "%d.", int(k + 1));
gdi.addStringUT(yp, xp, 0, bf);
pRunner r = oe->getRunnerByCardNo(cards[k].CardNumber, 0, oEvent::CardLookupProperty::Any);
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)
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();
}
}
@ -1914,10 +1930,16 @@ bool TabSI::loadPage(gdioutput& gdi) {
oe->checkDB();
gdi.setData("SIPageLoaded", 1);
if (!gSI) {
if (!gSI)
getSI(gdi);
if (oe->isClient())
if (firstLoadedAfterNew) {
if (oe->getNumRunners() == 0)
interactiveReadout = true;
else if (oe->isClient())
interactiveReadout = false;
firstLoadedAfterNew = false;
}
#ifdef _DEBUG
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 {
const bool wideFormat = oe->getPropertyInt("WideSplitFormat", 0) == 1;
if (!wideFormat && forPrinter)
gdi.setCX(10);
if (crdRef == nullptr)
crdRef = &getCard(cardId);
@ -4242,6 +4269,7 @@ void TabSI::StoredStartInfo::clear() {
}
void TabSI::clearCompetitionData() {
firstLoadedAfterNew = true;
printSplits = false;
interactiveReadout = oe->getPropertyInt("Interactive", 1) != 0;
useDatabase = oe->getPropertyInt("Database", 1) != 0;

View File

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

View File

@ -525,8 +525,34 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
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) {
ButtonInfo bi=*(ButtonInfo *)data;
@ -712,12 +738,14 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
gdi.dropLine();
gdi.addSelection("ForkKey", 100, 400, 0, L"Gafflingsnyckel:");
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++) {
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;
gdi.addItem("ForkKey", keys);
gdi.autoGrow("ForkKey");
gdi.selectItemByData("ForkKey", currentKey);
gdi.dropLine(0.9);
@ -1315,8 +1343,8 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
if (numF>1 && t) {
gdi.addString ("", 1, "Gafflingsnyckel X#" + itos(1+(max(t->getStartNo()-1, 0) % numF))).setColor(colorGreen);
wstring crsList;
bool hasCrs = false;
wstring crsList = getForking(pc, t->getStartNo(), 50);
/*bool hasCrs = false;
for (size_t k = 0; k < pc->getNumStages(); k++) {
pCourse crs = pc->getCourse(k, t->getStartNo());
wstring cS;
@ -1338,9 +1366,10 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
}
if (hasCrs && !crsList.empty()) {
gdi.addStringUT(0, crsList);
}
}*/
if (hasCrs) {
if (!crsList.empty()) {
gdi.addStringUT(0, crsList);
gdi.dropLine(0.5);
gdi.setRestorePoint("ChangeKey");
gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB);

View File

@ -53,15 +53,28 @@ extern gdioutput *gdi_main;
static int wtoi(const wstring &sp) {
return _wtoi(sp.c_str());
}
csvparser::csvparser()
{
csvparser::csvparser() {
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) {
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) ...
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,
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,
OSRfinish=5, OSRstatus=7, OSRcard=8, OSRrentcard=9};
nimport=0;
list< vector<wstring> > allLines;
parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin();
set<wstring> matchedClasses;
// Skip first line
while (++it != allLines.end()) {
//fin.getline(bf, 1024);
//split(bf, sp);
const vector<wstring> &sp = *it;
oe.noReevaluateOperation([&]() {
if (sp.size()>20 && sp[OSclub].size()>0)
{
nimport++;
nimport = 0;
list<vector<wstring>> allLines;
parse(file, allLines);
auto it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
//Create club with this club number...
int ClubId=wtoi(sp[OSclubno]);
pClub pclub=event.getClubCreate(ClubId, sp[OSclub]);
int line = 1;
set<wstring> matchedClasses;
// Skip first line
while (++it != allLines.end()) {
CSVLineWrapper sp(++line, *it);
if (pclub){
pclub->getDI().setString("Nationality", sp[OSnat]);
pclub->synchronize(true);
if (sp.size() > 20 && sp[OSclub].size() > 0)
{
nimport++;
//Create club with this club number...
int ClubId = wtoi(sp[OSclubno]);
pClub pclub = oe.getClubCreate(ClubId, sp[OSclub]);
if (pclub) {
pclub->getDI().setString("Nationality", sp[OSnat]);
pclub->synchronize(true);
}
//Create class with this class number...
int ClassId = wtoi(sp[OSclassno]);
oe.getClassCreate(ClassId, sp[OSclass], matchedClasses);
//Club is autocreated...
pTeam team = oe.addTeam(sp[OSclub] + L" " + sp[OSdesc], ClubId, ClassId);
team->setEntrySource(externalSourceId);
team->setStartNo(wtoi(sp[OSstno]), oBase::ChangeType::Update);
if (sp[12].length() > 0)
team->setStatus(ConvertOEStatus(wtoi(sp[OSstatus])), true, oBase::ChangeType::Update);
team->setStartTime(oe.convertAbsoluteTime(sp[OSstart]), true, oBase::ChangeType::Update);
if (sp[OStime].length() > 0)
team->setFinishTime(oe.convertAbsoluteTime(sp[OSstart]) + oe.convertAbsoluteTime(sp[OStime]) - oe.getZeroTimeNum());
if (team->getStatus() == StatusOK && team->getFinishTime() == 0)
team->setStatus(StatusUnknown, true, oBase::ChangeType::Update);
unsigned rindex = Offset;
oDataInterface teamDI = team->getDI();
teamDI.setInt("Fee", wtoi(sp[OSfee]));
teamDI.setInt("Paid", wtoi(sp[OSpaid]));
teamDI.setString("Nationality", sp[OSnat]);
//Import runners!
int runner = 0;
while ((rindex + OSRrentcard) < sp.size() && sp[rindex + OSRfname].length() > 0) {
int cardNo = wtoi(sp[rindex + OSRcard]);
wstring sname = sp[rindex + OSRsname] + L", " + sp[rindex + OSRfname];
pRunner r = oe.addRunner(sname, ClubId,
ClassId, cardNo, sp[rindex + OSRyb], false);
r->setEntrySource(externalSourceId);
oDataInterface DI = r->getDI();
r->setSex(interpretSex(sp[rindex + OSRsex]));
DI.setString("Nationality", sp[OSnat]);
if (sp[rindex + OSRrentcard].length() > 0)
DI.setInt("CardFee", oe.getDCI().getInt("CardFee"));
//r->setCardNo(atoi(sp[rindex+OSRcard]), false);
r->setStartTime(oe.convertAbsoluteTime(sp[rindex + OSRstart]), true, oBase::ChangeType::Update);
r->setFinishTime(oe.convertAbsoluteTime(sp[rindex + OSRfinish]));
if (sp[rindex + OSRstatus].length() > 0)
r->setStatus(ConvertOEStatus(wtoi(sp[rindex + OSRstatus])), true, oBase::ChangeType::Update, false);
if (r->getStatus() == StatusOK && r->getRunningTime(false) == 0)
r->setStatus(StatusUnknown, true, oBase::ChangeType::Update, false);
r->addClassDefaultFee(false);
team->setRunner(runner++, r, true);
rindex += PostSize;
}
//int nrunners=team->GetNumRunners();
pClass pc = oe.getClass(ClassId);
int teamId = team->getId();
if (pc && runner > (int)pc->getNumStages()) {
oe.setupRelay(*pc, oEvent::PRelay, runner, oe.getAbsTime(timeConstHour));
}
team = oe.getTeam(teamId);
if (team)
team->evaluate(oBase::ChangeType::Update);
}
//Create class with this class number...
int ClassId=wtoi(sp[OSclassno]);
event.getClassCreate(ClassId, sp[OSclass], matchedClasses);
//Club is autocreated...
pTeam team=event.addTeam(sp[OSclub] + L" " + sp[OSdesc], ClubId, ClassId);
team->setEntrySource(externalSourceId);
team->setStartNo(wtoi(sp[OSstno]), oBase::ChangeType::Update);
if (sp[12].length()>0)
team->setStatus( ConvertOEStatus( wtoi(sp[OSstatus]) ), true, oBase::ChangeType::Update);
team->setStartTime(event.convertAbsoluteTime(sp[OSstart]), true, oBase::ChangeType::Update);
if (sp[OStime].length()>0)
team->setFinishTime( event.convertAbsoluteTime(sp[OSstart])+event.convertAbsoluteTime(sp[OStime])-event.getZeroTimeNum() );
if (team->getStatus()==StatusOK && team->getFinishTime()==0)
team->setStatus(StatusUnknown, true, oBase::ChangeType::Update);
unsigned rindex=Offset;
oDataInterface teamDI=team->getDI();
teamDI.setInt("Fee", wtoi(sp[OSfee]));
teamDI.setInt("Paid", wtoi(sp[OSpaid]));
teamDI.setString("Nationality", sp[OSnat]);
//Import runners!
int runner=0;
while( (rindex+OSRrentcard)<sp.size() && sp[rindex+OSRfname].length()>0 ){
int cardNo = wtoi(sp[rindex+OSRcard]);
wstring sname = sp[rindex+OSRsname] + L", " + sp[rindex+OSRfname];
pRunner r = event.addRunner(sname, ClubId,
ClassId, cardNo, sp[rindex + OSRyb], false);
r->setEntrySource(externalSourceId);
oDataInterface DI=r->getDI();
r->setSex(interpretSex(sp[rindex + OSRsex]));
DI.setString("Nationality", sp[OSnat]);
if (sp[rindex+OSRrentcard].length() > 0)
DI.setInt("CardFee", event.getDCI().getInt("CardFee"));
//r->setCardNo(atoi(sp[rindex+OSRcard]), false);
r->setStartTime(event.convertAbsoluteTime(sp[rindex+OSRstart]), true, oBase::ChangeType::Update);
r->setFinishTime( event.convertAbsoluteTime(sp[rindex+OSRfinish]) );
if (sp[rindex+OSRstatus].length()>0)
r->setStatus( ConvertOEStatus( wtoi(sp[rindex+OSRstatus]) ), true, oBase::ChangeType::Update, false);
if (r->getStatus()==StatusOK && r->getRunningTime(false)==0)
r->setStatus(StatusUnknown, true, oBase::ChangeType::Update, false);
r->addClassDefaultFee(false);
team->setRunner(runner++, r, true);
rindex+=PostSize;
}
//int nrunners=team->GetNumRunners();
pClass pc=event.getClass(ClassId);
if (pc && runner>(int)pc->getNumStages())
pc->setNumStages(runner);
team->evaluate(oBase::ChangeType::Update);
}
}
fin.close();
fin.close();
});
oe.reEvaluateAll({}, 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,
OElength=40};
list< vector<wstring> > allLines;
list<vector<wstring>> 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;
// Skip first line
nimport=0;
while (++it != allLines.end()) {
const vector<wstring> &sp = *it;
CSVLineWrapper sp(++line, *it);
if (sp.size()>20) {
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) {
list< vector<wstring> > allLines;
parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin();
auto it = allLines.begin();
int line = 0;
while(it != allLines.end()) {
const vector<wstring> &sp = *it;
CSVLineWrapper sp(++line, *it);
++it;
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,
RAIDclassid=5, RAIDrunner1=6, RAIDrunner2=7, RAIDcanoe=8};
list< vector<wstring> > allLines;
list<vector<wstring>> allLines;
parse(file, allLines);
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;
int line = 1;
while (++it != allLines.end()) {
const vector<wstring> &sp = *it;
CSVLineWrapper sp(++line, *it);
if (sp.size()>7) {
nimport++;
@ -710,7 +741,7 @@ bool csvparser::importRAID(oEvent &event, const wstring &file)
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,
wstring &processedTime, wstring &processedDate) {
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)
{
punches.clear();
/* fin.clear();
fin.open(file);
if (!fin.good())
return false;
*/
list< vector<wstring> > allLines;
list<vector<wstring>> allLines;
parse(file, allLines);
list< vector<wstring> >::iterator it = allLines.begin();
//const size_t siz = 1024 * 1;
//char bf[siz];
//string bfs;
//fin.getline(bf, siz);
//std::getline(fin, bfs);
auto it = allLines.begin();
if (it == allLines.end())
throw meosException("Invalid CSV file");
nimport=0;
int cardIndex = -1;
@ -792,19 +812,9 @@ bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<Punc
wstring processedTime, processedDate;
const wstring date = oe.getDate();
//vector<char *> sp;
int line = 0;
while (++it != allLines.end()) {
const vector<wstring> &sp = *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);
*/
CSVLineWrapper sp(++line, *it);
int ret = selectPunchIndex(date, sp, cardIndex, timeIndex, dateIndex,
processedTime, processedDate);
@ -818,7 +828,6 @@ bool csvparser::importPunches(const oEvent &oe, const wstring &file, vector<Punc
PunchInfo pi;
pi.card = card;
pi.time = time;
//string pd(processedDate.begin(), processedDate.end());
string pd = gdioutput::narrow(processedDate);
strncpy_s(pi.date, pd.c_str(), 26);
pi.date[26] = 0;
@ -840,7 +849,7 @@ int analyseSITime(const wchar_t *dow, const wchar_t *time, bool &is12Hour)
return t;
}
void csvparser::checkSIConfigHeader(const vector<wstring> &sp) {
void csvparser::checkSIConfigHeader(const CSVLineWrapper &sp) {
siconfigmap.clear();
if (sp.size() < 200)
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);
if (res == siconfigmap.end() || size_t(res->second) >= sp.size())
return L"";
@ -910,7 +919,7 @@ const wchar_t *csvparser::getSIC(SIConfigFields sic, const vector<wstring> &sp)
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())
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)
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)
{
cards.clear();
list< vector<wstring> > allLines;
list<vector<wstring>> allLines;
parse(file, allLines);
//vector<wchar_t *> sp;
list< vector<wstring> >::iterator it = allLines.begin();
auto it = allLines.begin();
if (it == allLines.end())
return false;
// fin.clear();
// fin.open(file);
// if (!fin.good())
// 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);
checkSIConfigHeader(CSVLineWrapper(1, *it));
nimport=0;
int line = 1;
while (++it != allLines.end()) {
//fin.getline(bf, s);
//split(bf, sp);
const vector<wstring> &sp = *it;
CSVLineWrapper sp(++line, *it);
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();
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
#endif // _MSC_VER > 1000
#include <vector>
#include <map>
@ -38,6 +33,8 @@ class oEvent;
struct SICard;
class ImportFormats;
class CSVLineWrapper;
struct PunchInfo {
int code;
int card;
@ -71,13 +68,13 @@ protected:
string ErrorMessage;
// 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
void checkSIConfigHeader(const vector<wstring> &sp);
void checkSIConfigHeader(const CSVLineWrapper &sp);
// 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 {
sicSIID,
@ -97,12 +94,12 @@ protected:
};
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
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,
wstring &processedTime, wstring &date);
@ -153,5 +150,3 @@ public:
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ž
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 tiondels sekunder = Aktivuj podporu sub-sekundové časomíry.
Aktuell tid = Aktuální čas
AllPunches = Všechna ražení
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älningsdatum = Datum přihlášky
Anmälningsläge = Rychlé zadávání
Anmälningstid = Čas přihlášení
Anonymt namn = Anonymní jméno
Anslut = Spoj
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 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 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 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
@ -130,6 +133,7 @@ Automater = Služby
Automatic rogaining point reduction = Automatická bodová srážka pro rogaining
Automatisera = Automatizovat
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 omladdning = Automatický update
Automatisk skroll = Automatický posuv
@ -141,6 +145,7 @@ Available symbols = Dostupné symboly
Avancerat = Pokročilý
Avbockade brickor = Zaškrtnuté čipy
Avbryt = Zruš
Avbryt inläsning = Zruš vyčtení
Avdrag = Srážka
Avgift = Vklad
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, stafett = Přiřazení tratě, štafeta
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)
Batteridatum = Datum baterie
Batteristatus = Stav baterie
Begränsa antal per klass = Max. počet v kategorii
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
Brickan används av X = Čip je používán X
Brickan redan inläst = Čip byl již vyčten
Brickavläsning = Vyčtení čipu
Brickhantering = Spravuj čipy
Brickhyra = Vklad za čip
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
Calculate and apply forking = Spočítej a použij větvení
Cancel = Zrušit
Cannot represent ID X = Nemohu zobrazit ID 'X'
Centrera = Centrum
Check = Check
Check: X = Check: X
Checkenhet = Zkontroluj jednotku
Choose result module = Zvol výsledkový modul
ClassAvailableMaps = Dostupné mapy pro kategorii
ClassCourseResult = Kategorie, trať, výsledek
@ -274,8 +285,10 @@ Climb (m) = Stoupání (m)
Club = Oddíl
Club and runner database = Databáze oddílů a závodníků
Club id number = ID číslo oddílu
ClubClassStartTime = Oddíl, kategorie, čas startu
ClubName = Oddíl
ClubRunner = Oddíl (závodník)
ClubTeam = Oddíl (Týmy)
Clubs = Oddíly
CmpDate = Datum závodu
CmpName = Název závodu
@ -300,6 +313,7 @@ CourseClasses = Trať - kategorie
CourseClimb = Stoupání trati
CourseLength = Délka trati, specifická trat
CourseName = Název trati
CourseNumber = Číslo trati
CoursePunches = Ražení (na trati)
CourseResult = Trať, výsledek
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 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 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
Direkt tidtagning = Časomíra živě
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'
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 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
Duplicera = Kopíruj
Duplicerad nummerlapp: X, Y = Duplicitní startovní číslo: X, Y
Dölj = Schovat
Döp om = Přejmenuj
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 (utan banor) = Jen časomíra (bez tratí)
Endast tidtagning (utan banor), stafett = Jen časomíra (bez tratí), štafety
Enhet = Jednotka
Enhetens ID-nummer (MAC) = ID zařízení (MAC)
Enhetskod = Kód zařízení
Enhetstyp = Typ
EntryTime = Čas přihlášky
Error in result module X, method Y (Z) = Chyba ve výsledkovém modulu 'X', metoda 'Y'\n\nZ
Etapp = Etapa
Etapp X = Etapa X
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 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
@ -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 = Vícero tratí / Štafeta
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 höger = Vpravo
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
Identifierar X unika inledningar på banorna = Nalezeno X jedinečných začátků tratí
Ignorera startstämpling = Ignoruj ražení startu
Ignorerade X duplikat = Ignorováno X duplicit
Image = Obraz
Importera = Import
Importera IOF (xml) = Import IOF (xml)
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 nummerlapp = Bez startovního čísla
Ingen parstart = Individualní start
Ingen reducerad avgift = Bez sníženého poplatku
Ingen rogaining = Není rogaining
Ingen[competition] = Žádný
Inget filter = Žadný filtr
Inget nummer = žádné číslo
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 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í
Inläst bricka ställd i kö = Čip byl zařazen do fronty
Inlästa brickor = Vyčítej čipy
@ -923,6 +953,7 @@ Lag = Tým
Lag %d = Tým %d
Lag + sträcka = Tým + úsek
Lag och stafett = Tým a štafeta
Lag utan nummerlapp: X = Tým bez start. čísla: X
Lag(flera) = Týmy
Laget 'X' saknar klass = Tým 'X' je bez kategorie
Laget hittades inte = Tým nenalezen
@ -1002,6 +1033,7 @@ Lyssna = Poslouchat
Lyssnar på X = Naslouchám X
Lägg till = Přidat
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 klasser = Přidat/Obnovit kategorie
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
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 gaffllingsvarianter att skapa = Maximální počet klíčů větvení
Max antal gemensamma kontroller = Maximální počet společných kontrol
Max parallellt startande = Max. počet souběžných startů
Max. vakanser (per klass) = Max. rezerva (pro kategorii)
@ -1119,6 +1152,7 @@ Multipel = Násobná
MySQL Server / IP-adress = MySQL Server / IP-adresa
Män = Muži
Mål = Cíl
Målenhet = Cílová jednotka
Målfil = Cílový soubor
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)
@ -1149,6 +1183,8 @@ Normalavgift = Normální vklad
Not implemented = Není implementováno
Not yet implemented = Dosud neimplementováno
Nr = Číslo
NumEntries = Počet přihlášek
NumStarts = Počet startů
Number of shortenings = Počet zkrácení
Nummerlapp = Startovní číslo
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í
Prisutdelningslista = Protokol vyhlášení výsledků
Programinställningar = Nastavení programu
Programmera stationen utan AUTOSEND = Nastav na jednotce vypnutý AUTO SEND
Prolog + jaktstart = Prolog + hendikep
Prologue + Pursuit = Prolog + hendikep
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 för X = Edituj délky úseků pro 'X'
Reducerad avg = Snížený vkl.
Reducerad avgift = Snížený poplatek
Reducerad avgift för = Snížený poplatek za
Reduktionsmetod = Metoda snížení
Referens = Reference
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
RunnerAge = Závodníkův věk
RunnerBib = Závodník: Startovní číslo
RunnerBirthDate = Datum narození
RunnerBirthYear = Závodníkovo datum narození
RunnerCard = Závodník: Číslo čipu
RunnerCardVoltage = Napětí karty/čipu
@ -1527,6 +1567,7 @@ SOFT-avgift = SOFT vklad
SOFT-lottning = Švédská losovací metoda
SRR Dongle = SRR dongl
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
Samma = Stejný
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
Skapa = Vytvoř
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, tom, tävling = Založit nový, prázdný závod
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 inställningar = Ulož nastavení
Spara laguppställningar = Ulož složení týmů
Spara oparad bricka = Ulož nespárovaný čip
Spara på disk = Ulož na disk
Spara som = Ulož jako
Spara som PDF = Ulož do PDF
@ -1698,6 +1741,7 @@ Startbevis = Startovní certifikát
Startbevis X = Startovní certifikát X
Startblock = Startovní blok
Startblock: %d = Startovní blok: %d
Startenhet = Spustit jednotku
Startgrupp = Startovní skupina
Startgrupp med id X tilldelad Y finns inte = Startovní skupina s ID X definovaným pro Y neexistuje
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/WinSplits = Mezičasy/WinSplits
Sträcktidsfil = Jméno souboru
Sträcktidslista = Výpis mezičasů
Sträcktidsutskrift = Tiskni mezičasy
Sträcktidsutskrift[check] = Tiskni mezičasy automaticky
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
TeamBib = Startovní číslo týmu
TeamClub = Oddíl týmu
TeamCourseName = Jméno trati pro tým
TeamCourseNumber = Číslo trati pro tým
TeamFee = Startovné týmu
TeamGlobal = Tým (kategorie spolu)
TeamGrossTime = Čas týmu před úpravou
TeamLegName = Jméno úseku
TeamLegTimeAfter = Ztráta týmu na úseku
TeamLegTimeStatus = Čas týmu / status na úseku
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.
Tjänstebeställningar (IOF XML) = Požadavky služeb (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
Total = Celkem
Total tävlingsavgift = Celkové vklady závodu
Total/team result at a control = Celkový/týmový výsledek na kontrole
TotalCounter = Primární čítač
TotalRunLength = Celková běžecká vzdálenost
TotalRunTime = Celková doba běhue
Totalresultat = Celkové výsledky
Totalresultat - X = Celkové výsledky - X
Totalt = Celkem
@ -2001,7 +2052,9 @@ Undre gräns (år) = Od věku (roky)
Undre ålder = Nižší věk
Unexpected Fee = Neočekávané vklady
Unfair control legs = Nespravedlivé úseky
Unga, till och med X år = Mládež, do X let
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
Ungdomsklasser = mládežnické kategorie
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: 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
Varningar i X = Varování pro X
Varvningskontroll = Společná kontrola
Varvräkning = Počet kol
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 allt = Vyber vše
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 kommer efter denna tävling = Zvol následující etapu
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 rader kunde inte raderas = X řádků nemůže být smazáno
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 sträcknummer = X není platné číslo úseku
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: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ý).
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: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á?
@ -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ť.
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: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: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: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: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: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é.
@ -2388,6 +2450,7 @@ prefsAddress = Výchozí adresa
prefsAdvancedClassSettings = Ukaž pokročilá nastavení kategorie
prefsAutoSaveTimeOut = Interval automatického zálohování (ms)
prefsAutoTie = Spoj závodníka/čip automaticky
prefsAutoTieRent = Automatická správa zapůjčených čipů
prefsCardFee = Výchozí poplatek za čip
prefsClient = Jméno klienta v síti
prefsCodePage = Kódová tabulka pro 8-bitový text při importu/exportu.
@ -2407,6 +2470,9 @@ prefsEMail = e-mail
prefsEliteFee = Výchozí vklad elity
prefsEntryFee = Výchozí vklad
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
prefsExportFormat = Preferovaný exportní formát
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å 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: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: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
@ -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?
xml-data = xml data
Äldre protokoll = Starý protokol
Äldre, från och med X år = Veteráni, X let a víc
Ändra = Změna
Ändra MeOS lokala systemegenskaper = Změň lokální systémová nastavení MeOSu
Ändra X = Změň X
@ -2562,6 +2630,7 @@ xml-data = xml data
Öppen = Otevřená
Öppen klass = Otevřená kategorie
Öppna = Otevřít
Öppna avläsningsfönster = Otevři vyčítací okno
Öppna fil = Otevři soubor
Öppna från aktuell tävling = Otevři z tohoto závodu
Ö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
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 tiondels sekunder = Aktiver uderstøttelse af tiendedels sekund.
Aktuell tid = Aktuel tid
AllPunches = Alle stemplinger
Alla = Alle
@ -59,11 +60,12 @@ Anmälan mottagen = Tilmelding modtaget
Anmälan måste hanteras manuellt = Tilmelding skal håndteres manuelt.
Anmälda = Tilmeldte
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 (IOF (xml) eller OE-CSV) = Tilmeldinger (IOF-XML) eller OE-CSV)
Anmälningsavgift = Startafgift
Anmälningsdatum = Tilmeldingsdato
Anmälningsläge = Hurtig tilmelding
Anmälningstid = Tilmeldingtidspunkt
Anonymt namn = Anonymt navn
Anslut = Forbind
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 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 listan för sträcktidsutskrift = Brug listen for stræktidsudskrift
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 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
Automatisera = Automatiser
Automatisk = Automatisk
Automatisk hyrbrickshantering genom registrerade hyrbrickor = Automatisk håndtering af lejebrikker med præ-registrerede lejebrikker
Automatisk lottning = Automatisk lodtrækning
Automatisk omladdning = Automatisk opdatering
Automatisk skroll = Automatisk rulning
Automatisk utskrift / export = Automatisk udskrift / eksport
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
Available symbols = Tilgængelige symboler
Avancerat = Avanceret
Avbockade brickor = Afkrydsede brikker
Avbryt = Afbryd
Avbryt inläsning = afbryd indlæsning
Avdrag = Fradrag
Avgift = Afgift
Avgifter = Afgifter
@ -161,8 +167,8 @@ Bad file format = Forkert filformat
Bakgrund = Baggrund
Bakgrundsfärg = Baggrundsfarve
Bakåt = Tilbage
Bana %d = Bane %d
Bana = Bane
Bana %d = Bane %d
Bana med slingor = Bane med sløjfer
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
@ -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
Bananvändning = Brug af bane
Banmall = Baneskabelon
Banor (antal kontroller) = Baner (antal poster)
Banor = Baner
Banor (antal kontroller) = Baner (antal poster)
Banor för %s, sträcka %d = Baner for %s, tur %d
Banor, IOF (xml) = Baner, (IOF-XML)
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, stafett = Banetildeling, stafet
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)
Batteridatum = Batteridato
Batteristatus = Batteristatus
Begränsa antal per klass = Begræns antal pr. klasse
Begränsa antal rader per sida = Begræns antal rækker per side
@ -213,18 +222,19 @@ BoldLarge = Fed, stor
BoldSmall = Fed, lille
Bomkvot = Bom kvotient
Bommade kontroller = Poster med tidstab
Bomtid = Tidstab
Bomtid (max) = Tidstab (max)
Bomtid (medel) = Tidstab (gennemsnit)
Bomtid (median) = Tidstab (median)
Bomtid = Tidstab
Bomtid: X = Tidstab: 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 %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 används också av = Brik X bruges også af
Brickan används av X = Brikken bruges af X
Brickan redan inläst = Brikken er allerede aflæst
Brickavläsning = Brikaflæsning
Brickhantering = Brikhåndtering
Brickhyra = Leje af brik
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
Calculate and apply forking = Beregn og brug gafling
Cancel = Annuller
Cannot represent ID X = Kan ikke repræsentere ID 'X'
Centrera = Centrer
Check = Check
Check: X = Check: X
Checkenhet = Check enhed
Choose result module = Vælg resultatmodul
ClassAvailableMaps = Tilgængelige kort for klasse
ClassCourseResult = Klasse, bane, resultater
ClassDefaultResult = Klasse, standardresultater
ClassFinishTime = Klasse, måltid
ClassKnockoutTotalResult = Klasse, knock-out, samlet resultat
ClassLength = Banelængde for klasse
@ -267,16 +280,17 @@ Climb (m) = Stigning (m)
Club = Klub
Club and runner database = Klub og løber database
Club id number = Klub id nummer
ClubClassStartTime = Klub, klasse, starttid
ClubName = Klub
ClubRunner = Klub / løber
ClubTeam = Klub (Teams)
Clubs = Klubber
CmpDate = Løbsdato
CmpName = Løbsnavn
Control = Post
Control = Post
Control Overview = Post oversigt
Control Statistics - X = Post statistik - X
Control Statistics = Post statistik
Control Statistics - X = Post statistik - X
ControlClasses = Klasser for post
ControlCodes = koder for post
ControlCourses = Baner for post
@ -294,6 +308,7 @@ CourseClasses = Banes klasser
CourseClimb = Banens højdemeter
CourseLength = Banelængde, specifik bane
CourseName = Banens navn
CourseNumber = Bane nummer
CoursePunches = Stemplinger (for bane)
CourseResult = Bane, resultater
CourseShortening = Baneafkortninger
@ -311,8 +326,8 @@ Database is used and cannot be deleted = Databasen er i brug og kan ikke slettes
Databaskälla = Databaskilde
Databasvarning: X = Database advarsel: X
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 (för första start) = Dato (for første start)
Datumfilter = Datofilter
Debug = Afprøv
Debug Output = Resultat af afprøvning
@ -330,9 +345,9 @@ Dela klassen = Del klassen
Dela klubbvis = Del klubbvis
Dela slumpmässigt = Del tilfældigt
Dela upp = Del op
Deltagare = Deltagere
Deltagare %d = Deltagere %d
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 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
@ -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 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 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
Direkt tidtagning = Direkte tidtagning
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'
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 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
Duplicera = Dupliker
Duplicerad nummerlapp: X, Y = Duplikeret brystnummer: X, Y
Dölj = Skjul
Döp om = Døb 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 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 grundläggande (enklast möjligt) = Kund grundlæggende(så simpelt som muligt)
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 tidtagning = Kun tidtagning
Endast tidtagning (utan banor) = Kun tidtagning (uden baner)
Endast tidtagning (utan banor), stafett = Kun tidtagning (uden baner), stafet
Endast tidtagning = Kun tidtagning
Enhet = Enhed
Enhetens ID-nummer (MAC) = Enhedens ID (MAC)
Enhetskod = Enhedskode
Enhetstyp = Enhedstype
EntryTime = Tilmeldingstidspunkt
Error in result module X, method Y (Z) = Fejl i resultatmodul 'X', metode 'Y'\n\nZ
Etapp = Etape
Etapp X = Etape X
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 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
@ -429,8 +451,8 @@ Exempel = Eksempel
Export av resultat/sträcktider = Eksport af resultater / stræktider
Export language = Eksportsprog
Export split times = Eksporter mellemtider
Exportera / Säkerhetskopiera = Eksporter / Sikkerhedskopi
Exportera = Eksporter
Exportera / Säkerhetskopiera = Eksporter / Sikkerhedskopi
Exportera alla till HTML = Eksporter alle som HTML
Exportera alla till PDF = Eksporter alt som PDF
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 inte en MeOS-tävling = Filen (X) är ikke et MeOS-løb
Filen finns redan: X = Filen findes allerede: X
Filnamn (OCAD banfil) = Filnavn (OCAD banefil)
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) med klubbar = Filnavn (IOF-XML) med klubber
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
FinishTimeReverse = Omvendt måltid (sidste først)
First to finish = Først gennemført
Flera banor / stafett / patrull / banpool = Flere baner / Stafet / Patrulje / Frit banevalg
Flera banor = Flere baner
Flera banor / stafett / patrull / banpool = Flere baner / Stafet / Patrulje / Frit banevalg
Flera banor/stafett = Flere baner / Stafet
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 höger = Flyt til højre
Flytta ner = Flyt ned
@ -558,9 +581,9 @@ Från lag = Fra hold
Från laget = Fra holdet
Från löpardatabasen = Fra løberdatabase
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 (sidvis) = Fuldskærm (side for side)
Fullskärm = Fuldskærm
Funktion = Funktion
Funktioner = Funktioner
Funktioner i MeOS = Funktioner i MeOS
@ -569,14 +592,14 @@ Färg = Farve
Färre slingor = Færre sløjfer
Födelseår = Fødselsår
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 (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 ä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 överfördes ej = Følgende deltagere blev ikke overført
Fönster (rullande) = Vindue (rullende)
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 ä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
@ -659,8 +682,8 @@ Hoppar över stafettklass: X = Spring stafetklasse over: X
Huvudlista = Hovedliste
Hyravgift = Lejeafgift
Hyrbricka = Lejebrik
Hyrbricksrapport - %s = Lejebriksrapport - %s
Hyrbricksrapport = Lejebriksrapport
Hyrbricksrapport - %s = Lejebriksrapport - %s
Hyrd = Lejet
Hämta (efter)anmälningar från Eventor = Hent (efter)tilmeldinger 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 löpardatabasen = Henter løberdatabasen
Hämtar tävling = Henter løb
Händelser - tidslinje = Begivenheder - tidslinje
Händelser = Begivenheder
Händelser - tidslinje = Begivenheder - tidslinje
Håll ihop med = Hold kolonner samlet
Hög avgift = Forhøjet afgift
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
Identifierar X unika inledningar på banorna = Identificerer X unikke indledninger på banerne
Ignorera startstämpling = Ignorer startstempling
Ignorerade X duplikat = Ignorerede X duplikater
Image = Image
Importera = Importer
Importera IOF (xml) = Importer (IOF-XML)
Importera anmälda = Importer tilmeldte
@ -735,8 +760,8 @@ Individual results in a club = Individuelle resultater indenfor klub.
Individuell = Individuel
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, visst lopp (STOR) = Individuel resultatliste, bestemt løb (STOR)
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 tävling = Individuelt løb
Individuella deltagare = Individuelle deltagere
@ -749,12 +774,12 @@ Info = Information
Infoga version: X = Tilføj version: X
Informationsserver = Informationsserver
Inga = Ingen
Inga bommar registrerade =
Inga bommar registrerade = Ingen tidstab detekteret på strækkene
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 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 / okänd = Ingen / ukendt
Ingen bana = Ingen bane
Ingen deltagare matchar sökkriteriet = Ingen deltagere matcher søgekriteriet
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 nummerlapp = Intet brystnummer
Ingen parstart = Individuel start
Ingen reducerad avgift = Ikke reduceret afgift
Ingen rogaining = Intet pointløb
Ingen[competition] = Ingen [løb]
Inget filter = Intet filter
Inget nummer = Intet nummer
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 resultat från tidigare etapper = Inkluder resultater fra forudgående etapper
Inkludera sträcktider = Inkluder stræktider
Inkludera tempo = Inkluder tempo
Inkommande = Indkommende
Inläst bricka ställd i kö = Aflæst brik sat i kø
Inlästa brickor = Aflæste brikker
Inlästa stämplar = Indlæs stemplinger
Inmatning av mellantider = Indtastning af mellemtider
Inmatning online = Online indlæsning
Input Results - X = Input resultater - X
Input Results = Input resultater
Input Results - X = Input resultater - X
Inspekterar klasser = Undersøger klasser
Installera = Installer
Installerbara listor = Installerbare lister
@ -787,8 +818,8 @@ Inställningar startbevis = Instilliger for udskrift af startkvittering
Inställningar sträcktidsutskrift = Indstilling af stræktidsudskrifter
Interaktiv inläsning = Interaktiv indlæsning
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 (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
Invalid filter X = Ugyldigt filter 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: alla klasser lottade = Færdig. Alle klasser er lodtrukne.
Klart: inga klasser behövde lottas = Færdig: Ingen klasser behøvede lodtrækning
Klass = Klasse
Klass %d = Klasse %d
Klass / klasstyp = Klasse / Klassetype
Klass = Klasse
Klass X = Klasse X
Klass att slå ihop = Klasser der slås sammen
Klass saknad = Manglende klasse
@ -832,8 +863,8 @@ Klassen måste ha ett namn = Klassen skal have et navn
Klassen saknas = Klassen mangler
Klassen är full = Klassen er fuld
Klassens bana = Klassens bane
Klasser (IOF, xml) = Klasser (IOF-XML)
Klasser = Klasser
Klasser (IOF, xml) = Klasser (IOF-XML)
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
Klassinställningar = Klasseindstillinger
@ -849,16 +880,16 @@ Klubb = Klub
Klubb att ta bort = Klub der fjernes
Klubb: X = Klub: X
KlubbId = Klub Id
Klubbar (IOF, xml) = Klubber (IOF-XML)
Klubbar = Klubber
Klubbar (IOF, xml) = Klubber (IOF-XML)
Klubbar som inte svarat = Klubber som ikke har svaret
Klubbdatabasen = Klubdatabasen
Klubblös = Uden klub
Klubbresultat = Klubresultater
Klubbresultatlista - %s = Klubresultatliste - %s
Klubbresultatlista = Klubresultatliste
Klubbstartlista - %s = Klubstartliste - %s
Klubbresultatlista - %s = Klubresultatliste - %s
Klubbstartlista = Klubstartliste
Klubbstartlista - %s = Klubstartliste - %s
Klungstart = Gruppevis start
Knockout sammanställning = Knock-out opsummering
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 betalning = Kontant betaling
Konto = Konto
Kontroll %s = Post %s
Kontroll = Post
Kontroll %s = Post %s
Kontroll X = Post X
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
@ -914,10 +945,11 @@ Källkatalog = Mappe at hente fra
Kön = Køn
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
Lag = Hold
Lag %d = Hold %d
Lag + sträcka = Hold + tur
Lag = Hold
Lag och stafett = Hold og stafet
Lag utan nummerlapp: X = Hold uden brystnummer: X
Lag(flera) = Hold
Laget 'X' saknar klass = Der er ikke angivet klasse for holdet 'X'
Laget hittades inte = Holdet blev ikke fundet
@ -972,8 +1004,8 @@ Lopp %d = Løb %d
Lopp %s = Løb %s
Lopp X = Løb X
Lopp-id = Løbs ID
Lotta / starttider = Lodtrækning / starttider
Lotta = Træk lod
Lotta / starttider = Lodtrækning / starttider
Lotta flera klasser = Lodtrækning flere klasser
Lotta klassen = Lodtrækning, klasse
Lotta klassen X = Lodtrækning, klasse 'X'
@ -994,6 +1026,7 @@ Lyssna = Lyt
Lyssnar på X = Lytter på X
Lägg till = Tilføj
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 klasser = Tilføj klasser
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ägger till klubbar = Tilføjer klubber
Lägger till löpare = Tilføjer løbere
Längd (m) = Længde (m)
Längd = Længde
Längd (m) = Længde (m)
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ä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
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 gaffllingsvarianter att skapa = Maksimalt antal gafflinger der skal dannes
Max antal gemensamma kontroller = Maks. antal fælles poster
Max parallellt startande = Maks. antal samtidigt startende
Max. vakanser (per klass) = Maks. vakante (pr klasse)
@ -1111,6 +1145,7 @@ Multipel = Multiple
MySQL Server / IP-adress = MySQL Server / IP-addresse
Män = Mænd
Mål = Mål
Målenhet = Målenhed
Målfil = Destinationsfil
Målstämpling saknas = Manglende målstempling
Målstämpling tillåts inte (X) = Målstempling ikke tilladt (X)
@ -1141,6 +1176,8 @@ Normalavgift = Normal afgift
Not implemented = Ikke implementeret
Not yet implemented = Endnu ikke tilgægelig
Nr = Nummer
NumEntries = Antal tilmeldinger
NumStarts = Antal startende
Number of shortenings = Antal afkortninger af baner
Nummerlapp = Brystnummer
Nummerlapp, SI eller Namn = Brystnummer, SI-brik eller Navn
@ -1269,8 +1306,8 @@ Postkod = Postnummer
Poäng = Points
Poäng E[stageno] = Point E
Poäng in = Points i
Poängavdrag (per minut) = Pointfradrag (pr minut)
Poängavdrag = Pointfradrag
Poängavdrag (per minut) = Pointfradrag (pr minut)
Poängavdrag per påbörjad minut = Pointfradrag for hvert påbegyndt minut
Poänggräns = Pointgrænse
Poängjustering = Pointjustering
@ -1285,6 +1322,7 @@ Printing failed (X: Y) Z = Utskrivning fejlede (X: Y) Z
Prioritering = Prioritering
Prisutdelningslista = Prisuddelingsliste
Programinställningar = Programindstillinger
Programmera stationen utan AUTOSEND = Slå AUTO SEND fra i SPORTident enheden
Prolog + jaktstart = Prolog + jagtstart
Prologue + Pursuit = Prolog + Jagtstart
Publicera resultat = Offentliggør resultat
@ -1326,8 +1364,8 @@ Radera vakanser = Slet vakante
Radio = Radio
Radio tillåts inte (X) = Radioposter ikke tilladt (X)
Radiotider, kontroll = Radiotider, post
Ranking (IOF, xml, csv) = Rangliste (IOF, XML, CSV)
Ranking = Rangliste
Ranking (IOF, xml, csv) = Rangliste (IOF, XML, CSV)
Rapport = Rapport
Rapport inför = Rapport før
Rapporter = Rapporter
@ -1341,6 +1379,8 @@ Redigera listpost = Ret listepost
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'
Reducerad avg = Reduceret afgift
Reducerad avgift = Nedsat avgift
Reducerad avgift för = Nedsat afgift for
Reduktionsmetod = Reduktionsmetode
Referens = Reference
Region = Region
@ -1371,11 +1411,11 @@ ResultModuleNumber = Resultatmodul: Nummer
ResultModuleNumberTeam = Resultat Modul: Placering (for hold)
ResultModuleTime = Resultmodul: Tid
ResultModuleTimeTeam = Resultat Modul: Samlet tid (for hold)
Resultat = Resultater
Resultat && sträcktider = Resultater && stræktider
Resultat (STOR) = Resultater (STOR)
Resultat - %s = Resultater - %s
Resultat - X = Resultater - X
Resultat = Resultater
Resultat banvis per klass = Resultater banevis pr klasse
Resultat efter klass och bana - X = Resultat efter klasse og bane - 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 lopp X - Y = Resultater løb X - Y
Resultat online = Resultater online
Resultat per bana - X = Resultater pr bane - X
Resultat per bana = Resultater pr bane
Resultat per bana - X = Resultater pr bane - X
Resultat vid målstämpling = Resultater efter målstempling
Resultat, generell = Resultater, generelt
Resultat, individuell = Resultater, individuelle
@ -1396,9 +1436,8 @@ Resultatlista inställningar = Resultatliste indstillinger
Resultatlistor = Resultatlister
Resultatmodulen används i X = Resultatmodulet bruges i X
Resultatuträkning = Resultatberegning
Resultatutskrift / export = Udskriv resultater / eksporter
Resultatutskrift = Udskriv resultater
Rogaining = Pointløb
Resultatutskrift / export = Udskriv resultater / eksporter
Rogaining = Rogaining
Rogaining points before automatic reduction = Rogaining point før automatisk reduktion
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
RunnerAge = Løbers alder
RunnerBib = Løbers brystnummer
RunnerBirthDate = Fødselsdato
RunnerBirthYear = Løbers fødselsår
RunnerCard = Briknummer
RunnerCardVoltage = SIAC batterispænding
@ -1521,6 +1561,7 @@ SOFT-avgift = DO-F afgift
SOFT-lottning = Svensk lodtrækning
SRR Dongle = SRR Dongle
Saknad starttid = Manglende starttid
Saknat lag mellan X och Y = Mangler hold mellem X og Y
Samlade poäng = Samlet antal point
Samma = Samme
Samma bastävling = Samme basisløb
@ -1546,6 +1587,7 @@ Senast sedd: X vid Y = Sidst set: X ved Y
Server = Server
Server startad på X = Server startet på X
Server startad på port X = Server er startet på port X
Server version: X = Server version: X
Server: [X] Y = Server: [X] Y
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
@ -1553,10 +1595,11 @@ Several stages = Flere etaper
Short = Kort
Shortest time in class = Korteste tid i klassen
Show forking = Vis gaflinger
Sidbrytning mellan klasser / klubbar = Sideskift mellem klasser / klubber
Sidbrytning mellan klasser = Sideskift mellem klasser
Sidbrytning mellan klasser / klubbar = Sideskift mellem klasser / klubber
Sidor per skärm = Sider per skærm
Simulera inläsning av stämplar = Simuler aflæsning af stemplinger
Sist = Sidst
Sista betalningsdatum = Sidste betalingsdato
Sista ordinarie anmälningsdatum = Sidste ordinære tilmeldingsdato
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
Skapa = Opret
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, tom, tävling = Opret et nyt, tomt, løb
Skapa fakturor = Dan fakturaer
@ -1576,6 +1620,7 @@ Skapa tävlingen = Opret løb
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 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 tävling = Opretter nyt løb
Skapar saknad klass = Opretter manglende klasse
@ -1601,8 +1646,8 @@ Skriv ut rapporten = Udskriv rapporten
Skriv ut startbevis = Udskriv Startkvittering
Skriv ut startbevis för deltagaren = Udskriv startkvittering for løber
Skriv ut sträcktider = Udskriv stræktider
Skriv ut tabellen (X) = Udskriv tabellen (X)
Skriv ut tabellen = Udskriv tabellen
Skriv ut tabellen (X) = Udskriv tabellen (X)
Skriv över existerande bricknummer? = Overskriv eksisterende briknummer?
Skrivare = Printer
Skrivarinställningar = Printer indstilling
@ -1615,8 +1660,8 @@ Slutresultat = Endelige resultater
Sluttid = Sluttid
Slå ihop = Slå 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 (denna klass behålls) = Slå klasse X sammen: (behold denne klasse)
Slå ihop klasser = Slå klasser sammen
Slå ihop klubb = Slå klub sammen
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 inställningar = Gem indstillinger
Spara laguppställningar = Gem holdopstillinger
Spara oparad bricka = Gem uparret Si brik
Spara på disk = Gem på disk
Spara som = Gem som
Spara som PDF = Gem som PDF
@ -1651,6 +1697,7 @@ Spara som fil = Gem som fil
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 tid = Gem tid
Sparade automater = Gemte Autofunktioner (Tjenester)
Sparade listval = Gemte listevalg
Speaker = Speaker
Speakerstöd = Speaker funktion
@ -1659,17 +1706,17 @@ SportIdent = SPORTident
Språk = Sprog
Spänning = Spænding
Stad = By
Stafett = Stafet
Stafett (sammanställning) = Stafet (sammenfatning)
Stafett - sammanställning = Stafet - sammenfatning
Stafett - sträcka = Stafet - tur
Stafett - total = Stafet - total
Stafett = Stafet
Stafettklasser = Stafetklasser
Stafettresultat = Stafet Resultater
Stafettresultat, delsträckor = Stafetresultater, delstræk
Stafettresultat, lag = Stafetresulater, hold
Stafettresultat, sträcka (STOR) = Stafetresultater, tur (STOR)
Stafettresultat, sträcka = Stafetresultater, tur
Stafettresultat, sträcka (STOR) = Stafetresultater, tur (STOR)
Standard = Standard
Start = Start
Start nr = Start nr
@ -1689,17 +1736,18 @@ Startbevis = Startkvittering
Startbevis X = Startkvittering X
Startblock = Startblok
Startblock: %d = Startblok: %d
Startenhet = Start enhed
Startgrupp = Startgruppe
Startgrupp med id X tilldelad Y finns inte = Startgruppe med id X defineret for Y findes ikke
Startgrupper = Startgrupper
Startgrupperna X och Y överlappar = Startgrupperne X och Y overlapper hinanden
Startintervall (min) = Startinterval (min)
Startintervall = Startinterval
Startintervall (min) = Startinterval (min)
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 = Startliste - %s
Startlista - X = Startliste - X
Startlista = Startliste
Startlista ett visst lopp = Startliste for et specifikt løb
Startlista lopp X - Y = Startliste løb X - Y
Startlista, banvis = Startliste, banevis
@ -1712,8 +1760,8 @@ Startmetod = Startmetode
Startnamn = Startnavn
Startnummer = Startnummer
Startstämpling tillåts inte (X) = Startstempling ikke tilladt (X)
Starttid (HH:MM:SS) = Starttid (HH:MM:SS)
Starttid = Starttid
Starttid (HH:MM:SS) = Starttid (HH:MM:SS)
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 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 for each team member = Status for hvert holdmedlem
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 deltagarnas status = Status matcher ikke deltagerens status.
Stigning = Stigning
@ -1751,17 +1800,18 @@ Struken med återbetalning = Afbud med tilbagebetaling
Struken utan återbetalning = Afbud uden tilbagebetaling
Strukturerat exportformat = Struktureret eksportformat
Strukturerat webbdokument (html) = Struktureret webdokument (html)
Sträcka %d = Tur %d
Sträcka = Tur
Sträcka %d = Tur %d
Sträcka X = Tur X
Sträcka att lotta = Ture til lodtrækning
Sträckans banor = Strækkets baner
Sträcktider = Stræktider
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/WinSplits = Stræktider/WinSplits
Sträcktidsfil = Stræktidsfil
Sträcktidslista = Stræktidsliste
Sträcktidsutskrift = Udskriv stræktider
Sträcktidsutskrift[check] = Udskriv stræktider automatisk
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 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ök (X) = Søg (X)
Sök = Søg
Sök (X) = Søg (X)
Sök deltagare = Søg deltagere
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
@ -1808,8 +1858,8 @@ Sök symbol = Søg symbol
Söker efter SI-enheter = Søger efter SI-enheder
TCP: Port %d, Nolltid: %s = TCP: Port %d, Nultid: %s
TRASIG( = DEFEKT(
Ta bort / slå ihop = Fjern / slå sammen
Ta bort = Fjern
Ta bort / slå ihop = Fjern / slå sammen
Ta bort eventuella avanmälda deltagare = Fjern evt. afmeldte deltagere
Ta bort listposten = Fjern listeposten
Ta bort markerad = Fjern valgte
@ -1823,9 +1873,12 @@ Team = Hold
Team Rogaining = Hold pointløb
TeamBib = Holdets startnummer
TeamClub = Holdets klub
TeamCourseName = Banenavn for hold/tur
TeamCourseNumber = Banenummer for hold/tur
TeamFee = Holdafgift
TeamGlobal = Hold (klasser sammen)
TeamGrossTime = Holdets tid før korrektion
TeamLegName = Navn på tur
TeamLegTimeAfter = Holdets tid efter på tur
TeamLegTimeStatus = Holdets tid / status på tur
TeamName = Holdets navn
@ -1857,6 +1910,7 @@ Telefon = Telefon
Test = Test
Test Result Module = Test resultatmodul
Test av stämplingsinläsningar = Test af stemplingsindlæsninger
Testa = Test
Testa rösten = Afprøv stemme
Testa servern = Test serveren
Text = Tekst
@ -1894,6 +1948,7 @@ Till huvudsidan = Til hovedside
Till kontroll = Til post
Till sista = Til sidste
Till vilka klasser = Til hvilke klasser
Tillagda: X = Tilføjede: X
Tilldela = Tildel
Tilldela avgifter = Tildel afgifter
Tilldela endast avgift till deltagare utan avgift = Tildel kun afgift til deltagere uden afgift
@ -1931,14 +1986,19 @@ Time: X = Tid: X
Timekeeping = Tidtagning
TimingFrom = Navn på startpunkt
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
Total = Total
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
TotalCounter = Primær tæller
Totalresultat - X = Totalresultat - X
TotalRunLength = Samlet løbsdistance
TotalRunTime = Samlet løbstid
Totalresultat = Totalresultat
Totalresultat - X = Totalresultat - X
Totalt = Total
Totalt antal etapper = Totalt antal etapper
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: X = Løbets navn: X
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 (IOF, xml) = Løbsindstillinger (IOF, XML)
Tävlingsnamn = Løbsnavn
Tävlingsrapport = Løbsrapport
Tävlingsregler = Løbsreglement
@ -1985,15 +2045,17 @@ Undre gräns (år) = Nedre grænse (år)
Undre ålder = Laveste alder
Unexpected Fee = Uventet tilmeldingsgebyr
Unfair control legs = Uretfærdige stræk
Unga, till och med X år = Unge op til (og med) X år
Ungdom = Ungdom
Ungdomar och äldre kan få reducerad avgift = Unge og ældre kan få nedsat startafgift
Ungdomsavgift = Ungdomsafgift
Ungdomsklasser = Ungdomsklasser
Unknown symbol X = Ukendt symbol X
Unroll split times for loop courses = Udjævn splittider for loops
Uppdatera = Opdater
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 (X) = Opdater alle værdier i tabellen (X)
Uppdatera från Eventor = Opdater fra Eventor
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
@ -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 löpardatabasen = Opdater løberdatabasen
Uppdaterade: X = Oppdaterede: X
Urval %c%s = Udvælg %c%s
Urval = Sorter efter
Urval %c%s = Udvælg %c%s
Use initials in names = Brug initialer i navne
User input number = Bruger defineret input parameter
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
Utrymme: X = Plads: X
Utseende = Udseende
Utskrift / export = Udskrift / Eksport
Utskrift = Udskrift
Utskrift / export = Udskrift / Eksport
Utskriftsintervall (MM:SS) = Udskriftsinterval (MM:SS)
Utökat protokoll = Udvidet protokol
VALFRI( = VALGFRI(
Vacancies and entry cancellations = Vakante og sletning af tilmeldinger
Vak. ranking = Vak. rangliste
Vakanser = Vakante
Vakanser - X = Vakante - X
Vakanser / klassbyte = Vakante / skift klasse
Vakanser = Vakante
Vakanser och efteranmälda = Vakante og eftertilmeldte
Vakanser stöds ej i stafett = Vakante understøttes ikke i stafet
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: 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
Varningar i X = Advarsel i X
Varvningskontroll = Sløjfepost
Varvräkning = Tæl omgange
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 allt = Vælg alle
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 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
@ -2170,8 +2234,8 @@ Vänster = Venstre
Växel = Skifte
Växling = Veksling
Webb = Web
Webbdokument (html) = Webdokument (html)
Webbdokument = Webdokument
Webbdokument (html) = Webdokument (html)
Webben (html) = Webben (html)
Without courses = Uden baner
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 rader kunde inte raderas = X rækker kunne ikke slettes
X senaste = X seneste
X stämplingar = X stemplinger
X är inget giltigt index = X er ikke et gyldigt indeks
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:e = X'e
Year of birth = Førdselsår
Youth Cup X = Ungdoms Cup X
Zooma in (Ctrl + '+') = Zoom ind (Ctrl + '+')
Zooma ut (Ctrl + '-') = Zoom ud (Ctrl + '-')
[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: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'.
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: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?
@ -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.
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: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: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: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: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: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.
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
@ -2348,7 +2421,6 @@ klar = færdig
kontroll = post
kontroll X (Y) = post X (Y)
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; 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.
@ -2357,8 +2429,8 @@ localhost = localhost
lopp = løb
min/km = min/km
mål = mål
målet (X) = målet (X)
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.
nia = ni
nionde = niende
@ -2371,6 +2443,7 @@ prefsAddress = Forvalgt adresse
prefsAdvancedClassSettings = Vis avancerade klassindstillninger
prefsAutoSaveTimeOut = Interval for automatisk backup (ms)
prefsAutoTie = Knyt automatisk Si brik til løber
prefsAutoTieRent = Automatisk håndtering af lejebiler.
prefsCardFee = Forvalgt Si brik leje
prefsClient = Klientnavn i netværket
prefsCodePage = Tegnsæt for 8-bits text vid im- og export
@ -2390,6 +2463,9 @@ prefsEMail = Arrangør email
prefsEliteFee = Standard elite startgebyr
prefsEntryFee = Standard startgebyr
prefsEventorBase = URL til Eventor
prefsExpResFilename = Standard eksport filnavn
prefsExpTypeIOF = Standard eksport type
prefsExpWithRaceNo = Inkluder løbsnummer ved eksport
prefsExportCSVSplits = Inkluder mellemtider i csv export
prefsExportFormat = Foretrukket eksportformat
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å 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: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: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
@ -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?
xml-data = XML data
Äldre protokoll = Ældre protokol
Äldre, från och med X år = Ældre X år eller mere
Ändra = Skift
Ändra MeOS lokala systemegenskaper = Skift MeOS lokale systemegenskaber
Ändra X = Ændr X
@ -2532,18 +2610,19 @@ xml-data = XML data
Återgå = Gå tilbage
Återskapa = Gendan
Å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 <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 säkerhetskopia = Gendan fra sikkerhedskopi
Återställ tabeldesignen och visa allt = Gendan tabeldesign og vis alt
Åtgärd krävs = Handling påkrævet
ÅÅÅÅ-MM-DD = ÅÅÅÅ-MM-DD
Ökande = Stigende
Öppen = Åben
Öppen klass = Åben klasse
Öppna = Åbn
Öppna = Åbne
Öppna avläsningsfönster = Åbn aflæsningsvindue
Öppna fil = Åbn fil
Öppna från aktuell tävling = Åbn fra aktuelt løb
Öppna föregående = Åbn foregående

View File

@ -126,7 +126,7 @@ void Download::initInternet() {
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_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) {
hasAnyTimer = true;
DWORD zt=GetTickCount()-1000*zeroTime;
wstring text = getTimerText(zeroTime, format);
wstring text = getTimerText(zeroTime, format, true);
addStringUT(yp, xp, format, text, xlimit, cb, fontFace);
TextInfo &ti=TL.back();
@ -996,12 +996,14 @@ TextInfo& gdioutput::addStringUT(int yp, int xp, int format, const wstring& text
calcStringSize(TI, hDC);
if (xlimit == 0 || (format & (textRight | textCenter)) == 0) {
updatePos(TI.textRect.right + OffsetX, TI.yp, scaleLength(10),
TI.textRect.bottom - TI.textRect.top + scaleLength(2));
updatePosTight(TI.textRect.left, TI.yp,
TI.realWidth, TI.textRect.bottom - TI.textRect.top,
scaleLength(10), scaleLength(2));
}
else {
updatePos(TI.xp, TI.yp, TI.realWidth + scaleLength(10),
TI.textRect.bottom - TI.textRect.top + scaleLength(2));
updatePosTight(TI.xp, TI.yp,
TI.realWidth, TI.textRect.bottom - TI.textRect.top,
scaleLength(10), scaleLength(2));
}
ReleaseDC(hWndTarget, hDC);
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) {
/*WINDOWPLACEMENT wpl;
GetWindowPlacement(hWnd, &wpl);
wpl.
SetWindowPos*/
//SetWindowPos(hWnd, NULL, xp, yp, 0, 0,
xp = nxp;
yp = nyp;
int w, h;
@ -2140,7 +2136,7 @@ bool gdioutput::autoGrow(const char *id) {
ReleaseDC(hWndTarget, hDC);
size += scaleLength(20);
size += scaleLength(30);
if (size > it->width) {
it->width = size;
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);
size += scaleLength(20);
size += scaleLength(30);
if (size > it->width) {
it->width = size;
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);
}
bool gdioutput::updatePos(int x, int y, int width, int height) {
bool gdioutput::updatePosTight(int x, int y, int width, int height, int marginx, int marginy) {
int ox = MaxX;
int oy = MaxY;
@ -3646,14 +3641,19 @@ bool gdioutput::updatePos(int x, int y, int width, int height) {
}
if (flowDirection == FlowDirection::Down) {
CurrentY = max(y + height, CurrentY);
CurrentY = max(y + height + marginy, CurrentY);
}
else if (flowDirection == FlowDirection::Right) {
CurrentX = max(x + width, CurrentX);
CurrentX = max(x + width + marginx, CurrentX);
}
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)
{
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;
temp.zeroTime=0;
//memset(&temp, 0, sizeof(TextInfo));
temp.format=format;
return getTimerText(&temp, 1000*zeroTime);
if (timeInSeconds)
return getTimerText(&temp, 1000*zeroTime);
else
return getTimerText(&temp, (1000/timeUnitsPerSecond) * zeroTime);
}
wstring gdioutput::getTimerText(TextInfo *tit, DWORD T)

View File

@ -531,7 +531,7 @@ public:
void formatString(const TextInfo& ti, HDC hDC) const;
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 setWaitCursor(bool wait);
@ -629,6 +629,8 @@ public:
void popY() { CurrentY = SY; }
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);
/** Return a selected item*/

View File

@ -333,7 +333,7 @@ void IOF30Interface::classCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
xmlList xClsId;
xClsAssignment.getObjects("ClassId", xClsId);
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) {
gdi.addString("", 0, "Klass saknad").setColor(colorRed);
}
@ -1145,7 +1145,7 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
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) {
vector<int> key(it->second.size());
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,
map<int, vector<LegInfo> > &teamClassConfig) {
map<int, vector<LegInfo>> &teamClassConfig) {
if (!xclass)
return 0;
int classId = xclass.getObjectInt("Id");
int origId = classId;
if (classId > 0)
classId += classIdOffset;
wstring name, shortName, longName;
xclass.getObjectString("Name", name);
xclass.getObjectString("ShortName", shortName);
@ -2911,7 +2915,7 @@ pClass IOF30Interface::readClass(const xmlobject &xclass,
name = shortName;
}
pClass pc = 0;
pClass pc = nullptr;
if (classId) {
pc = oe.getClass(classId);
@ -2921,8 +2925,12 @@ pClass IOF30Interface::readClass(const xmlobject &xclass,
pc = oe.addClass(c);
}
}
else
else {
pc = oe.addClass(name);
}
if (origId > 0)
pc->setExtIdentifier(origId);
oDataInterface DI = pc->getDI();
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 {
int cardFee = r.getDCI().getInt("CardFee");
int cardFee = max(0, r.getDCI().getInt("CardFee"));
bool paidCard = r.getDCI().getInt("Paid") >= cardFee;
writeAssignedFee(xml, r, paidCard ? cardFee : 0);

View File

@ -74,6 +74,9 @@ class IOF30Interface {
// Include data on stage number
bool includeStageRaceInfo;
int classIdOffset = 0;
int courseIdOffset = 0;
const IOF30Interface &operator=(const IOF30Interface &) = delete;
set<wstring> matchedClasses;
@ -302,7 +305,14 @@ class IOF30Interface {
public:
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);

View File

@ -66,7 +66,7 @@ void ListEditor::setCurrentList(MetaList *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);
setCurrentList(new MetaList());
*currentList = mc;
@ -74,6 +74,14 @@ void ListEditor::load(const MetaListContainer &mlc, int index) {
if (mlc.isInternal(index)) {
currentIndex = -1;
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
currentIndex = index;
@ -81,6 +89,7 @@ void ListEditor::load(const MetaListContainer &mlc, int index) {
dirtyExt = true;
dirtyInt = false;
savedFileName.clear();
return currentIndex;
}
void ListEditor::show(TabBase *dst, gdioutput &gdi) {
@ -101,7 +110,7 @@ void ListEditor::show(gdioutput &gdi) {
int bx = gdi.getCX();
int by = gdi.getCY();
gdi.fillDown();
if (currentList)
gdi.addString("", boldLarge, makeDash(L"Listredigerare - X#") + currentList->getListName());
else
@ -655,6 +664,10 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
spInfo->withSpeed = gdi.isChecked("Speed");
spInfo->withResult = gdi.isChecked("Result");
spInfo->withAnalysis = gdi.isChecked("Analysis");
auto res = gdi.getSelectedItem("NumResult");
if (res.second)
spInfo->numClassResults = res.first;
list.setSplitPrintInfo(spInfo);
}
@ -781,7 +794,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
else if (bi.id == "DoOpen" || bi.id == "DoOpenCopy" ) {
ListBoxInfo lbi;
if (gdi.getSelectedItem("OpenList", lbi)) {
load(oe->getListContainer(), lbi.data);
load(oe->getListContainer(), lbi.data, false);
}
if (bi.id == "DoOpenCopy") {
@ -1405,7 +1418,7 @@ void ListEditor::editImage(gdioutput& gdi, const MetaListPost& mlp, int id) {
gdi.addString("", 0, "Förskjutning:");
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.popX();
@ -1842,7 +1855,7 @@ void ListEditor::editListProp(gdioutput &gdi, bool newList) {
gdi.setCX(gdi.getCX()+20);
int f = list.getFontFaceFactor(k);
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);
gdi.addInput("ExtraSpace" + itos(k), itow(f), 4, 0, L"Avstånd", L"Extra avstånd ovanför textblock");
if (k == 1) {
@ -1892,6 +1905,7 @@ void ListEditor::statusSplitPrint(gdioutput& gdi, bool status) {
gdi.setInputStatus("Speed", status);
gdi.setInputStatus("Result", status);
gdi.setInputStatus("Analysis", status);
gdi.setInputStatus("NumResult", status);
}
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("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);
gdi.dropLine(0.8);
gdi.setCX(gdi.getCX() + 20);
gdi.setCX(gdi.getCX() + gdi.scaleLength(40));
gdi.addButton("ApplySplitList", "OK", editListCB);
gdi.addButton("Cancel", "Avbryt", editListCB);
gdi.dropLine(3);
int maxY = gdi.getCY();
int maxX = gdi.getCX();
maxX = max(maxX, gdi.getCX());
gdi.fillDown();
gdi.popX();

View File

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

View File

@ -1,6 +1,6 @@
/************************************************************************
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
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";
for (size_t k=0;k<raw.size();k++) {
const string &s = raw[order[k]];
int pos = s.find_first_of('=');
size_t pos = s.find_first_of('=');
if (pos==string::npos)
throw std::exception("Bad file format.");
int spos = pos;
int epos = pos+1;
while (spos>0 && s[spos-1]==' ')
spos--;
size_t spos = pos;
size_t epos = pos+1;
const unsigned char *udata = (const unsigned char*)s.data();
while (unsigned(epos)<s.size() && s[epos]==' ')
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++;
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 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");
while (nl!=string::npos) {
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"Español", L"111");
lang.get().addLangResource(L"Russian", L"107");
lang.get().addLangResource(L"Ukrainian", L"112");
if (fileExists(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;
u.HighPart = ft.dwHighDateTime;
u.LowPart = ft.dwLowDateTime;
__int64 qp = u.QuadPart;
qp /= __int64(1000 * 1000 * timeUnitsPerSecond);
__int64 qp = u.QuadPart; // Time resolution 100 ns
qp /= __int64(1000 * 1000 * 10 / timeUnitsPerSecond);
return qp;
}
@ -168,8 +168,8 @@ SYSTEMTIME Int64TenthSecondToSystemTime(__int64 time) {
SYSTEMTIME st;
FILETIME ft;
ULARGE_INTEGER u;
u.QuadPart = time * __int64(1000 * 1000 * timeUnitsPerSecond);
ULARGE_INTEGER u; // Time resolution 100 ns
u.QuadPart = time * __int64(1000 * 1000 * 10 / timeUnitsPerSecond);
ft.dwHighDateTime = u.HighPart;
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);
else
swprintf_s(bf, L"%d:%02d.%d", (rt / timeConstMinute), (rt / timeConstSecond) % 60, rt%timeConstSecond);
}
res = bf;
return res;

View File

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

View File

@ -25,17 +25,17 @@
//ABCDEFGHIJKLMNOP
int getMeosBuild() {
string revision("$Rev: 1225 $");
string revision("$Rev: 1263 $");
return 174 + atoi(revision.substr(5, string::npos).c_str());
}
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);
}
wstring getBuildType() {
return L"Beta 1"; // No parantheses (...)
return L"U1"; // No parantheses (...)
}
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"OK Orinto");
supp.emplace_back(L"Trosabygdens OK");
supp.emplace_back(L"Järla Orientering");
supp.emplace_back(L"Hans Wilhelmsson, Säffle OK");
supp.emplace_back(L"Cent Vallées Orientation 12 (C.V.O. 12)");
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"Lerums SOK");
supp.emplace_back(L"OSC Hamburg");
supp.emplace_back(L"HEYRIES, ACA Aix en Provence");
developSupp.emplace_back(L"IFK Mora OK");
supp.emplace_back(L"OK Rodhen");
supp.emplace_back(L"Big Foot Orienteers");
developSupp.emplace_back(L"OK Måsen");
supp.emplace_back(L"Ligue PACA");
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());
}

View File

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

View File

@ -500,6 +500,7 @@ public:
void saveList(int index, const MetaList &ml);
bool isInternal(int index) const {return data[index].first == InternalList;}
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 getGeneralResults(vector<DynamicResultRef> &resMod);

View File

@ -74,7 +74,7 @@ int TabCompetition::newGuideCB(gdioutput &gdi, int type, void *data)
try {
gdi.autoRefresh(true);
FlowOperation res = saveEntries(gdi, false, true);
FlowOperation res = saveEntries(gdi, false, 0, true);
if (res != FlowContinue) {
if (res == FlowCancel)
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 {
group.clear();
// Assume hasUnorderedLegs
@ -4260,14 +4278,48 @@ pair<int, int> oClass::autoForking(const vector<vector<int>> &inputCourses, int
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;
int lastSet = -1;
for (int j = 0; j < legs; j++) {
if (nf[j] > 0) {
lastSet = j;
for (size_t k = 0; k < fperm.size(); k++) {
coursesUsed.insert(courseMatrix[j][fperm[k]]->getId());
addStageCourse(j, courseMatrix[j][fperm[k]], -1);
int kk = unsigned(k + off) % fperm.size();
coursesUsed.insert(courseMatrix[j][fperm[kk]]->getId());
addStageCourse(j, courseMatrix[j][fperm[kk]], -1);
}
}
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);
}
int candidate = -1;
for (set<int>::iterator it = bibs.begin(); it != bibs.end(); ++it) {
if (candidate > 0 && *it != candidate) {
@ -4702,11 +4760,14 @@ set<oClass::DrawSpecified> oClass::getDrawSpecification() const {
return res;
}
void oClass::initClassId(oEvent &oe) {
void oClass::initClassId(oEvent &oe, const set<int>& classes) {
vector<pClass> cls;
oe.getClasses(cls, true);
map<long long, wstring> id2Cls;
for (size_t k = 0; k < cls.size(); k++) {
if (!classes.empty() && !classes.count(cls[k]->getId()))
continue;
long long extId = cls[k]->getExtIdentifier();
if (extId > 0) {
if (id2Cls.count(extId)) {
@ -4718,8 +4779,11 @@ void oClass::initClassId(oEvent &oe) {
}
// Generate external identifiers when not set
for (size_t k = 0; k < cls.size(); k++) {
if (!classes.empty() && !classes.count(cls[k]->getId()))
continue;
long long extId = cls[k]->getExtIdentifier();
if (extId <= 0) {
if (extId == 0) {
long long id = cls[k]->getId();
while (id2Cls.count(id)) {
id += 100000;

View File

@ -408,7 +408,7 @@ public:
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
bool lockedForking() const;
@ -730,6 +730,8 @@ public:
// Returns 0 for no parallel selection (= normal mode)
pCourse selectParallelCourse(const oRunner &r, const SICard &sic);
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;
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) {
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);
yp+=lh*2;
yp+=int(lh*2.5);
gdi.addStringUT(yp, xs, normalText, lang.tl(L"Vänligen betala senast ")
+ 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()) {
wstring name;
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)
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)
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);
}
else {

View File

@ -399,10 +399,8 @@ bool oDataContainer::setDate(void *data, const char *Name, const wstring &V)
else return false;//Not modified
}
const wstring& oDataContainer::getDate(const void* data,
const char* Name) const
{
const oDataInfo* odi = findVariable(Name);
const wstring& oDataContainer::getDate(const void* data, const char* name) const {
const oDataInfo* odi = findVariable(name);
if (!odi)
throw std::exception("oDataContainer: Variable not found.");
@ -435,6 +433,31 @@ const wstring& oDataContainer::getDate(const void* data,
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 {
void *data, *oldData;
vector< vector<wstring> > *strptr;

View File

@ -180,7 +180,8 @@ public:
const wstring &formatString(const oBase *ob, const char *name) const;
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;
void set(oBase *ob, const xmlobject &xo);
@ -298,8 +299,12 @@ public:
else return false;
}
inline const wstring &getDate(const char *Name) const
{return oDC->getDate(Data, Name);}
inline const wstring &getDate(const char *name) const
{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
{return oDC->buildDataFields(gdi, maxFieldSize);}
@ -398,9 +403,12 @@ public:
return oDC->formatString(oB, name);
}
inline const wstring &getDate(const char *Name) const
{return oDC->getDate(Data, Name);}
inline const wstring &getDate(const char *name) const
{return oDC->getDate(Data, name);}
inline int getYear(const char* name) const {
return oDC->getYear(Data, name);
}
inline __int64 getInt64(const string &name) const
{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 generateList(gdioutput &gdi, bool reEvaluate, const oListInfo &li, bool updateScrollBars);
void generateListInfo(oListParam &par, oListInfo &li);
void generateListInfo(vector<oListParam> &par, oListInfo &li);
void generateListInfo(EStdListType lt, const gdioutput &gdi, int classId, oListInfo &li);
void generateListInfoAux(oListParam &par, oListInfo &li, const wstring &name);
void generateListInfo(const gdioutput& target, oListParam &par, oListInfo &li);
void generateListInfo(const gdioutput& target, vector<oListParam> &par, oListInfo &li);
void generateListInfo(const gdioutput& target, EStdListType lt, int classId, oListInfo &li);
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*/
const wstring &formatListString(const oPrintPost &pp, const oListParam &par,
@ -826,7 +826,7 @@ public:
//Speaker functions.
void speakerList(gdioutput &gdi, int classId, int leg, int controlId,
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;}
void updateComputerTime();
@ -1023,7 +1023,7 @@ public:
bool forceSplitFee,
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();
void duplicate(const wstring &annotation, bool keepTags = false);
@ -1340,7 +1340,8 @@ public:
/** Import entry data */
void importXML_EntryData(gdioutput &gdi, const wstring &file,
bool updateClass, bool removeNonexisting,
const set<int> &filter, const string &preferredIdType);
const set<int> &filter, int classIdOffset,
int courseIdOffset, const string &preferredIdType);
protected:
pClass getXMLClass(const xmlobject &xentry);
@ -1376,6 +1377,21 @@ protected:
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*/
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"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"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"");
//Find last starter
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);
}
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.#" +
oe->getAbsTime(laststart*di.baseInterval+di.firstStart));
@ -1553,7 +1553,7 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
int leg = spec[0].leg;
VacantPosition vp = VacantPosition::Mixed;
DrawInfo di;
di.baseInterval = 60;
di.baseInterval = timeConstMinute;
di.allowNeighbourSameCourse = true;
di.extraFactor = 0;
@ -1826,7 +1826,7 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
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.
spec[k].firstStart = timeConstHour;
spec[k].interval = 2*timeConstMinute;
@ -1949,9 +1949,9 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
Vacances--;
}
for (it=Runners.begin(); it != Runners.end(); ++it)
if (it->Class && it->Class->Id==ClassID) nRunners++;
for (it = Runners.begin(); it != Runners.end(); ++it) {
if (it->Class && it->Class->Id == ClassID && !it->isRemoved()) nRunners++;
}
if (nRunners==0) return;
int *stimes=new int[nRunners];
@ -1962,28 +1962,29 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
int ginterval;
if (nRunners>=Interval)
ginterval=10;
else if (Interval/nRunners>60){
ginterval=40;
ginterval=10 * timeConstSecond;
else if (Interval/nRunners>60*timeConstSecond){
ginterval=40 * timeConstSecond;
}
else if (Interval/nRunners>30){
ginterval=20;
else if (Interval/nRunners>30 * timeConstSecond){
ginterval=20 * timeConstSecond;
}
else if (Interval/nRunners>20){
ginterval=15;
else if (Interval/nRunners>20 * timeConstSecond){
ginterval=15 * timeConstSecond;
}
else if (Interval/nRunners>10){
ginterval=1;
else if (Interval/nRunners>10 * timeConstSecond){
ginterval=12 * timeConstSecond;
}
else ginterval=10;
else ginterval=10 * timeConstSecond;
int nGroups=Interval/ginterval+1; //15 s. per interval.
nGroups = min(nGroups, 2*nRunners+1);
int k;
if (nGroups>0){
int MaxRunnersGroup=max((2*nRunners)/nGroups, 4)+GetRandomNumber(2);
int *sgroups=new int[nGroups];
vector<int> sgroups(nGroups);
for(k=0;k<nGroups; k++)
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){
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++){
if ((nRunners/nGroups)<MaxRunnersGroup && nGroups>5){
sgroups[k]=sgroups[nGroups-1];
@ -2029,10 +2030,9 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
}
//Premute all groups;
permute(sgroups, nGroups);
permute(sgroups.data(), nGroups);
int *counters=new int[nGroups];
memset(counters, 0, sizeof(int)*nGroups);
vector<int> counters(nGroups);
stimes[0]=FirstStart;
stimes[1]=FirstStart+Interval;
@ -2066,10 +2066,6 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
stimes[k]=sgroups[g];
counters[g]++;
}
delete[] sgroups;
delete[] counters;
}
else{
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;
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->StartNo = k;
it->synchronize();
@ -2130,7 +2126,7 @@ void oEvent::automaticDrawAll(gdioutput &gdi,
return;
}
if (baseInterval<1 || baseInterval>60*60)
if (baseInterval<timeConstSecond || baseInterval>timeConstHour)
throw std::exception("Felaktigt tidsformat för intervall");
int iFirstStart = getRelativeTime(firstStart);

View File

@ -42,6 +42,8 @@
//////////////////////////////////////////////////////////////////////
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) :
time(time_), type(type_), priority(priority_), classId(classId_), ID(ID_)
@ -274,8 +276,9 @@ int MovePriorityCB(gdioutput *gdi, int type, void *data) {
return true;
}
void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
int leaderTime, int type, vector<SpeakerString> &row, bool shortName) {
void renderRowSpeakerList(const oSpeakerObject& r, const oSpeakerObject* next_r,
int leaderTime, int type, vector<SpeakerString>& row,
bool shortName, bool useSubSecond) {
if (r.place > 0)
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);
for (size_t j = 0; j < splt.size(); j++) {
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".";
else
names += splt[j];
@ -327,10 +330,10 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
}
else {
vector<wstring> splt;
split( r.outgoingnames[k], L" ", splt);
split(r.outgoingnames[k], L" ", splt);
for (size_t j = 0; j < splt.size(); j++) {
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".";
else
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));
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));
auto ssMode = useSubSecond ? SubSecond::On : SubSecond::Auto;
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)
row.push_back(SpeakerString(textRight, formatTime(r.runningTimeLeg.time)));
row.push_back(SpeakerString(textRight, formatTime(r.runningTimeLeg.time, ssMode)));
else
row.push_back(SpeakerString());
if (leaderTime!=100000 && leaderTime>0){
row.push_back(SpeakerString(textRight, gdioutput::getTimerText(r.runningTime.time-leaderTime,
timerCanBeNegative)));
if (leaderTime != constNoLeaderTime && leaderTime > 0) {
int flag = timerCanBeNegative;
if (useSubSecond)
flag |= timeWithTenth;
row.push_back(SpeakerString(textRight, gdioutput::getTimerText(r.runningTime.time - leaderTime,
flag, false)));
}
else
row.push_back(SpeakerString());
@ -373,55 +381,52 @@ void renderRowSpeakerList(const oSpeakerObject &r, const oSpeakerObject *next_r,
}*/
}
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)
TimeOut = next_r->runningTime.preliminary;
if (next_r && next_r->status == StatusOK && next_r->runningTime.preliminary > 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)
row.push_back(SpeakerString(textRight, r.runningTimeLeg.preliminary));
else
row.push_back(SpeakerString());
if (leaderTime != 100000)
row.push_back(SpeakerString(timerCanBeNegative|textRight, r.runningTime.preliminary - leaderTime));
if (leaderTime != constNoLeaderTime)
row.push_back(SpeakerString(timerCanBeNegative | textRight, r.runningTime.preliminary - leaderTime));
else
row.push_back(SpeakerString());
//gdi.addTimer(y, x+dx[5], timerCanBeNegative|textRight, r.runningTime.preliminary - leaderTime);
}
else{
//gdi.addStringUT(y, x+dx[4], textRight, "["+r.startTimeS+"]");
row.push_back(SpeakerString(textRight, L"["+r.startTimeS+L"]"));
else {
row.push_back(SpeakerString(textRight, L"[" + r.startTimeS + L"]"));
if (!r.missingStartTime)
row.push_back(SpeakerString(timerCanBeNegative|textRight, r.runningTimeLeg.preliminary));
//gdi.addTimer(y, x+dx[5], timerCanBeNegative|textRight, r.runningTimeLeg.preliminary, 0, SpeakerCB, NOTIMEOUT);
if (!r.missingStartTime) {
row.push_back(SpeakerString(timerCanBeNegative | textRight,
r.runningTimeLeg.preliminary, 0)); // Timeout on start
}
else
row.push_back(SpeakerString());
row.push_back(SpeakerString());
}
}
else{
//gdi.addStringUT(y, x+dx[4], textRight, oEvent::formatStatus(r.status)).setColor(colorDarkRed);
else {
row.push_back(SpeakerString());
row.push_back(SpeakerString(textRight, oEvent::formatStatus(r.status, true)));
row.back().color = colorDarkRed;
row.push_back(SpeakerString());
}
int ownerId = r.owner ? r.owner->getId(): 0;
if (type==1) {
int ownerId = r.owner ? r.owner->getId() : 0;
if (type == 1) {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bort]")));
row.back().color = colorRed;
row.back().moveKey = "D" + itos(ownerId);
}
else if (type==2) {
else if (type == 2) {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]")));
row.back().color = colorGreen;
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.back().moveKey = "M" + itos(ownerId);
}
else{
else {
row.push_back(SpeakerString(normalText, lang.tl(L"[Bevaka]")));
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) {
int lh=gdi.getLineHeight();
bool highlight = false;
if (r.timeSinceChange < 20 && r.timeSinceChange>=0) {
if (r.timeSinceChange < highlightNewResultTime * timeConstSecond && r.timeSinceChange>=0) {
RECT rc;
rc.left = x+pos[1] - 4;
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;
gdi.addRectangle(rc, colorLightGreen, false);
highlight = true;
gdi.addTimeout(highlightNewResultTime + 5, SpeakerCB);
}
for (size_t k = 0; k < row.size(); k++) {
@ -480,8 +486,8 @@ void renderRowSpeakerList(gdioutput &gdi, int type, const oSpeakerObject &r, int
}
}
else {
gdi.addTimer(y, x + pos[k], row[k].format, row[k].timer, limit,
row[k].timeout != NOTIMEOUT ? SpeakerCB : 0, row[k].timeout);
gdi.addTimer(y, x + pos[k], row[k].format, row[k].timer / timeConstSecond, limit,
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]="";
wstring legName, cname = pCls->getName();
size_t istage = -1;
bool useSS = useSubSecond(); // Only for finish time??
for (size_t k = 0; k < stages.size(); k++) {
if (stages[k].first >= leg) {
istage = k;
@ -648,20 +655,17 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
int lh=gdi.getLineHeight();
y+=lh*2;
int LeaderTime=100000;
int leaderTime = constNoLeaderTime;
//Calculate leader-time
for(sit=speakerList.begin(); sit != speakerList.end(); ++sit) {
for (sit = speakerList.begin(); sit != speakerList.end(); ++sit) {
int rt = sit->runningTime.time;
if ((sit->status==StatusOK || sit->status == StatusUnknown) && rt>0)
LeaderTime=min(LeaderTime, rt);
if ((sit->status == StatusOK || sit->status == StatusUnknown) && rt > 0)
leaderTime = min(leaderTime, rt);
}
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;
sit = speakerList.begin();
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)
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());
ix++;
}

View File

@ -61,15 +61,11 @@ FlowOperation importFilterGUI(oEvent *oe,
set<int> & filter,
string &preferredIdProvider);
string conv_is(int i)
{
string conv_is(int i) {
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 "";
return "";
}
int ConvertStatusToOE(int i)
@ -108,7 +104,7 @@ wstring &getFirst(wstring &inout, int maxNames) {
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 {
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;
oClass::initClassId(*this);
oClass::initClassId(*this, classes);
if (!csv.openOutput(file))
return false;
calculateResults({}, ResultType::ClassResult);
calculateResults(classes, ResultType::ClassResult);
sortRunners(SortOrder::ClassResult);
oRunnerList::iterator it;
string maleString;
@ -171,6 +167,11 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
char bf[256];
for (it = Runners.begin(); it != Runners.end(); ++it) {
if (it->isRemoved())
continue;
if (!classes.empty() && !classes.count(it->getClassId(true)))
continue;
vector<string> row;
row.resize(46);
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[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[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,
bool updateClass, bool removeNonexisting,
const set<int> &filter,
int classIdOffset,
int courseIdOffset,
const string &preferredIdType) {
vector< pair<int, int> > runnersInTeam;
vector<pair<int, int>> runnersInTeam;
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
if (!it->isRemoved() && it->tInTeam) {
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")) {
IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.setPreferredIdType(preferredIdType);
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")) {
IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readStartList(gdi, xo, ent, fail);
}
else {
@ -441,6 +449,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
gdi.addString("", 0, "Importerar resultat (IOF, xml)");
gdi.refreshFast();
IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readResultList(gdi, xo, ent, fail);
}
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")) {
IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readClassList(gdi, xo, imp, fail);
}
else {
@ -569,6 +579,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
if (xo && xo.getAttrib("iofVersion")) {
IOF30Interface reader(this, false, false);
reader.setIdOffset(classIdOffset, courseIdOffset);
reader.readCourseData(gdi, xo, updateClass, imp, fail);
}
else {
@ -2678,7 +2689,7 @@ void oEvent::exportIOFSplits(IOFVersion version, const wchar_t *file,
xmlparser xml;
xml.openOutput(file, false);
oClass::initClassId(*this);
oClass::initClassId(*this, classes);
reEvaluateAll(classes, true);
if (version != IOF20)
calculateResults(classes, ResultType::ClassCourseResult);
@ -2708,7 +2719,7 @@ void oEvent::exportIOFStartlist(IOFVersion version, const wchar_t *file, bool us
bool useEventorQuirks) {
xmlparser xml;
oClass::initClassId(*this);
oClass::initClassId(*this, classes);
xml.openOutput(file, false);
if (version == IOF20)

View File

@ -429,7 +429,8 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|| type == lTeamRunner || type == lTeamClub)
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");
if (type == lRunnerCompleteName || type == lPatrolNameNames || type == lPatrolClubNameNames)
@ -1254,6 +1255,17 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
case lRunnerCompleteName:
if (r) wcscpy_s(wbf, r->getCompleteIdentification().c_str());
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:
if (t) {
pRunner r1 = t->getRunner(0);
@ -1459,7 +1471,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
int len = pc->getLength();
if (len > 0 && t > 0) {
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;
if (!text.empty()) {
int tightBBFlag = ppi.par.tightBoundingBox ? 0 : skipBoundingBox;
pdy = ppi.gdi.scaleLength(pp.dy);
pdx = ppi.gdi.scaleLength(pp.dx);
if ((pp.type == lRunnerName || pp.type == lRunnerCompleteName ||
pp.type == lRunnerFamilyName || pp.type == lRunnerGivenName ||
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());
ti->setExtra(rr->getId());
ti->id = "R";
}
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());
ti->setExtra(t->getId());
ti->id = "T";
}
else {
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)
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;
if (classId!=0)
par.selection.insert(classId);
par.listCode=lt;
generateListInfo(par, li);
generateListInfo(target, par, li);
}
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);
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
loadGeneralResults(false, false);
for (size_t k = 0; k < par.size(); k++) {
@ -4103,7 +4113,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
getListTypes(listMap, false);
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;
// Add linked lists
oListParam *cPar = &par[0];
@ -4115,7 +4125,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
oListParam &nextPar = oe->getListContainer().getParam(cPar->nextList-1);
li.next.push_back(oListInfo());
nextPar.cb = 0;
generateListInfoAux(nextPar, li.next.back(), L"");
generateListInfoAux(target, nextPar, li.next.back(), L"");
cPar = &nextPar;
}
}
@ -4124,7 +4134,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
if (k > 0) {
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);
}
}
@ -4132,7 +4142,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
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 vspace=lh/2;
int bib;
@ -4600,7 +4610,7 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
mList.addToSubList(lRunnerName);
mList.addToSubList(lRunnerCard).align(lClassStartName);
mList.interpret(this, gdibase, par, li);
mList.interpret(this, target, par, li);
}
li.listType=li.EBaseTypeTeam;
li.listSubType=li.EBaseTypeRunner;
@ -4849,7 +4859,7 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
mList.setListType(li.EBaseTypeTeam);
mList.setSortOrder(ClassStartTime);
mList.addFilter(EFilterExcludeDNS);
mList.interpret(this, gdibase, par, li);
mList.interpret(this, target, par, li);
break;
}
case EStdPatrolResultList:
@ -5059,10 +5069,10 @@ void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &
continue;
par.setLegNumberCoded(out[k].second);
if (k == 0)
generateListInfo(par, li);
generateListInfo(target, par, li);
else {
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;
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));
}
}

View File

@ -65,6 +65,7 @@ enum EPostType {
lRunnerGivenName,
lRunnerFamilyName,
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
lPatrolClubNameNames, // Single runner's club or combination of patrol clubs
lRunnerFinish,
@ -484,6 +485,8 @@ struct oListParam {
int sourceParam = -1;
bool tightBoundingBox = false;
private:
int legNumber;
};
@ -507,6 +510,14 @@ public:
bool isTeamList() const {return listType == EBaseTypeTeam;}
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 {
Global,
Classwise,
@ -551,9 +562,10 @@ protected:
list<oPrintPost> head;
list<oPrintPost> subHead;
list<oPrintPost> listPost;
list<oPrintPost> subListPost;
vector<char> listPostFilter;
vector<char> listPostSubFilter;
list<oPrintPost> subListPost;
bool fixedType;
PunchMode needPunches;

View File

@ -2838,17 +2838,21 @@ const wstring &oRunner::getName() const {
return tRealName;
}
const wstring &oRunner::getNameLastFirst() const {
const wstring& getNameLastFirst(const wstring &sName) {
if (sName.find_first_of(',') != sName.npos)
return sName; // Already "Fiske, Eric"
if (sName.find_first_of(' ') == sName.npos)
return sName; // No space "Vacant", "Eric"
wstring &res = StringCache::getInstance().wget();
res = getFamilyName() + L", " + getGivenName();
wstring& res = StringCache::getInstance().wget();
res = getFamilyName(sName) + L", " + getGivenName(sName);
return res;
}
const wstring &oRunner::getNameLastFirst() const {
return ::getNameLastFirst(sName);
}
void oRunner::getRealName(const wstring &input, wstring &output) const {
bool wasSpace = false;
wstring n = input;
@ -2883,7 +2887,7 @@ void oRunner::getRealName(const wstring &input, wstring &output) const {
if (comma != string::npos)
output = n;
else
output = getNameLastFirst();
output = ::getNameLastFirst(n);
}
}
@ -4353,11 +4357,18 @@ void oRunner::fillSpeakerObject(int leg, int courseControlId, int previousContro
spk.status = getStatus();
}
if (courseControlId == oPunch::PunchFinish)
spk.timeSinceChange = oe->getComputerTime() - FinishTime;
else
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTime.time + tStartTime);
if (courseControlId == oPunch::PunchFinish) {
if (FinishTime > 0)
spk.timeSinceChange = oe->getComputerTime() - FinishTime;
else
spk.timeSinceChange = -1;
}
else {
if (spk.runningTime.time > timeConstSecond * 10)
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTime.time + tStartTime);
else
spk.timeSinceChange = -1;
}
spk.bib = getBib();
spk.names.push_back(getName());
@ -4770,10 +4781,22 @@ void oRunner::printSplits(gdioutput& gdi) const {
string listId;
if (wListId.empty()) {
if (cls1) {
if (cls1->getClassType() == ClassType::oClassIndividual)
listId = "split_indivudual";
if (cls1->getClassType() == ClassType::oClassIndividual) {
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 {
listId = gdioutput::narrow(wListId);
}
@ -4791,15 +4814,18 @@ void oRunner::printSplits(gdioutput& gdi) const {
oListInfo currentList;
par.listCode = oe->getListContainer().getCodeFromUnqiueId(listId);
//auto &metaList = oe->getListContainer().getList(par.listCode);
par.showInterTimes = false;
par.setLegNumberCoded(getLegNumber());
int legNo = getLegNumber(), legOrd;
if (Class)
Class->splitLegNumberParallel(getLegNumber(), legNo, legOrd);
par.setLegNumberCoded(legNo);
par.filterMaxPer = 3;
par.alwaysInclude = this;
par.showHeader = false;
par.tightBoundingBox = true;
try {
oe->generateListInfo(par, currentList);
oe->generateListInfo(gdi, par, currentList);
}
catch (const meosException&) {
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 withSpeed = (oe->getDI().getInt("Analysis") & 2) == 0;
bool withResult = (oe->getDI().getInt("Analysis") & 4) == 0;
bool includeStandardHeading = true;
bool includeDefaultTitle = true;
bool includeSplitTimes = true;
@ -4834,6 +4861,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
withSpeed = sp.withSpeed;
withResult = sp.withResult;
withAnalysis = sp.withAnalysis;
includeSplitTimes = sp.includeSplitTimes;
}
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) {
headerPos.insert(cx);
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)
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);
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;
sprintf_s(bf, "%d", it->type);
@ -5158,7 +5186,7 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
if (headerPos.count(cx) == 0) {
headerPos.insert(cx);
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;
@ -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);
if (hasInputData())
oe->calculateResults({ getClassId(true) }, oEvent::ResultType::TotalResult);
@ -5243,33 +5275,34 @@ void oRunner::printSplits(gdioutput& gdi, const oListInfo* li) const {
gdi.addString("", normal, place + timestatus + after);
gdi.popX();
}
if (Card->miliVolt > 0) {
gdi.dropLine(0.7);
auto stat = Card->isCriticalCardVoltage();
wstring warning;
if (stat == oCard::BatteryStatus::Bad)
warning = lang.tl("Replace[battery]");
else if (stat == oCard::BatteryStatus::Warning)
warning = lang.tl("Low");
else
warning = lang.tl("OK");
gdi.fillRight();
gdi.pushX();
gdi.addString("", fontSmall, L"Batteristatus:");
gdi.addStringUT(boldSmall, getCard()->getCardVoltage());
gdi.fillDown();
gdi.addStringUT(fontSmall, L"(" + warning + L")");
gdi.popX();
}
}
gdi.dropLine(0.7);
if (Card && Card->miliVolt > 0) {
gdi.dropLine(0.7);
auto stat = Card->isCriticalCardVoltage();
wstring warning;
if (stat == oCard::BatteryStatus::Bad)
warning = lang.tl("Replace[battery]");
else if (stat == oCard::BatteryStatus::Warning)
warning = lang.tl("Low");
else
warning = lang.tl("OK");
gdi.fillRight();
gdi.pushX();
gdi.addString("", fontSmall, L"Batteristatus:");
gdi.addStringUT(boldSmall, getCard()->getCardVoltage());
gdi.fillDown();
gdi.addStringUT(fontSmall, L"(" + warning + L")");
gdi.popX();
}
if (li) {
if (li && !li->empty(false)) {
oe->generateList(gdi, false, *li, false);
gdi.dropLine();
}
else {
gdi.dropLine(0.7);
}
vector< pair<wstring, int> > 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");
}
void oRunner::printStartInfo(gdioutput &gdi) const {
gdi.setCX(10);
gdi.fillDown();
@ -5464,7 +5496,7 @@ void oRunner::setBirthYear(int year)
int oRunner::getBirthYear() const
{
return getDCI().getInt("BirthYear");
return getDCI().getYear("BirthYear");
}
void oRunner::setBirthDate(const wstring& date) {
@ -6817,7 +6849,7 @@ bool oRunner::startTimeAvailable() const {
if (st == restart && Class->getStartType(tLeg) == STChange) {
int currentTime = oe->getComputerTime();
int rope = Class->getRopeTime(tLeg);
return rope != 0 && currentTime + 600 > rope;
return rope != 0 && currentTime + 10 * timeConstMinute > rope;
}
return true;
@ -7110,3 +7142,93 @@ bool oAbstractRunner::isStatusUnknown(bool computed, bool allowUpdate) const {
}
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;
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*/
static const wstring &encodeStatus(RunnerStatus st, bool allowError = false);
@ -712,6 +715,8 @@ protected:
int getBuiltinAdjustment() const override;
public:
bool matchAbstractRunner(const oAbstractRunner* target) const override;
static const shared_ptr<Table> &getTable(oEvent *oe);
oRunner *getMainRunner() { return tParentRunner != nullptr ? tParentRunner : this; }
@ -754,6 +759,30 @@ public:
const wstring &getNameLastFirst() 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,
or false if it conflicts with the card of the other runner. */
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 {
if (leg==-1)
leg = Runners.size()-1;
oTeam *ths = (oTeam *)this;
ths->apply(oBase::ChangeType::Quiet, leg < Runners.size() ? Runners[leg] : nullptr);
spk.club = getName();
spk.missingStartTime = true;
//Defaults (if early return)
@ -1600,7 +1601,10 @@ void oTeam::fillSpeakerObject(int leg, int courseControlId, int previousControlC
}
}
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTimeLeg.time + Runners[leg]->tStartTime);
if (spk.runningTimeLeg.time > 10)
spk.timeSinceChange = oe->getComputerTime() - (spk.runningTimeLeg.time + Runners[leg]->tStartTime);
else
spk.timeSinceChange = -1;
spk.owner=Runners[leg];
spk.finishStatus=getLegStatus(specifiedLeg, true, totalResult);
@ -2590,3 +2594,45 @@ void oTeam::changedObject() {
sqlChanged = 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:
bool matchAbstractRunner(const oAbstractRunner* target) const override;
/** Deduce from computed runner times.*/
RunnerStatus deduceComputedStatus() const;
int deduceComputedRunningTime() const;
@ -230,6 +232,10 @@ public:
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 importRunners(const vector<int> &rns);
void importRunners(const vector<pRunner> &rns);

View File

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

View File

@ -100,15 +100,20 @@ int OnlineInput::processButton(gdioutput &gdi, ButtonInfo &bi) {
}
else if (bi.id == "UseUnitId") {
useUnitId = gdi.isChecked(bi.id);
if (useUnitId)
gdi.setTextTranslate("CmpID_label", L"Enhetens ID-nummer (MAC):", true);
else
gdi.setTextTranslate("CmpID_label", L"Tävlingens ID-nummer:", true);
updateLabel(gdi);
}
return 0;
}
void OnlineInput::updateLabel(gdioutput& gdi)
{
if (useUnitId)
gdi.setTextTranslate("CmpID_label", L"Enhetens ID-nummer (MAC):", true);
else
gdi.setTextTranslate("CmpID_label", L"Tävlingens ID-nummer:", true);
}
void OnlineInput::fillMappings(gdioutput &gdi) const{
gdi.clearList("Mappings");
for (map<int, oPunch::SpecialPunch>::const_iterator it = specialPunches.begin(); it != specialPunches.end(); ++it) {
@ -134,7 +139,11 @@ void OnlineInput::settings(gdioutput &gdi, oEvent &oe, State state) {
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.setInputStatus("UseUnitId", useROCProtocol);
gdi.addInput("CmpID", itow(cmpId), 10, 0, L"Tävlingens ID-nummer:");
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.dropLine(1);
gdi.addString("", boldText, "Kontrollmappning");

View File

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

View File

@ -29,8 +29,8 @@ struct SpeakerString {
wstring str;
int format;
bool hasTimer;
int timer;
int timeout;
int timer; // Timer time (in normal time units)
int timeout; // Timeout time (in seconds)
string moveKey;
GDICOLOR color;
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) {
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);
//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