MeOS version 3.5.916 Update 2

This commit is contained in:
Erik Melin 2018-08-06 11:11:35 +02:00
parent 00906d29ea
commit ef53f6da74
14 changed files with 227 additions and 169 deletions

View File

@ -166,11 +166,6 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
//r->apply(false); //r->apply(false);
vector<int> mp; vector<int> mp;
r->evaluateCard(true, mp, 0, false); r->evaluateCard(true, mp, 0, false);
/*
if (parent!=r) {
parent->synchronize();
parent->apply(false);
}*/
gdi.selectItemByData("Runners", parent->getId()); gdi.selectItemByData("Runners", parent->getId());
@ -267,31 +262,28 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
gdi.selectItemByData("RCourse", r->getCourseId()); gdi.selectItemByData("RCourse", r->getCourseId());
updateNumShort(gdi, r->getCourse(false), r); updateNumShort(gdi, r->getCourse(false), r);
int cno = parent->getCardNo(); int cno = r->getCardNo();
gdi.setText("CardNo", cno > 0 ? itow(cno) : L""); gdi.setText("CardNo", cno > 0 ? itow(cno) : L"");
warnDuplicateCard(gdi, cno, r); warnDuplicateCard(gdi, cno, r);
gdi.check("RentCard", parent->getDI().getInt("CardFee") != 0); gdi.check("RentCard", r->isHiredCard());
bool hasFee = gdi.hasField("Fee"); bool hasFee = gdi.hasField("Fee");
if (hasFee) if (hasFee)
gdi.setText("Fee", oe->formatCurrency(parent->getDI().getInt("Fee"))); gdi.setText("Fee", oe->formatCurrency(parent->getDI().getInt("Fee")));
if (parent != r) { bool canEditClass = parent == r || (parent->getClassRef(false) &&
gdi.disableInput("CardNo"); parent->getClassRef(false)->getQualificationFinal());
gdi.disableInput("RentCard");
if (hasFee) gdi.setInputStatus("RClass", canEditClass);
gdi.disableInput("Fee");
gdi.disableInput("RClass");
}
else {
gdi.enableInput("CardNo"); gdi.enableInput("CardNo");
gdi.enableInput("RentCard"); gdi.enableInput("RentCard");
if (hasFee) if (hasFee)
gdi.enableInput("Fee"); gdi.setInputStatus("Fee", parent == r);
gdi.enableInput("RClass");
} if(gdi.hasField("Club"))
gdi.setInputStatus("Club", parent == r);
enableControlButtons(gdi, true, r->isVacant()); enableControlButtons(gdi, true, r->isVacant());
@ -537,8 +529,8 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
throw meosException("Internal error runner index"); throw meosException("Internal error runner index");
cardNoChanged = r->getCardNo() != cardNo; cardNoChanged = r->getCardNo() != cardNo;
if (r->getName() != name || (r->getClubId() != clubId && clubId != 0)) if (!r->matchName(name) || (r->getClubId() != clubId && clubId != 0))
r->updateFromDB(name, clubId, classId, cardNo, r->getBirthYear()); r->updateFromDB(name, clubId, classId, cardNo, r->getBirthYear(), false);
} }
if (cardNoChanged && cardNo>0) { if (cardNoChanged && cardNo>0) {
@ -580,11 +572,17 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
} }
} }
if (r->getCardNo() != cardNo) {
r->setCardNo(cardNo, true); r->setCardNo(cardNo, true);
if (gdi.isChecked("RentCard")) }
const bool hireChecked = gdi.isChecked("RentCard");
const bool hireState = r->isHiredCard();
if (hireChecked && !hireState) {
r->getDI().setInt("CardFee", oe->getDI().getInt("CardFee")); r->getDI().setInt("CardFee", oe->getDI().getInt("CardFee"));
else }
else if (!hireChecked && hireState) {
r->getDI().setInt("CardFee", 0); r->getDI().setInt("CardFee", 0);
}
if (gdi.hasField("Fee")) if (gdi.hasField("Fee"))
r->getDI().setInt("Fee", oe->interpretCurrency(gdi.getText("Fee"))); r->getDI().setInt("Fee", oe->interpretCurrency(gdi.getText("Fee")));
@ -926,10 +924,17 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
gdi.getSelectedItem("RClass", lbi); gdi.getSelectedItem("RClass", lbi);
pRunner r = oe->addRunner(oe->getAutoRunnerName(), 0,0,0,0, false); pRunner r = oe->addRunner(oe->getAutoRunnerName(), 0,0,0,0, false);
if (signed(lbi.data)>0) int clsId = lbi.data;
r->setClassId(lbi.data, true); if (clsId > 0) {
else pClass tCls = oe->getClass(clsId);
r->setClassId(oe->getFirstClassId(false), true); if (tCls && tCls->getParentClass() != nullptr && tCls->getParentClass() != tCls) {
clsId = tCls->getParentClass()->getId();
}
}
if (clsId <= 0)
clsId = oe->getFirstClassId(false);
r->setClassId(clsId, true);
fillRunnerList(gdi); fillRunnerList(gdi);
oe->fillClubs(gdi, "Club"); oe->fillClubs(gdi, "Club");
@ -1402,7 +1407,7 @@ int TabRunner::vacancyCB(gdioutput &gdi, int type, void *data)
if (pc) if (pc)
clubId = pc->getId(); clubId = pc->getId();
} }
r->updateFromDB(name, clubId, r->getClassId(false), cardNo, birthYear); r->updateFromDB(name, clubId, r->getClassId(false), cardNo, birthYear, false);
r->setName(name, true); r->setName(name, true);
r->setCardNo(cardNo, true); r->setCardNo(cardNo, true);
r->setClub(club); r->setClub(club);

View File

@ -864,7 +864,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
} }
} }
int birthYear = 0; int birthYear = 0;
r->updateFromDB(name, clubId, lbi.data, cardNo, birthYear); r->updateFromDB(name, clubId, lbi.data, cardNo, birthYear, false);
r->setName(name, true); r->setName(name, true);
r->setClubId(clubId); r->setClubId(clubId);
r->setClassId(lbi.data, true); r->setClassId(lbi.data, true);
@ -2378,7 +2378,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
statusline += lang.tl(L", Prel. bomtid: ") + runner->getMissedTimeS(); statusline += lang.tl(L", Prel. bomtid: ") + runner->getMissedTimeS();
gdi.addStringUT(rc.top+6+lh, rc.left+20, 0, statusline); gdi.addStringUT(rc.top+6+lh, rc.left+20, 0, statusline);
if (runner->getDI().getInt("CardFee") != 0) if (runner->isHiredCard())
rentCardInfo(gdi, rc.right-rc.left); rentCardInfo(gdi, rc.right-rc.left);
gdi.scrollToBottom(); gdi.scrollToBottom();
} }
@ -2414,7 +2414,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
gdi.addStringUT(rc.top+6+lh, rc.left+20, 0, msg); gdi.addStringUT(rc.top+6+lh, rc.left+20, 0, msg);
if (runner->getDI().getInt("CardFee") != 0) if (runner->isHiredCard())
rentCardInfo(gdi, rc.right-rc.left); rentCardInfo(gdi, rc.right-rc.left);
gdi.scrollToBottom(); gdi.scrollToBottom();
@ -3015,6 +3015,10 @@ void TabSI::showModeCardData(gdioutput &gdi) {
gdi.addButton("CreateCompetition", "Create Competition", SportIdentCB); gdi.addButton("CreateCompetition", "Create Competition", SportIdentCB);
if (savedCards.empty()) if (savedCards.empty())
gdi.disableInput("CreateCompetition"); gdi.disableInput("CreateCompetition");
#ifdef _DEBUG
gdi.addButton("Import", "Importera från fil...", SportIdentCB);
#endif
} }
gdi.dropLine(3); gdi.dropLine(3);
gdi.popX(); gdi.popX();
@ -3111,7 +3115,7 @@ void TabSI::printCard(gdioutput &gdi, int cardId, bool forPrinter) const {
name = wstring(c.firstName) + L" " + c.lastName; name = wstring(c.firstName) + L" " + c.lastName;
clubName = c.club; clubName = c.club;
} }
else { else if (useDatabase) {
const RunnerWDBEntry *r = oe->getRunnerDatabase().getRunnerByCard(c.CardNumber); const RunnerWDBEntry *r = oe->getRunnerDatabase().getRunnerByCard(c.CardNumber);
if (r) { if (r) {
r->getName(name); r->getName(name);
@ -3271,12 +3275,6 @@ void TabSI::createCompetitionFromCards(gdioutput &gdi) {
cards.push_back(p); cards.push_back(p);
} }
zeroTime -= 3600;
if (zeroTime < 0)
zeroTime += 3600 * 24;
zeroTime -= zeroTime % 1800;
oe->setZeroTime(formatTime(zeroTime));
int course = 0; int course = 0;
for (size_t k = 0; k < cards.size(); k++) { for (size_t k = 0; k < cards.size(); k++) {
if (!hashCount.count(cards[k].first)) if (!hashCount.count(cards[k].first))
@ -3306,7 +3304,7 @@ void TabSI::createCompetitionFromCards(gdioutput &gdi) {
if (abs(dist) > 3) { if (abs(dist) > 3) {
pCourse pc = oe->addCourse(lang.tl("Bana ") + itow(++course)); pCourse pc = oe->addCourse(lang.tl("Bana ") + itow(++course));
for (unsigned j = 0; j < cards[k].second->nPunch; k++) { for (unsigned j = 0; j < cards[k].second->nPunch; j++) {
pc->addControl(cards[k].second->Punch[j].Code); pc->addControl(cards[k].second->Punch[j].Code);
} }
oe->addClass(lang.tl(L"Klass ") + itow(course), pc->getId()); oe->addClass(lang.tl(L"Klass ") + itow(course), pc->getId());
@ -3314,6 +3312,13 @@ void TabSI::createCompetitionFromCards(gdioutput &gdi) {
} }
} }
// Define a new zero time
zeroTime -= 3600;
if (zeroTime < 0)
zeroTime += 3600 * 24;
zeroTime -= zeroTime % 1800;
oe->setZeroTime(formatTime(zeroTime));
// Add competitors // Add competitors
for (size_t k = 0; k < cards.size(); k++) { for (size_t k = 0; k < cards.size(); k++) {
if (oe->isCardRead(*cards[k].second)) if (oe->isCardRead(*cards[k].second))
@ -3489,8 +3494,8 @@ void TabSI::showCheckCardStatus(gdioutput &gdi, const string &cmd) {
checkedCardFlags[cno] == CNFRentAndNotRent) { checkedCardFlags[cno] == CNFRentAndNotRent) {
int yp = gdi.getCY(); int yp = gdi.getCY();
wstring cp = r[k]->getCompleteIdentification(); wstring cp = r[k]->getCompleteIdentification();
bool rent = r[k]->getDI().getInt("CardFee") != 0; bool hire = r[k]->isHiredCard();
wstring info = rent ? (L" (" + lang.tl("Hyrd") + L")") : L""; wstring info = hire ? (L" (" + lang.tl("Hyrd") + L")") : L"";
gdi.addStringUT(yp, cx, 0, itow(cno) + info); gdi.addStringUT(yp, cx, 0, itow(cno) + info);
gdi.addStringUT(yp, cx + col2, 0, cp); gdi.addStringUT(yp, cx + col2, 0, cp);
} }

View File

@ -424,13 +424,13 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
int cardNo = gdi.getTextNo(bf2); int cardNo = gdi.getTextNo(bf2);
if (r) { if (r) {
bool newName = name != r->getName(); bool newName = !r->matchName(name);
int oldId = gdi.getExtraInt(bf); int oldId = gdi.getExtraInt(bf);
// Same runner set // Same runner set
if (oldId == r->getId()) { if (oldId == r->getId()) {
if (newName) { if (newName) {
r->updateFromDB(name, r->getClubId(), r->getClassId(false), r->updateFromDB(name, r->getClubId(), r->getClassId(false),
cardNo, 0); cardNo, 0, false);
r->setName(name, true); r->setName(name, true);
} }
r->setCardNo(cardNo, true); r->setCardNo(cardNo, true);
@ -449,7 +449,7 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
r->setClub(t->getClub()); r->setClub(t->getClub());
r->resetPersonalData(); r->resetPersonalData();
r->updateFromDB(name, r->getClubId(), r->getClassId(false), r->updateFromDB(name, r->getClubId(), r->getClassId(false),
cardNo, 0); cardNo, 0, false);
} }
} }
else else

View File

@ -250,6 +250,8 @@ void Table::filter(int col, const wstring &filt, bool forceFilter)
if (filt==oldFilter && (!forceFilter || filt.empty())) if (filt==oldFilter && (!forceFilter || filt.empty()))
return; return;
else if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) { else if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) {
if (sortIndex.empty())
return;
//Filter more... //Filter more...
baseIndex.resize(2); baseIndex.resize(2);
baseIndex[0]=sortIndex[0]; baseIndex[0]=sortIndex[0];

View File

@ -617,6 +617,9 @@ bool csvparser::importOCAD_CSV(oEvent &event, const wstring &file, bool addClass
for (size_t k=firstIndex; k<sp.size()-1;k+=(hasLengths ? 2 : 1)) { for (size_t k=firstIndex; k<sp.size()-1;k+=(hasLengths ? 2 : 1)) {
wstring ctrlStr = trim(sp[k]); wstring ctrlStr = trim(sp[k]);
if (!ctrlStr.empty()) { if (!ctrlStr.empty()) {
if (ctrlStr[0] == 'S')
continue;
int ctrl = wtoi(ctrlStr.c_str()); int ctrl = wtoi(ctrlStr.c_str());
if (ctrl == 0 && trim(sp[k+1]).length() == 0) if (ctrl == 0 && trim(sp[k+1]).length() == 0)

View File

@ -29,7 +29,7 @@
//V33: abcde //V33: abcde
//V35: abcdef //V35: abcdef
int getMeosBuild() { int getMeosBuild() {
string revision("$Rev: 706 $"); string revision("$Rev: 742 $");
return 174 + atoi(revision.substr(5, string::npos).c_str()); return 174 + atoi(revision.substr(5, string::npos).c_str());
} }
@ -41,12 +41,12 @@ int getMeosBuild() {
//V33: abcdefghij //V33: abcdefghij
//V34: abcdfge //V34: abcdfge
wstring getMeosDate() { wstring getMeosDate() {
wstring date(L"$Date: 2018-05-20 12:07:24 +0200 (sö, 20 maj 2018) $"); wstring date(L"$Date: 2018-08-04 08:53:52 +0200 (lö, 04 aug 2018) $");
return date.substr(7,10); return date.substr(7,10);
} }
wstring getBuildType() { wstring getBuildType() {
return L"U1"; // No parantheses (...) return L"U2"; // No parantheses (...)
} }
wstring getMajorVersion() { wstring getMajorVersion() {
@ -72,74 +72,7 @@ wstring getMeosCompectVersion() {
void getSupporters(vector<wstring> &supp, vector<wstring> developSupp) void getSupporters(vector<wstring> &supp, vector<wstring> developSupp)
{ {
supp.emplace_back(L"Centrum OK");
supp.emplace_back(L"Ove Persson, Piteå IF");
supp.emplace_back(L"OK Rodhen");
supp.emplace_back(L"Täby Extreme Challenge");
supp.emplace_back(L"Thomas Engberg, VK Uvarna");
supp.emplace_back(L"Eilert Edin, Sidensjö IK");
supp.emplace_back(L"Göran Nordh, Trollhättans SK");
supp.emplace_back(L"Roger Gustavsson, OK Tisaren");
supp.emplace_back(L"Sundsvalls OK");
supp.emplace_back(L"OK Gipens OL-skytte");
supp.emplace_back(L"Helsingborgs SOK");
supp.emplace_back(L"OK Gipens OL-skytte");
supp.emplace_back(L"Rune Thurén, Vallentuna-Össeby OL");
supp.emplace_back(L"Roland Persson, Kalmar OK");
supp.emplace_back(L"Robert Jessen, Främmestads IK");
supp.emplace_back(L"Anders Platt, Järla Orientering");
supp.emplace_back(L"Almby IK, Örebro");
supp.emplace_back(L"Peter Rydesäter, Rehns BK");
supp.emplace_back(L"IK Hakarpspojkarna");
supp.emplace_back(L"Rydboholms SK");
supp.emplace_back(L"IFK Kiruna");
supp.emplace_back(L"Peter Andersson, Söders SOL");
supp.emplace_back(L"Björkfors GoIF");
supp.emplace_back(L"OK Ziemelkurzeme");
supp.emplace_back(L"Big Foot Orienteers");
supp.emplace_back(L"FIF Hillerød");
supp.emplace_back(L"Anne Udd");
supp.emplace_back(L"OK Orinto");
supp.emplace_back(L"SOK Träff");
supp.emplace_back(L"Gamleby OK");
supp.emplace_back(L"Vänersborgs SK");
supp.emplace_back(L"Henrik Ortman, Västerås SOK");
supp.emplace_back(L"Leif Olofsson, Sjuntorp");
supp.emplace_back(L"Vallentuna/Össeby OL");
supp.emplace_back(L"Oskarström OK");
supp.emplace_back(L"Skogslöparna");
supp.emplace_back(L"OK Milan");
supp.emplace_back(L"Tjalve IF");
supp.emplace_back(L"OK Skärmen");
supp.emplace_back(L"Østkredsen");
supp.emplace_back(L"OK Roskilde");
supp.emplace_back(L"Holbæk Orienteringsklub");
supp.emplace_back(L"Bodens BK");
supp.emplace_back(L"OK Tyr, Karlstad");
supp.emplace_back(L"Göteborg-Majorna OK");
supp.emplace_back(L"OK Järnbärarna, Kopparberg");
supp.emplace_back(L"FK Åsen");
supp.emplace_back(L"Ballerup OK");
supp.emplace_back(L"Olivier Benevello, Valbonne SAO");
supp.emplace_back(L"Tommy Wåhlin, OK Enen");
supp.emplace_back(L"Hjobygdens OK");
supp.emplace_back(L"Tisvilde Hegn OK");
supp.emplace_back(L"Lindebygdens OK");
supp.emplace_back(L"OK Flundrehof");
supp.emplace_back(L"Vittjärvs IK");
supp.emplace_back(L"Annebergs GIF");
supp.emplace_back(L"Lars-Eric Gahlin, Östersunds OK");
supp.emplace_back(L"Sundsvalls OK:s Veteraner");
supp.emplace_back(L"OK Skogshjortarna");
supp.emplace_back(L"Kinnaströms SK");
supp.emplace_back(L"OK Pan Århus");
supp.emplace_back(L"Jan Ernberg, Täby OK");
supp.emplace_back(L"Stjärnorps SK");
supp.emplace_back(L"Mölndal Outdoor IF");
supp.emplace_back(L"Roland Elg, Fjärås AIK");
supp.emplace_back(L"Tenhults SOK");
supp.emplace_back(L"Järfälla OK"); supp.emplace_back(L"Järfälla OK");
supp.emplace_back(L"Lars Jonasson");
supp.emplace_back(L"Anders Larsson, OK Nackhe"); supp.emplace_back(L"Anders Larsson, OK Nackhe");
supp.emplace_back(L"Hans Wilhelmsson"); supp.emplace_back(L"Hans Wilhelmsson");
supp.emplace_back(L"Patrice Lavallee, Noyon Course d'Orientation"); supp.emplace_back(L"Patrice Lavallee, Noyon Course d'Orientation");
@ -147,7 +80,6 @@ void getSupporters(vector<wstring> &supp, vector<wstring> developSupp)
supp.emplace_back(L"Lars Ove Karlsson, Västerås SOK"); supp.emplace_back(L"Lars Ove Karlsson, Västerås SOK");
supp.emplace_back(L"OK Djerf"); supp.emplace_back(L"OK Djerf");
supp.emplace_back(L"OK Vivill"); supp.emplace_back(L"OK Vivill");
supp.emplace_back(L"IFK Mora OK");
supp.emplace_back(L"Sonny Andersson, Huskvarna"); supp.emplace_back(L"Sonny Andersson, Huskvarna");
supp.emplace_back(L"Hässleholms OK Skolorientering"); supp.emplace_back(L"Hässleholms OK Skolorientering");
supp.emplace_back(L"IBM-klubben Orientering"); supp.emplace_back(L"IBM-klubben Orientering");
@ -167,7 +99,6 @@ void getSupporters(vector<wstring> &supp, vector<wstring> developSupp)
supp.emplace_back(L"Gävle OK"); supp.emplace_back(L"Gävle OK");
supp.emplace_back(L"Kenneth Gattmalm, Jönköpings OK"); supp.emplace_back(L"Kenneth Gattmalm, Jönköpings OK");
supp.emplace_back(L"Søllerød OK"); supp.emplace_back(L"Søllerød OK");
supp.emplace_back(L"O-travel");
supp.emplace_back(L"Bengt Bengtsson"); supp.emplace_back(L"Bengt Bengtsson");
supp.emplace_back(L"OK Landehof"); supp.emplace_back(L"OK Landehof");
supp.emplace_back(L"OK Orinto"); supp.emplace_back(L"OK Orinto");
@ -184,14 +115,23 @@ void getSupporters(vector<wstring> &supp, vector<wstring> developSupp)
supp.emplace_back(L"Christoffer Ohlsson, Uddevalla OK"); supp.emplace_back(L"Christoffer Ohlsson, Uddevalla OK");
supp.emplace_back(L"O-Ringen AB"); supp.emplace_back(L"O-Ringen AB");
supp.emplace_back(L"Hans Carlstedt, Sävedalens AIK"); supp.emplace_back(L"Hans Carlstedt, Sävedalens AIK");
supp.emplace_back(L"IFK Mora OK");
supp.emplace_back(L"Attunda OK"); supp.emplace_back(L"Attunda OK");
supp.emplace_back(L"OK Tyr, Karlstad");
supp.emplace_back(L"Siguldas Takas, Latvia"); supp.emplace_back(L"Siguldas Takas, Latvia");
supp.emplace_back(L"Eric Teutsch, Ottawa Orienteering Club, Canada"); supp.emplace_back(L"Eric Teutsch, Ottawa Orienteering Club, Canada");
supp.emplace_back(L"Silkeborg OK, Denmark"); supp.emplace_back(L"Silkeborg OK, Denmark");
supp.emplace_back(L"Almby IK, Örebro");
supp.emplace_back(L"Erik Ivarsson Sandberg"); supp.emplace_back(L"Erik Ivarsson Sandberg");
supp.emplace_back(L"Stenungsunds OK"); supp.emplace_back(L"Stenungsunds OK");
supp.emplace_back(L"OK Leipzig"); supp.emplace_back(L"OK Leipzig");
supp.emplace_back(L"Degerfors OK"); supp.emplace_back(L"Degerfors OK");
supp.emplace_back(L"OK Tjärnen"); supp.emplace_back(L"OK Tjärnen");
//reverse(supp.begin(), supp.end()); supp.emplace_back(L"Leksands OK");
supp.emplace_back(L"O-Travel");
supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice");
supp.emplace_back(L"Richard HEYRIES");
supp.emplace_back(L"Ingemar Carlsson");
reverse(supp.begin(), supp.end());
} }

View File

@ -1903,6 +1903,16 @@ public:
int baseRes; int baseRes;
if (r.getInputStatus() == StatusOK) { if (r.getInputStatus() == StatusOK) {
int t = r.getInputPlace(); int t = r.getInputPlace();
if (t == 0) {
const oRunner *rr = dynamic_cast<const oRunner *>(&r);
if (rr && rr->getTeam() && rr->getLegNumber() > 0) {
const pRunner rPrev = rr->getTeam()->getRunner(rr->getLegNumber() - 1);
if (rPrev && rPrev->getStatus() == StatusOK)
t = rPrev->getPlace();
}
}
if (t > 0) if (t > 0)
baseRes = t; baseRes = t;
else else
@ -3929,9 +3939,12 @@ void oClass::drawSeeded(ClassSeedMethod seed, int leg, int firstStart,
vector<pRunner> r; vector<pRunner> r;
oe->getRunners(Id, 0, r, true); oe->getRunners(Id, 0, r, true);
vector< pair<int, int> > seedIx; vector< pair<int, int> > seedIx;
if (seed == SeedResult) {
oe->reEvaluateAll(set<int>(), true);
oe->calculateResults(oEvent::ResultType::RTClassResult, false);
}
for (size_t k = 0; k < r.size(); k++) { for (size_t k = 0; k < r.size(); k++) {
if (r[k]->tLeg != leg) if (r[k]->tLeg != leg && leg != -1)
continue; continue;
pair<int,int> sx; pair<int,int> sx;
@ -4213,9 +4226,9 @@ oClass *oClass::getVirtualClass(int instance, bool allowCreation) {
return this; // Fallback return this; // Fallback
} }
const oClass *oClass::getVirtualClass(int instance) const { const pClass oClass::getVirtualClass(int instance) const {
if (instance == 0) if (instance == 0)
return this; return pClass(this);
if (parentClass) if (parentClass)
return parentClass->getVirtualClass(instance); return parentClass->getVirtualClass(instance);
@ -4223,7 +4236,7 @@ const oClass *oClass::getVirtualClass(int instance) const {
return virtualClasses[instance]; return virtualClasses[instance];
if (instance >= getNumQualificationFinalClasses()) if (instance >= getNumQualificationFinalClasses())
return this; // Invalid return pClass(this); // Invalid
virtualClasses.resize(getNumQualificationFinalClasses()); virtualClasses.resize(getNumQualificationFinalClasses());
int virtId = Id + instance * MaxClassId; int virtId = Id + instance * MaxClassId;
@ -4235,7 +4248,7 @@ const oClass *oClass::getVirtualClass(int instance) const {
configureInstance(instance, false); configureInstance(instance, false);
if (virtualClasses[instance]) if (virtualClasses[instance])
return virtualClasses[instance]; return virtualClasses[instance];
return this; // Fallback return pClass(this); // Fallback
} }
void oClass::configureInstance(int instance, bool allowCreation) const { void oClass::configureInstance(int instance, bool allowCreation) const {

View File

@ -346,7 +346,7 @@ public:
} }
oClass *getVirtualClass(int instance, bool allowCreation); oClass *getVirtualClass(int instance, bool allowCreation);
const oClass *getVirtualClass(int instance) const; const pClass getVirtualClass(int instance) const;
ClassStatus getClassStatus() const; ClassStatus getClassStatus() const;

View File

@ -1785,7 +1785,14 @@ int oEvent::getFirstClassId(bool teamClass) const {
for (oClassList::const_iterator it = Classes.begin(); it != Classes.end(); ++it) { for (oClassList::const_iterator it = Classes.begin(); it != Classes.end(); ++it) {
if (it->isRemoved()) if (it->isRemoved())
continue; continue;
if (it->getQualificationFinal())
return it->Id; // Both team and single
int ns = it->getNumStages(); int ns = it->getNumStages();
if (ns > 0 && it->getNumDistinctRunners() == 1)
return it->Id; // Both team and single
if (teamClass && ns > 0) if (teamClass && ns > 0)
return it->Id; return it->Id;
else if (!teamClass && ns == 0) else if (!teamClass && ns == 0)

View File

@ -2035,31 +2035,33 @@ void oRunner::setClub(const wstring &clubName)
tParentRunner->setClub(clubName); tParentRunner->setClub(clubName);
else { else {
oAbstractRunner::setClub(clubName); oAbstractRunner::setClub(clubName);
propagateClub();
for (size_t k=0;k<multiRunner.size();k++)
if (multiRunner[k] && multiRunner[k]->Club!=Club) {
multiRunner[k]->Club = Club;
multiRunner[k]->updateChanged();
}
} }
} }
pClub oRunner::setClubId(int clubId) pClub oRunner::setClubId(int clubId) {
{
if (tParentRunner) if (tParentRunner)
tParentRunner->setClubId(clubId); tParentRunner->setClubId(clubId);
else { else {
oAbstractRunner::setClubId(clubId); oAbstractRunner::setClubId(clubId);
for (size_t k=0;k<multiRunner.size();k++) propagateClub();
}
return Club;
}
void oRunner::propagateClub() {
for (size_t k = 0; k < multiRunner.size(); k++) {
if (multiRunner[k] && multiRunner[k]->Club != Club) { if (multiRunner[k] && multiRunner[k]->Club != Club) {
multiRunner[k]->Club = Club; multiRunner[k]->Club = Club;
multiRunner[k]->updateChanged(); multiRunner[k]->updateChanged();
} }
} }
return Club; if (tInTeam && Class && Class->getNumDistinctRunners() == 1 && tInTeam->getClubRef() != Club) {
tInTeam->Club = Club;
tInTeam->updateChanged();
}
} }
void oAbstractRunner::setStartNo(int no, bool tmpOnly) { void oAbstractRunner::setStartNo(int no, bool tmpOnly) {
if (tmpOnly) { if (tmpOnly) {
@ -2191,6 +2193,27 @@ void oRunner::setCardNo(int cno, bool matchCard, bool updateFromDatabase)
} }
} }
bool oRunner::isHiredCard() const {
if (getDCI().getInt("CardFee") != 0)
return true;
if (tParentRunner && tParentRunner != this)
return tParentRunner->isHiredCard(getCardNo());
return isHiredCard(CardNo);
}
bool oRunner::isHiredCard(int cno) const {
if (cno == CardNo)
return getDCI().getInt("CardFee") != 0;
for (pRunner r : multiRunner) {
if (r && r->getCardNo() == cno && r->getDCI().getInt("CardFee") != 0)
return true;
}
return false;
}
int oRunner::setCard(int cardId) int oRunner::setCard(int cardId)
{ {
pCard c=cardId ? oe->getCard(cardId) : 0; pCard c=cardId ? oe->getCard(cardId) : 0;
@ -3197,7 +3220,7 @@ bool oRunner::inputData(int id, const wstring &input,
throw std::exception("Tomt namn inte tillåtet."); throw std::exception("Tomt namn inte tillåtet.");
if (sName != input && tRealName != input) { if (sName != input && tRealName != input) {
updateFromDB(input, getClubId(), getClassId(false), getCardNo(), getBirthYear()); updateFromDB(input, getClubId(), getClassId(false), getCardNo(), getBirthYear(), false);
setName(input, true); setName(input, true);
synchronizeAll(); synchronizeAll();
} }
@ -3243,7 +3266,7 @@ bool oRunner::inputData(int id, const wstring &input,
else else
pc = oe->getClubCreate(0, input); pc = oe->getClubCreate(0, input);
updateFromDB(getName(), pc ? pc->getId():0, getClassId(false), getCardNo(), getBirthYear()); updateFromDB(getName(), pc ? pc->getId():0, getClassId(false), getCardNo(), getBirthYear(), false);
setClub(pc ? pc->getName() : L""); setClub(pc ? pc->getName() : L"");
synchronize(true); synchronize(true);
@ -3336,6 +3359,20 @@ void oRunner::fillInput(int id, vector< pair<wstring, size_t> > &out, size_t &se
int oRunner::getSplitTime(int controlNumber, bool normalized) const int oRunner::getSplitTime(int controlNumber, bool normalized) const
{ {
if (!Card) {
if (controlNumber == 0)
return getPunchTime(0, false);
else {
int ct = getPunchTime(controlNumber, false);
if (ct > 0) {
int dt = getPunchTime(controlNumber - 1, false);
if (dt > 0 && ct > dt)
return ct - dt;
}
}
return -1;
}
const vector<SplitData> &st = getSplitTimes(normalized); const vector<SplitData> &st = getSplitTimes(normalized);
if (controlNumber>0 && controlNumber == st.size() && FinishTime>0) { if (controlNumber>0 && controlNumber == st.size() && FinishTime>0) {
int t = st.back().time; int t = st.back().time;
@ -3360,11 +3397,9 @@ int oRunner::getTimeAdjust(int controlNumber) const
return 0; return 0;
} }
int oRunner::getNamedSplit(int controlNumber) const int oRunner::getNamedSplit(int controlNumber) const {
{
pCourse crs=getCourse(true); pCourse crs=getCourse(true);
if (!crs || unsigned(controlNumber)>=unsigned(crs->nControls) if (!crs || unsigned(controlNumber)>=unsigned(crs->nControls))
|| unsigned(controlNumber)>=splitTimes.size())
return -1; return -1;
pControl ctrl=crs->Controls[controlNumber]; pControl ctrl=crs->Controls[controlNumber];
@ -3372,24 +3407,25 @@ int oRunner::getNamedSplit(int controlNumber) const
return -1; return -1;
int k=controlNumber-1; int k=controlNumber-1;
int ct = getPunchTime(controlNumber, false);
if (ct <= 0)
return -1;
//Measure from previous named control //Measure from previous named control
while (k >= 0) { while (k >= 0) {
pControl c = crs->Controls[k]; pControl c = crs->Controls[k];
if (c && c->hasName()) { if (c && c->hasName()) {
if (splitTimes[controlNumber].time>0 && splitTimes[k].time>0) int dt = getPunchTime(k, false);
return max(splitTimes[controlNumber].time - splitTimes[k].time, -1); if (dt > 0 && ct > dt)
return max(ct - dt, -1);
else return -1; else return -1;
} }
k--; k--;
} }
//Measure from start time //Measure from start time
if (splitTimes[controlNumber].time>0) return ct;
return max(splitTimes[controlNumber].time - tStartTime, -1);
return -1;
} }
wstring oRunner::getSplitTimeS(int controlNumber, bool normalized) const wstring oRunner::getSplitTimeS(int controlNumber, bool normalized) const
@ -3404,6 +3440,20 @@ wstring oRunner::getNamedSplitS(int controlNumber) const
int oRunner::getPunchTime(int controlNumber, bool normalized) const int oRunner::getPunchTime(int controlNumber, bool normalized) const
{ {
if (!Card) {
pCourse pc = getCourse(false);
if (!pc || controlNumber > pc->getNumControls())
return -1;
if (controlNumber == pc->getNumControls())
return getFinishTime() - tStartTime;
int ccId = pc->getCourseControlId(controlNumber);
pFreePunch fp = oe->getPunch(Id, ccId, CardNo);
if (fp)
return fp->Time - tStartTime;
return -1;
}
const vector<SplitData> &st = getSplitTimes(normalized); const vector<SplitData> &st = getSplitTimes(normalized);
if ( unsigned(controlNumber)<st.size() ) { if ( unsigned(controlNumber)<st.size() ) {
@ -4336,14 +4386,17 @@ void oEvent::updateRunnersFromDB()
for (it=Runners.begin(); it != Runners.end(); ++it) { for (it=Runners.begin(); it != Runners.end(); ++it) {
if (!it->isVacant() && !it->isRemoved()) if (!it->isVacant() && !it->isRemoved())
it->updateFromDB(it->sName, it->getClubId(), it->getClassId(false), it->getCardNo(), it->getBirthYear()); it->updateFromDB(it->sName, it->getClubId(), it->getClassId(false), it->getCardNo(), it->getBirthYear(), true);
} }
} }
bool oRunner::updateFromDB(const wstring &name, int clubId, int classId, bool oRunner::updateFromDB(const wstring &name, int clubId, int classId,
int cardNo, int birthYear) { int cardNo, int birthYear, bool forceUpdate) {
if (!oe->useRunnerDb()) if (!oe->useRunnerDb())
return false; return false;
uint64_t oldId = getExtIdentifier();
if (oldId && !forceUpdate && oe->getRunnerDatabase().getRunnerById(oldId) == 0)
return false; // Keep data if database is not installed
pRunner db_r = 0; pRunner db_r = 0;
if (cardNo>0) { if (cardNo>0) {

View File

@ -257,7 +257,7 @@ public:
pClub getClubRef() {return Club;} pClub getClubRef() {return Club;}
virtual int classInstance() const = 0; virtual int classInstance() const = 0;
const oClass *getClassRef(bool virtualClass) const { const pClass getClassRef(bool virtualClass) const {
return (virtualClass && Class) ? Class->getVirtualClass(classInstance()) : Class; return (virtualClass && Class) ? Class->getVirtualClass(classInstance()) : Class;
} }
@ -508,6 +508,11 @@ protected:
mutable pCourse tAdaptedCourse; mutable pCourse tAdaptedCourse;
mutable int tAdaptedCourseRevision; mutable int tAdaptedCourseRevision;
/** Internal propagate club.*/
void propagateClub();
bool isHiredCard(int card) const;
public: public:
/** Get a runner reference (drawing) */ /** Get a runner reference (drawing) */
pRunner getReference() const; pRunner getReference() const;
@ -627,7 +632,7 @@ public:
/** Use db to pdate runner */ /** Use db to pdate runner */
bool updateFromDB(const wstring &name, int clubId, int classId, bool updateFromDB(const wstring &name, int clubId, int classId,
int cardNo, int birthYear); int cardNo, int birthYear, bool forceUpdate);
void printSplits(gdioutput &gdi) const; void printSplits(gdioutput &gdi) const;
@ -644,8 +649,8 @@ public:
int legToRun() const {return tInTeam ? tLeg : tDuplicateLeg;} int legToRun() const {return tInTeam ? tLeg : tDuplicateLeg;}
void setName(const wstring &n, bool manualUpdate); void setName(const wstring &n, bool manualUpdate);
void setClassId(int id, bool isManualUpdate); void setClassId(int id, bool isManualUpdate);
void setClub(const wstring &name); void setClub(const wstring &name) override;
pClub setClubId(int clubId); pClub setClubId(int clubId) override;
// Start number is equal to bib-no, but bib // Start number is equal to bib-no, but bib
// is only set when it should be shown in lists etc. // is only set when it should be shown in lists etc.
@ -739,6 +744,8 @@ public:
int getCourseId() const {if (Course) return Course->Id; else return 0;} int getCourseId() const {if (Course) return Course->Id; else return 0;}
void setCourseId(int id); void setCourseId(int id);
bool isHiredCard() const;
int getCardNo() const {return tParentRunner && CardNo == 0 ? tParentRunner->CardNo : CardNo;} int getCardNo() const {return tParentRunner && CardNo == 0 ? tParentRunner->CardNo : CardNo;}
void setCardNo(int card, bool matchCard, bool updateFromDatabase = false); void setCardNo(int card, bool matchCard, bool updateFromDatabase = false);
/** Sets the card to a given card. An existing card is marked as unpaired. /** Sets the card to a given card. An existing card is marked as unpaired.

View File

@ -2258,3 +2258,26 @@ int oTeam::getRogainingPatrolOvertime() const {
getRogainingPatrolPoints(false); getRogainingPatrolPoints(false);
return tTeamPatrolRogainingAndVersion.second.overtime; return tTeamPatrolRogainingAndVersion.second.overtime;
} }
void oTeam::setClub(const wstring &clubName) {
oAbstractRunner::setClub(clubName);
propagateClub();
}
pClub oTeam::setClubId(int clubId) {
oAbstractRunner::setClubId(clubId);
propagateClub();
return Club;
}
void oTeam::propagateClub() {
if (Class && Class->getNumDistinctRunners() == 1) {
for (pRunner r : Runners) {
if (r && r->Club != Club) {
r->Club = Club;
r->updateChanged();
}
}
}
}

View File

@ -51,6 +51,7 @@ private:
void speakerLegInfo(int leg, int specifiedLeg, int courseControlId, void speakerLegInfo(int leg, int specifiedLeg, int courseControlId,
int &missingLeg, int &totalLeg, int &missingLeg, int &totalLeg,
RunnerStatus &status, int &runningTime) const; RunnerStatus &status, int &runningTime) const;
void propagateClub();
protected: protected:
//pRunner Runners[maxRunnersTeam]; //pRunner Runners[maxRunnersTeam];
@ -127,9 +128,11 @@ public:
void resetResultCalcCache() const; void resetResultCalcCache() const;
vector< vector<int> > &getResultCache(ResultCalcCacheSymbol symb) const; vector< vector<int> > &getResultCache(ResultCalcCacheSymbol symb) const;
void setResultCache(ResultCalcCacheSymbol symb, int leg, vector<int> &data) const; void setResultCache(ResultCalcCacheSymbol symb, int leg, vector<int> &data) const;
void markClassChanged(int controlId); void markClassChanged(int controlId);
void setClub(const wstring &name) override;
pClub setClubId(int clubId) override;
/// Returns team fee (including participating runners fees) /// Returns team fee (including participating runners fees)
int getTeamFee() const; int getTeamFee() const;

View File

@ -98,15 +98,12 @@ void RestServer::handleRequest(const shared_ptr<restbed::Session> &session) {
chrono::duration<double> elapsed_seconds = end - start; chrono::duration<double> elapsed_seconds = end - start;
responseTimes.push_back(int(1000 * elapsed_seconds.count())); responseTimes.push_back(int(1000 * elapsed_seconds.count()));
} }
// lock.unlock();
session->fetch(content_length, [request, answer](const shared_ptr< Session > session, const Bytes & body) session->fetch(content_length, [request, answer](const shared_ptr< Session > session, const Bytes & body)
{ {
//fprintf(stdout, "%.*s\n", (int)body.size(), body.data()); session->close(restbed::OK, answer->answer, { { "Content-Length", itos(answer->answer.length()) },
/*while (!answer->state) { { "Connection", "close" },
std::this_thread::yield(); { "Access-Control-Allow-Origin", "*" } });
}*/
session->close(restbed::OK, answer->answer, { { "Content-Length", itos(answer->answer.length()) },{ "Connection", "close" } });
}); });
} }