MeOS version 3.5.808.
This commit is contained in:
parent
adba758c26
commit
4da3c93866
@ -2,13 +2,15 @@
|
|||||||
#include "RestService.h"
|
#include "RestService.h"
|
||||||
#include "meos_util.h"
|
#include "meos_util.h"
|
||||||
#include "restserver.h"
|
#include "restserver.h"
|
||||||
|
#include "meosexception.h"
|
||||||
|
|
||||||
|
#include <ShellAPI.h>
|
||||||
|
|
||||||
int AutomaticCB(gdioutput *gdi, int type, void *data);
|
int AutomaticCB(gdioutput *gdi, int type, void *data);
|
||||||
|
|
||||||
RestService::RestService() : AutoMachine("RestService"), port(-1) {
|
RestService::RestService() : AutoMachine("Informationsserver"), port(-1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RestService::~RestService() {
|
RestService::~RestService() {
|
||||||
if (server) {
|
if (server) {
|
||||||
server->stop();
|
server->stop();
|
||||||
@ -17,14 +19,17 @@ RestService::~RestService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RestService::save(oEvent &oe, gdioutput &gdi) {
|
void RestService::save(oEvent &oe, gdioutput &gdi) {
|
||||||
if (!server)
|
if (!server) {
|
||||||
server = RestServer::construct();
|
server = RestServer::construct();
|
||||||
|
|
||||||
int port = gdi.getTextNo("Port");
|
int xport = gdi.getTextNo("Port");
|
||||||
if (port > 0 && port < 65536)
|
if (xport > 0 && xport < 65536) {
|
||||||
|
port = xport;
|
||||||
server->startService(port);
|
server->startService(port);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw std::exception("Invalid port number");
|
throw meosException("Invalid port number");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
||||||
@ -35,7 +40,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
startCancelInterval(gdi, "Save", created, IntervalNone, L"");
|
startCancelInterval(gdi, "Save", created, IntervalNone, L"");
|
||||||
|
|
||||||
if (!server)
|
if (!server)
|
||||||
gdi.addInput("Port", itow(port), 10, 0, L"Port:", L"Testa genom http://localhost:[PORT]/meos");
|
gdi.addInput("Port", itow(port), 10, 0, L"Port:", L"#http://localhost:[PORT]/meos");
|
||||||
else
|
else
|
||||||
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
||||||
|
|
||||||
@ -46,29 +51,21 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
void RestService::status(gdioutput &gdi) {
|
void RestService::status(gdioutput &gdi) {
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.addString("", 1, name);
|
gdi.addString("", 1, name);
|
||||||
/*if (!baseFile.empty()) {
|
|
||||||
gdi.fillRight();
|
|
||||||
gdi.pushX();
|
|
||||||
gdi.addString("", 0, L"Destination: X#" + baseFile);
|
|
||||||
|
|
||||||
if (interval>0) {
|
|
||||||
gdi.popX();
|
|
||||||
gdi.dropLine(1);
|
|
||||||
gdi.addString("", 0, "Säkerhetskopierar om: ");
|
|
||||||
gdi.addTimer(gdi.getCY(), gdi.getCX(), timerIgnoreSign, (GetTickCount() - timeout) / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
gdi.popX();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
gdi.addString("", 0, "Server startad på port X#" + itos(port));
|
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
||||||
|
|
||||||
RestServer::Statistics rs;
|
RestServer::Statistics rs;
|
||||||
server->getStatistics(rs);
|
server->getStatistics(rs);
|
||||||
gdi.addString("", 0, "Antal förfrågningar: X#" + itos(rs.numRequests));
|
gdi.addString("", 0, "Antal förfrågningar: X.#" + itos(rs.numRequests));
|
||||||
gdi.addString("", 0, "Genomsnittlig svarstid: X ms#" + itos(rs.averageResponseTime));
|
gdi.addString("", 0, "Genomsnittlig svarstid: X ms.#" + itos(rs.averageResponseTime));
|
||||||
gdi.addString("", 0, "Längsta svarstid: X ms#" + itos(rs.maxResponseTime));
|
gdi.addString("", 0, "Längsta svarstid: X ms.#" + itos(rs.maxResponseTime));
|
||||||
|
|
||||||
|
gdi.dropLine(0.6);
|
||||||
|
gdi.addButton("Update", "Uppdatera").setHandler(this);
|
||||||
|
gdi.dropLine(0.6);
|
||||||
|
gdi.addString("", 1, "Testa servern:");
|
||||||
|
gdi.addString("link", 0, "#http://localhost:" + itos(port) + "/meos").setHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.dropLine(2);
|
gdi.dropLine(2);
|
||||||
@ -87,6 +84,12 @@ void RestService::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) {
|
|||||||
void RestService::handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) {
|
void RestService::handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) {
|
||||||
if (type == GUI_BUTTON) {
|
if (type == GUI_BUTTON) {
|
||||||
ButtonInfo &bi = static_cast<ButtonInfo&>(info);
|
ButtonInfo &bi = static_cast<ButtonInfo&>(info);
|
||||||
|
if (bi.id == "Update") {
|
||||||
|
gdi.getTabs().get(TAutoTab)->loadPage(gdi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == GUI_LINK) {
|
||||||
|
wstring url = L"http://localhost:" + itow(port) + L"/meos";
|
||||||
|
ShellExecute(NULL, L"open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,13 +23,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
|
||||||
#include <memory.h>
|
#include <memory>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <crtdbg.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
bool getUserFile(wchar_t *fileNamePath, const wchar_t *fileName);
|
bool getUserFile(wchar_t *fileNamePath, const wchar_t *fileName);
|
||||||
|
|||||||
@ -671,8 +671,11 @@ void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool c
|
|||||||
else if (type == IntervalSecond)
|
else if (type == IntervalSecond)
|
||||||
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):");
|
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):");
|
||||||
gdi.dropLine(1);
|
gdi.dropLine(1);
|
||||||
gdi.addButton(startCommand, "Starta automaten", AutomaticCB).setExtra(getId());
|
gdi.addButton(startCommand, created ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId());
|
||||||
gdi.addButton(created ? "Stop":"Cancel", "Avbryt", AutomaticCB).setExtra(getId());
|
if (!created)
|
||||||
|
gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
|
gdi.addButton("Stop", created ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
|
|||||||
@ -1325,6 +1325,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
DWORD cid=ClassId;
|
DWORD cid=ClassId;
|
||||||
|
pClass pc = oe->getClass(cid);
|
||||||
DrawMethod method = DrawMethod(gdi.getSelectedItem("Method").first);
|
DrawMethod method = DrawMethod(gdi.getSelectedItem("Method").first);
|
||||||
|
|
||||||
int interval = 0;
|
int interval = 0;
|
||||||
@ -1339,6 +1340,8 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
if (gdi.hasField("Leg")) {
|
if (gdi.hasField("Leg")) {
|
||||||
leg = gdi.getSelectedItem("Leg").first;
|
leg = gdi.getSelectedItem("Leg").first;
|
||||||
}
|
}
|
||||||
|
else if (pc && pc->getParentClass() != 0)
|
||||||
|
leg = -1;
|
||||||
|
|
||||||
wstring bib;
|
wstring bib;
|
||||||
bool doBibs = false;
|
bool doBibs = false;
|
||||||
@ -1536,6 +1539,19 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
setMultiDayClass(gdi, gdi.isChecked(bi.id), lastDrawMethod);
|
setMultiDayClass(gdi, gdi.isChecked(bi.id), lastDrawMethod);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (bi.id == "QualificationFinal") {
|
||||||
|
save(gdi, true);
|
||||||
|
pClass pc = oe->getClass(ClassId);
|
||||||
|
if (!pc)
|
||||||
|
throw std::exception("Class not found");
|
||||||
|
|
||||||
|
vector< pair<wstring, wstring> > ext;
|
||||||
|
ext.push_back(make_pair(L"Qualfication/Final", L"*.xml"));
|
||||||
|
wstring fileName = gdi.browseForOpen(ext, L"xml");
|
||||||
|
pc->loadQualificationFinalScheme(fileName);
|
||||||
|
pc->updateFinalClasses(0, true);
|
||||||
|
loadPage(gdi);
|
||||||
|
}
|
||||||
else if (bi.id=="Bibs") {
|
else if (bi.id=="Bibs") {
|
||||||
save(gdi, true);
|
save(gdi, true);
|
||||||
if (!checkClassSelected(gdi))
|
if (!checkClassSelected(gdi))
|
||||||
@ -1572,7 +1588,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
gdi.selectItemByData("BibSettings", bt);
|
gdi.selectItemByData("BibSettings", bt);
|
||||||
wstring bib = pc->getDCI().getString("Bib");
|
wstring bib = pc->getDCI().getString("Bib");
|
||||||
|
|
||||||
if (pc->getNumDistinctRunners() > 1) {
|
if (pc->getNumDistinctRunners() > 1 || pc->getQualificationFinal()) {
|
||||||
bibTeamOptions.push_back(make_pair(lang.tl("Oberoende"), BibFree));
|
bibTeamOptions.push_back(make_pair(lang.tl("Oberoende"), BibFree));
|
||||||
bibTeamOptions.push_back(make_pair(lang.tl("Samma"), BibSame));
|
bibTeamOptions.push_back(make_pair(lang.tl("Samma"), BibSame));
|
||||||
bibTeamOptions.push_back(make_pair(lang.tl("Ökande"), BibAdd));
|
bibTeamOptions.push_back(make_pair(lang.tl("Ökande"), BibAdd));
|
||||||
@ -1620,16 +1636,16 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
|
|
||||||
AutoBibType bt = AutoBibType(gdi.getSelectedItem("BibSettings").first);
|
AutoBibType bt = AutoBibType(gdi.getSelectedItem("BibSettings").first);
|
||||||
|
|
||||||
pair<int, bool> teamBib = gdi.getSelectedItem("TeamBib");
|
pair<int, bool> teamBib = gdi.getSelectedItem("BibTeam");
|
||||||
if (teamBib.second) {
|
if (teamBib.second) {
|
||||||
pc->setBibMode(BibMode(teamBib.first));
|
pc->setBibMode(BibMode(teamBib.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
pc->getDI().setString("Bib", getBibCode(bt, gdi.getText("Bib")));
|
pc->getDI().setString("Bib", getBibCode(bt, gdi.getText("Bib")));
|
||||||
pc->synchronize();
|
pc->synchronize();
|
||||||
|
int leg = pc->getParentClass() ? -1 : 0;
|
||||||
if (bt == AutoBibManual) {
|
if (bt == AutoBibManual) {
|
||||||
oe->addBib(cid, 0, gdi.getText("Bib"));
|
oe->addBib(cid, leg, gdi.getText("Bib"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
oe->setBibClassGap(gdi.getTextNo("BibGap"));
|
oe->setBibClassGap(gdi.getTextNo("BibGap"));
|
||||||
@ -1644,7 +1660,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
par.selection.insert(cid);
|
par.selection.insert(cid);
|
||||||
oListInfo info;
|
oListInfo info;
|
||||||
par.listCode = EStdStartList;
|
par.listCode = EStdStartList;
|
||||||
par.setLegNumberCoded(0);
|
par.setLegNumberCoded(leg);
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||||
oe->generateList(gdi, false, info, true);
|
oe->generateList(gdi, false, info, true);
|
||||||
|
|
||||||
@ -2223,6 +2239,10 @@ void TabClass::selectClass(gdioutput &gdi, int cid)
|
|||||||
if (gdi.hasField("DirectResult"))
|
if (gdi.hasField("DirectResult"))
|
||||||
gdi.check("DirectResult", false);
|
gdi.check("DirectResult", false);
|
||||||
|
|
||||||
|
if (gdi.hasField("LockStartList")) {
|
||||||
|
gdi.check("LockStartList", false);
|
||||||
|
gdi.setInputStatus("LockStartList", false);
|
||||||
|
}
|
||||||
gdi.check("NoTiming", false);
|
gdi.check("NoTiming", false);
|
||||||
|
|
||||||
ClassId=cid;
|
ClassId=cid;
|
||||||
@ -2274,6 +2294,11 @@ void TabClass::selectClass(gdioutput &gdi, int cid)
|
|||||||
if (gdi.hasField("DirectResult"))
|
if (gdi.hasField("DirectResult"))
|
||||||
gdi.check("DirectResult", pc->hasDirectResult());
|
gdi.check("DirectResult", pc->hasDirectResult());
|
||||||
|
|
||||||
|
if (gdi.hasField("LockStartList")) {
|
||||||
|
bool active = pc->getParentClass() != 0;
|
||||||
|
gdi.setInputStatus("LockStartList", active);
|
||||||
|
gdi.check("LockStartList", active && pc->lockedClassAssignment());
|
||||||
|
}
|
||||||
ClassId=cid;
|
ClassId=cid;
|
||||||
|
|
||||||
if (pc->hasTrueMultiCourse()) {
|
if (pc->hasTrueMultiCourse()) {
|
||||||
@ -2344,9 +2369,10 @@ void TabClass::selectClass(gdioutput &gdi, int cid)
|
|||||||
pCourse pcourse = pc->getCourse();
|
pCourse pcourse = pc->getCourse();
|
||||||
gdi.selectItemByData("Courses", pcourse ? pcourse->getId():-2);
|
gdi.selectItemByData("Courses", pcourse ? pcourse->getId():-2);
|
||||||
}
|
}
|
||||||
|
if (gdi.hasField("QualificationFinal"))
|
||||||
|
gdi.setInputStatus("QualificationFinal", pc->getParentClass() == 0);
|
||||||
|
|
||||||
gdi.selectItemByData("Classes", cid);
|
gdi.selectItemByData("Classes", cid);
|
||||||
|
|
||||||
ClassId=cid;
|
ClassId=cid;
|
||||||
EditChanged=false;
|
EditChanged=false;
|
||||||
}
|
}
|
||||||
@ -2672,6 +2698,12 @@ void TabClass::save(gdioutput &gdi, bool skipReload)
|
|||||||
pc->setDirectResult(withDirect);
|
pc->setDirectResult(withDirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gdi.hasField("LockStartList")) {
|
||||||
|
bool locked = gdi.isChecked("LockStartList");
|
||||||
|
if (pc->getParentClass())
|
||||||
|
pc->lockedClassAssignment(locked);
|
||||||
|
}
|
||||||
|
|
||||||
int crs = gdi.getSelectedItem("Courses").first;
|
int crs = gdi.getSelectedItem("Courses").first;
|
||||||
|
|
||||||
if (crs==0) {
|
if (crs==0) {
|
||||||
@ -2893,11 +2925,28 @@ bool TabClass::loadPage(gdioutput &gdi)
|
|||||||
|
|
||||||
gdi.addCheckbox("DirectResult", "Resultat vid målstämpling", 0, false,
|
gdi.addCheckbox("DirectResult", "Resultat vid målstämpling", 0, false,
|
||||||
"help:DirectResult");
|
"help:DirectResult");
|
||||||
|
|
||||||
}
|
}
|
||||||
gdi.dropLine(2);
|
gdi.dropLine(2);
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<pClass> pcls;
|
||||||
|
oe->getClasses(pcls, false);
|
||||||
|
bool hasCF = false;
|
||||||
|
for (pClass pc : pcls) {
|
||||||
|
if (pc->getQualificationFinal()) {
|
||||||
|
hasCF = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasCF) {
|
||||||
|
gdi.addCheckbox("LockStartList", "Lås startlista", 0, false,
|
||||||
|
"help:LockStartList");
|
||||||
|
|
||||||
|
gdi.dropLine(2);
|
||||||
|
gdi.popX();
|
||||||
|
}
|
||||||
|
}
|
||||||
vector<ButtonData> func;
|
vector<ButtonData> func;
|
||||||
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::DrawStartList))
|
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::DrawStartList))
|
||||||
func.push_back(ButtonData("Draw", "Lotta / starttider...", false));
|
func.push_back(ButtonData("Draw", "Lotta / starttider...", false));
|
||||||
@ -2960,6 +3009,9 @@ bool TabClass::loadPage(gdioutput &gdi)
|
|||||||
|
|
||||||
func.push_back(ButtonData("QuickSettings", "Snabbinställningar", true));
|
func.push_back(ButtonData("QuickSettings", "Snabbinställningar", true));
|
||||||
|
|
||||||
|
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces))
|
||||||
|
func.push_back(ButtonData("QualificationFinal", "Kval-Final-Schema", false));
|
||||||
|
|
||||||
RECT funRect;
|
RECT funRect;
|
||||||
funRect.right = gdi.getCX() - 7;
|
funRect.right = gdi.getCX() - 7;
|
||||||
funRect.top = gdi.getCY() - 2;
|
funRect.top = gdi.getCY() - 2;
|
||||||
@ -3216,7 +3268,7 @@ void TabClass::drawDialog(gdioutput &gdi, DrawMethod method, const oClass &pc) {
|
|||||||
if (method != DMSimultaneous)
|
if (method != DMSimultaneous)
|
||||||
gdi.addInput("Interval", formatTime(interval), 10, 0, L"Startintervall (min):").setSynchData(&lastInterval);
|
gdi.addInput("Interval", formatTime(interval), 10, 0, L"Startintervall (min):").setSynchData(&lastInterval);
|
||||||
|
|
||||||
if (method == DMRandom || method == DMSOFT || method == DMClumped)
|
if (method == DMRandom || method == DMSOFT || method == DMClumped && pc.getParentClass() == 0)
|
||||||
gdi.addInput("Vacanses", itow(vac), 10, 0, L"Antal vakanser:").setSynchData(&lastNumVac);
|
gdi.addInput("Vacanses", itow(vac), 10, 0, L"Antal vakanser:").setSynchData(&lastNumVac);
|
||||||
|
|
||||||
if ((method == DMRandom || method == DMSOFT || method == DMSeeded) && pc.getNumStages() > 1 && pc.getClassType() != oClassPatrol) {
|
if ((method == DMRandom || method == DMSOFT || method == DMSeeded) && pc.getNumStages() > 1 && pc.getClassType() != oClassPatrol) {
|
||||||
@ -3765,7 +3817,7 @@ void TabClass::getClassSettingsTable(gdioutput &gdi, GUICALLBACK cb) {
|
|||||||
else
|
else
|
||||||
gdi.setText("Bib"+ id, bib);
|
gdi.setText("Bib"+ id, bib);
|
||||||
|
|
||||||
if (useTeam && it->getNumDistinctRunners() > 1) {
|
if (useTeam && (it->getNumDistinctRunners() > 1 || it->getQualificationFinal())) {
|
||||||
gdi.addSelection(et, cyp, "BibTeam" + id, 80, 100, 0, L"", L"Ange relation mellan lagets och deltagarnas nummerlappar.");
|
gdi.addSelection(et, cyp, "BibTeam" + id, 80, 100, 0, L"", L"Ange relation mellan lagets och deltagarnas nummerlappar.");
|
||||||
gdi.addItem("BibTeam" + id, bibTeamOptions);
|
gdi.addItem("BibTeam" + id, bibTeamOptions);
|
||||||
gdi.selectItemByData("BibTeam" + id, it->getBibMode());
|
gdi.selectItemByData("BibTeam" + id, it->getBibMode());
|
||||||
|
|||||||
@ -528,7 +528,7 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
|||||||
else
|
else
|
||||||
fee = di.getInt("Fee");
|
fee = di.getInt("Fee");
|
||||||
|
|
||||||
wstring info = filtered[k]->getClass() + L", " + filtered[k]->getCompleteIdentification();
|
wstring info = filtered[k]->getClass(false) + L", " + filtered[k]->getCompleteIdentification();
|
||||||
|
|
||||||
gdi.addStringUT(0, info + L" (" + oe->formatCurrency(fee) + L")");
|
gdi.addStringUT(0, info + L" (" + oe->formatCurrency(fee) + L")");
|
||||||
if (count % 5 == 0)
|
if (count % 5 == 0)
|
||||||
|
|||||||
@ -119,13 +119,14 @@ bool TabCompetition::save(gdioutput &gdi, bool write)
|
|||||||
gdi.setText("Date", oe->getDate());
|
gdi.setText("Date", oe->getDate());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bool updateTimes = newZT != oldZT && oe->getNumRunners() > 0 && gdi.ask(L"ask:updatetimes");
|
bool updateTimes = newZT != oldZT && oe->getNumRunners() > 0 && gdi.ask(L"ask:updatetimes");
|
||||||
|
|
||||||
if (updateTimes) {
|
if (updateTimes) {
|
||||||
int delta = oldZT - newZT;
|
int delta = oldZT - newZT;
|
||||||
oe->updateStartTimes(delta);
|
oe->updateStartTimes(delta);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
oe->setDate(date);
|
oe->setDate(date);
|
||||||
oe->useLongTimes(longTimes);
|
oe->useLongTimes(longTimes);
|
||||||
oe->setName(gdi.getText("Name"));
|
oe->setName(gdi.getText("Name"));
|
||||||
@ -3228,7 +3229,7 @@ void TabCompetition::welcomeToMeOS(gdioutput &gdi) {
|
|||||||
|
|
||||||
void TabCompetition::displayRunners(gdioutput &gdi, const vector<pRunner> &changedClass) const {
|
void TabCompetition::displayRunners(gdioutput &gdi, const vector<pRunner> &changedClass) const {
|
||||||
for (size_t k = 0; k<changedClass.size(); k++) {
|
for (size_t k = 0; k<changedClass.size(); k++) {
|
||||||
gdi.addStringUT(0, changedClass[k]->getName() + L" (" + changedClass[k]->getClass() + L", " +
|
gdi.addStringUT(0, changedClass[k]->getName() + L" (" + changedClass[k]->getClass(true) + L", " +
|
||||||
changedClass[k]->getStartTimeS() + L")");
|
changedClass[k]->getStartTimeS() + L")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3991,7 +3992,7 @@ void TabCompetition::checkReadyForResultExport(gdioutput &gdi, const set<int> &c
|
|||||||
int numVacant = 0;
|
int numVacant = 0;
|
||||||
|
|
||||||
for (pRunner r : runners) {
|
for (pRunner r : runners) {
|
||||||
if (!classFilter.empty() && !classFilter.count(r->getClassId()))
|
if (!classFilter.empty() && !classFilter.count(r->getClassId(false)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (r->isVacant())
|
if (r->isVacant())
|
||||||
|
|||||||
192
code/TabList.cpp
192
code/TabList.cpp
@ -601,7 +601,6 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
lastSplitState = par.showSplitTimes;
|
lastSplitState = par.showSplitTimes;
|
||||||
lastLargeSize = par.useLargeSize;
|
lastLargeSize = par.useLargeSize;
|
||||||
|
|
||||||
|
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
|
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
@ -635,10 +634,8 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
oListParam par;
|
oListParam par;
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
|
getResultIndividual(par, cnf);
|
||||||
cnf.getIndividual(par.selection);
|
cnf.getIndividual(par.selection);
|
||||||
par.listCode = EStdResultList;
|
|
||||||
par.showInterTimes = true;
|
|
||||||
par.setLegNumberCoded(-1);
|
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
|
|
||||||
@ -667,12 +664,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="StartIndividual") {
|
else if (bi.id=="StartIndividual") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.listCode = EStdStartList;
|
|
||||||
par.setLegNumberCoded(-1);
|
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getIndividual(par.selection);
|
getStartIndividual(par, cnf);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
currentList.setCallback(openRunnerTeamCB);
|
currentList.setCallback(openRunnerTeamCB);
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
@ -681,33 +676,22 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="StartClub") {
|
else if (bi.id=="StartClub") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.listCode = EStdClubStartList;
|
getStartClub(par);
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
par.setLegNumberCoded(-1);
|
|
||||||
ClassConfigInfo cnf;
|
|
||||||
oe->getClassConfigurationInfo(cnf);
|
|
||||||
//cnf.getIndividual(par.selection);
|
|
||||||
//cnf.getPatrol(par.selection);
|
|
||||||
|
|
||||||
// oListInfo foo = currentList;
|
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
currentList.setCallback(openRunnerTeamCB);
|
currentList.setCallback(openRunnerTeamCB);
|
||||||
//currentList.addList(foo);
|
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
else if (bi.id=="ResultClub") {
|
else if (bi.id=="ResultClub") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.listCode = EStdClubResultList;
|
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
par.setLegNumberCoded(-1);
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getIndividual(par.selection);
|
getResultClub(par, cnf);
|
||||||
cnf.getPatrol(par.selection);
|
|
||||||
|
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
currentList.setCallback(openRunnerTeamCB);
|
currentList.setCallback(openRunnerTeamCB);
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
@ -735,12 +719,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="TeamStartList") {
|
else if (bi.id=="TeamStartList") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.listCode = EStdTeamStartList;
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getRelay(par.selection);
|
getStartTeam(par, cnf);
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
par.setLegNumberCoded(0);
|
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
currentList.setCallback(openRunnerTeamCB);
|
currentList.setCallback(openRunnerTeamCB);
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
@ -779,11 +761,10 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="PatrolStartList") {
|
else if (bi.id=="PatrolStartList") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.listCode = EStdPatrolStartList;
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getPatrol(par.selection);
|
getStartPatrol(par, cnf);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
currentList.setCallback(openRunnerTeamCB);
|
currentList.setCallback(openRunnerTeamCB);
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
@ -792,15 +773,12 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="TeamResults") {
|
else if (bi.id=="TeamResults") {
|
||||||
oe->sanityCheck(gdi, true);
|
oe->sanityCheck(gdi, true);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
par.listCode = EStdTeamResultListAll;
|
|
||||||
|
|
||||||
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
|
||||||
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getRelay(par.selection);
|
getResultTeam(par, cnf);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
|
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
generateList(gdi);
|
generateList(gdi);
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
@ -823,7 +801,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
oListParam par;
|
oListParam par;
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
int race = int(bi.getExtra());
|
int race = bi.getExtraInt();
|
||||||
par.setLegNumberCoded(race);
|
par.setLegNumberCoded(race);
|
||||||
par.listCode = EStdIndMultiResultListLeg;
|
par.listCode = EStdIndMultiResultListLeg;
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
@ -854,13 +832,11 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="PatrolResultList") {
|
else if (bi.id=="PatrolResultList") {
|
||||||
oe->sanityCheck(gdi, false);
|
oe->sanityCheck(gdi, false);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
par.listCode = EStdPatrolResultList;
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getPatrol(par.selection);
|
getResultPatrol(par, cnf);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
||||||
|
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
@ -871,13 +847,11 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id=="RogainingResultList") {
|
else if (bi.id=="RogainingResultList") {
|
||||||
oe->sanityCheck(gdi, true);
|
oe->sanityCheck(gdi, true);
|
||||||
oListParam par;
|
oListParam par;
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
par.listCode = ERogainingInd;
|
|
||||||
ClassConfigInfo cnf;
|
ClassConfigInfo cnf;
|
||||||
oe->getClassConfigurationInfo(cnf);
|
oe->getClassConfigurationInfo(cnf);
|
||||||
cnf.getRogaining(par.selection);
|
getResultRogaining(par, cnf);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
||||||
|
|
||||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||||
@ -2420,3 +2394,127 @@ void TabList::setAnimationMode(gdioutput &gdi) {
|
|||||||
gdi.setAnimationMode(make_shared<AnimationData>(gdi, par.timePerPage, par.nColumns,
|
gdi.setAnimationMode(make_shared<AnimationData>(gdi, par.timePerPage, par.nColumns,
|
||||||
par.margin, par.animate));
|
par.margin, par.animate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabList::getStartIndividual(oListParam &par, ClassConfigInfo &cnf){
|
||||||
|
par.listCode = EStdStartList;
|
||||||
|
par.setLegNumberCoded(-1);
|
||||||
|
cnf.getIndividual(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getStartClub(oListParam &par) {
|
||||||
|
par.listCode = EStdClubStartList;
|
||||||
|
par.setLegNumberCoded(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getResultIndividual(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
cnf.getIndividual(par.selection);
|
||||||
|
par.listCode = EStdResultList;
|
||||||
|
par.showInterTimes = true;
|
||||||
|
par.setLegNumberCoded(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getResultClub(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = EStdClubResultList;
|
||||||
|
par.setLegNumberCoded(-1);
|
||||||
|
cnf.getIndividual(par.selection);
|
||||||
|
cnf.getPatrol(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getStartPatrol(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = EStdPatrolStartList;
|
||||||
|
cnf.getPatrol(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getResultPatrol(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = EStdPatrolResultList;
|
||||||
|
cnf.getPatrol(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getStartTeam(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = EStdTeamStartList;
|
||||||
|
cnf.getRelay(par.selection);
|
||||||
|
par.setLegNumberCoded(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getResultTeam(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = EStdTeamResultListAll;
|
||||||
|
cnf.getRelay(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getResultRogaining(oListParam &par, ClassConfigInfo &cnf) {
|
||||||
|
par.listCode = ERogainingInd;
|
||||||
|
cnf.getRogaining(par.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabList::getPublicLists(oEvent &oe, vector<oListParam> &lists) {
|
||||||
|
lists.clear();
|
||||||
|
|
||||||
|
ClassConfigInfo cnf;
|
||||||
|
oe.getClassConfigurationInfo(cnf);
|
||||||
|
if (!cnf.empty()) {
|
||||||
|
if (cnf.hasIndividual()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getStartIndividual(lists.back(), cnf);
|
||||||
|
|
||||||
|
if (oe.getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getStartClub(lists.back());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf.hasRelay()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getStartTeam(lists.back(), cnf);
|
||||||
|
}
|
||||||
|
if (cnf.hasPatrol()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getStartPatrol(lists.back(), cnf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf.isMultiStageEvent()) {
|
||||||
|
//gdi.addButton("StartL:inputresult", "Input Results", ListsCB);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf.hasIndividual()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getResultIndividual(lists.back(), cnf);
|
||||||
|
if (oe.getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getResultClub(lists.back(), cnf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//gdi.addButton("ResultIndSplit", "Sträcktider", ListsCB);
|
||||||
|
|
||||||
|
if (cnf.isMultiStageEvent()) {
|
||||||
|
//gdi.addButton("Result:stageresult", "Etappresultat", ListsCB);
|
||||||
|
|
||||||
|
//gdi.addButton("Result:finalresult", "Slutresultat", ListsCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cnf.hasRelay()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getResultTeam(lists.back(), cnf);
|
||||||
|
}
|
||||||
|
if (cnf.hasPatrol()) {
|
||||||
|
lists.push_back(oListParam());
|
||||||
|
getResultPatrol(lists.back(), cnf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf.hasRogaining()) {
|
||||||
|
//gdi.addButton("Result:rogainingind", "Rogaining", ListsCB).setExtra(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaListContainer &lc = oe.getListContainer();
|
||||||
|
|
||||||
|
vector< pair<wstring, size_t> > savedParams;
|
||||||
|
lc.getListParam(savedParams);
|
||||||
|
for (auto &p : savedParams) {
|
||||||
|
oListParam &par = lc.getParam(p.second);
|
||||||
|
lists.push_back(par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf.hasIndividual()) {
|
||||||
|
//gdi.addButton("PriceList", "Prisutdelningslista", ListsCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -87,7 +87,25 @@ private:
|
|||||||
|
|
||||||
/** Set animation mode*/
|
/** Set animation mode*/
|
||||||
void setAnimationMode(gdioutput &gdi);
|
void setAnimationMode(gdioutput &gdi);
|
||||||
|
|
||||||
|
static void getStartIndividual(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
static void getStartClub(oListParam &par);
|
||||||
|
static void getResultIndividual(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
static void getResultClub(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
|
||||||
|
static void getStartPatrol(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
static void getResultPatrol(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
|
||||||
|
static void getStartTeam(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
static void getResultTeam(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
|
||||||
|
static void getResultRogaining(oListParam &par, ClassConfigInfo &cnf);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** Returns a collection of public lists. */
|
||||||
|
void static getPublicLists(oEvent &oe, vector<oListParam> &lists);
|
||||||
|
|
||||||
bool loadPage(gdioutput &gdi);
|
bool loadPage(gdioutput &gdi);
|
||||||
bool loadPage(gdioutput &gdi, const string &command);
|
bool loadPage(gdioutput &gdi, const string &command);
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ void TabRunner::enableControlButtons(gdioutput &gdi, bool enable, bool vacant)
|
|||||||
|
|
||||||
void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
||||||
if (!r) {
|
if (!r) {
|
||||||
runnerId=0;
|
runnerId = 0;
|
||||||
gdi.setText("Name", L"");
|
gdi.setText("Name", L"");
|
||||||
gdi.setText("Bib", L"");
|
gdi.setText("Bib", L"");
|
||||||
gdi.selectItemByData("RCourse", 0);
|
gdi.selectItemByData("RCourse", 0);
|
||||||
@ -158,7 +158,7 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
gdi.enableEditControls(true);
|
gdi.enableEditControls(true);
|
||||||
disablePunchCourse(gdi);
|
disablePunchCourse(gdi);
|
||||||
|
|
||||||
pRunner parent=r->getMultiRunner(0);
|
pRunner parent = r->getMultiRunner(0);
|
||||||
|
|
||||||
r->synchronizeAll();
|
r->synchronizeAll();
|
||||||
//r->apply(false);
|
//r->apply(false);
|
||||||
@ -172,14 +172,14 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
|
|
||||||
gdi.selectItemByData("Runners", parent->getId());
|
gdi.selectItemByData("Runners", parent->getId());
|
||||||
|
|
||||||
runnerId=r->getId();
|
runnerId = r->getId();
|
||||||
|
|
||||||
gdi.setText("Name", r->getNameRaw());
|
gdi.setText("Name", r->getNameRaw());
|
||||||
wstring bib = r->getBib();
|
wstring bib = r->getBib();
|
||||||
|
|
||||||
if (gdi.hasField("Bib")) {
|
if (gdi.hasField("Bib")) {
|
||||||
gdi.setText("Bib", bib);
|
gdi.setText("Bib", bib);
|
||||||
bool controlBib = r->getTeam() == 0 || (r->getClassRef() && r->getClassRef()->getBibMode() == BibFree);
|
bool controlBib = r->getTeam() == 0 || (r->getClassRef(true) && r->getClassRef(true)->getBibMode() == BibFree);
|
||||||
gdi.setInputStatus("Bib", controlBib);
|
gdi.setInputStatus("Bib", controlBib);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,10 +187,10 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
|
|
||||||
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
||||||
gdi.addItem("RClass", lang.tl("Ingen klass"), 0);
|
gdi.addItem("RClass", lang.tl("Ingen klass"), 0);
|
||||||
gdi.selectItemByData("RClass", r->getClassId());
|
gdi.selectItemByData("RClass", r->getClassId(true));
|
||||||
|
|
||||||
if (gdi.hasField("EditTeam")) {
|
if (gdi.hasField("EditTeam")) {
|
||||||
gdi.setInputStatus("EditTeam", r->getTeam()!=0);
|
gdi.setInputStatus("EditTeam", r->getTeam() != 0);
|
||||||
|
|
||||||
if (r->getTeam()) {
|
if (r->getTeam()) {
|
||||||
gdi.setText("Team", r->getTeam()->getName());
|
gdi.setText("Team", r->getTeam()->getName());
|
||||||
@ -217,19 +217,19 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
r->getLegPlacesAcc(placeAcc);
|
r->getLegPlacesAcc(placeAcc);
|
||||||
|
|
||||||
wstring out;
|
wstring out;
|
||||||
for (size_t k = 0; k<delta.size(); k++) {
|
for (size_t k = 0; k < delta.size(); k++) {
|
||||||
out += itow(place[k]);
|
out += itow(place[k]);
|
||||||
if (k<placeAcc.size())
|
if (k < placeAcc.size())
|
||||||
out += L" (" + itow(placeAcc[k]) + L")";
|
out += L" (" + itow(placeAcc[k]) + L")";
|
||||||
|
|
||||||
if (after[k]>0)
|
if (after[k] > 0)
|
||||||
out+= L" +" + getTimeMS(after[k]);
|
out += L" +" + getTimeMS(after[k]);
|
||||||
|
|
||||||
if (k<afterAcc.size() && afterAcc[k]>0)
|
if (k < afterAcc.size() && afterAcc[k]>0)
|
||||||
out+= L" (+" + getTimeMS(afterAcc[k]) + L")";
|
out += L" (+" + getTimeMS(afterAcc[k]) + L")";
|
||||||
|
|
||||||
if (delta[k]>0)
|
if (delta[k] > 0)
|
||||||
out+= L" B: " + getTimeMS(delta[k]);
|
out += L" B: " + getTimeMS(delta[k]);
|
||||||
|
|
||||||
out += L" | ";
|
out += L" | ";
|
||||||
|
|
||||||
@ -241,18 +241,18 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gdi.hasField("MultiR")) {
|
if (gdi.hasField("MultiR")) {
|
||||||
int numMulti=parent->getNumMulti();
|
int numMulti = parent->getNumMulti();
|
||||||
if (numMulti==0) {
|
if (numMulti == 0) {
|
||||||
gdi.clearList("MultiR");
|
gdi.clearList("MultiR");
|
||||||
gdi.disableInput("MultiR");
|
gdi.disableInput("MultiR");
|
||||||
lastRace=0;
|
lastRace = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gdi.clearList("MultiR");
|
gdi.clearList("MultiR");
|
||||||
gdi.enableInput("MultiR");
|
gdi.enableInput("MultiR");
|
||||||
|
|
||||||
for (int k=0;k<numMulti+1;k++) {
|
for (int k = 0; k < numMulti + 1; k++) {
|
||||||
gdi.addItem("MultiR", lang.tl("Lopp X#" + itos(k+1)), k);
|
gdi.addItem("MultiR", lang.tl("Lopp X#" + itos(k + 1)), k);
|
||||||
}
|
}
|
||||||
gdi.selectItemByData("MultiR", r->getRaceNo());
|
gdi.selectItemByData("MultiR", r->getRaceNo());
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
updateNumShort(gdi, r->getCourse(false), r);
|
updateNumShort(gdi, r->getCourse(false), r);
|
||||||
|
|
||||||
int cno = parent->getCardNo();
|
int cno = parent->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);
|
||||||
|
|
||||||
@ -316,9 +316,9 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
gdi.setText("PointIn", r->getInputPoints());
|
gdi.setText("PointIn", r->getInputPoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
pCard pc=r->getCard();
|
pCard pc = r->getCard();
|
||||||
|
|
||||||
pCourse pcourse=r->getCourse(true);
|
pCourse pcourse = r->getCourse(true);
|
||||||
|
|
||||||
if (pc) {
|
if (pc) {
|
||||||
gdi.setTabStops("Punches", 70);
|
gdi.setTabStops("Punches", 70);
|
||||||
@ -337,6 +337,12 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
gdi.clearList("Course");
|
gdi.clearList("Course");
|
||||||
gdi.disableInput("AddAllC");
|
gdi.disableInput("AddAllC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
||||||
|
if (gdi_settings) {
|
||||||
|
TabRunner &dst = dynamic_cast<TabRunner&>(*gdi_settings->getTabs().get(TabType::TRunnerTab));
|
||||||
|
dst.loadEconomy(*gdi_settings, *r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RunnerCB(gdioutput *gdi, int type, void *data)
|
int RunnerCB(gdioutput *gdi, int type, void *data)
|
||||||
@ -579,6 +585,12 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
|
|||||||
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")));
|
||||||
|
|
||||||
|
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
||||||
|
if (gdi_settings) {
|
||||||
|
TabRunner &dst = dynamic_cast<TabRunner&>(*gdi_settings->getTabs().get(TabType::TRunnerTab));
|
||||||
|
dst.getEconomyHandler(*r)->save(*gdi_settings);
|
||||||
|
}
|
||||||
|
|
||||||
r->setStartTimeS(gdi.getText("Start"));
|
r->setStartTimeS(gdi.getText("Start"));
|
||||||
r->setFinishTimeS(gdi.getText("Finish"));
|
r->setFinishTimeS(gdi.getText("Finish"));
|
||||||
|
|
||||||
@ -608,14 +620,14 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
|
|||||||
gdi.alert("För att delta i en lagklass måste deltagaren ingå i ett lag.");
|
gdi.alert("För att delta i en lagklass måste deltagaren ingå i ett lag.");
|
||||||
classId = 0;
|
classId = 0;
|
||||||
}
|
}
|
||||||
else if (r->getTeam()->getClassId() != classId && r->getClassId() != classId) {
|
else if (r->getTeam()->getClassId(true) != classId && r->getClassId(true) != classId) {
|
||||||
gdi.alert("Deltagarens klass styrs av laget.");
|
gdi.alert("Deltagarens klass styrs av laget.");
|
||||||
classId = r->getTeam()->getClassId();
|
classId = r->getTeam()->getClassId(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readStatusIn = true;
|
bool readStatusIn = true;
|
||||||
if (r->getClassId() != classId && r->getInputStatus() != StatusNotCompetiting && r->hasInputData()) {
|
if (r->getClassId(true) != classId && r->getInputStatus() != StatusNotCompetiting && r->hasInputData()) {
|
||||||
if (gdi.ask(L"Vill du sätta resultatet från tidigare etapper till <Deltar ej>?")) {
|
if (gdi.ask(L"Vill du sätta resultatet från tidigare etapper till <Deltar ej>?")) {
|
||||||
r->resetInputData();
|
r->resetInputData();
|
||||||
readStatusIn = false;
|
readStatusIn = false;
|
||||||
@ -635,7 +647,7 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
|
|||||||
vector<int> mp;
|
vector<int> mp;
|
||||||
r->evaluateCard(true, mp, 0, true);
|
r->evaluateCard(true, mp, 0, true);
|
||||||
|
|
||||||
if (r->getClassId() != classId) {
|
if (r->getClassId(true) != classId) {
|
||||||
gdi.alert("Deltagarens klass styrs av laget.");
|
gdi.alert("Deltagarens klass styrs av laget.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,11 +664,14 @@ pRunner TabRunner::save(gdioutput &gdi, int runnerId, bool willExit) {
|
|||||||
|
|
||||||
r->synchronizeAll();
|
r->synchronizeAll();
|
||||||
|
|
||||||
if (r->getClassRef() && r->getClassRef()->hasClassGlobalDependance()) {
|
if (r->getClassRef(false) && r->getClassRef(false)->hasClassGlobalDependence()) {
|
||||||
set<int> cls;
|
set<int> cls;
|
||||||
cls.insert(r->getClassId());
|
cls.insert(r->getClassId(false));
|
||||||
oe->reEvaluateAll(cls, false);
|
oe->reEvaluateAll(cls, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r->getClassRef(false))
|
||||||
|
r->getClassRef(false)->updateFinalClasses(r, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
runnerId=0;
|
runnerId=0;
|
||||||
@ -938,9 +953,11 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
if (!runnerId)
|
if (!runnerId)
|
||||||
return 0;
|
return 0;
|
||||||
pRunner r = oe->getRunner(runnerId, 0);
|
pRunner r = oe->getRunner(runnerId, 0);
|
||||||
gdioutput *settings = createExtraWindow("ecosettings", L"Economy for X#" + r->getName(), 400, 200);
|
if (getExtraWindow("ecosettings", true) == 0) {
|
||||||
|
gdioutput *settings = createExtraWindow("ecosettings", L"Economy", 550, 350);
|
||||||
|
TabRunner &dst = dynamic_cast<TabRunner&>(*settings->getTabs().get(TabType::TRunnerTab));
|
||||||
|
dst.loadEconomy(*settings, *r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (bi.id=="NoStart") {
|
else if (bi.id=="NoStart") {
|
||||||
if (!runnerId)
|
if (!runnerId)
|
||||||
@ -950,7 +967,7 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
|
|
||||||
if (r && gdi.ask(L"Bekräfta att deltagaren har lämnat återbud.")) {
|
if (r && gdi.ask(L"Bekräfta att deltagaren har lämnat återbud.")) {
|
||||||
if (r->getStartTime()>0) {
|
if (r->getStartTime()>0) {
|
||||||
pRunner newRunner = oe->addRunnerVacant(r->getClassId());
|
pRunner newRunner = oe->addRunnerVacant(r->getClassId(true));
|
||||||
newRunner->cloneStartTime(r);
|
newRunner->cloneStartTime(r);
|
||||||
newRunner->setStartNo(r->getStartNo(), false);
|
newRunner->setStartNo(r->getStartNo(), false);
|
||||||
if (r->getCourseId())
|
if (r->getCourseId())
|
||||||
@ -1045,12 +1062,18 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
if (gdi.isInputChanged("")) {
|
if (gdi.isInputChanged("")) {
|
||||||
pRunner r = oe->getRunner(runnerId, 0);
|
pRunner r = oe->getRunner(runnerId, 0);
|
||||||
bool newName = r && r->getName() != gdi.getText("Name");
|
bool newName = r && r->getName() != gdi.getText("Name");
|
||||||
|
|
||||||
save(gdi, runnerId, true);
|
save(gdi, runnerId, true);
|
||||||
|
|
||||||
if (newName)
|
if (newName)
|
||||||
fillRunnerList(gdi);
|
fillRunnerList(gdi);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
pRunner r = oe->getRunner(runnerId, 0);
|
||||||
|
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
||||||
|
if (gdi_settings) {
|
||||||
|
TabRunner &dst = dynamic_cast<TabRunner&>(*gdi_settings->getTabs().get(TabType::TRunnerTab));
|
||||||
|
dst.getEconomyHandler(*r)->save(*gdi_settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bi.data == -1) {
|
if (bi.data == -1) {
|
||||||
fillRunnerList(gdi);
|
fillRunnerList(gdi);
|
||||||
@ -1193,6 +1216,10 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type==GUI_CLEAR) {
|
else if (type==GUI_CLEAR) {
|
||||||
|
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
||||||
|
if (gdi_settings)
|
||||||
|
gdi_settings->closeWindow();
|
||||||
|
|
||||||
if (runnerId>0 && currentMode == 0)
|
if (runnerId>0 && currentMode == 0)
|
||||||
save(gdi, runnerId, true);
|
save(gdi, runnerId, true);
|
||||||
|
|
||||||
@ -1202,7 +1229,7 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
int id = static_cast<TextInfo*>(data)->getExtraInt();
|
int id = static_cast<TextInfo*>(data)->getExtraInt();
|
||||||
oRunner *vacancy = oe->getRunner(id, 0);
|
oRunner *vacancy = oe->getRunner(id, 0);
|
||||||
|
|
||||||
if (vacancy==0 || vacancy->getClassId()==0)
|
if (vacancy==0 || vacancy->getClassId(false)==0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pRunner r = oe->getRunner(runnerId, 0);
|
pRunner r = oe->getRunner(runnerId, 0);
|
||||||
@ -1215,7 +1242,7 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
|
|
||||||
wchar_t bf[1024];
|
wchar_t bf[1024];
|
||||||
swprintf_s(bf, lang.tl("Bekräfta att %s byter klass till %s.").c_str(),
|
swprintf_s(bf, lang.tl("Bekräfta att %s byter klass till %s.").c_str(),
|
||||||
r->getName().c_str(), vacancy->getClass().c_str());
|
r->getName().c_str(), vacancy->getClass(true).c_str());
|
||||||
if (gdi.ask(wstring(L"#") + bf)) {
|
if (gdi.ask(wstring(L"#") + bf)) {
|
||||||
|
|
||||||
vacancy->synchronize();
|
vacancy->synchronize();
|
||||||
@ -1226,11 +1253,11 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
temp.setTemporary();
|
temp.setTemporary();
|
||||||
temp.setBib(r->getBib(), 0, false, false);
|
temp.setBib(r->getBib(), 0, false, false);
|
||||||
temp.setStartNo(r->getStartNo(), false);
|
temp.setStartNo(r->getStartNo(), false);
|
||||||
temp.setClassId(r->getClassId(), true);
|
temp.setClassId(r->getClassId(true), true);
|
||||||
temp.apply(false, 0, false);
|
temp.apply(false, 0, false);
|
||||||
temp.cloneStartTime(r);
|
temp.cloneStartTime(r);
|
||||||
|
|
||||||
r->setClassId(vacancy->getClassId(), true);
|
r->setClassId(vacancy->getClassId(true), true);
|
||||||
// Remove or create multi runners
|
// Remove or create multi runners
|
||||||
r->createMultiRunner(true, true);
|
r->createMultiRunner(true, true);
|
||||||
r->apply(false, 0, false);
|
r->apply(false, 0, false);
|
||||||
@ -1243,7 +1270,7 @@ int TabRunner::runnerCB(gdioutput &gdi, int type, void *data)
|
|||||||
r->resetInputData();
|
r->resetInputData();
|
||||||
}
|
}
|
||||||
|
|
||||||
vacancy->setClassId(temp.getClassId(), true);
|
vacancy->setClassId(temp.getClassId(true), true);
|
||||||
// Remove or create multi runners
|
// Remove or create multi runners
|
||||||
vacancy->createMultiRunner(true, true);
|
vacancy->createMultiRunner(true, true);
|
||||||
vacancy->apply(false, 0, false);
|
vacancy->apply(false, 0, false);
|
||||||
@ -1321,7 +1348,7 @@ int TabRunner::vacancyCB(gdioutput &gdi, int type, void *data)
|
|||||||
int birthYear = 0;
|
int birthYear = 0;
|
||||||
pClub pc = oe->getClubCreate(0, club);
|
pClub pc = oe->getClubCreate(0, club);
|
||||||
|
|
||||||
r->updateFromDB(name, pc->getId(), r->getClassId(), cardNo, birthYear);
|
r->updateFromDB(name, pc->getId(), r->getClassId(false), cardNo, birthYear);
|
||||||
|
|
||||||
r->setName(name, true);
|
r->setName(name, true);
|
||||||
r->setCardNo(cardNo, true);
|
r->setCardNo(cardNo, true);
|
||||||
@ -1377,7 +1404,7 @@ int TabRunner::vacancyCB(gdioutput &gdi, int type, void *data)
|
|||||||
// Print start certificate
|
// Print start certificate
|
||||||
tsi.generateStartInfo(gdi, *r);
|
tsi.generateStartInfo(gdi, *r);
|
||||||
|
|
||||||
showVacancyList(gdi, "", r->getClassId());
|
showVacancyList(gdi, "", r->getClassId(true));
|
||||||
}
|
}
|
||||||
else if (type==GUI_INPUT) {
|
else if (type==GUI_INPUT) {
|
||||||
InputInfo ii=*(InputInfo *)data;
|
InputInfo ii=*(InputInfo *)data;
|
||||||
@ -1473,7 +1500,7 @@ void TabRunner::showRunnerReport(gdioutput &gdi)
|
|||||||
for (size_t k = 0; k < runnersToReport.size(); k++) {
|
for (size_t k = 0; k < runnersToReport.size(); k++) {
|
||||||
pRunner r = oe->getRunner(runnersToReport[k].first, 0);
|
pRunner r = oe->getRunner(runnersToReport[k].first, 0);
|
||||||
if (r && r->getTeam()) {
|
if (r && r->getTeam()) {
|
||||||
pClass cls = oe->getClass(r->getClassId());
|
pClass cls = r->getClassRef(true);
|
||||||
if (cls && cls->getClassType() == oClassPatrol)
|
if (cls && cls->getClassType() == oClassPatrol)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1511,7 +1538,7 @@ void TabRunner::showRunnerReport(gdioutput &gdi)
|
|||||||
tInfo += L" " + t->getStatusS();
|
tInfo += L" " + t->getStatusS();
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.addStringUT(fontMediumPlus, t->getClass());
|
gdi.addStringUT(fontMediumPlus, t->getClass(true));
|
||||||
gdi.addStringUT(boldLarge, tInfo);
|
gdi.addStringUT(boldLarge, tInfo);
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
|
|
||||||
@ -1542,19 +1569,19 @@ void TabRunner::showRunnerReport(gdioutput &gdi)
|
|||||||
|
|
||||||
void TabRunner::runnerReport(gdioutput &gdi, int id, bool compact) {
|
void TabRunner::runnerReport(gdioutput &gdi, int id, bool compact) {
|
||||||
pRunner r = oe->getRunner(id, 0);
|
pRunner r = oe->getRunner(id, 0);
|
||||||
if (!r || ! r->getClassRef())
|
if (!r || ! r->getClassRef(false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
if (r->getTeam() == 0) {
|
if (r->getTeam() == 0) {
|
||||||
gdi.addStringUT(fontMediumPlus, r->getClass());
|
gdi.addStringUT(fontMediumPlus, r->getClass(true));
|
||||||
gdi.addStringUT(boldLarge, r->getCompleteIdentification());
|
gdi.addStringUT(boldLarge, r->getCompleteIdentification());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wstring s;
|
wstring s;
|
||||||
if (r->getTeam())
|
if (r->getTeam())
|
||||||
s += r->getClassRef()->getLegNumber(r->getLegNumber());
|
s += r->getClassRef(false)->getLegNumber(r->getLegNumber());
|
||||||
|
|
||||||
s += L": " + r->getName();
|
s += L": " + r->getName();
|
||||||
gdi.addStringUT(boldText, s);
|
gdi.addStringUT(boldText, s);
|
||||||
@ -1573,7 +1600,7 @@ void TabRunner::runnerReport(gdioutput &gdi, int id, bool compact) {
|
|||||||
|
|
||||||
if (r->statusOK()) {
|
if (r->statusOK()) {
|
||||||
int total, finished, dns;
|
int total, finished, dns;
|
||||||
oe->getNumClassRunners(r->getClassId(), r->getLegNumber(), total, finished, dns);
|
oe->getNumClassRunners(r->getClassId(true), r->getLegNumber(), total, finished, dns);
|
||||||
|
|
||||||
if (r->getTeam() == 0) {
|
if (r->getTeam() == 0) {
|
||||||
gdi.addString("", fontMediumPlus, L"Tid: X, nuvarande placering Y/Z.#" + str + L"#" + r->getPlaceS() + L"#" + itow(finished));
|
gdi.addString("", fontMediumPlus, L"Tid: X, nuvarande placering Y/Z.#" + str + L"#" + r->getPlaceS() + L"#" + itow(finished));
|
||||||
@ -2005,7 +2032,7 @@ void TabRunner::listRunners(gdioutput &gdi, const vector<pRunner> &r, bool filte
|
|||||||
sprintf_s(bf, "%d.", k+1);
|
sprintf_s(bf, "%d.", k+1);
|
||||||
gdi.addStringUT(yp, xp, 0, bf);
|
gdi.addStringUT(yp, xp, 0, bf);
|
||||||
gdi.addStringUT(yp, xp+40, 0, r[k]->getNameAndRace(true), 190);
|
gdi.addStringUT(yp, xp+40, 0, r[k]->getNameAndRace(true), 190);
|
||||||
gdi.addStringUT(yp, xp+200, 0, r[k]->getClass(), 140);
|
gdi.addStringUT(yp, xp+200, 0, r[k]->getClass(true), 140);
|
||||||
gdi.addStringUT(yp, xp+350, 0, r[k]->getClub(), 190);
|
gdi.addStringUT(yp, xp+350, 0, r[k]->getClub(), 190);
|
||||||
int c = r[k]->getCardNo();
|
int c = r[k]->getCardNo();
|
||||||
if (c>0) {
|
if (c>0) {
|
||||||
@ -2224,6 +2251,7 @@ int TabRunner::punchesCB(gdioutput &gdi, int type, void *data)
|
|||||||
card->synchronize();
|
card->synchronize();
|
||||||
r->synchronize(true);
|
r->synchronize(true);
|
||||||
r->evaluateCard(true, mp);
|
r->evaluateCard(true, mp);
|
||||||
|
r->hasManuallyUpdatedTimeStatus();
|
||||||
card->fillPunches(gdi, "Punches", pc);
|
card->fillPunches(gdi, "Punches", pc);
|
||||||
UpdateStatus(gdi, r);
|
UpdateStatus(gdi, r);
|
||||||
}
|
}
|
||||||
@ -2246,6 +2274,7 @@ int TabRunner::punchesCB(gdioutput &gdi, int type, void *data)
|
|||||||
r->synchronize(true);
|
r->synchronize(true);
|
||||||
r->evaluateCard(true, mp);
|
r->evaluateCard(true, mp);
|
||||||
card->fillPunches(gdi, "Punches", r->getCourse(true));
|
card->fillPunches(gdi, "Punches", r->getCourse(true));
|
||||||
|
r->hasManuallyUpdatedTimeStatus();
|
||||||
UpdateStatus(gdi, r);
|
UpdateStatus(gdi, r);
|
||||||
}
|
}
|
||||||
else if (bi.id=="SaveC"){
|
else if (bi.id=="SaveC"){
|
||||||
@ -2274,6 +2303,7 @@ int TabRunner::punchesCB(gdioutput &gdi, int type, void *data)
|
|||||||
card->synchronize();
|
card->synchronize();
|
||||||
r->synchronize();
|
r->synchronize();
|
||||||
r->evaluateCard(true, mp);
|
r->evaluateCard(true, mp);
|
||||||
|
r->hasManuallyUpdatedTimeStatus();
|
||||||
card->fillPunches(gdi, "Punches", r->getCourse(true));
|
card->fillPunches(gdi, "Punches", r->getCourse(true));
|
||||||
UpdateStatus(gdi, r);
|
UpdateStatus(gdi, r);
|
||||||
gdi.selectItemByData("Punches", lbi.data);
|
gdi.selectItemByData("Punches", lbi.data);
|
||||||
@ -2380,14 +2410,17 @@ bool TabRunner::loadPage(gdioutput &gdi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.addSelection("RClass", 130, 300, RunnerCB, L"Klass:");
|
bool hasEco = oe->getMeOSFeatures().hasFeature(MeOSFeatures::Economy);
|
||||||
|
gdi.addSelection("RClass", hasEco ? 130 : 170, 300, RunnerCB, L"Klass:");
|
||||||
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
||||||
gdi.addItem("RClass", lang.tl("Ingen klass"), 0);
|
gdi.addItem("RClass", lang.tl("Ingen klass"), 0);
|
||||||
|
|
||||||
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::Economy)) {
|
if (hasEco) {
|
||||||
|
//gdi.addInput("Fee", L"", 4, 0, L"Avgift:");
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.addInput("Fee", L"", 4, 0, L"Avgift:");
|
gdi.dropLine();
|
||||||
//gdi.addButton("Economy", "@" + itos(131), RunnerCB, "Ekonomi...");
|
gdi.addButton("Economy", "Ekonomi...", RunnerCB, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
@ -2652,7 +2685,7 @@ void TabRunner::fillRunnerList(gdioutput &gdi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TabRunner::canSetStart(pRunner r) const {
|
bool TabRunner::canSetStart(pRunner r) const {
|
||||||
pClass pc = r->getTeam() ? r->getTeam()->getClassRef() : r->getClassRef();
|
pClass pc = r->getTeam() ? r->getTeam()->getClassRef(false) : r->getClassRef(true);
|
||||||
|
|
||||||
if (pc && pc->getNumStages() > 0) {
|
if (pc && pc->getNumStages() > 0) {
|
||||||
StartTypes st = pc->getStartType(r->getLegNumber());
|
StartTypes st = pc->getStartType(r->getLegNumber());
|
||||||
@ -2778,3 +2811,138 @@ void TabRunner::autoGrowCourse(gdioutput &gdi) {
|
|||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TabRunner::EconomyHandler::init(oRunner &r) {
|
||||||
|
oe = r.getEvent();
|
||||||
|
runnerId = r.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
oRunner &TabRunner::EconomyHandler::getRunner() const {
|
||||||
|
pRunner p = oe->getRunner(runnerId, 0);
|
||||||
|
if (!p)
|
||||||
|
throw meosException("Löpare saknas");
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
TabRunner::EconomyHandler *TabRunner::getEconomyHandler(oRunner &r) {
|
||||||
|
if (!ecoHandler)
|
||||||
|
ecoHandler = make_shared<EconomyHandler>();
|
||||||
|
|
||||||
|
ecoHandler->init(r);
|
||||||
|
return ecoHandler.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabRunner::EconomyHandler::handle(gdioutput &gdi, BaseInfo &info, GuiEventType type) {
|
||||||
|
if (type == GuiEventType::GUI_BUTTON) {
|
||||||
|
ButtonInfo &bi = dynamic_cast<ButtonInfo &>(info);
|
||||||
|
if (bi.id == "Close") {
|
||||||
|
save(gdi);
|
||||||
|
gdi.closeWindow();
|
||||||
|
}
|
||||||
|
else if (bi.id == "Save") {
|
||||||
|
save(gdi);
|
||||||
|
}
|
||||||
|
else if (bi.id == "Cancel") {
|
||||||
|
TabRunner &dst = dynamic_cast<TabRunner&>(*gdi.getTabs().get(TabType::TRunnerTab));
|
||||||
|
dst.loadEconomy(gdi, getRunner());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == GuiEventType::GUI_INPUTCHANGE) {
|
||||||
|
InputInfo &ii = dynamic_cast<InputInfo &>(info);
|
||||||
|
if (ii.id == "Fee") {
|
||||||
|
gdi.check("ModFee", ii.changed() || getRunner().hasFlag(oAbstractRunner::FlagFeeSpecified));
|
||||||
|
}
|
||||||
|
else if (ii.id == "PaidAmount") {
|
||||||
|
int paid = oe->interpretCurrency(ii.text);
|
||||||
|
gdi.setInputStatus("PayMode", paid != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabRunner::EconomyHandler::save(gdioutput &gdi) {
|
||||||
|
oRunner &r = getRunner();
|
||||||
|
if (r.getTeam() == 0) {
|
||||||
|
r.getDI().setDate("EntryDate", gdi.getText("EntryDate"));
|
||||||
|
int t = convertAbsoluteTimeHMS(gdi.getText("EntryTime"), -1);
|
||||||
|
r.getDI().setInt("EntryTime", t);
|
||||||
|
}
|
||||||
|
int fee = oe->interpretCurrency(gdi.getText("Fee"));
|
||||||
|
if (r.getClassRef(true)) {
|
||||||
|
int def = r.getClassRef(true)->getEntryFee(r.getEntryDate(), r.getBirthAge());
|
||||||
|
r.setFlag(oAbstractRunner::FlagFeeSpecified, def != fee);
|
||||||
|
}
|
||||||
|
r.getDI().setInt("Fee", fee);
|
||||||
|
int cf = oe->interpretCurrency(gdi.getText("Card"));
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
if (paid != 0) {
|
||||||
|
int m = gdi.getSelectedItem("").first;
|
||||||
|
if (m != 1000)
|
||||||
|
r.getDI().setInt("PayMode", m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabRunner::loadEconomy(gdioutput &gdi, oRunner &r) {
|
||||||
|
gdi.clearPage(false);
|
||||||
|
gdi.fillDown();
|
||||||
|
gdi.pushX();
|
||||||
|
gdi.addString("", fontMediumPlus, L"Ekonomihantering, X#" + r.getCompleteIdentification());
|
||||||
|
auto h = getEconomyHandler(r);
|
||||||
|
|
||||||
|
gdi.fillRight();
|
||||||
|
gdi.addInput("EntryDate", r.getEntryDate(true), 10, 0, L"Anmälningsdatum:");
|
||||||
|
gdi.fillDown();
|
||||||
|
gdi.addInput("EntryTime", formatTime(r.getDCI().getInt("EntryTime")), 10, 0, L"Anmälningstid:");
|
||||||
|
gdi.setInputStatus("EntryDate", r.getTeam() == 0);
|
||||||
|
gdi.setInputStatus("EntryTime", r.getTeam() == 0);
|
||||||
|
|
||||||
|
gdi.popX();
|
||||||
|
gdi.dropLine();
|
||||||
|
|
||||||
|
gdi.fillRight();
|
||||||
|
gdi.addInput("Fee", oe->formatCurrency(r.getDCI().getInt("Fee")), 5, 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:");
|
||||||
|
int paid = r.getDCI().getInt("Paid");
|
||||||
|
gdi.addInput("PaidAmount", oe->formatCurrency(paid), 5, 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);
|
||||||
|
gdi.addItem("PayMode", pm);
|
||||||
|
gdi.selectItemByData("PayMode", mypm);
|
||||||
|
gdi.autoGrow("PayMode");
|
||||||
|
gdi.setInputStatus("PayMode", paid != 0);
|
||||||
|
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.popX();
|
||||||
|
|
||||||
|
gdi.addString("", 1, "Manuellt gjorda justeringar");
|
||||||
|
gdi.fillRight();
|
||||||
|
|
||||||
|
gdi.addCheckbox("ModFee", "Avgift", 0, r.hasFlag(oAbstractRunner::FlagFeeSpecified));
|
||||||
|
gdi.disableInput("ModFee");
|
||||||
|
|
||||||
|
gdi.addCheckbox("ModCls", "Klass", 0, r.hasFlag(oAbstractRunner::FlagUpdateClass));
|
||||||
|
gdi.disableInput("ModCls");
|
||||||
|
|
||||||
|
gdi.fillDown();
|
||||||
|
gdi.addCheckbox("ModCls", "Namn", 0, r.hasFlag(oAbstractRunner::FlagUpdateName));
|
||||||
|
gdi.disableInput("ModCls");
|
||||||
|
|
||||||
|
gdi.fillRight();
|
||||||
|
gdi.addButton("Cancel", "Ångra").setHandler(h);
|
||||||
|
gdi.addButton("Close", "Stäng").setHandler(h);
|
||||||
|
gdi.addButton("Save", "Spara").setHandler(h);
|
||||||
|
gdi.refresh();
|
||||||
|
}
|
||||||
|
|||||||
@ -91,6 +91,21 @@ private:
|
|||||||
|
|
||||||
static void autoGrowCourse(gdioutput &gdi);
|
static void autoGrowCourse(gdioutput &gdi);
|
||||||
|
|
||||||
|
void loadEconomy(gdioutput &gdi, oRunner &r);
|
||||||
|
|
||||||
|
class EconomyHandler : public GuiHandler {
|
||||||
|
int runnerId;
|
||||||
|
oEvent *oe;
|
||||||
|
oRunner &getRunner() const;
|
||||||
|
public:
|
||||||
|
void init(oRunner &r);
|
||||||
|
void handle(gdioutput &gdi, BaseInfo &info, GuiEventType type);
|
||||||
|
void save(gdioutput &gdi);
|
||||||
|
};
|
||||||
|
|
||||||
|
shared_ptr<EconomyHandler> ecoHandler;
|
||||||
|
EconomyHandler *getEconomyHandler(oRunner &r);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
|
|
||||||
@ -104,6 +119,8 @@ public:
|
|||||||
bool loadPage(gdioutput &gdi);
|
bool loadPage(gdioutput &gdi);
|
||||||
bool loadPage(gdioutput &gdi, int runnerId);
|
bool loadPage(gdioutput &gdi, int runnerId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TabRunner(oEvent *oe);
|
TabRunner(oEvent *oe);
|
||||||
~TabRunner(void);
|
~TabRunner(void);
|
||||||
|
|
||||||
|
|||||||
@ -818,7 +818,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
|||||||
|
|
||||||
pRunner cardRunner = oe->getRunnerByCardNo(cardNo, 0, true);
|
pRunner cardRunner = oe->getRunnerByCardNo(cardNo, 0, true);
|
||||||
if (cardNo>0 && cardRunner!=0 && cardRunner!=r) {
|
if (cardNo>0 && cardRunner!=0 && cardRunner!=r) {
|
||||||
gdi.alert(L"Bricknummret är upptaget (X).#" + cardRunner->getName() + L", " + cardRunner->getClass());
|
gdi.alert(L"Bricknummret är upptaget (X).#" + cardRunner->getName() + L", " + cardRunner->getClass(true));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,7 +857,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastClubId=r->getClubId();
|
lastClubId=r->getClubId();
|
||||||
lastClassId=r->getClassId();
|
lastClassId=r->getClassId(true);
|
||||||
lastFee = gdi.getText("Fee", true);
|
lastFee = gdi.getText("Fee", true);
|
||||||
int lastFeeNum = oe->interpretCurrency(lastFee);
|
int lastFeeNum = oe->interpretCurrency(lastFee);
|
||||||
|
|
||||||
@ -890,10 +890,10 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
|||||||
wchar_t bf[256];
|
wchar_t bf[256];
|
||||||
if (r->getClubId() != 0) {
|
if (r->getClubId() != 0) {
|
||||||
swprintf_s(bf, L"(%d), %s, %s", r->getCardNo(), r->getClub().c_str(),
|
swprintf_s(bf, L"(%d), %s, %s", r->getCardNo(), r->getClub().c_str(),
|
||||||
r->getClass().c_str());
|
r->getClass(true).c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
swprintf_s(bf, L"(%d), %s", r->getCardNo(), r->getClass().c_str());
|
swprintf_s(bf, L"(%d), %s", r->getCardNo(), r->getClass(true).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring info(bf);
|
wstring info(bf);
|
||||||
@ -1810,7 +1810,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
autoAssignClass(r, sic);
|
autoAssignClass(r, sic);
|
||||||
|
|
||||||
if (interactiveReadout) {
|
if (interactiveReadout) {
|
||||||
if (r && r->getClassId() && !readBefore && !sameCardNewRace) {
|
if (r && r->getClassId(false) && !readBefore && !sameCardNewRace) {
|
||||||
//We can do a silent read-out...
|
//We can do a silent read-out...
|
||||||
processCard(gdi, r, sic, true);
|
processCard(gdi, r, sic, true);
|
||||||
return;
|
return;
|
||||||
@ -1823,7 +1823,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!readBefore) {
|
if (!readBefore) {
|
||||||
if (r && r->getClassId() && !sameCardNewRace)
|
if (r && r->getClassId(false) && !sameCardNewRace)
|
||||||
processCard(gdi, r, sic, true);
|
processCard(gdi, r, sic, true);
|
||||||
else
|
else
|
||||||
processUnmatched(gdi, sic, true);
|
processUnmatched(gdi, sic, true);
|
||||||
@ -1839,7 +1839,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
// Assign a class if not already done
|
// Assign a class if not already done
|
||||||
autoAssignClass(r, sic);
|
autoAssignClass(r, sic);
|
||||||
|
|
||||||
if (r && r->getClassId() && !readBefore && !sameCardNewRace) {
|
if (r && r->getClassId(false) && !readBefore && !sameCardNewRace) {
|
||||||
//We can do a silent read-out...
|
//We can do a silent read-out...
|
||||||
processCard(gdi, r, sic, true);
|
processCard(gdi, r, sic, true);
|
||||||
return;
|
return;
|
||||||
@ -1923,7 +1923,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
// Assign a class if not already done
|
// Assign a class if not already done
|
||||||
autoAssignClass(r, sic);
|
autoAssignClass(r, sic);
|
||||||
|
|
||||||
if (r && r->getClassId() && !r->getCard()) {
|
if (r && r->getClassId(false) && !r->getCard()) {
|
||||||
SICard copy = sic;
|
SICard copy = sic;
|
||||||
activeSIC.clear(0);
|
activeSIC.clear(0);
|
||||||
processCard(gdi, r, copy); //Everyting is OK
|
processCard(gdi, r, copy); //Everyting is OK
|
||||||
@ -2148,11 +2148,11 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
//Update from SQL-source
|
//Update from SQL-source
|
||||||
runner->synchronize();
|
runner->synchronize();
|
||||||
|
|
||||||
if (!runner->getClassId())
|
if (!runner->getClassId(false))
|
||||||
runner->setClassId(gEvent->addClass(lang.tl(L"Okänd klass"))->getId(), true);
|
runner->setClassId(gEvent->addClass(lang.tl(L"Okänd klass"))->getId(), true);
|
||||||
|
|
||||||
// Choose course from pool
|
// Choose course from pool
|
||||||
pClass cls=gEvent->getClass(runner->getClassId());
|
pClass cls = runner->getClassRef(false);
|
||||||
if (cls && cls->hasCoursePool()) {
|
if (cls && cls->hasCoursePool()) {
|
||||||
unsigned leg=runner->legToRun();
|
unsigned leg=runner->legToRun();
|
||||||
|
|
||||||
@ -2171,11 +2171,11 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pClass pclass=gEvent->getClass(runner->getClassId());
|
pClass pclass = runner->getClassRef(true);
|
||||||
if (!runner->getCourse(false) && !csic.isManualInput()) {
|
if (!runner->getCourse(false) && !csic.isManualInput()) {
|
||||||
|
|
||||||
if (pclass && !pclass->hasMultiCourse() && !pclass->hasDirectResult()) {
|
if (pclass && !pclass->hasMultiCourse() && !pclass->hasDirectResult()) {
|
||||||
pCourse pcourse=gEvent->addCourse(runner->getClass());
|
pCourse pcourse=gEvent->addCourse(pclass->getName());
|
||||||
pclass->setCourse(pcourse);
|
pclass->setCourse(pcourse);
|
||||||
|
|
||||||
for(unsigned i=0;i<csic.nPunch; i++)
|
for(unsigned i=0;i<csic.nPunch; i++)
|
||||||
@ -2222,8 +2222,10 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
|
|
||||||
cardno = itow(sic.CardNumber);
|
cardno = itow(sic.CardNumber);
|
||||||
|
|
||||||
info = runner->getName() + L" (" + cardno + L"), " + runner->getClub()
|
info = runner->getName() + L" (" + cardno + L"), ";
|
||||||
+ L", " + runner->getClass();
|
if (!runner->getClub().empty())
|
||||||
|
info += runner->getClub() + +L", ";
|
||||||
|
info += runner->getClass(true);
|
||||||
|
|
||||||
// Write read card to log
|
// Write read card to log
|
||||||
logCard(sic);
|
logCard(sic);
|
||||||
@ -2260,7 +2262,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//Manual input
|
//Manual input
|
||||||
info = runner->getName() + L", " + runner->getClub() + L", " + runner->getClass();
|
info = runner->getName() + L", " + runner->getClub() + L", " + runner->getClass(true);
|
||||||
runner->setCard(0);
|
runner->setCard(0);
|
||||||
|
|
||||||
if (csic.statusOK) {
|
if (csic.statusOK) {
|
||||||
@ -2297,7 +2299,10 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
gEvent->calculateResults(oEvent::RTClassResult);
|
gEvent->calculateResults(oEvent::RTClassResult);
|
||||||
if (runner->getTeam())
|
if (runner->getTeam())
|
||||||
gEvent->calculateTeamResults(runner->getLegNumber(), false);
|
gEvent->calculateTeamResults(runner->getLegNumber(), false);
|
||||||
wstring placeS = runner->getTeam() ? runner->getTeam()->getLegPlaceS(runner->getLegNumber(), false) : runner->getPlaceS();
|
bool qfClass = runner->getClassId(false) != runner->getClassId(true);
|
||||||
|
wstring placeS = (runner->getTeam() && !qfClass) ?
|
||||||
|
runner->getTeam()->getLegPlaceS(runner->getLegNumber(), false) :
|
||||||
|
runner->getPlaceS();
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
@ -2322,7 +2327,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wstring msg = L"#" + runner->getName() + L" (" + cardno + L")\n"+
|
wstring msg = L"#" + runner->getName() + L" (" + cardno + L")\n"+
|
||||||
runner->getClub() + L". " + runner->getClass() +
|
runner->getClub() + L". " + runner->getClass(true) +
|
||||||
L"\n" + lang.tl("Tid: ") + runner->getRunningTimeS() + lang.tl(L", Plats ") + placeS;
|
L"\n" + lang.tl("Tid: ") + runner->getRunningTimeS() + lang.tl(L", Plats ") + placeS;
|
||||||
|
|
||||||
gdi.addInfoBox("SIINFO", msg, 10000);
|
gdi.addInfoBox("SIINFO", msg, 10000);
|
||||||
@ -2359,7 +2364,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wstring statusmsg = L"#" + runner->getName() + L" (" + cardno + L")\n"+
|
wstring statusmsg = L"#" + runner->getName() + L" (" + cardno + L")\n"+
|
||||||
runner->getClub() + L". "+ runner->getClass() +
|
runner->getClub() + L". "+ runner->getClass(true) +
|
||||||
L"\n" + msg;
|
L"\n" + msg;
|
||||||
|
|
||||||
gdi.addInfoBox("SIINFO", statusmsg, 10000);
|
gdi.addInfoBox("SIINFO", statusmsg, 10000);
|
||||||
@ -2594,7 +2599,7 @@ void TabSI::generateEntryLine(gdioutput &gdi, pRunner r)
|
|||||||
if (gdi.hasField("Club")) {
|
if (gdi.hasField("Club")) {
|
||||||
gdi.selectItemByData("Club", r->getClubId());
|
gdi.selectItemByData("Club", r->getClubId());
|
||||||
}
|
}
|
||||||
gdi.selectItemByData("Class", r->getClassId());
|
gdi.selectItemByData("Class", r->getClassId(true));
|
||||||
|
|
||||||
oDataConstInterface dci = r->getDCI();
|
oDataConstInterface dci = r->getDCI();
|
||||||
if (gdi.hasField("Fee"))
|
if (gdi.hasField("Fee"))
|
||||||
@ -2729,7 +2734,7 @@ void TabSI::checkMoreCardsInQueue(gdioutput &gdi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TabSI::autoAssignClass(pRunner r, const SICard &sic) {
|
bool TabSI::autoAssignClass(pRunner r, const SICard &sic) {
|
||||||
if (r && r->getClassId()==0) {
|
if (r && r->getClassId(false)==0) {
|
||||||
vector<pClass> classes;
|
vector<pClass> classes;
|
||||||
int dist = oe->findBestClass(sic, classes);
|
int dist = oe->findBestClass(sic, classes);
|
||||||
|
|
||||||
@ -2737,7 +2742,7 @@ bool TabSI::autoAssignClass(pRunner r, const SICard &sic) {
|
|||||||
r->setClassId(classes[0]->getId(), true);
|
r->setClassId(classes[0]->getId(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r && r->getClassId() != 0;
|
return r && r->getClassId(false) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabSI::showManualInput(gdioutput &gdi) {
|
void TabSI::showManualInput(gdioutput &gdi) {
|
||||||
|
|||||||
@ -717,6 +717,10 @@ void TabSpeaker::generateControlList(gdioutput &gdi, int classId)
|
|||||||
|
|
||||||
vector<oClass::TrueLegInfo> stages;
|
vector<oClass::TrueLegInfo> stages;
|
||||||
pc->getTrueStages(stages);
|
pc->getTrueStages(stages);
|
||||||
|
if (pc->getQualificationFinal()) {
|
||||||
|
while (stages.size() > 1)
|
||||||
|
stages.pop_back(); //Ignore for qualification race
|
||||||
|
}
|
||||||
int leg = selectedControl[pc->getId()].getLeg();
|
int leg = selectedControl[pc->getId()].getLeg();
|
||||||
const bool multiDay = oe->hasPrevStage();
|
const bool multiDay = oe->hasPrevStage();
|
||||||
|
|
||||||
@ -1017,6 +1021,8 @@ bool TabSpeaker::loadPage(gdioutput &gdi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdi.setRestorePoint("classes");
|
||||||
|
|
||||||
if (classId == -1) {
|
if (classId == -1) {
|
||||||
string btn = "Events";
|
string btn = "Events";
|
||||||
if (gdi.hasField(btn))
|
if (gdi.hasField(btn))
|
||||||
@ -1028,8 +1034,6 @@ bool TabSpeaker::loadPage(gdioutput &gdi)
|
|||||||
gdi.sendCtrlMessage(btn);
|
gdi.sendCtrlMessage(btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gdi.setRestorePoint("classes");
|
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -188,7 +188,7 @@ void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
|
|||||||
gdi.enableInput("Remove");
|
gdi.enableInput("Remove");
|
||||||
|
|
||||||
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
oe->fillClasses(gdi, "RClass", oEvent::extraNone, oEvent::filterNone);
|
||||||
gdi.selectItemByData("RClass", t->getClassId());
|
gdi.selectItemByData("RClass", t->getClassId(false));
|
||||||
gdi.selectItemByData("Teams", t->getId());
|
gdi.selectItemByData("Teams", t->getId());
|
||||||
|
|
||||||
if (gdi.hasField("StatusIn")) {
|
if (gdi.hasField("StatusIn")) {
|
||||||
@ -353,14 +353,14 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
|
|||||||
gdi.getSelectedItem("RClass", lbi);
|
gdi.getSelectedItem("RClass", lbi);
|
||||||
|
|
||||||
int classId = lbi.data;
|
int classId = lbi.data;
|
||||||
bool newClass = t->getClassId() != classId;
|
bool newClass = t->getClassId(false) != classId;
|
||||||
set<int> classes;
|
set<int> classes;
|
||||||
bool globalDep = false;
|
bool globalDep = false;
|
||||||
if (t->getClassRef())
|
if (t->getClassRef(false))
|
||||||
globalDep = t->getClassRef()->hasClassGlobalDependance();
|
globalDep = t->getClassRef(false)->hasClassGlobalDependence();
|
||||||
|
|
||||||
classes.insert(classId);
|
classes.insert(classId);
|
||||||
classes.insert(t->getClassId());
|
classes.insert(t->getClassId(false));
|
||||||
|
|
||||||
bool readStatusIn = true;
|
bool readStatusIn = true;
|
||||||
if (newClass && t->getInputStatus() != StatusNotCompetiting && t->hasInputData()) {
|
if (newClass && t->getInputStatus() != StatusNotCompetiting && t->hasInputData()) {
|
||||||
@ -402,7 +402,7 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
|
|||||||
pClass pc=oe->getClass(classId);
|
pClass pc=oe->getClass(classId);
|
||||||
|
|
||||||
if (pc) {
|
if (pc) {
|
||||||
globalDep |= pc->hasClassGlobalDependance();
|
globalDep |= pc->hasClassGlobalDependence();
|
||||||
|
|
||||||
for (unsigned i=0;i<pc->getNumStages(); i++) {
|
for (unsigned i=0;i<pc->getNumStages(); i++) {
|
||||||
char bf[16];
|
char bf[16];
|
||||||
@ -428,7 +428,7 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
|
|||||||
// 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(),
|
r->updateFromDB(name, r->getClubId(), r->getClassId(false),
|
||||||
cardNo, 0);
|
cardNo, 0);
|
||||||
r->setName(name, true);
|
r->setName(name, true);
|
||||||
}
|
}
|
||||||
@ -447,12 +447,12 @@ bool TabTeam::save(gdioutput &gdi, bool dontReloadTeams) {
|
|||||||
if (!t->getClub().empty())
|
if (!t->getClub().empty())
|
||||||
r->setClub(t->getClub());
|
r->setClub(t->getClub());
|
||||||
r->resetPersonalData();
|
r->resetPersonalData();
|
||||||
r->updateFromDB(name, r->getClubId(), r->getClassId(),
|
r->updateFromDB(name, r->getClubId(), r->getClassId(false),
|
||||||
cardNo, 0);
|
cardNo, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
r=oe->addRunner(name, t->getClubId(), t->getClassId(), cardNo, 0, false);
|
r=oe->addRunner(name, t->getClubId(), t->getClassId(false), cardNo, 0, false);
|
||||||
|
|
||||||
r->setName(name, true);
|
r->setName(name, true);
|
||||||
r->setCardNo(cardNo, true);
|
r->setCardNo(cardNo, true);
|
||||||
@ -594,7 +594,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
}
|
}
|
||||||
else if (bi.id == "DirOK") {
|
else if (bi.id == "DirOK") {
|
||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
if (!t || !t->getClassRef())
|
if (!t || !t->getClassRef(false))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int leg = bi.getExtraInt();
|
int leg = bi.getExtraInt();
|
||||||
@ -632,7 +632,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
bool rent = gdi.isChecked("DirRent");
|
bool rent = gdi.isChecked("DirRent");
|
||||||
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
r = oe->addRunner(name, clb ? clb->getId() : t->getClubId(), t->getClassId(), card, 0, false);
|
r = oe->addRunner(name, clb ? clb->getId() : t->getClubId(), t->getClassId(false), card, 0, false);
|
||||||
}
|
}
|
||||||
if (rent)
|
if (rent)
|
||||||
r->getDI().setInt("CardFee", oe->getDI().getInt("CardFee"));
|
r->getDI().setInt("CardFee", oe->getDI().getInt("CardFee"));
|
||||||
@ -671,10 +671,10 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
}
|
}
|
||||||
else if (bi.id == "ChangeKey") {
|
else if (bi.id == "ChangeKey") {
|
||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
if (!t || !t->getClassRef())
|
if (!t || !t->getClassRef(false))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pClass pc = t->getClassRef();
|
pClass pc = t->getClassRef(false);
|
||||||
gdi.restore("ChangeKey", false);
|
gdi.restore("ChangeKey", false);
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
@ -695,10 +695,10 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
}
|
}
|
||||||
else if (bi.id == "SaveKey") {
|
else if (bi.id == "SaveKey") {
|
||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
if (!t || !t->getClassRef())
|
if (!t || !t->getClassRef(false))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pClass pc = t->getClassRef();
|
pClass pc = t->getClassRef(false);
|
||||||
int nf = pc->getNumForks();
|
int nf = pc->getNumForks();
|
||||||
ListBoxInfo lbi;
|
ListBoxInfo lbi;
|
||||||
gdi.getSelectedItem("ForkKey", lbi);
|
gdi.getSelectedItem("ForkKey", lbi);
|
||||||
@ -752,7 +752,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
return 0;
|
return 0;
|
||||||
pClass pc = t->getClassRef();
|
pClass pc = t->getClassRef(false);
|
||||||
if (pc == 0)
|
if (pc == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -806,7 +806,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
continue;
|
continue;
|
||||||
if (clubs.count(clsR[i]->getClubId()) == 0)
|
if (clubs.count(clsR[i]->getClubId()) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (clsR[i]->getClassId() != t->getClassId())
|
if (clsR[i]->getClassId(false) != t->getClassId(false))
|
||||||
continue;
|
continue;
|
||||||
if (clsR[i]->getName() == anon)
|
if (clsR[i]->getName() == anon)
|
||||||
continue;
|
continue;
|
||||||
@ -839,7 +839,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
if (usedR.count(clsR[i]->getId()))
|
if (usedR.count(clsR[i]->getId()))
|
||||||
continue;
|
continue;
|
||||||
const wstring &club = clsR[i]->getClub();
|
const wstring &club = clsR[i]->getClub();
|
||||||
wstring id = clsR[i]->getName() + L", " + clsR[i]->getClass();
|
wstring id = clsR[i]->getName() + L", " + clsR[i]->getClass(false);
|
||||||
if (!club.empty())
|
if (!club.empty())
|
||||||
id += L" (" + club + L")";
|
id += L" (" + club + L")";
|
||||||
|
|
||||||
@ -999,7 +999,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
pc->getNumStages() == shownRunners) {
|
pc->getNumStages() == shownRunners) {
|
||||||
// Keep team setup, i.e. do nothing
|
// Keep team setup, i.e. do nothing
|
||||||
}
|
}
|
||||||
else if (t && pc && (t->getClassId()==bi.data
|
else if (t && pc && (t->getClassId(false)==bi.data
|
||||||
|| t->getNumRunners()==pc->getNumStages()) )
|
|| t->getNumRunners()==pc->getNumStages()) )
|
||||||
loadTeamMembers(gdi, 0,0,t);
|
loadTeamMembers(gdi, 0,0,t);
|
||||||
else
|
else
|
||||||
@ -1134,7 +1134,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
|||||||
void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
||||||
{
|
{
|
||||||
if (ClassId==0)
|
if (ClassId==0)
|
||||||
if (t) ClassId=t->getClassId();
|
if (t) ClassId=t->getClassId(false);
|
||||||
|
|
||||||
classId=ClassId;
|
classId=ClassId;
|
||||||
gdi.restore("",false);
|
gdi.restore("",false);
|
||||||
@ -1696,7 +1696,7 @@ void TabTeam::doAddTeamMembers(gdioutput &gdi) {
|
|||||||
|
|
||||||
for (size_t k = 0; k < t.size(); k++) {
|
for (size_t k = 0; k < t.size(); k++) {
|
||||||
pTeam mt = t[k];
|
pTeam mt = t[k];
|
||||||
pClass cls = mt->getClassRef();
|
pClass cls = mt->getClassRef(false);
|
||||||
if (cls == 0)
|
if (cls == 0)
|
||||||
continue;
|
continue;
|
||||||
bool ch = false;
|
bool ch = false;
|
||||||
@ -1845,7 +1845,7 @@ void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
|
|||||||
else if (oldR) {
|
else if (oldR) {
|
||||||
t->setRunner(leg, 0, false);
|
t->setRunner(leg, 0, false);
|
||||||
t->synchronize(true);
|
t->synchronize(true);
|
||||||
oldR->setClassId(r->getClassId(), true);
|
oldR->setClassId(r->getClassId(false), true);
|
||||||
oldR->evaluateCard(true, mp, 0, true);
|
oldR->evaluateCard(true, mp, 0, true);
|
||||||
oldR->synchronize(true);
|
oldR->synchronize(true);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
code/bmp00001.bmp
Normal file
BIN
code/bmp00001.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 406 B |
@ -352,7 +352,7 @@ bool csvparser::importOE_CSV(oEvent &event, const wstring &file) {
|
|||||||
|
|
||||||
if (pc) {
|
if (pc) {
|
||||||
pc->synchronize();
|
pc->synchronize();
|
||||||
if (pr->getClassId() == 0 || !pr->hasFlag(oAbstractRunner::FlagUpdateClass))
|
if (pr->getClassId(false) == 0 || !pr->hasFlag(oAbstractRunner::FlagUpdateClass))
|
||||||
pr->setClassId(pc->getId(), false);
|
pr->setClassId(pc->getId(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,8 +397,8 @@ bool csvparser::importOE_CSV(oEvent &event, const wstring &file) {
|
|||||||
course->synchronize();
|
course->synchronize();
|
||||||
}
|
}
|
||||||
if (course) {
|
if (course) {
|
||||||
if (pr->getClassId() != 0)
|
if (pr->getClassId(false) != 0)
|
||||||
event.getClass(pr->getClassId())->setCourse(course);
|
event.getClass(pr->getClassId(false))->setCourse(course);
|
||||||
else
|
else
|
||||||
pr->setCourseId(course->getId());
|
pr->setCourseId(course->getId());
|
||||||
}
|
}
|
||||||
@ -1253,23 +1253,71 @@ void csvparser::parse(const wstring &file, list< vector<string> > &data) {
|
|||||||
fin.close();
|
fin.close();
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
void csvparser::parseUnicode(const wstring &file, list< vector<wstring> > &data) {
|
||||||
|
fin.open(file, ifstream::in | ifstream::binary);
|
||||||
|
fin.seekg(0, ios_base::end);
|
||||||
|
size_t len = int(fin.tellg())-2;
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
fin.seekg(2); // BOM
|
||||||
|
assert(len % 2 == 0);
|
||||||
|
vector<wchar_t> bf(len / 2 + 1);
|
||||||
|
fin.read((char *)&bf[0], len);
|
||||||
|
vector<wstring> rows;
|
||||||
|
int spp = 0;
|
||||||
|
for (size_t k = 0; k < len / 2; k++) {
|
||||||
|
if (bf[spp] == '\r')
|
||||||
|
spp++;
|
||||||
|
if (bf[k] == '\n') {
|
||||||
|
bf[k] = 0;
|
||||||
|
if (k > 0 && bf[k - 1] == '\r')
|
||||||
|
bf[k - 1] = 0;
|
||||||
|
wstring r = &bf[spp];
|
||||||
|
spp = k + 1;
|
||||||
|
rows.push_back(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size_t(spp + 1) < len / 2) {
|
||||||
|
wstring r = &bf[spp];
|
||||||
|
rows.push_back(r);
|
||||||
|
}
|
||||||
|
vector<wchar_t *> sp;
|
||||||
|
|
||||||
|
for (size_t k = 0; k < rows.size(); k++) {
|
||||||
|
split(const_cast<wchar_t*>(rows[k].c_str()), sp);
|
||||||
|
|
||||||
|
if (!sp.empty()) {
|
||||||
|
data.push_back(vector<wstring>());
|
||||||
|
data.back().resize(sp.size());
|
||||||
|
for (size_t k = 0; k < sp.size(); k++) {
|
||||||
|
data.back()[k] = sp[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void csvparser::parse(const wstring &file, list< vector<wstring> > &data) {
|
void csvparser::parse(const wstring &file, list< vector<wstring> > &data) {
|
||||||
data.clear();
|
data.clear();
|
||||||
|
|
||||||
fin.open(file);
|
fin.open(file);
|
||||||
// const size_t bf_size = 8192;
|
|
||||||
|
fin.seekg(0, ios_base::end);
|
||||||
|
auto len = fin.tellg();
|
||||||
|
fin.seekg(0);
|
||||||
|
|
||||||
string rbf;
|
string rbf;
|
||||||
|
|
||||||
if (!fin.good())
|
if (!fin.good())
|
||||||
throw meosException("Failed to read file");
|
throw meosException("Failed to read file");
|
||||||
|
|
||||||
bool isUTF8 = false;
|
bool isUTF8 = false;
|
||||||
bool isUnicode = false;
|
|
||||||
bool firstLine = true;
|
bool firstLine = true;
|
||||||
vector<wchar_t *> sp;
|
vector<wchar_t *> sp;
|
||||||
wchar_t wbf[buff_pre_alloc];
|
vector<wchar_t> wbf_a;
|
||||||
|
wbf_a.resize(size_t(len));
|
||||||
|
wchar_t *wbf = &wbf_a[0];
|
||||||
wstring w;
|
wstring w;
|
||||||
|
|
||||||
while(std::getline(fin, rbf)) {
|
while(std::getline(fin, rbf)) {
|
||||||
const char *bf = rbf.c_str();
|
const char *bf = rbf.c_str();
|
||||||
if (firstLine) {
|
if (firstLine) {
|
||||||
@ -1278,27 +1326,23 @@ void csvparser::parse(const wstring &file, list< vector<wstring> > &data) {
|
|||||||
bf += 3;
|
bf += 3;
|
||||||
}
|
}
|
||||||
else if (bf[0] == -1 && bf[1] == -2) {
|
else if (bf[0] == -1 && bf[1] == -2) {
|
||||||
isUnicode = true;
|
fin.close();
|
||||||
bf += 2;
|
vector<wchar_t>().swap(wbf_a);
|
||||||
|
parseUnicode(file, data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUnicode) {
|
if (isUTF8) {
|
||||||
int len = 0;
|
|
||||||
if (bf[len] == 0 && bf[len+1] != 0)
|
|
||||||
len++;
|
|
||||||
split((wchar_t*)&bf[len], sp);
|
|
||||||
}
|
|
||||||
else if (isUTF8) {
|
|
||||||
int len = strlen(bf);
|
int len = strlen(bf);
|
||||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, bf, len, wbf, buff_pre_alloc);
|
int wlen = MultiByteToWideChar(CP_UTF8, 0, bf, len, wbf, buff_pre_alloc);
|
||||||
wbf[wlen] = 0;
|
wbf[wlen] = 0;
|
||||||
split(wbf, sp);
|
split(&wbf[0], sp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
w = gdi_main->recodeToWide(bf);
|
w = gdi_main->recodeToWide(bf);
|
||||||
wchar_t *wbf = const_cast<wchar_t *>(w.c_str());
|
wchar_t *wbfL = const_cast<wchar_t *>(w.c_str());
|
||||||
split(wbf, sp);
|
split(wbfL, sp);
|
||||||
}
|
}
|
||||||
firstLine = false;
|
firstLine = false;
|
||||||
|
|
||||||
|
|||||||
@ -99,6 +99,8 @@ protected:
|
|||||||
map<SIConfigFields, int> siconfigmap;
|
map<SIConfigFields, int> siconfigmap;
|
||||||
const wchar_t *getSIC(SIConfigFields sic, const vector<wstring> &sp) const;
|
const wchar_t *getSIC(SIConfigFields sic, const vector<wstring> &sp) const;
|
||||||
|
|
||||||
|
void parseUnicode(const wstring &file, list< vector<wstring> > &data);
|
||||||
|
|
||||||
// Check and process a punch line
|
// Check and process a punch line
|
||||||
static int selectPunchIndex(const wstring &competitionDate, const vector<wstring> &sp,
|
static int selectPunchIndex(const wstring &competitionDate, const vector<wstring> &sp,
|
||||||
int &cardIndex, int &timeIndex, int &dateIndex,
|
int &cardIndex, int &timeIndex, int &dateIndex,
|
||||||
|
|||||||
@ -2284,3 +2284,17 @@ RunnerEntryTime = Competitor's entry time
|
|||||||
RunnerPaid = Paid amount
|
RunnerPaid = Paid amount
|
||||||
RunnerPayMethod = Payment method
|
RunnerPayMethod = Payment method
|
||||||
EntryTime = Entry Time
|
EntryTime = Entry Time
|
||||||
|
Ekonomihantering, X = Economy status, X
|
||||||
|
Manuellt gjorda justeringar = Manually made adjustments
|
||||||
|
Antal förfrågningar: X = Number of requests: X
|
||||||
|
Genomsnittlig svarstid: X ms = Average response time: X ms
|
||||||
|
Informationsserver = Information server
|
||||||
|
Längsta svarstid: X ms = Longest response time: X ms
|
||||||
|
MeOS Informationsserver REST-API = MeOS Information Server REST-API
|
||||||
|
Testa servern = Test the server
|
||||||
|
help:rest = MeOS REST API lets you access competition data via a webb connection. You can show result lists directly in a webb browser, but you can also request competition data and results in a XML format, suitble for further processing in third party programs and apps.
|
||||||
|
Server startad på X = Server running on port X
|
||||||
|
Inconsistent qualification rule, X = Inconsistent qualification rule, X
|
||||||
|
help:LockStartList = MeOS will not update assignement to a locked class even if qualification results are altered.
|
||||||
|
Kval-Final-Schema = Load qualification scheme
|
||||||
|
Lås startlista = Lock start list
|
||||||
|
|||||||
@ -4215,7 +4215,7 @@ void gdioutput::calcStringSize(TextInfo &ti, HDC hDC_in) const
|
|||||||
HDC hDC=hDC_in;
|
HDC hDC=hDC_in;
|
||||||
|
|
||||||
if (!hDC) {
|
if (!hDC) {
|
||||||
assert(hWndTarget!=0);
|
// assert(hWndTarget!=0);
|
||||||
hDC=GetDC(hWndTarget);
|
hDC=GetDC(hWndTarget);
|
||||||
}
|
}
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|||||||
@ -78,6 +78,7 @@ GeneralResult::GeneralResult(void) {
|
|||||||
GeneralResult::~GeneralResult(void) {
|
GeneralResult::~GeneralResult(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Needed to generate template instances
|
||||||
void GRINSTANCE() {
|
void GRINSTANCE() {
|
||||||
vector<oRunner *> a;
|
vector<oRunner *> a;
|
||||||
vector<oTeam *> b;
|
vector<oTeam *> b;
|
||||||
@ -86,6 +87,7 @@ void GRINSTANCE() {
|
|||||||
gr.sort(b, SortByFinishTime);
|
gr.sort(b, SortByFinishTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GeneralResult::setContext(const oListParam *contextIn) {
|
void GeneralResult::setContext(const oListParam *contextIn) {
|
||||||
context = contextIn;
|
context = contextIn;
|
||||||
}
|
}
|
||||||
@ -230,8 +232,10 @@ template<class T> void GeneralResult::sort(vector<T *> &rt, SortOrder so) const
|
|||||||
const int maxT = 3600 * 100;
|
const int maxT = 3600 * 100;
|
||||||
for(size_t k = 0; k < rt.size(); k++) {
|
for(size_t k = 0; k < rt.size(); k++) {
|
||||||
arr[k].first = 0;
|
arr[k].first = 0;
|
||||||
if (ps == ClassWise)
|
if (ps == ClassWise) {
|
||||||
arr[k].first = rt[k]->getClassRef() ? rt[k]->getClassRef()->getSortIndex() : 0;
|
pClass sclass = rt[k]->getClassRef(true);
|
||||||
|
arr[k].first = sclass ? sclass->getSortIndex() : 0;
|
||||||
|
}
|
||||||
else if (ps == CourseWise) {
|
else if (ps == CourseWise) {
|
||||||
oRunner *r = dynamic_cast<oRunner *>(rt[k]);
|
oRunner *r = dynamic_cast<oRunner *>(rt[k]);
|
||||||
arr[k].first = r && r->getCourse(false) ? r->getCourse(false)->getId() : 0;
|
arr[k].first = r && r->getCourse(false) ? r->getCourse(false)->getId() : 0;
|
||||||
@ -266,7 +270,10 @@ template<class T> void GeneralResult::sort(vector<T *> &rt, SortOrder so) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralResult::calculateIndividualResults(vector<oRunner *> &runners, oListInfo::ResultType resType, bool sortRunners, int inputNumber) const {
|
void GeneralResult::calculateIndividualResults(vector<oRunner *> &runners,
|
||||||
|
oListInfo::ResultType resType,
|
||||||
|
bool sortRunners,
|
||||||
|
int inputNumber) const {
|
||||||
|
|
||||||
if (runners.empty())
|
if (runners.empty())
|
||||||
return;
|
return;
|
||||||
@ -286,7 +293,7 @@ void GeneralResult::calculateIndividualResults(vector<oRunner *> &runners, oList
|
|||||||
int ln = r->getLegNumber();
|
int ln = r->getLegNumber();
|
||||||
const oTeam *pt = r->getTeam();
|
const oTeam *pt = r->getTeam();
|
||||||
if (pt) {
|
if (pt) {
|
||||||
const oClass *tcls = pt->getClassRef();
|
const oClass *tcls = pt->getClassRef(false);
|
||||||
if (tcls && tcls->getClassType() == oClassRelay) {
|
if (tcls && tcls->getClassType() == oClassRelay) {
|
||||||
int dummy;
|
int dummy;
|
||||||
tcls->splitLegNumberParallel(r->getLegNumber(), ln, dummy);
|
tcls->splitLegNumberParallel(r->getLegNumber(), ln, dummy);
|
||||||
@ -294,6 +301,10 @@ void GeneralResult::calculateIndividualResults(vector<oRunner *> &runners, oList
|
|||||||
}
|
}
|
||||||
runnerScore[k].principalSort = runnerScore[k].principalSort * 50 + ln;
|
runnerScore[k].principalSort = runnerScore[k].principalSort * 50 + ln;
|
||||||
}
|
}
|
||||||
|
else if (resType == oListInfo::Coursewise) {
|
||||||
|
pCourse crs = r->getCourse(false);
|
||||||
|
runnerScore[k].principalSort = crs ? crs->getId() : 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
runnerScore[k].principalSort = 0;
|
runnerScore[k].principalSort = 0;
|
||||||
|
|
||||||
@ -474,10 +485,10 @@ RunnerStatus TotalResultAtControl::deduceStatus(oRunner &runner) const {
|
|||||||
if (runner.getTeam() && getListParamTimeFromControl() <= 0) {
|
if (runner.getTeam() && getListParamTimeFromControl() <= 0) {
|
||||||
// Only use input time when start time is used
|
// Only use input time when start time is used
|
||||||
const pTeam t = runner.getTeam();
|
const pTeam t = runner.getTeam();
|
||||||
if (runner.getLegNumber()>0 && t->getClassRef()) {
|
if (runner.getLegNumber()>0 && t->getClassRef(false)) {
|
||||||
// Find base leg
|
// Find base leg
|
||||||
int legIx = runner.getLegNumber();
|
int legIx = runner.getLegNumber();
|
||||||
const pClass cls = t->getClassRef();
|
const pClass cls = t->getClassRef(false);
|
||||||
while (legIx > 0 && (cls->isParallel(legIx) || cls->isOptional(legIx)))
|
while (legIx > 0 && (cls->isParallel(legIx) || cls->isOptional(legIx)))
|
||||||
legIx--;
|
legIx--;
|
||||||
if (legIx > 0)
|
if (legIx > 0)
|
||||||
@ -504,10 +515,10 @@ int TotalResultAtControl::deduceTime(oRunner &runner, int startTime) const {
|
|||||||
if (runner.getTeam() && getListParamTimeFromControl() <= 0) {
|
if (runner.getTeam() && getListParamTimeFromControl() <= 0) {
|
||||||
// Only use input time when start time is used
|
// Only use input time when start time is used
|
||||||
const pTeam t = runner.getTeam();
|
const pTeam t = runner.getTeam();
|
||||||
if (runner.getLegNumber()>0 && t->getClassRef()) {
|
if (runner.getLegNumber()>0 && t->getClassRef(false)) {
|
||||||
// Find base leg
|
// Find base leg
|
||||||
int legIx = runner.getLegNumber();
|
int legIx = runner.getLegNumber();
|
||||||
const pClass cls = t->getClassRef();
|
const pClass cls = t->getClassRef(false);
|
||||||
while (legIx > 0 && (cls->isParallel(legIx) || cls->isOptional(legIx)))
|
while (legIx > 0 && (cls->isParallel(legIx) || cls->isOptional(legIx)))
|
||||||
legIx--;
|
legIx--;
|
||||||
if (legIx > 0)
|
if (legIx > 0)
|
||||||
@ -1125,11 +1136,10 @@ void DynamicResult::prepareCalculations(oTeam &team) const {
|
|||||||
parser.addSymbol("RunnerCourse", team.getResultCache(oTeam::RCCCourse));
|
parser.addSymbol("RunnerCourse", team.getResultCache(oTeam::RCCCourse));
|
||||||
parser.addSymbol("RunnerSplitTimes", team.getResultCache(oTeam::RCCSplitTime));
|
parser.addSymbol("RunnerSplitTimes", team.getResultCache(oTeam::RCCSplitTime));
|
||||||
|
|
||||||
pClass cls = team.getClassRef();
|
pClass cls = team.getClassRef(true);
|
||||||
if (cls) {
|
if (cls) {
|
||||||
int nl = max<int>(1, cls->getNumStages()-1);
|
int nl = max<int>(1, cls->getNumStages()-1);
|
||||||
parser.addSymbol("ShortestClassTime", cls->getTotalLegLeaderTime(nl, false));
|
parser.addSymbol("ShortestClassTime", cls->getTotalLegLeaderTime(nl, false));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,7 +1247,7 @@ void DynamicResult::prepareCalculations(oRunner &runner) const {
|
|||||||
parser.addSymbol("SplitTimesAccumulated", e);
|
parser.addSymbol("SplitTimesAccumulated", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pClass cls = runner.getClassRef();
|
pClass cls = runner.getClassRef(true);
|
||||||
if (cls) {
|
if (cls) {
|
||||||
int nl = runner.getLegNumber();
|
int nl = runner.getLegNumber();
|
||||||
parser.addSymbol("ShortestClassTime", cls->getBestLegTime(nl));
|
parser.addSymbol("ShortestClassTime", cls->getBestLegTime(nl));
|
||||||
@ -1303,3 +1313,294 @@ void DynamicResult::debugDumpVariables(gdioutput &gdi, bool includeSymbols) cons
|
|||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneralResult::calculateIndividualResults(vector<pRunner> &runners,
|
||||||
|
const pair<int, int> & controlId,
|
||||||
|
bool totalResults,
|
||||||
|
const string &resTag,
|
||||||
|
oListInfo::ResultType resType,
|
||||||
|
int inputNumber,
|
||||||
|
oEvent &oe,
|
||||||
|
vector<GeneralResultInfo> &results) {
|
||||||
|
|
||||||
|
results.reserve(runners.size());
|
||||||
|
|
||||||
|
if (resTag.empty() && resType == ClassWise) {
|
||||||
|
GeneralResultInfo ri;
|
||||||
|
if (controlId.second == oPunch::PunchFinish &&
|
||||||
|
controlId.first == oPunch::PunchStart) {
|
||||||
|
|
||||||
|
if (!totalResults) {
|
||||||
|
oe.calculateResults(oEvent::RTClassResult, true);
|
||||||
|
for (pRunner r : runners) {
|
||||||
|
ri.status = r->getStatus();
|
||||||
|
if (ri.status == StatusUnknown) {
|
||||||
|
if (r->getFinishTime() == 0)
|
||||||
|
continue;
|
||||||
|
ri.status = StatusOK; // Preliminary status
|
||||||
|
}
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = r->getPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
ri.score = r->getRogainingPoints(false);
|
||||||
|
ri.time = r->getRunningTime();
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oe.calculateResults(oEvent::RTTotalResult, true);
|
||||||
|
for (pRunner r : runners) {
|
||||||
|
ri.status = r->getTotalStatus();
|
||||||
|
if (ri.status == StatusUnknown && r->getInputStatus() == StatusOK) {
|
||||||
|
if (r->getFinishTime() == 0)
|
||||||
|
continue;
|
||||||
|
ri.status = StatusOK; // Preliminary status
|
||||||
|
}
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = r->getTotalPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
ri.score = r->getRogainingPoints(true);
|
||||||
|
ri.time = r->getTotalRunningTime();
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oe.calculateSplitResults(controlId.first, controlId.second);
|
||||||
|
|
||||||
|
ri.score = 0; // Undefined
|
||||||
|
for (pRunner r : runners) {
|
||||||
|
ri.status = r->getTempStatus();
|
||||||
|
if (ri.status == StatusUnknown) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ri.status == StatusMP && r->getStatus() != StatusMP)
|
||||||
|
continue; // Control that is not needed requested
|
||||||
|
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = r->getPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
ri.time = r->getTempTime();
|
||||||
|
|
||||||
|
if (ri.time <= 0 && ri.status == StatusOK)
|
||||||
|
continue;
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wstring srcDMY;
|
||||||
|
GeneralResult *gResult = 0;
|
||||||
|
shared_ptr<GeneralResult> specialInstance;
|
||||||
|
oListParam param;
|
||||||
|
param.useControlIdResultTo = controlId.second;
|
||||||
|
param.useControlIdResultFrom = controlId.first;
|
||||||
|
|
||||||
|
if (!resTag.empty())
|
||||||
|
gResult = &oe.getGeneralResult(resTag, srcDMY);
|
||||||
|
else {
|
||||||
|
if (controlId.second == oPunch::PunchFinish &&
|
||||||
|
controlId.first == oPunch::PunchStart && !totalResults)
|
||||||
|
specialInstance = make_shared<GeneralResult>();
|
||||||
|
else if (!totalResults)
|
||||||
|
specialInstance = make_shared<ResultAtControl>();
|
||||||
|
else
|
||||||
|
specialInstance = make_shared<TotalResultAtControl>();
|
||||||
|
|
||||||
|
gResult = specialInstance.get();
|
||||||
|
}
|
||||||
|
gResult->setContext(¶m);
|
||||||
|
gResult->calculateIndividualResults(runners, resType, true, inputNumber);
|
||||||
|
gResult->clearContext();
|
||||||
|
map<int, bool> mapHasCourse;
|
||||||
|
GeneralResultInfo ri;
|
||||||
|
for (pRunner r : runners) {
|
||||||
|
const auto &tmp = r->getTempResult(0);
|
||||||
|
ri.status = tmp.getStatus();
|
||||||
|
if (ri.status == StatusUnknown) {
|
||||||
|
if (r->getFinishTime() == 0)
|
||||||
|
continue;
|
||||||
|
ri.status = StatusOK; // Preliminary status
|
||||||
|
}
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = tmp.getPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
if ((controlId.first != oPunch::PunchStart ||
|
||||||
|
controlId.second != oPunch::PunchFinish) && ri.status == StatusMP && r->getStatus() != StatusMP) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ri.score = tmp.getPoints();
|
||||||
|
ri.time = tmp.getRunningTime();
|
||||||
|
|
||||||
|
|
||||||
|
if (controlId.first != oPunch::PunchStart && ri.time <= 0 && ri.status == StatusOK)
|
||||||
|
continue; // Wrong order, skip
|
||||||
|
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<GeneralResult::BaseResultContext>
|
||||||
|
GeneralResult::calculateTeamResults(vector<pTeam> &teams,
|
||||||
|
int leg,
|
||||||
|
const pair<int, int> &controlId,
|
||||||
|
bool totalResults,
|
||||||
|
const string &resTag,
|
||||||
|
oListInfo::ResultType resType,
|
||||||
|
int inputNumber,
|
||||||
|
oEvent &oe,
|
||||||
|
vector<GeneralResultInfo> &results) {
|
||||||
|
shared_ptr<BaseResultContext> out = make_shared<BaseResultContext>();
|
||||||
|
out->leg = leg;
|
||||||
|
out->controlId = controlId;
|
||||||
|
out->totalResults = totalResults;
|
||||||
|
results.reserve(teams.size());
|
||||||
|
|
||||||
|
if (resTag.empty()) {
|
||||||
|
out->useModule = false;
|
||||||
|
if (controlId.second == oPunch::PunchFinish) {
|
||||||
|
oe.calculateTeamResults(false);
|
||||||
|
GeneralResultInfo ri;
|
||||||
|
for (pTeam r : teams) {
|
||||||
|
ri.status = r->getStatus();
|
||||||
|
if (ri.status == StatusUnknown) {
|
||||||
|
if (r->getFinishTime() == 0)
|
||||||
|
continue;
|
||||||
|
ri.status = StatusOK; // Preliminary status
|
||||||
|
}
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = r->getPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
ri.score = r->getRogainingPoints(false);
|
||||||
|
ri.status = r->getStatus();
|
||||||
|
ri.time = r->getRunningTime();
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set<int> clsId;
|
||||||
|
for (pTeam t : teams)
|
||||||
|
clsId.insert(t->getClassId(false));
|
||||||
|
|
||||||
|
oe.calculateTeamResultAtControl(clsId, leg, controlId.second, totalResults);
|
||||||
|
GeneralResultInfo ri;
|
||||||
|
for (pTeam r : teams) {
|
||||||
|
const auto &tmp = r->getTempResult(0);
|
||||||
|
ri.status = tmp.getStatus();
|
||||||
|
if (ri.status == StatusUnknown || ri.status == StatusMP)
|
||||||
|
continue;
|
||||||
|
ri.place = tmp.getPlace();
|
||||||
|
ri.score = tmp.getPoints();
|
||||||
|
ri.time = tmp.getRunningTime();
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out->useModule = true;
|
||||||
|
wstring srcDMY;
|
||||||
|
auto &gResult = oe.getGeneralResult(resTag, srcDMY);
|
||||||
|
gResult.calculateTeamResults(teams, resType, true, inputNumber);
|
||||||
|
GeneralResultInfo ri;
|
||||||
|
for (pTeam r : teams) {
|
||||||
|
const auto &tmp = r->getTempResult(0);
|
||||||
|
ri.status = tmp.getStatus();
|
||||||
|
if (ri.status == StatusUnknown) {
|
||||||
|
if (r->getFinishTime() == 0)
|
||||||
|
continue;
|
||||||
|
ri.status = StatusOK; // Preliminary status
|
||||||
|
}
|
||||||
|
if (ri.status == StatusOK)
|
||||||
|
ri.place = tmp.getPlace();
|
||||||
|
else
|
||||||
|
ri.place = 0;
|
||||||
|
|
||||||
|
ri.score = tmp.getPoints();
|
||||||
|
ri.time = tmp.getRunningTime();
|
||||||
|
ri.src = r;
|
||||||
|
results.push_back(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeneralResult::GeneralResultInfo::getNumSubresult(const BaseResultContext &context) const {
|
||||||
|
int cid = src->getClassId(false);
|
||||||
|
if (cid == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (context.resIntervalCache.count(cid)) {
|
||||||
|
const auto &cached = context.resIntervalCache[cid];
|
||||||
|
return cached.second - cached.first;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const pClass cls = src->getClassRef(false);
|
||||||
|
int leg = context.leg == -1 ? cls->getNumStages() : context.leg;
|
||||||
|
|
||||||
|
int nb = cls->getNextBaseLeg(leg);
|
||||||
|
if (nb == -1)
|
||||||
|
nb = cls->getNumStages();
|
||||||
|
|
||||||
|
int pb = cls->getPreceedingLeg(leg)+1;
|
||||||
|
|
||||||
|
context.resIntervalCache[cid] = make_pair(pb, nb);
|
||||||
|
return nb - pb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GeneralResult::GeneralResultInfo::getSubResult(const BaseResultContext &context,
|
||||||
|
int ix, GeneralResultInfo &out) const {
|
||||||
|
|
||||||
|
if (getNumSubresult(context) == 0)
|
||||||
|
return false; // Ensure cache is setup
|
||||||
|
int base = context.resIntervalCache[src->getClassId(false)].first;
|
||||||
|
pRunner r = pTeam(src)->getRunner(base + ix);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
out.place = 0; // Not defined
|
||||||
|
out.src = r;
|
||||||
|
|
||||||
|
if (context.useModule) {
|
||||||
|
out.score = r->tmpResult.getPoints();
|
||||||
|
out.status = r->tmpResult.getStatus();
|
||||||
|
out.time = r->tmpResult.getRunningTime();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (context.controlId.second == oPunch::PunchFinish) {
|
||||||
|
out.score = r->getRogainingPoints(false);
|
||||||
|
out.status = r->getStatus();
|
||||||
|
out.time = r->getRunningTime();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.score = 0; // Undefined
|
||||||
|
r->getSplitTime(context.controlId.second, out.status, out.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out.status == StatusUnknown && out.time > 0)
|
||||||
|
out.status = StatusOK;
|
||||||
|
|
||||||
|
if (out.status == StatusUnknown)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -42,8 +42,6 @@ protected:
|
|||||||
|
|
||||||
enum PrincipalSort {None, ClassWise, CourseWise};
|
enum PrincipalSort {None, ClassWise, CourseWise};
|
||||||
|
|
||||||
virtual PrincipalSort getPrincipalSort() const {return ClassWise;}
|
|
||||||
|
|
||||||
virtual int score(oTeam &team, RunnerStatus st, int time, int points) const;
|
virtual int score(oTeam &team, RunnerStatus st, int time, int points) const;
|
||||||
virtual RunnerStatus deduceStatus(oTeam &team) const;
|
virtual RunnerStatus deduceStatus(oTeam &team) const;
|
||||||
virtual int deduceTime(oTeam &team) const;
|
virtual int deduceTime(oTeam &team) const;
|
||||||
@ -64,6 +62,82 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
struct BaseResultContext {
|
||||||
|
private:
|
||||||
|
int leg;
|
||||||
|
bool useModule;
|
||||||
|
pair<int,int> controlId; // Start - finish
|
||||||
|
bool totalResults;
|
||||||
|
mutable map<int, pair<int, int> > resIntervalCache;
|
||||||
|
|
||||||
|
friend class GeneralResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeneralResultInfo {
|
||||||
|
oAbstractRunner *src;
|
||||||
|
int time;
|
||||||
|
RunnerStatus status;
|
||||||
|
int score;
|
||||||
|
int place;
|
||||||
|
|
||||||
|
int getNumSubresult(const BaseResultContext &context) const;
|
||||||
|
bool getSubResult(const BaseResultContext &context, int ix, GeneralResultInfo &out) const;
|
||||||
|
|
||||||
|
inline bool compareResult(const GeneralResultInfo &o) const {
|
||||||
|
if (status != o.status)
|
||||||
|
return RunnerStatusOrderMap[status] < RunnerStatusOrderMap[o.status];
|
||||||
|
|
||||||
|
if (place != o.place)
|
||||||
|
return place < o.place;
|
||||||
|
|
||||||
|
const wstring &name = src->getName();
|
||||||
|
const wstring &oname = o.src->getName();
|
||||||
|
|
||||||
|
return CompareString(LOCALE_USER_DEFAULT, 0,
|
||||||
|
name.c_str(), name.length(),
|
||||||
|
oname.c_str(), oname.length()) == CSTR_LESS_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const GeneralResultInfo &o) const {
|
||||||
|
pClass cls = src->getClassRef(true);
|
||||||
|
pClass ocls = o.src->getClassRef(true);
|
||||||
|
|
||||||
|
if (cls != ocls) {
|
||||||
|
int so = cls ? cls->getSortIndex() : 0;
|
||||||
|
int oso = ocls ? ocls->getSortIndex() : 0;
|
||||||
|
if (so != oso)
|
||||||
|
return so < oso;
|
||||||
|
|
||||||
|
// Use id as fallback
|
||||||
|
so = cls ? cls->getId() : 0;
|
||||||
|
oso = ocls ? ocls->getId() : 0;
|
||||||
|
if (so != oso)
|
||||||
|
return so < oso;
|
||||||
|
}
|
||||||
|
return compareResult(o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void calculateIndividualResults(vector<pRunner> &runners,
|
||||||
|
const pair<int, int> &controlId,
|
||||||
|
bool totalResults,
|
||||||
|
const string &resTag,
|
||||||
|
oListInfo::ResultType resType,
|
||||||
|
int inputNumber,
|
||||||
|
oEvent &oe,
|
||||||
|
vector<GeneralResultInfo> &results);
|
||||||
|
|
||||||
|
static shared_ptr<BaseResultContext> calculateTeamResults(vector<pTeam> &teams,
|
||||||
|
int leg,
|
||||||
|
const pair<int, int> &controlId,
|
||||||
|
bool totalResults,
|
||||||
|
const string &resTag,
|
||||||
|
oListInfo::ResultType resType,
|
||||||
|
int inputNumber,
|
||||||
|
oEvent &oe,
|
||||||
|
vector<GeneralResultInfo> &results);
|
||||||
|
|
||||||
void setContext(const oListParam *context);
|
void setContext(const oListParam *context);
|
||||||
void clearContext();
|
void clearContext();
|
||||||
|
|
||||||
|
|||||||
300
code/html1.htm
Normal file
300
code/html1.htm
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
<h1>Documentation of MeOS REST API</h1>
|
||||||
|
|
||||||
|
<h2>Competition</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=competition">/meos?get=competition</a></pre>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Competition XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*competition date="2015-09-06" organizer="Orienteringsklubben Linné" homepage="http://www.oklinne.nu">Stafett-DM, Uppland*/competition>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>Classes</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=class">/meos?get=class</a></pre>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Classes XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*cls id="1" ord="10" radio="90,130;90,130;90,130">D21*/cls>
|
||||||
|
*cls id="100" ord="1000" radio="90,130">M7*/cls>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<b>Remarks:</b> The attribute <i>ord</i> should be used to sort classes. The attribute <i>radio</i>
|
||||||
|
lists the MeOS default radio control for each class and leg.
|
||||||
|
Each leg of the class is separated by ';' and each radio control within a leg with ','.
|
||||||
|
Note that you may query for results at any control; the listed
|
||||||
|
controls are only for convenience.
|
||||||
|
|
||||||
|
<h2>Controls</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=control">/meos?get=control</a></pre>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Controls XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*control id="31">[31]*/control>
|
||||||
|
*control id="32">[32]*/control>
|
||||||
|
*control id="50">Radio 1*/control>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>Competitors</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=competitor">/meos?get=competitor</a></pre>
|
||||||
|
<pre>/meos?get=competitor#class=*c1>,*c2>,...</pre>
|
||||||
|
|
||||||
|
<b>Arguments:</b>
|
||||||
|
<ul><li><i>class</i> A list of one or more class id:s, separated by comma. The default is all classes.
|
||||||
|
</li></ul>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Competitors XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*cmp id="3565">
|
||||||
|
*base org="570" cls="5" stat="1" st="360000" rt="20580">Elsa Winter*/base>
|
||||||
|
*input it="20340" tstat="1"/>
|
||||||
|
*/cmp>
|
||||||
|
*cmp id="55851">
|
||||||
|
*base org="134" cls="7" stat="1" st="380710" rt="46910">Anna Spring*/base>
|
||||||
|
*/cmp>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<b>Remarks:</b>
|
||||||
|
Please refer to the MOP documentation for a complete description of all attributes. Below is a quick reference.
|
||||||
|
<ul>
|
||||||
|
<li><i>stat</i> Status code. 1 is OK, 0 is unknown. Higher codes are used for disqualifications.</li>
|
||||||
|
<li><i>st</i> Start time. In 1/10 seconds after 00:00:00.</li>
|
||||||
|
<li><i>rt</i> Running time. In 1/10 seconds.</li>
|
||||||
|
<li><i>input/it</i> Input running time accumulated from earlier races. In 1/10 seconds.</li>
|
||||||
|
<li><i>input/st</i> Input status from earlier races.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Teams</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=team">/meos?get=team</a></pre>
|
||||||
|
<pre>/meos?get=team#class=*c1>,*c2>,...</pre>
|
||||||
|
|
||||||
|
<b>Arguments:</b>
|
||||||
|
<ul><li><i>class</i> A list of one or more class id:s, separated by comma. The default is all classes.
|
||||||
|
</li></ul>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Teams XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*tm id="2928771">
|
||||||
|
*base org="396" cls="5" stat="1" st="360000" rt="65770">IF Thor 1*/base>
|
||||||
|
*r>34346;48866,866,0;32609*/r>
|
||||||
|
*/tm>
|
||||||
|
*tm id="2928346">
|
||||||
|
*base org="134" cls="5" stat="1" st="360000" rt="99660">OK Enen 1*/base>
|
||||||
|
*r>42020;55851;35732*/r>
|
||||||
|
*/tm>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<b>Remarks:</b>
|
||||||
|
Please refer to the MOP documentation for a complete description of all attributes. Below is a quick reference.
|
||||||
|
<ul>
|
||||||
|
<li><i>stat</i> Status code. 1 is OK, 0 is unknown. Higher codes are used for disqualifications.</li>
|
||||||
|
<li><i>st</i> Start time. In 1/10 seconds after 00:00:00.</li>
|
||||||
|
<li><i>rt</i> Running time (At finish, last leg). In 1/10 seconds.</li>
|
||||||
|
<li><i>r</i> List of runners in the team. A ';' is used to separate the legs, a ',' within a legs
|
||||||
|
are used to list paralell runners. A '0' indicates a vacant leg, which may or may
|
||||||
|
not be valid for the team, depending on the rules.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Organizations and Clubs</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=organization">/meos?get=organization</a></pre>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Organization XML</p>
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*org id="1012">BAOC*/org>
|
||||||
|
*org id="598">Dalaportens OL*/org>
|
||||||
|
*org id="133">Enebybergs IF*/org>
|
||||||
|
*org id="140">Falkenbergs OK*/org>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>Results</h2>
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=result">/meos?get=result</a></pre>
|
||||||
|
<pre>/meos?get=result#class=*c1>,*c2>,...</pre>
|
||||||
|
<pre>/meos?get=result#to=*c1></pre>
|
||||||
|
<pre>/meos?get=result#from=*c1></pre>
|
||||||
|
<pre>/meos?get=result#leg=*leg></pre>
|
||||||
|
<pre>/meos?get=result#module=*module></pre>
|
||||||
|
<pre>/meos?get=result#module=*module>#argument=*arg></pre>
|
||||||
|
<pre><a href="/meos?get=result&limit=1">/meos?get=result#limit=*limit></a></pre>
|
||||||
|
<pre><a href="/meos?get=result&total=true">/meos?get=result#total=*true/false></a></pre>
|
||||||
|
<pre><a href="/meos?get=result&type=GlobalIndividual">/meos?get=result#type=*type></a></pre>
|
||||||
|
|
||||||
|
<b>Arguments:</b>
|
||||||
|
<ul>
|
||||||
|
<li><i>class</i> A list of one or more class id:s, separated by comma. The default is all classes.</li>
|
||||||
|
<li><i>from</i> Returns the result measuring time from a specific control. If a specified class
|
||||||
|
does not visit the control, an empty result set is returned; no error is given.
|
||||||
|
The default is the start.</li>
|
||||||
|
<li><i>to</i> Returns the result at a specific control. If a specified class does not visit the control,
|
||||||
|
an empty result set is returned; no error is given. The default is the finish.</li>
|
||||||
|
|
||||||
|
<li><i>leg</i> In a team competition, returns result for a specified leg. If the leg is parallel,
|
||||||
|
the result is for the completed parallel leg. The leg number refer to the flat view in
|
||||||
|
MeOS class settings, i.e., for a setup "1, 2a, 2b, 2c, 3", correspons to flat leg numbers,
|
||||||
|
"1, 2, 3, 4, 5". The default is the last leg.</li>
|
||||||
|
<li><i>module</i> The result module tag to use for the result calculation.
|
||||||
|
The support of the leg and control options depends on result module. The default is no module.</li>
|
||||||
|
<li><i>argument</i> A numeric argument, defined and used by the result module.</li>
|
||||||
|
|
||||||
|
<li><i>limit</i> Limit the number of results per class. If there is a tie, the number of returned results
|
||||||
|
may be higher than the requested. The default is no limit.</li>
|
||||||
|
<li><i>total</i> Set to <b>true</b> if you want to calculate total results, i.e., results including earliers stages.</li>
|
||||||
|
|
||||||
|
<li><i>type</i> Use one of <b>ClassIndividual</b> (default for individual classes), <b>CourseIndividual</b>, <b>GlobalIndividual</b>, or
|
||||||
|
<b>LegIndividual</b> to calculate individual results. <b>CourseIndividual</b> calculates result
|
||||||
|
per course, ignoring class. <b>GlobalIndividual</b> calculates results without
|
||||||
|
considering classes, <b>LegIndividual</b> calculates results considering classes and legs.
|
||||||
|
Use one of <b>ClassTeam</b> (default for team classes) or <b>GlobalTeam</b> to calculate team
|
||||||
|
results. <b>GlobalTeam</b> calculates team results without considering classes.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>MOP Individual or Team Result XML. The result list is sorted according to the result. Note than disqualified
|
||||||
|
competitors are also included; for example a competitor with status *DNS> will be returned with this status for
|
||||||
|
all radio controls. You may want to filter out such entries, depending on your application.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<b>Examples:</b>
|
||||||
|
|
||||||
|
<p>Individual results at the finish.</p>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*results location="Finish">
|
||||||
|
*person cls="100" stat="1" st="387240" rt="21880" place="1">
|
||||||
|
*name id="134940">Isac Ulvesson*/name>
|
||||||
|
*org id="2184">BOIC*/org>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="100" stat="1" st="387700" rt="22720" place="2">
|
||||||
|
*name id="134923">Anne Brahe*/name>
|
||||||
|
*org id="2253">IFA*/org>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="100" stat="1" st="382570" rt="23260" place="3">
|
||||||
|
*name id="134914">Dan Andersson*/name>
|
||||||
|
*org id="5938">OK Kompassen*/org>
|
||||||
|
*/person>
|
||||||
|
*/results>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Team results, leg 2 at Radio 1, leg has three parallel runners.</p>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*results leg="2" location="Radio 1">
|
||||||
|
*team cls="6" stat="1" st="372000" rt="32030" place="1">
|
||||||
|
*name id="2927509">OK Linné 1*/name>
|
||||||
|
*org id="84">OK Linné*/org>
|
||||||
|
*person cls="6" leg="2" stat="1" st="392720" rt="11310">
|
||||||
|
*name id="52054">John Woods*/name>
|
||||||
|
*org id="84">OK Linné*/club>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="6" leg="3" stat="3" st="392720">
|
||||||
|
*name id="134850">Ralph Audoro*/name>
|
||||||
|
*org id="84">OK Linné*/org>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="6" leg="4" stat="1" st="392720" rt="12850">
|
||||||
|
*name id="134851">Niel Success*/name>
|
||||||
|
*club id="84">OK Linné*/club>
|
||||||
|
*/person>
|
||||||
|
*/team>
|
||||||
|
*/results>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Roganing results, Invoke with argument module=rogaining, which is a built in module.</p>
|
||||||
|
<pre>
|
||||||
|
*MOPComplete>
|
||||||
|
*results module="rogaining" location="Finish">
|
||||||
|
*person cls="1" stat="1" score="26" st="324000" rt="72550" place="1">
|
||||||
|
*name id="4">Omar Rue*/name>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="1" stat="1" score="25" st="324000" rt="72730" place="2">
|
||||||
|
*name id="3">Oscar Wilde*/name>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="1" stat="1" score="25" st="324000" rt="72780" place="3">
|
||||||
|
*name id="5">Alice Alison*/name>
|
||||||
|
*/person>
|
||||||
|
|
||||||
|
*person cls="1" stat="5" score="26" st="324000" rt="72590">
|
||||||
|
*name id="6">Reimund Rossinger*/name>
|
||||||
|
*/person>
|
||||||
|
*/results>
|
||||||
|
*/MOPComplete>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<b>Remarks:</b>
|
||||||
|
When and only when the type is <b>CourseIndividual</b>, the attribute <i>course/i> is included.
|
||||||
|
<pre>
|
||||||
|
*person cls="1" stat="1" st="324000" rt="72550" place="1" course=28>
|
||||||
|
*name id="4">Jordan Griesmer*/name>
|
||||||
|
*/person>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>IOF XML Results</h2>
|
||||||
|
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=iofresult">/meos?get=iofresult</a></pre>
|
||||||
|
<pre>/meos?get=iofresult#class=*c1>,*c2>,...</pre>
|
||||||
|
|
||||||
|
<b>Arguments:</b>
|
||||||
|
<ul>
|
||||||
|
<li><i>class</i> A list of one or more class id:s, separated by comma. The default is all classes.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>IOF XML version 3.0 result list.</p>
|
||||||
|
|
||||||
|
<h2>IOF XML Startlist</h2>
|
||||||
|
|
||||||
|
<b>Syntax:</b>
|
||||||
|
<pre><a href="/meos?get=iofstart">/meos?get=iofstart</a></pre>
|
||||||
|
<pre>/meos?get=iofstart#class=*c1>,*c2>,...</pre>
|
||||||
|
|
||||||
|
<b>Arguments:</b>
|
||||||
|
<ul>
|
||||||
|
<li><i>class</i> A list of one or more class id:s, separated by comma. The default is all classes.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<b>Returns:</b>
|
||||||
|
<p>IOF XML version 3.0 start list.</p>
|
||||||
@ -203,7 +203,7 @@ bool InfoCompetition::synchronize(oEvent &oe, bool onlyCmp, const set<int> &incl
|
|||||||
vector<pTeam> t;
|
vector<pTeam> t;
|
||||||
oe.getTeams(0, t, false);
|
oe.getTeams(0, t, false);
|
||||||
for (size_t k = 0; k < t.size(); k++) {
|
for (size_t k = 0; k < t.size(); k++) {
|
||||||
if (!includeCls.count(t[k]->getClassId()))
|
if (!includeCls.count(t[k]->getClassId(true)))
|
||||||
continue;
|
continue;
|
||||||
int wid = t[k]->getId();
|
int wid = t[k]->getId();
|
||||||
knownId.insert(wid);
|
knownId.insert(wid);
|
||||||
@ -228,7 +228,7 @@ bool InfoCompetition::synchronize(oEvent &oe, bool onlyCmp, const set<int> &incl
|
|||||||
vector<pRunner> r;
|
vector<pRunner> r;
|
||||||
oe.getRunners(0, 0, r, false);
|
oe.getRunners(0, 0, r, false);
|
||||||
for (size_t k = 0; k < r.size(); k++) {
|
for (size_t k = 0; k < r.size(); k++) {
|
||||||
if (!includeCls.count(r[k]->getClassId()))
|
if (!includeCls.count(r[k]->getClassId(true)))
|
||||||
continue;
|
continue;
|
||||||
int wid = r[k]->getId();
|
int wid = r[k]->getId();
|
||||||
knownId.insert(wid);
|
knownId.insert(wid);
|
||||||
@ -397,7 +397,7 @@ bool InfoBaseCompetitor::synchronizeBase(oAbstractRunner &bc) {
|
|||||||
ch = true;
|
ch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cls = bc.getClassId();
|
int cls = bc.getClassId(true);
|
||||||
if (cls != classId) {
|
if (cls != classId) {
|
||||||
classId = cls;
|
classId = cls;
|
||||||
ch = true;
|
ch = true;
|
||||||
@ -463,8 +463,8 @@ bool InfoCompetitor::synchronize(const InfoCompetition &cmp, oRunner &r) {
|
|||||||
bool ch = synchronize(useTotalResults, r);
|
bool ch = synchronize(useTotalResults, r);
|
||||||
|
|
||||||
vector<RadioTime> newRT;
|
vector<RadioTime> newRT;
|
||||||
if (r.getClassId() > 0) {
|
if (r.getClassId(false) > 0) {
|
||||||
const vector<int> &radios = cmp.getControls(r.getClassId(), r.getLegNumber());
|
const vector<int> &radios = cmp.getControls(r.getClassId(false), r.getLegNumber());
|
||||||
for (size_t k = 0; k < radios.size(); k++) {
|
for (size_t k = 0; k < radios.size(); k++) {
|
||||||
RadioTime radioTime;
|
RadioTime radioTime;
|
||||||
RunnerStatus s_split;
|
RunnerStatus s_split;
|
||||||
@ -520,7 +520,7 @@ void InfoCompetitor::serialize(xmlbuffer &xml, bool diffOnly) const {
|
|||||||
bool InfoTeam::synchronize(oTeam &t) {
|
bool InfoTeam::synchronize(oTeam &t) {
|
||||||
bool ch = synchronizeBase(t);
|
bool ch = synchronizeBase(t);
|
||||||
|
|
||||||
const pClass cls = t.getClassRef();
|
const pClass cls = t.getClassRef(true);
|
||||||
if (cls) {
|
if (cls) {
|
||||||
vector< vector<int> > r;
|
vector< vector<int> > r;
|
||||||
|
|
||||||
|
|||||||
@ -127,12 +127,13 @@ class InfoClass : public InfoBase {
|
|||||||
class InfoOrganization : public InfoBase {
|
class InfoOrganization : public InfoBase {
|
||||||
protected:
|
protected:
|
||||||
wstring name;
|
wstring name;
|
||||||
bool synchronize(oClub &c);
|
|
||||||
void serialize(xmlbuffer &xml, bool diffOnly) const;
|
|
||||||
public:
|
public:
|
||||||
InfoOrganization(int id);
|
InfoOrganization(int id);
|
||||||
virtual ~InfoOrganization() {}
|
virtual ~InfoOrganization() {}
|
||||||
|
|
||||||
|
bool synchronize(oClub &c);
|
||||||
|
void serialize(xmlbuffer &xml, bool diffOnly) const;
|
||||||
|
|
||||||
friend class InfoCompetition;
|
friend class InfoCompetition;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -183,9 +184,10 @@ class InfoTeam : public InfoBaseCompetitor {
|
|||||||
protected:
|
protected:
|
||||||
// The outer level holds legs, the inner level holds (parallel/patrol) runners on each leg.
|
// The outer level holds legs, the inner level holds (parallel/patrol) runners on each leg.
|
||||||
vector< vector<int> > competitors;
|
vector< vector<int> > competitors;
|
||||||
|
public:
|
||||||
bool synchronize(oTeam &t);
|
bool synchronize(oTeam &t);
|
||||||
void serialize(xmlbuffer &xml, bool diffOnly) const;
|
void serialize(xmlbuffer &xml, bool diffOnly) const;
|
||||||
public:
|
|
||||||
InfoTeam(int id);
|
InfoTeam(int id);
|
||||||
virtual ~InfoTeam() {}
|
virtual ~InfoTeam() {}
|
||||||
friend class InfoCompetition;
|
friend class InfoCompetition;
|
||||||
|
|||||||
@ -335,7 +335,7 @@ void IOF30Interface::personCourseAssignment(gdioutput &gdi, xmlList &xAssignment
|
|||||||
xPAssignment.getObjectString("ClassName", cls);
|
xPAssignment.getObjectString("ClassName", cls);
|
||||||
multimap<wstring, pRunner>::const_iterator res = name2Runner.find(person);
|
multimap<wstring, pRunner>::const_iterator res = name2Runner.find(person);
|
||||||
while (res != name2Runner.end() && person == res->first) {
|
while (res != name2Runner.end() && person == res->first) {
|
||||||
if (cls.empty() || res->second->getClass() == cls) {
|
if (cls.empty() || res->second->getClass(false) == cls) {
|
||||||
r = res->second;
|
r = res->second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -386,7 +386,7 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
|||||||
if (!bib.empty())
|
if (!bib.empty())
|
||||||
bib2Team[bib] = allT[k];
|
bib2Team[bib] = allT[k];
|
||||||
|
|
||||||
nameClass2Team[make_pair(allT[k]->getName(), allT[k]->getClass())] = allT[k];
|
nameClass2Team[make_pair(allT[k]->getName(), allT[k]->getClass(false))] = allT[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t k = 0; k < xAssignment.size(); k++) {
|
for (size_t k = 0; k < xAssignment.size(); k++) {
|
||||||
@ -426,7 +426,7 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
|||||||
void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAssignment,
|
void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAssignment,
|
||||||
const map<wstring, pCourse> &courses) {
|
const map<wstring, pCourse> &courses) {
|
||||||
|
|
||||||
if (!team.getClassRef())
|
if (!team.getClassRef(false))
|
||||||
return;
|
return;
|
||||||
for (size_t k = 0; k <xAssignment.size(); k++) {
|
for (size_t k = 0; k <xAssignment.size(); k++) {
|
||||||
|
|
||||||
@ -443,11 +443,11 @@ void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAss
|
|||||||
if (xLegOrder)
|
if (xLegOrder)
|
||||||
legorder = xLegOrder.getInt() - 1;
|
legorder = xLegOrder.getInt() - 1;
|
||||||
|
|
||||||
int legId = team.getClassRef()->getLegNumberLinear(leg, legorder);
|
int legId = team.getClassRef(false)->getLegNumberLinear(leg, legorder);
|
||||||
if (legId>=0) {
|
if (legId>=0) {
|
||||||
pRunner r = team.getRunner(legId);
|
pRunner r = team.getRunner(legId);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
r = oe.addRunner(lang.tl(L"N.N."), team.getClubId(), team.getClassId(), 0, 0, false);
|
r = oe.addRunner(lang.tl(L"N.N."), team.getClubId(), team.getClassId(false), 0, 0, false);
|
||||||
if (r) {
|
if (r) {
|
||||||
r->setEntrySource(entrySourceId);
|
r->setEntrySource(entrySourceId);
|
||||||
r->flagEntryTouched(true);
|
r->flagEntryTouched(true);
|
||||||
@ -460,7 +460,7 @@ void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAss
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gdi.addString("", 0, L"Bantilldelning för 'X' hänvisar till en sträcka som inte finns#" + team.getClass()).setColor(colorRed);
|
gdi.addString("", 0, L"Bantilldelning för 'X' hänvisar till en sträcka som inte finns#" + team.getClass(false)).setColor(colorRed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wstring name;
|
wstring name;
|
||||||
@ -543,8 +543,8 @@ void IOF30Interface::classAssignmentObsolete(gdioutput &gdi, xmlList &xAssignmen
|
|||||||
for (bibIterT it = range.first; it != range.second; ++it) {
|
for (bibIterT it = range.first; it != range.second; ++it) {
|
||||||
int ln = it->second->getLegNumber();
|
int ln = it->second->getLegNumber();
|
||||||
int rLegNumber = 0, rLegOrder = 0;
|
int rLegNumber = 0, rLegOrder = 0;
|
||||||
if (it->second->getClassRef())
|
if (it->second->getClassRef(false))
|
||||||
it->second->getClassRef()->splitLegNumberParallel(ln, rLegNumber, rLegOrder);
|
it->second->getClassRef(false)->splitLegNumberParallel(ln, rLegNumber, rLegOrder);
|
||||||
bool match = true;
|
bool match = true;
|
||||||
if (leg != 0 && leg != rLegNumber+1)
|
if (leg != 0 && leg != rLegNumber+1)
|
||||||
match = false;
|
match = false;
|
||||||
@ -569,14 +569,14 @@ void IOF30Interface::classAssignmentObsolete(gdioutput &gdi, xmlList &xAssignmen
|
|||||||
vector<pTeam> t;
|
vector<pTeam> t;
|
||||||
oe.getTeams(0, t);
|
oe.getTeams(0, t);
|
||||||
for (size_t i = 0; i < t.size(); i++)
|
for (size_t i = 0; i < t.size(); i++)
|
||||||
clsName2Team[make_pair(t[i]->getClass(), t[i]->getName())] = t[i];
|
clsName2Team[make_pair(t[i]->getClass(false), t[i]->getName())] = t[i];
|
||||||
c2TeamInit = true;
|
c2TeamInit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
teamIterT res = clsName2Team.find(make_pair(className, teamName));
|
teamIterT res = clsName2Team.find(make_pair(className, teamName));
|
||||||
|
|
||||||
if (res != clsName2Team.end()) {
|
if (res != clsName2Team.end()) {
|
||||||
pClass cls = res->second->getClassRef();
|
pClass cls = res->second->getClassRef(false);
|
||||||
if (cls) {
|
if (cls) {
|
||||||
int ln = cls->getLegNumberLinear(leg, legOrder);
|
int ln = cls->getLegNumberLinear(leg, legOrder);
|
||||||
pRunner r = res->second->getRunner(ln);
|
pRunner r = res->second->getRunner(ln);
|
||||||
@ -863,7 +863,7 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
|
|||||||
key[j] = it->second[j].second;
|
key[j] = it->second[j].second;
|
||||||
|
|
||||||
sort(key.begin(), key.end());
|
sort(key.begin(), key.end());
|
||||||
classLegEqClasses[t->getClassId()].insert(key);
|
classLegEqClasses[t->getClassId(false)].insert(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1326,7 +1326,7 @@ pTeam IOF30Interface::readTeamEntry(gdioutput &gdi, xmlobject &xTeam,
|
|||||||
map<int, vector<LegInfo> > localTeamClassConfig;
|
map<int, vector<LegInfo> > localTeamClassConfig;
|
||||||
pClass pc = readClass(xTeam.getObject("Class"), localTeamClassConfig);
|
pClass pc = readClass(xTeam.getObject("Class"), localTeamClassConfig);
|
||||||
|
|
||||||
if (pc && (t->getClassId() == 0 || !t->hasFlag(oAbstractRunner::FlagUpdateClass)) ) {
|
if (pc && (t->getClassId(false) == 0 || !t->hasFlag(oAbstractRunner::FlagUpdateClass)) ) {
|
||||||
t->setClassId(pc->getId(), false);
|
t->setClassId(pc->getId(), false);
|
||||||
}
|
}
|
||||||
wstring bib;
|
wstring bib;
|
||||||
@ -1392,7 +1392,7 @@ pTeam IOF30Interface::readTeamStart(gdioutput &gdi, pClass pc, xmlobject &xTeam,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Class
|
// Class
|
||||||
if (pc && (t->getClassId() == 0 || !t->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
if (pc && (t->getClassId(false) == 0 || !t->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
||||||
t->setClassId(pc->getId(), false);
|
t->setClassId(pc->getId(), false);
|
||||||
|
|
||||||
wstring bib;
|
wstring bib;
|
||||||
@ -1534,7 +1534,7 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
|
|||||||
|
|
||||||
if (cardNo > 0 && r == 0 && team) {
|
if (cardNo > 0 && r == 0 && team) {
|
||||||
// We got no person, but a card number. Add the runner anonymously.
|
// We got no person, but a card number. Add the runner anonymously.
|
||||||
r = oe.addRunner(lang.tl(L"N.N."), team->getClubId(), team->getClassId(), cardNo, 0, false);
|
r = oe.addRunner(lang.tl(L"N.N."), team->getClubId(), team->getClassId(false), cardNo, 0, false);
|
||||||
r->flagEntryTouched(true);
|
r->flagEntryTouched(true);
|
||||||
r->setEntrySource(entrySourceId);
|
r->setEntrySource(entrySourceId);
|
||||||
r->synchronize();
|
r->synchronize();
|
||||||
@ -1555,21 +1555,21 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
|
|||||||
map<int, vector<LegInfo> > localTeamClassConfig;
|
map<int, vector<LegInfo> > localTeamClassConfig;
|
||||||
pClass pc = readClass(xo.getObject("Class"), localTeamClassConfig);
|
pClass pc = readClass(xo.getObject("Class"), localTeamClassConfig);
|
||||||
|
|
||||||
if (pc && (r->getClassId() == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
if (pc && (r->getClassId(false) == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
||||||
r->setClassId(pc->getId(), false);
|
r->setClassId(pc->getId(), false);
|
||||||
|
|
||||||
if (team) {
|
if (team) {
|
||||||
int leg = xo.getObjectInt("Leg");
|
int leg = xo.getObjectInt("Leg");
|
||||||
int legorder = xo.getObjectInt("LegOrder");
|
int legorder = xo.getObjectInt("LegOrder");
|
||||||
int legindex = max(0, leg - 1);
|
int legindex = max(0, leg - 1);
|
||||||
map<int, vector<LegInfo> >::const_iterator res = teamClassConfig.find(team->getClassId());
|
map<int, vector<LegInfo> >::const_iterator res = teamClassConfig.find(team->getClassId(false));
|
||||||
if (res != teamClassConfig.end()) {
|
if (res != teamClassConfig.end()) {
|
||||||
legindex = getIndexFromLegPos(leg, legorder, res->second);
|
legindex = getIndexFromLegPos(leg, legorder, res->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (personId2TeamLeg.find(r->getId()) == personId2TeamLeg.end()) {
|
if (personId2TeamLeg.find(r->getId()) == personId2TeamLeg.end()) {
|
||||||
if (team->getClassRef())
|
if (team->getClassRef(false))
|
||||||
legindex = team->getClassRef()->getLegRunner(legindex);
|
legindex = team->getClassRef(false)->getLegRunner(legindex);
|
||||||
|
|
||||||
// Ensure unique
|
// Ensure unique
|
||||||
team->setRunner(legindex, r, false);
|
team->setRunner(legindex, r, false);
|
||||||
@ -1676,7 +1676,7 @@ pRunner IOF30Interface::readPersonStart(gdioutput &gdi, pClass pc, xmlobject &xo
|
|||||||
int leg = starts[k].getObjectInt("Leg");
|
int leg = starts[k].getObjectInt("Leg");
|
||||||
int legorder = starts[k].getObjectInt("LegOrder");
|
int legorder = starts[k].getObjectInt("LegOrder");
|
||||||
int legindex = max(0, leg - 1);
|
int legindex = max(0, leg - 1);
|
||||||
map<int, vector<LegInfo> >::const_iterator res = teamClassConfig.find(team->getClassId());
|
map<int, vector<LegInfo> >::const_iterator res = teamClassConfig.find(team->getClassId(false));
|
||||||
if (res != teamClassConfig.end()) {
|
if (res != teamClassConfig.end()) {
|
||||||
legindex = getIndexFromLegPos(leg, legorder, res->second);
|
legindex = getIndexFromLegPos(leg, legorder, res->second);
|
||||||
}
|
}
|
||||||
@ -1698,7 +1698,7 @@ pRunner IOF30Interface::readPersonStart(gdioutput &gdi, pClass pc, xmlobject &xo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pc && (r->getClassId() == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
if (pc && (r->getClassId(false) == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass)) )
|
||||||
r->setClassId(pc->getId(), true);
|
r->setClassId(pc->getId(), true);
|
||||||
|
|
||||||
r->synchronize();
|
r->synchronize();
|
||||||
@ -1961,7 +1961,7 @@ void IOF30Interface::writeAssignedFee(xmlparser &xml, const oAbstractRunner &tr,
|
|||||||
if (paid >= paidForCard) {
|
if (paid >= paidForCard) {
|
||||||
paid -= paidForCard; // Included in card service fee
|
paid -= paidForCard; // Included in card service fee
|
||||||
}
|
}
|
||||||
const pClass pc = tr.getClassRef();
|
const oClass *pc = tr.getClassRef(false);
|
||||||
if (!splitLateFee || !pc || !tr.hasLateEntryFee()) {
|
if (!splitLateFee || !pc || !tr.hasLateEntryFee()) {
|
||||||
xml.startTag("AssignedFee");
|
xml.startTag("AssignedFee");
|
||||||
string type = tr.hasLateEntryFee() ? "Late" : "Normal";
|
string type = tr.hasLateEntryFee() ? "Late" : "Normal";
|
||||||
@ -2476,7 +2476,6 @@ void IOF30Interface::writeClass(xmlparser &xml, const oClass &c) {
|
|||||||
else if (stat == oClass::InvalidRefund)
|
else if (stat == oClass::InvalidRefund)
|
||||||
xml.write("Status", L"InvalidatedNoFee");
|
xml.write("Status", L"InvalidatedNoFee");
|
||||||
|
|
||||||
|
|
||||||
xml.endTag();
|
xml.endTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2537,7 +2536,7 @@ void IOF30Interface::writePersonResult(xmlparser &xml, const oRunner &r,
|
|||||||
if (teamMember) {
|
if (teamMember) {
|
||||||
oRunner const *resultHolder = &r;
|
oRunner const *resultHolder = &r;
|
||||||
cTeam t = r.getTeam();
|
cTeam t = r.getTeam();
|
||||||
pClass cls = r.getClassRef();
|
const oClass *cls = r.getClassRef(false);
|
||||||
|
|
||||||
if (t && cls) {
|
if (t && cls) {
|
||||||
int leg = r.getLegNumber();
|
int leg = r.getLegNumber();
|
||||||
@ -2614,9 +2613,9 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
|||||||
xml.write("TimeBehind", after);
|
xml.write("TimeBehind", after);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.getClassRef()) {
|
if (r.getClassRef(false)) {
|
||||||
|
|
||||||
if (r.statusOK() && r.getClassRef()->getNoTiming() == false) {
|
if (r.statusOK() && r.getClassRef(false)->getNoTiming() == false) {
|
||||||
if (!teamMember && r.getPlace() > 0 && r.getPlace() < 50000) {
|
if (!teamMember && r.getPlace() > 0 && r.getPlace() < 50000) {
|
||||||
xml.write("Position", r.getPlace());
|
xml.write("Position", r.getPlace());
|
||||||
}
|
}
|
||||||
@ -2634,19 +2633,19 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
|||||||
|
|
||||||
xml.write("Status", formatStatus(r.getStatus()));
|
xml.write("Status", formatStatus(r.getStatus()));
|
||||||
|
|
||||||
if ( (r.getTeam() && r.getClassRef()->getClassType() != oClassPatrol && !teamsAsIndividual) || hasInputTime) {
|
if ( (r.getTeam() && r.getClassRef(false)->getClassType() != oClassPatrol && !teamsAsIndividual) || hasInputTime) {
|
||||||
xml.startTag("OverallResult");
|
xml.startTag("OverallResult");
|
||||||
int rt = r.getTotalRunningTime();
|
int rt = r.getTotalRunningTime();
|
||||||
if (rt > 0)
|
if (rt > 0)
|
||||||
xml.write("Time", rt);
|
xml.write("Time", rt);
|
||||||
|
|
||||||
bool hasTiming = r.getClassRef()->getNoTiming() == false;
|
bool hasTiming = r.getClassRef(false)->getNoTiming() == false;
|
||||||
RunnerStatus stat = r.getTotalStatus();
|
RunnerStatus stat = r.getTotalStatus();
|
||||||
|
|
||||||
int tleg = r.getLegNumber() >= 0 ? r.getLegNumber() : 0;
|
int tleg = r.getLegNumber() >= 0 ? r.getLegNumber() : 0;
|
||||||
|
|
||||||
if (stat == StatusOK && hasTiming) {
|
if (stat == StatusOK && hasTiming) {
|
||||||
int after = r.getTotalRunningTime() - r.getClassRef()->getTotalLegLeaderTime(tleg, true);
|
int after = r.getTotalRunningTime() - r.getClassRef(true)->getTotalLegLeaderTime(tleg, true);
|
||||||
if (after >= 0)
|
if (after >= 0)
|
||||||
xml.write("TimeBehind", after);
|
xml.write("TimeBehind", after);
|
||||||
}
|
}
|
||||||
@ -3100,7 +3099,7 @@ void IOF30Interface::writeStart(xmlparser &xml, const oRunner &r,
|
|||||||
void IOF30Interface::writeLegOrder(xmlparser &xml, const oRunner &r) const {
|
void IOF30Interface::writeLegOrder(xmlparser &xml, const oRunner &r) const {
|
||||||
// Team member race result
|
// Team member race result
|
||||||
int legNumber, legOrder;
|
int legNumber, legOrder;
|
||||||
const pClass pc = r.getClassRef();
|
const oClass *pc = r.getClassRef(false);
|
||||||
if (pc) {
|
if (pc) {
|
||||||
bool par = pc->splitLegNumberParallel(r.getLegNumber(), legNumber, legOrder);
|
bool par = pc->splitLegNumberParallel(r.getLegNumber(), legNumber, legOrder);
|
||||||
xml.write("Leg", legNumber + 1);
|
xml.write("Leg", legNumber + 1);
|
||||||
|
|||||||
@ -112,7 +112,7 @@ void LiveResult::showTimer(gdioutput &gdi, const oListInfo &liIn) {
|
|||||||
pair<int, int> key = make_pair(r->getId(), pp[k]->getControlId());
|
pair<int, int> key = make_pair(r->getId(), pp[k]->getControlId());
|
||||||
processedPunches[key] = max(processedPunches[key], pp[k]->getAdjustedTime());
|
processedPunches[key] = max(processedPunches[key], pp[k]->getAdjustedTime());
|
||||||
|
|
||||||
if (!li.getParam().selection.empty() && !li.getParam().selection.count(r->getClassId()))
|
if (!li.getParam().selection.empty() && !li.getParam().selection.count(r->getClassId(true)))
|
||||||
continue; // Filter class
|
continue; // Filter class
|
||||||
|
|
||||||
if (pp[k]->getTypeCode() == fromPunch) {
|
if (pp[k]->getTypeCode() == fromPunch) {
|
||||||
@ -182,7 +182,7 @@ void LiveResult::handle(gdioutput &gdi, BaseInfo &bu, GuiEventType type) {
|
|||||||
if (!r)
|
if (!r)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.getParam().selection.empty() && !li.getParam().selection.count(r->getClassId()))
|
if (!li.getParam().selection.empty() && !li.getParam().selection.count(r->getClassId(true)))
|
||||||
continue; // Filter class
|
continue; // Filter class
|
||||||
|
|
||||||
pair<int, int> key = make_pair(r->getId(), pp[k]->getControlId());
|
pair<int, int> key = make_pair(r->getId(), pp[k]->getControlId());
|
||||||
|
|||||||
@ -1149,6 +1149,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
delete gSI;
|
delete gSI;
|
||||||
gSI=0;
|
gSI=0;
|
||||||
|
|
||||||
|
for (size_t k = 0; k < gdi_extra.size(); k++) {
|
||||||
|
if (gdi_extra[k])
|
||||||
|
gdi_extra[k]->clearPage(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (gEvent) {
|
if (gEvent) {
|
||||||
try {
|
try {
|
||||||
gEvent->save();
|
gEvent->save();
|
||||||
|
|||||||
28
code/meos.rc
28
code/meos.rc
@ -28,10 +28,29 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||||||
//
|
//
|
||||||
|
|
||||||
BMP_TEST BITMAP "bitmap1.bmp"
|
BMP_TEST BITMAP "bitmap1.bmp"
|
||||||
|
|
||||||
#endif // Neutral resources
|
#endif // Neutral resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Neutral (Default) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD)
|
||||||
|
LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
|
||||||
|
#pragma code_page(1252)
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Bitmap
|
||||||
|
//
|
||||||
|
|
||||||
|
IDB_ECO BITMAP "bmp00001.bmp"
|
||||||
|
|
||||||
|
#endif // Neutral (Default) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// English (United States) resources
|
// English (United States) resources
|
||||||
|
|
||||||
@ -48,6 +67,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
// remains consistent on all systems.
|
// remains consistent on all systems.
|
||||||
IDI_MEOS ICON "meos.ICO"
|
IDI_MEOS ICON "meos.ICO"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Menu
|
// Menu
|
||||||
@ -160,6 +180,14 @@ BEGIN
|
|||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// HTML
|
||||||
|
//
|
||||||
|
|
||||||
|
IDR_HTML1 HTML "html1.htm"
|
||||||
|
|
||||||
#endif // Swedish (Sweden) resources
|
#endif // Swedish (Sweden) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@ -1368,7 +1368,7 @@ static void decomposeClassName(const wstring &name, vector<wstring> &dec) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < name.size(); i++) {
|
for (size_t i = 0; i < name.size(); i++) {
|
||||||
int bchar = toLowerStripped(name[i]);
|
int bchar = toLowerStripped(name[i]);
|
||||||
if (isspace(bchar) || bchar == '-' || bchar == 160) {
|
if (myIsSpace(bchar) || bchar == '-' || bchar == 160) {
|
||||||
if (!dec.back().empty())
|
if (!dec.back().empty())
|
||||||
dec.push_back(wstring());
|
dec.push_back(wstring());
|
||||||
continue;
|
continue;
|
||||||
@ -1823,7 +1823,7 @@ void capitalize(wstring &str) {
|
|||||||
int getTimeZoneInfo(const wstring &date) {
|
int getTimeZoneInfo(const wstring &date) {
|
||||||
static wchar_t lastDate[16] = {0};
|
static wchar_t lastDate[16] = {0};
|
||||||
static int lastValue = -1;
|
static int lastValue = -1;
|
||||||
// Local cacheing
|
// Local caching
|
||||||
if (lastValue != -1 && lastDate == date) {
|
if (lastValue != -1 && lastDate == date) {
|
||||||
return lastValue;
|
return lastValue;
|
||||||
}
|
}
|
||||||
@ -2161,8 +2161,14 @@ void processGeneralTime(const wstring &generalTime, wstring &meosTime, wstring &
|
|||||||
}
|
}
|
||||||
|
|
||||||
void string2Wide(const string &in, wstring &out) {
|
void string2Wide(const string &in, wstring &out) {
|
||||||
out.clear();
|
int cp = 1252;
|
||||||
out.insert(out.begin(), in.begin(), in.end());// XXX Simple extend
|
if (in.empty()) {
|
||||||
|
out = L"";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.reserve(in.size() + 1);
|
||||||
|
out.resize(in.size(), 0);
|
||||||
|
MultiByteToWideChar(cp, MB_PRECOMPOSED, in.c_str(), in.size(), &out[0], out.size() * sizeof(wchar_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wide2String(const wstring &in, string &out) {
|
void wide2String(const wstring &in, string &out) {
|
||||||
|
|||||||
@ -1906,7 +1906,7 @@ OpFailStatus MeosSQL::syncUpdate(oRunner *r, bool forceWriteAll)
|
|||||||
<< " StartTime=" << r->startTime << ", "
|
<< " StartTime=" << r->startTime << ", "
|
||||||
<< " FinishTime=" << r->FinishTime << ", "
|
<< " FinishTime=" << r->FinishTime << ", "
|
||||||
<< " Course=" << r->getCourseId() << ", "
|
<< " Course=" << r->getCourseId() << ", "
|
||||||
<< " Class=" << r->getClassId() << ", "
|
<< " Class=" << r->getClassId(false) << ", "
|
||||||
<< " Club=" << r->getClubId() << ", "
|
<< " Club=" << r->getClubId() << ", "
|
||||||
<< " Card=" << r->getCardId() << ", "
|
<< " Card=" << r->getCardId() << ", "
|
||||||
<< " Status=" << r->status << ", "
|
<< " Status=" << r->status << ", "
|
||||||
@ -2101,7 +2101,7 @@ OpFailStatus MeosSQL::syncUpdate(oTeam *t, bool forceWriteAll) {
|
|||||||
<< " Runners=" << quote << t->getRunners() << ", "
|
<< " Runners=" << quote << t->getRunners() << ", "
|
||||||
<< " StartTime=" << t->startTime << ", "
|
<< " StartTime=" << t->startTime << ", "
|
||||||
<< " FinishTime=" << t->FinishTime << ", "
|
<< " FinishTime=" << t->FinishTime << ", "
|
||||||
<< " Class=" << t->getClassId() << ", "
|
<< " Class=" << t->getClassId(false) << ", "
|
||||||
<< " Club=" << t->getClubId() << ", "
|
<< " Club=" << t->getClubId() << ", "
|
||||||
<< " StartNo=" << t->getStartNo() << ", "
|
<< " StartNo=" << t->getStartNo() << ", "
|
||||||
<< " Status=" << t->status
|
<< " Status=" << t->status
|
||||||
|
|||||||
@ -335,6 +335,7 @@
|
|||||||
<ClCompile Include="prefseditor.cpp" />
|
<ClCompile Include="prefseditor.cpp" />
|
||||||
<ClCompile Include="printer.cpp" />
|
<ClCompile Include="printer.cpp" />
|
||||||
<ClCompile Include="progress.cpp" />
|
<ClCompile Include="progress.cpp" />
|
||||||
|
<ClCompile Include="qualification_final.cpp" />
|
||||||
<ClCompile Include="random.cpp">
|
<ClCompile Include="random.cpp">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -420,6 +421,7 @@
|
|||||||
<ClInclude Include="pdfwriter.h" />
|
<ClInclude Include="pdfwriter.h" />
|
||||||
<ClInclude Include="prefseditor.h" />
|
<ClInclude Include="prefseditor.h" />
|
||||||
<ClInclude Include="Printer.h" />
|
<ClInclude Include="Printer.h" />
|
||||||
|
<ClInclude Include="qualification_final.h" />
|
||||||
<ClInclude Include="recorder.h" />
|
<ClInclude Include="recorder.h" />
|
||||||
<ClInclude Include="restserver.h" />
|
<ClInclude Include="restserver.h" />
|
||||||
<ClInclude Include="RestService.h" />
|
<ClInclude Include="RestService.h" />
|
||||||
@ -482,6 +484,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="bitmap1.bmp" />
|
<None Include="bitmap1.bmp" />
|
||||||
|
<None Include="html1.htm">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</None>
|
||||||
<None Include="meos.ico" />
|
<None Include="meos.ico" />
|
||||||
<None Include="small.ico" />
|
<None Include="small.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -27,9 +27,9 @@
|
|||||||
//V2: ABCDEFGHIHJKMN
|
//V2: ABCDEFGHIHJKMN
|
||||||
//V31: a
|
//V31: a
|
||||||
//V33: abcde
|
//V33: abcde
|
||||||
//V35: abc
|
//V35: abcde
|
||||||
int getMeosBuild() {
|
int getMeosBuild() {
|
||||||
string revision("$Rev: 621 $");
|
string revision("$Rev: 634 $");
|
||||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ int getMeosBuild() {
|
|||||||
//V33: abcdefghij
|
//V33: abcdefghij
|
||||||
//V34: abcdfg
|
//V34: abcdfg
|
||||||
wstring getMeosDate() {
|
wstring getMeosDate() {
|
||||||
wstring date(L"$Date: 2017-10-21 22:43:38 +0200 (lö, 21 okt 2017) $");
|
wstring date(L"$Date: 2017-12-25 16:08:33 +0100 (må, 25 dec 2017) $");
|
||||||
return date.substr(7,10);
|
return date.substr(7,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ void getSupporters(vector<string> &supp)
|
|||||||
supp.push_back("Oskarström OK");
|
supp.push_back("Oskarström OK");
|
||||||
supp.push_back("Skogslöparna");
|
supp.push_back("Skogslöparna");
|
||||||
supp.push_back("OK Milan");
|
supp.push_back("OK Milan");
|
||||||
supp.push_back("GoIF Tjalve");
|
supp.push_back("Tjalve IF");
|
||||||
supp.push_back("OK Skärmen");
|
supp.push_back("OK Skärmen");
|
||||||
supp.push_back("Østkredsen");
|
supp.push_back("Østkredsen");
|
||||||
supp.push_back("OK Roskilde");
|
supp.push_back("OK Roskilde");
|
||||||
@ -177,4 +177,7 @@ void getSupporters(vector<string> &supp)
|
|||||||
supp.push_back("Åke Larsson, OK Hedströmmen");
|
supp.push_back("Åke Larsson, OK Hedströmmen");
|
||||||
supp.push_back("Avesta OK");
|
supp.push_back("Avesta OK");
|
||||||
supp.push_back("Motionsorientering Göteborg");
|
supp.push_back("Motionsorientering Göteborg");
|
||||||
|
supp.push_back("OK Måsen");
|
||||||
|
supp.push_back("IF Thor");
|
||||||
|
supp.push_back("SOS Jindrichuv Hradec");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,7 @@ oBase::oBase(oEvent *poe)
|
|||||||
counter = 0;
|
counter = 0;
|
||||||
Modified.update();
|
Modified.update();
|
||||||
correctionNeeded = true;
|
correctionNeeded = true;
|
||||||
|
localObject = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
oBase::~oBase()
|
oBase::~oBase()
|
||||||
@ -68,6 +69,8 @@ bool oBase::synchronize(bool writeOnly)
|
|||||||
}
|
}
|
||||||
if (oe && oe->HasDBConnection && (changed || !writeOnly)) {
|
if (oe && oe->HasDBConnection && (changed || !writeOnly)) {
|
||||||
correctionNeeded = false;
|
correctionNeeded = false;
|
||||||
|
if (localObject)
|
||||||
|
return false;
|
||||||
return oe->msSynchronize(this);
|
return oe->msSynchronize(this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -79,17 +82,6 @@ bool oBase::synchronize(bool writeOnly)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void oBase::clearCombo(HWND hWnd)
|
|
||||||
{
|
|
||||||
SendMessage(hWnd, CB_RESETCONTENT, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void oBase::addToCombo(HWND hWnd, const string &str, int data)
|
|
||||||
{
|
|
||||||
int index=SendMessage(hWnd, CB_ADDSTRING, 0, LPARAM(str.c_str()));
|
|
||||||
SendMessage(hWnd, CB_SETITEMDATA, index, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void oBase::setExtIdentifier(__int64 id)
|
void oBase::setExtIdentifier(__int64 id)
|
||||||
{
|
{
|
||||||
getDI().setInt64("ExtId", id);
|
getDI().setInt64("ExtId", id);
|
||||||
|
|||||||
12
code/oBase.h
12
code/oBase.h
@ -75,7 +75,7 @@ private:
|
|||||||
void resetChangeStatus() {changed &= reChanged;}
|
void resetChangeStatus() {changed &= reChanged;}
|
||||||
bool reChanged;
|
bool reChanged;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
bool localObject;
|
||||||
const static unsigned long long BaseGenStringFlag = 1ull << 63;
|
const static unsigned long long BaseGenStringFlag = 1ull << 63;
|
||||||
const static unsigned long long Base36StringFlag = 1ull << 62;
|
const static unsigned long long Base36StringFlag = 1ull << 62;
|
||||||
const static unsigned long long ExtStringMask = ~(BaseGenStringFlag|Base36StringFlag);
|
const static unsigned long long ExtStringMask = ~(BaseGenStringFlag|Base36StringFlag);
|
||||||
@ -106,15 +106,17 @@ protected:
|
|||||||
/** Change the id of the object */
|
/** Change the id of the object */
|
||||||
virtual void changeId(int newId);
|
virtual void changeId(int newId);
|
||||||
|
|
||||||
//Used for handeling GUI combo boxes;
|
|
||||||
static void clearCombo(HWND hWnd);
|
|
||||||
static void addToCombo(HWND hWnd, const string &str, int data);
|
|
||||||
|
|
||||||
/** Get internal data buffers for DI */
|
/** Get internal data buffers for DI */
|
||||||
virtual oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const = 0;
|
virtual oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const = 0;
|
||||||
virtual int getDISize() const = 0;
|
virtual int getDISize() const = 0;
|
||||||
|
|
||||||
|
void setLocalObject() { localObject = true; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Returns true if the object is local, not stored in DB/On disc
|
||||||
|
bool isLocalObject() { return localObject; }
|
||||||
|
|
||||||
/// Returns textual information on the object
|
/// Returns textual information on the object
|
||||||
virtual wstring getInfo() const = 0;
|
virtual wstring getInfo() const = 0;
|
||||||
|
|
||||||
|
|||||||
313
code/oClass.cpp
313
code/oClass.cpp
@ -43,6 +43,8 @@
|
|||||||
#include "gdistructures.h"
|
#include "gdistructures.h"
|
||||||
#include "meosexception.h"
|
#include "meosexception.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
#include "qualification_final.h"
|
||||||
|
#include "generalresult.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Construction/Destruction
|
// Construction/Destruction
|
||||||
@ -64,6 +66,7 @@ oClass::oClass(oEvent *poe): oBase(poe)
|
|||||||
tCoursesChanged = false;
|
tCoursesChanged = false;
|
||||||
tStatusRevision = 0;
|
tStatusRevision = 0;
|
||||||
tShowMultiDialog = false;
|
tShowMultiDialog = false;
|
||||||
|
parentClass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
oClass::oClass(oEvent *poe, int id): oBase(poe)
|
oClass::oClass(oEvent *poe, int id): oBase(poe)
|
||||||
@ -73,7 +76,7 @@ oClass::oClass(oEvent *poe, int id): oBase(poe)
|
|||||||
if (id == 0)
|
if (id == 0)
|
||||||
id = oe->getFreeClassId();
|
id = oe->getFreeClassId();
|
||||||
Id=id;
|
Id=id;
|
||||||
oe->qFreeClassId = max(id, oe->qFreeClassId);
|
oe->qFreeClassId = max(id % MaxClassId, oe->qFreeClassId);
|
||||||
tLeaderTime.resize(1);
|
tLeaderTime.resize(1);
|
||||||
tNoTiming = -1;
|
tNoTiming = -1;
|
||||||
tIgnoreStartPunch = -1;
|
tIgnoreStartPunch = -1;
|
||||||
@ -85,6 +88,8 @@ oClass::oClass(oEvent *poe, int id): oBase(poe)
|
|||||||
tCoursesChanged = false;
|
tCoursesChanged = false;
|
||||||
tStatusRevision = 0;
|
tStatusRevision = 0;
|
||||||
tShowMultiDialog = false;
|
tShowMultiDialog = false;
|
||||||
|
|
||||||
|
parentClass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
oClass::~oClass()
|
oClass::~oClass()
|
||||||
@ -359,7 +364,7 @@ int oClass::getNumRunners(bool checkFirstLeg, bool noCountVacant, bool noCountNo
|
|||||||
oRunnerList::iterator it;
|
oRunnerList::iterator it;
|
||||||
|
|
||||||
for (it=oe->Runners.begin(); it != oe->Runners.end(); ++it) {
|
for (it=oe->Runners.begin(); it != oe->Runners.end(); ++it) {
|
||||||
if (it->getClassId()==Id) {
|
if (it->getClassId(true)==Id) {
|
||||||
if (it->skip())
|
if (it->skip())
|
||||||
continue;
|
continue;
|
||||||
if (checkFirstLeg && it->tLeg > 0)
|
if (checkFirstLeg && it->tLeg > 0)
|
||||||
@ -412,7 +417,7 @@ void oClass::setName(const wstring &name)
|
|||||||
oDataContainer &oClass::getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const {
|
oDataContainer &oClass::getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const {
|
||||||
data = (pvoid)oData;
|
data = (pvoid)oData;
|
||||||
olddata = (pvoid)oDataOld;
|
olddata = (pvoid)oDataOld;
|
||||||
strData = 0;
|
strData = const_cast< vector <vector<wstring> >* >(&oDataStr);
|
||||||
return *oe->oClassData;
|
return *oe->oClassData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,13 +1072,14 @@ const vector< pair<wstring, size_t> > &oEvent::fillClasses(vector< pair<wstring,
|
|||||||
if (rit->isRemoved())
|
if (rit->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rit->Class) {
|
pClass pc = rit->getClassRef(true);
|
||||||
if (rit->Class->getNumStages() > 0 && rit->Class->getStartType(rit->tLeg) != STDrawn)
|
if (pc) {
|
||||||
|
if (pc->getNumStages() > 0 && pc->getStartType(rit->tLeg) != STDrawn)
|
||||||
needTime = false;
|
needTime = false;
|
||||||
}
|
}
|
||||||
if (rit->tStartTime==0 && needTime)
|
if (rit->tStartTime==0 && needTime)
|
||||||
undrawn.insert(rit->getClassId());
|
undrawn.insert(rit->getClassId(true));
|
||||||
hasRunner.insert(rit->getClassId());
|
hasRunner.insert(rit->getClassId(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (extended == extraNumMaps)
|
else if (extended == extraNumMaps)
|
||||||
@ -1137,9 +1143,9 @@ void oEvent::getNotDrawnClasses(set<int> &classes, bool someMissing)
|
|||||||
synchronizeList(oLRunnerId);
|
synchronizeList(oLRunnerId);
|
||||||
for (rit=Runners.begin(); rit != Runners.end(); ++rit) {
|
for (rit=Runners.begin(); rit != Runners.end(); ++rit) {
|
||||||
if (rit->tStartTime>0)
|
if (rit->tStartTime>0)
|
||||||
drawn.insert(rit->getClassId());
|
drawn.insert(rit->getClassId(true));
|
||||||
else if (someMissing)
|
else if (someMissing)
|
||||||
classes.insert(rit->getClassId());
|
classes.insert(rit->getClassId(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return all classe where some runner has no start time
|
// Return all classe where some runner has no start time
|
||||||
@ -1231,28 +1237,6 @@ bool oClass::isCourseUsed(int Id) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string oClass::getClassResultStatus() const
|
|
||||||
{
|
|
||||||
list<oRunner>::iterator it;
|
|
||||||
|
|
||||||
int nrunner=0;
|
|
||||||
int nrunner_finish=0;
|
|
||||||
|
|
||||||
for (it=oe->Runners.begin(); it!=oe->Runners.end();++it) {
|
|
||||||
if (it->getClassId()==Id){
|
|
||||||
nrunner++;
|
|
||||||
|
|
||||||
if (it->getStatus())
|
|
||||||
nrunner_finish++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char bf[128];
|
|
||||||
sprintf_s(bf, "%d/%d", nrunner_finish, nrunner);
|
|
||||||
|
|
||||||
return bf;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oClass::hasTrueMultiCourse() const {
|
bool oClass::hasTrueMultiCourse() const {
|
||||||
if (MultiCourse.empty())
|
if (MultiCourse.empty())
|
||||||
return false;
|
return false;
|
||||||
@ -1516,7 +1500,7 @@ void oEvent::getNumClassRunners(int id, int leg, int &total, int &finished, int
|
|||||||
int maxleg = pc->getLastStageIndex();
|
int maxleg = pc->getLastStageIndex();
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it){
|
for (it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (!it->skip() && it->getClassId()==id && it->getStatus() != StatusNotCompetiting) {
|
if (!it->skip() && it->getClassId(true)==id && it->getStatus() != StatusNotCompetiting) {
|
||||||
if (leg==0) {
|
if (leg==0) {
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
@ -1543,7 +1527,7 @@ void oEvent::getNumClassRunners(int id, int leg, int &total, int &finished, int
|
|||||||
oTeamList::const_iterator it;
|
oTeamList::const_iterator it;
|
||||||
|
|
||||||
for (it=Teams.begin(); it != Teams.end(); ++it) {
|
for (it=Teams.begin(); it != Teams.end(); ++it) {
|
||||||
if (it->getClassId()==id) {
|
if (it->getClassId(true)==id) {
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
if (it->tStatus!=StatusUnknown ||
|
if (it->tStatus!=StatusUnknown ||
|
||||||
@ -2695,7 +2679,7 @@ void oClass::getStatistics(const set<int> &feeLock, int &entries, int &started)
|
|||||||
if (it->getStatus() == StatusNotCompetiting)
|
if (it->getStatus() == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->getClassId()==Id) {
|
if (it->getClassId(false)==Id) {
|
||||||
if (feeLock.empty() || feeLock.count(it->getDCI().getInt("Fee"))) {
|
if (feeLock.empty() || feeLock.count(it->getDCI().getInt("Fee"))) {
|
||||||
entries++;
|
entries++;
|
||||||
if (it->getStatus()!= StatusUnknown && it->getStatus()!= StatusDNS && it->tStatus != StatusCANCEL)
|
if (it->getStatus()!= StatusUnknown && it->getStatus()!= StatusDNS && it->tStatus != StatusCANCEL)
|
||||||
@ -2789,6 +2773,22 @@ void oClass::reinitialize()
|
|||||||
tMaxTime = oe->getMaximalTime();
|
tMaxTime = oe->getMaximalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wstring wInfo = getDI().getString("Qualification");
|
||||||
|
if (!wInfo.empty()) {
|
||||||
|
if (!qualificatonFinal)
|
||||||
|
qualificatonFinal = make_shared<QualificationFinal>(MaxClassId, Id);
|
||||||
|
|
||||||
|
qualificatonFinal->init(wInfo);
|
||||||
|
virtualClasses.resize(getNumQualificationFinalClasses());
|
||||||
|
|
||||||
|
int nc = qualificatonFinal->getNumClasses();
|
||||||
|
for (int i = 1; i <= nc; i++)
|
||||||
|
getVirtualClass(i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qualificatonFinal.reset();
|
||||||
|
}
|
||||||
|
|
||||||
tNoTiming = -1;
|
tNoTiming = -1;
|
||||||
tIgnoreStartPunch = -1;
|
tIgnoreStartPunch = -1;
|
||||||
}
|
}
|
||||||
@ -3787,7 +3787,7 @@ void oClass::extractBibPatterns(oEvent &oe, map<int, pair<wstring, int> > &patte
|
|||||||
patterns.clear();
|
patterns.clear();
|
||||||
wchar_t pattern[32];
|
wchar_t pattern[32];
|
||||||
for (size_t k = t.size(); k > 0; k--) {
|
for (size_t k = t.size(); k > 0; k--) {
|
||||||
int cls = t[k-1]->getClassId();
|
int cls = t[k-1]->getClassId(true);
|
||||||
if (cls == 0)
|
if (cls == 0)
|
||||||
continue;
|
continue;
|
||||||
const wstring &bib = t[k-1]->getBib();
|
const wstring &bib = t[k-1]->getBib();
|
||||||
@ -3806,7 +3806,7 @@ void oClass::extractBibPatterns(oEvent &oe, map<int, pair<wstring, int> > &patte
|
|||||||
for (size_t k = r.size(); k > 0; k--) {
|
for (size_t k = r.size(); k > 0; k--) {
|
||||||
if (r[k-1]->getTeam() != 0)
|
if (r[k-1]->getTeam() != 0)
|
||||||
continue;
|
continue;
|
||||||
int cls = r[k-1]->getClassId();
|
int cls = r[k-1]->getClassId(true);
|
||||||
if (cls == 0)
|
if (cls == 0)
|
||||||
continue;
|
continue;
|
||||||
const wstring &bib = r[k-1]->getBib();
|
const wstring &bib = r[k-1]->getBib();
|
||||||
@ -4061,7 +4061,7 @@ void oClass::drawSeeded(ClassSeedMethod seed, int leg, int firstStart,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool oClass::hasClassGlobalDependance() const {
|
bool oClass::hasClassGlobalDependence() const {
|
||||||
for (size_t k = 0; k < legInfo.size(); k++) {
|
for (size_t k = 0; k < legInfo.size(); k++) {
|
||||||
if (legInfo[k].startMethod == STHunting)
|
if (legInfo[k].startMethod == STHunting)
|
||||||
return true;
|
return true;
|
||||||
@ -4139,6 +4139,8 @@ int oClass::getNextBaseLeg(int leg) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int oClass::getPreceedingLeg(int leg) const {
|
int oClass::getPreceedingLeg(int leg) const {
|
||||||
|
if (size_t(leg) >= legInfo.size())
|
||||||
|
leg = legInfo.size() - 1;
|
||||||
for (int k = leg; k > 0; k--) {
|
for (int k = leg; k > 0; k--) {
|
||||||
if (!(legInfo[k].isParallel() || legInfo[k].isOptional()))
|
if (!(legInfo[k].isParallel() || legInfo[k].isOptional()))
|
||||||
return k-1;
|
return k-1;
|
||||||
@ -4147,9 +4149,242 @@ int oClass::getPreceedingLeg(int leg) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool oClass::lockedForking() const {
|
bool oClass::lockedForking() const {
|
||||||
return getDCI().getInt("Locked") != 0;
|
return (getDCI().getInt("Locked") & 1) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void oClass::lockedForking(bool locked) {
|
void oClass::lockedForking(bool locked) {
|
||||||
getDI().setInt("Locked", locked);
|
int current = getDCI().getInt("Locked");
|
||||||
|
getDI().setInt("Locked", locked ? (current | 1) : (current & ~1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool oClass::lockedClassAssignment() const {
|
||||||
|
return (getDCI().getInt("Locked") & 2) == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void oClass::lockedClassAssignment(bool locked) {
|
||||||
|
int current = getDCI().getInt("Locked");
|
||||||
|
getDI().setInt("Locked", locked ? (current | 2) : (current & ~2));
|
||||||
|
}
|
||||||
|
|
||||||
|
oClass *oClass::getVirtualClass(int instance, bool allowCreation) {
|
||||||
|
if (instance == 0)
|
||||||
|
return this;
|
||||||
|
if (parentClass)
|
||||||
|
return parentClass->getVirtualClass(instance, allowCreation);
|
||||||
|
|
||||||
|
if (size_t(instance) < virtualClasses.size() && virtualClasses[instance])
|
||||||
|
return virtualClasses[instance];
|
||||||
|
|
||||||
|
if (instance >= getNumQualificationFinalClasses())
|
||||||
|
return this; // Invalid
|
||||||
|
virtualClasses.resize(getNumQualificationFinalClasses());
|
||||||
|
int virtId = Id + instance * MaxClassId;
|
||||||
|
virtualClasses[instance] = oe->getClass(virtId);
|
||||||
|
if (virtualClasses[instance]) {
|
||||||
|
virtualClasses[instance]->parentClass = pClass(this);
|
||||||
|
return virtualClasses[instance];
|
||||||
|
}
|
||||||
|
configureInstance(instance, allowCreation);
|
||||||
|
if (virtualClasses[instance])
|
||||||
|
return virtualClasses[instance];
|
||||||
|
return this; // Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
const oClass *oClass::getVirtualClass(int instance) const {
|
||||||
|
if (instance == 0)
|
||||||
|
return this;
|
||||||
|
if (parentClass)
|
||||||
|
return parentClass->getVirtualClass(instance);
|
||||||
|
|
||||||
|
if (size_t(instance) < virtualClasses.size() && virtualClasses[instance])
|
||||||
|
return virtualClasses[instance];
|
||||||
|
|
||||||
|
if (instance >= getNumQualificationFinalClasses())
|
||||||
|
return this; // Invalid
|
||||||
|
virtualClasses.resize(getNumQualificationFinalClasses());
|
||||||
|
|
||||||
|
int virtId = Id + instance * MaxClassId;
|
||||||
|
virtualClasses[instance] = oe->getClass(virtId);
|
||||||
|
if (virtualClasses[instance]) {
|
||||||
|
virtualClasses[instance]->parentClass = pClass(this);
|
||||||
|
return virtualClasses[instance];
|
||||||
|
}
|
||||||
|
configureInstance(instance, false);
|
||||||
|
if (virtualClasses[instance])
|
||||||
|
return virtualClasses[instance];
|
||||||
|
return this; // Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
void oClass::configureInstance(int instance, bool allowCreation) const {
|
||||||
|
int virtId = Id + instance * MaxClassId;
|
||||||
|
virtualClasses[instance] = oe->getClass(virtId);
|
||||||
|
if (virtualClasses[instance]) {
|
||||||
|
virtualClasses[instance]->parentClass = pClass(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!allowCreation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
oClass copy(*this);
|
||||||
|
copy.Id = Id + instance * MaxClassId;
|
||||||
|
copy.setExtIdentifier(copy.Id);
|
||||||
|
copy.Name += makeDash(L"-") + qualificatonFinal->getInstanceName(instance);
|
||||||
|
copy.setLocalObject();
|
||||||
|
copy.parentClass = pClass(this);
|
||||||
|
copy.tSortIndex += instance;
|
||||||
|
copy.getDI().setInt("SortIndex", copy.tSortIndex);
|
||||||
|
copy.legInfo.clear();
|
||||||
|
copy.MultiCourse.clear();
|
||||||
|
copy.getDI().setString("Qualification", L"");
|
||||||
|
virtualClasses[instance] = oe->addClass(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
int oClass::getNumQualificationFinalClasses() const {
|
||||||
|
if (qualificatonFinal)
|
||||||
|
return qualificatonFinal->getNumClasses()+1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void oClass::loadQualificationFinalScheme(const wstring &fileName) {
|
||||||
|
auto qf = make_shared<QualificationFinal>(MaxClassId, Id);
|
||||||
|
qf->import(fileName);
|
||||||
|
wstring enc;
|
||||||
|
qf->encode(enc);
|
||||||
|
int ns = qf->getNumStages();
|
||||||
|
setNumStages(ns);
|
||||||
|
for (int i = 1; i < ns; i++) {
|
||||||
|
setStartType(i, StartTypes::STDrawn, true);
|
||||||
|
setLegType(i, LegTypes::LTNormal);
|
||||||
|
setLegRunner(i, 0);
|
||||||
|
}
|
||||||
|
qualificatonFinal = qf;
|
||||||
|
getDI().setString("Qualification", enc);
|
||||||
|
for (int i = 0; i < qualificatonFinal->getNumClasses(); i++) {
|
||||||
|
pClass inst = getVirtualClass(i+1, true);
|
||||||
|
inst->synchronize();
|
||||||
|
}
|
||||||
|
synchronize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void oClass::updateFinalClasses(oRunner *causingResult, bool updateStartNumbers) {
|
||||||
|
if (!qualificatonFinal)
|
||||||
|
return;
|
||||||
|
assert(!causingResult || causingResult->Class == this);
|
||||||
|
int instance = causingResult ? causingResult->classInstance() : 0;
|
||||||
|
pClass currentInst = getVirtualClass(instance, false);
|
||||||
|
if (instance == virtualClasses.size())
|
||||||
|
return; // Final class
|
||||||
|
int maxDepth = getNumStages();
|
||||||
|
bool needIter = true;
|
||||||
|
int limit = virtualClasses.size() - 1;
|
||||||
|
|
||||||
|
while (needIter && --maxDepth > 0) {
|
||||||
|
needIter = false;
|
||||||
|
if (size_t(instance) >= virtualClasses.size())
|
||||||
|
break; // Final class
|
||||||
|
|
||||||
|
vector< vector<pRunner> > classSplit(virtualClasses.size());
|
||||||
|
|
||||||
|
for (oRunner &r : oe->Runners) {
|
||||||
|
if (r.isRemoved() || !r.Class)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (r.Class != this && (r.Class->getId() % MaxClassId) != getId())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int inst = r.Class == this ? r.classInstance() : (r.Class->getId() - getId()) & MaxClassId;
|
||||||
|
|
||||||
|
if (inst == 0 && r.tLeg > 0)
|
||||||
|
continue; // Only allow base class for leg 0.
|
||||||
|
|
||||||
|
if (inst < instance || inst >= limit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
classSplit[inst].push_back(&r);
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneralResult gr;
|
||||||
|
|
||||||
|
for (int i = instance; i < limit; i++) {
|
||||||
|
if (classSplit[i].empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (i == 0 && qualificatonFinal->noQualification(i)) {
|
||||||
|
set<int> allowed;
|
||||||
|
qualificatonFinal->getBaseClassInstances(allowed);
|
||||||
|
// Place all in this group
|
||||||
|
for (pRunner r : classSplit[i]) {
|
||||||
|
auto di = r->getDI();
|
||||||
|
int oldHeat = di.getInt("Heat");
|
||||||
|
if (allowed.count(oldHeat) || classSplit.size() < 2)
|
||||||
|
continue;
|
||||||
|
// Take the smallest gruop. User can set heat explicitly of other distribution is wanted.
|
||||||
|
int heat = 1;
|
||||||
|
for (int i : allowed) {
|
||||||
|
if (size_t(i) < classSplit.size() &&
|
||||||
|
classSplit[heat].size() > classSplit[i].size())
|
||||||
|
heat = i;
|
||||||
|
}
|
||||||
|
if (heat != oldHeat) {
|
||||||
|
bool lockedStartList = getVirtualClass(heat)->lockedClassAssignment() ||
|
||||||
|
getVirtualClass(oldHeat)->lockedClassAssignment();
|
||||||
|
|
||||||
|
if (!lockedStartList) {
|
||||||
|
pClass oldClass = r->getClassRef(true);
|
||||||
|
oldClass->markSQLChanged(-1, 0);
|
||||||
|
di.setInt("Heat", heat);
|
||||||
|
r->classInstanceRev.first = -1;
|
||||||
|
r->synchronize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gr.calculateIndividualResults(classSplit[i], oListInfo::Classwise, true, 0);
|
||||||
|
int lastPlace = 0, orderPlace = 1;
|
||||||
|
int numEqual = 0;
|
||||||
|
for (size_t k = 0; k < classSplit[i].size(); k++) {
|
||||||
|
auto &res = classSplit[i][k]->getTempResult();
|
||||||
|
int heat = 0;
|
||||||
|
if (res.getStatus() == StatusOK) {
|
||||||
|
int place = res.getPlace();
|
||||||
|
if (lastPlace == place)
|
||||||
|
numEqual++;
|
||||||
|
else
|
||||||
|
numEqual = 0;
|
||||||
|
|
||||||
|
auto nextFinal = qualificatonFinal->getNextFinal(i, orderPlace, numEqual);
|
||||||
|
heat = nextFinal.first;
|
||||||
|
lastPlace = place;
|
||||||
|
}
|
||||||
|
orderPlace++;
|
||||||
|
oRunner &thisRunner = *classSplit[i][k];
|
||||||
|
pRunner runnerToChange = thisRunner.getMultiRunner(thisRunner.getRaceNo() + 1);
|
||||||
|
|
||||||
|
if (runnerToChange) {
|
||||||
|
auto di = runnerToChange->getDI();
|
||||||
|
int oldHeat = di.getInt("Heat");
|
||||||
|
|
||||||
|
if (heat != oldHeat) {
|
||||||
|
bool lockedStartList = getVirtualClass(heat)->lockedClassAssignment() ||
|
||||||
|
getVirtualClass(oldHeat)->lockedClassAssignment();
|
||||||
|
|
||||||
|
if (!lockedStartList) {
|
||||||
|
pClass oldClass = runnerToChange->getClassRef(true);
|
||||||
|
oldClass->markSQLChanged(-1, 0);
|
||||||
|
di.setInt("Heat", heat);
|
||||||
|
runnerToChange->classInstanceRev.first = -1;
|
||||||
|
runnerToChange->synchronize();
|
||||||
|
if (runnerToChange->getFinishTime() > 0)
|
||||||
|
needIter = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needIter) {
|
||||||
|
instance = i+1; // Need not process last class again
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,8 @@ class oClass;
|
|||||||
typedef oClass* pClass;
|
typedef oClass* pClass;
|
||||||
class oDataInterface;
|
class oDataInterface;
|
||||||
|
|
||||||
|
const int MaxClassId = 1000000;
|
||||||
|
|
||||||
enum PersonSex;
|
enum PersonSex;
|
||||||
|
|
||||||
enum StartTypes {
|
enum StartTypes {
|
||||||
@ -132,6 +134,7 @@ struct ClassResultInfo {
|
|||||||
int lastStartTime;
|
int lastStartTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QualificationFinal;
|
||||||
|
|
||||||
enum ClassType {oClassIndividual=1, oClassPatrol=2,
|
enum ClassType {oClassIndividual=1, oClassPatrol=2,
|
||||||
oClassRelay=3, oClassIndividRelay=4};
|
oClassRelay=3, oClassIndividRelay=4};
|
||||||
@ -206,7 +209,7 @@ protected:
|
|||||||
|
|
||||||
BYTE oData[dataSize];
|
BYTE oData[dataSize];
|
||||||
BYTE oDataOld[dataSize];
|
BYTE oDataOld[dataSize];
|
||||||
|
vector< vector<wstring> > oDataStr;
|
||||||
//Multicourse data
|
//Multicourse data
|
||||||
string codeMultiCourse() const;
|
string codeMultiCourse() const;
|
||||||
//Fill courseId with id:s of used courses.
|
//Fill courseId with id:s of used courses.
|
||||||
@ -258,14 +261,34 @@ protected:
|
|||||||
|
|
||||||
static long long setupForkKey(const vector<int> indices, const vector< vector< vector<int> > > &courseKeys, vector<int> &ws);
|
static long long setupForkKey(const vector<int> indices, const vector< vector< vector<int> > > &courseKeys, vector<int> &ws);
|
||||||
|
|
||||||
|
mutable vector<pClass> virtualClasses;
|
||||||
|
pClass parentClass;
|
||||||
|
|
||||||
|
shared_ptr<QualificationFinal> qualificatonFinal;
|
||||||
|
|
||||||
|
void configureInstance(int instance, bool allowCreation) const;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** The master class in a qualification/final scheme. */
|
||||||
|
const pClass getParentClass() const { return parentClass; }
|
||||||
|
|
||||||
|
const QualificationFinal *getQualificationFinal() const { return qualificatonFinal.get(); }
|
||||||
|
|
||||||
|
/** Returns the number of possible final classes.*/
|
||||||
|
int getNumQualificationFinalClasses() const;
|
||||||
|
void loadQualificationFinalScheme(const wstring &fileName);
|
||||||
|
|
||||||
|
void updateFinalClasses(oRunner *causingResult, bool updateStartNumbers);
|
||||||
|
|
||||||
static void initClassId(oEvent &oe);
|
static void initClassId(oEvent &oe);
|
||||||
|
|
||||||
// Return true if forking in the class is locked
|
// Return true if forking in the class is locked
|
||||||
bool lockedForking() const;
|
bool lockedForking() const;
|
||||||
void lockedForking(bool locked);
|
void lockedForking(bool locked);
|
||||||
|
|
||||||
|
bool lockedClassAssignment() const;
|
||||||
|
void lockedClassAssignment(bool locked);
|
||||||
|
|
||||||
// Draw data
|
// Draw data
|
||||||
int getDrawFirstStart() const;
|
int getDrawFirstStart() const;
|
||||||
void setDrawFirstStart(int st);
|
void setDrawFirstStart(int st);
|
||||||
@ -286,7 +309,7 @@ public:
|
|||||||
void drawSeeded(ClassSeedMethod seed, int leg, int firstStart, int interval, const vector<int> &groups,
|
void drawSeeded(ClassSeedMethod seed, int leg, int firstStart, int interval, const vector<int> &groups,
|
||||||
bool noClubNb, bool reverse, int pairSize);
|
bool noClubNb, bool reverse, int pairSize);
|
||||||
/** Returns true if the class is setup so that changeing one runner can effect all others. (Pursuit)*/
|
/** Returns true if the class is setup so that changeing one runner can effect all others. (Pursuit)*/
|
||||||
bool hasClassGlobalDependance() const;
|
bool hasClassGlobalDependence() const;
|
||||||
// Autoassign new bibs
|
// Autoassign new bibs
|
||||||
static void extractBibPatterns(oEvent &oe, map<int, pair<wstring, int> > &patterns);
|
static void extractBibPatterns(oEvent &oe, map<int, pair<wstring, int> > &patterns);
|
||||||
pair<int, wstring> getNextBib(map<int, pair<wstring, int> > &patterns); // Version that calculates next free bib from cached data (fast, no gap usage)
|
pair<int, wstring> getNextBib(map<int, pair<wstring, int> > &patterns); // Version that calculates next free bib from cached data (fast, no gap usage)
|
||||||
@ -315,6 +338,9 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oClass *getVirtualClass(int instance, bool allowCreation);
|
||||||
|
const oClass *getVirtualClass(int instance) const;
|
||||||
|
|
||||||
ClassStatus getClassStatus() const;
|
ClassStatus getClassStatus() const;
|
||||||
|
|
||||||
ClassMetaType interpretClassType() const;
|
ClassMetaType interpretClassType() const;
|
||||||
@ -441,9 +467,6 @@ public:
|
|||||||
void setDirectResult(bool directResult);
|
void setDirectResult(bool directResult);
|
||||||
bool hasDirectResult() const;
|
bool hasDirectResult() const;
|
||||||
|
|
||||||
|
|
||||||
string getClassResultStatus() const;
|
|
||||||
|
|
||||||
bool isCourseUsed(int Id) const;
|
bool isCourseUsed(int Id) const;
|
||||||
wstring getLength(int leg) const;
|
wstring getLength(int leg) const;
|
||||||
|
|
||||||
@ -472,7 +495,7 @@ public:
|
|||||||
|
|
||||||
void setNumStages(int no);
|
void setNumStages(int no);
|
||||||
|
|
||||||
bool operator<(const oClass &b){return tSortIndex<b.tSortIndex;}
|
bool operator<(const oClass &b) {return tSortIndex<b.tSortIndex || (tSortIndex == b.tSortIndex && Id < b.Id);}
|
||||||
|
|
||||||
// Get total number of runners running this class.
|
// Get total number of runners running this class.
|
||||||
// Use checkFirstLeg to only check the number of runners running leg 1.
|
// Use checkFirstLeg to only check the number of runners running leg 1.
|
||||||
|
|||||||
@ -428,7 +428,6 @@ void oEvent::getClubs(vector<pClub> &c, bool sort) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void oEvent::viewClubMembers(gdioutput &gdi, int clubId)
|
void oEvent::viewClubMembers(gdioutput &gdi, int clubId)
|
||||||
{
|
{
|
||||||
sortRunners(ClassStartTime);
|
sortRunners(ClassStartTime);
|
||||||
@ -440,10 +439,12 @@ void oEvent::viewClubMembers(gdioutput &gdi, int clubId)
|
|||||||
int nt = 0;
|
int nt = 0;
|
||||||
// Update teams
|
// Update teams
|
||||||
for (oTeamList::iterator it = Teams.begin(); it!=Teams.end(); ++it) {
|
for (oTeamList::iterator it = Teams.begin(); it!=Teams.end(); ++it) {
|
||||||
|
if (it->skip())
|
||||||
|
continue;
|
||||||
if (it->getClubId() == clubId) {
|
if (it->getClubId() == clubId) {
|
||||||
if (nt==0)
|
if (nt==0)
|
||||||
gdi.addString("", 1, "Lag(flera)");
|
gdi.addString("", 1, "Lag(flera)");
|
||||||
gdi.addStringUT(0, it->getName() + L", " + it->getClass() );
|
gdi.addStringUT(0, it->getName() + L", " + it->getClass(false) );
|
||||||
nt++;
|
nt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,10 +452,12 @@ void oEvent::viewClubMembers(gdioutput &gdi, int clubId)
|
|||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
// Update runners
|
// Update runners
|
||||||
for (oRunnerList::iterator it = Runners.begin(); it!=Runners.end(); ++it) {
|
for (oRunnerList::iterator it = Runners.begin(); it!=Runners.end(); ++it) {
|
||||||
|
if (it->skip())
|
||||||
|
continue;
|
||||||
if (it->getClubId() == clubId) {
|
if (it->getClubId() == clubId) {
|
||||||
if (nr==0)
|
if (nr==0)
|
||||||
gdi.addString("", 1, "Löpare:");
|
gdi.addString("", 1, "Löpare:");
|
||||||
gdi.addStringUT(0, it->getName() + L", " + it->getClass() );
|
gdi.addStringUT(0, it->getName() + L", " + it->getClass(true) );
|
||||||
nr++;
|
nr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +499,7 @@ void oClub::addRunnerInvoiceLine(const pRunner r, bool inTeam,
|
|||||||
|
|
||||||
wstring ts;
|
wstring ts;
|
||||||
if (!inTeam)
|
if (!inTeam)
|
||||||
line.addString(xs+data.clsPos, r->getClass());
|
line.addString(xs+data.clsPos, r->getClass(true));
|
||||||
|
|
||||||
if (r->getStatus() == StatusUnknown)
|
if (r->getStatus() == StatusUnknown)
|
||||||
ts = L"-";
|
ts = L"-";
|
||||||
@ -504,8 +507,8 @@ void oClub::addRunnerInvoiceLine(const pRunner r, bool inTeam,
|
|||||||
if (r->getStatus()==StatusOK) {
|
if (r->getStatus()==StatusOK) {
|
||||||
ClassType type = oClassIndividual;
|
ClassType type = oClassIndividual;
|
||||||
cTeam t = r->getTeam();
|
cTeam t = r->getTeam();
|
||||||
if (t && r->getClassRef())
|
if (t && r->getClassRef(false))
|
||||||
type = r->getClassRef()->getClassType();
|
type = r->getClassRef(false)->getClassType();
|
||||||
|
|
||||||
if (type == oClassIndividRelay || type == oClassRelay) {
|
if (type == oClassIndividRelay || type == oClassRelay) {
|
||||||
int leg = r->getLegNumber();
|
int leg = r->getLegNumber();
|
||||||
@ -541,7 +544,7 @@ void oClub::addRunnerInvoiceLine(const pRunner r, bool inTeam,
|
|||||||
if (res != definedPayModes.end())
|
if (res != definedPayModes.end())
|
||||||
payMode = ", " + res->second;
|
payMode = ", " + res->second;
|
||||||
*/
|
*/
|
||||||
if (r->getClassRef() && r->getClassRef()->getClassStatus() == oClass::InvalidRefund) {
|
if (r->getClassRef(false) && r->getClassRef(false)->getClassStatus() == oClass::InvalidRefund) {
|
||||||
fee = 0;
|
fee = 0;
|
||||||
card = 0;
|
card = 0;
|
||||||
}
|
}
|
||||||
@ -574,7 +577,7 @@ void oClub::addTeamInvoiceLine(const pTeam t, const map<int, wstring> &definedPa
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
line.addString(xs, t->getName());
|
line.addString(xs, t->getName());
|
||||||
line.addString(xs+data.clsPos, t->getClass());
|
line.addString(xs+data.clsPos, t->getClass(false));
|
||||||
wstring ts;
|
wstring ts;
|
||||||
|
|
||||||
if (t->getStatus() == StatusUnknown)
|
if (t->getStatus() == StatusUnknown)
|
||||||
@ -588,7 +591,7 @@ void oClub::addTeamInvoiceLine(const pTeam t, const map<int, wstring> &definedPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (t->getClassRef() && t->getClassRef()->getClassStatus() == oClass::InvalidRefund) {
|
if (t->getClassRef(false) && t->getClassRef(false)->getClassStatus() == oClass::InvalidRefund) {
|
||||||
fee = 0;
|
fee = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -998,3 +998,21 @@ void oControl::getClasses(vector<pClass> &cls) const {
|
|||||||
cls.push_back(pClass(&*it));
|
cls.push_back(pClass(&*it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int oControl::getControlIdByName(const oEvent &oe, const string &name) {
|
||||||
|
if (_stricmp(name.c_str(), "finish") == 0)
|
||||||
|
return oPunch::PunchFinish;
|
||||||
|
if (_stricmp(name.c_str(), "start") == 0)
|
||||||
|
return oPunch::PunchStart;
|
||||||
|
|
||||||
|
vector<pControl> ac;
|
||||||
|
oe.getControls(ac, true);
|
||||||
|
wstring wname = oe.gdiBase().recodeToWide(name);
|
||||||
|
for (pControl c : ac) {
|
||||||
|
if (_wcsicmp(c->getName().c_str(), wname.c_str()) == 0)
|
||||||
|
return c->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,6 +117,7 @@ protected:
|
|||||||
void changedObject();
|
void changedObject();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static int getControlIdByName(const oEvent &oe, const string &name);
|
||||||
|
|
||||||
// Returns true if controls is considered a radio control.
|
// Returns true if controls is considered a radio control.
|
||||||
bool isValidRadio() const;
|
bool isValidRadio() const;
|
||||||
|
|||||||
@ -289,8 +289,7 @@ __int64 oDataContainer::getInt64(const void *data, const char *Name) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool oDataContainer::setString(oBase *ob, const char *name, const wstring &v)
|
bool oDataContainer::setString(oBase *ob, const char *name, const wstring &v) {
|
||||||
{
|
|
||||||
oDataInfo *odi=findVariable(name);
|
oDataInfo *odi=findVariable(name);
|
||||||
|
|
||||||
if (!odi)
|
if (!odi)
|
||||||
|
|||||||
212
code/oEvent.cpp
212
code/oEvent.cpp
@ -441,6 +441,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
|||||||
oClassData->addVariableInt("Unordered", oDataContainer::oIS8U, "Oordnade parallella");
|
oClassData->addVariableInt("Unordered", oDataContainer::oIS8U, "Oordnade parallella");
|
||||||
oClassData->addVariableInt("Heat", oDataContainer::oIS8U, "Heat");
|
oClassData->addVariableInt("Heat", oDataContainer::oIS8U, "Heat");
|
||||||
oClassData->addVariableInt("Locked", oDataContainer::oIS8U, "Låst gaffling");
|
oClassData->addVariableInt("Locked", oDataContainer::oIS8U, "Låst gaffling");
|
||||||
|
oClassData->addVariableString("Qualification", "Kvalschema");
|
||||||
|
|
||||||
oTeamData = new oDataContainer(oTeam::dataSize);
|
oTeamData = new oDataContainer(oTeam::dataSize);
|
||||||
oTeamData->addVariableCurrency("Fee", "Anm. avgift");
|
oTeamData->addVariableCurrency("Fee", "Anm. avgift");
|
||||||
@ -1210,6 +1211,7 @@ bool oEvent::open(const xmlparser &xml) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toc("class");
|
toc("class");
|
||||||
|
reinitializeClasses();
|
||||||
|
|
||||||
//Get clubs
|
//Get clubs
|
||||||
xo=xml.getObject("ClubList");
|
xo=xml.getObject("ClubList");
|
||||||
@ -1839,7 +1841,7 @@ void oEvent::updateFreeId(oBase *obj)
|
|||||||
qFreeRunnerId=max(obj->Id, qFreeRunnerId);
|
qFreeRunnerId=max(obj->Id, qFreeRunnerId);
|
||||||
}
|
}
|
||||||
else if (typeid(*obj)==typeid(oClass)){
|
else if (typeid(*obj)==typeid(oClass)){
|
||||||
qFreeClassId=max(obj->Id, qFreeClassId);
|
qFreeClassId=max(obj->Id % MaxClassId, qFreeClassId);
|
||||||
}
|
}
|
||||||
else if (typeid(*obj)==typeid(oCourse)){
|
else if (typeid(*obj)==typeid(oCourse)){
|
||||||
qFreeCourseId=max(obj->Id, qFreeCourseId);
|
qFreeCourseId=max(obj->Id, qFreeCourseId);
|
||||||
@ -1881,7 +1883,7 @@ void oEvent::updateFreeId()
|
|||||||
oClassList::iterator it;
|
oClassList::iterator it;
|
||||||
qFreeClassId=0;
|
qFreeClassId=0;
|
||||||
for (it=Classes.begin(); it != Classes.end(); ++it)
|
for (it=Classes.begin(); it != Classes.end(); ++it)
|
||||||
qFreeClassId=max(qFreeClassId, it->Id);
|
qFreeClassId=max(qFreeClassId, it->Id % MaxClassId);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
oCourseList::iterator it;
|
oCourseList::iterator it;
|
||||||
@ -2553,17 +2555,27 @@ void oEvent::removeCourse(int Id)
|
|||||||
void oEvent::removeClass(int Id)
|
void oEvent::removeClass(int Id)
|
||||||
{
|
{
|
||||||
oClassList::iterator it;
|
oClassList::iterator it;
|
||||||
|
vector<int> subRemove;
|
||||||
for (it=Classes.begin(); it != Classes.end(); ++it){
|
for (it = Classes.begin(); it != Classes.end(); ++it){
|
||||||
if (it->Id==Id){
|
if (it->Id==Id){
|
||||||
|
if (it->getQualificationFinal()) {
|
||||||
|
for (int n = 0; n < it->getNumQualificationFinalClasses(); n++) {
|
||||||
|
const oClass *pc = it->getVirtualClass(n);
|
||||||
|
if (pc && pc != &*it)
|
||||||
|
subRemove.push_back(pc->getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (HasDBConnection)
|
if (HasDBConnection)
|
||||||
msRemove(&*it);
|
msRemove(&*it);
|
||||||
Classes.erase(it);
|
Classes.erase(it);
|
||||||
dataRevision++;
|
dataRevision++;
|
||||||
updateTabs();
|
updateTabs();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int id : subRemove) {
|
||||||
|
removeClass(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void oEvent::removeControl(int Id)
|
void oEvent::removeControl(int Id)
|
||||||
@ -2642,17 +2654,33 @@ bool oEvent::isCourseUsed(int Id) const
|
|||||||
|
|
||||||
bool oEvent::isClassUsed(int Id) const
|
bool oEvent::isClassUsed(int Id) const
|
||||||
{
|
{
|
||||||
|
pClass cl = getClass(Id);
|
||||||
|
if (cl && cl->parentClass) {
|
||||||
|
if (isClassUsed(cl->parentClass->Id))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
set<int> idToCheck;
|
||||||
|
idToCheck.insert(Id);
|
||||||
|
if (cl) {
|
||||||
|
for (int i = 0; i < cl->getNumQualificationFinalClasses(); i++)
|
||||||
|
idToCheck.insert(cl->getVirtualClass(i)->getId());
|
||||||
|
}
|
||||||
//Search runners
|
//Search runners
|
||||||
oRunnerList::const_iterator it;
|
oRunnerList::const_iterator it;
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it){
|
for (it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (it->getClassId()==Id)
|
if (it->isRemoved())
|
||||||
|
continue;
|
||||||
|
if (idToCheck.count(it->getClassId(false)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Search teams
|
//Search teams
|
||||||
oTeamList::const_iterator tit;
|
oTeamList::const_iterator tit;
|
||||||
for (tit=Teams.begin(); tit != Teams.end(); ++tit){
|
for (tit=Teams.begin(); tit != Teams.end(); ++tit){
|
||||||
if (tit->getClassId()==Id)
|
if (it->isRemoved())
|
||||||
|
continue;
|
||||||
|
if (idToCheck.count(tit->getClassId(false)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2713,7 +2741,7 @@ bool oEvent::classHasResults(int Id) const
|
|||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if ( (Id == 0 || it->getClassId() == Id) && (it->getCard() || it->FinishTime))
|
if ( (Id == 0 || it->getClassId(true) == Id) && (it->getCard() || it->FinishTime))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2722,10 +2750,16 @@ bool oEvent::classHasResults(int Id) const
|
|||||||
|
|
||||||
bool oEvent::classHasTeams(int Id) const
|
bool oEvent::classHasTeams(int Id) const
|
||||||
{
|
{
|
||||||
oTeamList::const_iterator it;
|
pClass pc = oe->getClass(Id);
|
||||||
|
if (pc == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pc->getQualificationFinal() != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
oTeamList::const_iterator it;
|
||||||
for (it=Teams.begin(); it != Teams.end(); ++it)
|
for (it=Teams.begin(); it != Teams.end(); ++it)
|
||||||
if (it->getClassId()==Id)
|
if (!it->isRemoved() && it->getClassId(false)==Id)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -2768,8 +2802,8 @@ void oEvent::generateVacancyList(gdioutput &gdi, GUICALLBACK cb)
|
|||||||
if (it->skip() || !it->isVacant())
|
if (it->skip() || !it->isVacant())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->getClassId() != Id) {
|
if (it->getClassId(true) != Id) {
|
||||||
Id=it->getClassId();
|
Id=it->getClassId(true);
|
||||||
y+=lh/2;
|
y+=lh/2;
|
||||||
|
|
||||||
if (nRunner>=RunnersPerCol) {
|
if (nRunner>=RunnersPerCol) {
|
||||||
@ -2779,7 +2813,7 @@ void oEvent::generateVacancyList(gdioutput &gdi, GUICALLBACK cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gdi.addStringUT(y, x+dx[0], 1, it->getClass());
|
gdi.addStringUT(y, x+dx[0], 1, it->getClass(true));
|
||||||
y+=lh+lh/3;
|
y+=lh+lh/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2865,7 +2899,7 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unknown) {
|
if (unknown) {
|
||||||
if (id != it->getClassId()) {
|
if (id != it->getClassId(false)) {
|
||||||
if (nr>0) {
|
if (nr>0) {
|
||||||
gdi.addString("", y, x, 0, "Antal: X#"+itos(nr));
|
gdi.addString("", y, x, 0, "Antal: X#"+itos(nr));
|
||||||
y+=lh;
|
y+=lh;
|
||||||
@ -2876,11 +2910,11 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
|||||||
y += lh;
|
y += lh;
|
||||||
}
|
}
|
||||||
y += lh;
|
y += lh;
|
||||||
id = it->getClassId();
|
id = it->getClassId(false);
|
||||||
gdi.addStringUT(y, x, 1, it->getClass());
|
gdi.addStringUT(y, x, 1, it->getClass(false));
|
||||||
y += lh;
|
y += lh;
|
||||||
}
|
}
|
||||||
gdi.addStringUT(y, x, 0, it->getClass());
|
gdi.addStringUT(y, x, 0, it->getClass(false));
|
||||||
nr++;
|
nr++;
|
||||||
gdi.addStringUT(y, x+100, 0, it->getName(), 0, cb).setExtra(it->getId()).id = "T";
|
gdi.addStringUT(y, x+100, 0, it->getName(), 0, cb).setExtra(it->getId()).id = "T";
|
||||||
y+=lh;
|
y+=lh;
|
||||||
@ -2920,15 +2954,15 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
|||||||
|
|
||||||
if (it->tStatus == StatusUnknown) {
|
if (it->tStatus == StatusUnknown) {
|
||||||
|
|
||||||
if (id != it->getClassId()) {
|
if (id != it->getClassId(true)) {
|
||||||
if (nr>0) {
|
if (nr>0) {
|
||||||
gdi.addString("", y, x, 0, "Antal: X#"+itos(nr));
|
gdi.addString("", y, x, 0, "Antal: X#"+itos(nr));
|
||||||
y+=lh;
|
y+=lh;
|
||||||
nr=0;
|
nr=0;
|
||||||
}
|
}
|
||||||
y += lh;
|
y += lh;
|
||||||
id = it->getClassId();
|
id = it->getClassId(true);
|
||||||
gdi.addStringUT(y, x, 1, it->getClass());
|
gdi.addStringUT(y, x, 1, it->getClass(true));
|
||||||
y += lh;
|
y += lh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2982,7 +3016,7 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
|||||||
gdi.addToolTip("", L"#" + punches + L". " + otherRunners, 0, &rc);
|
gdi.addToolTip("", L"#" + punches + L". " + otherRunners, 0, &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gdi.addStringUT(y, x+dx[3], 0, it->getClass());
|
gdi.addStringUT(y, x+dx[3], 0, it->getClass(true));
|
||||||
y+=lh;
|
y+=lh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3126,7 +3160,7 @@ void oEvent::generateMinuteStartlist(gdioutput &gdi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gdi.addStringUT(src_y, x+dx[2], fontMedium, r[0]->getClub(), dx[3]-dx[2]-4);
|
gdi.addStringUT(src_y, x+dx[2], fontMedium, r[0]->getClub(), dx[3]-dx[2]-4);
|
||||||
gdi.addStringUT(src_y, x+dx[3], fontMedium, r[0]->getClass());
|
gdi.addStringUT(src_y, x+dx[3], fontMedium, r[0]->getClass(true));
|
||||||
y+=lh;
|
y+=lh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3689,7 +3723,7 @@ void oEvent::reEvaluateCourse(int CourseId, bool DoSync)
|
|||||||
set<int> classes;
|
set<int> classes;
|
||||||
for(it=Runners.begin(); it != Runners.end(); ++it){
|
for(it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (it->getCourse(false) && it->getCourse(false)->getId()==CourseId){
|
if (it->getCourse(false) && it->getCourse(false)->getId()==CourseId){
|
||||||
classes.insert(it->getClassId());
|
classes.insert(it->getClassId(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3710,7 +3744,7 @@ void oEvent::reEvaluateAll(const set<int> &cls, bool doSync)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(oTeamList::iterator tit=Teams.begin();tit!=Teams.end();++tit) {
|
for(oTeamList::iterator tit=Teams.begin();tit!=Teams.end();++tit) {
|
||||||
if (!cls.empty() && cls.count(tit->getClassId()) == 0)
|
if (!cls.empty() && cls.count(tit->getClassId(false)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tit->resetTmpStore();
|
tit->resetTmpStore();
|
||||||
@ -3727,7 +3761,7 @@ void oEvent::reEvaluateAll(const set<int> &cls, bool doSync)
|
|||||||
oRunnerList::iterator it;
|
oRunnerList::iterator it;
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!cls.empty() && cls.count(it->getClassId()) == 0)
|
if (!cls.empty() && cls.count(it->getClassId(true)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!it->tInTeam) {
|
if (!it->tInTeam) {
|
||||||
@ -3742,7 +3776,7 @@ void oEvent::reEvaluateAll(const set<int> &cls, bool doSync)
|
|||||||
while (needupdate) {
|
while (needupdate) {
|
||||||
needupdate = false;
|
needupdate = false;
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!cls.empty() && cls.count(it->getClassId()) == 0)
|
if (!cls.empty() && cls.count(it->getClassId(true)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!it->isRemoved()) {
|
if (!it->isRemoved()) {
|
||||||
@ -3760,7 +3794,7 @@ void oEvent::reEvaluateAll(const set<int> &cls, bool doSync)
|
|||||||
// Update team start times etc.
|
// Update team start times etc.
|
||||||
for(oTeamList::iterator tit=Teams.begin();tit!=Teams.end();++tit) {
|
for(oTeamList::iterator tit=Teams.begin();tit!=Teams.end();++tit) {
|
||||||
if (!tit->isRemoved()) {
|
if (!tit->isRemoved()) {
|
||||||
if (!cls.empty() && cls.count(tit->getClassId()) == 0)
|
if (!cls.empty() && cls.count(tit->getClassId(true)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tit->apply(false, 0, true);
|
tit->apply(false, 0, true);
|
||||||
@ -3771,7 +3805,7 @@ void oEvent::reEvaluateAll(const set<int> &cls, bool doSync)
|
|||||||
}
|
}
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!it->isRemoved()) {
|
if (!it->isRemoved()) {
|
||||||
if (!cls.empty() && cls.count(it->getClassId()) == 0)
|
if (!cls.empty() && cls.count(it->getClassId(true)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!it->tInTeam)
|
if (!it->tInTeam)
|
||||||
@ -3805,7 +3839,7 @@ void oEvent::reEvaluateChanged()
|
|||||||
it->clearSplitAnalysis();
|
it->clearSplitAnalysis();
|
||||||
it->resetLeaderTime();
|
it->resetLeaderTime();
|
||||||
it->reinitialize();
|
it->reinitialize();
|
||||||
resetClasses[it->getId()] = it->hasClassGlobalDependance();
|
resetClasses[it->getId()] = it->hasClassGlobalDependence();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3833,11 +3867,11 @@ void oEvent::reEvaluateChanged()
|
|||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
int clz = it->getClassId(true);
|
||||||
if (resetClasses.count(it->getClassId()))
|
if (resetClasses.count(clz))
|
||||||
it->storeTimes();
|
it->storeTimes();
|
||||||
|
|
||||||
if (!it->wasSQLChanged() && !resetClasses[it->getClassId()])
|
if (!it->wasSQLChanged() && !resetClasses[clz])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pTeam t = it->tInTeam;
|
pTeam t = it->tInTeam;
|
||||||
@ -3926,7 +3960,7 @@ void oEvent::reCalculateLeaderTimes(int classId)
|
|||||||
while (needupdate) {
|
while (needupdate) {
|
||||||
needupdate = false;
|
needupdate = false;
|
||||||
for (oRunnerList::iterator it=Runners.begin(); it != Runners.end(); ++it) {
|
for (oRunnerList::iterator it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!it->isRemoved() && (classId==0 || classId==it->getClassId())) {
|
if (!it->isRemoved() && (classId==0 || classId==it->getClassId(true))) {
|
||||||
if (it->tLeg == leg)
|
if (it->tLeg == leg)
|
||||||
it->storeTimes();
|
it->storeTimes();
|
||||||
else if (it->tLeg>leg)
|
else if (it->tLeg>leg)
|
||||||
@ -4097,7 +4131,7 @@ int oEvent::getFirstStart(int classId) const {
|
|||||||
int minTime=3600*24;
|
int minTime=3600*24;
|
||||||
|
|
||||||
while(it!=Runners.end()){
|
while(it!=Runners.end()){
|
||||||
if (!it->isRemoved() && classId==0 || it->getClassId()==classId)
|
if (!it->isRemoved() && classId==0 || it->getClassId(true)==classId)
|
||||||
if (it->tStartTime < minTime && it->tStatus!=StatusNotCompetiting && it->tStartTime>0)
|
if (it->tStartTime < minTime && it->tStatus!=StatusNotCompetiting && it->tStartTime>0)
|
||||||
minTime = it->tStartTime;
|
minTime = it->tStartTime;
|
||||||
++it;
|
++it;
|
||||||
@ -4168,17 +4202,26 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
|||||||
sortRunners(ClassStartTimeClub);
|
sortRunners(ClassStartTimeClub);
|
||||||
oRunnerList::iterator it;
|
oRunnerList::iterator it;
|
||||||
|
|
||||||
|
pClass cls = getClass(ClassId);
|
||||||
|
if (cls == 0)
|
||||||
|
throw meosException("Class not found");
|
||||||
|
|
||||||
|
if (cls->getParentClass())
|
||||||
|
cls->getParentClass()->setBibMode(BibFree);
|
||||||
|
|
||||||
if (!firstNumber.empty()) {
|
if (!firstNumber.empty()) {
|
||||||
|
cls->setBibMode(BibFree);
|
||||||
wchar_t pattern[32];
|
wchar_t pattern[32];
|
||||||
int num = oClass::extractBibPattern(firstNumber, pattern);
|
int num = oClass::extractBibPattern(firstNumber, pattern);
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if ( (ClassId==0 || it->getClassId()==ClassId) && it->legToRun()==leg) {
|
if ( (ClassId==0 || it->getClassId(true)==ClassId) && (it->legToRun()==leg || leg == -1)) {
|
||||||
wchar_t bib[32];
|
wchar_t bib[32];
|
||||||
swprintf_s(bib, pattern, num);
|
swprintf_s(bib, pattern, num);
|
||||||
it->setBib(bib, num, true, false);
|
pClass pc = it->getClassRef(true);
|
||||||
|
it->setBib(bib, num, pc ? !pc->lockedForking() : true, false);
|
||||||
num++;
|
num++;
|
||||||
it->synchronize();
|
it->synchronize();
|
||||||
}
|
}
|
||||||
@ -4188,7 +4231,7 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
|||||||
for(it=Runners.begin(); it != Runners.end(); ++it){
|
for(it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (ClassId==0 || it->getClassId()==ClassId) {
|
if (ClassId==0 || it->getClassId(true)==ClassId) {
|
||||||
it->getDI().setString("Bib", L"");//Update only bib
|
it->getDI().setString("Bib", L"");//Update only bib
|
||||||
it->synchronize();
|
it->synchronize();
|
||||||
}
|
}
|
||||||
@ -4206,8 +4249,8 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
|||||||
for (it=Teams.begin(); it != Teams.end(); ++it) {
|
for (it=Teams.begin(); it != Teams.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (ClassId==0 || it->getClassId()==ClassId) {
|
if (ClassId==0 || it->getClassId(false)==ClassId) {
|
||||||
if (it->getClassRef() && it->getClassRef()->getBibMode() != BibFree) {
|
if (it->getClassRef(false) && it->getClassRef(false)->getBibMode() != BibFree) {
|
||||||
for (size_t i = 0; i < it->Runners.size(); i++) {
|
for (size_t i = 0; i < it->Runners.size(); i++) {
|
||||||
if (it->Runners[i]) {
|
if (it->Runners[i]) {
|
||||||
//runnerStartNo[it->Runners[i]->getId()] = it->Runners[i]->getStartNo();
|
//runnerStartNo[it->Runners[i]->getId()] = it->Runners[i]->getStartNo();
|
||||||
@ -4232,7 +4275,7 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
|||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ClassId == 0 || it->getClassId() == ClassId) {
|
if (ClassId == 0 || it->getClassId(false) == ClassId) {
|
||||||
wchar_t bib[32];
|
wchar_t bib[32];
|
||||||
swprintf_s(bib, pattern, num);
|
swprintf_s(bib, pattern, num);
|
||||||
bool lockedStartNo = it->Class && it->Class->lockedForking();
|
bool lockedStartNo = it->Class && it->Class->lockedForking();
|
||||||
@ -4250,7 +4293,7 @@ void oEvent::addBib(int ClassId, int leg, const wstring &firstNumber) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(it=Teams.begin(); it != Teams.end(); ++it){
|
for(it=Teams.begin(); it != Teams.end(); ++it){
|
||||||
if (ClassId==0 || it->getClassId()==ClassId) {
|
if (ClassId==0 || it->getClassId(false)==ClassId) {
|
||||||
it->getDI().setString("Bib", L""); //Update only bib
|
it->getDI().setString("Bib", L""); //Update only bib
|
||||||
it->apply(true, 0, false);
|
it->apply(true, 0, false);
|
||||||
}
|
}
|
||||||
@ -4265,7 +4308,7 @@ void oEvent::addAutoBib() {
|
|||||||
int clsId = -1;
|
int clsId = -1;
|
||||||
int bibGap = oe->getBibClassGap();
|
int bibGap = oe->getBibClassGap();
|
||||||
int interval = 1;
|
int interval = 1;
|
||||||
|
set<int> isTeamCls;
|
||||||
wchar_t pattern[32] = {0};
|
wchar_t pattern[32] = {0};
|
||||||
wchar_t storedPattern[32];
|
wchar_t storedPattern[32];
|
||||||
wcscpy_s(storedPattern, L"%d");
|
wcscpy_s(storedPattern, L"%d");
|
||||||
@ -4283,24 +4326,26 @@ void oEvent::addAutoBib() {
|
|||||||
for (oTeamList::iterator tit = Teams.begin(); tit != Teams.end(); ++tit) {
|
for (oTeamList::iterator tit = Teams.begin(); tit != Teams.end(); ++tit) {
|
||||||
if (tit->skip())
|
if (tit->skip())
|
||||||
continue;
|
continue;
|
||||||
pClass cls = tit->getClassRef();
|
pClass cls = tit->getClassRef(false);
|
||||||
if (cls == 0)
|
if (cls == 0)
|
||||||
continue;
|
continue;
|
||||||
teamStartNo[tit->getId()] = tit->getStartNo();
|
teamStartNo[tit->getId()] = tit->getStartNo();
|
||||||
|
|
||||||
wstring bibInfo = cls->getDCI().getString("Bib");
|
wstring bibInfo = cls->getDCI().getString("Bib");
|
||||||
|
|
||||||
bool teamAssign = !bibInfo.empty();
|
bool teamAssign = !bibInfo.empty() && cls->getNumStages() > 1;
|
||||||
|
|
||||||
bool freeMode = cls->getBibMode()==BibFree;
|
bool freeMode = cls->getBibMode()==BibFree;
|
||||||
if (!teamAssign && freeMode)
|
if (!teamAssign && freeMode)
|
||||||
continue; // Manul or none
|
continue; // Manul or none
|
||||||
|
isTeamCls.insert(cls->getId());
|
||||||
|
|
||||||
bool addBib = bibInfo != L"-";
|
bool addBib = bibInfo != L"-";
|
||||||
|
|
||||||
if (addBib && teamAssign)
|
if (addBib && teamAssign)
|
||||||
tit->setStartNo(0, false);
|
tit->setStartNo(0, false);
|
||||||
|
|
||||||
if (tit->getClassRef() && tit->getClassRef()->getBibMode() != BibFree) {
|
if (tit->getClassRef(false) && tit->getClassRef(false)->getBibMode() != BibFree) {
|
||||||
for (size_t i = 0; i < tit->Runners.size(); i++) {
|
for (size_t i = 0; i < tit->Runners.size(); i++) {
|
||||||
if (tit->Runners[i]) {
|
if (tit->Runners[i]) {
|
||||||
if (addBib && teamAssign)
|
if (addBib && teamAssign)
|
||||||
@ -4318,15 +4363,15 @@ void oEvent::addAutoBib() {
|
|||||||
for (oTeamList::iterator tit = Teams.begin(); tit != Teams.end(); ++tit) {
|
for (oTeamList::iterator tit = Teams.begin(); tit != Teams.end(); ++tit) {
|
||||||
if (tit->skip())
|
if (tit->skip())
|
||||||
continue;
|
continue;
|
||||||
int clsId = tit->getClassId();
|
int clsId = tit->getClassId(false);
|
||||||
cls2TeamList[clsId].push_back(&*tit);
|
cls2TeamList[clsId].push_back(&*tit);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<int, vector<pRunner> > cls2RunnerList;
|
map<int, vector<pRunner> > cls2RunnerList;
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->skip() || !it->getClassId())
|
if (it->isRemoved() || !it->getClassId(false))
|
||||||
continue;
|
continue;
|
||||||
int clsId = it->getClassId();
|
int clsId = it->getClassId(true);
|
||||||
cls2RunnerList[clsId].push_back(&*it);
|
cls2RunnerList[clsId].push_back(&*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4362,7 +4407,7 @@ void oEvent::addAutoBib() {
|
|||||||
number = oClass::extractBibPattern(bibInfo, pattern);
|
number = oClass::extractBibPattern(bibInfo, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cls->getNumStages() > 1) {
|
if (isTeamCls.count(clsId)) {
|
||||||
vector<pTeam> &tl = cls2TeamList[clsId];
|
vector<pTeam> &tl = cls2TeamList[clsId];
|
||||||
|
|
||||||
if (cls->getBibMode() == BibAdd) {
|
if (cls->getBibMode() == BibAdd) {
|
||||||
@ -4405,18 +4450,23 @@ void oEvent::addAutoBib() {
|
|||||||
tl[k]->apply(true, 0, false);
|
tl[k]->apply(true, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
interval = 1;
|
interval = 1;
|
||||||
|
|
||||||
vector<pRunner> &rl = cls2RunnerList[clsId];
|
vector<pRunner> &rl = cls2RunnerList[clsId];
|
||||||
|
bool locked = cls->lockedForking();
|
||||||
|
if (pattern[0] && cls->getParentClass()) {
|
||||||
|
// Switch to free mode if bib set for subclass
|
||||||
|
cls->getParentClass()->setBibMode(BibFree);
|
||||||
|
cls->setBibMode(BibFree);
|
||||||
|
}
|
||||||
for (size_t k = 0; k < rl.size(); k++) {
|
for (size_t k = 0; k < rl.size(); k++) {
|
||||||
if (pattern[0]) {
|
if (pattern[0]) {
|
||||||
wchar_t buff[32];
|
wchar_t buff[32];
|
||||||
swprintf_s(buff, pattern, number);
|
swprintf_s(buff, pattern, number);
|
||||||
rl[k]->setBib(buff, number, true, false);
|
rl[k]->setBib(buff, number, !locked, false);
|
||||||
number += interval;
|
number += interval;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4436,7 +4486,7 @@ void oEvent::checkOrderIdMultipleCourses(int ClassId)
|
|||||||
|
|
||||||
//Find first free order
|
//Find first free order
|
||||||
for(it=Runners.begin(); it != Runners.end(); ++it){
|
for(it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (ClassId==0 || it->getClassId()==ClassId){
|
if (ClassId==0 || it->getClassId(false)==ClassId){
|
||||||
it->synchronize();//Ensure we are up-to-date
|
it->synchronize();//Ensure we are up-to-date
|
||||||
order=max(order, it->StartNo);
|
order=max(order, it->StartNo);
|
||||||
}
|
}
|
||||||
@ -4444,7 +4494,7 @@ void oEvent::checkOrderIdMultipleCourses(int ClassId)
|
|||||||
|
|
||||||
//Assign orders
|
//Assign orders
|
||||||
for(it=Runners.begin(); it != Runners.end(); ++it){
|
for(it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (ClassId==0 || it->getClassId()==ClassId)
|
if (ClassId==0 || it->getClassId(false)==ClassId)
|
||||||
if (it->StartNo==0){
|
if (it->StartNo==0){
|
||||||
it->StartNo=++order;
|
it->StartNo=++order;
|
||||||
it->updateChanged(); //Mark as changed.
|
it->updateChanged(); //Mark as changed.
|
||||||
@ -4610,7 +4660,7 @@ void oEvent::loadProperties(const wchar_t *file) {
|
|||||||
bool compareClubClassTeamName(const oRunner &a, const oRunner &b)
|
bool compareClubClassTeamName(const oRunner &a, const oRunner &b)
|
||||||
{
|
{
|
||||||
if (a.Club==b.Club) {
|
if (a.Club==b.Club) {
|
||||||
if (a.Class==b.Class) {
|
if (a.getClassId(true) == b.getClassId(true)) {
|
||||||
if (a.tInTeam==b.tInTeam)
|
if (a.tInTeam==b.tInTeam)
|
||||||
return a.tRealName<b.tRealName;
|
return a.tRealName<b.tRealName;
|
||||||
else if (a.tInTeam) {
|
else if (a.tInTeam) {
|
||||||
@ -4621,11 +4671,10 @@ bool compareClubClassTeamName(const oRunner &a, const oRunner &b)
|
|||||||
return b.tInTeam!=0;
|
return b.tInTeam!=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return a.getClass()<b.getClass();
|
return a.getClass(true)<b.getClass(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return a.getClub()<b.getClub();
|
return a.getClub()<b.getClub();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void oEvent::assignCardInteractive(gdioutput &gdi, GUICALLBACK cb)
|
void oEvent::assignCardInteractive(gdioutput &gdi, GUICALLBACK cb)
|
||||||
@ -4656,7 +4705,7 @@ void oEvent::assignCardInteractive(gdioutput &gdi, GUICALLBACK cb)
|
|||||||
|
|
||||||
wstring r;
|
wstring r;
|
||||||
if (it->Class)
|
if (it->Class)
|
||||||
r+=it->getClass()+L", ";
|
r+=it->getClass(false)+L", ";
|
||||||
|
|
||||||
if (it->tInTeam) {
|
if (it->tInTeam) {
|
||||||
r+=itow(it->tInTeam->getStartNo()); + L" " + it->tInTeam->getName();
|
r+=itow(it->tInTeam->getStartNo()); + L" " + it->tInTeam->getName();
|
||||||
@ -5345,7 +5394,7 @@ void oEvent::applyEventFees(bool updateClassFromEvent,
|
|||||||
if (it->skip())
|
if (it->skip())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (allClass || classFilter.count(it->getClassId())) {
|
if (allClass || classFilter.count(it->getClassId(true))) {
|
||||||
it->addClassDefaultFee(true);
|
it->addClassDefaultFee(true);
|
||||||
it->synchronize(true);
|
it->synchronize(true);
|
||||||
}
|
}
|
||||||
@ -5451,7 +5500,7 @@ void oEvent::removeVacanies(int classId) {
|
|||||||
if (it->skip() || !it->isVacant())
|
if (it->skip() || !it->isVacant())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (classId!=0 && it->getClassId()!=classId)
|
if (classId!=0 && it->getClassId(false)!=classId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!isRunnerUsed(it->Id))
|
if (!isRunnerUsed(it->Id))
|
||||||
@ -5472,7 +5521,7 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
for (oRunnerList::iterator it = Runners.begin(); it!=Runners.end(); ++it) {
|
for (oRunnerList::iterator it = Runners.begin(); it!=Runners.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (onlyThisClass > 0 && it->getClassId() != onlyThisClass)
|
if (onlyThisClass > 0 && it->getClassId(false) != onlyThisClass)
|
||||||
continue;
|
continue;
|
||||||
if (it->sName.empty()) {
|
if (it->sName.empty()) {
|
||||||
if (!warnNoName) {
|
if (!warnNoName) {
|
||||||
@ -5502,7 +5551,7 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
if (!warnNoTeam) {
|
if (!warnNoTeam) {
|
||||||
gdi.alert(L"Deltagaren 'X' deltar i stafettklassen 'Y' men saknar lag. Klassens start- "
|
gdi.alert(L"Deltagaren 'X' deltar i stafettklassen 'Y' men saknar lag. Klassens start- "
|
||||||
L"och resultatlistor kan därmed bli felaktiga.#" + it->getName() +
|
L"och resultatlistor kan därmed bli felaktiga.#" + it->getName() +
|
||||||
L"#" + it->getClass());
|
L"#" + it->getClass(false));
|
||||||
warnNoTeam = true;
|
warnNoTeam = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5510,7 +5559,7 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
if (!warnNoPatrol) {
|
if (!warnNoPatrol) {
|
||||||
gdi.alert(L"Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- "
|
gdi.alert(L"Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- "
|
||||||
L"och resultatlistor kan därmed bli felaktiga.#" + it->getName() +
|
L"och resultatlistor kan därmed bli felaktiga.#" + it->getName() +
|
||||||
+ L"#" + it->getClass());
|
+ L"#" + it->getClass(false));
|
||||||
warnNoPatrol = true;
|
warnNoPatrol = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5524,7 +5573,7 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (onlyThisClass > 0 && it->getClassId() != onlyThisClass)
|
if (onlyThisClass > 0 && it->getClassId(false) != onlyThisClass)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->sName.empty()) {
|
if (it->sName.empty()) {
|
||||||
@ -5549,7 +5598,7 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
if (type == oClassIndividual) {
|
if (type == oClassIndividual) {
|
||||||
if (!warnIndividualTeam) {
|
if (!warnIndividualTeam) {
|
||||||
gdi.alert(L"Laget 'X' deltar i individuella klassen 'Y'. Klassens start- och resultatlistor "
|
gdi.alert(L"Laget 'X' deltar i individuella klassen 'Y'. Klassens start- och resultatlistor "
|
||||||
L"kan därmed bli felaktiga.#" + it->getName() + L"#" + it->getClass());
|
L"kan därmed bli felaktiga.#" + it->getName() + L"#" + it->getClass(true));
|
||||||
warnIndividualTeam = true;
|
warnIndividualTeam = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5571,6 +5620,9 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
|
|||||||
if (onlyThisClass > 0 && it->getId() != onlyThisClass)
|
if (onlyThisClass > 0 && it->getId() != onlyThisClass)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (it->getQualificationFinal())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (it->hasMultiCourse()) {
|
if (it->hasMultiCourse()) {
|
||||||
for (unsigned k=0;k<it->getNumStages(); k++) {
|
for (unsigned k=0;k<it->getNumStages(); k++) {
|
||||||
StartTypes st = it->getStartType(k);
|
StartTypes st = it->getStartType(k);
|
||||||
@ -5786,7 +5838,7 @@ wstring oEvent::cloneCompetition(bool cloneRunners, bool cloneTimes,
|
|||||||
r.StartNo = it->StartNo;
|
r.StartNo = it->StartNo;
|
||||||
r.CardNo = it->CardNo;
|
r.CardNo = it->CardNo;
|
||||||
r.Club = ce.getClub(it->getClubId());
|
r.Club = ce.getClub(it->getClubId());
|
||||||
r.Class = ce.getClass(it->getClassId());
|
r.Class = ce.getClass(it->getClassId(false));
|
||||||
|
|
||||||
if (cloneCourses)
|
if (cloneCourses)
|
||||||
r.Course = ce.getCourse(it->getCourseId());
|
r.Course = ce.getCourse(it->getCourseId());
|
||||||
@ -5819,7 +5871,7 @@ wstring oEvent::cloneCompetition(bool cloneRunners, bool cloneTimes,
|
|||||||
t.sName = it->sName;
|
t.sName = it->sName;
|
||||||
t.StartNo = it->StartNo;
|
t.StartNo = it->StartNo;
|
||||||
t.Club = ce.getClub(it->getClubId());
|
t.Club = ce.getClub(it->getClubId());
|
||||||
t.Class = ce.getClass(it->getClassId());
|
t.Class = ce.getClass(it->getClassId(false));
|
||||||
|
|
||||||
if (cloneTimes)
|
if (cloneTimes)
|
||||||
t.startTime = it->startTime;
|
t.startTime = it->startTime;
|
||||||
@ -5879,7 +5931,7 @@ bool checkTargetClass(pRunner target, pRunner source,
|
|||||||
if (changeClassMethod == oEvent::TransferAnyway)
|
if (changeClassMethod == oEvent::TransferAnyway)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!compareClassName(target->getClass(), source->getClass())) {
|
if (!compareClassName(target->getClass(false), source->getClass(false))) {
|
||||||
// Store all vacant positions in the right class
|
// Store all vacant positions in the right class
|
||||||
int targetClass = -1;
|
int targetClass = -1;
|
||||||
|
|
||||||
@ -5894,10 +5946,10 @@ bool checkTargetClass(pRunner target, pRunner source,
|
|||||||
for (oClassList::const_iterator cit = Classes.begin(); cit != Classes.end(); ++cit) {
|
for (oClassList::const_iterator cit = Classes.begin(); cit != Classes.end(); ++cit) {
|
||||||
if (cit->isRemoved())
|
if (cit->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (compareClassName(cit->getName(), source->getClass())) {
|
if (compareClassName(cit->getName(), source->getClass(false))) {
|
||||||
targetClass = cit->getId();
|
targetClass = cit->getId();
|
||||||
|
|
||||||
if (targetClass == source->getClassId() || cit->getName() == source->getClass())
|
if (targetClass == source->getClassId(false) || cit->getName() == source->getClass(false))
|
||||||
break; // Assume exact match
|
break; // Assume exact match
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5907,7 +5959,7 @@ bool checkTargetClass(pRunner target, pRunner source,
|
|||||||
for (size_t j = 0; j < targetVacant.size(); j++) {
|
for (size_t j = 0; j < targetVacant.size(); j++) {
|
||||||
if (!targetVacant[j])
|
if (!targetVacant[j])
|
||||||
continue;
|
continue;
|
||||||
if (targetVacant[j]->getClassId() == targetClass)
|
if (targetVacant[j]->getClassId(false) == targetClass)
|
||||||
vacantIx.insert(j);
|
vacantIx.insert(j);
|
||||||
}
|
}
|
||||||
int posToUse = -1;
|
int posToUse = -1;
|
||||||
@ -5935,12 +5987,12 @@ bool checkTargetClass(pRunner target, pRunner source,
|
|||||||
int oldStart = target->getStartTime();
|
int oldStart = target->getStartTime();
|
||||||
wstring oldBib = target->getBib();
|
wstring oldBib = target->getBib();
|
||||||
int oldSN = target->getStartNo();
|
int oldSN = target->getStartNo();
|
||||||
int oldClass = target->getClassId();
|
int oldClass = target->getClassId(false);
|
||||||
pRunner tgt = targetVacant[posToUse];
|
pRunner tgt = targetVacant[posToUse];
|
||||||
target->cloneStartTime(tgt);
|
target->cloneStartTime(tgt);
|
||||||
target->setBib(tgt->getBib(), 0, false, false);
|
target->setBib(tgt->getBib(), 0, false, false);
|
||||||
target->setStartNo(tgt->getStartNo(), false);
|
target->setStartNo(tgt->getStartNo(), false);
|
||||||
target->setClassId(tgt->getClassId(), false);
|
target->setClassId(tgt->getClassId(false), false);
|
||||||
|
|
||||||
tgt->setStartTime(oldStart, true, false);
|
tgt->setStartTime(oldStart, true, false);
|
||||||
tgt->setBib(oldBib, 0, false, false);
|
tgt->setBib(oldBib, 0, false, false);
|
||||||
@ -6122,7 +6174,7 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
for (size_t j = 0; j < cnd.size(); j++) {
|
for (size_t j = 0; j < cnd.size(); j++) {
|
||||||
pRunner src = remainingRunners[cnd[j]];
|
pRunner src = remainingRunners[cnd[j]];
|
||||||
int p = 0;
|
int p = 0;
|
||||||
if (src->getClass() == it->getClass())
|
if (src->getClass(false) == it->getClass(false))
|
||||||
p += 1;
|
p += 1;
|
||||||
if (src->getBirthYear() == it->getBirthYear())
|
if (src->getBirthYear() == it->getBirthYear())
|
||||||
p += 2;
|
p += 2;
|
||||||
@ -6165,7 +6217,7 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pRunner targetVacant = ce.getRunner(src->getId(), 0);
|
pRunner targetVacant = ce.getRunner(src->getId(), 0);
|
||||||
if (targetVacant && targetVacant->isVacant() && compareClassName(targetVacant->getClass(), src->getClass()) ) {
|
if (targetVacant && targetVacant->isVacant() && compareClassName(targetVacant->getClass(false), src->getClass(false)) ) {
|
||||||
targetVacant->setName(src->getName(), false);
|
targetVacant->setName(src->getName(), false);
|
||||||
targetVacant->setClub(src->getClub());
|
targetVacant->setClub(src->getClub());
|
||||||
targetVacant->setCardNo(src->getCardNo(), false);
|
targetVacant->setCardNo(src->getCardNo(), false);
|
||||||
@ -6173,13 +6225,13 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
assignedVacant.push_back(targetVacant);
|
assignedVacant.push_back(targetVacant);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pClass dstClass = ce.getClass(src->getClassId());
|
pClass dstClass = ce.getClass(src->getClassId(false));
|
||||||
if (dstClass && compareClassName(dstClass->getName(), src->getClass())) {
|
if (dstClass && compareClassName(dstClass->getName(), src->getClass(false))) {
|
||||||
if ( (!src->hasFlag(oAbstractRunner::FlagTransferSpecified) && allowNewEntries.count(src->getClassId()))
|
if ( (!src->hasFlag(oAbstractRunner::FlagTransferSpecified) && allowNewEntries.count(src->getClassId(false)))
|
||||||
|| src->hasFlag(oAbstractRunner::FlagTransferNew)) {
|
|| src->hasFlag(oAbstractRunner::FlagTransferNew)) {
|
||||||
if (src->getClubId() > 0)
|
if (src->getClubId() > 0)
|
||||||
ce.getClubCreate(src->getClubId(), src->getClub());
|
ce.getClubCreate(src->getClubId(), src->getClub());
|
||||||
pRunner dst = ce.addRunner(src->getName(), src->getClubId(), src->getClassId(),
|
pRunner dst = ce.addRunner(src->getName(), src->getClubId(), src->getClassId(false),
|
||||||
src->getCardNo(), src->getBirthYear(), true);
|
src->getCardNo(), src->getBirthYear(), true);
|
||||||
dst->cloneData(src);
|
dst->cloneData(src);
|
||||||
dst->setInputData(*src);
|
dst->setInputData(*src);
|
||||||
@ -6188,7 +6240,7 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
else if (transferAllNoCompete) {
|
else if (transferAllNoCompete) {
|
||||||
if (src->getClubId() > 0)
|
if (src->getClubId() > 0)
|
||||||
ce.getClubCreate(src->getClubId(), src->getClub());
|
ce.getClubCreate(src->getClubId(), src->getClub());
|
||||||
pRunner dst = ce.addRunner(src->getName(), src->getClubId(), src->getClassId(),
|
pRunner dst = ce.addRunner(src->getName(), src->getClubId(), src->getClassId(false),
|
||||||
0, src->getBirthYear(), true);
|
0, src->getBirthYear(), true);
|
||||||
dst->cloneData(src);
|
dst->cloneData(src);
|
||||||
dst->setInputData(*src);
|
dst->setInputData(*src);
|
||||||
@ -6313,7 +6365,7 @@ void oEvent::transferResult(oEvent &ce,
|
|||||||
for (size_t j = 0; j < cnd.size(); j++) {
|
for (size_t j = 0; j < cnd.size(); j++) {
|
||||||
pTeam src = remainingTeams[cnd[j]];
|
pTeam src = remainingTeams[cnd[j]];
|
||||||
int p = 0;
|
int p = 0;
|
||||||
if (src->getClass() == it->getClass())
|
if (src->getClass(false) == it->getClass(false))
|
||||||
p += 1;
|
p += 1;
|
||||||
if (p > point) {
|
if (p > point) {
|
||||||
winnerIx = cnd[j];
|
winnerIx = cnd[j];
|
||||||
|
|||||||
@ -447,7 +447,7 @@ protected:
|
|||||||
void exportIOFResults(xmlparser &xml, bool selfContained, const set<int> &classes, int leg, bool oldStylePatrol);
|
void exportIOFResults(xmlparser &xml, bool selfContained, const set<int> &classes, int leg, bool oldStylePatrol);
|
||||||
void exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldStylePatrol);
|
void exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldStylePatrol);
|
||||||
|
|
||||||
/** Set up transient data in cassss */
|
/** Set up transient data in classes */
|
||||||
void reinitializeClasses();
|
void reinitializeClasses();
|
||||||
|
|
||||||
/** Analyze the result status of each class*/
|
/** Analyze the result status of each class*/
|
||||||
@ -779,7 +779,7 @@ public:
|
|||||||
short partialCount;
|
short partialCount;
|
||||||
short legNumber;
|
short legNumber;
|
||||||
|
|
||||||
inline int classId() const {return r->getClassId();}
|
inline int classId() const {return r->getClassId(true);}
|
||||||
inline int leg() const {return legNumber;}
|
inline int leg() const {return legNumber;}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -917,7 +917,6 @@ public:
|
|||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
void generateMinuteStartlist(gdioutput &gdi);
|
void generateMinuteStartlist(gdioutput &gdi);
|
||||||
void generateMinuteStartlist(const string &file);
|
|
||||||
|
|
||||||
bool classHasTeams(int Id) const;
|
bool classHasTeams(int Id) const;
|
||||||
bool classHasResults(int Id) const;
|
bool classHasResults(int Id) const;
|
||||||
@ -982,12 +981,14 @@ public:
|
|||||||
bool saveRunnerDatabase(const wchar_t *file, bool onlyLocal);
|
bool saveRunnerDatabase(const wchar_t *file, bool onlyLocal);
|
||||||
|
|
||||||
enum ResultType {RTClassResult, RTTotalResult, RTCourseResult, RTClassCourseResult};
|
enum ResultType {RTClassResult, RTTotalResult, RTCourseResult, RTClassCourseResult};
|
||||||
void calculateResults(ResultType result);
|
void calculateResults(ResultType result, bool includePreliminary = false);
|
||||||
void calculateRogainingResults();
|
void calculateRogainingResults();
|
||||||
|
|
||||||
void calculateResults(list<oSpeakerObject> &rl);
|
void calculateResults(list<oSpeakerObject> &rl);
|
||||||
void calculateTeamResults(bool totalMultiday);
|
void calculateTeamResults(bool totalMultiday);
|
||||||
bool calculateTeamResults(int leg, bool totalMultiday);
|
bool calculateTeamResults(int leg, bool totalMultiday);
|
||||||
|
// Set results for specified classes to tempResult
|
||||||
|
void calculateTeamResultAtControl(const set<int> &classId, int leg, int controlId, bool totalResults);
|
||||||
|
|
||||||
bool sortRunners(SortOrder so);
|
bool sortRunners(SortOrder so);
|
||||||
/** If linear leg is true, leg is interpreted as actual leg numer, otherwise w.r.t to parallel legs. */
|
/** If linear leg is true, leg is interpreted as actual leg numer, otherwise w.r.t to parallel legs. */
|
||||||
|
|||||||
@ -565,13 +565,13 @@ void oEvent::optimizeStartOrder(vector< vector<pair<int, int> > > &StartField, D
|
|||||||
int relPos = relSt / di.baseInterval;
|
int relPos = relSt / di.baseInterval;
|
||||||
|
|
||||||
if (st>0 && relSt>=0 && relPos<3000 && (relSt%di.baseInterval) == 0) {
|
if (st>0 && relSt>=0 && relPos<3000 && (relSt%di.baseInterval) == 0) {
|
||||||
if (otherClasses.count(it->getClassId())==0)
|
if (otherClasses.count(it->getClassId(false))==0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!di.startName.empty() && it->Class && it->Class->getStart()!=di.startName)
|
if (!di.startName.empty() && it->Class && it->Class->getStart()!=di.startName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ClassInfo &ci = otherClasses[it->getClassId()];
|
ClassInfo &ci = otherClasses[it->getClassId(false)];
|
||||||
int k = 0;
|
int k = 0;
|
||||||
while(true) {
|
while(true) {
|
||||||
if (k==StartField.size()) {
|
if (k==StartField.size()) {
|
||||||
@ -688,14 +688,18 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
|||||||
if (spec[k].vacances>0 && pc->getClassType()==oClassRelay)
|
if (spec[k].vacances>0 && pc->getClassType()==oClassRelay)
|
||||||
throw std::exception("Vakanser stöds ej i stafett.");
|
throw std::exception("Vakanser stöds ej i stafett.");
|
||||||
|
|
||||||
if (spec[k].vacances>0 && spec[k].leg>0)
|
if (spec[k].vacances>0 && (spec[k].leg>0 || pc->getParentClass()))
|
||||||
throw std::exception("Det går endast att sätta in vakanser på sträcka 1.");
|
throw std::exception("Det går endast att sätta in vakanser på sträcka 1.");
|
||||||
|
|
||||||
if (size_t(spec[k].leg) < pc->legInfo.size()) {
|
if (size_t(spec[k].leg) < pc->legInfo.size()) {
|
||||||
pc->legInfo[spec[k].leg].startMethod = STDrawn; //Automatically change start method
|
pc->legInfo[spec[k].leg].startMethod = STDrawn; //Automatically change start method
|
||||||
}
|
}
|
||||||
|
else if (spec[k].leg == -1) {
|
||||||
|
for (size_t j = 0; j < pc->legInfo.size(); j++)
|
||||||
|
pc->legInfo[j].startMethod = STDrawn; //Automatically change start method
|
||||||
|
}
|
||||||
clsId2Ix[spec[k].classID] = k;
|
clsId2Ix[spec[k].classID] = k;
|
||||||
if (!multiDay && spec[k].leg == 0)
|
if (!multiDay && spec[k].leg == 0 && pc->getParentClass() == 0)
|
||||||
clsIdClearVac.insert(spec[k].classID);
|
clsIdClearVac.insert(spec[k].classID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,7 +713,7 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
|||||||
vector<int> toRemove;
|
vector<int> toRemove;
|
||||||
//Remove old vacances
|
//Remove old vacances
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (clsIdClearVac.count(it->getClassId())) {
|
if (clsIdClearVac.count(it->getClassId(true))) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (it->tInTeam)
|
if (it->tInTeam)
|
||||||
@ -734,11 +738,12 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!it->isRemoved() && clsId2Ix.count(it->getClassId())) {
|
int cid = it->getClassId(true);
|
||||||
|
if (!it->isRemoved() && clsId2Ix.count(cid)) {
|
||||||
if (it->getStatus() == StatusNotCompetiting)
|
if (it->getStatus() == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
int ix = clsId2Ix[it->getClassId()];
|
int ix = clsId2Ix[cid];
|
||||||
if (it->legToRun() == spec[ix].leg ) {
|
if (it->legToRun() == spec[ix].leg || spec[ix].leg == -1) {
|
||||||
runners.push_back(&*it);
|
runners.push_back(&*it);
|
||||||
spec[ix].ntimes++;
|
spec[ix].ntimes++;
|
||||||
}
|
}
|
||||||
@ -753,12 +758,12 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
|||||||
int baseInterval = 10*60;
|
int baseInterval = 10*60;
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!it->isRemoved() && clsId2Ix.count(it->getClassId())) {
|
if (!it->isRemoved() && clsId2Ix.count(it->getClassId(true))) {
|
||||||
if (it->getStatus() == StatusNotCompetiting)
|
if (it->getStatus() == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int st = it->getStartTime();
|
int st = it->getStartTime();
|
||||||
int ix = clsId2Ix[it->getClassId()];
|
int ix = clsId2Ix[it->getClassId(false)];
|
||||||
|
|
||||||
if (st>0) {
|
if (st>0) {
|
||||||
first[ix] = min(first[ix], st);
|
first[ix] = min(first[ix], st);
|
||||||
@ -839,7 +844,6 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
|||||||
nextFreeStartNo = max<int>(nextFreeStartNo, minStartNo + stimes.size());
|
nextFreeStartNo = max<int>(nextFreeStartNo, minStartNo + stimes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getLargestClub(map<int, vector<pRunner> > &clubRunner, vector<pRunner> &largest)
|
void getLargestClub(map<int, vector<pRunner> > &clubRunner, vector<pRunner> &largest)
|
||||||
{
|
{
|
||||||
size_t maxClub=0;
|
size_t maxClub=0;
|
||||||
@ -1176,7 +1180,7 @@ void oEvent::automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
|||||||
continue;
|
continue;
|
||||||
if (it->tLeg != leg)
|
if (it->tLeg != leg)
|
||||||
continue;
|
continue;
|
||||||
if (it->isVacant() && notDrawn.count(it->getClassId())==1)
|
if (it->isVacant() && notDrawn.count(it->getClassId(false))==1)
|
||||||
continue;
|
continue;
|
||||||
pClass pc = it->Class;
|
pClass pc = it->Class;
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ void oEvent::calculateSplitResults(int controlIdFrom, int controlIdTo)
|
|||||||
|
|
||||||
for (it=Runners.begin(); it!=Runners.end(); ++it) {
|
for (it=Runners.begin(); it!=Runners.end(); ++it) {
|
||||||
int st = 0;
|
int st = 0;
|
||||||
if (controlIdFrom > 0) {
|
if (controlIdFrom > 0 && controlIdFrom != oPunch::PunchStart) {
|
||||||
RunnerStatus stat;
|
RunnerStatus stat;
|
||||||
it->getSplitTime(controlIdFrom, stat, st);
|
it->getSplitTime(controlIdFrom, stat, st);
|
||||||
if (stat != StatusOK) {
|
if (stat != StatusOK) {
|
||||||
@ -56,7 +56,7 @@ void oEvent::calculateSplitResults(int controlIdFrom, int controlIdTo)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (controlIdTo == 0) {
|
if (controlIdTo == 0 || controlIdTo == oPunch::PunchFinish) {
|
||||||
it->tempRT = max(0, it->FinishTime - (st + it->tStartTime) );
|
it->tempRT = max(0, it->FinishTime - (st + it->tStartTime) );
|
||||||
if (it->tempRT > 0)
|
if (it->tempRT > 0)
|
||||||
it->tempRT += it->getTimeAdjustment();
|
it->tempRT += it->getTimeAdjustment();
|
||||||
@ -79,8 +79,8 @@ void oEvent::calculateSplitResults(int controlIdFrom, int controlIdTo)
|
|||||||
int cTime=0;
|
int cTime=0;
|
||||||
|
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it){
|
for (it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (it->getClassId()!=cClassId){
|
if (it->getClassId(true)!=cClassId){
|
||||||
cClassId=it->getClassId();
|
cClassId=it->getClassId(true);
|
||||||
cPlace=0;
|
cPlace=0;
|
||||||
vPlace=0;
|
vPlace=0;
|
||||||
cTime=0;
|
cTime=0;
|
||||||
@ -105,7 +105,7 @@ void oEvent::calculateSplitResults(int controlIdFrom, int controlIdTo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void oEvent::calculateResults(ResultType resultType) {
|
void oEvent::calculateResults(ResultType resultType, bool includePreliminary) {
|
||||||
const bool totalResults = resultType == RTTotalResult;
|
const bool totalResults = resultType == RTTotalResult;
|
||||||
const bool courseResults = resultType == RTCourseResult;
|
const bool courseResults = resultType == RTCourseResult;
|
||||||
const bool classCourseResults = resultType == RTClassCourseResult;
|
const bool classCourseResults = resultType == RTClassCourseResult;
|
||||||
@ -135,7 +135,7 @@ void oEvent::calculateResults(ResultType resultType) {
|
|||||||
// Start new "class"
|
// Start new "class"
|
||||||
if (classCourseResults) {
|
if (classCourseResults) {
|
||||||
const pCourse crs = it->getCourse(false);
|
const pCourse crs = it->getCourse(false);
|
||||||
int crsId = it->getClassId() * 997 + (crs ? crs->getId() : 0);
|
int crsId = it->getClassId(true) * 997 + (crs ? crs->getId() : 0);
|
||||||
if (crsId != cClassId) {
|
if (crsId != cClassId) {
|
||||||
cClassId = crsId;
|
cClassId = crsId;
|
||||||
cPlace=0;
|
cPlace=0;
|
||||||
@ -156,8 +156,8 @@ void oEvent::calculateResults(ResultType resultType) {
|
|||||||
cTime=0;
|
cTime=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (it->getClassId() != cClassId || it->tDuplicateLeg!=cDuplicateLeg || it->tLegEquClass != cLegEquClass) {
|
else if (it->getClassId(true) != cClassId || it->tDuplicateLeg!=cDuplicateLeg || it->tLegEquClass != cLegEquClass) {
|
||||||
cClassId=it->getClassId();
|
cClassId=it->getClassId(true);
|
||||||
useResults = it->Class ? !it->Class->getNoTiming() : false;
|
useResults = it->Class ? !it->Class->getNoTiming() : false;
|
||||||
cPlace=0;
|
cPlace=0;
|
||||||
vPlace=0;
|
vPlace=0;
|
||||||
@ -176,7 +176,7 @@ void oEvent::calculateResults(ResultType resultType) {
|
|||||||
else if (!totalResults) {
|
else if (!totalResults) {
|
||||||
int tPlace = 0;
|
int tPlace = 0;
|
||||||
|
|
||||||
if (it->tStatus==StatusOK){
|
if (it->tStatus==StatusOK || (includePreliminary && it->tStatus == StatusUnknown && it->FinishTime > 0)){
|
||||||
cPlace++;
|
cPlace++;
|
||||||
|
|
||||||
int rt = it->getRunningTime() + it->getNumShortening() * 3600 * 24* 8;
|
int rt = it->getRunningTime() + it->getNumShortening() * 3600 * 24* 8;
|
||||||
@ -200,7 +200,8 @@ void oEvent::calculateResults(ResultType resultType) {
|
|||||||
else {
|
else {
|
||||||
int tt = it->getTotalRunningTime(it->FinishTime, true);
|
int tt = it->getTotalRunningTime(it->FinishTime, true);
|
||||||
|
|
||||||
if (it->getTotalStatus() == StatusOK && tt>0) {
|
RunnerStatus totStat = it->getTotalStatus();
|
||||||
|
if (totStat == StatusOK || (includePreliminary && totStat == StatusUnknown) && tt>0) {
|
||||||
cPlace++;
|
cPlace++;
|
||||||
|
|
||||||
if (tt > cTime)
|
if (tt > cTime)
|
||||||
@ -236,8 +237,8 @@ void oEvent::calculateRogainingResults() {
|
|||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->getClassId()!=cClassId || it->tDuplicateLeg!=cDuplicateLeg) {
|
if (it->getClassId(true)!=cClassId || it->tDuplicateLeg!=cDuplicateLeg) {
|
||||||
cClassId = it->getClassId();
|
cClassId = it->getClassId(true);
|
||||||
useResults = it->Class ? !it->Class->getNoTiming() : false;
|
useResults = it->Class ? !it->Class->getNoTiming() : false;
|
||||||
cPlace = 0;
|
cPlace = 0;
|
||||||
vPlace = 0;
|
vPlace = 0;
|
||||||
@ -515,3 +516,81 @@ void oEvent::getGeneralResults(bool onlyEditable, vector< pair<int, pair<string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TeamResultContainer {
|
||||||
|
pTeam team;
|
||||||
|
int runningTime;
|
||||||
|
RunnerStatus status;
|
||||||
|
|
||||||
|
bool operator<(const TeamResultContainer &o) const {
|
||||||
|
|
||||||
|
pClass cls = team->getClassRef(false);
|
||||||
|
pClass ocls = o.team->getClassRef(false);
|
||||||
|
|
||||||
|
if (cls != ocls) {
|
||||||
|
int so = cls ? cls->getSortIndex() : 0;
|
||||||
|
int oso = ocls ? ocls->getSortIndex() : 0;
|
||||||
|
if (so != oso)
|
||||||
|
return so < oso;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != o.status)
|
||||||
|
return status < o.status;
|
||||||
|
|
||||||
|
if (runningTime != o.runningTime)
|
||||||
|
return runningTime < o.runningTime;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void oEvent::calculateTeamResultAtControl(const set<int> &classId, int leg, int courseControlId, bool totalResults) {
|
||||||
|
vector<TeamResultContainer> objs;
|
||||||
|
objs.reserve(Teams.size());
|
||||||
|
oSpeakerObject temp;
|
||||||
|
for (auto &t : Teams) {
|
||||||
|
if (t.isRemoved())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!classId.empty() && !classId.count(t.getClassId(false)))
|
||||||
|
continue;
|
||||||
|
temp.reset();
|
||||||
|
t.fillSpeakerObject(leg, courseControlId, -1, totalResults, temp);
|
||||||
|
if (!temp.owner)
|
||||||
|
continue;
|
||||||
|
TeamResultContainer trc;
|
||||||
|
trc.runningTime = temp.runningTime.time;
|
||||||
|
trc.status = temp.status;
|
||||||
|
trc.team = &t;
|
||||||
|
objs.push_back(trc);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(objs.begin(), objs.end());
|
||||||
|
|
||||||
|
int cClass = -1;
|
||||||
|
int cPlace = -1;
|
||||||
|
int placeCounter = -1;
|
||||||
|
int cTime = 0;
|
||||||
|
for (size_t i = 0; i < objs.size(); i++) {
|
||||||
|
pTeam team = objs[i].team;
|
||||||
|
int c = team->getClassId(false);
|
||||||
|
if (c != cClass) {
|
||||||
|
cClass = c;
|
||||||
|
placeCounter = 1;
|
||||||
|
cTime = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
placeCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cTime != objs[i].runningTime) {
|
||||||
|
cPlace = placeCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
team->tmpResult.startTime = team->getStartTime();
|
||||||
|
team->tmpResult.status = objs[i].status;
|
||||||
|
team->tmpResult.runningTime = objs[i].runningTime;
|
||||||
|
team->tmpResult.place = objs[i].status == StatusOK ? cPlace : 0;
|
||||||
|
team->tmpResult.points = 0; // Not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -251,6 +251,7 @@ bool oEvent::synchronizeList(oListId id, bool preSyncEvent, bool postSyncEvent)
|
|||||||
advanceInformationPunches.clear();
|
advanceInformationPunches.clear();
|
||||||
|
|
||||||
if (postSyncEvent) {
|
if (postSyncEvent) {
|
||||||
|
reinitializeClasses();
|
||||||
reEvaluateChanged();
|
reEvaluateChanged();
|
||||||
resetChangeStatus();
|
resetChangeStatus();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -561,7 +561,7 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
|
|||||||
if (classHasTeams(ClassId)) {
|
if (classHasTeams(ClassId)) {
|
||||||
oTeamList::iterator it=Teams.begin();
|
oTeamList::iterator it=Teams.begin();
|
||||||
while(it!=Teams.end()){
|
while(it!=Teams.end()){
|
||||||
if (it->getClassId()==ClassId && !it->skip()) {
|
if (it->getClassId(true)==ClassId && !it->skip()) {
|
||||||
oSpeakerObject so;
|
oSpeakerObject so;
|
||||||
it->fillSpeakerObject(leg, ControlId, PreviousControlId, totalResults, so);
|
it->fillSpeakerObject(leg, ControlId, PreviousControlId, totalResults, so);
|
||||||
if (so.owner)
|
if (so.owner)
|
||||||
@ -571,15 +571,23 @@ void oEvent::speakerList(gdioutput &gdi, int ClassId, int leg, int ControlId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
oRunnerList::iterator it=Runners.begin();
|
pClass pc = getClass(ClassId);
|
||||||
while(it!=Runners.end()){
|
bool qfBaseClass = pc && pc->getQualificationFinal();
|
||||||
if (it->getClassId()==ClassId && !it->skip()) {
|
bool qfFinalClass = pc && pc->getParentClass();
|
||||||
|
|
||||||
|
if (qfBaseClass || qfFinalClass)
|
||||||
|
leg = 0;
|
||||||
|
|
||||||
|
for(auto &it : Runners){
|
||||||
|
if (it.getClassId(true) == ClassId && !it.isRemoved()) {
|
||||||
|
if (qfBaseClass && it.getLegNumber() > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
oSpeakerObject so;
|
oSpeakerObject so;
|
||||||
it->fillSpeakerObject(leg, ControlId, PreviousControlId, totalResults, so);
|
it.fillSpeakerObject(leg, ControlId, PreviousControlId, totalResults, so);
|
||||||
if (so.owner)
|
if (so.owner)
|
||||||
speakerList.push_back(so);
|
speakerList.push_back(so);
|
||||||
}
|
}
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (speakerList.empty()) {
|
if (speakerList.empty()) {
|
||||||
@ -1089,9 +1097,9 @@ int oEvent::setupTimeLineEvents(int classId, int currentTime)
|
|||||||
if (false && startTimes.size() == 1) {
|
if (false && startTimes.size() == 1) {
|
||||||
oRunner &r = *started[firstNonEmpty][0];
|
oRunner &r = *started[firstNonEmpty][0];
|
||||||
|
|
||||||
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, oTimeLine::PHigh, r.getClassId(), 0, 0);
|
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, oTimeLine::PHigh, r.getClassId(true), 0, 0);
|
||||||
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime, tl));
|
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime, tl));
|
||||||
it->second.setMessage(L"X har startat.#" + r.getClass());
|
it->second.setMessage(L"X har startat.#" + r.getClass(true));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (size_t j = 0; j<started.size(); j++) {
|
for (size_t j = 0; j<started.size(); j++) {
|
||||||
@ -1106,15 +1114,15 @@ int oEvent::setupTimeLineEvents(int classId, int currentTime)
|
|||||||
prio = oTimeLine::PHigh;
|
prio = oTimeLine::PHigh;
|
||||||
else if (p == 1)
|
else if (p == 1)
|
||||||
prio = oTimeLine::PMedium;
|
prio = oTimeLine::PMedium;
|
||||||
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, prio, r.getClassId(), r.getId(), &r);
|
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, prio, r.getClassId(true), r.getId(), &r);
|
||||||
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime + 1, tl));
|
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime + 1, tl));
|
||||||
it->second.setMessage(L"har startat.");
|
it->second.setMessage(L"har startat.");
|
||||||
}
|
}
|
||||||
else if (!startedClass) {
|
else if (!startedClass) {
|
||||||
// The entire class started
|
// The entire class started
|
||||||
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, oTimeLine::PHigh, r.getClassId(), 0, 0);
|
oTimeLine tl(r.tStartTime, oTimeLine::TLTStart, oTimeLine::PHigh, r.getClassId(true), 0, 0);
|
||||||
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime, tl));
|
TimeLineIterator it = timeLineEvents.insert(pair<int, oTimeLine>(r.tStartTime, tl));
|
||||||
it->second.setMessage(L"X har startat.#" + r.getClass());
|
it->second.setMessage(L"X har startat.#" + r.getClass(true));
|
||||||
startedClass = true;
|
startedClass = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1203,7 +1211,7 @@ void oEvent::timeLinePrognose(TempResultMap &results, TimeRunner &tr, int prelT,
|
|||||||
else if (p>6 + prio * 5)
|
else if (p>6 + prio * 5)
|
||||||
mp = oTimeLine::PLow;
|
mp = oTimeLine::PLow;
|
||||||
|
|
||||||
oTimeLine tl(tr.time, oTimeLine::TLTExpected, mp, tr.runner->getClassId(), radioId, tr.runner);
|
oTimeLine tl(tr.time, oTimeLine::TLTExpected, mp, tr.runner->getClassId(true), radioId, tr.runner);
|
||||||
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
||||||
tlit->second.setMessage(msg);
|
tlit->second.setMessage(msg);
|
||||||
}
|
}
|
||||||
@ -1411,7 +1419,7 @@ int oEvent::setupTimeLineEvents(vector<pRunner> &started, const vector< pair<int
|
|||||||
else if (place <= 10)
|
else if (place <= 10)
|
||||||
mp = oTimeLine::PMedium;
|
mp = oTimeLine::PMedium;
|
||||||
|
|
||||||
oTimeLine tl(radio[k].time, oTimeLine::TLTRadio, mp, r.getClassId(), rc[j].first, &r);
|
oTimeLine tl(radio[k].time, oTimeLine::TLTRadio, mp, r.getClassId(true), rc[j].first, &r);
|
||||||
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
||||||
tlit->second.setMessage(msg).setDetail(detail);
|
tlit->second.setMessage(msg).setDetail(detail);
|
||||||
}
|
}
|
||||||
@ -1509,7 +1517,7 @@ int oEvent::setupTimeLineEvents(vector<pRunner> &started, const vector< pair<int
|
|||||||
else if (place <= 20)
|
else if (place <= 20)
|
||||||
mp = oTimeLine::PMedium;
|
mp = oTimeLine::PMedium;
|
||||||
|
|
||||||
oTimeLine tl(r.FinishTime, oTimeLine::TLTFinish, mp, r.getClassId(), r.getId(), &r);
|
oTimeLine tl(r.FinishTime, oTimeLine::TLTFinish, mp, r.getClassId(true), r.getId(), &r);
|
||||||
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(tl.getTime(), tl));
|
||||||
tlit->second.setMessage(msg).setDetail(detail);
|
tlit->second.setMessage(msg).setDetail(detail);
|
||||||
}
|
}
|
||||||
@ -1535,7 +1543,7 @@ int oEvent::setupTimeLineEvents(vector<pRunner> &started, const vector< pair<int
|
|||||||
else if (place <= 20)
|
else if (place <= 20)
|
||||||
mp = oTimeLine::PMedium;
|
mp = oTimeLine::PMedium;
|
||||||
|
|
||||||
oTimeLine tl(r.FinishTime, oTimeLine::TLTFinish, mp, r.getClassId(), r.getId(), &r);
|
oTimeLine tl(r.FinishTime, oTimeLine::TLTFinish, mp, r.getClassId(true), r.getId(), &r);
|
||||||
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(t, tl));
|
TimeLineIterator tlit = timeLineEvents.insert(pair<int, oTimeLine>(t, tl));
|
||||||
wstring msg;
|
wstring msg;
|
||||||
if (r.getStatus() != StatusDQ)
|
if (r.getStatus() != StatusDQ)
|
||||||
@ -1558,7 +1566,7 @@ void oEvent::renderTimeLineEvents(gdioutput &gdi) const
|
|||||||
wstring msg = t>0 ? getAbsTime(t) : makeDash(L"--:--:--");
|
wstring msg = t>0 ? getAbsTime(t) : makeDash(L"--:--:--");
|
||||||
oAbstractRunner *r = it->second.getSource(*this);
|
oAbstractRunner *r = it->second.getSource(*this);
|
||||||
if (r) {
|
if (r) {
|
||||||
msg += L" (" + r->getClass() + L") ";
|
msg += L" (" + r->getClass(true) + L") ";
|
||||||
msg += r->getName() + L", " + r->getClub();
|
msg += r->getName() + L", " + r->getClub();
|
||||||
}
|
}
|
||||||
msg += L", " + lang.tl(it->second.getMessage());
|
msg += L", " + lang.tl(it->second.getMessage());
|
||||||
@ -1676,7 +1684,7 @@ void oEvent::getResultEvents(const set<int> &classFilter, const set<int> &punchF
|
|||||||
teamLegStatusOK.reserve(Teams.size() * 5);
|
teamLegStatusOK.reserve(Teams.size() * 5);
|
||||||
map<int, int> teamStatusPos;
|
map<int, int> teamStatusPos;
|
||||||
for (oTeamList::const_iterator it = Teams.begin(); it != Teams.end(); ++it) {
|
for (oTeamList::const_iterator it = Teams.begin(); it != Teams.end(); ++it) {
|
||||||
if (!classFilter.count(it->getClassId()))
|
if (!classFilter.count(it->getClassId(false)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int base = teamLegStatusOK.size();
|
int base = teamLegStatusOK.size();
|
||||||
@ -1699,7 +1707,7 @@ void oEvent::getResultEvents(const set<int> &classFilter, const set<int> &punchF
|
|||||||
|
|
||||||
for (oRunnerList::const_iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
for (oRunnerList::const_iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
||||||
const oRunner &r = *it;
|
const oRunner &r = *it;
|
||||||
if (r.isRemoved() || !classFilter.count(r.getClassId()))
|
if (r.isRemoved() || !classFilter.count(r.getClassId(true)))
|
||||||
continue;
|
continue;
|
||||||
if (r.prelStatusOK() || r.getStatus() != StatusUnknown) {
|
if (r.prelStatusOK() || r.getStatus() != StatusUnknown) {
|
||||||
RunnerStatus stat = r.prelStatusOK() ? StatusOK : r.getStatus();
|
RunnerStatus stat = r.prelStatusOK() ? StatusOK : r.getStatus();
|
||||||
@ -1738,7 +1746,7 @@ void oEvent::getResultEvents(const set<int> &classFilter, const set<int> &punchF
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
pRunner r = getRunner(fp.tRunnerId, 0);
|
pRunner r = getRunner(fp.tRunnerId, 0);
|
||||||
if (r == 0 || !classFilter.count(r->getClassId()) || r->getCard())
|
if (r == 0 || !classFilter.count(r->getClassId(true)) || r->getCard())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int courseControlId = oFreePunch::getControlIdFromHash(fp.iHashType, true);
|
int courseControlId = oFreePunch::getControlIdFromHash(fp.iHashType, true);
|
||||||
@ -1766,7 +1774,7 @@ void oEvent::getResultEvents(const set<int> &classFilter, const set<int> &punchF
|
|||||||
if (fp.isRemoved() || fp.tRunnerId == 0 || fp.Type == oPunch::PunchCheck || fp.Type == oPunch::PunchStart)
|
if (fp.isRemoved() || fp.tRunnerId == 0 || fp.Type == oPunch::PunchCheck || fp.Type == oPunch::PunchStart)
|
||||||
continue;
|
continue;
|
||||||
pRunner r = getRunner(fp.tRunnerId, 0);
|
pRunner r = getRunner(fp.tRunnerId, 0);
|
||||||
if (r == 0 || !classFilter.count(r->getClassId()))
|
if (r == 0 || !classFilter.count(r->getClassId(true)))
|
||||||
continue;
|
continue;
|
||||||
int courseControlId = oFreePunch::getControlIdFromHash(fp.iHashType, true);
|
int courseControlId = oFreePunch::getControlIdFromHash(fp.iHashType, true);
|
||||||
int ctrl = oControl::getIdIndexFromCourseControlId(courseControlId).first;
|
int ctrl = oControl::getIdIndexFromCourseControlId(courseControlId).first;
|
||||||
|
|||||||
@ -1037,7 +1037,7 @@ void oFreeImport::test(const oRunnerList &li)
|
|||||||
givenDB.insert(it->getGivenName().c_str());
|
givenDB.insert(it->getGivenName().c_str());
|
||||||
familyDB.insert(it->getFamilyName().c_str());
|
familyDB.insert(it->getFamilyName().c_str());
|
||||||
clubDB.insert(it->getClub().c_str());
|
clubDB.insert(it->getClub().c_str());
|
||||||
classDB.insert(it->getClass().c_str());
|
classDB.insert(it->getClass(true).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -475,14 +475,14 @@ pFreePunch oEvent::addFreePunch(int time, int type, int card, bool updateStartFi
|
|||||||
if (tr && tr->getStatus() == StatusUnknown && time > 0) {
|
if (tr && tr->getStatus() == StatusUnknown && time > 0) {
|
||||||
tr->synchronize();
|
tr->synchronize();
|
||||||
if (type == oPunch::PunchStart) {
|
if (type == oPunch::PunchStart) {
|
||||||
if (tr->getClassRef() && !tr->getClassRef()->ignoreStartPunch())
|
if (tr->getClassRef(false) && !tr->getClassRef(true)->ignoreStartPunch())
|
||||||
tr->setStartTime(time, true, false);
|
tr->setStartTime(time, true, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tr->setFinishTime(time);
|
tr->setFinishTime(time);
|
||||||
|
|
||||||
// Direct result
|
// Direct result
|
||||||
if (type == oPunch::PunchFinish && tr->getClassRef() && tr->getClassRef()->hasDirectResult()) {
|
if (type == oPunch::PunchFinish && tr->getClassRef(false) && tr->getClassRef(true)->hasDirectResult()) {
|
||||||
if (tr->getCourse(false) == 0 && tr->getCard() == 0) {
|
if (tr->getCourse(false) == 0 && tr->getCard() == 0) {
|
||||||
tr->setStatus(StatusOK, true, false, true);
|
tr->setStatus(StatusOK, true, false, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -218,9 +218,9 @@ bool oEvent::exportOECSV(const wchar_t *file, int languageTypeIndex, bool includ
|
|||||||
row[OEclubcity] = gdibase.recodeToNarrow(it->getClub());
|
row[OEclubcity] = gdibase.recodeToNarrow(it->getClub());
|
||||||
}
|
}
|
||||||
row[OEnat] = gdibase.recodeToNarrow(di.getString("Nationality"));
|
row[OEnat] = gdibase.recodeToNarrow(di.getString("Nationality"));
|
||||||
row[OEclassno] = conv_is(it->getClassId());
|
row[OEclassno] = conv_is(it->getClassId(true));
|
||||||
row[OEclassshortname] = gdibase.recodeToNarrow(it->getClass());
|
row[OEclassshortname] = gdibase.recodeToNarrow(it->getClass(true));
|
||||||
row[OEclassname] = gdibase.recodeToNarrow(it->getClass());
|
row[OEclassname] = gdibase.recodeToNarrow(it->getClass(true));
|
||||||
|
|
||||||
row[OErent] = conv_is(di.getInt("CardFee"));
|
row[OErent] = conv_is(di.getInt("CardFee"));
|
||||||
row[OEfee] = conv_is(di.getInt("Fee"));
|
row[OEfee] = conv_is(di.getInt("Fee"));
|
||||||
@ -300,7 +300,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
|
|||||||
vector< pair<int, int> > runnersInTeam;
|
vector< pair<int, int> > runnersInTeam;
|
||||||
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (!it->isRemoved() && it->tInTeam) {
|
if (!it->isRemoved() && it->tInTeam) {
|
||||||
runnersInTeam.push_back(make_pair(it->getId(), it->getClassId()) );
|
runnersInTeam.push_back(make_pair(it->getId(), it->getClassId(false)) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +597,7 @@ void oEvent::importXML_EntryData(gdioutput &gdi, const wstring &file,
|
|||||||
int id = runnersInTeam[k].first;
|
int id = runnersInTeam[k].first;
|
||||||
int classId = runnersInTeam[k].second;
|
int classId = runnersInTeam[k].second;
|
||||||
pRunner r = getRunner(id, 0);
|
pRunner r = getRunner(id, 0);
|
||||||
if (r && !r->tInTeam && r->getClassId() == classId) {
|
if (r && !r->tInTeam && r->getClassId(false) == classId) {
|
||||||
toRemove.push_back(r->getId());
|
toRemove.push_back(r->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2048,7 +2048,7 @@ void oClass::exportIOFStart(xmlparser &xml) {
|
|||||||
|
|
||||||
if (getClassType() == oClassIndividual || getClassType() == oClassIndividRelay) {
|
if (getClassType() == oClassIndividual || getClassType() == oClassIndividRelay) {
|
||||||
for (oRunnerList::iterator it = oe->Runners.begin(); it!=oe->Runners.end(); ++it) {
|
for (oRunnerList::iterator it = oe->Runners.begin(); it!=oe->Runners.end(); ++it) {
|
||||||
if (it->getClassId() != getId() || it->isRemoved())
|
if (it->getClassId(true) != getId() || it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xml.startTag("PersonStart");
|
xml.startTag("PersonStart");
|
||||||
@ -2096,7 +2096,7 @@ void oClass::exportIOFStart(xmlparser &xml) {
|
|||||||
bool writeTeamName = !useEventor || getClassType() != oClassPatrol;
|
bool writeTeamName = !useEventor || getClassType() != oClassPatrol;
|
||||||
|
|
||||||
for (oTeamList::iterator it = oe->Teams.begin(); it!=oe->Teams.end(); ++it) {
|
for (oTeamList::iterator it = oe->Teams.begin(); it!=oe->Teams.end(); ++it) {
|
||||||
if (it->getClassId() != getId() || it->isRemoved())
|
if (it->getClassId(true) != getId() || it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xml.startTag("TeamStart");
|
xml.startTag("TeamStart");
|
||||||
@ -2218,7 +2218,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (it->Runners.size()>=2 && it->Runners[0] && it->Runners[1]) {
|
if (it->Runners.size()>=2 && it->Runners[0] && it->Runners[1]) {
|
||||||
if (it->getClassId()!=Id) {
|
if (it->getClassId(true)!=Id) {
|
||||||
if (ClassStarted) xml.endTag();
|
if (ClassStarted) xml.endTag();
|
||||||
|
|
||||||
if (!it->Class || it->Class->getClassType()!=oClassPatrol) {
|
if (!it->Class || it->Class->getClassType()!=oClassPatrol) {
|
||||||
@ -2227,7 +2227,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!classes.empty() && classes.count(it->getClassId()) == 0) || leg != -1) {
|
if ((!classes.empty() && classes.count(it->getClassId(true)) == 0) || leg != -1) {
|
||||||
skipClass=true;
|
skipClass=true;
|
||||||
ClassStarted=false;
|
ClassStarted=false;
|
||||||
continue;
|
continue;
|
||||||
@ -2236,9 +2236,9 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
skipClass=false;
|
skipClass=false;
|
||||||
xml.startTag("ClassResult");
|
xml.startTag("ClassResult");
|
||||||
ClassStarted=true;
|
ClassStarted=true;
|
||||||
Id=it->getClassId();
|
Id=it->getClassId(true);
|
||||||
|
|
||||||
xml.write("ClassShortName", it->getClass());
|
xml.write("ClassShortName", it->getClass(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipClass)
|
if (skipClass)
|
||||||
@ -2315,7 +2315,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
if (it->isRemoved() || (leg != -1 && it->tLeg != leg) || it->isVacant())
|
if (it->isRemoved() || (leg != -1 && it->tLeg != leg) || it->isVacant())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->getClassId()!=Id) {
|
if (it->getClassId(true)!=Id) {
|
||||||
if (ClassStarted) xml.endTag();
|
if (ClassStarted) xml.endTag();
|
||||||
|
|
||||||
if (!it->Class) {
|
if (!it->Class) {
|
||||||
@ -2332,7 +2332,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (!classes.empty() && classes.count(it->getClassId()) == 0) ) {
|
if ( (!classes.empty() && classes.count(it->getClassId(true)) == 0) ) {
|
||||||
skipClass=true;
|
skipClass=true;
|
||||||
ClassStarted=false;
|
ClassStarted=false;
|
||||||
continue;
|
continue;
|
||||||
@ -2341,9 +2341,9 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
|
|||||||
xml.startTag("ClassResult");
|
xml.startTag("ClassResult");
|
||||||
ClassStarted=true;
|
ClassStarted=true;
|
||||||
skipClass=false;
|
skipClass=false;
|
||||||
Id=it->getClassId();
|
Id=it->getClassId(true);
|
||||||
|
|
||||||
xml.write("ClassShortName", it->getClass());
|
xml.write("ClassShortName", it->getClass(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipClass)
|
if (skipClass)
|
||||||
@ -2419,7 +2419,7 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
|
|||||||
for(oTeamList::iterator it=Teams.begin(); it != Teams.end(); ++it) {
|
for(oTeamList::iterator it=Teams.begin(); it != Teams.end(); ++it) {
|
||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (it->getClassId()!=Id) {
|
if (it->getClassId(true)!=Id) {
|
||||||
if (ClassStarted) {
|
if (ClassStarted) {
|
||||||
xml.endTag();
|
xml.endTag();
|
||||||
ClassStarted = false;
|
ClassStarted = false;
|
||||||
@ -2442,7 +2442,7 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!classes.empty() && classes.count(it->getClassId()) == 0) {
|
if (!classes.empty() && classes.count(it->getClassId(true)) == 0) {
|
||||||
skipClass=true;
|
skipClass=true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2450,9 +2450,9 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
|
|||||||
skipClass=false;
|
skipClass=false;
|
||||||
xml.startTag("ClassResult");
|
xml.startTag("ClassResult");
|
||||||
ClassStarted=true;
|
ClassStarted=true;
|
||||||
Id=it->getClassId();
|
Id=it->getClassId(true);
|
||||||
|
|
||||||
xml.write("ClassShortName", it->getClass());
|
xml.write("ClassShortName", it->getClass(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipClass)
|
if (skipClass)
|
||||||
|
|||||||
@ -396,9 +396,9 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Case when runner/team has different class
|
// Case when runner/team has different class
|
||||||
bool teamOK = it->getTeam() && clsSel.count(it->getTeam()->getClassId());
|
bool teamOK = it->getTeam() && clsSel.count(it->getTeam()->getClassId(false));
|
||||||
|
|
||||||
if (!clsSel.empty() && (!teamOK && clsSel.count(it->getClassId()) == 0))
|
if (!clsSel.empty() && (!teamOK && clsSel.count(it->getClassId(true)) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
totWord.clear();
|
totWord.clear();
|
||||||
@ -417,7 +417,7 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|
|||||||
}
|
}
|
||||||
rout.clear();
|
rout.clear();
|
||||||
while (numIter-- > 0) {
|
while (numIter-- > 0) {
|
||||||
const wstring &out = oe->formatListString(pp, par, it->tInTeam, pRunner(&*it), it->Club, it->Class, c);
|
const wstring &out = oe->formatListString(pp, par, it->tInTeam, pRunner(&*it), it->Club, pClass(it->getClassRef(true)), c);
|
||||||
//row[k] = max(row[k], int(out.length()));
|
//row[k] = max(row[k], int(out.length()));
|
||||||
if (out.length() > rout.length())
|
if (out.length() > rout.length())
|
||||||
rout = out;
|
rout = out;
|
||||||
@ -474,7 +474,7 @@ const wstring & oEvent::formatListString(EPostType type, const pRunner r) const
|
|||||||
oListParam par;
|
oListParam par;
|
||||||
par.setLegNumberCoded(r->tLeg);
|
par.setLegNumberCoded(r->tLeg);
|
||||||
pp.type = type;
|
pp.type = type;
|
||||||
return formatListString(pp, par, r->tInTeam, r, r->Club, r->Class, ctr);
|
return formatListString(pp, par, r->tInTeam, r, r->Club, r->getClassRef(true), ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wstring & oEvent::formatListString(EPostType type, const pRunner r,
|
const wstring & oEvent::formatListString(EPostType type, const pRunner r,
|
||||||
@ -485,7 +485,7 @@ const wstring & oEvent::formatListString(EPostType type, const pRunner r,
|
|||||||
par.setLegNumberCoded(r->tLeg);
|
par.setLegNumberCoded(r->tLeg);
|
||||||
pp.type = type;
|
pp.type = type;
|
||||||
pp.text = format;
|
pp.text = format;
|
||||||
return formatListString(pp, par, r->tInTeam, r, r->Club, r->Class, ctr);
|
return formatListString(pp, par, r->tInTeam, r, r->Club, r->getClassRef(true), ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -572,16 +572,16 @@ const wstring &oEvent::formatSpecialStringAux(const oPrintPost &pp, const oListP
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case lRunnerLegNumberAlpha:
|
case lRunnerLegNumberAlpha:
|
||||||
if (t && t->getClassRef() && legIndex >= 0) {
|
if (t && t->getClassRef(false) && legIndex >= 0) {
|
||||||
wstring legStr = t->getClassRef()->getLegNumber(legIndex);
|
wstring legStr = t->getClassRef(false)->getLegNumber(legIndex);
|
||||||
wcscpy_s(bfw, legStr.c_str());
|
wcscpy_s(bfw, legStr.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lRunnerLegNumber:
|
case lRunnerLegNumber:
|
||||||
if (t && t->getClassRef() && legIndex >= 0) {
|
if (t && t->getClassRef(false) && legIndex >= 0) {
|
||||||
int legNumber, legOrder;
|
int legNumber, legOrder;
|
||||||
t->getClassRef()->splitLegNumberParallel(legIndex, legNumber, legOrder);
|
t->getClassRef(false)->splitLegNumberParallel(legIndex, legNumber, legOrder);
|
||||||
wsptr = &itow(legNumber+1);
|
wsptr = &itow(legNumber+1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -727,7 +727,7 @@ const wstring &oEvent::formatSpecialStringAux(const oPrintPost &pp, const oListP
|
|||||||
try {
|
try {
|
||||||
const wstring &res = formatListStringAux(pp, par, t, t ? t->getRunner(legIndex) : 0,
|
const wstring &res = formatListStringAux(pp, par, t, t ? t->getRunner(legIndex) : 0,
|
||||||
t ? t->getClubRef() : 0,
|
t ? t->getClubRef() : 0,
|
||||||
t ? t->getClassRef() : 0, counter);
|
t ? t->getClassRef(false) : 0, counter);
|
||||||
reentrantLock = false;
|
reentrantLock = false;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -928,7 +928,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
|
|||||||
if (t) {
|
if (t) {
|
||||||
pRunner r1 = t->getRunner(0);
|
pRunner r1 = t->getRunner(0);
|
||||||
pRunner r2 = t->getRunner(1);
|
pRunner r2 = t->getRunner(1);
|
||||||
if (r1 && r2) {
|
if (r1 && r2 && r2->tParentRunner != r1) {
|
||||||
swprintf_s(wbf, L"%s / %s", r1->getName().c_str(),r2->getName().c_str());
|
swprintf_s(wbf, L"%s / %s", r1->getName().c_str(),r2->getName().c_str());
|
||||||
}
|
}
|
||||||
else if (r1) {
|
else if (r1) {
|
||||||
@ -1375,7 +1375,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case lRunnerCard:
|
case lRunnerCard:
|
||||||
if (r && r->CardNo > 0)
|
if (r && r->getCardNo() > 0)
|
||||||
swprintf_s(wbf, L"%d", r->getCardNo());
|
swprintf_s(wbf, L"%d", r->getCardNo());
|
||||||
break;
|
break;
|
||||||
case lRunnerRank:
|
case lRunnerRank:
|
||||||
@ -2212,7 +2212,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId())==0)
|
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId(false))==0)
|
||||||
continue;
|
continue;
|
||||||
it->apply(false, 0, true);
|
it->apply(false, 0, true);
|
||||||
}
|
}
|
||||||
@ -2263,11 +2263,10 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId())==0)
|
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId(true))==0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//if (it->legToRun() != li.lp.legNumber && li.lp.legNumber!=-1)
|
if (!li.lp.matchLegNumber(it->getClassRef(false), it->legToRun()))
|
||||||
if (!li.lp.matchLegNumber(it->getClassRef(), it->legToRun()))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (li.filter(EFilterExcludeDNS))
|
if (li.filter(EFilterExcludeDNS))
|
||||||
@ -2348,29 +2347,29 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
|
|
||||||
wstring newKey;
|
wstring newKey;
|
||||||
printPostInfo.par.relayLegIndex = -1;
|
printPostInfo.par.relayLegIndex = -1;
|
||||||
calculatePrintPostKey(li.subHead, gdi, li.lp, it->tInTeam, &*it, it->Club, it->Class, printPostInfo.counter, newKey);
|
calculatePrintPostKey(li.subHead, gdi, li.lp, it->tInTeam, &*it, it->Club, it->getClassRef(true), printPostInfo.counter, newKey);
|
||||||
|
|
||||||
if (newKey != oldKey) {
|
if (newKey != oldKey) {
|
||||||
if (li.lp.pageBreak) {
|
if (li.lp.pageBreak) {
|
||||||
if (!oldKey.empty())
|
if (!oldKey.empty())
|
||||||
gdi.addStringUT(gdi.getCY()-1, 0, pageNewPage, "");
|
gdi.addStringUT(gdi.getCY()-1, 0, pageNewPage, "");
|
||||||
}
|
}
|
||||||
gdi.addStringUT(pagePageInfo, it->getClass());
|
gdi.addStringUT(pagePageInfo, it->getClass(true));
|
||||||
|
|
||||||
oldKey.swap(newKey);
|
oldKey.swap(newKey);
|
||||||
printPostInfo.counter.level2=0;
|
printPostInfo.counter.level2=0;
|
||||||
printPostInfo.counter.level3=0;
|
printPostInfo.counter.level3=0;
|
||||||
printPostInfo.reset();
|
printPostInfo.reset();
|
||||||
printPostInfo.par.relayLegIndex = -1;
|
printPostInfo.par.relayLegIndex = -1;
|
||||||
formatPrintPost(li.subHead, printPostInfo, it->tInTeam, &*it, it->Club, it->Class, 0, 0, -1);
|
formatPrintPost(li.subHead, printPostInfo, it->tInTeam, &*it, it->Club, it->getClassRef(true), 0, 0, -1);
|
||||||
}
|
}
|
||||||
if (li.lp.filterMaxPer==0 || printPostInfo.counter.level2<li.lp.filterMaxPer) {
|
if (li.lp.filterMaxPer==0 || printPostInfo.counter.level2<li.lp.filterMaxPer) {
|
||||||
printPostInfo.reset();
|
printPostInfo.reset();
|
||||||
printPostInfo.par.relayLegIndex = it->tLeg;
|
printPostInfo.par.relayLegIndex = it->tLeg;
|
||||||
formatPrintPost(li.listPost, printPostInfo, it->tInTeam, &*it, it->Club, it->Class, 0, 0, -1);
|
formatPrintPost(li.listPost, printPostInfo, it->tInTeam, &*it, it->Club, it->getClassRef(true), 0, 0, -1);
|
||||||
|
|
||||||
if (li.listSubType==li.EBaseTypePunches) {
|
if (li.listSubType==li.EBaseTypePunches) {
|
||||||
listGeneratePunches(li.subListPost, gdi, li.lp, it->tInTeam, &*it, it->Club, it->Class);
|
listGeneratePunches(li.subListPost, gdi, li.lp, it->tInTeam, &*it, it->Club, it->getClassRef(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++printPostInfo.counter;
|
++printPostInfo.counter;
|
||||||
@ -2397,7 +2396,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
if (it->isRemoved() || it->tStatus == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId())==0)
|
if (!li.lp.selection.empty() && li.lp.selection.count(it->getClassId(true))==0)
|
||||||
continue;
|
continue;
|
||||||
tlist.push_back(&*it);
|
tlist.push_back(&*it);
|
||||||
}
|
}
|
||||||
@ -2416,7 +2415,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
|
|
||||||
for (size_t k = 0; k < tlist.size(); k++) {
|
for (size_t k = 0; k < tlist.size(); k++) {
|
||||||
pTeam it = tlist[k];
|
pTeam it = tlist[k];
|
||||||
int linearLegSpec = li.lp.getLegNumber(it->getClassRef());
|
int linearLegSpec = li.lp.getLegNumber(it->getClassRef(false));
|
||||||
|
|
||||||
if (gResult && it->getTempResult(0).getStatus() == StatusNotCompetiting)
|
if (gResult && it->getTempResult(0).getStatus() == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
@ -2475,12 +2474,12 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
gdi.addStringUT(gdi.getCY()-1, 0, pageNewPage, "");
|
gdi.addStringUT(gdi.getCY()-1, 0, pageNewPage, "");
|
||||||
}
|
}
|
||||||
wstring legInfo;
|
wstring legInfo;
|
||||||
if (linearLegSpec >= 0 && it->getClassRef()) {
|
if (linearLegSpec >= 0 && it->getClassRef(false)) {
|
||||||
// Specified leg
|
// Specified leg
|
||||||
legInfo = lang.tl(L", Str. X#" + li.lp.getLegName());
|
legInfo = lang.tl(L", Str. X#" + li.lp.getLegName());
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.addStringUT(pagePageInfo, it->getClass() + legInfo); // Teamlist
|
gdi.addStringUT(pagePageInfo, it->getClass(true) + legInfo); // Teamlist
|
||||||
|
|
||||||
oldKey.swap(newKey);
|
oldKey.swap(newKey);
|
||||||
printPostInfo.counter.level2=0;
|
printPostInfo.counter.level2=0;
|
||||||
@ -2561,7 +2560,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
printPostInfo.keepToghether = suitableBreak;
|
printPostInfo.keepToghether = suitableBreak;
|
||||||
printPostInfo.par.relayLegIndex = tr[k] ? tr[k]->tLeg : -1;
|
printPostInfo.par.relayLegIndex = tr[k] ? tr[k]->tLeg : -1;
|
||||||
formatPrintPost(li.subListPost, printPostInfo, &*it, tr[k],
|
formatPrintPost(li.subListPost, printPostInfo, &*it, tr[k],
|
||||||
it->Club, tr[k]->Class, 0, 0, -1);
|
it->Club, tr[k]->getClassRef(true), 0, 0, -1);
|
||||||
printPostInfo.counter.level3++;
|
printPostInfo.counter.level3++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2579,7 +2578,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
formatPrintPost(li.subListPost, printPostInfo, &*it, tr[usedIx[k]],
|
formatPrintPost(li.subListPost, printPostInfo, &*it, tr[usedIx[k]],
|
||||||
it->Club, tr[usedIx[k]]->Class, 0, 0, -1);
|
it->Club, tr[usedIx[k]]->getClassRef(true), 0, 0, -1);
|
||||||
}
|
}
|
||||||
printPostInfo.counter.level3++;
|
printPostInfo.counter.level3++;
|
||||||
}
|
}
|
||||||
@ -2632,16 +2631,15 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool startClub = false;
|
bool startClub = false;
|
||||||
pRunner pLeader = 0;
|
|
||||||
|
|
||||||
for (rit = Runners.begin(); rit != Runners.end(); ++rit) {
|
for (rit = Runners.begin(); rit != Runners.end(); ++rit) {
|
||||||
if (rit->isRemoved() || rit->tStatus == StatusNotCompetiting)
|
if (rit->isRemoved() || rit->tStatus == StatusNotCompetiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.lp.selection.empty() && li.lp.selection.count(rit->getClassId())==0)
|
if (!li.lp.selection.empty() && li.lp.selection.count(rit->getClassId(true))==0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!li.lp.matchLegNumber(rit->getClassRef(), rit->legToRun()))
|
if (!li.lp.matchLegNumber(rit->getClassRef(false), rit->legToRun()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (li.filter(EFilterExcludeDNS))
|
if (li.filter(EFilterExcludeDNS))
|
||||||
@ -2657,8 +2655,6 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pLeader || pLeader->Class != rit->Class)
|
|
||||||
pLeader = &*rit;
|
|
||||||
if (rit->Club == &*it) {
|
if (rit->Club == &*it) {
|
||||||
if (!startClub) {
|
if (!startClub) {
|
||||||
if (li.lp.pageBreak) {
|
if (li.lp.pageBreak) {
|
||||||
@ -2680,7 +2676,7 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
printPostInfo.counter.level3=0;
|
printPostInfo.counter.level3=0;
|
||||||
printPostInfo.reset();
|
printPostInfo.reset();
|
||||||
printPostInfo.par.relayLegIndex = rit->tLeg;
|
printPostInfo.par.relayLegIndex = rit->tLeg;
|
||||||
formatPrintPost(li.listPost, printPostInfo, 0, &*rit, &*it, rit->Class, 0, 0, -1);
|
formatPrintPost(li.listPost, printPostInfo, 0, &*rit, &*it, rit->getClassRef(true), 0, 0, -1);
|
||||||
if (li.subListPost.empty())
|
if (li.subListPost.empty())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -294,6 +294,24 @@ class MetaListContainer;
|
|||||||
|
|
||||||
struct oListParam {
|
struct oListParam {
|
||||||
oListParam();
|
oListParam();
|
||||||
|
|
||||||
|
bool operator==(const oListParam& a) const {
|
||||||
|
return a.listCode == listCode &&
|
||||||
|
a.selection == selection &&
|
||||||
|
a.useControlIdResultFrom == useControlIdResultFrom &&
|
||||||
|
a.useControlIdResultTo == useControlIdResultTo &&
|
||||||
|
a.filterMaxPer == filterMaxPer &&
|
||||||
|
a.pageBreak == pageBreak &&
|
||||||
|
a.showInterTimes == showInterTimes &&
|
||||||
|
a.showSplitTimes == showSplitTimes &&
|
||||||
|
a.inputNumber == inputNumber &&
|
||||||
|
a.nextList == nextList &&
|
||||||
|
a.previousList == previousList &&
|
||||||
|
a.bgColor == bgColor &&
|
||||||
|
a.bgColor2 == bgColor2 &&
|
||||||
|
a.bgImage == bgImage &&
|
||||||
|
a.legNumber == legNumber;
|
||||||
|
}
|
||||||
EStdListType listCode;
|
EStdListType listCode;
|
||||||
GUICALLBACK cb;
|
GUICALLBACK cb;
|
||||||
set<int> selection;
|
set<int> selection;
|
||||||
@ -389,6 +407,7 @@ public:
|
|||||||
Global,
|
Global,
|
||||||
Classwise,
|
Classwise,
|
||||||
Legwise,
|
Legwise,
|
||||||
|
Coursewise
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool addRunners(EBaseType t) {return t == EBaseTypeRunner || t == EBaseTypeClub;}
|
static bool addRunners(EBaseType t) {return t == EBaseTypeRunner || t == EBaseTypeClub;}
|
||||||
|
|||||||
@ -405,7 +405,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
no_club.push_back(&*r_it);
|
no_club.push_back(&*r_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_it->getClassId()==0)
|
if (r_it->getClassId(false)==0)
|
||||||
no_class.push_back(&*r_it);
|
no_class.push_back(&*r_it);
|
||||||
else if (needCourse && r_it->getCourse(false)==0)
|
else if (needCourse && r_it->getCourse(false)==0)
|
||||||
no_course.push_back(&*r_it);
|
no_course.push_back(&*r_it);
|
||||||
@ -481,7 +481,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
while(!no_course.empty() && ++i<20){
|
while(!no_course.empty() && ++i<20){
|
||||||
pRunner r=no_course.front();
|
pRunner r=no_course.front();
|
||||||
no_course.pop_front();
|
no_course.pop_front();
|
||||||
wstring name = r->getClass() + L": " + r->getName();
|
wstring name = r->getClass(true) + L": " + r->getName();
|
||||||
if (!r->getClub().empty())
|
if (!r->getClub().empty())
|
||||||
name += L" ("+ r->getClub()+ L")";
|
name += L" ("+ r->getClub()+ L")";
|
||||||
gdi.addStringUT(0, name);
|
gdi.addStringUT(0, name);
|
||||||
@ -497,7 +497,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
while(!no_club.empty() && ++i<20){
|
while(!no_club.empty() && ++i<20){
|
||||||
pRunner r=no_club.front();
|
pRunner r=no_club.front();
|
||||||
no_club.pop_front();
|
no_club.pop_front();
|
||||||
gdi.addStringUT(0, r->getClass() + L": " + r->getName());
|
gdi.addStringUT(0, r->getClass(true) + L": " + r->getName());
|
||||||
}
|
}
|
||||||
if (!no_club.empty()) gdi.addStringUT(1, Ellipsis);
|
if (!no_club.empty()) gdi.addStringUT(1, Ellipsis);
|
||||||
}
|
}
|
||||||
@ -510,7 +510,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
while(!no_start.empty() && ++i<20){
|
while(!no_start.empty() && ++i<20){
|
||||||
pRunner r=no_start.front();
|
pRunner r=no_start.front();
|
||||||
no_start.pop_front();
|
no_start.pop_front();
|
||||||
wstring name = r->getClass() + L": " + r->getName();
|
wstring name = r->getClass(true) + L": " + r->getName();
|
||||||
if (!r->getClub().empty())
|
if (!r->getClub().empty())
|
||||||
name += L" (" + r->getClub() + L")";
|
name += L" (" + r->getClub() + L")";
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
while(!no_card.empty() && ++i<20){
|
while(!no_card.empty() && ++i<20){
|
||||||
pRunner r=no_card.front();
|
pRunner r=no_card.front();
|
||||||
no_card.pop_front();
|
no_card.pop_front();
|
||||||
wstring name = r->getClass() + L": " + r->getName();
|
wstring name = r->getClass(true) + L": " + r->getName();
|
||||||
if (!r->getClub().empty())
|
if (!r->getClub().empty())
|
||||||
name += L" (" + r->getClub() + L")";
|
name += L" (" + r->getClub() + L")";
|
||||||
|
|
||||||
@ -543,7 +543,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
while(!si_duplicate.empty() && ++i<50){
|
while(!si_duplicate.empty() && ++i<50){
|
||||||
pRunner r=si_duplicate.front();
|
pRunner r=si_duplicate.front();
|
||||||
si_duplicate.pop_front();
|
si_duplicate.pop_front();
|
||||||
wstring name = r->getClass() + L" / " + r->getName();
|
wstring name = r->getClass(true) + L" / " + r->getName();
|
||||||
if (!r->getClub().empty())
|
if (!r->getClub().empty())
|
||||||
name += L" (" + r->getClub() + L")";
|
name += L" (" + r->getClub() + L")";
|
||||||
name += L": " + itow(r->getCardNo());
|
name += L": " + itow(r->getCardNo());
|
||||||
@ -566,7 +566,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
header = true;
|
header = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring name = r->getClass() + L" / " + r->getName();
|
wstring name = r->getClass(true) + L" / " + r->getName();
|
||||||
if (!r->getClub().empty())
|
if (!r->getClub().empty())
|
||||||
name += L" (" + r->getClub() + L")";
|
name += L" (" + r->getClub() + L")";
|
||||||
name += L": " + itow(r->getCardNo());
|
name += L": " + itow(r->getCardNo());
|
||||||
@ -589,7 +589,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
for (t_it=Teams.begin(); t_it != Teams.end(); ++t_it) {
|
for (t_it=Teams.begin(); t_it != Teams.end(); ++t_it) {
|
||||||
if (t_it->isRemoved())
|
if (t_it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
pClass pc=getClass(t_it->getClassId());
|
pClass pc=getClass(t_it->getClassId(true));
|
||||||
|
|
||||||
if (pc){
|
if (pc){
|
||||||
for(unsigned i=0;i<pc->getNumStages();i++){
|
for(unsigned i=0;i<pc->getNumStages();i++){
|
||||||
@ -604,7 +604,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
bool any = false;
|
bool any = false;
|
||||||
for (r_it=Runners.begin(); r_it != Runners.end(); ++r_it){
|
for (r_it=Runners.begin(); r_it != Runners.end(); ++r_it){
|
||||||
if (r_it->_objectmarker>1) {
|
if (r_it->_objectmarker>1) {
|
||||||
wstring name = r_it->getClass() + L": " + r_it->getName();
|
wstring name = r_it->getClass(true) + L": " + r_it->getName();
|
||||||
if (!r_it->getClub().empty())
|
if (!r_it->getClub().empty())
|
||||||
name += L" (" + r_it->getClub() + L")";
|
name += L" (" + r_it->getClub() + L")";
|
||||||
|
|
||||||
@ -626,7 +626,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
if (r_it->isRemoved())
|
if (r_it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (r_it->_objectmarker==0){ //Only consider runners not in a team.
|
if (r_it->_objectmarker==0){ //Only consider runners not in a team.
|
||||||
gdi.addStringUT(y, x+tab[0], 0, r_it->getClass(), tab[1]-tab[0]);
|
gdi.addStringUT(y, x+tab[0], 0, r_it->getClass(true), tab[1]-tab[0]);
|
||||||
wstring name = r_it->getName();
|
wstring name = r_it->getName();
|
||||||
if (!r_it->getClub().empty())
|
if (!r_it->getClub().empty())
|
||||||
name += L" (" + r_it->getClub() + L")";
|
name += L" (" + r_it->getClub() + L")";
|
||||||
@ -650,9 +650,9 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
|||||||
gdi.addString("", 1, "Lag(flera)");
|
gdi.addString("", 1, "Lag(flera)");
|
||||||
|
|
||||||
for (t_it=Teams.begin(); t_it != Teams.end(); ++t_it){
|
for (t_it=Teams.begin(); t_it != Teams.end(); ++t_it){
|
||||||
pClass pc=getClass(t_it->getClassId());
|
pClass pc=getClass(t_it->getClassId(false));
|
||||||
|
|
||||||
gdi.addStringUT(0, t_it->getClass() + L": " + t_it->getName() + L" " + t_it->getStartTimeS());
|
gdi.addStringUT(0, t_it->getClass(false) + L": " + t_it->getName() + L" " + t_it->getStartTimeS());
|
||||||
|
|
||||||
if (pc){
|
if (pc){
|
||||||
for(unsigned i=0;i<pc->getNumStages();i++){
|
for(unsigned i=0;i<pc->getNumStages();i++){
|
||||||
|
|||||||
234
code/oRunner.cpp
234
code/oRunner.cpp
@ -44,6 +44,7 @@
|
|||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "MeOSFeatures.h"
|
#include "MeOSFeatures.h"
|
||||||
#include "oListInfo.h"
|
#include "oListInfo.h"
|
||||||
|
#include "qualification_final.h"
|
||||||
|
|
||||||
oRunner::RaceIdFormatter oRunner::raceIdFormatter;
|
oRunner::RaceIdFormatter oRunner::raceIdFormatter;
|
||||||
|
|
||||||
@ -420,8 +421,27 @@ void oAbstractRunner::setClassId(int id, bool isManualUpdate) {
|
|||||||
// Update all classes (for multirunner)
|
// Update all classes (for multirunner)
|
||||||
void oRunner::setClassId(int id, bool isManualUpdate)
|
void oRunner::setClassId(int id, bool isManualUpdate)
|
||||||
{
|
{
|
||||||
if (tParentRunner)
|
if (Class && Class->getQualificationFinal() && isManualUpdate) {
|
||||||
tParentRunner->setClassId(id, isManualUpdate);
|
int heat = Class->getQualificationFinal()->getHeatFromClass(id, Class->getId());
|
||||||
|
if (heat >= 0) {
|
||||||
|
int oldHeat = getDI().getInt("Heat");
|
||||||
|
|
||||||
|
if (heat != oldHeat) {
|
||||||
|
pClass oldHeatClass = getClassRef(true);
|
||||||
|
getDI().setInt("Heat", heat);
|
||||||
|
pClass newHeatClass = getClassRef(true);
|
||||||
|
oldHeatClass->clearCache(true);
|
||||||
|
newHeatClass->clearCache(true);
|
||||||
|
tSplitRevision = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tParentRunner) {
|
||||||
|
assert(!isManualUpdate); // Do not support! This may be destroyed if calling tParentRunner->setClass
|
||||||
|
return;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
pClass pc = Class;
|
pClass pc = Class;
|
||||||
pClass nPc = id>0 ? oe->getClass(id):0;
|
pClass nPc = id>0 ? oe->getClass(id):0;
|
||||||
@ -451,7 +471,7 @@ void oRunner::setClassId(int id, bool isManualUpdate)
|
|||||||
if (Class != 0 && Class != pc && tInTeam==0 &&
|
if (Class != 0 && Class != pc && tInTeam==0 &&
|
||||||
Class->isSingleRunnerMultiStage()) {
|
Class->isSingleRunnerMultiStage()) {
|
||||||
if (!isTemporaryObject) {
|
if (!isTemporaryObject) {
|
||||||
pTeam t = oe->addTeam(getName(), getClubId(), getClassId());
|
pTeam t = oe->addTeam(getName(), getClubId(), getClassId(false));
|
||||||
t->setStartNo(StartNo, false);
|
t->setStartNo(StartNo, false);
|
||||||
t->setRunner(0, this, true);
|
t->setRunner(0, this, true);
|
||||||
}
|
}
|
||||||
@ -765,13 +785,16 @@ pCourse oRunner::getCourse(bool useAdaptedCourse) const {
|
|||||||
if (Course)
|
if (Course)
|
||||||
tCrs = Course;
|
tCrs = Course;
|
||||||
else if (Class) {
|
else if (Class) {
|
||||||
if (Class->hasMultiCourse()) {
|
const oClass *cls = getClassRef(true);
|
||||||
|
|
||||||
|
if (cls->hasMultiCourse()) {
|
||||||
if (tInTeam) {
|
if (tInTeam) {
|
||||||
if (size_t(tLeg) >= tInTeam->Runners.size() || tInTeam->Runners[tLeg] != this) {
|
if (size_t(tLeg) >= tInTeam->Runners.size() || tInTeam->Runners[tLeg] != this) {
|
||||||
tInTeam->quickApply();
|
tInTeam->quickApply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Class == cls) {
|
||||||
if (tInTeam && Class->hasUnorderedLegs()) {
|
if (tInTeam && Class->hasUnorderedLegs()) {
|
||||||
vector< pair<int, pCourse> > group;
|
vector< pair<int, pCourse> > group;
|
||||||
Class->getParallelCourseGroup(tLeg, StartNo, group);
|
Class->getParallelCourseGroup(tLeg, StartNo, group);
|
||||||
@ -825,31 +848,26 @@ pCourse oRunner::getCourse(bool useAdaptedCourse) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tInTeam) {
|
else if (tInTeam) {
|
||||||
unsigned leg=legToRun();
|
unsigned leg = legToRun();
|
||||||
tCrs = Class->getCourse(leg, StartNo);
|
tCrs = Class->getCourse(leg, StartNo);
|
||||||
/*if (leg<Class->MultiCourse.size()) {
|
|
||||||
vector<pCourse> &courses=Class->MultiCourse[leg];
|
|
||||||
if (courses.size()>0) {
|
|
||||||
int index=StartNo;
|
|
||||||
if (index>0)
|
|
||||||
index = (index-1) % courses.size();
|
|
||||||
|
|
||||||
tCrs = courses[index];
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (unsigned(tDuplicateLeg)<Class->MultiCourse.size()) {
|
if (unsigned(tDuplicateLeg) < Class->MultiCourse.size()) {
|
||||||
vector<pCourse> &courses=Class->MultiCourse[tDuplicateLeg];
|
vector<pCourse> &courses = Class->MultiCourse[tDuplicateLeg];
|
||||||
if (courses.size()>0) {
|
if (courses.size() > 0) {
|
||||||
int index=StartNo % courses.size();
|
int index = StartNo % courses.size();
|
||||||
tCrs = courses[index];
|
tCrs = courses[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Final / qualification classes
|
||||||
|
tCrs = cls->getCourse(0, StartNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
tCrs = Class->Course;
|
tCrs = cls->Course;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tCrs && useAdaptedCourse) {
|
if (tCrs && useAdaptedCourse) {
|
||||||
@ -1329,6 +1347,19 @@ bool oRunner::evaluateCard(bool doApply, vector<int> & MissingPunches,
|
|||||||
doAdjustTimes(course);
|
doAdjustTimes(course);
|
||||||
|
|
||||||
tRogainingPointsGross = tRogainingPoints;
|
tRogainingPointsGross = tRogainingPoints;
|
||||||
|
|
||||||
|
if (oldStatus!=*refStatus || oldFT!=FinishTime) {
|
||||||
|
clearSplitAnalysis = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inTeam || !tUseStartPunch) && doApply)
|
||||||
|
apply(sync, 0, false); //Post apply. Update start times.
|
||||||
|
|
||||||
|
if (tCachedRunningTime != FinishTime - *refStartTime) {
|
||||||
|
tCachedRunningTime = FinishTime - *refStartTime;
|
||||||
|
clearSplitAnalysis = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (time_limit > 0) {
|
if (time_limit > 0) {
|
||||||
int rt = getRunningTime();
|
int rt = getRunningTime();
|
||||||
if (rt > 0) {
|
if (rt > 0) {
|
||||||
@ -1342,17 +1373,7 @@ bool oRunner::evaluateCard(bool doApply, vector<int> & MissingPunches,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldStatus!=*refStatus || oldFT!=FinishTime) {
|
|
||||||
clearSplitAnalysis = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((inTeam || !tUseStartPunch) && doApply)
|
|
||||||
apply(sync, 0, false); //Post apply. Update start times.
|
|
||||||
|
|
||||||
if (tCachedRunningTime != FinishTime - *refStartTime) {
|
|
||||||
tCachedRunningTime = FinishTime - *refStartTime;
|
|
||||||
clearSplitAnalysis = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear split analysis data if necessary
|
// Clear split analysis data if necessary
|
||||||
bool clear = splitTimes.size() != oldTimes.size() || clearSplitAnalysis;
|
bool clear = splitTimes.size() != oldTimes.size() || clearSplitAnalysis;
|
||||||
@ -1650,8 +1671,8 @@ int oRunner::getRaceRunningTime(int leg) const
|
|||||||
|
|
||||||
bool oRunner::sortSplit(const oRunner &a, const oRunner &b)
|
bool oRunner::sortSplit(const oRunner &a, const oRunner &b)
|
||||||
{
|
{
|
||||||
int acid=a.getClassId();
|
int acid=a.getClassId(true);
|
||||||
int bcid=b.getClassId();
|
int bcid=b.getClassId(true);
|
||||||
if (acid!=bcid)
|
if (acid!=bcid)
|
||||||
return acid<bcid;
|
return acid<bcid;
|
||||||
else if (a.tempStatus != b.tempStatus)
|
else if (a.tempStatus != b.tempStatus)
|
||||||
@ -1661,21 +1682,29 @@ bool oRunner::sortSplit(const oRunner &a, const oRunner &b)
|
|||||||
if (a.tempRT!=b.tempRT)
|
if (a.tempRT!=b.tempRT)
|
||||||
return a.tempRT<b.tempRT;
|
return a.tempRT<b.tempRT;
|
||||||
}
|
}
|
||||||
return a.tRealName<b.tRealName;
|
return CompareString(LOCALE_USER_DEFAULT, 0,
|
||||||
|
a.tRealName.c_str(), a.tRealName.length(),
|
||||||
|
b.tRealName.c_str(), b.tRealName.length()) == CSTR_LESS_THAN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool oRunner::operator <(const oRunner &c) {
|
bool oRunner::operator<(const oRunner &c) const {
|
||||||
if (!Class || !c.Class)
|
const oClass * myClass = getClassRef(true);
|
||||||
return size_t(Class)<size_t(c.Class);
|
const oClass * cClass = c.getClassRef(true);
|
||||||
else if (Class == c.Class && Class->getClassStatus() != oClass::Normal)
|
if (!myClass || !cClass)
|
||||||
|
return size_t(myClass)<size_t(cClass);
|
||||||
|
else if (Class == cClass && Class->getClassStatus() != oClass::Normal)
|
||||||
return CompareString(LOCALE_USER_DEFAULT, 0,
|
return CompareString(LOCALE_USER_DEFAULT, 0,
|
||||||
tRealName.c_str(), tRealName.length(),
|
tRealName.c_str(), tRealName.length(),
|
||||||
c.tRealName.c_str(), c.tRealName.length()) == CSTR_LESS_THAN;
|
c.tRealName.c_str(), c.tRealName.length()) == CSTR_LESS_THAN;
|
||||||
|
|
||||||
if (oe->CurrentSortOrder==ClassStartTime) {
|
if (oe->CurrentSortOrder==ClassStartTime) {
|
||||||
if (Class->Id != c.Class->Id)
|
if (myClass->Id != cClass->Id) {
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
if (myClass->tSortIndex != cClass->tSortIndex)
|
||||||
|
return myClass->tSortIndex < cClass->tSortIndex;
|
||||||
|
else
|
||||||
|
return myClass->Id < cClass->Id;
|
||||||
|
}
|
||||||
else if (tStartTime != c.tStartTime) {
|
else if (tStartTime != c.tStartTime) {
|
||||||
if (tStartTime <= 0 && c.tStartTime > 0)
|
if (tStartTime <= 0 && c.tStartTime > 0)
|
||||||
return false;
|
return false;
|
||||||
@ -1697,8 +1726,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
RunnerStatus stat = tStatus == StatusUnknown ? StatusOK : tStatus;
|
RunnerStatus stat = tStatus == StatusUnknown ? StatusOK : tStatus;
|
||||||
RunnerStatus cstat = c.tStatus == StatusUnknown ? StatusOK : c.tStatus;
|
RunnerStatus cstat = c.tStatus == StatusUnknown ? StatusOK : c.tStatus;
|
||||||
|
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
else if (tLegEquClass != c.tLegEquClass)
|
else if (tLegEquClass != c.tLegEquClass)
|
||||||
return tLegEquClass < c.tLegEquClass;
|
return tLegEquClass < c.tLegEquClass;
|
||||||
else if (tDuplicateLeg != c.tDuplicateLeg)
|
else if (tDuplicateLeg != c.tDuplicateLeg)
|
||||||
@ -1730,8 +1759,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder == ClassCourseResult) {
|
else if (oe->CurrentSortOrder == ClassCourseResult) {
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex;
|
||||||
|
|
||||||
const pCourse crs1 = getCourse(false);
|
const pCourse crs1 = getCourse(false);
|
||||||
const pCourse crs2 = c.getCourse(false);
|
const pCourse crs2 = c.getCourse(false);
|
||||||
@ -1805,8 +1834,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
return ft > cft;
|
return ft > cft;
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder == ClassFinishTime){
|
else if (oe->CurrentSortOrder == ClassFinishTime){
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
if (tStatus != c.tStatus)
|
if (tStatus != c.tStatus)
|
||||||
return RunnerStatusOrderMap[tStatus] < RunnerStatusOrderMap[c.tStatus];
|
return RunnerStatusOrderMap[tStatus] < RunnerStatusOrderMap[c.tStatus];
|
||||||
else{
|
else{
|
||||||
@ -1834,8 +1863,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
return et > cet;
|
return et > cet;
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder == ClassPoints) {
|
else if (oe->CurrentSortOrder == ClassPoints) {
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
else if (tDuplicateLeg != c.tDuplicateLeg)
|
else if (tDuplicateLeg != c.tDuplicateLeg)
|
||||||
return tDuplicateLeg < c.tDuplicateLeg;
|
return tDuplicateLeg < c.tDuplicateLeg;
|
||||||
else if (tStatus != c.tStatus)
|
else if (tStatus != c.tStatus)
|
||||||
@ -1852,8 +1881,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder==ClassTotalResult) {
|
else if (oe->CurrentSortOrder==ClassTotalResult) {
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
else if (tDuplicateLeg != c.tDuplicateLeg)
|
else if (tDuplicateLeg != c.tDuplicateLeg)
|
||||||
return tDuplicateLeg < c.tDuplicateLeg;
|
return tDuplicateLeg < c.tDuplicateLeg;
|
||||||
else {
|
else {
|
||||||
@ -1902,8 +1931,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder==ClassStartTimeClub) {
|
else if (oe->CurrentSortOrder==ClassStartTimeClub) {
|
||||||
if (Class != c.Class)
|
if (myClass != cClass)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
else if (tStartTime != c.tStartTime) {
|
else if (tStartTime != c.tStartTime) {
|
||||||
if (tStartTime <= 0 && c.tStartTime > 0)
|
if (tStartTime <= 0 && c.tStartTime > 0)
|
||||||
return false;
|
return false;
|
||||||
@ -1916,8 +1945,8 @@ bool oRunner::operator <(const oRunner &c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oe->CurrentSortOrder==ClassTeamLeg) {
|
else if (oe->CurrentSortOrder==ClassTeamLeg) {
|
||||||
if (Class->Id != c.Class->Id)
|
if (myClass->Id != cClass->Id)
|
||||||
return Class->tSortIndex < c.Class->tSortIndex;
|
return myClass->tSortIndex < cClass->tSortIndex || (myClass->tSortIndex == cClass->tSortIndex && myClass->Id < cClass->Id);
|
||||||
else if (tInTeam != c.tInTeam) {
|
else if (tInTeam != c.tInTeam) {
|
||||||
if (tInTeam == 0)
|
if (tInTeam == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -1959,7 +1988,7 @@ void oAbstractRunner::setClub(const wstring &clubName)
|
|||||||
updateChanged();
|
updateChanged();
|
||||||
if (Class) {
|
if (Class) {
|
||||||
// Vacant clubs have special logic
|
// Vacant clubs have special logic
|
||||||
Class->tResultInfo.clear();
|
getClassRef(true)->tResultInfo.clear();
|
||||||
}
|
}
|
||||||
if (Club && Club->isVacant()) { // Clear entry date/time for vacant
|
if (Club && Club->isVacant()) { // Clear entry date/time for vacant
|
||||||
getDI().setInt("EntryDate", 0);
|
getDI().setInt("EntryDate", 0);
|
||||||
@ -2326,7 +2355,7 @@ void oEvent::getRunners(int classId, int courseId, vector<pRunner> &r, bool sort
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classId <= 0 || it->getClassId() == classId)
|
if (classId <= 0 || it->getClassId(true) == classId)
|
||||||
r.push_back(&*it);
|
r.push_back(&*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2364,7 +2393,7 @@ pRunner oRunner::nextNeedReadout() const {
|
|||||||
// For a runner in a team, first the team for the card
|
// For a runner in a team, first the team for the card
|
||||||
for (size_t k = 0; k < tInTeam->Runners.size(); k++) {
|
for (size_t k = 0; k < tInTeam->Runners.size(); k++) {
|
||||||
pRunner tr = tInTeam->Runners[k];
|
pRunner tr = tInTeam->Runners[k];
|
||||||
if (tr && tr->CardNo == CardNo && !tr->Card && !tr->statusOK())
|
if (tr && tr->getCardNo() == CardNo && !tr->Card && !tr->statusOK())
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2432,9 +2461,11 @@ pRunner oEvent::getRunnerByCardNo(int cardNo, int time, bool onlyWithNoCard, boo
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (time <= 0) { //No time specified. Card readout search
|
if (time <= 0) { //No time specified. Card readout search
|
||||||
|
|
||||||
|
pRunner secondTry = 0;
|
||||||
//First try runners with no card read or a different card read.
|
//First try runners with no card read or a different card read.
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->skip())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (ignoreRunnersWithNoStart && (it->getStatus() == StatusDNS || it->getStatus() == StatusCANCEL))
|
if (ignoreRunnersWithNoStart && (it->getStatus() == StatusDNS || it->getStatus() == StatusCANCEL))
|
||||||
continue;
|
continue;
|
||||||
@ -2442,10 +2473,16 @@ pRunner oEvent::getRunnerByCardNo(int cardNo, int time, bool onlyWithNoCard, boo
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
pRunner ret;
|
pRunner ret;
|
||||||
if (it->CardNo==cardNo && (ret = it->nextNeedReadout()) != 0)
|
if (it->CardNo == cardNo && (ret = it->nextNeedReadout()) != 0) {
|
||||||
|
if (!it->skip())
|
||||||
return ret;
|
return ret;
|
||||||
|
else if (secondTry == 0 || secondTry->tLeg > ret->tLeg)
|
||||||
|
secondTry = ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (secondTry)
|
||||||
|
return secondTry;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
for (it=Runners.begin(); it != Runners.end(); ++it) {
|
||||||
pRunner r = pRunner(&*it);
|
pRunner r = pRunner(&*it);
|
||||||
@ -2745,11 +2782,11 @@ const vector< pair<wstring, size_t> > &oEvent::fillRunners(vector< pair<wstring,
|
|||||||
if (compact) {
|
if (compact) {
|
||||||
swprintf_s(bf, L"%s, %s (%s)", it->getNameAndRace(true).c_str(),
|
swprintf_s(bf, L"%s, %s (%s)", it->getNameAndRace(true).c_str(),
|
||||||
it->getClub().c_str(),
|
it->getClub().c_str(),
|
||||||
it->getClass().c_str());
|
it->getClass(true).c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
swprintf_s(bf, L"%s\t%s\t%s", it->getNameAndRace(true).c_str(),
|
swprintf_s(bf, L"%s\t%s\t%s", it->getNameAndRace(true).c_str(),
|
||||||
it->getClass().c_str(),
|
it->getClass(true).c_str(),
|
||||||
it->getClub().c_str());
|
it->getClub().c_str());
|
||||||
}
|
}
|
||||||
out.push_back(make_pair(bf, it->Id));
|
out.push_back(make_pair(bf, it->Id));
|
||||||
@ -2769,7 +2806,7 @@ const vector< pair<wstring, size_t> > &oEvent::fillRunners(vector< pair<wstring,
|
|||||||
if ( it->getClubId() != lVacId || lVacId == 0)
|
if ( it->getClubId() != lVacId || lVacId == 0)
|
||||||
out.push_back(make_pair(it->getUIName(), it->Id));
|
out.push_back(make_pair(it->getUIName(), it->Id));
|
||||||
else {
|
else {
|
||||||
swprintf_s(bf, L"%s (%s)", it->getUIName().c_str(), it->getClass().c_str());
|
swprintf_s(bf, L"%s (%s)", it->getUIName().c_str(), it->getClass(true).c_str());
|
||||||
out.push_back(make_pair(bf, it->Id));
|
out.push_back(make_pair(bf, it->Id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2879,7 +2916,7 @@ void oRunner::createMultiRunner(bool createMaster, bool sync)
|
|||||||
if (!multiRunner[k-1]) {
|
if (!multiRunner[k-1]) {
|
||||||
update = true;
|
update = true;
|
||||||
multiRunner[k-1]=oe->addRunner(sName, getClubId(),
|
multiRunner[k-1]=oe->addRunner(sName, getClubId(),
|
||||||
getClassId(), 0, 0, false);
|
getClassId(false), 0, 0, false);
|
||||||
multiRunner[k-1]->tDuplicateLeg=k;
|
multiRunner[k-1]->tDuplicateLeg=k;
|
||||||
multiRunner[k-1]->tParentRunner=this;
|
multiRunner[k-1]->tParentRunner=this;
|
||||||
|
|
||||||
@ -2909,6 +2946,12 @@ pRunner oRunner::getPredecessor() const
|
|||||||
|
|
||||||
bool oRunner::apply(bool sync, pRunner src, bool setTmpOnly) {
|
bool oRunner::apply(bool sync, pRunner src, bool setTmpOnly) {
|
||||||
createMultiRunner(false, sync);
|
createMultiRunner(false, sync);
|
||||||
|
if (sync) {
|
||||||
|
for (size_t k = 0; k < multiRunner.size(); k++) {
|
||||||
|
if (multiRunner[k])
|
||||||
|
multiRunner[k]->synchronize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
tLeg = -1;
|
tLeg = -1;
|
||||||
tLegEquClass = 0;
|
tLegEquClass = 0;
|
||||||
tUseStartPunch=true;
|
tUseStartPunch=true;
|
||||||
@ -3045,7 +3088,7 @@ void oEvent::generateRunnerTableData(Table &table, oRunner *addRunner)
|
|||||||
oRunnerList::iterator it;
|
oRunnerList::iterator it;
|
||||||
table.reserve(Runners.size());
|
table.reserve(Runners.size());
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it){
|
for (it=Runners.begin(); it != Runners.end(); ++it){
|
||||||
if (!it->skip()){
|
if (!it->isRemoved()){
|
||||||
it->addTableRow(table);
|
it->addTableRow(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3088,11 +3131,13 @@ void oRunner::addTableRow(Table &table) const
|
|||||||
table.set(row++, it, TID_ID, itow(getId()), false);
|
table.set(row++, it, TID_ID, itow(getId()), false);
|
||||||
table.set(row++, it, TID_MODIFIED, getTimeStamp(), false);
|
table.set(row++, it, TID_MODIFIED, getTimeStamp(), false);
|
||||||
|
|
||||||
|
if (tParentRunner == 0)
|
||||||
table.set(row++, it, TID_RUNNER, getUIName(), true);
|
table.set(row++, it, TID_RUNNER, getUIName(), true);
|
||||||
|
else
|
||||||
table.set(row++, it, TID_CLASSNAME, getClass(), true, cellSelection);
|
table.set(row++, it, TID_RUNNER, getUIName() + L" (" + itow(tDuplicateLeg+1) + L")", false);
|
||||||
|
table.set(row++, it, TID_CLASSNAME, getClass(true), true, cellSelection);
|
||||||
table.set(row++, it, TID_COURSE, getCourseName(), true, cellSelection);
|
table.set(row++, it, TID_COURSE, getCourseName(), true, cellSelection);
|
||||||
table.set(row++, it, TID_CLUB, getClub(), true, cellCombo);
|
table.set(row++, it, TID_CLUB, getClub(), tParentRunner == 0, cellCombo);
|
||||||
|
|
||||||
table.set(row++, it, TID_TEAM, tInTeam ? tInTeam->getName() : L"", false);
|
table.set(row++, it, TID_TEAM, tInTeam ? tInTeam->getName() : L"", false);
|
||||||
table.set(row++, it, TID_LEG, tInTeam ? itow(tLeg+1) : L"" , false);
|
table.set(row++, it, TID_LEG, tInTeam ? itow(tLeg+1) : L"" , false);
|
||||||
@ -3138,7 +3183,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(), getCardNo(), getBirthYear());
|
updateFromDB(input, getClubId(), getClassId(false), getCardNo(), getBirthYear());
|
||||||
setName(input, true);
|
setName(input, true);
|
||||||
synchronizeAll();
|
synchronizeAll();
|
||||||
}
|
}
|
||||||
@ -3184,7 +3229,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(), getCardNo(), getBirthYear());
|
updateFromDB(getName(), pc ? pc->getId():0, getClassId(false), getCardNo(), getBirthYear());
|
||||||
|
|
||||||
setClub(pc ? pc->getName() : L"");
|
setClub(pc ? pc->getName() : L"");
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
@ -3195,7 +3240,7 @@ bool oRunner::inputData(int id, const wstring &input,
|
|||||||
case TID_CLASSNAME:
|
case TID_CLASSNAME:
|
||||||
setClassId(inputId, true);
|
setClassId(inputId, true);
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
output = getClass();
|
output = getClass(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_STATUS: {
|
case TID_STATUS: {
|
||||||
@ -3258,7 +3303,7 @@ void oRunner::fillInput(int id, vector< pair<wstring, size_t> > &out, size_t &se
|
|||||||
else if (id==TID_CLASSNAME) {
|
else if (id==TID_CLASSNAME) {
|
||||||
oe->fillClasses(out, oEvent::extraNone, oEvent::filterNone);
|
oe->fillClasses(out, oEvent::extraNone, oEvent::filterNone);
|
||||||
out.push_back(make_pair(lang.tl(L"Ingen klass"), 0));
|
out.push_back(make_pair(lang.tl(L"Ingen klass"), 0));
|
||||||
selected = getClassId();
|
selected = getClassId(true);
|
||||||
}
|
}
|
||||||
else if (id==TID_CLUB) {
|
else if (id==TID_CLUB) {
|
||||||
oe->fillClubs(out);
|
oe->fillClubs(out);
|
||||||
@ -3378,7 +3423,7 @@ void oRunner::getSplitTime(int courseControlId, RunnerStatus &stat, int &rt) con
|
|||||||
{
|
{
|
||||||
rt = 0;
|
rt = 0;
|
||||||
stat = StatusUnknown;
|
stat = StatusUnknown;
|
||||||
int cardno = tParentRunner ? tParentRunner->CardNo : CardNo;
|
int cardno = getCardNo();
|
||||||
|
|
||||||
if (courseControlId==oPunch::PunchFinish &&
|
if (courseControlId==oPunch::PunchFinish &&
|
||||||
FinishTime>0 && tStatus!=StatusUnknown) {
|
FinishTime>0 && tStatus!=StatusUnknown) {
|
||||||
@ -3643,7 +3688,9 @@ const wstring &oAbstractRunner::getBib() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void oRunner::setBib(const wstring &bib, int bibNumerical, bool updateStartNo, bool tmpOnly) {
|
void oRunner::setBib(const wstring &bib, int bibNumerical, bool updateStartNo, bool tmpOnly) {
|
||||||
if (tParentRunner)
|
const bool freeBib = !Class || Class->getBibMode() == BibMode::BibFree;
|
||||||
|
|
||||||
|
if (tParentRunner && !freeBib)
|
||||||
tParentRunner->setBib(bib, bibNumerical, updateStartNo, tmpOnly);
|
tParentRunner->setBib(bib, bibNumerical, updateStartNo, tmpOnly);
|
||||||
else {
|
else {
|
||||||
if (updateStartNo)
|
if (updateStartNo)
|
||||||
@ -3657,13 +3704,14 @@ void oRunner::setBib(const wstring &bib, int bibNumerical, bool updateStartNo, b
|
|||||||
if (oe)
|
if (oe)
|
||||||
oe->bibStartNoToRunnerTeam.clear();
|
oe->bibStartNoToRunnerTeam.clear();
|
||||||
}
|
}
|
||||||
|
if (!freeBib) {
|
||||||
for (size_t k=0;k<multiRunner.size();k++) {
|
for (size_t k = 0; k < multiRunner.size(); k++) {
|
||||||
if (multiRunner[k]) {
|
if (multiRunner[k]) {
|
||||||
multiRunner[k]->getDI().setString("Bib", bib);
|
multiRunner[k]->getDI().setString("Bib", bib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3848,7 +3896,7 @@ void oRunner::printSplits(gdioutput &gdi) const {
|
|||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
pCourse pc = getCourse(true);
|
pCourse pc = getCourse(true);
|
||||||
|
|
||||||
gdi.addStringUT(bnormal, getName() + L", " + getClass());
|
gdi.addStringUT(bnormal, getName() + L", " + getClass(true));
|
||||||
gdi.addStringUT(normal, getClub());
|
gdi.addStringUT(normal, getClub());
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
gdi.addStringUT(normal, lang.tl("Start: ") + getStartTimeS() + lang.tl(", Mål: ") + getFinishTimeS());
|
gdi.addStringUT(normal, lang.tl("Start: ") + getStartTimeS() + lang.tl(", Mål: ") + getFinishTimeS());
|
||||||
@ -4175,7 +4223,7 @@ void oRunner::printStartInfo(gdioutput &gdi) const {
|
|||||||
if (!bib.empty())
|
if (!bib.empty())
|
||||||
bib = bib + L": ";
|
bib = bib + L": ";
|
||||||
|
|
||||||
gdi.addStringUT(boldSmall, bib + getName() + L", " + getClass());
|
gdi.addStringUT(boldSmall, bib + getName() + L", " + getClass(true));
|
||||||
gdi.addStringUT(fontSmall, getClub());
|
gdi.addStringUT(fontSmall, getClub());
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
|
|
||||||
@ -4274,7 +4322,7 @@ 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(), it->getCardNo(), it->getBirthYear());
|
it->updateFromDB(it->sName, it->getClubId(), it->getClassId(false), it->getCardNo(), it->getBirthYear());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5258,6 +5306,10 @@ void oRunner::markClassChanged(int controlId) {
|
|||||||
assert(controlId < 4096);
|
assert(controlId < 4096);
|
||||||
if (Class) {
|
if (Class) {
|
||||||
Class->markSQLChanged(tLeg, controlId);
|
Class->markSQLChanged(tLeg, controlId);
|
||||||
|
pClass cls2 = getClassRef(true);
|
||||||
|
if (cls2 != Class)
|
||||||
|
cls2->markSQLChanged(-1, controlId);
|
||||||
|
|
||||||
if (tInTeam && tInTeam->Class != Class && tInTeam->Class) {
|
if (tInTeam && tInTeam->Class != Class && tInTeam->Class) {
|
||||||
tInTeam->Class->markSQLChanged(tLeg, controlId);
|
tInTeam->Class->markSQLChanged(tLeg, controlId);
|
||||||
}
|
}
|
||||||
@ -5535,10 +5587,13 @@ int oRunner::getRanking() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void oAbstractRunner::hasManuallyUpdatedTimeStatus() {
|
void oAbstractRunner::hasManuallyUpdatedTimeStatus() {
|
||||||
if (Class && Class->hasClassGlobalDependance()) {
|
if (Class && Class->hasClassGlobalDependence()) {
|
||||||
set<int> cls;
|
set<int> cls;
|
||||||
oe->reEvaluateAll(cls, false);
|
oe->reEvaluateAll(cls, false);
|
||||||
}
|
}
|
||||||
|
if (Class) {
|
||||||
|
Class->updateFinalClasses(dynamic_cast<oRunner *>(this), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool oRunner::canShareCard(const pRunner other, int newCardNo) const {
|
bool oRunner::canShareCard(const pRunner other, int newCardNo) const {
|
||||||
@ -5555,7 +5610,7 @@ bool oRunner::canShareCard(const pRunner other, int newCardNo) const {
|
|||||||
if (!getTeam() || other->getTeam() != getTeam())
|
if (!getTeam() || other->getTeam() != getTeam())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pClass tCls = getTeam()->getClassRef();
|
const oClass * tCls = getTeam()->getClassRef(false);
|
||||||
if (!tCls || tCls != Class)
|
if (!tCls || tCls != Class)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -5598,3 +5653,24 @@ bool oAbstractRunner::hasLateEntryFee() const {
|
|||||||
|
|
||||||
return late;
|
return late;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int oRunner::classInstance() const {
|
||||||
|
if (classInstanceRev.first == oe->dataRevision)
|
||||||
|
return classInstanceRev.second;
|
||||||
|
classInstanceRev.second = getDCI().getInt("Heat");
|
||||||
|
if (Class)
|
||||||
|
classInstanceRev.second = min(classInstanceRev.second, Class->getNumQualificationFinalClasses());
|
||||||
|
classInstanceRev.first = oe->dataRevision;
|
||||||
|
return classInstanceRev.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wstring &oAbstractRunner::getClass(bool virtualClass) const {
|
||||||
|
if (Class) {
|
||||||
|
if (virtualClass)
|
||||||
|
return Class->getVirtualClass(classInstance())->Name;
|
||||||
|
else
|
||||||
|
return Class->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
else return _EmptyWString;
|
||||||
|
}
|
||||||
|
|||||||
@ -255,17 +255,28 @@ public:
|
|||||||
|
|
||||||
const pClub getClubRef() const {return Club;}
|
const pClub getClubRef() const {return Club;}
|
||||||
pClub getClubRef() {return Club;}
|
pClub getClubRef() {return Club;}
|
||||||
|
virtual int classInstance() const = 0;
|
||||||
|
|
||||||
const pClass getClassRef() const {return Class;}
|
const oClass *getClassRef(bool virtualClass) const {
|
||||||
pClass getClassRef() {return Class;}
|
return (virtualClass && Class) ? Class->getVirtualClass(classInstance()) : Class;
|
||||||
|
}
|
||||||
|
|
||||||
|
pClass getClassRef(bool virtualClass) {
|
||||||
|
return pClass((virtualClass && Class) ? Class->getVirtualClass(classInstance()) : Class);
|
||||||
|
}
|
||||||
|
|
||||||
virtual const wstring &getClub() const {if (Club) return Club->name; else return _EmptyWString;}
|
virtual const wstring &getClub() const {if (Club) return Club->name; else return _EmptyWString;}
|
||||||
virtual int getClubId() const {if (Club) return Club->Id; else return 0;}
|
virtual int getClubId() const {if (Club) return Club->Id; else return 0;}
|
||||||
virtual void setClub(const wstring &clubName);
|
virtual void setClub(const wstring &clubName);
|
||||||
virtual pClub setClubId(int clubId);
|
virtual pClub setClubId(int clubId);
|
||||||
|
|
||||||
virtual const wstring &getClass() const {if (Class) return Class->Name; else return _EmptyWString;}
|
const wstring &getClass(bool virtualClass) const;
|
||||||
virtual int getClassId() const {if (Class) return Class->Id; else return 0;}
|
int getClassId(bool virtualClass) const {
|
||||||
|
if (Class)
|
||||||
|
return virtualClass ? Class->getVirtualClass(classInstance())->Id : Class->Id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setClassId(int id, bool isManualUpdate);
|
virtual void setClassId(int id, bool isManualUpdate);
|
||||||
virtual int getStartNo() const {return StartNo;}
|
virtual int getStartNo() const {return StartNo;}
|
||||||
virtual void setStartNo(int no, bool storeTmpOnly);
|
virtual void setStartNo(int no, bool storeTmpOnly);
|
||||||
@ -457,6 +468,8 @@ protected:
|
|||||||
// Running time as calculated by evalute. Used to detect changes.
|
// Running time as calculated by evalute. Used to detect changes.
|
||||||
int tCachedRunningTime;
|
int tCachedRunningTime;
|
||||||
|
|
||||||
|
mutable pair<int, int> classInstanceRev;
|
||||||
|
|
||||||
void clearOnChangedRunningTime();
|
void clearOnChangedRunningTime();
|
||||||
|
|
||||||
// Cached runner statistics
|
// Cached runner statistics
|
||||||
@ -499,6 +512,8 @@ public:
|
|||||||
/** Get a runner reference (drawing) */
|
/** Get a runner reference (drawing) */
|
||||||
pRunner getReference() const;
|
pRunner getReference() const;
|
||||||
|
|
||||||
|
int classInstance() const override;
|
||||||
|
|
||||||
/**Set a runner reference*/
|
/**Set a runner reference*/
|
||||||
void setReference(int runnerId);
|
void setReference(int runnerId);
|
||||||
|
|
||||||
@ -546,6 +561,9 @@ public:
|
|||||||
int getLegNumber() const {return tLeg;}
|
int getLegNumber() const {return tLeg;}
|
||||||
int getSpeakerPriority() const;
|
int getSpeakerPriority() const;
|
||||||
|
|
||||||
|
RunnerStatus getTempStatus() const { return tempStatus; }
|
||||||
|
int getTempTime() const { return tempRT; }
|
||||||
|
|
||||||
void remove();
|
void remove();
|
||||||
bool canRemove() const;
|
bool canRemove() const;
|
||||||
|
|
||||||
@ -703,7 +721,7 @@ public:
|
|||||||
pCard getCard() const {return Card;}
|
pCard getCard() const {return Card;}
|
||||||
int getCardId(){if (Card) return Card->Id; else return 0;}
|
int getCardId(){if (Card) return Card->Id; else return 0;}
|
||||||
|
|
||||||
bool operator<(const oRunner &c);
|
bool operator<(const oRunner &c) const;
|
||||||
bool static CompareSINumber(const oRunner &a, const oRunner &b){return a.CardNo<b.CardNo;}
|
bool static CompareSINumber(const oRunner &a, const oRunner &b){return a.CardNo<b.CardNo;}
|
||||||
|
|
||||||
bool evaluateCard(bool applyTeam, vector<int> &missingPunches, int addpunch=0, bool synchronize=false);
|
bool evaluateCard(bool applyTeam, vector<int> &missingPunches, int addpunch=0, bool synchronize=false);
|
||||||
@ -716,7 +734,7 @@ 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);
|
||||||
|
|
||||||
int getCardNo() const {return tParentRunner ? 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.
|
||||||
CardNo is updated. Returns id of old card (or 0).
|
CardNo is updated. Returns id of old card (or 0).
|
||||||
|
|||||||
@ -315,7 +315,7 @@ void oTeam::setRunnerInternal(int k, pRunner r)
|
|||||||
Runners[k]->tInTeam = this;
|
Runners[k]->tInTeam = this;
|
||||||
Runners[k]->tLeg = k;
|
Runners[k]->tLeg = k;
|
||||||
if (Class && Class->getLegType(k) != LTGroup)
|
if (Class && Class->getLegType(k) != LTGroup)
|
||||||
Runners[k]->setClassId(getClassId(), false);
|
Runners[k]->setClassId(getClassId(false), false);
|
||||||
}
|
}
|
||||||
updateChanged();
|
updateChanged();
|
||||||
}
|
}
|
||||||
@ -698,7 +698,7 @@ bool oTeam::compareResult(const oTeam &a, const oTeam &b)
|
|||||||
{
|
{
|
||||||
if (a.Class != b.Class) {
|
if (a.Class != b.Class) {
|
||||||
if (a.Class) {
|
if (a.Class) {
|
||||||
if (b.Class) return a.Class->tSortIndex < b.Class->tSortIndex;
|
if (b.Class) return a.Class->tSortIndex < b.Class->tSortIndex || (a.Class->tSortIndex == b.Class->tSortIndex && a.Class->Id < b.Class->Id);
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
@ -728,7 +728,8 @@ bool oTeam::compareStartTime(const oTeam &a, const oTeam &b)
|
|||||||
{
|
{
|
||||||
if (a.Class != b.Class) {
|
if (a.Class != b.Class) {
|
||||||
if (a.Class) {
|
if (a.Class) {
|
||||||
if (b.Class) return a.Class->tSortIndex<b.Class->tSortIndex;
|
if (b.Class)
|
||||||
|
return a.Class->tSortIndex<b.Class->tSortIndex || (a.Class->tSortIndex == b.Class->tSortIndex && a.Class->Id < b.Class->Id);
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,7 +761,8 @@ bool oTeam::compareSNO(const oTeam &a, const oTeam &b) {
|
|||||||
}
|
}
|
||||||
else if (a.Class != b.Class) {
|
else if (a.Class != b.Class) {
|
||||||
if (a.Class) {
|
if (a.Class) {
|
||||||
if (b.Class) return a.Class->tSortIndex<b.Class->tSortIndex;
|
if (b.Class)
|
||||||
|
return a.Class->tSortIndex < b.Class->tSortIndex || (a.Class->tSortIndex == b.Class->tSortIndex && a.Class->Id < b.Class->Id);
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -928,6 +930,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Runners[i]) {
|
if (Runners[i]) {
|
||||||
|
pClass actualClass = Runners[i]->getClassRef(true);
|
||||||
if (Runners[i]->tInTeam && Runners[i]->tInTeam!=this) {
|
if (Runners[i]->tInTeam && Runners[i]->tInTeam!=this) {
|
||||||
Runners[i]->tInTeam->correctRemove(Runners[i]);
|
Runners[i]->tInTeam->correctRemove(Runners[i]);
|
||||||
}
|
}
|
||||||
@ -942,6 +945,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
|||||||
Runners[i]->tLegEquClass = i;
|
Runners[i]->tLegEquClass = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actualClass == Class)
|
||||||
Runners[i]->setStartNo(StartNo, setTmpOnly);
|
Runners[i]->setStartNo(StartNo, setTmpOnly);
|
||||||
if (!bib.empty() && Runners[i]->isChanged()) {
|
if (!bib.empty() && Runners[i]->isChanged()) {
|
||||||
if (bibMode == -1 && Class)
|
if (bibMode == -1 && Class)
|
||||||
@ -980,7 +984,7 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
|||||||
else
|
else
|
||||||
lastStatus = Runners[i]->getStatus();
|
lastStatus = Runners[i]->getStatus();
|
||||||
|
|
||||||
StartTypes st = pc->getStartType(i);
|
StartTypes st = actualClass == pc ? pc->getStartType(i) : actualClass->getStartType(0);
|
||||||
LegTypes lt = legType;
|
LegTypes lt = legType;
|
||||||
|
|
||||||
if ((lt==LTParallel || lt==LTParallelOptional) && i==0) {
|
if ((lt==LTParallel || lt==LTParallelOptional) && i==0) {
|
||||||
@ -1016,9 +1020,12 @@ bool oTeam::apply(bool sync, pRunner source, bool setTmpOnly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!prs) {
|
if (!prs) {
|
||||||
if (lt==LTNormal || lt==LTSum || lt == LTGroup)
|
if (lt == LTNormal || lt == LTSum || lt == LTGroup) {
|
||||||
lastStartTime=pc->getStartData(i);
|
if (actualClass == pc)
|
||||||
|
lastStartTime = pc->getStartData(i);
|
||||||
|
else
|
||||||
|
lastStartTime = actualClass->getStartData(0); // Qualification/final classes
|
||||||
|
}
|
||||||
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
Runners[i]->setStartTime(lastStartTime, false, setTmpOnly);
|
||||||
Runners[i]->tUseStartPunch=false;
|
Runners[i]->tUseStartPunch=false;
|
||||||
}
|
}
|
||||||
@ -1740,7 +1747,7 @@ void oEvent::getTeams(int classId, vector<pTeam> &t, bool sort) {
|
|||||||
if (it->isRemoved())
|
if (it->isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (classId == 0 || it->getClassId() == classId)
|
if (classId == 0 || it->getClassId(false) == classId)
|
||||||
t.push_back(&*it);
|
t.push_back(&*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1855,7 +1862,7 @@ void oTeam::addTableRow(Table &table) const {
|
|||||||
table.set(row++, it, TID_MODIFIED, getTimeStamp(), false);
|
table.set(row++, it, TID_MODIFIED, getTimeStamp(), false);
|
||||||
|
|
||||||
table.set(row++, it, TID_NAME, getName(), true);
|
table.set(row++, it, TID_NAME, getName(), true);
|
||||||
table.set(row++, it, TID_CLASSNAME, getClass(), true, cellSelection);
|
table.set(row++, it, TID_CLASSNAME, getClass(true), true, cellSelection);
|
||||||
table.set(row++, it, TID_CLUB, getClub(), true, cellCombo);
|
table.set(row++, it, TID_CLUB, getClub(), true, cellCombo);
|
||||||
|
|
||||||
table.set(row++, it, TID_START, getStartTimeS(), true);
|
table.set(row++, it, TID_START, getStartTimeS(), true);
|
||||||
@ -1920,7 +1927,7 @@ bool oTeam::inputData(int id, const wstring &input,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (isName && !input.empty() && Class) {
|
if (isName && !input.empty() && Class) {
|
||||||
pRunner r = oe->addRunner(input, getClubId(), getClassId(), 0, 0, false);
|
pRunner r = oe->addRunner(input, getClubId(), getClassId(false), 0, 0, false);
|
||||||
setRunner(ix, r, true);
|
setRunner(ix, r, true);
|
||||||
output = r->getName();
|
output = r->getName();
|
||||||
}
|
}
|
||||||
@ -1968,7 +1975,7 @@ bool oTeam::inputData(int id, const wstring &input,
|
|||||||
case TID_CLASSNAME:
|
case TID_CLASSNAME:
|
||||||
setClassId(inputId, true);
|
setClassId(inputId, true);
|
||||||
synchronize(true);
|
synchronize(true);
|
||||||
output = getClass();
|
output = getClass(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_STATUS: {
|
case TID_STATUS: {
|
||||||
@ -2033,7 +2040,7 @@ void oTeam::fillInput(int id, vector< pair<wstring, size_t> > &out, size_t &sele
|
|||||||
else if (id==TID_CLASSNAME) {
|
else if (id==TID_CLASSNAME) {
|
||||||
oe->fillClasses(out, oEvent::extraNone, oEvent::filterOnlyMulti);
|
oe->fillClasses(out, oEvent::extraNone, oEvent::filterOnlyMulti);
|
||||||
out.push_back(make_pair(lang.tl(L"Ingen klass"), 0));
|
out.push_back(make_pair(lang.tl(L"Ingen klass"), 0));
|
||||||
selected = getClassId();
|
selected = getClassId(true);
|
||||||
}
|
}
|
||||||
else if (id==TID_CLUB) {
|
else if (id==TID_CLUB) {
|
||||||
oe->fillClubs(out);
|
oe->fillClubs(out);
|
||||||
|
|||||||
@ -105,6 +105,10 @@ public:
|
|||||||
|
|
||||||
int getRanking() const;
|
int getRanking() const;
|
||||||
|
|
||||||
|
int classInstance() const override {
|
||||||
|
return 0; // Not supported
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@ -102,7 +102,7 @@ const vector< pair<wstring, size_t> > &oEvent::fillTeams(vector< pair<wstring, s
|
|||||||
tn = dashes + it->getName();
|
tn = dashes + it->getName();
|
||||||
}
|
}
|
||||||
if (it->Class)
|
if (it->Class)
|
||||||
out.push_back(make_pair(tn + L" (" + it->getClass() + L")", it->Id));
|
out.push_back(make_pair(tn + L" (" + it->getClass(true) + L")", it->Id));
|
||||||
else
|
else
|
||||||
out.push_back(make_pair(tn, it->Id));
|
out.push_back(make_pair(tn, it->Id));
|
||||||
}
|
}
|
||||||
@ -612,14 +612,14 @@ void oEvent::adjustTeamMultiRunners(pClass cls)
|
|||||||
if (cls) {
|
if (cls) {
|
||||||
bool multi = cls->getNumStages() > 1;
|
bool multi = cls->getNumStages() > 1;
|
||||||
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
for (oRunnerList::iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
||||||
if (it->skip() || it->getClassId() != cls->getId())
|
if (it->skip() || it->getClassId(false) != cls->getId())
|
||||||
continue;
|
continue;
|
||||||
if (multi && it->tInTeam == 0) {
|
if (multi && it->tInTeam == 0) {
|
||||||
oe->autoAddTeam(&*it);
|
oe->autoAddTeam(&*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!multi && it->tInTeam) {
|
if (!multi && it->tInTeam) {
|
||||||
assert( it->tInTeam->getClassId() == cls->getId());
|
assert( it->tInTeam->getClassId(false) == cls->getId());
|
||||||
removeTeam(it->tInTeam->getId());
|
removeTeam(it->tInTeam->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,7 +628,7 @@ void oEvent::adjustTeamMultiRunners(pClass cls)
|
|||||||
|
|
||||||
vector<int> tr;
|
vector<int> tr;
|
||||||
for (oTeamList::iterator it=Teams.begin(); it != Teams.end(); ++it) {
|
for (oTeamList::iterator it=Teams.begin(); it != Teams.end(); ++it) {
|
||||||
if (!multi && !it->isRemoved() && it->getClassId() == cls->getId()) {
|
if (!multi && !it->isRemoved() && it->getClassId(false) == cls->getId()) {
|
||||||
tr.push_back(it->getId());
|
tr.push_back(it->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -728,9 +728,9 @@ void oTeam::checkClassesWithReferences(oEvent &oe, std::set<int> &clsWithRef) {
|
|||||||
map<int, pair<int, int> > pairedUnpairedPerClass;
|
map<int, pair<int, int> > pairedUnpairedPerClass;
|
||||||
for (size_t k = 0; k < r.size(); k++) {
|
for (size_t k = 0; k < r.size(); k++) {
|
||||||
if (r[k]->getReference())
|
if (r[k]->getReference())
|
||||||
++pairedUnpairedPerClass[r[k]->getClassId()].first;
|
++pairedUnpairedPerClass[r[k]->getClassId(false)].first;
|
||||||
else
|
else
|
||||||
++pairedUnpairedPerClass[r[k]->getClassId()].second;
|
++pairedUnpairedPerClass[r[k]->getClassId(false)].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &it : pairedUnpairedPerClass) {
|
for (auto &it : pairedUnpairedPerClass) {
|
||||||
@ -744,8 +744,8 @@ void oTeam::convertClassWithReferenceToPatrol(oEvent &oe, const std::set<int> &c
|
|||||||
oe.getRunners(-1, -1, r, true);
|
oe.getRunners(-1, -1, r, true);
|
||||||
|
|
||||||
for(auto it : r) {
|
for(auto it : r) {
|
||||||
if (clsWithRef.count(it->getClassId())) {
|
if (clsWithRef.count(it->getClassId(false))) {
|
||||||
pClass cls = it->getClassRef();
|
pClass cls = it->getClassRef(false);
|
||||||
|
|
||||||
if (cls->getNumStages() == 0) {
|
if (cls->getNumStages() == 0) {
|
||||||
pCourse crs = cls->getCourse();
|
pCourse crs = cls->getCourse();
|
||||||
|
|||||||
@ -45,11 +45,27 @@ class oSpeakerObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct RunningTime {
|
struct RunningTime {
|
||||||
|
void reset() { time = 0; preliminary = 0; }
|
||||||
int time;
|
int time;
|
||||||
int preliminary;
|
int preliminary;
|
||||||
RunningTime() : time(0), preliminary(0) {}
|
RunningTime() : time(0), preliminary(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
owner = 0;
|
||||||
|
bib.clear();
|
||||||
|
names.clear();
|
||||||
|
outgoingnames.clear();
|
||||||
|
resultRemark.clear();
|
||||||
|
club.clear();
|
||||||
|
startTimeS.clear();
|
||||||
|
status = StatusUnknown;
|
||||||
|
finishStatus = StatusUnknown;
|
||||||
|
useSinceLast = 0;
|
||||||
|
runningTime.reset();
|
||||||
|
runningTimeLeg.reset();
|
||||||
|
runningTimeSinceLast.reset();
|
||||||
|
}
|
||||||
oRunner *owner;
|
oRunner *owner;
|
||||||
wstring bib;
|
wstring bib;
|
||||||
vector<wstring> names;
|
vector<wstring> names;
|
||||||
|
|||||||
298
code/qualification_final.cpp
Normal file
298
code/qualification_final.cpp
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "qualification_final.h"
|
||||||
|
|
||||||
|
#include "meos_util.h"
|
||||||
|
#include "meosexception.h"
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "xmlparser.h"
|
||||||
|
|
||||||
|
pair<int, int> QualificationFinal::getNextFinal(int instance, int orderPlace, int numSharedPlaceNext) const {
|
||||||
|
pair<int, int> key(instance, orderPlace);
|
||||||
|
int iter = 0;
|
||||||
|
while (numSharedPlaceNext >= 0) {
|
||||||
|
auto res = sourcePlaceToFinalOrder.find(key);
|
||||||
|
if (res != sourcePlaceToFinalOrder.end()) {
|
||||||
|
if (iter >= 2) { // For three in a shared last place
|
||||||
|
pair<int, int> key2 = key;
|
||||||
|
int extraSub = ((iter + 1) % 2);
|
||||||
|
key2.second -= extraSub;
|
||||||
|
auto res2 = sourcePlaceToFinalOrder.find(key2);
|
||||||
|
if (res2 != sourcePlaceToFinalOrder.end()) {
|
||||||
|
auto ans = res2->second;
|
||||||
|
ans.second += iter + extraSub;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto ans = res->second;
|
||||||
|
ans.second += iter;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
--key.second;
|
||||||
|
--numSharedPlaceNext;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_pair(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QualificationFinal::noQualification(int instance) const {
|
||||||
|
if (size_t(instance) >= classDefinition.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return classDefinition[instance].qualificationMap.empty() &&
|
||||||
|
classDefinition[instance].timeQualifications.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QualificationFinal::getBaseClassInstances(set<int> &base) const {
|
||||||
|
for (size_t k = 0; k < classDefinition.size(); k++) {
|
||||||
|
if (noQualification(k))
|
||||||
|
base.insert(k+1);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QualificationFinal::import(const wstring &file) {
|
||||||
|
xmlparser xml;
|
||||||
|
xml.read(file);
|
||||||
|
|
||||||
|
auto qr = xml.getObject("QualificationRules");
|
||||||
|
xmlList levels;
|
||||||
|
qr.getObjects("Level", levels);
|
||||||
|
map<int, int> idToIndex;
|
||||||
|
map<int, set<int> > qualificationRelations;
|
||||||
|
int numBaseLevels = 0;
|
||||||
|
int iLevel = 0;
|
||||||
|
for (size_t iLevel = 0; iLevel < levels.size(); iLevel++) {
|
||||||
|
auto &level = levels[iLevel];
|
||||||
|
xmlList classes;
|
||||||
|
level.getObjects("Class", classes);
|
||||||
|
for (auto &cls : classes) {
|
||||||
|
wstring name;
|
||||||
|
cls.getObjectString("Name", name);
|
||||||
|
if (name.empty())
|
||||||
|
throw meosException("Klassen måste ha ett namn.");
|
||||||
|
int classId = cls.getObjectInt("id");
|
||||||
|
if (!(classId>0))
|
||||||
|
throw meosException("Id must be a positive integer.");
|
||||||
|
if (idToIndex.count(classId))
|
||||||
|
throw meosException("Duplicate class with id " + itos(classId));
|
||||||
|
|
||||||
|
xmlList rules;
|
||||||
|
cls.getObjects("Qualification", rules);
|
||||||
|
if (rules.empty())
|
||||||
|
numBaseLevels = 1; // Instance zero is not used as qualification,
|
||||||
|
|
||||||
|
idToIndex[classId] = classDefinition.size() + numBaseLevels;
|
||||||
|
classDefinition.push_back(Class());
|
||||||
|
classDefinition.back().name = name;
|
||||||
|
|
||||||
|
for (auto &qf : rules) {
|
||||||
|
int place = qf.getObjectInt("place");
|
||||||
|
if (place > 0) {
|
||||||
|
int id = qf.getObjectInt("id");
|
||||||
|
if (id == 0 && iLevel == 0)
|
||||||
|
classDefinition.back().qualificationMap.push_back(make_pair(0, place));
|
||||||
|
else if (idToIndex.count(id)) {
|
||||||
|
classDefinition.back().qualificationMap.push_back(make_pair(idToIndex[id], place));
|
||||||
|
qualificationRelations[classId].insert(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw meosException("Unknown class with id " + itos(id));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
string time;
|
||||||
|
qf.getObjectString("place", time);
|
||||||
|
if (time == "time") {
|
||||||
|
string ids;
|
||||||
|
qf.getObjectString("id", ids);
|
||||||
|
vector<string> vid;
|
||||||
|
split(ids, ",;", vid);
|
||||||
|
vector<int> ivid;
|
||||||
|
for (auto &s : vid) {
|
||||||
|
int i = atoi(s.c_str());
|
||||||
|
if (!idToIndex.count(i))
|
||||||
|
throw meosException("Unknown class with id " + itos(i));
|
||||||
|
ivid.push_back(idToIndex[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ivid.empty())
|
||||||
|
throw meosException(L"Empty time qualification for " + name);
|
||||||
|
classDefinition.back().timeQualifications.push_back(ivid);
|
||||||
|
}
|
||||||
|
else throw meosException("Unknown classification rule " + time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*classDefinition.resize(3);
|
||||||
|
classDefinition[0].name = L"Semi A";
|
||||||
|
classDefinition[1].name = L"Semi B";
|
||||||
|
classDefinition[2].name = L"Final";
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
classDefinition[0].qualificationMap.push_back(make_pair(0, i * 2 + 1));
|
||||||
|
classDefinition[1].qualificationMap.push_back(make_pair(0, i * 2 + 2));
|
||||||
|
classDefinition[2].qualificationMap.push_back(make_pair(i%2+1, i/2 + 1));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
initgmap(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QualificationFinal::init(const wstring &def) {
|
||||||
|
vector <wstring> races, rtdef, rdef;
|
||||||
|
split(def, L"|", races);
|
||||||
|
classDefinition.resize(races.size());
|
||||||
|
bool valid = true;
|
||||||
|
bool first = true;
|
||||||
|
for (size_t k = 0; k < races.size(); k++) {
|
||||||
|
split(races[k], L"T", rtdef);
|
||||||
|
classDefinition[k].qualificationMap.clear();
|
||||||
|
classDefinition[k].timeQualifications.clear();
|
||||||
|
|
||||||
|
if (first && rtdef.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
valid = rtdef.size() > 0;
|
||||||
|
if (!valid)
|
||||||
|
break;
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
split(rtdef[0], L";", rdef);
|
||||||
|
valid = rdef.size() > 0 && rdef.size()%2 == 0;
|
||||||
|
if (!valid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < rdef.size(); j+=2) {
|
||||||
|
size_t src = _wtoi(rdef[j].c_str());
|
||||||
|
if (src > k) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const wstring &rd = rdef[j + 1];
|
||||||
|
size_t d1 = _wtoi(rd.c_str());
|
||||||
|
size_t d2 = d1;
|
||||||
|
size_t range = rd.find_first_of('-', 0);
|
||||||
|
if (range < rd.size())
|
||||||
|
d2 = _wtoi(rd.c_str()+range+1);
|
||||||
|
|
||||||
|
if (d1 > d2) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (d1 <= d2) {
|
||||||
|
classDefinition[k].qualificationMap.push_back(make_pair(int(src), int(d1)));
|
||||||
|
d1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; valid && i < rtdef.size(); i++) {
|
||||||
|
split(rtdef[i], L";", rdef);
|
||||||
|
classDefinition[k].timeQualifications.push_back(vector<int>());
|
||||||
|
for (size_t j = 0; valid && j < rdef.size(); j += 2) {
|
||||||
|
size_t src = _wtoi(rdef[j].c_str());
|
||||||
|
if (src > k) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
classDefinition[k].timeQualifications.back().push_back(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
classDefinition.clear();
|
||||||
|
|
||||||
|
initgmap(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QualificationFinal::encode(wstring &output) const {
|
||||||
|
output.clear();
|
||||||
|
|
||||||
|
for (size_t k = 0; k < classDefinition.size(); k++) {
|
||||||
|
if (k > 0)
|
||||||
|
output.append(L"|");
|
||||||
|
|
||||||
|
auto &qm = classDefinition[k].qualificationMap;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < qm.size(); j++) {
|
||||||
|
if (j > 0)
|
||||||
|
output.append(L";");
|
||||||
|
|
||||||
|
size_t i = j;
|
||||||
|
while ((i + 1) < qm.size() && qm[i + 1].first == qm[i].first
|
||||||
|
&& qm[i + 1].second == qm[i].second+1) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
output.append(itow(qm[j].first) + L";");
|
||||||
|
if (i <= j + 1) {
|
||||||
|
output.append(itow(qm[j].second));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output.append(itow(qm[j].second) + L"-" + itow(qm[i].second));
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &tqm = classDefinition[k].timeQualifications;
|
||||||
|
for (auto &source : tqm) {
|
||||||
|
output.append(L"T");
|
||||||
|
for (size_t i = 0; i < source.size(); i++) {
|
||||||
|
if (i > 0)
|
||||||
|
output.append(L";");
|
||||||
|
output.append(itow(source[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int QualificationFinal::getNumStages(int stage) const {
|
||||||
|
if (stage == 0 || classDefinition[stage-1].qualificationMap.empty())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
set<int> races;
|
||||||
|
for (auto &qm : classDefinition[stage - 1].qualificationMap) {
|
||||||
|
if (qm.first == stage)
|
||||||
|
throw meosException("Invalid qualification scheme");
|
||||||
|
races.insert(qm.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
int def = 0;
|
||||||
|
for (int r : races)
|
||||||
|
def = max(def, 1 + getNumStages(r));
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QualificationFinal::initgmap(bool check) {
|
||||||
|
sourcePlaceToFinalOrder.clear();
|
||||||
|
|
||||||
|
for (int ix = 0; ix < (int)classDefinition.size(); ix++) {
|
||||||
|
auto &c = classDefinition[ix];
|
||||||
|
|
||||||
|
for (int k = 0; k < (int)c.qualificationMap.size(); k++) {
|
||||||
|
const pair<int, int> &sd = c.qualificationMap[k];
|
||||||
|
if (check && sourcePlaceToFinalOrder.count(sd))
|
||||||
|
throw meosException(L"Inconsistent qualification rule, X#" + c.name + + L"/" + itow(sd.first));
|
||||||
|
|
||||||
|
sourcePlaceToFinalOrder[sd] = make_pair(ix+1, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int QualificationFinal::getHeatFromClass(int finalClassId, int baseClassId) const {
|
||||||
|
if (baseClassId == baseId) {
|
||||||
|
int fci = (finalClassId - baseId) / maxClassId;
|
||||||
|
|
||||||
|
if (fci * maxClassId + baseClassId == finalClassId)
|
||||||
|
return fci;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
84
code/qualification_final.h
Normal file
84
code/qualification_final.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
MeOS - Orienteering Software
|
||||||
|
Copyright (C) 2009-2017 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
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Melin Software HB - software@melin.nu - www.melin.nu
|
||||||
|
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
|
||||||
|
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
|
class QualificationFinal {
|
||||||
|
private:
|
||||||
|
|
||||||
|
int maxClassId;
|
||||||
|
int baseId;
|
||||||
|
|
||||||
|
struct Class {
|
||||||
|
wstring name;
|
||||||
|
vector< pair<int, int> > qualificationMap;
|
||||||
|
vector< vector<int> > timeQualifications;
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<Class> classDefinition;
|
||||||
|
|
||||||
|
map<pair<int, int>, pair<int, int>> sourcePlaceToFinalOrder;
|
||||||
|
|
||||||
|
void initgmap(bool check);
|
||||||
|
|
||||||
|
// Recursive implementation
|
||||||
|
int getNumStages(int stage) const;
|
||||||
|
public:
|
||||||
|
|
||||||
|
QualificationFinal(int maxClassId, int baseId) : maxClassId(maxClassId), baseId(baseId) {}
|
||||||
|
|
||||||
|
int getNumClasses() const {
|
||||||
|
return classDefinition.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const wstring getInstanceName(int inst) {
|
||||||
|
return classDefinition.at(inst-1).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count number of stages
|
||||||
|
int getNumStages() const {
|
||||||
|
return getNumStages(classDefinition.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int getHeatFromClass(int finalClassId, int baseClassId) const;
|
||||||
|
|
||||||
|
void import(const wstring &file);
|
||||||
|
|
||||||
|
void init(const wstring &def);
|
||||||
|
void encode(wstring &output) const;
|
||||||
|
|
||||||
|
/** Retuns the final class and the order within that class. */
|
||||||
|
pair<int,int> getNextFinal(int instance, int orderPlace, int numSharedPlaceNext) const;
|
||||||
|
|
||||||
|
/** Returns true if all competitors are automatically qualified*/
|
||||||
|
bool noQualification(int instance) const;
|
||||||
|
|
||||||
|
/** Fills in the set of no-qualification classes*/
|
||||||
|
void getBaseClassInstances(set<int> &base) const;
|
||||||
|
};
|
||||||
@ -10,6 +10,8 @@
|
|||||||
#define IDI_SMALL 108
|
#define IDI_SMALL 108
|
||||||
#define IDC_MEOS 109
|
#define IDC_MEOS 109
|
||||||
#define IDR_MAINFRAME 128
|
#define IDR_MAINFRAME 128
|
||||||
|
#define IDB_ECO 131
|
||||||
|
#define IDR_HTML1 132
|
||||||
#define IDC_STATIC -1
|
#define IDC_STATIC -1
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
@ -17,7 +19,7 @@
|
|||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NO_MFC 1
|
#define _APS_NO_MFC 1
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 131
|
#define _APS_NEXT_RESOURCE_VALUE 133
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
#define _APS_NEXT_SYMED_VALUE 110
|
#define _APS_NEXT_SYMED_VALUE 110
|
||||||
|
|||||||
@ -31,11 +31,14 @@ Eksoppsv
|
|||||||
#include "infoserver.h"
|
#include "infoserver.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "oListInfo.h"
|
||||||
|
#include "TabList.h"
|
||||||
|
#include "generalresult.h"
|
||||||
|
|
||||||
using namespace restbed;
|
using namespace restbed;
|
||||||
|
|
||||||
vector< shared_ptr<RestServer> > RestServer::startedServers;
|
vector< shared_ptr<RestServer> > RestServer::startedServers;
|
||||||
|
|
||||||
|
|
||||||
shared_ptr<RestServer> RestServer::construct() {
|
shared_ptr<RestServer> RestServer::construct() {
|
||||||
shared_ptr<RestServer> obj(new RestServer());
|
shared_ptr<RestServer> obj(new RestServer());
|
||||||
startedServers.push_back(obj);
|
startedServers.push_back(obj);
|
||||||
@ -43,7 +46,13 @@ shared_ptr<RestServer> RestServer::construct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RestServer::remove(shared_ptr<RestServer> server) {
|
void RestServer::remove(shared_ptr<RestServer> server) {
|
||||||
// xxx std::remove(startedServers.begin(), startedServers.end(), server);
|
//std::remove(startedServers.begin(), startedServers.end(), server);
|
||||||
|
for (size_t k = 0; k < startedServers.size(); k++) {
|
||||||
|
if (startedServers[k] == server) {
|
||||||
|
startedServers.erase(startedServers.begin() + k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestServer::RestServer() : hasAnyRequest(false) {
|
RestServer::RestServer() : hasAnyRequest(false) {
|
||||||
@ -142,21 +151,18 @@ void RestServer::compute(oEvent &ref) {
|
|||||||
auto rq = getRequest();
|
auto rq = getRequest();
|
||||||
if (!rq)
|
if (!rq)
|
||||||
return;
|
return;
|
||||||
if (rq->parameters.empty()) {
|
|
||||||
rq->answer = "<html><head>"
|
try {
|
||||||
"<title>MeOS Information Service</title>"
|
computeInternal(ref, rq);
|
||||||
"</head>"
|
|
||||||
"<body>"
|
|
||||||
"<h2>MeOS</h2>"
|
|
||||||
"</body>"
|
|
||||||
"</html>";
|
|
||||||
}
|
}
|
||||||
else if (rq->parameters.count("get") > 0) {
|
catch (meosException &ex) {
|
||||||
string what = rq->parameters.find("get")->second;
|
rq->answer = "Error (MeOS): Error: " + ref.gdiBase().toUTF8(lang.tl(ex.wwhat()));
|
||||||
getData(ref, what, rq->parameters, rq->answer);
|
|
||||||
}
|
}
|
||||||
else {
|
catch (std::exception &ex) {
|
||||||
rq->answer = "Error (MeOS): Unknown request";
|
rq->answer = "Error (MeOS): General Error: " + string(ex.what());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
rq->answer = "Error (MeOS): Unknown internal error.";
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -166,39 +172,594 @@ void RestServer::compute(oEvent &ref) {
|
|||||||
waitForCompletion.notify_all();
|
waitForCompletion.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RestServer::computeInternal(oEvent &ref, shared_ptr<RestServer::EventRequest> &rq) {
|
||||||
|
if (rq->parameters.empty()) {
|
||||||
|
rq->answer = "<html><head>"
|
||||||
|
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset = UTF-8\">"
|
||||||
|
"<title>MeOS Information Service</title>"
|
||||||
|
"</head>"
|
||||||
|
"<body>"
|
||||||
|
"<h2>MeOS</h2><p>" + ref.gdiBase().toUTF8(lang.tl(getMeosFullVersion())) + "<p>"
|
||||||
|
"<ul>\n";
|
||||||
|
|
||||||
|
vector<oListParam> lists;
|
||||||
|
TabList::getPublicLists(ref, lists);
|
||||||
|
map<EStdListType, oListInfo> listMap;
|
||||||
|
ref.getListTypes(listMap, false);
|
||||||
|
for (auto &lp : lists) {
|
||||||
|
wstring n = lp.getName();
|
||||||
|
if (n.empty()) {
|
||||||
|
n = listMap[lp.listCode].getName();
|
||||||
|
}
|
||||||
|
lp.setName(n);
|
||||||
|
|
||||||
|
int keyCand = lp.listCode * 100;
|
||||||
|
bool done = false;
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
if (!listCache.count(keyCand + i)) {
|
||||||
|
keyCand += i;
|
||||||
|
listCache[keyCand].first = lp;
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(listCache[keyCand + i].first == lp) {
|
||||||
|
keyCand = keyCand + i;
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!done) {
|
||||||
|
listCache[keyCand].first = lp;
|
||||||
|
listCache[keyCand].second.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
rq->answer += "<li><a href=\"?html=1&type=" + itos(keyCand) + "\">" + ref.gdiBase().toUTF8(n) + "</a></li>\n";
|
||||||
|
}
|
||||||
|
// "<li><a href=\"?html=1&result=1\">Resultat</a></li>"
|
||||||
|
// "<li><a href=\"?html=1&startlist=1\">Startlista</a></li>"
|
||||||
|
rq->answer += "</ul>\n";
|
||||||
|
|
||||||
|
HINSTANCE hInst = GetModuleHandle(0);
|
||||||
|
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(132), RT_HTML);
|
||||||
|
HGLOBAL res = LoadResource(hInst, hRes);
|
||||||
|
char *html = (char *)LockResource(res);
|
||||||
|
int resSize = SizeofResource(hInst, hRes);
|
||||||
|
|
||||||
|
if (html) {
|
||||||
|
string htmlS;
|
||||||
|
while (*html != 0 && resSize > 0) {
|
||||||
|
if (*html == '*')
|
||||||
|
htmlS += "<";
|
||||||
|
else if (*html == '#')
|
||||||
|
htmlS += "&";
|
||||||
|
else
|
||||||
|
htmlS += *html;
|
||||||
|
++html;
|
||||||
|
resSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
rq->answer += htmlS;
|
||||||
|
}
|
||||||
|
|
||||||
|
rq->answer += "\n</body></html>\n";
|
||||||
|
}
|
||||||
|
else if (rq->parameters.count("get") > 0) {
|
||||||
|
string what = rq->parameters.find("get")->second;
|
||||||
|
getData(ref, what, rq->parameters, rq->answer);
|
||||||
|
}
|
||||||
|
else if (rq->parameters.count("html") > 0) {
|
||||||
|
string stype = rq->parameters.count("type") ? rq->parameters.find("type")->second : _EmptyString;
|
||||||
|
int type = atoi(stype.c_str());
|
||||||
|
auto res = listCache.find(type);
|
||||||
|
|
||||||
|
if (res != listCache.end()) {
|
||||||
|
gdioutput gdiPrint("print", ref.gdiBase().getScale(), ref.gdiBase().getCP());
|
||||||
|
gdiPrint.clearPage(false);
|
||||||
|
|
||||||
|
if (!res->second.second) {
|
||||||
|
res->second.second = make_shared<oListInfo>();
|
||||||
|
ref.generateListInfo(res->second.first, gdiPrint.getLineHeight(), *res->second.second);
|
||||||
|
}
|
||||||
|
ref.generateList(gdiPrint, true, *res->second.second, false);
|
||||||
|
wstring exportFile = getTempFile();
|
||||||
|
gdiPrint.writeHTML(exportFile, ref.getName(), 30);
|
||||||
|
ifstream fin(exportFile.c_str());
|
||||||
|
string rbf;
|
||||||
|
while (std::getline(fin, rbf)) {
|
||||||
|
rq->answer += rbf;
|
||||||
|
}
|
||||||
|
removeTempFile(exportFile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rq->answer = "Error (MeOS): Unknown list";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rq->answer = "Error (MeOS): Unknown request";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writePerson(const GeneralResult::GeneralResultInfo &res,
|
||||||
|
xmlbuffer &reslist,
|
||||||
|
bool includeTeam,
|
||||||
|
bool includeCourse,
|
||||||
|
vector< pair<string, wstring> > &rProp) {
|
||||||
|
int clsId = res.src->getClassId(true);
|
||||||
|
rProp.push_back(make_pair("cls", itow(clsId)));
|
||||||
|
if (includeCourse) {
|
||||||
|
pRunner pr = dynamic_cast<pRunner>(res.src);
|
||||||
|
if (pr && pr->getCourse(false))
|
||||||
|
rProp.push_back(make_pair("course", itow(pr->getCourse(false)->getId())));
|
||||||
|
}
|
||||||
|
bool hasTeam = res.src->getTeam() != 0 &&
|
||||||
|
clsId == res.src->getClassId(false) && // No Qualification/Final
|
||||||
|
(clsId == 0 || res.src->getClassRef(false)->getQualificationFinal() == 0); // // No Qualification/Final
|
||||||
|
|
||||||
|
if (includeTeam && hasTeam)
|
||||||
|
rProp.push_back(make_pair("team", itow(res.src->getTeam()->getId())));
|
||||||
|
|
||||||
|
if (hasTeam)
|
||||||
|
rProp.push_back(make_pair("leg", itow(1+pRunner(res.src)->getLegNumber())));
|
||||||
|
|
||||||
|
rProp.push_back(make_pair("stat", itow(res.status)));
|
||||||
|
|
||||||
|
if (res.score > 0)
|
||||||
|
rProp.push_back(make_pair("score", itow(res.score)));
|
||||||
|
|
||||||
|
rProp.push_back(make_pair("st", itow(10 * (res.src->getStartTime() + res.src->getEvent()->getZeroTimeNum()))));
|
||||||
|
|
||||||
|
if (res.src->getClassRef(false) == 0 || !res.src->getClassRef(true)->getNoTiming()) {
|
||||||
|
if (res.time > 0)
|
||||||
|
rProp.push_back(make_pair("rt", itow(10 * res.time)));
|
||||||
|
if (res.place > 0)
|
||||||
|
rProp.push_back(make_pair("place", itow(res.place)));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &subTag = reslist.startTag("person", rProp);
|
||||||
|
rProp.clear();
|
||||||
|
rProp.push_back(make_pair("id", itow(res.src->getId())));
|
||||||
|
subTag.write("name", rProp, res.src->getName());
|
||||||
|
rProp.clear();
|
||||||
|
|
||||||
|
if (res.src->getClubRef()) {
|
||||||
|
rProp.push_back(make_pair("id", itow(res.src->getClubId())));
|
||||||
|
subTag.write("org", rProp, res.src->getClub());
|
||||||
|
rProp.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
subTag.endTag();
|
||||||
|
}
|
||||||
|
|
||||||
void RestServer::getData(oEvent &oe, const string &what, const multimap<string, string> ¶m, string &answer) {
|
void RestServer::getData(oEvent &oe, const string &what, const multimap<string, string> ¶m, string &answer) {
|
||||||
xmlbuffer out;
|
xmlbuffer out;
|
||||||
out.setComplete(true);
|
out.setComplete(true);
|
||||||
|
bool okRequest = false;
|
||||||
|
if (what == "iofresult") {
|
||||||
|
wstring exportFile = getTempFile();
|
||||||
|
bool useUTC = false;
|
||||||
|
set<int> cls;
|
||||||
|
if (param.count("class") > 0)
|
||||||
|
getSelection(param.find("class")->second, cls);
|
||||||
|
|
||||||
if (what == "competition") {
|
oe.exportIOFSplits(oEvent::IOF30, exportFile.c_str(), false, useUTC, cls, -1, false, false, true, false);
|
||||||
|
ifstream fin(exportFile.c_str());
|
||||||
|
string rbf;
|
||||||
|
while (std::getline(fin, rbf)) {
|
||||||
|
answer += rbf;
|
||||||
|
}
|
||||||
|
removeTempFile(exportFile);
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "iofstart") {
|
||||||
|
wstring exportFile = getTempFile();
|
||||||
|
bool useUTC = false;
|
||||||
|
set<int> cls;
|
||||||
|
if (param.count("class") > 0)
|
||||||
|
getSelection(param.find("class")->second, cls);
|
||||||
|
|
||||||
|
oe.exportIOFStartlist(oEvent::IOF30, exportFile.c_str(), useUTC, cls, false, true, false);
|
||||||
|
ifstream fin(exportFile.c_str());
|
||||||
|
string rbf;
|
||||||
|
while (std::getline(fin, rbf)) {
|
||||||
|
answer += rbf;
|
||||||
|
}
|
||||||
|
removeTempFile(exportFile);
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "competition") {
|
||||||
InfoCompetition cmp(0);
|
InfoCompetition cmp(0);
|
||||||
cmp.synchronize(oe);
|
cmp.synchronize(oe);
|
||||||
cmp.serialize(out, false);
|
cmp.serialize(out, false);
|
||||||
|
okRequest = true;
|
||||||
}
|
}
|
||||||
else if (what == "class") {
|
else if (what == "class") {
|
||||||
vector<pClass> cls;
|
vector<pClass> cls;
|
||||||
oe.getClasses(cls, true);
|
oe.getClasses(cls, true);
|
||||||
|
set<int> ctrlW;
|
||||||
|
vector<pControl> ctrl;
|
||||||
|
oe.getControls(ctrl, true);
|
||||||
|
for (size_t k = 0; k < ctrl.size(); k++) {
|
||||||
|
if (ctrl[k]->isValidRadio()) {
|
||||||
|
vector<int> cc;
|
||||||
|
ctrl[k]->getCourseControls(cc);
|
||||||
|
ctrlW.insert(cc.begin(), cc.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
for (auto c : cls) {
|
for (auto c : cls) {
|
||||||
InfoClass iCls(c->getId());
|
InfoClass iCls(c->getId());
|
||||||
set<int> ctrl;
|
iCls.synchronize(*c, ctrlW);
|
||||||
iCls.synchronize(*c, ctrl);
|
|
||||||
iCls.serialize(out, false);
|
iCls.serialize(out, false);
|
||||||
}
|
}
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "organization") {
|
||||||
|
vector<pClub> clb;
|
||||||
|
oe.getClubs(clb, true);
|
||||||
|
for (auto c : clb) {
|
||||||
|
InfoOrganization iClb(c->getId());
|
||||||
|
iClb.synchronize(*c);
|
||||||
|
iClb.serialize(out, false);
|
||||||
|
}
|
||||||
|
okRequest = true;
|
||||||
}
|
}
|
||||||
else if (what == "competitor") {
|
else if (what == "competitor") {
|
||||||
vector<pRunner> r;
|
vector<pRunner> r;
|
||||||
set<int> selection;
|
set<int> selection;
|
||||||
if (param.count("id") > 0)
|
if (param.count("class") > 0)
|
||||||
getSelection(param.find("id")->second, selection);
|
getSelection(param.find("class")->second, selection);
|
||||||
|
|
||||||
oe.getRunners(selection.size() == 1 ? *selection.begin() : 0, -1, r, true);
|
oe.getRunners(selection.size() == 1 ? *selection.begin() : 0, -1, r, true);
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<pRunner> r2;
|
||||||
|
r2.reserve(r.size());
|
||||||
|
for (pRunner tr : r) {
|
||||||
|
pClass cls = tr->getClassRef(true);
|
||||||
|
if (cls && cls->getQualificationFinal() && tr->getLegNumber() != 0)
|
||||||
|
continue;
|
||||||
|
if (selection.empty() || (cls && selection.count(cls->getId())))
|
||||||
|
r2.push_back(tr);
|
||||||
|
}
|
||||||
|
r.swap(r2);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto c : r) {
|
for (auto c : r) {
|
||||||
InfoCompetitor iR(c->getId());
|
InfoCompetitor iR(c->getId());
|
||||||
iR.synchronize(false, *c);
|
iR.synchronize(false, *c);
|
||||||
iR.serialize(out, false);
|
iR.serialize(out, false);
|
||||||
}
|
}
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "team") {
|
||||||
|
vector<pTeam> teams;
|
||||||
|
set<int> selection;
|
||||||
|
if (param.count("class") > 0)
|
||||||
|
getSelection(param.find("class")->second, selection);
|
||||||
|
|
||||||
|
oe.getTeams(selection.size() == 1 ? *selection.begin() : 0, teams, true);
|
||||||
|
|
||||||
|
if (selection.size() > 1) {
|
||||||
|
vector<pTeam> r2;
|
||||||
|
r2.reserve(teams.size());
|
||||||
|
for (pTeam tr : teams) {
|
||||||
|
if (selection.count(tr->getClassId(false)))
|
||||||
|
r2.push_back(tr);
|
||||||
|
}
|
||||||
|
teams.swap(r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto c : teams) {
|
||||||
|
InfoTeam iT(c->getId());
|
||||||
|
iT.synchronize(*c);
|
||||||
|
iT.serialize(out, false);
|
||||||
|
}
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "control") {
|
||||||
|
vector<pControl> ctrl;
|
||||||
|
oe.getControls(ctrl, true);
|
||||||
|
vector< pair<string, wstring> > prop(1);
|
||||||
|
prop[0].first = "id";
|
||||||
|
for (pControl c : ctrl) {
|
||||||
|
int nd = c->getNumberDuplicates();
|
||||||
|
for (int k = 0; k < nd; k++) {
|
||||||
|
prop[0].second = itow(oControl::getCourseControlIdFromIdIndex(c->getId(), k));
|
||||||
|
if (nd > 1)
|
||||||
|
out.write("control", prop, c->getName() + L"-" + itow(k+1));
|
||||||
|
else
|
||||||
|
out.write("control", prop, c->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
okRequest = true;
|
||||||
|
}
|
||||||
|
else if (what == "result") {
|
||||||
|
okRequest = true;
|
||||||
|
vector<pRunner> r;
|
||||||
|
set<int> selection;
|
||||||
|
pClass sampleClass = 0;
|
||||||
|
if (param.count("class") > 0) {
|
||||||
|
getSelection(param.find("class")->second, selection);
|
||||||
|
if (!selection.empty())
|
||||||
|
sampleClass = oe.getClass(*selection.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampleClass == 0) {
|
||||||
|
vector<pClass> tt;
|
||||||
|
oe.getClasses(tt, false);
|
||||||
|
if (!tt.empty())
|
||||||
|
sampleClass = tt[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
string resTag;
|
||||||
|
if (param.count("module") > 0)
|
||||||
|
resTag = param.find("module")->second;
|
||||||
|
|
||||||
|
pair<int,int> controlId(oPunch::PunchStart, oPunch::PunchFinish);
|
||||||
|
bool totalResult = false;
|
||||||
|
if (param.count("total")) {
|
||||||
|
const string &tot = param.find("total")->second;
|
||||||
|
totalResult = atoi(tot.c_str()) > 0 || _stricmp(tot.c_str(), "true") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.count("to")) {
|
||||||
|
const string &cid = param.find("to")->second;
|
||||||
|
|
||||||
|
controlId.second = atoi(cid.c_str());
|
||||||
|
if (controlId.second == 0)
|
||||||
|
controlId.second = oControl::getControlIdByName(oe, cid);
|
||||||
|
|
||||||
|
if (controlId.second == 0)
|
||||||
|
throw meosException("Unknown control: " + cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.count("from")) {
|
||||||
|
const string &cid = param.find("from")->second;
|
||||||
|
|
||||||
|
controlId.first = atoi(cid.c_str());
|
||||||
|
if (controlId.first == 0)
|
||||||
|
controlId.first = oControl::getControlIdByName(oe, cid);
|
||||||
|
|
||||||
|
if (controlId.first == 0)
|
||||||
|
throw meosException("Unknown control: " + cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
oListInfo::ResultType resType = oListInfo::Classwise;
|
||||||
|
wstring resTypeStr = L"classindividual";
|
||||||
|
|
||||||
|
ClassType ct = sampleClass ? sampleClass->getClassType() : ClassType::oClassIndividual;
|
||||||
|
bool team = ct == oClassPatrol || ct == oClassRelay;
|
||||||
|
int limit = 100000;
|
||||||
|
if (param.count("limit")) {
|
||||||
|
limit = atoi(param.find("limit")->second.c_str());
|
||||||
|
if (limit <= 0)
|
||||||
|
throw meosException("Invalid limit: " + param.find("limit")->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.count("type")) {
|
||||||
|
string type = param.find("type")->second;
|
||||||
|
|
||||||
|
if (type == "GlobalIndividual") {
|
||||||
|
resType = oListInfo::Global;
|
||||||
|
team = false;
|
||||||
|
}
|
||||||
|
else if (type == "ClassIndividual") {
|
||||||
|
resType = oListInfo::Classwise;
|
||||||
|
team = false;
|
||||||
|
}
|
||||||
|
else if (type == "CourseIndividual") {
|
||||||
|
resType = oListInfo::Coursewise;
|
||||||
|
team = false;
|
||||||
|
}
|
||||||
|
else if (type == "LegIndividual") {
|
||||||
|
resType = oListInfo::Legwise;
|
||||||
|
team = false;
|
||||||
|
}
|
||||||
|
else if (type == "GlobalTeam") {
|
||||||
|
resType = oListInfo::Global;
|
||||||
|
team = true;
|
||||||
|
}
|
||||||
|
else if (type == "ClassTeam") {
|
||||||
|
resType = oListInfo::Classwise;
|
||||||
|
team = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw meosException("Unknown type: " + type);
|
||||||
|
|
||||||
|
string2Wide(type, resTypeStr);
|
||||||
|
resTypeStr = canonizeName(resTypeStr.c_str());
|
||||||
|
}
|
||||||
|
else if (team) {
|
||||||
|
resTypeStr = L"classteam";
|
||||||
|
}
|
||||||
|
|
||||||
|
int inputNumber = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (param.count("argument")) {
|
||||||
|
const string &arg = param.find("argument")->second;
|
||||||
|
inputNumber = atoi(arg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<GeneralResult::GeneralResultInfo> results;
|
||||||
|
vector< pair<string, wstring> > prop, noProp, rProp;
|
||||||
|
|
||||||
|
prop.push_back(make_pair("type", resTypeStr));
|
||||||
|
|
||||||
|
int leg = -1;
|
||||||
|
if (param.count("leg") > 0) {
|
||||||
|
string legs = param.find("leg")->second;
|
||||||
|
leg = atoi(legs.c_str())-1;
|
||||||
|
if (leg < 0 || leg > 32)
|
||||||
|
throw meosException("Invalid leg: " + legs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ct == oClassRelay) {
|
||||||
|
if (leg == -1)
|
||||||
|
prop.push_back(make_pair("leg", L"Last"));
|
||||||
|
else
|
||||||
|
prop.push_back(make_pair("leg", itow(leg + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resTag.empty())
|
||||||
|
prop.push_back(make_pair("module", oe.gdiBase().widen(resTag) + L"(" + itow(inputNumber) + L")"));
|
||||||
|
|
||||||
|
if (controlId.first != oPunch::PunchStart) {
|
||||||
|
pair<int, int> idIx = oControl::getIdIndexFromCourseControlId(controlId.first);
|
||||||
|
pControl ctrl = oe.getControl(idIx.first);
|
||||||
|
if (ctrl == 0)
|
||||||
|
throw meosException("Unknown control: " + itos(idIx.first));
|
||||||
|
|
||||||
|
wstring loc = ctrl->getName();
|
||||||
|
if (idIx.second > 0)
|
||||||
|
loc += L"-" + itow(idIx.second + 1);
|
||||||
|
|
||||||
|
prop.push_back(make_pair("from", loc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controlId.second == oPunch::PunchFinish)
|
||||||
|
prop.push_back(make_pair("to", L"Finish"));
|
||||||
|
else {
|
||||||
|
pair<int, int> idIx = oControl::getIdIndexFromCourseControlId(controlId.second);
|
||||||
|
pControl ctrl = oe.getControl(idIx.first);
|
||||||
|
if (ctrl == 0)
|
||||||
|
throw meosException("Unknown control: " + itos(idIx.first));
|
||||||
|
|
||||||
|
wstring loc = ctrl->getName();
|
||||||
|
if (idIx.second > 0)
|
||||||
|
loc += L"-" + itow(idIx.second+1);
|
||||||
|
|
||||||
|
prop.push_back(make_pair("to", loc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!team) {
|
||||||
|
oe.getRunners(selection.size() == 1 ? *selection.begin() : 0, -1, r, false);
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<pRunner> r2;
|
||||||
|
r2.reserve(r.size());
|
||||||
|
for (pRunner tr : r) {
|
||||||
|
pClass cls = tr->getClassRef(true);
|
||||||
|
if (cls && cls->getQualificationFinal() && tr->getLegNumber() != 0)
|
||||||
|
continue;
|
||||||
|
if (selection.empty() || (cls && selection.count(cls->getId())))
|
||||||
|
r2.push_back(tr);
|
||||||
|
}
|
||||||
|
r.swap(r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneralResult::calculateIndividualResults(r, controlId, totalResult, resTag, resType, inputNumber, oe, results);
|
||||||
|
|
||||||
|
if (resType == oListInfo::Classwise)
|
||||||
|
sort(results.begin(), results.end());
|
||||||
|
/*else if (resType == oListInfo::Coursewise) {
|
||||||
|
sort(results.begin(), results.end(),
|
||||||
|
[](const GeneralResult::GeneralResultInfo &a, const GeneralResult::GeneralResultInfo &b)->
|
||||||
|
bool {
|
||||||
|
pCourse ac = dynamic_cast<const oRunner &>(*a.src).getCourse(false);
|
||||||
|
pCourse bc = dynamic_cast<const oRunner &>(*b.src).getCourse(false);
|
||||||
|
if (ac != bc)
|
||||||
|
return ac->getId() < bc->getId();
|
||||||
|
|
||||||
|
return a.compareResult(b);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
auto &reslist = out.startTag("results", prop);
|
||||||
|
|
||||||
|
int place = -1;
|
||||||
|
int cClass = -1;
|
||||||
|
int counter = 0;
|
||||||
|
for (const auto &res : results) {
|
||||||
|
if (res.src->getClassId(true) != cClass) {
|
||||||
|
counter = 0;
|
||||||
|
place = 1;
|
||||||
|
cClass = res.src->getClassId(true);
|
||||||
|
}
|
||||||
|
if (++counter > limit && (place != res.place || res.status != StatusOK))
|
||||||
|
continue;
|
||||||
|
place = res.place;
|
||||||
|
writePerson(res, reslist, true, resType == oListInfo::Coursewise, rProp);
|
||||||
|
}
|
||||||
|
reslist.endTag();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Teams
|
||||||
|
vector<pTeam> teams;
|
||||||
|
oe.getTeams(selection.size() == 1 ? *selection.begin() : 0, teams, true);
|
||||||
|
|
||||||
|
if (selection.size() > 1) {
|
||||||
|
vector<pTeam> r2;
|
||||||
|
r2.reserve(teams.size());
|
||||||
|
for (pTeam tr : teams) {
|
||||||
|
if (selection.count(tr->getClassId(true)))
|
||||||
|
r2.push_back(tr);
|
||||||
|
}
|
||||||
|
teams.swap(r2);
|
||||||
|
}
|
||||||
|
auto context = GeneralResult::calculateTeamResults(teams, leg, controlId, totalResult, resTag, resType, inputNumber, oe, results);
|
||||||
|
|
||||||
|
sort(results.begin(), results.end());
|
||||||
|
auto &reslist = out.startTag("results", prop);
|
||||||
|
|
||||||
|
int place = -1;
|
||||||
|
int cClass = -1;
|
||||||
|
int counter = 0;
|
||||||
|
for (const auto &res : results) {
|
||||||
|
pTeam team = pTeam(res.src);
|
||||||
|
if (leg >= team->getNumRunners())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (res.src->getClassId(true) != cClass) {
|
||||||
|
counter = 0;
|
||||||
|
place = 1;
|
||||||
|
cClass = res.src->getClassId(true);
|
||||||
|
}
|
||||||
|
if (++counter > limit && (place != res.place || res.status != StatusOK))
|
||||||
|
continue;
|
||||||
|
place = res.place;
|
||||||
|
|
||||||
|
rProp.push_back(make_pair("cls", itow(res.src->getClassId(true))));
|
||||||
|
rProp.push_back(make_pair("stat", itow(res.status)));
|
||||||
|
if (res.score > 0)
|
||||||
|
rProp.push_back(make_pair("score", itow(res.score)));
|
||||||
|
|
||||||
|
if (res.src->getStartTime() > 0)
|
||||||
|
rProp.push_back(make_pair("st", itow(10 * (res.src->getStartTime() + oe.getZeroTimeNum()))));
|
||||||
|
|
||||||
|
if (res.src->getClassRef(false) == 0 || !res.src->getClassRef(true)->getNoTiming()) {
|
||||||
|
if (res.time > 0)
|
||||||
|
rProp.push_back(make_pair("rt", itow(10 * res.time)));
|
||||||
|
if (res.place > 0)
|
||||||
|
rProp.push_back(make_pair("place", itow(res.place)));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &subTag = reslist.startTag("team", rProp);
|
||||||
|
rProp.clear();
|
||||||
|
rProp.push_back(make_pair("id", itow(res.src->getId())));
|
||||||
|
subTag.write("name", rProp, res.src->getName());
|
||||||
|
rProp.clear();
|
||||||
|
|
||||||
|
if (res.src->getClubRef()) {
|
||||||
|
rProp.push_back(make_pair("id", itow(res.src->getClubId())));
|
||||||
|
subTag.write("org", rProp, res.src->getClub());
|
||||||
|
rProp.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int subRes = res.getNumSubresult(*context);
|
||||||
|
GeneralResult::GeneralResultInfo out;
|
||||||
|
|
||||||
|
for (int k = 0; k < subRes; k++) {
|
||||||
|
if (res.getSubResult(*context, k, out)) {
|
||||||
|
writePerson(out, subTag, false, false, rProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subTag.endTag();
|
||||||
|
}
|
||||||
|
reslist.endTag();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (out.size() > 0) {
|
if (out.size() > 0) {
|
||||||
xmlparser mem;
|
xmlparser mem;
|
||||||
@ -208,7 +769,7 @@ void RestServer::getData(oEvent &oe, const string &what, const multimap<string,
|
|||||||
mem.endTag();
|
mem.endTag();
|
||||||
mem.getMemoryOutput(answer);
|
mem.getMemoryOutput(answer);
|
||||||
}
|
}
|
||||||
else {
|
else if (!okRequest) {
|
||||||
answer = "Error (MeOS): Unknown command '" + what + "'";
|
answer = "Error (MeOS): Unknown command '" + what + "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,6 +75,11 @@ private:
|
|||||||
|
|
||||||
RestServer(const RestServer &);
|
RestServer(const RestServer &);
|
||||||
RestServer & operator=(const RestServer &) const;
|
RestServer & operator=(const RestServer &) const;
|
||||||
|
|
||||||
|
|
||||||
|
void computeInternal(oEvent &ref, shared_ptr<RestServer::EventRequest> &rq);
|
||||||
|
|
||||||
|
map<int, pair<oListParam, shared_ptr<oListInfo> > > listCache;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
~RestServer();
|
~RestServer();
|
||||||
|
|||||||
@ -194,7 +194,7 @@ void SpeakerMonitor::renderResult(gdioutput &gdi,
|
|||||||
|
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
if (showClass) {
|
if (showClass) {
|
||||||
pClass pc = res.r->getClassRef();
|
pClass pc = res.r->getClassRef(true);
|
||||||
if (pc) {
|
if (pc) {
|
||||||
gdi.addStringUT(yp, xp + timeWidth, fontMediumPlus, pc->getName());
|
gdi.addStringUT(yp, xp + timeWidth, fontMediumPlus, pc->getName());
|
||||||
dx = classWidth;
|
dx = classWidth;
|
||||||
@ -243,7 +243,7 @@ void SpeakerMonitor::renderResult(gdioutput &gdi,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (showClass) {
|
if (showClass) {
|
||||||
pClass pc = res.r->getClassRef();
|
pClass pc = res.r->getClassRef(true);
|
||||||
if (pc)
|
if (pc)
|
||||||
msg += L" (" + pc->getName() + L") ";
|
msg += L" (" + pc->getName() + L") ";
|
||||||
else
|
else
|
||||||
@ -412,7 +412,7 @@ wstring getTimeDesc(int t1, int t2) {
|
|||||||
|
|
||||||
void SpeakerMonitor::getMessage(const oEvent::ResultEvent &res,
|
void SpeakerMonitor::getMessage(const oEvent::ResultEvent &res,
|
||||||
wstring &message, deque<wstring> &details) {
|
wstring &message, deque<wstring> &details) {
|
||||||
pClass cls = res.r->getClassRef();
|
pClass cls = res.r->getClassRef(true);
|
||||||
if (!cls)
|
if (!cls)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -605,10 +605,10 @@ void SpeakerMonitor::getMessage(const oEvent::ResultEvent &res,
|
|||||||
details.push_back(share);
|
details.push_back(share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changeover && res.r->getTeam() && res.r->getTeam()->getClassRef() != 0) {
|
if (changeover && res.r->getTeam() && res.r->getTeam()->getClassRef(true) != 0) {
|
||||||
wstring vxl = L"skickar ut X.#";
|
wstring vxl = L"skickar ut X.#";
|
||||||
pTeam t = res.r->getTeam();
|
pTeam t = res.r->getTeam();
|
||||||
pClass cls = t->getClassRef();
|
pClass cls = t->getClassRef(true);
|
||||||
bool second = false;
|
bool second = false;
|
||||||
int nextLeg = cls->getNextBaseLeg(res.r->getLegNumber());
|
int nextLeg = cls->getNextBaseLeg(res.r->getLegNumber());
|
||||||
if (nextLeg > 0) {
|
if (nextLeg > 0) {
|
||||||
|
|||||||
@ -2279,3 +2279,19 @@ ask:updatetimes = Vill du behålla nuvarande starttider, om möjligt? Svara nej
|
|||||||
X har en tid (Y) som inte är kompatibel med förändringen = X har en tid (Y) som inte är kompatibel med förändringen
|
X har en tid (Y) som inte är kompatibel med förändringen = X har en tid (Y) som inte är kompatibel med förändringen
|
||||||
warn:latestarttime = Att använda starttider mer än X timmar efter nolltiden rekommenderas inte eftersom äldre SI brickor endast har en 12-timmarsklocka.\n\nVill du ändå använda starttiden?
|
warn:latestarttime = Att använda starttider mer än X timmar efter nolltiden rekommenderas inte eftersom äldre SI brickor endast har en 12-timmarsklocka.\n\nVill du ändå använda starttiden?
|
||||||
Anm. tid = Anm. tid
|
Anm. tid = Anm. tid
|
||||||
|
Ekonomihantering, X = Ekonomihantering, X
|
||||||
|
Manuellt gjorda justeringar = Manuellt gjorda justeringar
|
||||||
|
Antal förfrågningar: X = Antal förfrågningar: X
|
||||||
|
Genomsnittlig svarstid: X ms = Genomsnittlig svarstid: X ms
|
||||||
|
Informationsserver = Informationsserver
|
||||||
|
Längsta svarstid: X ms = Längsta svarstid: X ms
|
||||||
|
MeOS Informationsserver REST-API = MeOS Informationsserver REST-API
|
||||||
|
RestService = RestService
|
||||||
|
Server startad på port X = Server startad på port X
|
||||||
|
Testa servern = Testa servern
|
||||||
|
help:rest = MeOS REST API låter dig komma åt tävlingsdata via en webbanslutning. Du kan visa resultatlistor direkt i en webbläsare, men du kan också komma åt tävlingsdata och resultat i XML-format för vidare behandling andra program och appar.
|
||||||
|
Server startad på X = Server startad på X
|
||||||
|
Inconsistent qualification rule, X = Inkonsekvent kvalifikationsregel, X
|
||||||
|
help:LockStartList = MeOS uppdaterar inte löparna i en låst klass även om kvalificeringsresultaten ändras.
|
||||||
|
Kval-Final-Schema = Kval-Final-Schema
|
||||||
|
Lås startlista = Lås startlista
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user