MeOS version 3.7.1178 RC1
This commit is contained in:
parent
3dcdfa3b65
commit
338fb3c34e
@ -96,7 +96,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
||||
bool disablePermisson = true;
|
||||
gdi.popX();
|
||||
|
||||
gdi.addCheckbox("MapRoot", "Mappa rootadresssen (http:///localhost:port/) till funktion:", nullptr, !rootMap.empty()).setHandler(this);
|
||||
gdi.addCheckbox("MapRoot", "Mappa rootadressen (http:///localhost:port/) till funktion:", nullptr, !rootMap.empty()).setHandler(this);
|
||||
gdi.addInput("RootMap", gdi.recodeToWide(rootMap));
|
||||
gdi.setInputStatus("RootMap", !rootMap.empty());
|
||||
|
||||
|
||||
@ -48,8 +48,24 @@ RunnerDB::RunnerDB(oEvent *oe_): oe(oe_)
|
||||
loadedFromServer = false;
|
||||
dataDate = 20100201;
|
||||
dataTime = 222222;
|
||||
runnerTable = 0;
|
||||
clubTable = 0;
|
||||
}
|
||||
|
||||
RunnerDB::RunnerDB(const RunnerDB &in) : oe(in.oe) {
|
||||
loadedFromServer = false;
|
||||
dataDate = in.dataDate;
|
||||
dataTime = in.dataTime;
|
||||
|
||||
rdb = in.rdb;
|
||||
rwdb = in.rwdb;
|
||||
for (size_t k = 0; k < rwdb.size(); k++)
|
||||
rwdb[k].init(this, k);
|
||||
|
||||
rhash = in.rhash;
|
||||
|
||||
cdb = in.cdb;
|
||||
oRDB = in.oRDB;
|
||||
chash = in.chash;
|
||||
freeCIx = in.freeCIx;
|
||||
}
|
||||
|
||||
RunnerDB::~RunnerDB(void)
|
||||
@ -57,6 +73,15 @@ RunnerDB::~RunnerDB(void)
|
||||
releaseTables();
|
||||
}
|
||||
|
||||
bool RunnerDB::operator!=(const RunnerDB &in) const {
|
||||
return dataDate != in.dataDate ||
|
||||
dataTime != in.dataTime ||
|
||||
freeCIx != in.freeCIx ||
|
||||
rdb.size() != in.rdb.size() ||
|
||||
cdb.size() != in.cdb.size() ||
|
||||
(!rdb.empty() && !(rdb.back() == in.rdb.back()));
|
||||
}
|
||||
|
||||
RunnerDBEntry::RunnerDBEntry()
|
||||
{
|
||||
memset(this, 0, sizeof(RunnerDBEntry));
|
||||
@ -268,8 +293,8 @@ RunnerWDBEntry *RunnerDB::addRunner(const wchar_t *name,
|
||||
int club, int card)
|
||||
{
|
||||
assert(rdb.size() == rwdb.size());
|
||||
rdb.push_back(RunnerDBEntry());
|
||||
rwdb.push_back(RunnerWDBEntry());
|
||||
rdb.emplace_back();
|
||||
rwdb.emplace_back();
|
||||
rwdb.back().init(this, rdb.size()-1);
|
||||
|
||||
RunnerWDBEntry &e=rwdb.back();
|
||||
@ -290,7 +315,7 @@ RunnerWDBEntry *RunnerDB::addRunner(const wchar_t *name,
|
||||
if (!idhash.empty())
|
||||
idhash[extId] = rdb.size()-1;
|
||||
if (!nhash.empty())
|
||||
nhash.insert(pair<wstring, int>(canonizeName(e.name), rdb.size()-1));
|
||||
nhash.emplace(canonizeName(e.name), rdb.size()-1);
|
||||
}
|
||||
return &e;
|
||||
}
|
||||
@ -301,8 +326,8 @@ RunnerWDBEntry *RunnerDB::addRunner(const char *nameUTF,
|
||||
int club, int card)
|
||||
{
|
||||
assert(rdb.size() == rwdb.size());
|
||||
rdb.push_back(RunnerDBEntry());
|
||||
rwdb.push_back(RunnerWDBEntry());
|
||||
rdb.emplace_back();
|
||||
rwdb.emplace_back();
|
||||
rwdb.back().init(this, rdb.size()-1);
|
||||
|
||||
RunnerWDBEntry &e=rwdb.back();
|
||||
@ -325,7 +350,7 @@ RunnerWDBEntry *RunnerDB::addRunner(const char *nameUTF,
|
||||
if (!nhash.empty()) {
|
||||
wstring wn;
|
||||
e.getName(wn);
|
||||
nhash.insert(pair<wstring, int>(canonizeName(wn.c_str()), rdb.size()-1));
|
||||
nhash.emplace(canonizeName(wn.c_str()), rdb.size()-1);
|
||||
}
|
||||
}
|
||||
return &e;
|
||||
@ -406,7 +431,7 @@ void RunnerDB::importClub(oClub &club, bool matchName)
|
||||
else {
|
||||
// Completely new club
|
||||
chash [club.getId()] = cdb.size();
|
||||
cdb.push_back(oDBClubEntry(club, cdb.size(), this));
|
||||
cdb.emplace_back(club, cdb.size(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1139,17 +1164,41 @@ void RunnerDB::fillClubs(vector< pair<wstring, size_t> > &out) const {
|
||||
out.reserve(cdb.size());
|
||||
for (size_t k = 0; k<cdb.size(); k++) {
|
||||
if (!cdb[k].isRemoved()) {
|
||||
out.push_back(make_pair(cdb[k].getName(), cdb[k].getId()));
|
||||
out.emplace_back(cdb[k].getName(), cdb[k].getId());
|
||||
}
|
||||
}
|
||||
sort(out.begin(), out.end());
|
||||
}
|
||||
|
||||
oDBRunnerEntry::oDBRunnerEntry(oEvent *oe) : oBase(oe) {
|
||||
db = 0;
|
||||
db = nullptr;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
oDBRunnerEntry::oDBRunnerEntry(oDBRunnerEntry &&in) : oBase(std::move(in)) {
|
||||
db = in.db;
|
||||
index = in.index;
|
||||
}
|
||||
|
||||
oDBRunnerEntry::oDBRunnerEntry(const oDBRunnerEntry &in) : oBase(in) {
|
||||
db = in.db;
|
||||
index = in.index;
|
||||
}
|
||||
|
||||
const oDBRunnerEntry &oDBRunnerEntry::operator=(const oDBRunnerEntry &in) {
|
||||
oBase::operator=(in);
|
||||
db = in.db;
|
||||
index = in.index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const oDBRunnerEntry &oDBRunnerEntry::operator=(oDBRunnerEntry &&in) {
|
||||
oBase::operator=(std::move(in));
|
||||
db = in.db;
|
||||
index = in.index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
oDBRunnerEntry::~oDBRunnerEntry() {}
|
||||
|
||||
void RunnerDB::generateRunnerTableData(Table &table, oDBRunnerEntry *addEntry)
|
||||
@ -1210,7 +1259,7 @@ const shared_ptr<Table> &RunnerDB::getRunnerTB() {
|
||||
table->addColumn("Nationalitet", 70, false, true);
|
||||
table->addColumn("Kön", 50, false, true);
|
||||
table->addColumn("Födelseår", 70, true, true);
|
||||
table->addColumn("Anmäl", 70, false, true);
|
||||
table->addColumn("Anmäl", 120, false, true);
|
||||
|
||||
table->setTableProp(Table::CAN_INSERT|Table::CAN_DELETE|Table::CAN_PASTE);
|
||||
table->setClearOnHide(false);
|
||||
@ -1224,6 +1273,25 @@ const shared_ptr<Table> &RunnerDB::getRunnerTB() {
|
||||
|
||||
if (runnerTable->getNumDataRows() != nr)
|
||||
runnerTable->update();
|
||||
else {
|
||||
/*vector<pRunner> runners;
|
||||
setupIdHash();
|
||||
oe->getRunners(0, 0, runners, false);
|
||||
for (pRunner r : runners) {
|
||||
int64_t extId = r->getExtIdentifier();
|
||||
if (extId != 0) {
|
||||
int value;
|
||||
if (idhash.lookup(extId, value)) {
|
||||
try {
|
||||
runnerTable->reloadRow(value + 1);
|
||||
}
|
||||
catch (const std::exception &) {
|
||||
// Ignore any problems with the table.
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return runnerTable;
|
||||
}
|
||||
|
||||
@ -1259,15 +1327,15 @@ void RunnerDB::refreshRunnerTableData(Table &table) {
|
||||
if (row) {
|
||||
row->setObject(oRDB[k]);
|
||||
|
||||
oClass *val = 0;
|
||||
int runnerId;
|
||||
bool found = false;
|
||||
|
||||
if (rdb[k].extId != 0)
|
||||
found = runnerInEvent.lookup(rdb[k].extId, val);
|
||||
found = runnerInEvent.lookup(rdb[k].extId, runnerId);
|
||||
|
||||
|
||||
if (found && row->getCellType(cellEntryIndex) == cellAction) {
|
||||
row->updateCell(cellEntryIndex, cellEdit, val->getName());
|
||||
if (found) {
|
||||
pRunner r = oe->getRunner(runnerId, 0);
|
||||
row->updateCell(cellEntryIndex, cellEdit, r ? r->getClass(true) : L"");
|
||||
}
|
||||
else if (!found && row->getCellType(cellEntryIndex) == cellEdit) {
|
||||
row->updateCell(cellEntryIndex, cellAction, L"@+");
|
||||
@ -1343,11 +1411,11 @@ void oDBRunnerEntry::addTableRow(Table &table) const {
|
||||
table.set(row++, it, TID_SEX, sex, canEdit, cellEdit);
|
||||
table.set(row++, it, TID_YEAR, itow(rn.birthYear), canEdit, cellEdit);
|
||||
|
||||
oClass *val = 0;
|
||||
int runnerId;
|
||||
bool found = false;
|
||||
|
||||
if (rn.extId != 0)
|
||||
found = db->runnerInEvent.lookup(rn.extId, val);
|
||||
found = db->runnerInEvent.lookup(rn.extId, runnerId);
|
||||
|
||||
if (canEdit)
|
||||
table.setTableProp(Table::CAN_DELETE|Table::CAN_INSERT|Table::CAN_PASTE);
|
||||
@ -1357,8 +1425,10 @@ void oDBRunnerEntry::addTableRow(Table &table) const {
|
||||
RunnerDB::cellEntryIndex = row;
|
||||
if (!found)
|
||||
table.set(row++, it, TID_ENTER, L"@+", false, cellAction);
|
||||
else
|
||||
table.set(row++, it, TID_ENTER, val ? val->getName() : L"", false, cellEdit);
|
||||
else {
|
||||
pRunner r = oe->getRunner(runnerId, 0);
|
||||
table.set(row++, it, TID_ENTER, r ? r->getClass(true) : L"", false, cellEdit);
|
||||
}
|
||||
}
|
||||
|
||||
const RunnerDBEntry &oDBRunnerEntry::getRunner() const {
|
||||
@ -1427,7 +1497,7 @@ void oDBRunnerEntry::fillInput(int id, vector< pair<wstring, size_t> > &out, siz
|
||||
RunnerDBEntry &r = db->rdb[index];
|
||||
if (id==TID_CLUB) {
|
||||
db->fillClubs(out);
|
||||
out.push_back(make_pair(L"-", 0));
|
||||
out.emplace_back(L"-", 0);
|
||||
selected = r.clubNo;
|
||||
}
|
||||
}
|
||||
@ -1460,11 +1530,11 @@ bool oDBRunnerEntry::canRemove() const {
|
||||
}
|
||||
|
||||
oDBRunnerEntry *RunnerDB::addRunner() {
|
||||
rdb.push_back(RunnerDBEntry());
|
||||
rwdb.push_back(RunnerWDBEntry());
|
||||
rdb.emplace_back();
|
||||
rwdb.emplace_back();
|
||||
rwdb.back().init(this, rdb.size() -1);
|
||||
|
||||
oRDB.push_back(oDBRunnerEntry(oe));
|
||||
oRDB.emplace_back(oe);
|
||||
oRDB.back().init(this, rdb.size() - 1);
|
||||
|
||||
return &oRDB.back();
|
||||
@ -1475,7 +1545,7 @@ oClub *RunnerDB::addClub() {
|
||||
while (chash.count(freeCIx))
|
||||
freeCIx++;
|
||||
|
||||
cdb.push_back(oDBClubEntry(oe, freeCIx, cdb.size(), this));
|
||||
cdb.emplace_back(oe, freeCIx, cdb.size(), this);
|
||||
chash.insert(freeCIx, cdb.size()-1);
|
||||
cnhash.clear();
|
||||
|
||||
|
||||
@ -107,6 +107,10 @@ struct RunnerDBEntry {
|
||||
|
||||
bool isUTF() const { return (reserved & 2) == 2; }
|
||||
void setUTF() { reserved |= 2; }
|
||||
|
||||
bool operator==(const RunnerDBEntry &d) const {
|
||||
return memcmp(this, &d, sizeof(RunnerDBEntry)) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
class RunnerDB;
|
||||
@ -168,7 +172,7 @@ private:
|
||||
|
||||
bool check(const RunnerDBEntry &rde) const;
|
||||
|
||||
intkeymap<oClass *, __int64> runnerInEvent;
|
||||
intkeymap<int, __int64> runnerInEvent;
|
||||
|
||||
/** Init name hash lazy */
|
||||
void setupNameHash() const;
|
||||
@ -345,6 +349,9 @@ public:
|
||||
|
||||
void getAllNames(vector<wstring> &givenName, vector<wstring> &familyName);
|
||||
RunnerDB(oEvent *);
|
||||
RunnerDB(const RunnerDB &in);
|
||||
bool operator!=(const RunnerDB &other) const;
|
||||
|
||||
~RunnerDB(void);
|
||||
friend class oDBRunnerEntry;
|
||||
friend class oDBClubEntry;
|
||||
@ -373,6 +380,12 @@ public:
|
||||
void fillInput(int id, vector< pair<wstring, size_t> > &out, size_t &selected) override;
|
||||
|
||||
oDBRunnerEntry(oEvent *oe);
|
||||
oDBRunnerEntry(oDBRunnerEntry &&in);
|
||||
oDBRunnerEntry(const oDBRunnerEntry &in);
|
||||
|
||||
const oDBRunnerEntry &operator=(oDBRunnerEntry &&in);
|
||||
const oDBRunnerEntry &operator=(const oDBRunnerEntry &in);
|
||||
|
||||
virtual ~oDBRunnerEntry();
|
||||
|
||||
void remove();
|
||||
|
||||
@ -366,7 +366,7 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
|
||||
else
|
||||
par.setLegNumberCoded(0);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), prm->listInfo);
|
||||
oe->generateListInfo(par, prm->listInfo);
|
||||
}
|
||||
}
|
||||
prm->po.onlyChanged = gdi.isChecked("OnlyChanged");
|
||||
|
||||
@ -913,7 +913,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
readClassSettings(gdi);
|
||||
oEvent::DrawMethod method = (oEvent::DrawMethod)gdi.getSelectedItem("Method").first;
|
||||
int pairSize = gdi.getSelectedItem("PairSize").first;
|
||||
|
||||
auto vp = readVacantPosition(gdi);
|
||||
bool drawCoursebased = drawInfo.coursesTogether;
|
||||
|
||||
int maxST = 0;
|
||||
@ -923,7 +923,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
const ClassInfo &ci=cInfo[k];
|
||||
|
||||
ClassDrawSpecification cds(ci.classId, 0, drawInfo.firstStart + drawInfo.baseInterval * ci.firstStart,
|
||||
drawInfo.baseInterval * ci.interval, ci.nVacant);
|
||||
drawInfo.baseInterval * ci.interval, ci.nVacant, vp);
|
||||
if (drawCoursebased) {
|
||||
pCourse pCrs = oe->getClass(ci.classId)->getCourse();
|
||||
int id = pCrs ? pCrs->getId() : 101010101 + ci.classId;
|
||||
@ -954,7 +954,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
for (size_t k=0; k<cInfo.size(); k++)
|
||||
par.selection.insert(cInfo[k].classId);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -1013,8 +1013,10 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
gdi.fillRight();
|
||||
gdi.addInput("FirstStart", oe->getAbsTime(3600), 10, 0, L"Första (ordinarie) start:");
|
||||
gdi.addInput("MinInterval", L"2:00", 10, 0, L"Minsta startintervall:");
|
||||
gdi.fillDown();
|
||||
gdi.addInput("Vacances", getDefaultVacant(), 10, 0, L"Andel vakanser:");
|
||||
gdi.fillDown();
|
||||
addVacantPosition(gdi);
|
||||
|
||||
gdi.popX();
|
||||
|
||||
createDrawMethod(gdi);
|
||||
@ -1134,7 +1136,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
oListInfo info;
|
||||
par.listCode = EStdStartList;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
gdi.dropLine();
|
||||
gdi.addButton("Cancel", "Återgå", ClassesCB);
|
||||
@ -1151,6 +1153,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
return 0;
|
||||
wstring minInterval = gdi.getText("MinInterval");
|
||||
wstring vacances = gdi.getText("Vacances");
|
||||
auto vp = readVacantPosition(gdi);
|
||||
setDefaultVacant(vacances);
|
||||
bool lateBefore = gdi.isChecked("LateBefore");
|
||||
bool allowNeighbourSameCourse = gdi.isChecked("AllowNeighbours");
|
||||
@ -1160,7 +1163,6 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
if (gdi.hasWidget("PairSize")) {
|
||||
pairSize = gdi.getSelectedItem("PairSize").first;
|
||||
}
|
||||
|
||||
oEvent::DrawMethod method = (oEvent::DrawMethod)gdi.getSelectedItem("Method").first;
|
||||
|
||||
int baseInterval = convertAbsoluteTimeMS(minInterval) / 2;
|
||||
@ -1174,7 +1176,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
throw meosException("Ogiltig första starttid. Måste vara efter nolltid.");
|
||||
|
||||
clearPage(gdi, true);
|
||||
oe->automaticDrawAll(gdi, firstStart, minInterval, vacances,
|
||||
oe->automaticDrawAll(gdi, firstStart, minInterval, vacances, vp,
|
||||
lateBefore, allowNeighbourSameCourse, method, pairSize);
|
||||
oe->addAutoBib();
|
||||
gdi.scrollToBottom();
|
||||
@ -1203,13 +1205,16 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
showClassSelection(gdi, bx, by, 0);
|
||||
|
||||
gdi.pushX();
|
||||
|
||||
gdi.fillRight();
|
||||
gdi.addInput("FirstStart", firstStart, 10, 0, L"Starttid:");
|
||||
gdi.addInput("Vacanses", lastNumVac, 10, 0, L"Antal vakanser:").setSynchData(&lastNumVac);
|
||||
|
||||
gdi.dropLine(4);
|
||||
gdi.popX();
|
||||
gdi.fillRight();
|
||||
gdi.addButton("AssignStart", "Tilldela", ClassesCB).isEdit(true);
|
||||
gdi.addButton("Cancel", "Avbryt", ClassesCB).setCancel();
|
||||
gdi.addButton("Cancel", "Återgå", ClassesCB).setCancel();
|
||||
gdi.addButton("EraseStartAll", "Radera starttider...", ClassesCB).isEdit(true).setExtra(1);
|
||||
|
||||
gdi.refresh();
|
||||
@ -1226,8 +1231,10 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
if (warnDrawStartTime(gdi, time))
|
||||
return 0;
|
||||
|
||||
int nVacant = gdi.getTextNo("Vacanses");
|
||||
|
||||
for (set<int>::iterator it = classes.begin(); it!=classes.end();++it) {
|
||||
simultaneous(*it, time);
|
||||
simultaneous(*it, time, nVacant);
|
||||
}
|
||||
|
||||
bi.id = "Simultaneous";
|
||||
@ -1412,7 +1419,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
for (set<int>::const_iterator it = classes.begin(); it != classes.end(); ++it) {
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(*it, 0, 0, 0, 0));
|
||||
spec.emplace_back(ClassDrawSpecification(*it, 0, 0, 0, 0, oEvent::VacantPosition::Mixed));
|
||||
oe->drawList(spec, oEvent::DrawMethod::Random, 1, oEvent::DrawType::DrawAll);
|
||||
}
|
||||
|
||||
@ -1487,15 +1494,14 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
if (warnDrawStartTime(gdi, t, false))
|
||||
return 0;
|
||||
}
|
||||
//bool pairwise = false;
|
||||
|
||||
// if (gdi.hasWidget("Pairwise"))
|
||||
// pairwise = gdi.isChecked("Pairwise");
|
||||
int pairSize = 1;
|
||||
if (gdi.hasWidget("PairSize")) {
|
||||
pairSize = gdi.getSelectedItem("PairSize").first;
|
||||
}
|
||||
|
||||
auto vp = readVacantPosition(gdi);
|
||||
|
||||
int maxTime = 0, restartTime = 0;
|
||||
double scaleFactor = 1.0;
|
||||
|
||||
@ -1510,7 +1516,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
if (method == oEvent::DrawMethod::Random || method == oEvent::DrawMethod::SOFT || method == oEvent::DrawMethod::MeOS) {
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(cid, leg, t, interval, vacanses));
|
||||
spec.emplace_back(cid, leg, t, interval, vacanses, vp);
|
||||
|
||||
oe->drawList(spec, method, pairSize, dtype);
|
||||
}
|
||||
@ -1523,7 +1529,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
scaleFactor);
|
||||
}
|
||||
else if (method == oEvent::DrawMethod::Simultaneous) {
|
||||
simultaneous(cid, time);
|
||||
simultaneous(cid, time, vacanses);
|
||||
}
|
||||
else if (method == oEvent::DrawMethod::Seeded) {
|
||||
ListBoxInfo seedMethod;
|
||||
@ -1572,7 +1578,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
oListInfo info;
|
||||
par.listCode = EStdStartList;
|
||||
par.setLegNumberCoded(leg);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
|
||||
gdi.refresh();
|
||||
@ -1596,7 +1602,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
leg = gdi.getSelectedItem("Leg").first;
|
||||
}
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(ClassId, leg, 0, 0, 0));
|
||||
spec.emplace_back(ClassId, leg, 0, 0, 0, oEvent::VacantPosition::Mixed);
|
||||
|
||||
oe->drawList(spec, oEvent::DrawMethod::Random, 1, oEvent::DrawType::DrawAll);
|
||||
loadPage(gdi);
|
||||
@ -1822,7 +1828,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
par.listCode = EStdStartList;
|
||||
}
|
||||
}
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
|
||||
gdi.refresh();
|
||||
@ -1953,7 +1959,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
par.selection.insert(outClass.begin(), outClass.end());
|
||||
oListInfo info;
|
||||
par.listCode = EStdStartList;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
}
|
||||
else if (bi.id == "LockAllForks" || bi.id == "UnLockAllForks") {
|
||||
@ -2069,7 +2075,7 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
||||
par.selection.insert(ClassId);
|
||||
oListInfo info;
|
||||
par.listCode = EStdStartList;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -2452,6 +2458,8 @@ void TabClass::showClassSettings(gdioutput &gdi)
|
||||
|
||||
createDrawMethod(gdi);
|
||||
|
||||
addVacantPosition(gdi);
|
||||
|
||||
gdi.addSelection("PairSize", 150, 200, 0, L"Tillämpa parstart:");
|
||||
gdi.addItem("PairSize", getPairOptions());
|
||||
gdi.selectItemByData("PairSize", 1);
|
||||
@ -3634,9 +3642,18 @@ void TabClass::drawDialog(gdioutput &gdi, oEvent::DrawMethod method, const oClas
|
||||
if (method != oEvent::DrawMethod::Simultaneous)
|
||||
gdi.addInput("Interval", formatTime(interval), 10, 0, L"Startintervall (min):").setSynchData(&lastInterval);
|
||||
|
||||
if ((method == oEvent::DrawMethod::Random || method == oEvent::DrawMethod::SOFT || method == oEvent::DrawMethod::Clumped || method == oEvent::DrawMethod::MeOS) && pc.getParentClass() == 0)
|
||||
if ((method == oEvent::DrawMethod::Random ||
|
||||
method == oEvent::DrawMethod::SOFT ||
|
||||
method == oEvent::DrawMethod::Clumped ||
|
||||
method == oEvent::DrawMethod::MeOS ||
|
||||
method == oEvent::DrawMethod::Simultaneous) && pc.getParentClass() == 0) {
|
||||
gdi.addInput("Vacanses", itow(vac), 10, 0, L"Antal vakanser:").setSynchData(&lastNumVac);
|
||||
|
||||
if (method == oEvent::DrawMethod::SOFT ||
|
||||
method == oEvent::DrawMethod::Random ||
|
||||
method == oEvent::DrawMethod::MeOS)
|
||||
addVacantPosition(gdi);
|
||||
}
|
||||
if ((method == oEvent::DrawMethod::Random || method == oEvent::DrawMethod::SOFT || method == oEvent::DrawMethod::Seeded || method == oEvent::DrawMethod::MeOS) && pc.getNumStages() > 1 && pc.getClassType() != oClassPatrol) {
|
||||
gdi.addSelection("Leg", 90, 100, 0, L"Sträcka:", L"Sträcka att lotta");
|
||||
for (unsigned k = 0; k < pc.getNumStages(); k++)
|
||||
@ -3691,6 +3708,26 @@ void TabClass::drawDialog(gdioutput &gdi, oEvent::DrawMethod method, const oClas
|
||||
lastDrawMethod = method;
|
||||
}
|
||||
|
||||
void TabClass::addVacantPosition(gdioutput &gdi) {
|
||||
gdi.addSelection("VacantPosition", 120, 80, nullptr, L"Vakansplacering:");
|
||||
vector<pair<wstring, size_t>> vp;
|
||||
vp.emplace_back(lang.tl("Lottat"), size_t(oEvent::VacantPosition::Mixed));
|
||||
vp.emplace_back(lang.tl("Först"), size_t(oEvent::VacantPosition::First));
|
||||
vp.emplace_back(lang.tl("Sist"), size_t(oEvent::VacantPosition::Last));
|
||||
gdi.addItem("VacantPosition", vp);
|
||||
int def = oe->getPropertyInt("VacantPosition", size_t(oEvent::VacantPosition::Mixed));
|
||||
gdi.selectItemByData("VacantPosition", def);
|
||||
}
|
||||
|
||||
oEvent::VacantPosition TabClass::readVacantPosition(gdioutput &gdi) const {
|
||||
if (gdi.hasWidget("VacantPosition")) {
|
||||
int val = gdi.getSelectedItem("VacantPosition").first;
|
||||
oe->setProperty("VacantPosition", val);
|
||||
return oEvent::VacantPosition(val);
|
||||
}
|
||||
return oEvent::VacantPosition::Mixed;
|
||||
}
|
||||
|
||||
set<oEvent::DrawMethod> TabClass::getSupportedDrawMethods(bool hasMulti) const {
|
||||
set<oEvent::DrawMethod> base = { oEvent::DrawMethod::Random, oEvent::DrawMethod::SOFT, oEvent::DrawMethod::Clumped,
|
||||
oEvent::DrawMethod::MeOS, oEvent::DrawMethod::Simultaneous, oEvent::DrawMethod::Seeded };
|
||||
@ -3916,13 +3953,34 @@ void TabClass::enableLoadSettings(gdioutput &gdi) {
|
||||
}
|
||||
|
||||
|
||||
void TabClass::simultaneous(int classId, const wstring &time) {
|
||||
void TabClass::simultaneous(int classId, const wstring &time, int nVacant) {
|
||||
pClass pc = oe->getClass(classId);
|
||||
|
||||
if (!pc)
|
||||
throw exception();
|
||||
|
||||
pc->getNumStages();
|
||||
if (nVacant >= 0 && pc->getNumStages() <= 1) {
|
||||
vector<int> toRemove;
|
||||
vector<pRunner> runners;
|
||||
oe->getRunners(classId, 0, runners, true);
|
||||
//Remove old vacances
|
||||
for (pRunner r : runners) {
|
||||
if (r->getTeam())
|
||||
continue; // Cannot remove team runners
|
||||
if (r->isVacant()) {
|
||||
|
||||
if (--nVacant < 0)
|
||||
toRemove.push_back(r->getId());
|
||||
}
|
||||
}
|
||||
|
||||
oe->removeRunner(toRemove);
|
||||
toRemove.clear();
|
||||
for (int i = 0; i < nVacant; i++) {
|
||||
oe->addRunnerVacant(classId);
|
||||
}
|
||||
}
|
||||
|
||||
if (pc->getNumStages() == 0) {
|
||||
pCourse crs = pc->getCourse();
|
||||
pc->setNumStages(1);
|
||||
|
||||
@ -79,8 +79,9 @@ class TabClass :
|
||||
set<oEvent::DrawMethod> getSupportedDrawMethods(bool multiDay) const;
|
||||
|
||||
void drawDialog(gdioutput &gdi, oEvent::DrawMethod method, const oClass &cls);
|
||||
|
||||
void pursuitDialog(gdioutput &gdi);
|
||||
void addVacantPosition(gdioutput &gdi);
|
||||
oEvent::VacantPosition TabClass::readVacantPosition(gdioutput &gdi) const;
|
||||
|
||||
bool warnDrawStartTime(gdioutput &gdi, int time, bool absTime);
|
||||
bool warnDrawStartTime(gdioutput &gdi, const wstring &firstStart);
|
||||
@ -117,7 +118,7 @@ class TabClass :
|
||||
void showClassSelection(gdioutput &gdi, int &bx, int &by, GUICALLBACK classesCB) const;
|
||||
|
||||
// Set simultaneous start in a class
|
||||
void simultaneous(int classId, const wstring &time);
|
||||
void simultaneous(int classId, const wstring &time, int nVacant);
|
||||
|
||||
void updateFairForking(gdioutput &gdi, pClass pc) const;
|
||||
void selectCourses(gdioutput &gdi, int legNo);
|
||||
|
||||
@ -144,12 +144,12 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
oClub::definedPayModes(*oe, dpm);
|
||||
pc->generateInvoice(gdi, pay, paid, dpm, ppm);
|
||||
}
|
||||
gdi.addButton(gdi.getWidth()+20, 15, gdi.scaleLength(120),
|
||||
gdi.addButton(gdi.getWidth()+20, gdi.scaleLength(15), gdi.scaleLength(120),
|
||||
"Cancel", "Återgå", ClubsCB, "", true, false);
|
||||
gdi.addButton(gdi.getWidth()+20, 45, gdi.scaleLength(120),
|
||||
gdi.addButton(gdi.getWidth()+20, gdi.scaleLength(45), gdi.scaleLength(120),
|
||||
"Print", "Skriv ut...", ClubsCB,
|
||||
"Skriv ut fakturan", true, false);
|
||||
gdi.addButton(gdi.getWidth()+20, 75, gdi.scaleLength(120),
|
||||
gdi.addButton(gdi.getWidth()+20, gdi.scaleLength(75), gdi.scaleLength(120),
|
||||
"PDF", "PDF...", ClubsCB,
|
||||
"Spara som PDF.", true, false);
|
||||
gdi.refresh();
|
||||
@ -299,16 +299,20 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
}
|
||||
else if (bi.id == "InvoiceSettings") {
|
||||
gdi.clearPage(true);
|
||||
gdi.pushX();
|
||||
gdi.addString("", boldLarge, "Fakturainställningar");
|
||||
gdi.dropLine();
|
||||
firstInvoice = oClub::getFirstInvoiceNumber(*oe);
|
||||
if (firstInvoice == 0)
|
||||
firstInvoice = oe->getPropertyInt("FirstInvoice", 1000);
|
||||
|
||||
gdi.addInput("FirstInvoice", itow(firstInvoice), 5, 0, L"Första fakturanummer:");
|
||||
|
||||
gdi.dropLine();
|
||||
gdi.addString("", boldText, "Organisatör");
|
||||
gdi.fillRight();
|
||||
gdi.addInput("InvoiceDate", oClub::getInvoiceDate(*oe), 16, nullptr, L"Fakturadatum:");
|
||||
gdi.addInput("FirstInvoice", itow(firstInvoice), 16, 0, L"Första fakturanummer:");
|
||||
gdi.fillDown();
|
||||
gdi.popX();
|
||||
gdi.dropLine(4);
|
||||
gdi.addString("", fontMediumPlus, "Organisatör");
|
||||
|
||||
vector<string> fields;
|
||||
gdi.pushY();
|
||||
@ -320,7 +324,7 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
oe->getDI().buildDataFields(gdi, fields, 32);
|
||||
|
||||
gdi.dropLine();
|
||||
gdi.addString("", boldText, "Betalningsinformation");
|
||||
gdi.addString("", fontMediumPlus, "Betalningsinformation");
|
||||
fields.clear();
|
||||
fields.push_back("Account");
|
||||
fields.push_back("PaymentDue");
|
||||
@ -334,7 +338,7 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
gdi.dropLine(2);
|
||||
gdi.popX();
|
||||
|
||||
gdi.addString("", boldText, "Formatering");
|
||||
gdi.addString("", fontMediumPlus, "Formatering");
|
||||
|
||||
gdi.fillRight();
|
||||
gdi.addString("", 0, "Koordinater (mm) för adressfält:");
|
||||
@ -353,12 +357,11 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
gdi.dropLine(1);
|
||||
|
||||
gdi.fillRight();
|
||||
gdi.addButton("SaveSettings", "Spara", ClubsCB);
|
||||
gdi.addButton("Cancel", "Avbryt", ClubsCB);
|
||||
gdi.addButton("SaveSettings", "Spara", ClubsCB).setDefault();
|
||||
gdi.addButton("Cancel", "Avbryt", ClubsCB).setCancel();
|
||||
gdi.dropLine(2);
|
||||
gdi.setOnClearCb(ClubsCB);
|
||||
oe->getDI().fillDataFields(gdi);
|
||||
|
||||
}
|
||||
else if (bi.id == "SaveSettings") {
|
||||
oe->getDI().saveDataFields(gdi);
|
||||
@ -376,6 +379,13 @@ int TabClub::clubCB(gdioutput &gdi, int type, void *data)
|
||||
else
|
||||
oe->setProperty("FirstInvoice", fn);
|
||||
|
||||
if (gdi.getText("InvoiceDate").empty()) {
|
||||
gdi.setText("InvoiceDate", oClub::getInvoiceDate(*oe));
|
||||
dynamic_cast<InputInfo &>(gdi.getBaseInfo("InvoiceDate")).setBgColor(colorLightRed);
|
||||
return 0;
|
||||
}
|
||||
oClub::setInvoiceDate(*oe, gdi.getText("InvoiceDate"));
|
||||
|
||||
int xc = gdi.getTextNo("XC");
|
||||
int yc = gdi.getTextNo("YC");
|
||||
|
||||
|
||||
@ -621,7 +621,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
}
|
||||
else if (bi.id=="Browse") {
|
||||
vector< pair<wstring, wstring> > ext;
|
||||
ext.push_back(make_pair(lang.tl(L"Databaskälla"), L"*.xml;*.csv"));
|
||||
ext.push_back(make_pair(L"Databaskälla", L"*.xml;*.csv"));
|
||||
|
||||
wstring f = gdi.browseForOpen(ext, L"xml");
|
||||
string id;
|
||||
@ -1545,7 +1545,9 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
switch (startType) {
|
||||
case SMCommon:
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"0", L"0", false, false, oEvent::DrawMethod::Random, 1);
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"0",
|
||||
L"0", oEvent::VacantPosition::Mixed,
|
||||
false, false, oEvent::DrawMethod::Random, 1);
|
||||
drawn = true;
|
||||
break;
|
||||
|
||||
@ -1570,7 +1572,9 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
}
|
||||
}
|
||||
if (!skip)
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"2:00", L"2", true, false, oEvent::DrawMethod::MeOS, 1);
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"2:00",
|
||||
L"2", oEvent::VacantPosition::Mixed,
|
||||
true, false, oEvent::DrawMethod::MeOS, 1);
|
||||
drawn = true;
|
||||
break;
|
||||
}
|
||||
@ -1766,7 +1770,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
par.setLegNumberCoded(-1);
|
||||
oListInfo li;
|
||||
par.selection = allTransfer;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), li);
|
||||
oe->generateListInfo(par, li);
|
||||
gdioutput tGdi("temp", gdi.getScale());
|
||||
oe->generateList(tGdi, true, li, false);
|
||||
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
|
||||
@ -1851,7 +1855,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
par.showSplitTimes = true;
|
||||
par.setLegNumberCoded(-1);
|
||||
oListInfo li;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), li);
|
||||
oe->generateListInfo(par, li);
|
||||
gdioutput tGdi("temp", gdi.getScale());
|
||||
oe->generateList(tGdi, true, li, false);
|
||||
HTMLWriter::writeTableHTML(tGdi, save, oe->getName(), 0, 1.0);
|
||||
@ -3459,7 +3463,7 @@ void TabCompetition::entryForm(gdioutput &gdi, bool isGuide) {
|
||||
gdi.dropLine(3);
|
||||
}
|
||||
|
||||
TabCompetition::FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, bool isGuide) {
|
||||
FlowOperation TabCompetition::saveEntries(gdioutput &gdi, bool removeRemoved, bool isGuide) {
|
||||
wstring filename[5];
|
||||
filename[0] = gdi.getText("FileNameCmp");
|
||||
filename[1] = gdi.getText("FileNameCls");
|
||||
@ -3574,11 +3578,17 @@ int stageInfoCB(gdioutput *gdi, int type, void *data)
|
||||
}
|
||||
|
||||
void mainMessageLoop(HACCEL hAccelTable, DWORD time);
|
||||
FlowOperation importFilterGUI(oEvent *oe,
|
||||
gdioutput & gdi,
|
||||
const set<int>& stages,
|
||||
const vector<string> &idProviders,
|
||||
set<int> & filter,
|
||||
string &preferredIdProvider);
|
||||
|
||||
TabCompetition::FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi,
|
||||
const wstring & fname,
|
||||
set<int>& filter,
|
||||
string &preferredIdProvider) {
|
||||
FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi,
|
||||
const wstring & fname,
|
||||
set<int>& filter,
|
||||
string &preferredIdProvider) {
|
||||
xmlparser xml;
|
||||
xml.read(fname);
|
||||
xmlobject xo = xml.getObject("EntryList");
|
||||
@ -3591,6 +3601,16 @@ TabCompetition::FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi,
|
||||
reader.getIdTypes(idProviders);
|
||||
}
|
||||
}
|
||||
return importFilterGUI(oe, gdi, scanFilter, idProviders, filter, preferredIdProvider);
|
||||
}
|
||||
|
||||
FlowOperation importFilterGUI(oEvent *oe,
|
||||
gdioutput & gdi,
|
||||
const set<int>& stages,
|
||||
const vector<string> &idProviders,
|
||||
set<int> & filter,
|
||||
string &preferredIdProvider) {
|
||||
auto &scanFilter = stages;
|
||||
bool stageFilter = scanFilter.size() > 1;
|
||||
bool idtype = idProviders.size() > 1;
|
||||
|
||||
@ -3631,7 +3651,7 @@ TabCompetition::FlowOperation TabCompetition::checkStageFilter(gdioutput & gdi,
|
||||
gdi.fillRight();
|
||||
gdi.addSelection("IdType", 150, 200, stageInfoCB, L"Välj vilken typ du vill importera:");
|
||||
int i = 0;
|
||||
for (string &sn : idProviders) {
|
||||
for (const string &sn : idProviders) {
|
||||
gdi.addItem("IdType", gdi.widen(sn), i++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
************************************************************************/
|
||||
|
||||
#include "tabbase.h"
|
||||
|
||||
#include "gdiconstants.h"
|
||||
#include "oFreeImport.h"
|
||||
|
||||
class PrefsEditor;
|
||||
@ -31,12 +31,6 @@ class ImportFormats;
|
||||
class TabCompetition :
|
||||
public TabBase
|
||||
{
|
||||
enum FlowOperation {
|
||||
FlowContinue,
|
||||
FlowCancel,
|
||||
FlowAborted
|
||||
};
|
||||
|
||||
wstring eventorBase;
|
||||
wstring iofExportVersion;
|
||||
void textSizeControl(gdioutput &gdi) const;
|
||||
|
||||
@ -510,7 +510,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
|
||||
if (!gdi.ask(L"warning:drawresult"))
|
||||
return 0;
|
||||
}
|
||||
courseDrawClasses.push_back(ClassDrawSpecification(cls[k]->getId(), 0, -1, -1, 0));
|
||||
courseDrawClasses.emplace_back(cls[k]->getId(), 0, -1, -1, 0, oEvent::VacantPosition::Mixed);
|
||||
if (!clsNames.empty())
|
||||
clsNames += L", ";
|
||||
clsNames += cls[k]->getName();
|
||||
@ -586,7 +586,7 @@ int TabCourse::courseCB(gdioutput &gdi, int type, void *data)
|
||||
for (size_t k=0; k<courseDrawClasses.size(); k++)
|
||||
par.selection.insert(courseDrawClasses[k].classID);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
gdi.refresh();
|
||||
}
|
||||
|
||||
@ -449,7 +449,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
if (gdi.getSelectedItem("SavedInstance", lbi)) {
|
||||
oListParam &par = oe->getListContainer().getParam(lbi.data);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.getParam().sourceParam = lbi.data;
|
||||
generateList(gdi);
|
||||
}
|
||||
@ -646,7 +646,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
lastSplitState = par.showSplitTimes;
|
||||
lastLargeSize = par.useLargeSize;
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -676,7 +676,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
cnf.getIndividual(par.selection, false);
|
||||
readSettings(gdi, par, true);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -692,7 +692,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
par.showSplitTimes = true;
|
||||
par.setLegNumberCoded(-1);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -704,7 +704,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
getStartIndividual(par, cnf);
|
||||
readSettings(gdi, par, false);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -715,7 +715,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
getStartClub(par);
|
||||
readSettings(gdi, par, false);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -730,7 +730,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
readSettings(gdi, par, false);
|
||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -762,7 +762,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
getStartTeam(par, cnf);
|
||||
readSettings(gdi, par, false);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -778,7 +778,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
cnf.getRaceNStart(race, par.selection);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -794,7 +794,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
cnf.getLegNStart(race, par.selection);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -806,7 +806,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
getResultTeam(par, cnf);
|
||||
readSettings(gdi, par, true);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -818,7 +818,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
cnf.getRaceNRes(0, par.selection);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -833,7 +833,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
cnf.getRaceNRes(race, par.selection);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -848,7 +848,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
cnf.getLegNRes(race, par.selection);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -861,7 +861,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
getResultRogaining(par, cnf);
|
||||
readSettings(gdi, par, true);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -891,7 +891,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
cnf.getIndividual(par.back().selection, true);
|
||||
}
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -902,7 +902,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
par.listCode = EStdRentedCard;
|
||||
par.showHeader = gdi.isChecked("ShowHeader");
|
||||
par.setLegNumberCoded(-1);
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -914,7 +914,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
par.listCode = EIndPriceList;
|
||||
par.showHeader = gdi.isChecked("ShowHeader");
|
||||
par.filterMaxPer = gdi.getSelectedItem("ClassLimit").first;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
}
|
||||
@ -984,7 +984,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
cnf.getPatrol(par.selection);
|
||||
}
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -999,7 +999,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ClassConfigInfo cnf;
|
||||
oe->getClassConfigurationInfo(cnf);
|
||||
par.selection = set<int>(cnf.knockout.begin(), cnf.knockout.end());
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -1019,7 +1019,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
else
|
||||
par.selection = set<int>(cnf.lapcountsingle.begin(), cnf.lapcountsingle.end());
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -1043,7 +1043,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
if (oListInfo::addTeams(type))
|
||||
cnf.getTeamClass(par.selection);
|
||||
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), currentList);
|
||||
oe->generateListInfo(par, currentList);
|
||||
currentList.setCallback(openRunnerTeamCB);
|
||||
generateList(gdi);
|
||||
gdi.refresh();
|
||||
@ -1965,6 +1965,7 @@ void TabList::htmlSettings(gdioutput &gdi, string targetTag) {
|
||||
html2IdToInfo[id] = t.desc;
|
||||
}
|
||||
gdi.addSelection("Format", 200, 100, 0, L"Format:").setHandler(&htmlClass);
|
||||
gdi.autoGrow("Format");
|
||||
if (!htmlTemplateTag2Id.count(tmpSettingsParam.htmlTypeTag))
|
||||
tmpSettingsParam.htmlTypeTag = "free";
|
||||
|
||||
|
||||
@ -1944,7 +1944,7 @@ void TabRunner::showVacancyList(gdioutput &gdi, const string &method, int classI
|
||||
par.selection.insert(classId);
|
||||
oListInfo info;
|
||||
par.listCode = EStdStartList;
|
||||
oe->generateListInfo(par, gdi.getLineHeight(), info);
|
||||
oe->generateListInfo(par, info);
|
||||
oe->generateList(gdi, false, info, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -944,6 +944,11 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
di.setString("Phone", gdi.getText("Phone"));
|
||||
|
||||
if (gdi.isChecked("NoTiming"))
|
||||
r->setStatus(RunnerStatus::StatusNoTiming, true, oBase::ChangeType::Update, false);
|
||||
else if (r->getStatus() == RunnerStatus::StatusNoTiming)
|
||||
r->setStatus(RunnerStatus::StatusUnknown, true, oBase::ChangeType::Update, false);
|
||||
|
||||
r->setFlag(oRunner::FlagTransferSpecified, gdi.hasWidget("AllStages"));
|
||||
r->setFlag(oRunner::FlagTransferNew, gdi.isChecked("AllStages"));
|
||||
|
||||
@ -2938,6 +2943,8 @@ void TabSI::generateEntryLine(gdioutput &gdi, pRunner r) {
|
||||
gdi.setCX(gdi.getCX()+gdi.scaleLength(20));
|
||||
|
||||
gdi.addCheckbox("RentCard", "Hyrbricka", SportIdentCB, storedInfo.rentState);
|
||||
gdi.addCheckbox("NoTiming", "Utan tidtagning", nullptr, false);
|
||||
|
||||
if (oe->hasNextStage())
|
||||
gdi.addCheckbox("AllStages", "Anmäl till efterföljande etapper", SportIdentCB, storedInfo.allStages);
|
||||
|
||||
@ -2955,9 +2962,10 @@ void TabSI::generateEntryLine(gdioutput &gdi, pRunner r) {
|
||||
if (gdi.hasWidget("Fee"))
|
||||
gdi.setText("Fee", oe->formatCurrency(dci.getInt("Fee")));
|
||||
|
||||
gdi.setText("StartTime", r->getStartTimeS());
|
||||
gdi.setText("Phone", dci.getString("Phone"));
|
||||
gdi.setText("Bib", r->getBib());
|
||||
|
||||
gdi.check("NoTiming", r->hasFlag(oAbstractRunner::TransferFlags::FlagNoTiming));
|
||||
gdi.check("RentCard", dci.getInt("CardFee") != 0);
|
||||
if (gdi.hasWidget("Paid"))
|
||||
gdi.check("Paid", dci.getInt("Paid")>0);
|
||||
|
||||
@ -1215,8 +1215,9 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
||||
int numberPos = xp;
|
||||
xp += gdi.scaleLength(25);
|
||||
int dx[6] = {0, 184, 220, 290, 316, 364};
|
||||
for (int i = 0; i<6; i++)
|
||||
dx[i] = gdi.scaleLength(dx[i]);
|
||||
dx[1] = gdi.getInputDimension(18).first + gdi.scaleLength(4);
|
||||
for (int i = 2; i<6; i++)
|
||||
dx[i] = dx[1] + gdi.scaleLength(dx[i]-188);
|
||||
|
||||
gdi.addString("", yp, xp + dx[0], 0, "Namn:");
|
||||
gdi.addString("", yp, xp + dx[2], 0, "Bricka:");
|
||||
@ -1224,38 +1225,36 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
||||
gdi.addString("", yp, xp + dx[5], 0, "Status:");
|
||||
gdi.dropLine(0.5);
|
||||
|
||||
for (unsigned i=0;i<pc->getNumStages();i++) {
|
||||
yp = gdi.getCY();
|
||||
for (unsigned i = 0; i < pc->getNumStages(); i++) {
|
||||
yp = gdi.getCY() - gdi.scaleLength(3);
|
||||
|
||||
sprintf_s(bf, "R%d", i);
|
||||
gdi.pushX();
|
||||
bool hasSI = false;
|
||||
gdi.addStringUT(yp, numberPos, 0, pc->getLegNumber(i) + L".");
|
||||
if (pc->getLegRunner(i)==i) {
|
||||
if (pc->getLegRunner(i) == i) {
|
||||
|
||||
gdi.addInput(xp + dx[0], yp, bf, L"", 18, TeamCB);//Name
|
||||
gdi.addButton(xp + dx[1], yp-2, gdi.scaleLength(28), "DR" + itos(i), "<>", TeamCB, "Knyt löpare till sträckan.", false, false); // Change
|
||||
gdi.addButton(xp + dx[1], yp - 2, gdi.scaleLength(28), "DR" + itos(i), "<>", TeamCB, "Knyt löpare till sträckan.", false, false); // Change
|
||||
sprintf_s(bf_si, "SI%d", i);
|
||||
hasSI = true;
|
||||
gdi.addInput(xp + dx[2], yp, bf_si, L"", 5, TeamCB).setExtra(i); //Si
|
||||
|
||||
gdi.addCheckbox(xp + dx[3], yp + gdi.scaleLength(10), "RENT"+itos(i), "", 0, false); //Rentcard
|
||||
gdi.addCheckbox(xp + dx[3], yp + gdi.scaleLength(10), "RENT" + itos(i), "", 0, false); //Rentcard
|
||||
}
|
||||
else {
|
||||
//gdi.addInput(bf, "", 24);
|
||||
gdi.addInput(xp + dx[0], yp, bf, L"", 18, 0);//Name
|
||||
gdi.disableInput(bf);
|
||||
}
|
||||
gdi.addButton(xp + dx[4], yp-2, gdi.scaleLength(38), "MR" + itos(i), "...", TeamCB, "Redigera deltagaren.", false, false); // Change
|
||||
gdi.addButton(xp + dx[4], yp - 2, gdi.scaleLength(38), "MR" + itos(i), "...", TeamCB, "Redigera deltagaren.", false, false); // Change
|
||||
|
||||
gdi.addString(("STATUS"+itos(i)).c_str(), yp+gdi.scaleLength(5), xp + dx[5], 0, "#MMMMMMMMMMMMMMMM");
|
||||
gdi.setText("STATUS"+itos(i), L"", false);
|
||||
gdi.addString(("STATUS" + itos(i)).c_str(), yp + gdi.scaleLength(5), xp + dx[5], 0, "#MMMMMMMMMMMMMMMM");
|
||||
gdi.setText("STATUS" + itos(i), L"", false);
|
||||
gdi.dropLine(0.5);
|
||||
gdi.popX();
|
||||
|
||||
|
||||
if (t) {
|
||||
pRunner r=t->getRunner(i);
|
||||
pRunner r = t->getRunner(i);
|
||||
if (r) {
|
||||
gdi.setText(bf, r->getNameRaw())->setExtra(r->getId());
|
||||
|
||||
@ -1265,7 +1264,7 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
||||
warnDuplicateCard(gdi, bf_si, cno, r);
|
||||
gdi.check("RENT" + itos(i), r->getDCI().getInt("CardFee") != 0);
|
||||
}
|
||||
string sid = "STATUS"+itos(i);
|
||||
string sid = "STATUS" + itos(i);
|
||||
if (r->statusOK(true)) {
|
||||
TextInfo * ti = (TextInfo *)gdi.setText(sid, L"OK, " + r->getRunningTimeS(true), false);
|
||||
if (ti)
|
||||
|
||||
@ -2045,7 +2045,7 @@ void Table::importClipboard(gdioutput &gdi)
|
||||
tw = max(tw, table[k].size());
|
||||
|
||||
if (tw > columns.size())
|
||||
throw std::exception("Antalet columner i urklippet är större än antalet kolumner i tabellen.");
|
||||
throw meosException("Antalet kolumner i urklippet är större än antalet kolumner i tabellen.");
|
||||
|
||||
if (upperRow == -1) {
|
||||
if (!gdi.ask(L"Vill du klistra in X nya rader i tabellen?#"+itow(table.size())))
|
||||
@ -2059,10 +2059,10 @@ void Table::importClipboard(gdioutput &gdi)
|
||||
getRowRange(row1, row2);
|
||||
|
||||
if ( (row1 + table.size()) > sortIndex.size() )
|
||||
throw std::exception("Antalet rader i urklipp får inte plats i selektionen.");
|
||||
throw meosException("Antalet rader i urklipp får inte plats i selektionen.");
|
||||
|
||||
if ( (col1 + tw) > columns.size() )
|
||||
throw std::exception("Antalet kolumner i urklipp får inte plats i selektionen.");
|
||||
throw meosException("Antalet kolumner i urklipp får inte plats i selektionen.");
|
||||
|
||||
bool wrongSize = false;
|
||||
|
||||
|
||||
@ -2410,3 +2410,70 @@ help:custom_text_lines = Du kan indsætte egne data ved at skrive [Symbol Name].
|
||||
htmlhelp = HTML kan eksporteres som en struktureret tabel eller som et frit formateret dokument (mere i stil med MeOS lister). Du kan også bruge eksporter skabeloner med egen formatering: kolonner, JavaScript base page flips, automatisk rulning, o.s.v. Det er muligt at tilføje egne skabeloner ved at tilføje '.template' filer i MeOS mappen. Hvis du bruger skabeloner er der et antal parametre der skal angives, se nedenfor. Den præcise fortolkning af parametrene afhænger af skabelonen.\n\nHvis du vælger <Store Settings> bliver listen og dens opsætning gemt permanent i løbet. Du kan så tilgå listen ved at bruge MeOS som Web server (Tjenesten 'Information Server') eller ved at eksportere listen ved jævne mellemrum.
|
||||
info:pageswithcolumns = Vis listen en side af gangen med det angivne antal kolonner. Genindlæs listen automatisk efter hvert gennemløb.
|
||||
Övrigt = Øvrigt
|
||||
Age (on last day of current year) = Alder ved årets udgang
|
||||
Age above or equal implies senior/pensioner = Aldersgrænse for seniorer
|
||||
Age below or equal implies youth = Aldersgrænse for ungdom
|
||||
Anmälningsdatum = Tilmeldingsdato
|
||||
ClassAvailableMaps = Tilgængelige kort for klasse
|
||||
ClassNumEntries = Antal tilmeldte i klassen
|
||||
ClassTotalMaps = Antal kort total
|
||||
EFilterWrongFee = Forkert gebyr
|
||||
Flera lopp i valfri ordning = Flere løb i vilkårlig rækkefølge
|
||||
Flytta ner = Flyt ned
|
||||
Flytta upp = Flyt op
|
||||
Från första = Fra første
|
||||
Förväntad = Forventet
|
||||
Heat = Heat
|
||||
Inkludera bana = Inkluder bane
|
||||
Kartor = Kort
|
||||
Klassen är full = Klassen er fuld
|
||||
Knockout sammanställning = Knock-out opsummering
|
||||
Kunde inte ladda upp löpardatabasen (X) = Kunne ikke overføre løberdatabase (X)
|
||||
Kunde inte öppna databasen (X) = Kunne ikke åbne database (X)
|
||||
Kvalschema = Kvalifikationsskema
|
||||
Lagändringblankett = Holdændringsskema
|
||||
Lås funktion = Lås funktion
|
||||
Lås upp = Lås op
|
||||
Låst gaffling = Låst gaffling
|
||||
Mappa rootadressen (http:///localhost:port/) till funktion = Map root addresse (http:///localhost:port/) til funktion
|
||||
Målstämpling tillåts inte (X) = Målstempling ikke tilladt (X)
|
||||
Plac. E[stageno] = Plac. E
|
||||
Poäng E[stageno] = Point E
|
||||
Poängreduktion = Reduktion
|
||||
Radio = Radio
|
||||
Radio tillåts inte (X) = Radioposter ikke tilladt (X)
|
||||
Referens = Reference
|
||||
Registrera hyrbrickor = Registrer lejebrikker
|
||||
Result module = Resultat modul
|
||||
Rogaining points before automatic reduction = Rogaining point før automatisk reduktion
|
||||
Runner check time = Løbers check tid
|
||||
Runner/team earlier stage places = Deltagere/hold: placering på tidligere etapper
|
||||
Runner/team earlier stage points = Deltagere/hold: point på tidligere etapper
|
||||
Runner/team earlier stage running times = Deltagere/hold: tid på tidligere etapper
|
||||
Runner/team earlier stage statuses = Deltagere/hold: status for tidligere etapper
|
||||
RunnerExpectedFee = Forventet deltagerafgift
|
||||
Senast sedd: X vid Y = Sidst set: X ved Y
|
||||
Startstämpling tillåts inte (X) = Startstempling ikke tilladt (X)
|
||||
Status E[stageno] = Status E
|
||||
Status code for cancelled entry = Statuskode for afbud
|
||||
Status code for no timing = Statuskode for uden tidsstempling
|
||||
Status code for running out-of-competition = Statuskode for udenfor konkurrance (OOC)
|
||||
Stigning = Stigning
|
||||
There is no result module with X as identifier = Der er intet resultatmodul med identifikator X
|
||||
Tid E[stageno] = Tid E
|
||||
Till sista = Til sidste
|
||||
Tillåt = Tillad
|
||||
Unexpected Fee = Uventet tilmeldingsgebyr
|
||||
Utom tävlan = Udenfor konkurrance OOC
|
||||
Vill du sätta hyrbricka på befintliga löpare med dessa brickor? = Vil du tildele lejebrikker til eksisterende løbere med disse brikker?
|
||||
Vill du ta bort brickan från hyrbrickslistan? = Vil du fjerne brikken fra listen af lejebrikker?
|
||||
Vill du tömma listan med hyrbrickor? = Vil du slette listen med lejebrikker?
|
||||
X anmälda = X tilmeldte
|
||||
ask:usecourseinclass = Banen bruges ikke af andre deltagere i klassen.\n\nV il du alligevel bruge den?
|
||||
help:registerhiredcards = Forregistrer Si-brikker som lejebrikker så de automatisk får status lejebrik når de tildeles.
|
||||
info:advanceinfo = Det var ikke muligt at starte tjesten for forhåndsinformation om resultat. Resultatet vil komme med nogle skunders forsinkelse. Dette kan forventes hvis der kører flere udgaver at MeOS på maskinen samtidigt.
|
||||
prefsLastExportTarget = Seneste mål for eksport
|
||||
prefsServiceRootMap = Standardfunktion for webserverens root
|
||||
prefsshowheader = Vis overskrifter på siderne
|
||||
warn:printmodeonly = Bemærk: Du laver kun en udskrift af Si-brikkens indhold. Hvis du vil gemme resultatet skal du bruge funktionen aflæs/radiotider.
|
||||
Åldersfiltrering = Aldersfiltrering
|
||||
|
||||
@ -2426,7 +2426,7 @@ prefsServiceRootMap = Standard function for web server root
|
||||
prefsshowheader = Show page headers
|
||||
help:registerhiredcards = Preregister punching cards as rental cards to get automatic hired card status when the card is assigned.
|
||||
Lagändringblankett = Team Change Form
|
||||
Mappa rootadresssen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function
|
||||
Mappa rootadressen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function
|
||||
ClassAvailableMaps = Available maps for class
|
||||
ClassTotalMaps = Total number of maps for class
|
||||
Kunde inte öppna databasen (X) = Could not connect to database (X)
|
||||
@ -2474,4 +2474,22 @@ Status code for cancelled entry = Status code for cancelled entry
|
||||
Age (on last day of current year) = Age (on last day of current year)
|
||||
Age above or equal implies senior/pensioner = Age above or equal implies senior/pensioner
|
||||
Age below or equal implies youth = Age below or equal implies youth
|
||||
Status code for not no timing = Status code for not no timing
|
||||
Det finns multiplia Id-nummer för personer = There are multiple ID:s for persons
|
||||
Välj vilken typ du vill importera = Select type of ID to import
|
||||
Status code for no timing = Status code for no timing
|
||||
prefsVacantPercent = Percent vacant default
|
||||
ClassNumEntries = Number of entries
|
||||
Före X = Before X
|
||||
Efter X = After X
|
||||
Slå ihop X = Merge with X
|
||||
Slå ihop med = Merge with
|
||||
Mellan X och Y = Between X and Y
|
||||
Ett okänt fel inträffade = An unknown error occurred
|
||||
Antalet kolumner i urklippet är större än antalet kolumner i tabellen = The number of columns in the clipboard is greater than the number of columns in the table
|
||||
Antalet kolumner i urklipp får inte plats i selektionen = The number of columns in the clipboard does not fit the selection
|
||||
prefsVacantPosition = Placement of vacancies
|
||||
Vakansplacering = Vacancy placement
|
||||
Först = First
|
||||
Lottat = Drawn
|
||||
Sist = Last
|
||||
Fakturadatum = Fakturadatum
|
||||
|
||||
@ -2429,7 +2429,61 @@ prefsServiceRootMap = Fonctions standard pour la source du serveur Web
|
||||
prefsshowheader = Afficher les titres
|
||||
help:registerhiredcards = Pré-inscrivez des puces comme puces louées pour assigner automatiquement le statut et le tarif correspondant quand cette puce est assignée.
|
||||
Lagändringblankett = Modifications d'équipes
|
||||
Mappa rootadresssen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function ($2428)
|
||||
Mappa rootadressen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function ($2428)
|
||||
ClassAvailableMaps = Cartes disponibles pour la catégorie
|
||||
ClassTotalMaps = Nombre total de cartes pour la catégorie
|
||||
Export split times = Exporter les temps intermédiaires
|
||||
Age (on last day of current year) = Age (au dernier jour de l'année en cours)
|
||||
Age above or equal implies senior/pensioner = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition)
|
||||
Age below or equal implies youth = Limite d'âge haute des jeunes (défini dans Compétition/Configuration de la competition)
|
||||
ClassNumEntries = Nombres d'inscrits dans la catégorie
|
||||
Endast tidtagning = chronométrage seul
|
||||
Flera lopp i valfri ordning = Plusieurs circuits dans un ordre quelconque
|
||||
Från första = Dép. au premier poste
|
||||
Heat = Manche
|
||||
Inkludera bana = Inclure le circuit
|
||||
Kartor = Cartes
|
||||
Knockout sammanställning = Résumé des éliminations
|
||||
Kunde inte ladda upp löpardatabasen (X) = Impossible d'importer la base de données coureurs (X)
|
||||
Kunde inte öppna databasen (X) = Impossible de se connecter à la base de données (X)
|
||||
Kvalschema = Procédé de qualification
|
||||
Lås funktion = Verr. fonction
|
||||
Lås upp = Déverouiller
|
||||
Låst gaffling = Variations verrouillées
|
||||
Målstämpling tillåts inte (X) = Arrivée radio désactivée (x) [Finish punch disallowed]
|
||||
Plac. E[stageno] = Place E
|
||||
Poäng E[stageno] = Points E
|
||||
Poängreduktion = Réduction
|
||||
Radio = Radio
|
||||
Radio tillåts inte (X) = Postes de contrôle radios désactivés (X) [Radio controls disallowed]
|
||||
Referens = Référence
|
||||
Result module = Module de résultats
|
||||
Rogaining points before automatic reduction = Points du circuit avant réduction automatique
|
||||
Runner check time = Heure de contrôle du coureur
|
||||
Runner/team earlier stage places = Places du coureur/de l'équipe aux étapes précédentes
|
||||
Runner/team earlier stage points = Points du coureur/de l'équipe aux étapes précédentes
|
||||
Runner/team earlier stage running times = Temps du coureur/de l'équipe aux étapes précédentes
|
||||
Runner/team earlier stage statuses = Statuts du coureur/de l'équipe aux étapes précédentes
|
||||
Senast sedd: X vid Y = Dernières infos: à X au poste Y
|
||||
Startstämpling tillåts inte (X) = Départ radio désactivé (X) [Start punch disallowed]
|
||||
Status E[stageno] = Statut E
|
||||
Status code for cancelled entry = Code de statut pour une inscription annulée
|
||||
Status code for no timing = Code de statut pour une course non chronométrée
|
||||
Status code for running out-of-competition = Code de statut pour non classé (NC)
|
||||
Stigning = Dénivellé
|
||||
Tid E[stageno] = Temps E
|
||||
Till sista = Arr. au dernier poste
|
||||
Tillåt = Autoriser
|
||||
Utom tävlan = NC
|
||||
X anmälda = X inscrits
|
||||
ask:usecourseinclass = Le circuit n'est utilisé par aucun autre coureur dans cette catégorie\n\nVoulez-vous tout de même l'utiliser ?
|
||||
warn:printmodeonly = Attention, notez bien que vous ne faites qu'imprimer les données de la puce sans l'enregistrer.\n\nPour l'intégrer à la course, utilisez la fonction Lecture des puces/Radios.
|
||||
Åldersfiltrering = Filtrer par âge
|
||||
There is no result module with X as identifier = Aucun module de résultat n'a X comme identifiant
|
||||
prefsVacantPercent = Pourcentage de vacants
|
||||
ClassNumEntries = Nombre d'inscrits dans la catégorie
|
||||
Före X = Avant X
|
||||
Efter X = Après X
|
||||
Slå ihop X = Fusionner X
|
||||
Slå ihop med = Fusionner avec
|
||||
Ett okänt fel inträffade = Une erreur inconnue s'est produite
|
||||
|
||||
@ -40,5 +40,14 @@ enum KeyCommandCode {
|
||||
KC_AUTOCOMPLETE,
|
||||
};
|
||||
|
||||
/** Enum used to stack GUI command control, "command line wizard" */
|
||||
enum FlowOperation {
|
||||
FlowContinue,
|
||||
FlowCancel,
|
||||
FlowAborted
|
||||
};
|
||||
|
||||
|
||||
|
||||
const int GDI_BUTTON_SPACING = 8;
|
||||
#endif
|
||||
|
||||
@ -1358,6 +1358,15 @@ HFONT gdioutput::getGUIFont() const
|
||||
return getCurrentFont().getGUIFont();
|
||||
}
|
||||
|
||||
pair<int, int> gdioutput::getInputDimension(int length) const {
|
||||
HDC hDC = GetDC(hWndTarget);
|
||||
SelectObject(hDC, getGUIFont());
|
||||
SIZE size;
|
||||
GetTextExtentPoint32(hDC, L"M", 1, &size);
|
||||
ReleaseDC(hWndTarget, hDC);
|
||||
return make_pair(length*size.cx + scaleLength(8), size.cy + scaleLength(6));
|
||||
}
|
||||
|
||||
InputInfo &gdioutput::addInput(int x, int y, const string &id, const wstring &text,
|
||||
int length, GUICALLBACK cb,
|
||||
const wstring &explanation, const wstring &help) {
|
||||
@ -1367,30 +1376,25 @@ InputInfo &gdioutput::addInput(int x, int y, const string &id, const wstring &te
|
||||
}
|
||||
|
||||
InputInfo ii;
|
||||
SIZE size;
|
||||
|
||||
HDC hDC=GetDC(hWndTarget);
|
||||
SelectObject(hDC, getGUIFont());
|
||||
GetTextExtentPoint32(hDC, L"M", 1, &size);
|
||||
ReleaseDC(hWndTarget, hDC);
|
||||
|
||||
auto dim = getInputDimension(length);
|
||||
int ox=OffsetX;
|
||||
int oy=OffsetY;
|
||||
|
||||
ii.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", text.c_str(),
|
||||
WS_TABSTOP|WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | ES_AUTOHSCROLL | WS_BORDER,
|
||||
x-ox, y-oy, length*size.cx+scaleLength(8), size.cy+scaleLength(6),
|
||||
x-ox, y-oy, dim.first, dim.second,
|
||||
hWndTarget, NULL, (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
|
||||
updatePos(x, y, length*size.cx+scaleLength(12), size.cy+scaleLength(10));
|
||||
int mrg = scaleLength(4);
|
||||
updatePos(x, y, dim.first+mrg, dim.second+mrg);
|
||||
|
||||
SendMessage(ii.hWnd, WM_SETFONT,
|
||||
(WPARAM) getGUIFont(), 0);
|
||||
|
||||
ii.xp=x;
|
||||
ii.yp=y;
|
||||
ii.width = length*size.cx+scaleLength(8);
|
||||
ii.height = size.cy+scaleLength(6);
|
||||
ii.width = dim.first;
|
||||
ii.height = dim.second;
|
||||
ii.text = text;
|
||||
ii.original = text;
|
||||
ii.focusText = text;
|
||||
|
||||
@ -684,6 +684,9 @@ public:
|
||||
|
||||
bool isInputChanged(const string &exclude);
|
||||
|
||||
/** Get width of input widget with specified length (chars)*/
|
||||
pair<int,int> getInputDimension(int length) const;
|
||||
|
||||
InputInfo &addInput(const string &id, const wstring &text = L"", int length=16, GUICALLBACK cb=0,
|
||||
const wstring &Explanation = L"", const wstring &tooltip=L"");
|
||||
InputInfo &addInput(int x, int y, const string &id, const wstring &text, int length,
|
||||
|
||||
@ -1063,7 +1063,7 @@ void DynamicResult::declareSymbols(DynamicMethods m, bool clear) const {
|
||||
parser.declareSymbol("StatusDQ", "Status code for disqualification", false);
|
||||
parser.declareSymbol("StatusOutOfCompetition", "Status code for running out-of-competition", false);
|
||||
parser.declareSymbol("StatusNotCompetiting", "Status code for not competing", false);
|
||||
parser.declareSymbol("StatusNoTiming", "Status code for not no timing", false);
|
||||
parser.declareSymbol("StatusNoTiming", "Status code for no timing", false);
|
||||
|
||||
parser.declareSymbol("ShortestClassTime", "Shortest time in class", false);
|
||||
|
||||
|
||||
431
code/html1.htm
431
code/html1.htm
@ -1,28 +1,29 @@
|
||||
<image source="/meos?image=meos"><br>
|
||||
<h1>Documentation of MeOS REST API</h1>
|
||||
<image source="/meos?image=meos">
|
||||
<br>
|
||||
<h1>Documentation of MeOS REST API</h1>
|
||||
|
||||
<h2>Competition</h2>
|
||||
<b>Syntax:</b>
|
||||
<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>Returns:</b>
|
||||
<p>MOP Competition XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<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>
|
||||
<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>Returns:</b>
|
||||
<p>MOP Classes XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*cls id="1" ord="10" radio="90,130;90,130;90,130">D21*/cls>
|
||||
@ -30,20 +31,20 @@
|
||||
*/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.
|
||||
<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>
|
||||
<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>Returns:</b>
|
||||
<p>MOP Controls XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*control id="31">[31]*/control>
|
||||
@ -52,54 +53,60 @@ controls are only for convenience.
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<h2>Competitors</h2>
|
||||
<b>Syntax:</b>
|
||||
<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>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>Returns:</b>
|
||||
<p>MOP Competitors XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*cmp id="3565">
|
||||
*base org="570" cls="5" stat="1" st="360000" rt="20580">Elsa Winter*/base>
|
||||
*cmp id="3565" card="101050">
|
||||
*base org="570" cls="5" stat="1" st="360000" rt="20580" nat="NOR">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>
|
||||
*base org="134" cls="7" stat="1" st="380710" rt="46910" nat="SWE">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>
|
||||
<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, 2 is no timing. Higher codes are used for disqualifications etc.</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>
|
||||
<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>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>Returns:</b>
|
||||
<p>MOP Teams XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*tm id="2928771">
|
||||
@ -113,25 +120,27 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
*/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>
|
||||
<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>
|
||||
<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>Returns:</b>
|
||||
<p>MOP Organization XML</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*org id="1012">BAOC*/org>
|
||||
@ -141,8 +150,42 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<h2>Results</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Recent Competition Changes</h2>
|
||||
<b>Purpose:</b>
|
||||
Keep a separate database with results synchronized with MeOS.
|
||||
<br />
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?difference=zero">/meos?difference=zero</a></pre>
|
||||
<pre>/meos?difference=*nextdifference></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>
|
||||
Complete or difference MOP of changes since last time API was called. Use litteral 'zero' to obtain
|
||||
a new set of differences (the difference from zero).
|
||||
The returned data includes an attribute <i>nextdifference</i> that you use as argument in
|
||||
the nex call to difference, to get changes since this call.
|
||||
</p>
|
||||
<b>Example:</b>
|
||||
<p>
|
||||
Start by invoking /meos?difference=zero. The returned data will look like:
|
||||
<pre>
|
||||
*MOPComplete nextdifference="332617">
|
||||
...
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
Next time, you invoke /meos?difference=332617, which may return
|
||||
<pre>
|
||||
*MOPDiff nextdifference="324254">
|
||||
...
|
||||
*/MOPDiff>
|
||||
</pre>
|
||||
|
||||
Next time you use difference=324254 and so on. Note that under some circumstances,
|
||||
you may also get a complete event instead of a difference. See the general MOP documentation.
|
||||
</p>
|
||||
<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>
|
||||
@ -154,46 +197,59 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
<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>
|
||||
<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>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>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>
|
||||
<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>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>
|
||||
<b>Examples:</b>
|
||||
|
||||
<p>Individual results at the finish.</p>
|
||||
<p>Individual results at the finish.</p>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*results location="Finish">
|
||||
@ -215,7 +271,7 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<p>Team results, leg 2 at Radio 1, leg has three parallel runners.</p>
|
||||
<p>Team results, leg 2 at Radio 1, leg has three parallel runners.</p>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*results leg="2" location="Radio 1">
|
||||
@ -241,7 +297,7 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<p>Roganing results, Invoke with argument module=rogaining, which is a built in module.</p>
|
||||
<p>Roganing results, Invoke with argument module=rogaining, which is a built in module.</p>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*results module="rogaining" location="Finish">
|
||||
@ -264,8 +320,8 @@ Please refer to the MOP documentation for a complete description of all attribut
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<b>Remarks:</b>
|
||||
When and only when the type is <b>CourseIndividual</b>, the attribute <i>course</i> is included.
|
||||
<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>
|
||||
@ -273,26 +329,26 @@ When and only when the type is <b>CourseIndividual</b>, the attribute <i>course<
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Status</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Status</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?get=status">/meos?get=status</a></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>MeOS Status Data. Includes MeOS version and competition name id, which also is the name of the database used, if any.</p>
|
||||
<b>Returns:</b>
|
||||
<p>MeOS Status Data. Includes MeOS version and competition name id, which also is the name of the database used, if any.</p>
|
||||
|
||||
<b>Example:</b>
|
||||
<b>Example:</b>
|
||||
<pre>
|
||||
*MOPComplete>
|
||||
*status version="3.6.1029" eventNameId="meos_20190223_212818_2FD" onDatabase="1"/>
|
||||
*/MOPComplete>
|
||||
</pre>
|
||||
|
||||
<h2>Entry Classes</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Entry Classes</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?get=entryclass">/meos?get=entryclass</a></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>Classes where entry is allowed via the API.</p>
|
||||
<b>Returns:</b>
|
||||
<p>Classes where entry is allowed via the API.</p>
|
||||
|
||||
<pre>
|
||||
*EntryClasses>
|
||||
@ -306,24 +362,24 @@ When and only when the type is <b>CourseIndividual</b>, the attribute <i>course<
|
||||
*/EntryClasses>
|
||||
</pre>
|
||||
|
||||
<h2>Lookup competitor</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Lookup competitor</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?lookup=competitor&id=%runnerid%">/meos?lookup=competitor&id=*id></a></pre>
|
||||
<pre><a href="/meos?lookup=competitor&card=%card%">/meos?lookup=competitor&card=*card></a></pre>
|
||||
<pre><a href="/meos?lookup=competitor&bib=%bib%">/meos?lookup=competitor&bib=*bib></a></pre>
|
||||
<pre><a href="/meos?lookup=competitor&name=%name%&club=%club%">/meos?lookup=competitor&name=*name>&club=*club></a></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>Competitor including individual result.</p>
|
||||
<b>Returns:</b>
|
||||
<p>Competitor including individual result.</p>
|
||||
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> Competitor id. MeOS internal id.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
<li><i>bib</i> Bib or start number.</li>
|
||||
<li><i>name</i> Name of competitor.</li>
|
||||
<li><i>club</i> Name of club.</li>
|
||||
</ul>
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> Competitor id. MeOS internal id.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
<li><i>bib</i> Bib or start number.</li>
|
||||
<li><i>name</i> Name of competitor.</li>
|
||||
<li><i>club</i> Name of club.</li>
|
||||
</ul>
|
||||
|
||||
<pre>
|
||||
*Competitors>
|
||||
@ -359,23 +415,25 @@ When and only when the type is <b>CourseIndividual</b>, the attribute <i>course<
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Lookup Database Competitor</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Lookup Database Competitor</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?lookup=dbcompetitor&id=%runnerextid%">/meos?lookup=dbcompetitor&id=*id></a></pre>
|
||||
<pre><a href="/meos?lookup=dbcompetitor&card=%card%">/meos?lookup=dbcompetitor&card=*card></a></pre>
|
||||
<pre><a href="/meos?lookup=dbcompetitor&name=%dbname%&club=%dbclub%">/meos?lookup=dbcompetitor&name=*name>&club=*club></a></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>Competitor from runner database. Note that a partial name may be submitted, and that several matching result may be returned, sorted by relevance.
|
||||
This query is suitable for auto complete functionality.</p>
|
||||
<b>Returns:</b>
|
||||
<p>
|
||||
Competitor from runner database. Note that a partial name may be submitted, and that several matching result may be returned, sorted by relevance.
|
||||
This query is suitable for auto complete functionality.
|
||||
</p>
|
||||
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id from runner database.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
<li><i>name</i> Name of competitor. Possibly a partial name.</li>
|
||||
<li><i>club</i> Name of club.</li>
|
||||
</ul>
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id from runner database.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
<li><i>name</i> Name of competitor. Possibly a partial name.</li>
|
||||
<li><i>club</i> Name of club.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<pre>
|
||||
@ -392,20 +450,22 @@ This query is suitable for auto complete functionality.</p>
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Lookup Database Club</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Lookup Database Club</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre><a href="/meos?lookup=dbclub&id=%clubid%">/meos?lookup=dbclub&id=*id></a></pre>
|
||||
<pre><a href="/meos?lookup=dbclub&name=%club%">/meos?lookup=dbclub&name=*name></a></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
<p>Club from club database. Note that a partial name may be submitted, and that several matching result may be returned, sorted by relevance.
|
||||
This query is suitable for auto complete functionality.</p>
|
||||
<b>Returns:</b>
|
||||
<p>
|
||||
Club from club database. Note that a partial name may be submitted, and that several matching result may be returned, sorted by relevance.
|
||||
This query is suitable for auto complete functionality.
|
||||
</p>
|
||||
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id from club database.</li>
|
||||
<li><i>name</i> Name of club. Possibly a partial name.</li>
|
||||
</ul>
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id from club database.</li>
|
||||
<li><i>name</i> Name of club. Possibly a partial name.</li>
|
||||
</ul>
|
||||
|
||||
<pre>
|
||||
*DatabaseClubs>
|
||||
@ -415,25 +475,26 @@ This query is suitable for auto complete functionality.</p>
|
||||
*/DatabaseClubs>
|
||||
</pre>
|
||||
|
||||
<h2>API New Entry</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>API New Entry</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre>/meos?entry&id=*id>&class=*classid>&card=*card></pre>
|
||||
<pre>/meos?entry&name=*name>&club=*club>&class=*classid>&card=*card></pre>
|
||||
<pre>/meos?entry&name=*name>&club=*club>&class=*classid>&card=*card>¬iming</pre>
|
||||
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id of runner from runner database.</li>
|
||||
<li><i>name</i> Name of runner.</li>
|
||||
<li><i>club</i> Name of runner's club.</li>
|
||||
<li><i>class</i> Id of class.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
</ul>
|
||||
<b>Arguments:</b>
|
||||
<ul>
|
||||
<li><i>id</i> External id of runner from runner database.</li>
|
||||
<li><i>name</i> Name of runner.</li>
|
||||
<li><i>club</i> Name of runner's club.</li>
|
||||
<li><i>class</i> Id of class.</li>
|
||||
<li><i>card</i> Card number.</li>
|
||||
<li><i>notiming</i> Set status no timing.</li>
|
||||
</ul>
|
||||
|
||||
<p></p><b>Returns:</b>
|
||||
Status.</p>
|
||||
<p><b>Returns:</b>
|
||||
Status.</p>
|
||||
|
||||
<b>Note: </b> <p></p>If the card number is registered as a rental card, it will be set as such and
|
||||
<i>hiredCard</i> will be set in the Fee attribute. The returned fee includes any rental card fee.</p>
|
||||
<p><b>Note: </b> <br />If the card number is registered as a rental card, it will be set as such and
|
||||
<i>hiredCard</i> will be set in the Fee attribute. The returned fee includes any rental card fee.</p>
|
||||
|
||||
<pre>
|
||||
*Answer>
|
||||
@ -450,44 +511,44 @@ Status.</p>
|
||||
*/Answer>
|
||||
</pre>
|
||||
|
||||
<h2>Page template</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Page template</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre>/meos?page=*page></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
Installed template file with the specified tag.
|
||||
<b>Returns:</b>
|
||||
Installed template file with the specified tag.
|
||||
|
||||
<h2>Image</h2>
|
||||
<b>Syntax:</b>
|
||||
<h2>Image</h2>
|
||||
<b>Syntax:</b>
|
||||
<pre>/meos?image=*image></pre>
|
||||
|
||||
<b>Returns:</b>
|
||||
Image, *image>.png, if installed in MeOS datafolder. MeOS logo if *image> is meos.
|
||||
<b>Returns:</b>
|
||||
Image, *image>.png, if installed in MeOS datafolder. MeOS logo if *image> is meos.
|
||||
|
||||
<h2>IOF XML Results</h2>
|
||||
<h2>IOF XML Results</h2>
|
||||
|
||||
<b>Syntax:</b>
|
||||
<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>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>
|
||||
<b>Returns:</b>
|
||||
<p>IOF XML version 3.0 result list.</p>
|
||||
|
||||
<h2>IOF XML Startlist</h2>
|
||||
<h2>IOF XML Startlist</h2>
|
||||
|
||||
<b>Syntax:</b>
|
||||
<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>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>
|
||||
<b>Returns:</b>
|
||||
<p>IOF XML version 3.0 start list.</p>
|
||||
|
||||
@ -427,9 +427,12 @@ void InfoMeosStatus::serialize(xmlbuffer &xml, bool diffOnly) const {
|
||||
|
||||
bool InfoOrganization::synchronize(oClub &c) {
|
||||
const wstring &n = c.getDisplayName();
|
||||
if (n == name)
|
||||
const wstring &nat = c.getDCI().getString("Nationality");
|
||||
|
||||
if (n == name && nat == nationality)
|
||||
return false;
|
||||
else {
|
||||
nationality = nat;
|
||||
name = n;
|
||||
modified();
|
||||
}
|
||||
@ -439,6 +442,8 @@ bool InfoOrganization::synchronize(oClub &c) {
|
||||
void InfoOrganization::serialize(xmlbuffer &xml, bool diffOnly) const {
|
||||
vector< pair<string, wstring> > prop;
|
||||
prop.push_back(make_pair("id", itow(getId())));
|
||||
if (!nationality.empty())
|
||||
prop.emplace_back("nat", nationality);
|
||||
xml.write("org", prop, name);
|
||||
}
|
||||
|
||||
@ -461,9 +466,11 @@ void InfoBaseCompetitor::serialize(xmlbuffer &xml, bool diffOnly, int course) co
|
||||
if (course != 0)
|
||||
prop.emplace_back("crs", itow(course));
|
||||
|
||||
if (!bib.empty()) {
|
||||
if (!bib.empty())
|
||||
prop.emplace_back("bib", bib);
|
||||
}
|
||||
|
||||
if (!nationality.empty())
|
||||
prop.emplace_back("nat", nationality);
|
||||
|
||||
xml.write("base", prop, name);
|
||||
}
|
||||
@ -488,11 +495,21 @@ bool InfoBaseCompetitor::synchronizeBase(oAbstractRunner &bc) {
|
||||
ch = true;
|
||||
}
|
||||
|
||||
RunnerStatus s = bc.getStatus();
|
||||
const wstring &nat = bc.getDCI().getString("Nationality");
|
||||
if (nat != nationality) {
|
||||
nationality = nat;
|
||||
ch = true;
|
||||
}
|
||||
|
||||
RunnerStatus s = bc.getStatusComputed();
|
||||
|
||||
int rt = bc.getRunningTime(true) * 10;
|
||||
if (rt > 0) {
|
||||
if (s == RunnerStatus::StatusUnknown)
|
||||
s = RunnerStatus::StatusOK;
|
||||
|
||||
if (s == RunnerStatus::StatusNoTiming)
|
||||
rt = 0;
|
||||
}
|
||||
else if (isPossibleResultStatus(s))
|
||||
s = StatusUnknown;
|
||||
@ -583,7 +600,7 @@ bool InfoCompetitor::synchronize(const InfoCompetition &cmp, oRunner &r) {
|
||||
}
|
||||
|
||||
bool nr;
|
||||
if ((r.getStatus() == StatusUnknown || r.getStatus() == StatusOutOfCompetition || r.getStatus() == StatusNoTiming) && r.getFinishTime() <= 0) {
|
||||
if ((r.getStatus() == StatusUnknown || isPossibleResultStatus(r.getStatus())) && r.getFinishTime() <= 0) {
|
||||
vector<pFreePunch> pv;
|
||||
r.getEvent()->getPunchesForRunner(r.getId(), false, pv);
|
||||
nr = pv.size() > 0;
|
||||
@ -597,7 +614,7 @@ bool InfoCompetitor::synchronize(const InfoCompetition &cmp, oRunner &r) {
|
||||
}
|
||||
|
||||
vector<RadioTime> newRT;
|
||||
if (r.getClassId(false) > 0) {
|
||||
if (r.getClassId(false) > 0 && r.getStatusComputed() != RunnerStatus::StatusNoTiming) {
|
||||
const vector<int> &radios = cmp.getControls(r.getClassId(true), r.getLegNumber());
|
||||
for (size_t k = 0; k < radios.size(); k++) {
|
||||
RadioTime radioTime;
|
||||
@ -611,7 +628,7 @@ bool InfoCompetitor::synchronize(const InfoCompetition &cmp, oRunner &r) {
|
||||
}
|
||||
}
|
||||
}
|
||||
changeRadio = radioTimes.size() > 0;//false; // Always write full attributes
|
||||
changeRadio = radioTimes.size() > 0; // Always write full attributes
|
||||
if (newRT != radioTimes) {
|
||||
ch = true;
|
||||
changeRadio = true;
|
||||
@ -879,3 +896,33 @@ bool xmlbuffer::commit(xmlparser &xml, int count) {
|
||||
|
||||
return !blocks.empty();
|
||||
}
|
||||
|
||||
void xmlbuffer::commitCopy(xmlparser &xml) {
|
||||
vector<wstring> p2;
|
||||
for (block &block : blocks) {
|
||||
if (block.subValues.empty()) {
|
||||
xml.write(block.tag.c_str(), block.prop, block.value);
|
||||
}
|
||||
else {
|
||||
if (block.prop.size() > 1) {
|
||||
p2.resize(block.prop.size() * 2);
|
||||
for (size_t k = 0; k < block.prop.size(); k++) {
|
||||
p2[k * 2] = gdi_main->widen(block.prop[k].first);
|
||||
p2[k * 2 + 1] = block.prop[k].second;
|
||||
}
|
||||
xml.startTag(block.tag.c_str(), p2);
|
||||
}
|
||||
else if (block.prop.size() == 1) {
|
||||
xml.startTag(block.tag.c_str(), block.prop[0].first.c_str(), block.prop[0].second);
|
||||
}
|
||||
else if (block.prop.empty()) {
|
||||
xml.startTag(block.tag.c_str());
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < block.subValues.size(); k++)
|
||||
block.subValues[k].commitCopy(xml);
|
||||
|
||||
xml.endTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,9 @@ public:
|
||||
|
||||
size_t size() const {return blocks.size();}
|
||||
bool commit(xmlparser &xml, int count);
|
||||
void commitCopy(xmlparser &xml);
|
||||
|
||||
bool isComplete() const { return complete; }
|
||||
void startXML(xmlparser &xml, const wstring &dest);
|
||||
};
|
||||
|
||||
@ -140,6 +142,7 @@ class InfoMeosStatus : public InfoBase {
|
||||
class InfoOrganization : public InfoBase {
|
||||
protected:
|
||||
wstring name;
|
||||
wstring nationality;
|
||||
public:
|
||||
InfoOrganization(int id);
|
||||
virtual ~InfoOrganization() {}
|
||||
@ -169,6 +172,7 @@ class InfoBaseCompetitor : public InfoBase {
|
||||
int startTime;
|
||||
int runningTime;
|
||||
wstring bib;
|
||||
wstring nationality;
|
||||
void serialize(xmlbuffer &xml, bool diffOnly, int course) const;
|
||||
bool synchronizeBase(oAbstractRunner &bc);
|
||||
public:
|
||||
|
||||
@ -47,13 +47,13 @@ private:
|
||||
T &rehash(int size, KEY key, const T &value);
|
||||
T &get(const KEY key);
|
||||
|
||||
const intkeymap &operator=(const intkeymap &co);
|
||||
void *lookup(KEY key) const;
|
||||
public:
|
||||
virtual ~intkeymap();
|
||||
intkeymap(int size);
|
||||
intkeymap();
|
||||
intkeymap(const intkeymap &co);
|
||||
const intkeymap &operator=(const intkeymap &co);
|
||||
|
||||
bool empty() const;
|
||||
int size() const;
|
||||
|
||||
@ -83,6 +83,34 @@ template <class T, class KEY> intkeymap<T, KEY>::intkeymap(const intkeymap &co)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class KEY>
|
||||
const intkeymap<T, KEY> &intkeymap<T, KEY>::operator=(const intkeymap<T, KEY> &co) {
|
||||
clear();
|
||||
delete[] keys;
|
||||
|
||||
allocFactor = co.allocFactor;
|
||||
siz = co.siz;
|
||||
keys = new keypair[siz];
|
||||
hash1 = co.hash1;
|
||||
hash2 = co.hash2;
|
||||
used = co.used;
|
||||
level = co.level;
|
||||
dummy = co.dummy;
|
||||
noValue = co.noValue;
|
||||
|
||||
for (unsigned k = 0; k<siz; k++)
|
||||
keys[k] = co.keys[k];
|
||||
|
||||
parent = 0;
|
||||
next = 0;
|
||||
|
||||
if (co.next) {
|
||||
next = new intkeymap<T, KEY>(*co.next);
|
||||
next->parent = this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T, class KEY> intkeymap<T, KEY>::~intkeymap()
|
||||
{
|
||||
delete[] keys;
|
||||
|
||||
@ -492,7 +492,6 @@ void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAss
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOF30Interface::classAssignmentObsolete(gdioutput &gdi, xmlList &xAssignment,
|
||||
const map<wstring, pCourse> &courses,
|
||||
const map<wstring, vector<pCourse> > &coursesFamilies) {
|
||||
@ -690,6 +689,23 @@ void IOF30Interface::classAssignmentObsolete(gdioutput &gdi, xmlList &xAssignmen
|
||||
}
|
||||
}
|
||||
|
||||
void IOF30Interface::prescanCompetitorList(xmlobject &xo) {
|
||||
xmlList xl;
|
||||
xo.getObjects(xl);
|
||||
|
||||
xmlList::const_iterator it;
|
||||
xmlList work;
|
||||
string wstring;
|
||||
for (it = xl.begin(); it != xl.end(); ++it) {
|
||||
if (it->is("Competitor")) {
|
||||
xmlobject person = it->getObject("Person");
|
||||
if (person) {
|
||||
readIdProviders(person, work, wstring);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IOF30Interface::readCompetitorList(gdioutput &gdi, const xmlobject &xo, int &personCount) {
|
||||
if (!xo)
|
||||
return;
|
||||
@ -704,7 +720,7 @@ void IOF30Interface::readCompetitorList(gdioutput &gdi, const xmlobject &xo, int
|
||||
|
||||
xmlList::const_iterator it;
|
||||
|
||||
for (it=xl.begin(); it != xl.end(); ++it) {
|
||||
for (it = xl.begin(); it != xl.end(); ++it) {
|
||||
if (it->is("Competitor")) {
|
||||
if (readXMLCompetitorDB(*it))
|
||||
personCount++;
|
||||
@ -736,15 +752,15 @@ void IOF30Interface::readClubList(gdioutput &gdi, const xmlobject &xo, int &club
|
||||
void IOF30Interface::prescanEntryList(xmlobject &xo, set<int> &definedStages) {
|
||||
definedStages.clear();
|
||||
|
||||
xmlList pEntries;
|
||||
xmlList pEntries, work;
|
||||
xo.getObjects("PersonEntry", pEntries);
|
||||
for (size_t k = 0; k < pEntries.size(); k++) {
|
||||
prescanEntry(pEntries[k], definedStages);
|
||||
prescanEntry(pEntries[k], definedStages, work);
|
||||
}
|
||||
|
||||
xo.getObjects("TeamEntry", pEntries);
|
||||
for (size_t k = 0; k < pEntries.size(); k++) {
|
||||
prescanEntry(pEntries[k], definedStages);
|
||||
prescanEntry(pEntries[k], definedStages, work);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1598,8 +1614,8 @@ int IOF30Interface::getIndexFromLegPos(int leg, int legorder, const vector<LegIn
|
||||
return ix;
|
||||
}
|
||||
|
||||
void IOF30Interface::prescanEntry(xmlobject &xo, set<int> &stages) {
|
||||
xmlList races;
|
||||
void IOF30Interface::prescanEntry(xmlobject &xo, set<int> &stages, xmlList &work) {
|
||||
xmlList &races = work;
|
||||
xo.getObjects("RaceNumber", races);
|
||||
if (races.empty())
|
||||
xo.getObjects("Race", races); // For unclear reason the attribute is called Race for teams and RaceNumber for persons.
|
||||
@ -1621,16 +1637,21 @@ void IOF30Interface::prescanEntry(xmlobject &xo, set<int> &stages) {
|
||||
person = teamPerson.getObject("Person");
|
||||
}
|
||||
|
||||
xmlList ids;
|
||||
if (person) {
|
||||
person.getObjects("Id", ids);
|
||||
xmlList &ids = work;
|
||||
string type;
|
||||
if (ids.size() > 1) {
|
||||
for (auto &id : ids) {
|
||||
id.getObjectString("type", type);
|
||||
if (!type.empty()) {
|
||||
idProviders.insert(type);
|
||||
}
|
||||
readIdProviders(person, ids, type);
|
||||
}
|
||||
}
|
||||
|
||||
void IOF30Interface::readIdProviders(xmlobject &person, xmlList &ids, std::string &type)
|
||||
{
|
||||
person.getObjects("Id", ids);
|
||||
if (ids.size() > 1) {
|
||||
for (auto &id : ids) {
|
||||
id.getObjectString("type", type);
|
||||
if (!type.empty()) {
|
||||
idProviders.insert(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1767,6 +1788,22 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
|
||||
}
|
||||
}
|
||||
|
||||
bool hasTime = true;
|
||||
xmlobject ext = xo.getObject("Extensions");
|
||||
if (ext) {
|
||||
xmlList exts;
|
||||
ext.getObjects(exts);
|
||||
for (xmlobject &xx : exts) {
|
||||
if (xx.is("TimePresentation")) {
|
||||
hasTime = xx.getObjectBool(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasTime)
|
||||
r->setStatus(StatusNoTiming, true, oBase::ChangeType::Update);
|
||||
else if (r->getStatus() == StatusNoTiming)
|
||||
r->setStatus(StatusUnknown, true, oBase::ChangeType::Update);
|
||||
|
||||
r->synchronize();
|
||||
return r;
|
||||
}
|
||||
@ -2766,7 +2803,6 @@ void IOF30Interface::writeCourseInfo(xmlparser &xml, const oCourse &c) {
|
||||
xml.write("Climb", climb);
|
||||
}
|
||||
|
||||
|
||||
wstring formatStatus(RunnerStatus st, bool hasTime) {
|
||||
switch (st) {
|
||||
case StatusNoTiming:
|
||||
@ -2870,6 +2906,9 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
if (r.getStartTime() > 0)
|
||||
xml.write("StartTime", oe.getAbsDateTimeISO(r.getStartTime(), true, useGMT));
|
||||
|
||||
bool hasTiming = (!r.getClassRef(false) || r.getClassRef(true)->getNoTiming() == false) &&
|
||||
r.getStatusComputed() != RunnerStatus::StatusNoTiming;
|
||||
|
||||
int finishTime, runningTime, place, after;
|
||||
RunnerStatus status;
|
||||
if (!patrolResult) {
|
||||
@ -2892,13 +2931,13 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
status = r.getTeam()->getLegStatus(pl, true, false);
|
||||
}
|
||||
|
||||
if ((r.getClassRef(false) && r.getClassRef(true)->getNoTiming()) ||
|
||||
r.getStatusComputed() == StatusNoTiming) {
|
||||
if (!hasTiming) {
|
||||
after = -1;
|
||||
runningTime = 0;
|
||||
finishTime = 0;
|
||||
}
|
||||
|
||||
if (r.getFinishTime() > 0)
|
||||
if (finishTime > 0)
|
||||
xml.write("FinishTime", oe.getAbsDateTimeISO(finishTime, true, useGMT));
|
||||
|
||||
if (runningTime > 0)
|
||||
@ -2918,7 +2957,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
|
||||
if (r.getClassRef(false)) {
|
||||
|
||||
if (r.statusOK(true) && r.getClassRef(false)->getNoTiming() == false) {
|
||||
if (r.statusOK(true) && hasTiming) {
|
||||
if (!teamMember && place > 0 && place < 50000) {
|
||||
xml.write("Position", place);
|
||||
}
|
||||
@ -2941,11 +2980,11 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
}
|
||||
if ( (r.getTeam() && r.getClassRef(false)->getClassType() != oClassPatrol && !teamsAsIndividual) || hasInputTime) {
|
||||
xml.startTag("OverallResult");
|
||||
|
||||
int rt = r.getTotalRunningTime();
|
||||
if (rt > 0)
|
||||
if (rt > 0 && hasTiming)
|
||||
xml.write("Time", rt);
|
||||
|
||||
bool hasTiming = r.getClassRef(false)->getNoTiming() == false;
|
||||
RunnerStatus stat = r.getTotalStatus();
|
||||
|
||||
int tleg = r.getLegNumber() >= 0 ? r.getLegNumber() : 0;
|
||||
@ -3002,7 +3041,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
else
|
||||
xml.startTag("SplitTime");
|
||||
xml.write("ControlCode", crs->getControl(k)->getFirstNumber());
|
||||
if (sp[k].hasTime())
|
||||
if (sp[k].hasTime() && hasTiming)
|
||||
xml.write("Time", sp[k].time - r.getStartTime());
|
||||
xml.endTag();
|
||||
}
|
||||
@ -3014,6 +3053,21 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
xml.write("Time", it->first);
|
||||
xml.endTag();
|
||||
}
|
||||
|
||||
oCard *card = r.getCard();
|
||||
if (card) { // Write additional punches
|
||||
vector<pPunch> plist;
|
||||
card->getPunches(plist);
|
||||
for (pPunch p : plist) {
|
||||
if (p->getTypeCode() >= 30 && !p->isUsedInCourse()) {
|
||||
xml.startTag("SplitTime", "status", "Additional");
|
||||
xml.write("ControlCode", p->getTypeCode());
|
||||
if (p->getTimeInt() > r.getStartTime())
|
||||
xml.write("Time", p->getTimeInt() - r.getStartTime());
|
||||
xml.endTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3023,6 +3077,12 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
|
||||
writeFees(xml, rPerson);
|
||||
|
||||
if (!hasTiming) {
|
||||
xml.startTag("Extensions");
|
||||
xml.write("TimePresentation", L"false");
|
||||
xml.endTag();
|
||||
}
|
||||
|
||||
xml.endTag();
|
||||
}
|
||||
|
||||
@ -3464,9 +3524,13 @@ bool IOF30Interface::readXMLCompetitorDB(const xmlobject &xCompetitor) {
|
||||
|
||||
if (!person) return false;
|
||||
|
||||
int pidI;
|
||||
long long pid;
|
||||
readId(person, pidI, pid);
|
||||
/*
|
||||
wstring pidS;
|
||||
person.getObjectString("Id", pidS);
|
||||
long long pid = oBase::converExtIdentifierString(pidS);
|
||||
person.getObjectString("Id", pidS);xxx
|
||||
long long pid = oBase::converExtIdentifierString(pidS);*/
|
||||
xmlobject pname = person.getObject("Name");
|
||||
if (!pname) return false;
|
||||
|
||||
|
||||
@ -167,7 +167,8 @@ class IOF30Interface {
|
||||
|
||||
static int getIndexFromLegPos(int leg, int legorder, const vector<LegInfo> &setup);
|
||||
|
||||
void prescanEntry(xmlobject & xo, set<int>& stages);
|
||||
void prescanEntry(xmlobject & xo, set<int>& stages, xmlList &work);
|
||||
void readIdProviders(xmlobject &person, xmlList &ids, std::string &type);
|
||||
void setupClassConfig(int classId, const xmlobject &xTeam, map<int, vector<LegInfo> > &teamClassConfig);
|
||||
|
||||
void setupRelayClasses(const map<int, vector<LegInfo> > &teamClassConfig);
|
||||
@ -298,6 +299,7 @@ public:
|
||||
|
||||
void readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
||||
|
||||
void prescanCompetitorList(xmlobject &xo);
|
||||
void readCompetitorList(gdioutput &gdi, const xmlobject &xo, int &personCount);
|
||||
|
||||
void readClubList(gdioutput &gdi, const xmlobject &xo, int &clubCount);
|
||||
|
||||
@ -225,7 +225,7 @@ void ListEditor::show(gdioutput &gdi) {
|
||||
gdi.fillDown();
|
||||
|
||||
try {
|
||||
currentList->interpret(oe, gdi, par, gdi.getLineHeight(), li);
|
||||
currentList->interpret(oe, gdi, par, li);
|
||||
rc.left = gdi.getCX();
|
||||
rc.right = gdi.getCX() + gdi.getWidth() - 20;
|
||||
rc.top = gdi.getCY();
|
||||
|
||||
@ -30,24 +30,18 @@
|
||||
//V35: abcdef
|
||||
//V36: abcdef
|
||||
int getMeosBuild() {
|
||||
string revision("$Rev: 972 $");
|
||||
string revision("$Rev: 1004 $");
|
||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||
}
|
||||
|
||||
//ABCDEFGHIJKILMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz
|
||||
//V2: abcdefgh
|
||||
//V3: abcdefghijklmnopqrstuvxyz
|
||||
//V31: abcde
|
||||
//V32: abcdefgh
|
||||
//V33: abcdefghij
|
||||
//V34: abcdfge
|
||||
//V37: a
|
||||
wstring getMeosDate() {
|
||||
wstring date(L"$Date: 2020-01-18 15:14:04 +0100 (lö, 18 jan 2020) $");
|
||||
wstring date(L"$Date: 2020-02-25 21:05:03 +0100 (ti, 25 feb 2020) $");
|
||||
return date.substr(7,10);
|
||||
}
|
||||
|
||||
wstring getBuildType() {
|
||||
return L"Beta 1"; // No parantheses (...)
|
||||
return L"RC1"; // No parantheses (...)
|
||||
}
|
||||
|
||||
wstring getMajorVersion() {
|
||||
@ -149,5 +143,8 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||
supp.emplace_back(L"Finspångs SOK");
|
||||
supp.emplace_back(L"OK Gorm, Denmark");
|
||||
supp.emplace_back(L"Nyköpings OK");
|
||||
supp.emplace_back(L"Thomas Engberg, VK Uvarna");
|
||||
supp.emplace_back(L"LG Axmalm, Sävedalens AIK");
|
||||
|
||||
reverse(supp.begin(), supp.end());
|
||||
}
|
||||
|
||||
@ -358,8 +358,7 @@ static void setFixedWidth(oPrintPost &added,
|
||||
added.fixedWidth = 0;
|
||||
}
|
||||
|
||||
void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par,
|
||||
int lineHeight, oListInfo &li) const {
|
||||
void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par, oListInfo &li) const {
|
||||
const MetaList &mList = *this;
|
||||
Position pos;
|
||||
const bool large = par.useLargeSize;
|
||||
@ -376,19 +375,20 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
if (fontFaces[k].scale > 0 && fontFaces[k].scale != 100) {
|
||||
face += L";" + itow(fontFaces[k].scale/100) + L"." + itow(fontFaces[k].scale%100);
|
||||
}
|
||||
fontHeight[make_pair(it->first, int(k))] = gdi.getLineHeight(it->first, face.c_str());
|
||||
fontHeight[make_pair(it->first, int(k))] = int(gdi.getLineHeight(it->first, face.c_str()) / gdi.getScale());
|
||||
}
|
||||
}
|
||||
|
||||
int lineHeight;
|
||||
if (large) {
|
||||
s_factor = 0.9;
|
||||
normal = fontLarge;
|
||||
header = boldLarge;
|
||||
small = normalText;
|
||||
lineHeight = int(lineHeight *1.6);
|
||||
lineHeight = 22;
|
||||
italic = italicMediumPlus;
|
||||
}
|
||||
else {
|
||||
lineHeight = 14;
|
||||
s_factor = 1.0;
|
||||
normal = normalText;
|
||||
header = boldText;
|
||||
@ -511,6 +511,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
oPrintPost::encodeFont(fontFaces[i].font,
|
||||
fontFaces[i].scale).c_str(),
|
||||
large, max(mp.blockWidth, extraMinWidth));
|
||||
|
||||
++linePostCount[make_pair(i, j)]; // Count how many positions on this line
|
||||
indexPosToWidth[tuple<int,int,int>(i, j, k)] = width;
|
||||
}
|
||||
@ -584,7 +585,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
resultToIndex.clear();
|
||||
/*if (large == false && par.pageBreak == false) {*/
|
||||
{
|
||||
int head_dy = gdi.scaleLength(mList.getExtraSpace(MLHead));
|
||||
int head_dy = mList.getExtraSpace(MLHead);
|
||||
for (size_t j = 0; j<mList.getHead().size(); j++) {
|
||||
const vector<MetaListPost> &cline = mList.getHead()[j];
|
||||
next_dy = 0;
|
||||
@ -639,7 +640,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
}
|
||||
|
||||
dy = lineHeight;
|
||||
int subhead_dy = gdi.scaleLength(mList.getExtraSpace(MLSubHead));
|
||||
int subhead_dy = mList.getExtraSpace(MLSubHead);
|
||||
|
||||
last = 0;
|
||||
base = 0;
|
||||
@ -689,7 +690,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
|
||||
last = 0;
|
||||
base = 0;
|
||||
int list_dy = gdi.scaleLength(mList.getExtraSpace(MLList));//mList.getSubList().size() > 0 ? lineHeight/2 : 0;
|
||||
int list_dy = mList.getExtraSpace(MLList);
|
||||
dy = 0;
|
||||
for (size_t j = 0; j<mList.getList().size(); j++) {
|
||||
const vector<MetaListPost> &cline = mList.getList()[j];
|
||||
@ -731,7 +732,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
||||
dy += next_dy;
|
||||
}
|
||||
|
||||
int sublist_dy = gdi.scaleLength(mList.getExtraSpace(MLSubList));
|
||||
int sublist_dy = mList.getExtraSpace(MLSubList);
|
||||
last = 0;
|
||||
base = 0;
|
||||
dy = 0;
|
||||
@ -2309,12 +2310,11 @@ wstring MetaListContainer::makeUniqueParamName(const wstring &nameIn) const {
|
||||
}
|
||||
|
||||
|
||||
bool MetaListContainer::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par,
|
||||
int lineHeight, oListInfo &li) const {
|
||||
bool MetaListContainer::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par, oListInfo &li) const {
|
||||
|
||||
map<EStdListType, int>::const_iterator it = globalIndex.find(par.listCode);
|
||||
if (it != globalIndex.end()) {
|
||||
data[it->second].second.interpret(oe, gdi, par, lineHeight, li);
|
||||
data[it->second].second.interpret(oe, gdi, par, li);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -307,8 +307,7 @@ public:
|
||||
void save(xmlparser &xml, const oEvent *oe) const;
|
||||
void load(const xmlobject &xDef);
|
||||
|
||||
void interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par,
|
||||
int lineHeight, oListInfo &li) const;
|
||||
void interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par, oListInfo &li) const;
|
||||
|
||||
MetaList &setListName(const wstring &title) {listName = title; return *this;}
|
||||
|
||||
@ -424,8 +423,7 @@ public:
|
||||
|
||||
void synchronizeTo(MetaListContainer &dst) const;
|
||||
|
||||
bool interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par,
|
||||
int lineHeight, oListInfo &li) const;
|
||||
bool interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par, oListInfo &li) const;
|
||||
|
||||
void enumerateLists(vector< pair<wstring, pair<string, wstring> > > &out) const;
|
||||
};
|
||||
|
||||
@ -54,6 +54,59 @@ oBase::oBase(oEvent *poe) {
|
||||
localObject = false;
|
||||
}
|
||||
|
||||
oBase::oBase(const oBase &in) {
|
||||
Removed = in.Removed;
|
||||
oe = in.oe;
|
||||
Id = in.Id;
|
||||
changed = false;
|
||||
counter = in.counter;
|
||||
Modified.update();
|
||||
correctionNeeded = in.correctionNeeded;
|
||||
localObject = in.localObject;
|
||||
implicitlyAdded = in.implicitlyAdded;
|
||||
addedToEvent = in.addedToEvent;
|
||||
sqlUpdated = in.sqlUpdated;
|
||||
localObject = in.localObject;
|
||||
transientChanged = in.transientChanged;
|
||||
}
|
||||
|
||||
oBase::oBase(oBase &&in) {
|
||||
Removed = in.Removed;
|
||||
oe = in.oe;
|
||||
Id = in.Id;
|
||||
changed = false;
|
||||
counter = in.counter;
|
||||
Modified.update();
|
||||
correctionNeeded = in.correctionNeeded;
|
||||
localObject = in.localObject;
|
||||
implicitlyAdded = in.implicitlyAdded;
|
||||
addedToEvent = in.addedToEvent;
|
||||
sqlUpdated = in.sqlUpdated;
|
||||
localObject = in.localObject;
|
||||
transientChanged = in.transientChanged;
|
||||
if (in.myReference) {
|
||||
myReference.swap(in.myReference);
|
||||
myReference->ref = this;
|
||||
}
|
||||
}
|
||||
|
||||
const oBase &oBase::operator=(const oBase &in) {
|
||||
Removed = in.Removed;
|
||||
oe = in.oe;
|
||||
Id = in.Id;
|
||||
changed = false;
|
||||
counter = in.counter;
|
||||
Modified.update();
|
||||
correctionNeeded = in.correctionNeeded;
|
||||
localObject = in.localObject;
|
||||
implicitlyAdded = in.implicitlyAdded;
|
||||
addedToEvent = in.addedToEvent;
|
||||
sqlUpdated = in.sqlUpdated;
|
||||
localObject = in.localObject;
|
||||
transientChanged = in.transientChanged;
|
||||
return *this;
|
||||
}
|
||||
|
||||
oBase::~oBase(){
|
||||
if (myReference)
|
||||
myReference->ref = nullptr;
|
||||
@ -64,6 +117,7 @@ void oBase::remove() {
|
||||
myReference->ref = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool oBase::synchronize(bool writeOnly)
|
||||
{
|
||||
if (oe && (changed || transientChanged)) {
|
||||
|
||||
26
code/oBase.h
26
code/oBase.h
@ -65,21 +65,19 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
// Changed in client, not yet sent to server
|
||||
bool changed;
|
||||
// Changed in client, silent mode, should not be sent to server
|
||||
bool transientChanged;
|
||||
|
||||
bool localObject;
|
||||
const static unsigned long long BaseGenStringFlag = 1ull << 63;
|
||||
const static unsigned long long Base36StringFlag = 1ull << 62;
|
||||
const static unsigned long long ExtStringMask = ~(BaseGenStringFlag|Base36StringFlag);
|
||||
shared_ptr<oBaseReference> myReference;
|
||||
|
||||
protected:
|
||||
int Id;
|
||||
TimeStamp Modified;
|
||||
string sqlUpdated; //SQL TIMESTAMP
|
||||
|
||||
private:
|
||||
const static unsigned long long BaseGenStringFlag = 1ull << 63;
|
||||
const static unsigned long long Base36StringFlag = 1ull << 62;
|
||||
const static unsigned long long ExtStringMask = ~(BaseGenStringFlag | Base36StringFlag);
|
||||
shared_ptr<oBaseReference> myReference;
|
||||
|
||||
protected:
|
||||
int counter;
|
||||
oEvent *oe;
|
||||
bool Removed;
|
||||
@ -93,6 +91,11 @@ private:
|
||||
|
||||
bool implicitlyAdded = false;
|
||||
bool addedToEvent = false;
|
||||
// Changed in client, not yet sent to server
|
||||
bool changed;
|
||||
// Changed in client, silent mode, should not be sent to server
|
||||
bool transientChanged;
|
||||
bool localObject;
|
||||
|
||||
protected:
|
||||
|
||||
@ -186,6 +189,9 @@ public:
|
||||
static __int64 converExtIdentifierString(const wstring &str);
|
||||
|
||||
oBase(oEvent *poe);
|
||||
oBase(const oBase &in);
|
||||
oBase(oBase &&in);
|
||||
const oBase &operator=(const oBase &in);
|
||||
virtual ~oBase();
|
||||
|
||||
friend class RunnerDB;
|
||||
|
||||
@ -656,11 +656,14 @@ void oClub::generateInvoice(gdioutput &gdi, int &toPay, int &hasPaid,
|
||||
data.resPos = gdi.scaleLength(550);
|
||||
|
||||
gdi.addString("", ys, xs+data.adrPos, boldHuge, "FAKTURA");
|
||||
if (number>0)
|
||||
gdi.addStringUT(ys+lh*3, xs+data.adrPos, fontMedium, lang.tl("Faktura nr")+ L": " + itow(number));
|
||||
if (number > 0) {
|
||||
gdi.addStringUT(ys + lh * 3, xs + data.adrPos, fontMedium, lang.tl("Faktura nr") + L": " + itow(number));
|
||||
gdi.addStringUT(ys + lh * 4, xs + data.adrPos, fontMedium, getInvoiceDate(*oe));
|
||||
}
|
||||
|
||||
int &yp = data.yp;
|
||||
|
||||
yp = ys+lh;
|
||||
yp = ys+lh * 2;
|
||||
wstring ostreet = oe->getDI().getString("Street");
|
||||
wstring oaddress = oe->getDI().getString("Address");
|
||||
wstring oco = oe->getDI().getString("CareOf");
|
||||
@ -684,7 +687,7 @@ void oClub::generateInvoice(gdioutput &gdi, int &toPay, int &hasPaid,
|
||||
wstring city = getDCI().getString("ZIP") + L" " + getDCI().getString("City");
|
||||
wstring country = getDCI().getString("Country");
|
||||
|
||||
int ayp = ys + 122;
|
||||
int ayp = ys + gdi.scaleLength(122);
|
||||
|
||||
const int absX = oe->getPropertyInt("addressxpos", 125);
|
||||
int absY = oe->getPropertyInt("addressypos", 50);
|
||||
@ -706,7 +709,7 @@ void oClub::generateInvoice(gdioutput &gdi, int &toPay, int &hasPaid,
|
||||
if (!country.empty())
|
||||
gdi.addStringUT(ayp, xs+data.adrPos, fontMedium, country).setAbsPrintPos(absX,absY), ayp+=lh, absY+=absYL;
|
||||
|
||||
yp = ayp+30;
|
||||
yp = ayp+gdi.scaleLength(36);
|
||||
|
||||
gdi.addString("", yp, xs, boldSmall, "Deltagare");
|
||||
gdi.addString("", yp, xs+data.clsPos, boldSmall, "Klass");
|
||||
@ -1148,3 +1151,17 @@ bool oClub::operator<(const oClub &c) const {
|
||||
name.c_str(), name.length(),
|
||||
c.name.c_str(), c.name.length()) == CSTR_LESS_THAN;
|
||||
}
|
||||
|
||||
wstring oClub::getInvoiceDate(oEvent &oe) {
|
||||
wstring invoiceDate = oe.getDCI().getDate("InvoiceDate");
|
||||
int invoiceDateI = oe.getDCI().getInt("InvoiceDate");
|
||||
if (invoiceDateI == 0) {
|
||||
invoiceDate = getLocalDate();
|
||||
setInvoiceDate(oe, invoiceDate);
|
||||
}
|
||||
return invoiceDate;
|
||||
}
|
||||
|
||||
void oClub::setInvoiceDate(oEvent &oe, const wstring &id) {
|
||||
oe.getDI().setDate("InvoiceDate", id);
|
||||
}
|
||||
|
||||
@ -147,10 +147,11 @@ public:
|
||||
static void assignInvoiceNumber(oEvent &oe, bool reset);
|
||||
|
||||
static int getFirstInvoiceNumber(oEvent &oe);
|
||||
static wstring getInvoiceDate(oEvent &oe);
|
||||
static void setInvoiceDate(oEvent &oe, const wstring &id);
|
||||
|
||||
static void definedPayModes(oEvent &oe, map<int, wstring> &definedPayModes);
|
||||
|
||||
|
||||
/** Remove all clubs from a competion (and all belong to club relations)*/
|
||||
static void clearClubs(oEvent &oe);
|
||||
|
||||
|
||||
@ -249,7 +249,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
||||
ZeroTime=st.wHour*3600;
|
||||
oe=this;
|
||||
|
||||
runnerDB = new RunnerDB(this);
|
||||
runnerDB = make_shared<RunnerDB>(this);
|
||||
meosFeatures = new MeOSFeatures();
|
||||
openFileLock = new MeOSFileLock();
|
||||
|
||||
@ -342,6 +342,8 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
||||
oEventData->addVariableInt("LongTimes", oDataContainer::oIS8U, "Långa tider");
|
||||
oEventData->addVariableString("PayModes", "Betalsätt");
|
||||
oEventData->addVariableInt("TransferFlags", oDataContainer::oIS32, "Överföring");
|
||||
oEventData->addVariableDate("InvoiceDate", "Fakturadatum");
|
||||
|
||||
oEventData->initData(this, dataSize);
|
||||
|
||||
oClubData=new oDataContainer(oClub::dataSize);
|
||||
@ -520,9 +522,8 @@ oEvent::~oEvent()
|
||||
{
|
||||
//Clean up things in the right order.
|
||||
clear();
|
||||
delete runnerDB;
|
||||
runnerDB.reset();
|
||||
delete meosFeatures;
|
||||
runnerDB = 0;
|
||||
meosFeatures = 0;
|
||||
|
||||
delete oEventData;
|
||||
@ -1595,6 +1596,17 @@ void oEvent::updateRunnerDatabase(pRunner r, map<int, int> &clubIdMap)
|
||||
runnerDB->updateAdd(*r, clubIdMap);
|
||||
}
|
||||
|
||||
void oEvent::backupRunnerDatabase() {
|
||||
if (!runnerDBCopy)
|
||||
runnerDBCopy = make_shared<RunnerDB>(*runnerDB);
|
||||
}
|
||||
|
||||
void oEvent::restoreRunnerDatabase() {
|
||||
if (runnerDBCopy && *runnerDB != *runnerDBCopy) {
|
||||
runnerDB = make_shared<RunnerDB>(*runnerDBCopy);
|
||||
}
|
||||
}
|
||||
|
||||
pCourse oEvent::addCourse(const wstring &pname, int plengh, int id) {
|
||||
oCourse c(this, id);
|
||||
c.Length = plengh;
|
||||
@ -2181,6 +2193,7 @@ void oEvent::setDate(const wstring &m, bool manualSet)
|
||||
throw meosException(L"Felaktigt datumformat 'X' (Använd ÅÅÅÅ-MM-DD).#" + m);
|
||||
wstring nDate = formatDate(d, true);
|
||||
if (Date != nDate) {
|
||||
Date = nDate;
|
||||
if (manualSet)
|
||||
setFlag(TransferFlags::FlagManualDateTime, true);
|
||||
updateChanged();
|
||||
@ -2210,7 +2223,7 @@ const wstring &oEvent::getTimeZoneString() const {
|
||||
|
||||
wstring oEvent::getAbsDateTimeISO(DWORD time, bool includeDate, bool useGMT) const
|
||||
{
|
||||
DWORD t = ZeroTime + time;
|
||||
int t = ZeroTime + time;
|
||||
wstring dateS, timeS;
|
||||
if (int(t)<0) {
|
||||
dateS = L"2000-01-01";
|
||||
@ -2888,7 +2901,7 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
||||
// Get a set with unknown runner id:s
|
||||
set<int> statUnknown;
|
||||
for (oRunnerList::const_iterator itr=Runners.begin(); itr != Runners.end(); ++itr) {
|
||||
if (itr->tStatus == StatusUnknown && !(itr->skip() || itr->needNoCard())) {
|
||||
if (!itr->hasFinished() && !(itr->skip() || itr->needNoCard())) {
|
||||
statUnknown.insert(itr->getId());
|
||||
}
|
||||
}
|
||||
@ -2959,7 +2972,7 @@ void oEvent::generateInForestList(gdioutput &gdi, GUICALLBACK cb, GUICALLBACK cb
|
||||
if (it->skip() || it->needNoCard())
|
||||
continue;
|
||||
|
||||
if (it->tStatus == StatusUnknown) {
|
||||
if (!it->hasFinished()) {
|
||||
|
||||
if (id != it->getClassId(true)) {
|
||||
if (nr>0) {
|
||||
@ -5181,7 +5194,7 @@ void oEvent::generateTestCompetition(int nClasses, int nRunners,
|
||||
nRunners-=nRInClass;
|
||||
if (k%5!=5) {
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(cls->getId(), 0, getRelativeTime(start), 10, 3));
|
||||
spec.emplace_back(cls->getId(), 0, getRelativeTime(start), 10, 3, VacantPosition::Mixed);
|
||||
drawList(spec, DrawMethod::MeOS, 1, oEvent::DrawType::DrawAll);
|
||||
}
|
||||
else
|
||||
@ -5203,7 +5216,7 @@ void oEvent::generateTestCompetition(int nClasses, int nRunners,
|
||||
|
||||
if ( cls->getStartType(0)==STDrawn ) {
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(cls->getId(), 0, getRelativeTime(start), 20, 3));
|
||||
spec.emplace_back(cls->getId(), 0, getRelativeTime(start), 20, 3, VacantPosition::Mixed);
|
||||
drawList(spec, DrawMethod::MeOS, 1, DrawType::DrawAll);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +263,9 @@ protected:
|
||||
oRunnerList Runners;
|
||||
intkeymap<pRunner> runnerById;
|
||||
|
||||
RunnerDB *runnerDB;
|
||||
shared_ptr<RunnerDB> runnerDB;
|
||||
shared_ptr<RunnerDB> runnerDBCopy;
|
||||
|
||||
MeOSFeatures *meosFeatures;
|
||||
|
||||
oCardList Cards;
|
||||
@ -296,35 +298,6 @@ protected:
|
||||
SqlUpdated sqlPunches;
|
||||
SqlUpdated sqlTeams;
|
||||
|
||||
/*
|
||||
string sqlUpdateRunners;
|
||||
string sqlUpdateClasses;
|
||||
string sqlUpdateCourses;
|
||||
string sqlUpdateControls;
|
||||
string sqlUpdateClubs;
|
||||
string sqlUpdateCards;
|
||||
string sqlUpdatePunches;
|
||||
string sqlUpdateTeams;
|
||||
|
||||
int sqlCounterRunners;
|
||||
int sqlCounterClasses;
|
||||
int sqlCounterCourses;
|
||||
int sqlCounterControls;
|
||||
int sqlCounterClubs;
|
||||
int sqlCounterCards;
|
||||
int sqlCounterPunches;
|
||||
int sqlCounterTeams;
|
||||
|
||||
bool sqlChangedRunners;
|
||||
bool sqlChangedClasses;
|
||||
bool sqlChangedCourses;
|
||||
bool sqlChangedControls;
|
||||
bool sqlChangedClubs;
|
||||
bool sqlChangedCards;
|
||||
bool sqlChangedPunches;
|
||||
bool sqlChangedTeams;
|
||||
*/
|
||||
|
||||
bool needReEvaluate();
|
||||
|
||||
DirectSocket *directSocket;
|
||||
@ -496,6 +469,13 @@ public:
|
||||
DrawAll, RemainingBefore, RemainingAfter,
|
||||
};
|
||||
|
||||
/** Where to put vacancies */
|
||||
enum class VacantPosition {
|
||||
Mixed = 0,
|
||||
First = 1,
|
||||
Last = 2,
|
||||
};
|
||||
|
||||
/** Drawing algorithm. */
|
||||
enum class DrawMethod {
|
||||
NOMethod = -1,
|
||||
@ -553,9 +533,11 @@ public:
|
||||
void getExtraLines(const char *attrib, vector<pair<wstring, int> > &lines) const;
|
||||
|
||||
RunnerDB &getRunnerDatabase() const {return *runnerDB;}
|
||||
void backupRunnerDatabase();
|
||||
void restoreRunnerDatabase();
|
||||
|
||||
MeOSFeatures &getMeOSFeatures() const {return *meosFeatures;}
|
||||
void getDBRunnersInEvent(intkeymap<pClass, __int64> &runners) const;
|
||||
void getDBRunnersInEvent(intkeymap<int, __int64> &runners) const;
|
||||
MetaListContainer &getListContainer() const;
|
||||
wstring getNameId(int id) const;
|
||||
const wstring &getFileNameFromId(int id) const;
|
||||
@ -607,8 +589,10 @@ public:
|
||||
|
||||
// Automatic draw of all classes
|
||||
void automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
||||
const wstring &minIntervall, const wstring &vacances,
|
||||
bool lateBefore, bool allowNeighbourSameCourse, DrawMethod method, int pairSize);
|
||||
const wstring &minIntervall,
|
||||
const wstring &vacances, VacantPosition vp,
|
||||
bool lateBefore, bool allowNeighbourSameCourse,
|
||||
DrawMethod method, int pairSize);
|
||||
|
||||
// Restore a backup by renamning the file to .meos
|
||||
void restoreBackup();
|
||||
@ -728,10 +712,10 @@ public:
|
||||
|
||||
void generateList(gdioutput &gdi, bool reEvaluate, const oListInfo &li, bool updateScrollBars);
|
||||
|
||||
void generateListInfo(oListParam &par, int lineHeight, oListInfo &li);
|
||||
void generateListInfo(vector<oListParam> &par, int lineHeight, oListInfo &li);
|
||||
void generateListInfo(oListParam &par, oListInfo &li);
|
||||
void generateListInfo(vector<oListParam> &par, oListInfo &li);
|
||||
void generateListInfo(EStdListType lt, const gdioutput &gdi, int classId, oListInfo &li);
|
||||
void generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li, const wstring &name);
|
||||
void generateListInfoAux(oListParam &par, oListInfo &li, const wstring &name);
|
||||
|
||||
/** Format a string for a list. Returns true of output is not empty*/
|
||||
const wstring &formatListString(const oPrintPost &pp, const oListParam &par,
|
||||
|
||||
@ -212,6 +212,7 @@ namespace {
|
||||
void drawMeOSMethod(vector<pRunner> &runners) {
|
||||
if (runners.empty())
|
||||
return;
|
||||
|
||||
map<int, vector<pRunner>> runnersPerClub;
|
||||
for (pRunner r : runners)
|
||||
runnersPerClub[r->getClubId()].push_back(r);
|
||||
@ -960,7 +961,7 @@ void oEvent::drawRemaining(DrawMethod method, bool placeAfter)
|
||||
|
||||
for (oClassList::iterator it = Classes.begin(); it != Classes.end(); ++it) {
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(it->getId(), 0, 0, 0, 0));
|
||||
spec.emplace_back(it->getId(), 0, 0, 0, 0, VacantPosition::Mixed);
|
||||
|
||||
drawList(spec, method, 1, drawType);
|
||||
}
|
||||
@ -1120,6 +1121,21 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
||||
if (gdibase.isTest())
|
||||
InitRanom(0,0);
|
||||
|
||||
|
||||
vector<pRunner> vacant;
|
||||
VacantPosition vp = spec[0].vacantPosition;
|
||||
if (vp != VacantPosition::Mixed) {
|
||||
// Move vacants to a dedicated container
|
||||
for (size_t k = 0; k < runners.size(); k++) {
|
||||
if (runners[k]->isVacant()) {
|
||||
vacant.push_back(runners[k]);
|
||||
swap(runners[k], runners.back());
|
||||
runners.pop_back();
|
||||
k--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (method) {
|
||||
case DrawMethod::SOFT:
|
||||
drawSOFTMethod(runners, true);
|
||||
@ -1128,12 +1144,28 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
||||
drawMeOSMethod(runners);
|
||||
break;
|
||||
case DrawMethod::Random:
|
||||
permute(stimes);
|
||||
{
|
||||
vector<int> pv(runners.size());
|
||||
for (size_t k = 0; k < pv.size(); k++)
|
||||
pv[k] = k;
|
||||
permute(pv);
|
||||
vector<pRunner> r2(runners.size());
|
||||
for (size_t k = 0; k < pv.size(); k++)
|
||||
r2[k] = runners[pv[k]];
|
||||
r2.swap(runners);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 0;
|
||||
}
|
||||
|
||||
if (vp == VacantPosition::First) {
|
||||
runners.insert(runners.begin(), vacant.begin(), vacant.end());
|
||||
}
|
||||
else if (vp == VacantPosition::Last) {
|
||||
runners.insert(runners.end(), vacant.begin(), vacant.end());
|
||||
}
|
||||
|
||||
int minStartNo = Runners.size();
|
||||
vector<pair<int, int>> newStartNo;
|
||||
for(unsigned k=0;k<stimes.size(); k++) {
|
||||
@ -1323,10 +1355,15 @@ void oEvent::drawListClumped(int ClassID, int FirstStart, int Interval, int Vaca
|
||||
delete[] stimes;
|
||||
}
|
||||
|
||||
void oEvent::automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
||||
const wstring &minIntervall, const wstring &vacances,
|
||||
bool lateBefore, bool allowNeighbourSameCourse, DrawMethod method, int pairSize)
|
||||
{
|
||||
void oEvent::automaticDrawAll(gdioutput &gdi,
|
||||
const wstring &firstStart,
|
||||
const wstring &minIntervall,
|
||||
const wstring &vacances,
|
||||
VacantPosition vp,
|
||||
bool lateBefore,
|
||||
bool allowNeighbourSameCourse,
|
||||
DrawMethod method,
|
||||
int pairSize) {
|
||||
gdi.refresh();
|
||||
const int leg = 0;
|
||||
const double extraFactor = 0.0;
|
||||
@ -1350,7 +1387,7 @@ void oEvent::automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
||||
if (it->isRemoved())
|
||||
continue;
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(it->getId(), 0, iFirstStart, 0, 0));
|
||||
spec.emplace_back(it->getId(), 0, iFirstStart, 0, 0, vp);
|
||||
oe->drawList(spec, DrawMethod::Random, 1, DrawType::DrawAll);
|
||||
}
|
||||
return;
|
||||
@ -1505,9 +1542,9 @@ void oEvent::automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
||||
|
||||
gdi.addString("", 0, L"Lottar: X#" + getClass(ci.classId)->getName());
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(ci.classId, leg,
|
||||
di.firstStart + di.baseInterval * ci.firstStart,
|
||||
di.baseInterval * ci.interval, ci.nVacant));
|
||||
spec.emplace_back(ci.classId, leg,
|
||||
di.firstStart + di.baseInterval * ci.firstStart,
|
||||
di.baseInterval * ci.interval, ci.nVacant, vp);
|
||||
|
||||
drawList(spec, method, pairSize, DrawType::DrawAll);
|
||||
gdi.scrollToBottom();
|
||||
@ -1526,7 +1563,7 @@ void oEvent::automaticDrawAll(gdioutput &gdi, const wstring &firstStart,
|
||||
gdi.addStringUT(0, lang.tl(L"Lottar efteranmälda: ") + it->getName());
|
||||
|
||||
vector<ClassDrawSpecification> spec;
|
||||
spec.push_back(ClassDrawSpecification(it->getId(), leg, 0, 0, 0));
|
||||
spec.emplace_back(it->getId(), leg, 0, 0, 0, vp);
|
||||
drawList(spec, method, 1, lateBefore ? DrawType::RemainingBefore : DrawType::RemainingAfter);
|
||||
|
||||
gdi.scrollToBottom();
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#include "oEvent.h"
|
||||
|
||||
struct ClassDrawSpecification {
|
||||
int classID;
|
||||
int leg;
|
||||
@ -29,11 +31,11 @@ struct ClassDrawSpecification {
|
||||
mutable int interval;
|
||||
int vacances;
|
||||
mutable int ntimes;
|
||||
|
||||
ClassDrawSpecification() : ntimes(0) {}
|
||||
ClassDrawSpecification(int classID, int leg, int firstStart, int interval, int vacances) :
|
||||
oEvent::VacantPosition vacantPosition;
|
||||
ClassDrawSpecification() : ntimes(0), vacantPosition(oEvent::VacantPosition::Mixed) {}
|
||||
ClassDrawSpecification(int classID, int leg, int firstStart, int interval, int vacances, oEvent::VacantPosition vp) :
|
||||
classID(classID), leg(leg), firstStart(firstStart),
|
||||
interval(interval), vacances(vacances), ntimes(0) {}
|
||||
interval(interval), vacances(vacances), ntimes(0), vacantPosition(vp) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ template<typename T, typename Apply> void calculatePlace(vector<ResultCalcData<T
|
||||
vPlace = 0;
|
||||
cScore = 0;
|
||||
pClass cls = it.dst->getClassRef(true);
|
||||
useResults = cls ? cls->getNoTiming() == false : true;
|
||||
useResults = true;// cls ? cls->getNoTiming() == false : true;
|
||||
invalidClass = cls ? cls->getClassStatus() != oClass::Normal : false;
|
||||
}
|
||||
|
||||
|
||||
@ -51,9 +51,17 @@
|
||||
#include <fcntl.h>
|
||||
#include "localizer.h"
|
||||
#include "iof30interface.h"
|
||||
#include "gdiconstants.h"
|
||||
|
||||
#include "meosdb/sqltypes.h"
|
||||
|
||||
FlowOperation importFilterGUI(oEvent *oe,
|
||||
gdioutput & gdi,
|
||||
const set<int>& stages,
|
||||
const vector<string> &idProviders,
|
||||
set<int> & filter,
|
||||
string &preferredIdProvider);
|
||||
|
||||
string conv_is(int i)
|
||||
{
|
||||
char bf[256];
|
||||
@ -1276,6 +1284,22 @@ void oEvent::importXML_IOF_Data(const wstring &clubfile,
|
||||
|
||||
if (xo && xo.getAttrib("iofVersion")) {
|
||||
IOF30Interface reader(this, false);
|
||||
|
||||
vector<string> idProviders;
|
||||
reader.prescanCompetitorList(xo);
|
||||
reader.getIdTypes(idProviders);
|
||||
|
||||
if (idProviders.size() > 1) {
|
||||
string preferredIdProvider;
|
||||
set<int> dmy;
|
||||
FlowOperation op = importFilterGUI(oe, gdibase,
|
||||
{}, idProviders,
|
||||
dmy, preferredIdProvider);
|
||||
if (op != FlowContinue)
|
||||
return;
|
||||
|
||||
reader.setPreferredIdType(preferredIdProvider);
|
||||
}
|
||||
reader.readCompetitorList(gdibase, xo, personCount);
|
||||
}
|
||||
else {
|
||||
@ -1306,8 +1330,6 @@ void oEvent::importXML_IOF_Data(const wstring &clubfile,
|
||||
gdibase.addString("", 0, "Uppdaterar serverns databas...");
|
||||
gdibase.refresh();
|
||||
|
||||
//msUploadRunnerDB(this);
|
||||
|
||||
OpFailStatus stat = (OpFailStatus)msUploadRunnerDB(this);
|
||||
|
||||
if (stat == opStatusFail) {
|
||||
|
||||
@ -471,7 +471,6 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|
||||
}
|
||||
}
|
||||
|
||||
int width = minSize;
|
||||
vector<int> row(pps.size(), 0);
|
||||
vector<wstring> samples(pps.size());
|
||||
wstring totWord = L"";
|
||||
@ -527,11 +526,8 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
|
||||
|
||||
wstring dummy;
|
||||
int w = totMeasure.measure(gdi, font, fontFace, dummy);
|
||||
w = max(w, minSize);
|
||||
if (large)
|
||||
return w + 5;
|
||||
else
|
||||
return w + 15;
|
||||
w = max(w, gdi.scaleLength(minSize));
|
||||
return int(0.5 + (w + (large ? 5 : 15))/gdi.getScale());
|
||||
}
|
||||
|
||||
const wstring & oEvent::formatListString(EPostType type, const pRunner r) const
|
||||
@ -2416,7 +2412,6 @@ bool oEvent::formatPrintPost(const list<oPrintPost> &ppli, PrintPostInfo &ppi,
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (pp.color != colorDefault)
|
||||
ti->setColor(pp.color);
|
||||
}
|
||||
@ -3719,7 +3714,7 @@ void oEvent::generateListInfo(EStdListType lt, const gdioutput &gdi, int classId
|
||||
|
||||
par.listCode=lt;
|
||||
|
||||
generateListInfo(par, gdi.getLineHeight(), li);
|
||||
generateListInfo(par, li);
|
||||
}
|
||||
|
||||
int openRunnerTeamCB(gdioutput *gdi, int type, void *data);
|
||||
@ -3822,15 +3817,14 @@ void oListInfo::setCallback(GUICALLBACK cb) {
|
||||
}
|
||||
}
|
||||
|
||||
void oEvent::generateListInfo(oListParam &par, int lineHeight, oListInfo &li) {
|
||||
void oEvent::generateListInfo(oListParam &par, oListInfo &li) {
|
||||
vector<oListParam> parV(1, par);
|
||||
generateListInfo(parV, lineHeight, li);
|
||||
generateListInfo(parV, li);
|
||||
}
|
||||
|
||||
void oEvent::generateListInfo(vector<oListParam> &par, int lineHeight, oListInfo &li) {
|
||||
void oEvent::generateListInfo(vector<oListParam> &par, oListInfo &li) {
|
||||
li.getParam().sourceParam = -1;// Reset source
|
||||
loadGeneralResults(false, false);
|
||||
lineHeight = 14;
|
||||
for (size_t k = 0; k < par.size(); k++) {
|
||||
par[k].cb = 0;
|
||||
}
|
||||
@ -3839,7 +3833,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, int lineHeight, oListInfo
|
||||
getListTypes(listMap, false);
|
||||
|
||||
if (par.size() == 1) {
|
||||
generateListInfoAux(par[0], lineHeight, li, listMap[par[0].listCode].Name);
|
||||
generateListInfoAux(par[0], li, listMap[par[0].listCode].Name);
|
||||
set<int> used;
|
||||
// Add linked lists
|
||||
oListParam *cPar = &par[0];
|
||||
@ -3851,7 +3845,7 @@ void oEvent::generateListInfo(vector<oListParam> &par, int lineHeight, oListInfo
|
||||
oListParam &nextPar = oe->getListContainer().getParam(cPar->nextList-1);
|
||||
li.next.push_back(oListInfo());
|
||||
nextPar.cb = 0;
|
||||
generateListInfoAux(nextPar, lineHeight, li.next.back(), L"");
|
||||
generateListInfoAux(nextPar, li.next.back(), L"");
|
||||
cPar = &nextPar;
|
||||
}
|
||||
}
|
||||
@ -3860,14 +3854,14 @@ void oEvent::generateListInfo(vector<oListParam> &par, int lineHeight, oListInfo
|
||||
if (k > 0) {
|
||||
li.next.push_back(oListInfo());
|
||||
}
|
||||
generateListInfoAux(par[k], lineHeight, k == 0 ? li : li.next.back(),
|
||||
generateListInfoAux(par[k], k == 0 ? li : li.next.back(),
|
||||
li.Name = listMap[par[0].listCode].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li, const wstring &name) {
|
||||
const int lh=lineHeight;
|
||||
void oEvent::generateListInfoAux(oListParam &par, oListInfo &li, const wstring &name) {
|
||||
const int lh=14;
|
||||
const int vspace=lh/2;
|
||||
int bib;
|
||||
pair<int, bool> ln;
|
||||
@ -3896,7 +3890,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
|
||||
switch (lt) {
|
||||
case EStdStartList: {
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Startlista - %s")), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Startlista - %s", true)), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpDate, L"", normalText, 0, 25));
|
||||
|
||||
int bib = 0;
|
||||
@ -3926,7 +3920,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
}
|
||||
|
||||
case EStdClubStartList: {
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Klubbstartlista - %s")), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Klubbstartlista - %s", true)), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpDate, L"", normalText, 0, 25));
|
||||
|
||||
if (hasBib(true, true)) {
|
||||
@ -3964,7 +3958,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
}
|
||||
|
||||
case EStdClubResultList: {
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Klubbresultatlista - %s")), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Klubbresultatlista - %s", true)), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpDate, L"", normalText, 0, 25));
|
||||
|
||||
pos.add("class", li.getMaxCharWidth(this, par.selection, lClassName, L"", normalText));
|
||||
@ -3994,7 +3988,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
|
||||
case EStdRentedCard:
|
||||
{
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Hyrbricksrapport - %s")), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpName, makeDash(lang.tl(L"Hyrbricksrapport - %s", true)), boldLarge, 0,0));
|
||||
li.addHead(oPrintPost(lCmpDate, L"", normalText, 0, 25));
|
||||
|
||||
li.addListPost(oPrintPost(lTotalCounter, L"%s", normalText, 0, 0));
|
||||
@ -4334,7 +4328,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
mList.addToSubList(lRunnerName);
|
||||
mList.addToSubList(lRunnerCard).align(lClassStartName);
|
||||
|
||||
mList.interpret(this, gdibase, par, lh, li);
|
||||
mList.interpret(this, gdibase, par, li);
|
||||
}
|
||||
li.listType=li.EBaseTypeTeam;
|
||||
li.listSubType=li.EBaseTypeRunner;
|
||||
@ -4583,7 +4577,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
mList.setListType(li.EBaseTypeTeam);
|
||||
mList.setSortOrder(ClassStartTime);
|
||||
mList.addFilter(EFilterExcludeDNS);
|
||||
mList.interpret(this, gdibase, par, lh, li);
|
||||
mList.interpret(this, gdibase, par, li);
|
||||
break;
|
||||
}
|
||||
case EStdPatrolResultList:
|
||||
@ -4793,10 +4787,10 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
continue;
|
||||
par.setLegNumberCoded(out[k].second);
|
||||
if (k == 0)
|
||||
generateListInfo(par, lineHeight, li);
|
||||
generateListInfo(par, li);
|
||||
else {
|
||||
li.next.push_back(oListInfo());
|
||||
generateListInfo(par, lineHeight, li.next.back());
|
||||
generateListInfo(par, li.next.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4814,7 +4808,7 @@ void oEvent::generateListInfoAux(oListParam &par, int lineHeight, oListInfo &li,
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!getListContainer().interpret(this, gdibase, par, lineHeight, li))
|
||||
if (!getListContainer().interpret(this, gdibase, par, li))
|
||||
throw std::exception("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1557,6 +1557,8 @@ bool oRunner::evaluateCard(bool doApply, vector<int> & MissingPunches,
|
||||
*refStatus = StatusOutOfCompetition;
|
||||
else if (hasFlag(TransferFlags::FlagNoTiming))
|
||||
*refStatus = StatusNoTiming;
|
||||
else if (clz && clz->getNoTiming())
|
||||
*refStatus = StatusNoTiming;
|
||||
}
|
||||
// Adjust times on course, including finish time
|
||||
doAdjustTimes(course);
|
||||
@ -4128,6 +4130,11 @@ void oRunner::fillSpeakerObject(int leg, int courseControlId, int previousContro
|
||||
|
||||
getSplitTime(courseControlId, spk.status, spk.runningTime.time);
|
||||
|
||||
if (getStatus() == StatusNoTiming || getStatus() == StatusOutOfCompetition) {
|
||||
if (spk.status == StatusOK)
|
||||
spk.status = getStatus();
|
||||
}
|
||||
|
||||
if (courseControlId == oPunch::PunchFinish)
|
||||
spk.timeSinceChange = oe->getComputerTime() - FinishTime;
|
||||
else
|
||||
@ -4380,7 +4387,7 @@ void oEvent::analyseDNS(vector<pRunner> &unknown_dns, vector<pRunner> &known_dns
|
||||
|
||||
for (oRunnerList::iterator it = Runners.begin(); it!=Runners.end();++it) {
|
||||
if (!it->isRemoved() && !it->needNoCard()) {
|
||||
if (it->getStatus() == StatusUnknown)
|
||||
if (!it->hasFinished())
|
||||
stUnknown.push_back(&*it);
|
||||
else if (it->getStatus() == StatusDNS) {
|
||||
stDNS.push_back(&*it);
|
||||
@ -5909,14 +5916,14 @@ void oRunner::setInputData(const oRunner &r) {
|
||||
}
|
||||
}
|
||||
|
||||
void oEvent::getDBRunnersInEvent(intkeymap<pClass, __int64> &runners) const {
|
||||
void oEvent::getDBRunnersInEvent(intkeymap<int, __int64> &runners) const {
|
||||
runners.clear();
|
||||
for (oRunnerList::const_iterator it = Runners.begin(); it != Runners.end(); ++it) {
|
||||
if (it->isRemoved())
|
||||
continue;
|
||||
__int64 id = it->getExtIdentifier();
|
||||
if (id != 0)
|
||||
runners.insert(id, it->Class);
|
||||
runners.insert(id, it->getId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -6338,6 +6345,7 @@ void oAbstractRunner::getInputResults(vector<RunnerStatus> &st,
|
||||
|
||||
// Add current result to input result. Only use when transferring to next stage
|
||||
void oAbstractRunner::addToInputResult(int thisStageNo, const oAbstractRunner *src) {
|
||||
thisStageNo = max(thisStageNo, 0);
|
||||
int p = src->getPlace();
|
||||
int rt = src->getRunningTime(true);
|
||||
RunnerStatus st = src->getStatusComputed();
|
||||
@ -6594,7 +6602,7 @@ int oRunner::getCheckTime() const {
|
||||
const pair<wstring, int> oRunner::getRaceInfo() {
|
||||
pair<wstring, int> res;
|
||||
RunnerStatus baseStatus = getStatus();
|
||||
if (baseStatus != StatusUnknown) {
|
||||
if (hasFinished()) {
|
||||
int p = getPlace();
|
||||
int rtComp = getRunningTime(true);
|
||||
int rtActual = getRunningTime(false);
|
||||
|
||||
@ -408,6 +408,7 @@ public:
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Sets the status. If updatePermanent is true, the stored start
|
||||
time is updated, otherwise the value is considered deduced.
|
||||
*/
|
||||
@ -646,7 +647,6 @@ protected:
|
||||
bool isHiredCard(int card) const;
|
||||
|
||||
public:
|
||||
|
||||
static const shared_ptr<Table> &getTable(oEvent *oe);
|
||||
|
||||
// Get the leg defineing parallel results for this runner (in a team)
|
||||
@ -655,6 +655,17 @@ public:
|
||||
// Returns true if there are radio control results, provided result calculation oEvent::ResultType::PreliminarySplitResults was invoked.
|
||||
bool hasOnCourseResult() const { return !tOnCourseResults.empty() || getFinishTime() > 0 || hasResult(); }
|
||||
|
||||
/** Return true if the race is completed (or definitely never will be started), e.g., not in forest*/
|
||||
bool hasFinished() const {
|
||||
if (tStatus == StatusUnknown)
|
||||
return false;
|
||||
else if (isPossibleResultStatus(tStatus)) {
|
||||
return Card || FinishTime > 0;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Returns a check time (or zero for no time). */
|
||||
int getCheckTime() const;
|
||||
|
||||
|
||||
@ -805,6 +805,7 @@ bool oTeam::compareSNO(const oTeam &a, const oTeam &b) {
|
||||
return a.Class->tSortIndex < b.Class->tSortIndex || (a.Class->tSortIndex == b.Class->tSortIndex && a.Class->Id < b.Class->Id);
|
||||
else return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
return CompareString(LOCALE_USER_DEFAULT, 0,
|
||||
@ -2382,8 +2383,9 @@ oTeam::TeamPlace &oTeam::getTeamPlace(int leg) const {
|
||||
if (size_t(leg) < tPlace.size())
|
||||
return tPlace[leg];
|
||||
|
||||
if (tComputedResults.empty())
|
||||
if (tComputedResults.empty() || tPlace.empty())
|
||||
tPlace.resize(1);
|
||||
|
||||
return tPlace[0];
|
||||
}
|
||||
|
||||
|
||||
@ -290,16 +290,18 @@ void pdfwriter::generatePDF(const gdioutput &gdi,
|
||||
string nt = gdi.toUTF8(info[k].ti.text);
|
||||
|
||||
if (info[k].ti.format & textRight) {
|
||||
float w = float(info[k].ti.xlimit) * scale*fontScale;
|
||||
float w = float(info[k].ti.xlimit) * scale;
|
||||
float sw = HPDF_Page_TextWidth(page, nt.c_str());
|
||||
float space = info[k].ti.xlimit > 0 ? 2 * HPDF_Page_GetCharSpace(page) : 0;
|
||||
//float space = info[k].ti.xlimit > 0 ? 2 * HPDF_Page_GetCharSpace(page) : 0;
|
||||
float space = info[k].ti.xlimit > 0 ? HPDF_Page_TextWidth(page, "-") : 0;
|
||||
|
||||
HPDF_Page_TextOut (page, info[k].xp + w - sw - space, h - info[k].yp,
|
||||
nt.c_str());
|
||||
}
|
||||
else if (info[k].ti.format & textCenter) {
|
||||
float w = float(info[k].ti.xlimit) * scale*fontScale;
|
||||
float w = float(info[k].ti.xlimit) * scale;
|
||||
float sw = HPDF_Page_TextWidth(page, nt.c_str());
|
||||
HPDF_Page_TextOut (page, info[k].xp + w - sw/2, h - info[k].yp,
|
||||
HPDF_Page_TextOut (page, info[k].xp + (w - sw) *0.5, h - info[k].yp,
|
||||
nt.c_str());
|
||||
}
|
||||
else {
|
||||
|
||||
@ -21,15 +21,18 @@ Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
|
||||
************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <thread>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
#include "oEvent.h"
|
||||
#include "xmlparser.h"
|
||||
#include <thread>
|
||||
|
||||
#include "restbed/restbed"
|
||||
#include "meosexception.h"
|
||||
#include "restserver.h"
|
||||
#include "infoserver.h"
|
||||
#include <chrono>
|
||||
|
||||
#include "oListInfo.h"
|
||||
#include "TabList.h"
|
||||
@ -376,6 +379,16 @@ void RestServer::computeInternal(oEvent &ref, shared_ptr<RestServer::EventReques
|
||||
string what = rq->parameters.find("lookup")->second;
|
||||
lookup(ref, what, rq->parameters, rq->answer);
|
||||
}
|
||||
else if (rq->parameters.count("difference")) {
|
||||
string what = rq->parameters.find("difference")->second;
|
||||
int id = -2;
|
||||
if (what == "zero")
|
||||
id = -1;
|
||||
else
|
||||
id = atoi(what.c_str());
|
||||
|
||||
difference(ref, id, rq->answer);
|
||||
}
|
||||
else if (rq->parameters.count("page") > 0) {
|
||||
string what = rq->parameters.find("page")->second;
|
||||
auto &writer = HTMLWriter::getWriter(HTMLWriter::TemplateType::Page, what);
|
||||
@ -424,7 +437,7 @@ void RestServer::computeInternal(oEvent &ref, shared_ptr<RestServer::EventReques
|
||||
|
||||
if (!res->second.second) {
|
||||
res->second.second = make_shared<oListInfo>();
|
||||
ref.generateListInfo(res->second.first, gdiPrint.getLineHeight(), *res->second.second);
|
||||
ref.generateListInfo(res->second.first, *res->second.second);
|
||||
}
|
||||
ref.generateList(gdiPrint, true, *res->second.second, false);
|
||||
wstring exportFile = getTempFile();
|
||||
@ -1100,7 +1113,7 @@ void RestServer::lookup(oEvent &oe, const string &what, const multimap<string, s
|
||||
xml.write("Card", r->getCardNo());
|
||||
xml.write("Status", {make_pair("code", itow(r->getStatusComputed()))}, r->getStatusS(true, true));
|
||||
xml.write("Start", r->getStartTimeS());
|
||||
if (r->getFinishTime() > 0) {
|
||||
if (r->getFinishTime() > 0 && r->getStatusComputed() != StatusNoTiming) {
|
||||
xml.write("Finish", r->getFinishTimeS());
|
||||
xml.write("RunningTime", r->getRunningTimeS(true));
|
||||
xml.write("Place", r->getPlaceS());
|
||||
@ -1112,7 +1125,9 @@ void RestServer::lookup(oEvent &oe, const string &what, const multimap<string, s
|
||||
if (cls)
|
||||
xml.write("Leg", cls->getLegNumber(r->getLegNumber()));
|
||||
}
|
||||
if ((r->getFinishTime() > 0 || r->getCard() != nullptr) && r->getCourse(false)) {
|
||||
if ((r->getFinishTime() > 0 || r->getCard() != nullptr) &&
|
||||
r->getCourse(false) &&
|
||||
r->getStatusComputed() != StatusNoTiming) {
|
||||
auto &sd = r->getSplitTimes(false);
|
||||
vector<int> after;
|
||||
r->getLegTimeAfter(after);
|
||||
@ -1343,6 +1358,10 @@ void RestServer::newEntry(oEvent &oe, const multimap<string, string> ¶m, str
|
||||
error = L"Anmälan måste hanteras manuellt";
|
||||
}
|
||||
|
||||
bool noTiming = false;
|
||||
if (param.count("notiming"))
|
||||
noTiming = true;
|
||||
|
||||
int cardNo = 0;
|
||||
if (param.count("card"))
|
||||
cardNo = atoi(param.find("card")->second.c_str());
|
||||
@ -1374,6 +1393,9 @@ void RestServer::newEntry(oEvent &oe, const multimap<string, string> ¶m, str
|
||||
}
|
||||
r->setFlag(oRunner::FlagAddedViaAPI, true);
|
||||
r->addClassDefaultFee(true);
|
||||
if (noTiming)
|
||||
r->setStatus(StatusNoTiming, true, oBase::ChangeType::Update, false);
|
||||
|
||||
r->synchronize();
|
||||
r->markClassChanged(-1);
|
||||
xml.write("Status", "OK");
|
||||
@ -1383,6 +1405,8 @@ void RestServer::newEntry(oEvent &oe, const multimap<string, string> ¶m, str
|
||||
}
|
||||
xml.write("Fee", rentCard, itow(r->getDCI().getInt("Fee") + max(cf, 0)));
|
||||
xml.write("Info", r->getClass(true) + L", " + r->getCompleteIdentification(false));
|
||||
if (r->getStatus() == StatusNoTiming)
|
||||
xml.write("NoTiming", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1413,3 +1437,131 @@ vector<pair<wstring, size_t>> RestServer::getPermissionsClass() {
|
||||
res.emplace_back(lang.tl("Med direktanmälan"), size_t(EntryPermissionClass::DirectEntry));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//constexpr int largePrime = 5000011;
|
||||
//constexpr int smallPrime = 101;
|
||||
|
||||
constexpr int largePrime = 5000011;
|
||||
constexpr int smallPrime = 101;
|
||||
constexpr int idOffset = 100;
|
||||
|
||||
int RestServer::InfoServerContainer::getNextInstanceId() {
|
||||
|
||||
int newInstanceId = (thisInstanceId - idOffset + instanceIncrementor) % (largePrime * smallPrime);
|
||||
return newInstanceId + idOffset;
|
||||
}
|
||||
|
||||
int RestServer::getNewInstanceId() {
|
||||
int limit = 10;
|
||||
if (isContainers.size() > 10) {
|
||||
isContainers.pop_back();
|
||||
}
|
||||
|
||||
set<int> usedBaseId;
|
||||
for (auto &c : isContainers) {
|
||||
int baseId = (c.nextInstanceId - idOffset) % smallPrime;
|
||||
usedBaseId.insert(baseId);
|
||||
OutputDebugString((L"used: " + itow(baseId) + L"\n").c_str());
|
||||
}
|
||||
if (!randGen) {
|
||||
random_device r;
|
||||
randGen = make_shared<default_random_engine>(r());
|
||||
}
|
||||
int first = (*randGen)() % smallPrime;
|
||||
int off = 1 + (*randGen)() % (smallPrime-1);
|
||||
for (int i = 0; i < smallPrime; i++) {
|
||||
int s = (first + i * off) % smallPrime;
|
||||
if (!usedBaseId.count(s)) {
|
||||
int id = s + smallPrime * ((*randGen)() % 32767) + idOffset;
|
||||
int f = smallPrime * ((113 + (*randGen)() % 32767) % (largePrime - 1) + 1);
|
||||
OutputDebugString((L"add: " + itow(s) + L", " + itow(f) + L"\n").c_str());
|
||||
|
||||
isContainers.emplace_front(id, f);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
throw meosException("No server instance found");
|
||||
}
|
||||
|
||||
xmlbuffer * RestServer::getMOPXML(oEvent &oe, int id, int &nextId) {
|
||||
for (auto it = isContainers.begin(); it != isContainers.end(); ++it) {
|
||||
auto &c = *it;
|
||||
if (c.thisInstanceId == id) {
|
||||
nextId = c.nextInstanceId;
|
||||
if (it != isContainers.begin())
|
||||
isContainers.splice(isContainers.begin(), isContainers, it);
|
||||
|
||||
return c.lastData.get();
|
||||
}
|
||||
else if (c.nextInstanceId == id) {
|
||||
if (it != isContainers.begin())
|
||||
isContainers.splice(isContainers.begin(), isContainers, it);
|
||||
|
||||
oe.autoSynchronizeLists(true);
|
||||
if (!c.cmpModel) {
|
||||
c.cmpModel = make_shared<InfoCompetition>(id);
|
||||
if (c.classes.empty()) {
|
||||
vector<pClass> classes;
|
||||
oe.getClasses(classes, false);
|
||||
for (pClass pc : classes) {
|
||||
if (!pc->isQualificationFinalBaseClass())
|
||||
c.classes.insert(pc->getId());
|
||||
}
|
||||
}
|
||||
if (c.controls.empty()) {
|
||||
vector<pControl> ctrl;
|
||||
vector<int> ids;
|
||||
oe.getControls(ctrl, true);
|
||||
for (size_t k = 0; k < ctrl.size(); k++) {
|
||||
if (ctrl[k]->isValidRadio()) {
|
||||
ctrl[k]->getCourseControls(ids);
|
||||
c.controls.insert(ids.begin(), ids.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.cmpModel->synchronize(oe, false, c.classes, c.controls, true);
|
||||
c.lastData = make_shared<xmlbuffer>();
|
||||
c.cmpModel->getDiffXML(*c.lastData);
|
||||
c.cmpModel->commitComplete();
|
||||
|
||||
if (c.lastData->size() == 0) {
|
||||
nextId = c.nextInstanceId;
|
||||
return c.lastData.get();
|
||||
}
|
||||
|
||||
c.thisInstanceId = id;
|
||||
nextId = c.nextInstanceId = c.getNextInstanceId();
|
||||
return c.lastData.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RestServer::difference(oEvent &oe, int id, string &answer) {
|
||||
string type;
|
||||
if (id == -1) {
|
||||
id = getNewInstanceId();
|
||||
}
|
||||
int nextId;
|
||||
xmlbuffer *bf = getMOPXML(oe, id, nextId);
|
||||
if (bf) {
|
||||
xmlparser mem;
|
||||
mem.openMemoryOutput(false);
|
||||
if (bf->isComplete())
|
||||
type = "MOPComplete";
|
||||
else
|
||||
type = "MOPDiff";
|
||||
|
||||
mem.startTag(type.c_str(), { L"xmlns", L"http://www.melin.nu/mop",
|
||||
L"nextdifference", itow(nextId)});
|
||||
bf->commitCopy(mem);
|
||||
mem.endTag();
|
||||
mem.getMemoryOutput(answer);
|
||||
}
|
||||
else {
|
||||
answer = "Error (MeOS): Unknown difference state. Use litteral 'zero' (?difference=zero) to get complete competition";
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,10 @@ Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
|
||||
#include <deque>
|
||||
#include <condition_variable>
|
||||
#include <tuple>
|
||||
#include <random>
|
||||
|
||||
class InfoCompetition;
|
||||
class xmlbuffer;
|
||||
|
||||
namespace restbed {
|
||||
class Service;
|
||||
@ -111,6 +115,29 @@ private:
|
||||
|
||||
string root;
|
||||
multimap<string, string> rootMap;
|
||||
|
||||
struct InfoServerContainer {
|
||||
//static int currentInstanceId;
|
||||
int getNextInstanceId();
|
||||
|
||||
const int instanceIncrementor;
|
||||
int thisInstanceId = -1;
|
||||
int nextInstanceId;
|
||||
shared_ptr<InfoCompetition> cmpModel;
|
||||
shared_ptr<xmlbuffer> lastData;
|
||||
set<int> classes;
|
||||
set<int> controls;
|
||||
|
||||
InfoServerContainer(int s, int e) : nextInstanceId(s), instanceIncrementor(e) {}
|
||||
};
|
||||
|
||||
shared_ptr<default_random_engine> randGen;
|
||||
list<InfoServerContainer> isContainers;
|
||||
int getNewInstanceId();
|
||||
xmlbuffer *getMOPXML(oEvent &oe, int id, int &nextId);
|
||||
|
||||
void difference(oEvent &oe, int id, string &answer);
|
||||
|
||||
public:
|
||||
|
||||
~RestServer();
|
||||
|
||||
@ -53,7 +53,7 @@ void SpeakerMonitor::setClassFilter(const set<int> &filter, const set<int> &cfil
|
||||
classFilter = filter;
|
||||
controlIdFilter = cfilter;
|
||||
oListInfo li;
|
||||
maxClassNameWidth = li.getMaxCharWidth(&oe, classFilter, lClassName, L"", normalText, false);
|
||||
maxClassNameWidth = oe.gdiBase().scaleLength(li.getMaxCharWidth(&oe, classFilter, lClassName, L"", normalText, false));
|
||||
}
|
||||
|
||||
void SpeakerMonitor::setLimits(int place, int num) {
|
||||
|
||||
@ -2428,7 +2428,7 @@ prefsLastExportTarget = Senaste exportmål
|
||||
prefsServiceRootMap = Standardfunktion för webbserverns root
|
||||
prefsshowheader = Visa sidrubriker i listor
|
||||
Lagändringblankett = Lagändringblankett
|
||||
Mappa rootadresssen (http:///localhost:port/) till funktion = Mappa rootadresssen (http:///localhost:port/) till funktion
|
||||
Mappa rootadressen (http:///localhost:port/) till funktion = Mappa rootadressen (http:///localhost:port/) till funktion
|
||||
ClassAvailableMaps = Klassens lediga kartor
|
||||
ClassTotalMaps = Klassens antal kartor
|
||||
Patrol overtime = Patrulls tid övertid
|
||||
@ -2482,4 +2482,21 @@ Status code for cancelled entry = Statuskod för återbud
|
||||
Age (on last day of current year) = Ålder vid årets slut
|
||||
Age above or equal implies senior/pensioner = Åldersgräns äldre/pensionär
|
||||
Age below or equal implies youth = Åldersgräns ungdom
|
||||
Status code for not no timing = Statuskod för utan tidtagning
|
||||
Det finns multiplia Id-nummer för personer = Det finns multiplia Id-nummer för personer
|
||||
Välj vilken typ du vill importera = Välj vilken typ du vill importera
|
||||
Status code for no timing = Statuskod för utan tidtagning
|
||||
prefsVacantPercent = Andel vakanser
|
||||
Före X = Före X
|
||||
Efter X = Efter X
|
||||
Slå ihop X = Slå ihop X
|
||||
Slå ihop med = Slå ihop med
|
||||
Mellan X och Y = Mellan X och Y
|
||||
Ett okänt fel inträffade = Ett okänt fel inträffade
|
||||
Antalet kolumner i urklippet är större än antalet kolumner i tabellen = Antalet kolumner i urklippet är större än antalet kolumner i tabellen
|
||||
Antalet kolumner i urklipp får inte plats i selektionen = Fler kolumner i urklippet än i selektionen
|
||||
prefsVacantPosition = Placering av vakanser
|
||||
Vakansplacering = Vakansplacering
|
||||
Först = Först
|
||||
Lottat = Lottat
|
||||
Sist = Sist
|
||||
Fakturadatum = Fakturadatum
|
||||
|
||||
@ -137,11 +137,10 @@ void TestMeOS::runProtected(bool protect) const {
|
||||
oe_main->setProperty("TestPath", tp);
|
||||
oe_main->getPropertyInt("UseEventor", 1);
|
||||
oe_main->setProperty("Interactive", 0);
|
||||
oe_main->backupRunnerDatabase();
|
||||
TabSI *tsi = dynamic_cast<TabSI*>(gdi_main->getTabs().get(TabType::TSITab));
|
||||
tsi->setMode(TabSI::ModeReadOut);
|
||||
tsi->clearQueue();
|
||||
//string pmOrig = oe_main->getPropertyString("PayModes", "");
|
||||
//oe_main->setProperty("PayModes", "");
|
||||
|
||||
OutputDebugString((L"Running test" + gdi_main->widen(test) + L"\n").c_str());
|
||||
try {
|
||||
@ -161,20 +160,20 @@ void TestMeOS::runProtected(bool protect) const {
|
||||
catch (const meosAssertionFailure & ex) {
|
||||
OutputDebugString(L"Test FAILED (assert)\n");
|
||||
status = FAILED;
|
||||
oe_main->restoreRunnerDatabase();
|
||||
oe_main->useDefaultProperties(false);
|
||||
gdi_main->clearDialogAnswers(false);
|
||||
gdi_main->dbRegisterSubCommand(0, "");
|
||||
gdi_main->isTestMode = false;
|
||||
subWindows.clear();
|
||||
message = ex.message;
|
||||
//oe_main->setProperty("PayModes", pmOrig);
|
||||
if (!protect)
|
||||
throw meosException(message);
|
||||
}
|
||||
catch (const std::exception &ex) {
|
||||
status = FAILED;
|
||||
OutputDebugString(L"Test FAILED (std)\n");
|
||||
|
||||
oe_main->restoreRunnerDatabase();
|
||||
oe_main->useDefaultProperties(false);
|
||||
gdi_main->clearDialogAnswers(false);
|
||||
gdi_main->dbRegisterSubCommand(0, "");
|
||||
@ -189,18 +188,18 @@ void TestMeOS::runProtected(bool protect) const {
|
||||
OutputDebugString(L"Test FAILED (...)\n");
|
||||
|
||||
status = FAILED;
|
||||
oe_main->restoreRunnerDatabase();
|
||||
oe_main->useDefaultProperties(false);
|
||||
gdi_main->clearDialogAnswers(false);
|
||||
gdi_main->dbRegisterSubCommand(0, "");
|
||||
gdi_main->isTestMode = false;
|
||||
subWindows.clear();
|
||||
//oe_main->setProperty("PayModes", pmOrig);
|
||||
message = L"Unknown Exception";
|
||||
cleanup();
|
||||
if (!protect)
|
||||
throw;
|
||||
}
|
||||
//oe_main->setProperty("PayModes", pmOrig);
|
||||
oe_main->restoreRunnerDatabase();
|
||||
oe_main->useDefaultProperties(false);
|
||||
gdi_main->dbRegisterSubCommand(0, "");
|
||||
for (size_t k = 0; k < tmpFiles.size(); k++)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user