MeOS version 3.7SD.1221
This commit is contained in:
parent
5e242c81c0
commit
035fec52ec
@ -368,7 +368,7 @@ protected:
|
||||
int getDISize() const {return 0;}
|
||||
void changedObject() {}
|
||||
public:
|
||||
void merge(const oBase &input) final {}
|
||||
void merge(const oBase &input, const oBase * base) final {}
|
||||
|
||||
int getIndex() const {return index;}
|
||||
void init(RunnerDB *db_, int index_) {db=db_, index=index_; Id = index;}
|
||||
|
||||
@ -3477,7 +3477,7 @@ bool TabClass::loadPage(gdioutput &gdi)
|
||||
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::MultipleRaces))
|
||||
func.push_back(ButtonData("QualificationFinal", "Kval/final-schema", false));
|
||||
|
||||
if (showAdvanced)
|
||||
if (showAdvanced || oe->getStartGroups(true).size() > 0)
|
||||
func.push_back(ButtonData("StartGroups", "Startgrupper", true));
|
||||
|
||||
RECT funRect;
|
||||
|
||||
@ -166,6 +166,12 @@ bool TabCompetition::importFile(HWND hWnd, gdioutput &gdi)
|
||||
if (oe->open(fileName, true, false)) {
|
||||
gdi.setWindowTitle(oe->getTitleName());
|
||||
resetSaveTimer();
|
||||
|
||||
// Save base copy
|
||||
wstring base = constructBase(L"base", L"");
|
||||
wchar_t newBase[_MAX_PATH];
|
||||
getUserFile(newBase, base.c_str());
|
||||
oe->save(newBase);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -763,6 +769,13 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
oe->getDirectSocket().startUDPSocketThread(gdi.getHWNDMain());
|
||||
}
|
||||
|
||||
// Save base copy
|
||||
wstring base = constructBase(L"base", L"");
|
||||
wchar_t newBase[_MAX_PATH];
|
||||
getUserFile(newBase, base.c_str());
|
||||
if (!fileExist(newBase))
|
||||
oe->save(newBase);
|
||||
|
||||
loadConnectionPage(gdi);
|
||||
}
|
||||
else if (bi.id == "MultiEvent") {
|
||||
@ -4167,10 +4180,23 @@ void TabCompetition::checkReadyForResultExport(gdioutput &gdi, const set<int> &c
|
||||
}
|
||||
}
|
||||
|
||||
wstring TabCompetition::constructBase(const wstring &r, const wstring &mt) const {
|
||||
wstring ret = oe->getNameId(0) + L"-";
|
||||
if (!mt.empty())
|
||||
ret += mt + L"-";
|
||||
ret += r + L".meosdiff";
|
||||
return ret;
|
||||
};
|
||||
|
||||
void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
|
||||
class MergeHandler : public GuiHandler {
|
||||
TabCompetition *tc;
|
||||
shared_ptr<oEvent> mergeEvent;
|
||||
shared_ptr<oEvent> baseEvent;
|
||||
wstring thisFile;
|
||||
wstring baseFile;
|
||||
|
||||
public:
|
||||
|
||||
MergeHandler(TabCompetition *tc) : tc(tc) {}
|
||||
@ -4180,19 +4206,29 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
ButtonInfo bi = dynamic_cast<ButtonInfo &>(info);
|
||||
|
||||
if (bi.id == "Cancel") {
|
||||
if (tc->mergeEvent)
|
||||
tc->mergeEvent->clear();
|
||||
if (mergeEvent)
|
||||
mergeEvent->clear();
|
||||
tc->loadPage(gdi);
|
||||
}
|
||||
else if (bi.id == "Merge") {
|
||||
if (!tc->mergeEvent)
|
||||
if (!mergeEvent)
|
||||
return;
|
||||
int numAdd, numRemove, numUpdate;
|
||||
bool allowRemove = true;
|
||||
|
||||
wstring anno = lang.tl(L"Kopia (X)#MRG " + wstring(getLocalTime()));
|
||||
tc->oe->duplicate(anno);
|
||||
if (gdi.hasWidget("AllowRemove"))
|
||||
allowRemove = gdi.isChecked("AllowRemove");
|
||||
|
||||
tc->oe->merge(*tc->mergeEvent, numAdd, numRemove, numUpdate);
|
||||
wstring anno = lang.tl(L"Kopia (X)#MRG " + getLocalTime());
|
||||
tc->oe->duplicate(anno, true);
|
||||
|
||||
if (!thisFile.empty()) {
|
||||
wchar_t newBase[_MAX_PATH];
|
||||
getUserFile(newBase, thisFile.c_str());
|
||||
mergeEvent->save(newBase);
|
||||
}
|
||||
|
||||
tc->oe->merge(*mergeEvent, baseEvent.get(), allowRemove, numAdd, numRemove, numUpdate);
|
||||
|
||||
|
||||
gdi.clearPage(true);
|
||||
@ -4207,7 +4243,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
gdi.dropLine();
|
||||
gdi.addString("", 0, L"Skapade lokal säkerhetskopia (X) innan sammanslagning#" + anno);
|
||||
|
||||
tc->mergeEvent->clear();
|
||||
mergeEvent->clear();
|
||||
|
||||
gdi.dropLine(3);
|
||||
gdi.addButton("Cancel", "Återgå").setHandler(this);
|
||||
@ -4223,29 +4259,33 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
gdi.enableInput("Read");
|
||||
}
|
||||
else if (bi.id == "Read") {
|
||||
tc->mergeEvent = make_shared<oEvent>(gdi);
|
||||
mergeEvent = make_shared<oEvent>(gdi);
|
||||
|
||||
if (!tc->mergeEvent->open(tc->mergeFile, true, true))
|
||||
if (!mergeEvent->open(tc->mergeFile, true, true))
|
||||
return;
|
||||
|
||||
gdi.restore("merge", false);
|
||||
gdi.fillDown();
|
||||
gdi.addStringUT(1, tc->mergeEvent->getName());
|
||||
gdi.addStringUT(1, mergeEvent->getName());
|
||||
|
||||
gdi.dropLine();
|
||||
bool error = false;
|
||||
if (tc->mergeEvent->getNameId(0) == tc->oe->getNameId(0)) {
|
||||
if (tc->mergeEvent->getMergeTag() == tc->oe->getMergeTag()) {
|
||||
bool sameBase = false;
|
||||
if (mergeEvent->getNameId(0) == tc->oe->getNameId(0)) {
|
||||
if (mergeEvent->getMergeTag() == tc->oe->getMergeTag()) {
|
||||
gdi.addString("", 1, "Fel: En tävling kan inte slås ihop med sig själv.").setColor(colorRed);
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
sameBase = true;
|
||||
gdi.addString("", 1, "Samma bastävling").setColor(colorDarkGreen);
|
||||
wstring info = tc->oe->getMergeInfo(tc->mergeEvent->getMergeTag());
|
||||
string mod = tc->mergeEvent->getLastModified();
|
||||
wstring info = tc->oe->getMergeInfo(mergeEvent->getMergeTag());
|
||||
string mod = mergeEvent->getLastModified();
|
||||
|
||||
|
||||
if (info.empty()) {
|
||||
gdi.addString("", 0, "Denna datakälla är aldrig tidigare infogad");
|
||||
baseFile = tc->constructBase(L"base", L"");
|
||||
}
|
||||
else {
|
||||
string merged = gdi.narrow(info);
|
||||
@ -4258,6 +4298,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
TimeStamp ts;
|
||||
ts.setStamp(merged);
|
||||
gdi.addString("", 0, "Tidigare infogad version: X#" + ts.getStampStringN());
|
||||
baseFile = tc->constructBase(info, mergeEvent->getMergeTag());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4265,6 +4306,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
TimeStamp ts;
|
||||
ts.setStamp(mod);
|
||||
gdi.addString("", 0, "Infoga version: X#" + ts.getStampStringN());
|
||||
thisFile = tc->constructBase(gdi.widen(mod), mergeEvent->getMergeTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4281,7 +4323,7 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
gdi.addString("", 1, "Klasser: ");
|
||||
|
||||
vector<pClass> cls;
|
||||
tc->mergeEvent->getClasses(cls, false);
|
||||
mergeEvent->getClasses(cls, false);
|
||||
int xw, yw;
|
||||
gdi.getTargetDimension(xw, yw);
|
||||
int limit = (xw * 2) / 3;
|
||||
@ -4298,14 +4340,39 @@ void TabCompetition::mergeCompetition(gdioutput &gdi) {
|
||||
gdi.popX();
|
||||
gdi.dropLine();
|
||||
|
||||
gdi.addString("", 1, "Antal deltagare: X#" + itos(tc->mergeEvent->getNumRunners()));
|
||||
gdi.addString("", 1, "Antal deltagare: X#" + itos(mergeEvent->getNumRunners()));
|
||||
}
|
||||
|
||||
if (!baseFile.empty()) {
|
||||
wchar_t base[_MAX_PATH];
|
||||
getUserFile(base, baseFile.c_str());
|
||||
baseEvent = make_shared<oEvent>(gdi);
|
||||
bool ok = false;
|
||||
try {
|
||||
ok = baseEvent->open(base, true, true);
|
||||
ok = true;
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
baseEvent.reset();
|
||||
gdi.dropLine();
|
||||
gdi.addString("", 0, L"Varning: Kunde inte hitta föregående version av tävlingen (X).#" + baseFile).setColor(GDICOLOR::colorRed);
|
||||
gdi.addString("", 0, L"Använd om möjligt samma dator som användes vid senaste importen.");
|
||||
}
|
||||
}
|
||||
|
||||
if (sameBase) {
|
||||
gdi.dropLine();
|
||||
gdi.addCheckbox("AllowRemove", "Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen");
|
||||
}
|
||||
|
||||
gdi.dropLine();
|
||||
gdi.fillRight();
|
||||
if (!error)
|
||||
gdi.addButton("Merge", "Slå ihop").setHandler(tc->mergeHandler.get());
|
||||
gdi.addButton("Cancel", "Avbryt").setHandler(tc->mergeHandler.get());
|
||||
gdi.addButton("Merge", "Slå ihop").setHandler(this);
|
||||
gdi.addButton("Cancel", "Avbryt").setHandler(this);
|
||||
|
||||
gdi.refresh();
|
||||
}
|
||||
|
||||
@ -135,9 +135,11 @@ class TabCompetition :
|
||||
void listBackups(gdioutput &gdi);
|
||||
|
||||
shared_ptr<GuiHandler> mergeHandler;
|
||||
shared_ptr<oEvent> mergeEvent;
|
||||
void mergeCompetition(gdioutput &gdi);
|
||||
wstring mergeFile;
|
||||
|
||||
wstring constructBase(const wstring &r, const wstring &mt) const;
|
||||
|
||||
protected:
|
||||
void clearCompetitionData();
|
||||
|
||||
|
||||
@ -2520,3 +2520,7 @@ Tjänstebeställningar (IOF XML) = Service Requests (IOF XML)
|
||||
Tjänster (IOF XML) = Services (IOF XML)
|
||||
Flytta deltagare från överfulla grupper = Move competitors from full groups
|
||||
Lotta med startgrupper = Draw with Starting Groups
|
||||
Startgrupp med id X tilldelad Y finns inte = Starting group with ID X defined for Y does not exist
|
||||
Använd om möjligt samma dator som användes vid senaste importen = If possible, use the same computer that was used to import the last time
|
||||
Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Allow removal of competitors (etc) that has was deleted in the imported version.
|
||||
Varning: Kunde inte hitta föregående version av tävlingen (X) = Warning: Could not find the previous version of the competition (X)
|
||||
|
||||
@ -1413,7 +1413,7 @@ void IOF30Interface::readEvent(gdioutput &gdi, const xmlobject &xo,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool anySG = false;
|
||||
// This is a "hack" to interpret services of the from "XXXX 14:00 - 15:00 XXXX" as a start group.
|
||||
for (auto &srv : services) {
|
||||
vector<wstring> parts;
|
||||
@ -1428,10 +1428,15 @@ void IOF30Interface::readEvent(gdioutput &gdi, const xmlobject &xo,
|
||||
if (t > 0)
|
||||
times.push_back(t);
|
||||
}
|
||||
if (times.size() == 2 && times[0] < times[1])
|
||||
oe.setStartGroup(srv.id, times[0], times[1]);
|
||||
int ts = times.size();
|
||||
if (ts >= 2 && times[ts - 2] < times[ts - 1]) {
|
||||
oe.setStartGroup(srv.id, times[ts - 2], times[ts - 1]);
|
||||
anySG = true;
|
||||
}
|
||||
}
|
||||
oe.updateStartGroups();
|
||||
|
||||
if (anySG)
|
||||
oe.updateStartGroups();
|
||||
}
|
||||
|
||||
void IOF30Interface::setupClassConfig(int classId, const xmlobject &xTeam, map<int, vector<LegInfo> > &teamClassConfig) {
|
||||
@ -2950,7 +2955,7 @@ void IOF30Interface::writeResult(xmlparser &xml, const oRunner &rPerson, const o
|
||||
xml.write("StartTime", oe.getAbsDateTimeISO(r.getStartTime(), true, useGMT));
|
||||
|
||||
bool hasTiming = (!r.getClassRef(false) || r.getClassRef(true)->getNoTiming() == false) &&
|
||||
r.getStatusComputed() != RunnerStatus::StatusNoTiming;
|
||||
r.getStatusComputed() != RunnerStatus::StatusNoTiming && !r.noTiming();
|
||||
|
||||
int finishTime, runningTime, place, after;
|
||||
RunnerStatus status;
|
||||
|
||||
@ -30,18 +30,18 @@
|
||||
//V35: abcdef
|
||||
//V36: abcdef
|
||||
int getMeosBuild() {
|
||||
string revision("$Rev: 1031 $");
|
||||
string revision("$Rev: 1047 $");
|
||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||
}
|
||||
|
||||
//V37: ab
|
||||
wstring getMeosDate() {
|
||||
wstring date(L"$Date: 2020-08-01 10:38:11 +0200 (lö, 01 aug 2020) $");
|
||||
wstring date(L"$Date: 2020-09-06 08:57:56 +0200 (sö, 06 sep 2020) $");
|
||||
return date.substr(7,10);
|
||||
}
|
||||
|
||||
wstring getBuildType() {
|
||||
return L"RC1"; // No parantheses (...)
|
||||
return L""; // No parantheses (...)
|
||||
}
|
||||
|
||||
wstring getMajorVersion() {
|
||||
@ -67,29 +67,13 @@ wstring getMeosCompectVersion() {
|
||||
|
||||
void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||
{
|
||||
supp.emplace_back(L"Sergio Yañez, ABC TRAIL");
|
||||
supp.emplace_back(L"Western Race Services");
|
||||
supp.emplace_back(L"IK Gandvik, Skara");
|
||||
supp.emplace_back(L"IK Stern");
|
||||
supp.emplace_back(L"OK Roslagen");
|
||||
supp.emplace_back(L"TSV Malente");
|
||||
supp.emplace_back(L"Emmaboda Verda OK");
|
||||
supp.emplace_back(L"KOB ATU Košice");
|
||||
supp.emplace_back(L"Gävle OK");
|
||||
supp.emplace_back(L"Kenneth Gattmalm, Jönköpings OK");
|
||||
supp.emplace_back(L"Søllerød OK");
|
||||
supp.emplace_back(L"Bengt Bengtsson");
|
||||
supp.emplace_back(L"OK Landehof");
|
||||
supp.emplace_back(L"OK Orinto");
|
||||
supp.emplace_back(L"Bredaryds SOK");
|
||||
supp.emplace_back(L"Thore Nilsson, Uddevalla OK");
|
||||
supp.emplace_back(L"Timrå SOK");
|
||||
supp.emplace_back(L"Åke Larsson, OK Hedströmmen");
|
||||
supp.emplace_back(L"Avesta OK");
|
||||
supp.emplace_back(L"Tjalve IF");
|
||||
supp.emplace_back(L"Nyköpings Orienteringsklubb");
|
||||
supp.emplace_back(L"Motionsorientering Göteborg");
|
||||
supp.emplace_back(L"OK Måsen");
|
||||
supp.emplace_back(L"IF Thor");
|
||||
supp.emplace_back(L"SOS Jindřichův Hradec");
|
||||
supp.emplace_back(L"KOB ATU Košice");
|
||||
supp.emplace_back(L"Mats Holmberg, OK Gränsen");
|
||||
supp.emplace_back(L"Christoffer Ohlsson, Uddevalla OK");
|
||||
supp.emplace_back(L"KOB ATU Košice");
|
||||
@ -114,6 +98,7 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||
supp.emplace_back(L"Tolereds AIK");
|
||||
supp.emplace_back(L"OK Snab");
|
||||
supp.emplace_back(L"OK 73");
|
||||
supp.emplace_back(L"Herlufsholm OK");
|
||||
supp.emplace_back(L"Helsingborgs SOK");
|
||||
supp.emplace_back(L"Sala OK");
|
||||
supp.emplace_back(L"OK Roskilde");
|
||||
@ -139,14 +124,19 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
||||
supp.emplace_back(L"Nässjö OK");
|
||||
supp.emplace_back(L"Ringsjö OK");
|
||||
supp.emplace_back(L"Big Foot Orienteers");
|
||||
supp.emplace_back(L"Erik Hulthen, Mölndal Outdoor IF");
|
||||
supp.emplace_back(L"Bay Area Orienteering Club");
|
||||
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");
|
||||
supp.emplace_back(L"Martin Ivarsson");
|
||||
supp.emplace_back(L"Falköpings AIK OK");
|
||||
developSupp.push_back(L"Karlskrona SOK");
|
||||
|
||||
supp.emplace_back(L"Kristian Toustrup, OK Syd");
|
||||
supp.emplace_back(L"Patrick NG, HKAYP");
|
||||
supp.emplace_back(L"Lars Ove Karlsson, Västerås SOK");
|
||||
supp.emplace_back(L"OK Milan");
|
||||
reverse(supp.begin(), supp.end());
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ protected:
|
||||
void setLocalObject() { localObject = true; }
|
||||
|
||||
// Merge into this entity
|
||||
virtual void merge(const oBase &input) = 0;
|
||||
virtual void merge(const oBase &input, const oBase *base) = 0;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@ -130,7 +130,7 @@ public:
|
||||
void importPunches(const string &s);
|
||||
const string &getPunchString() const;
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
pair<int, int> getCardHash() const;
|
||||
|
||||
void Set(const xmlobject &xo);
|
||||
|
||||
@ -707,7 +707,7 @@ public:
|
||||
void setResultModule(const string &tag);
|
||||
const string &getResultModuleTag() const;
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
oClass(oEvent *poe);
|
||||
oClass(oEvent *poe, int id);
|
||||
|
||||
@ -177,7 +177,7 @@ public:
|
||||
|
||||
void setName(const wstring &n);
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
void set(const xmlobject &xo);
|
||||
bool write(xmlparser &xml);
|
||||
|
||||
@ -219,7 +219,7 @@ public:
|
||||
int getFirstNumber() const;
|
||||
void getNumbers(vector<int> &numbers) const;
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
void set(const xmlobject *xo);
|
||||
void set(int pId, int pNumber, wstring pName);
|
||||
|
||||
@ -239,7 +239,7 @@ public:
|
||||
wstring getStart() const;
|
||||
void setStart(const wstring &start, bool sync);
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
bool Write(xmlparser &xml);
|
||||
|
||||
|
||||
@ -845,6 +845,7 @@ namespace {
|
||||
return &bfData[0];
|
||||
}
|
||||
}
|
||||
|
||||
string oDataContainer::generateSQLSet(const oBase *ob, bool forceSetAll) const {
|
||||
void *data, *oldData;
|
||||
vector< vector<wstring> > *strptr;
|
||||
@ -914,6 +915,73 @@ string oDataContainer::generateSQLSet(const oBase *ob, bool forceSetAll) const {
|
||||
return sql;
|
||||
}
|
||||
|
||||
bool oDataContainer::merge(oBase &destination, const oBase &source, const oBase *base) const {
|
||||
bool modified = false;
|
||||
void *destdata, *oldDataDmy;
|
||||
vector< vector<wstring> > *deststrptr;
|
||||
destination.getDataBuffers(destdata, oldDataDmy, deststrptr);
|
||||
|
||||
void *srcdata;
|
||||
vector< vector<wstring> > *srcstrptr;
|
||||
source.getDataBuffers(srcdata, oldDataDmy, srcstrptr);
|
||||
|
||||
void *basedata = nullptr;
|
||||
vector< vector<wstring> > *basestrptr = nullptr;
|
||||
if (base)
|
||||
base->getDataBuffers(basedata, oldDataDmy, basestrptr);
|
||||
|
||||
auto setData = [](void *d, void *s, void *b, int off, int size) {
|
||||
LPBYTE vd = LPBYTE(d) + off;
|
||||
LPBYTE vs = LPBYTE(s) + off;
|
||||
if (memcmp(vd, vs, size) != 0) {
|
||||
if (b == nullptr || memcmp(LPBYTE(b) + off, vs, size) != 0) {
|
||||
memcpy(vd, vs, size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (size_t kk = 0; kk < ordered.size(); kk++) {
|
||||
const oDataInfo &di = ordered[kk];
|
||||
if (di.Type == oDTInt) {
|
||||
if (di.SubType != oIS64) {
|
||||
if (setData(destdata, srcdata, basedata, di.Index, sizeof(int)))
|
||||
modified = true;
|
||||
}
|
||||
else {
|
||||
if (setData(destdata, srcdata, basedata, di.Index, sizeof(int64_t)))
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else if (di.Type == oDTString) {
|
||||
if (setData(destdata, srcdata, basedata, di.Index, di.Size))
|
||||
modified = true;
|
||||
}
|
||||
else if (di.Type == oDTStringDynamic) {
|
||||
const wstring &s = (*srcstrptr)[0][di.Index];
|
||||
wstring &d = (*deststrptr)[0][di.Index];
|
||||
if (s != d) {
|
||||
if (basestrptr == nullptr || (*basestrptr)[0][di.Index] != s) {
|
||||
d = s;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (di.Type == oDTStringArray) {
|
||||
const auto &s = (*srcstrptr)[di.Index];
|
||||
auto &d = (*deststrptr)[di.Index];
|
||||
if (s != d) {
|
||||
if (basestrptr == nullptr || (*basestrptr)[di.Index] != s) {
|
||||
d = s;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
void oDataContainer::getVariableInt(const void *data,
|
||||
list<oVariableInt> &var) const {
|
||||
|
||||
@ -104,8 +104,6 @@ protected:
|
||||
size_t stringIndexPointer;
|
||||
size_t stringArrayIndexPointer;
|
||||
|
||||
//map<string, oDataInfo> index;
|
||||
//vector<string> ordered;
|
||||
inthashmap index;
|
||||
vector<oDataInfo> ordered;
|
||||
|
||||
@ -140,6 +138,8 @@ public:
|
||||
return generateSQLDefinition(std::set<string>());
|
||||
}
|
||||
|
||||
bool merge(oBase &destination, const oBase &source, const oBase *base) const;
|
||||
|
||||
string generateSQLSet(const oBase *ob, bool forceSetAll) const;
|
||||
|
||||
void allDataStored(const oBase *ob);
|
||||
@ -211,6 +211,10 @@ private:
|
||||
oBase *oB;
|
||||
public:
|
||||
|
||||
bool merge(const oBase &source, const oBase *base) {
|
||||
return oDC->merge(*oB, source, base);
|
||||
}
|
||||
|
||||
inline bool setInt(const char *Name, int Value)
|
||||
{
|
||||
if (oDC->setInt(Data, Name, Value)){
|
||||
|
||||
@ -824,7 +824,7 @@ bool oEvent::writeCards(xmlparser &xml)
|
||||
return true;
|
||||
}
|
||||
|
||||
void oEvent::duplicate(const wstring &annotationIn) {
|
||||
void oEvent::duplicate(const wstring &annotationIn, bool keepTags) {
|
||||
wchar_t file[260];
|
||||
wchar_t filename[64];
|
||||
wchar_t nameid[64];
|
||||
@ -854,7 +854,8 @@ void oEvent::duplicate(const wstring &annotationIn) {
|
||||
wstring oldAnno = getAnnotation();
|
||||
|
||||
wcscpy_s(CurrentFile, file);
|
||||
currentNameId = nameid;
|
||||
if (!keepTags)
|
||||
currentNameId = nameid;
|
||||
|
||||
swprintf_s(filename, L"%d/%d %d:%02d",
|
||||
st.wDay, st.wMonth, st.wHour, st.wMinute);
|
||||
@ -869,7 +870,8 @@ void oEvent::duplicate(const wstring &annotationIn) {
|
||||
}
|
||||
wstring oldTag = getMergeTag();
|
||||
try {
|
||||
getMergeTag(true);
|
||||
if (!keepTags)
|
||||
getMergeTag(true);
|
||||
save();
|
||||
}
|
||||
catch(...) {
|
||||
|
||||
@ -963,7 +963,7 @@ public:
|
||||
|
||||
bool exportOECSV(const wchar_t *file, int LanguageTypeIndex, bool includeSplits);
|
||||
bool save();
|
||||
void duplicate(const wstring &annotation);
|
||||
void duplicate(const wstring &annotation, bool keepTags = false);
|
||||
void newCompetition(const wstring &Name);
|
||||
void clearListedCmp();
|
||||
bool enumerateCompetitions(const wchar_t *path, const wchar_t *extension);
|
||||
@ -1301,7 +1301,7 @@ protected:
|
||||
/** type: 0 control, 1 start, 2 finish*/
|
||||
bool addXMLControl(const xmlobject &xcontrol, int type);
|
||||
|
||||
void merge(const oBase &src) final;
|
||||
void merge(const oBase &src, const oBase *base) final;
|
||||
|
||||
public:
|
||||
|
||||
@ -1313,7 +1313,7 @@ public:
|
||||
|
||||
void getPredefinedClassTypes(map<wstring, ClassMetaType> &types) const;
|
||||
|
||||
void merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate);
|
||||
void merge(oEvent &src, oEvent *base, bool allowRemove, int &numAdd, int &numRemove, int &numUpdate);
|
||||
string getLastModified() const;
|
||||
|
||||
wstring cloneCompetition(bool cloneRunners, bool cloneTimes,
|
||||
|
||||
@ -1170,8 +1170,6 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
||||
if (diIn)
|
||||
nParallel = diIn->nFields;
|
||||
|
||||
pRunner alice = getRunner(155227, 0);
|
||||
|
||||
constexpr bool logOutput = false;
|
||||
auto &sgMap = getStartGroups(true);
|
||||
if (sgMap.empty())
|
||||
@ -1218,6 +1216,8 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
||||
++rPerGroupTotal[idRes->second].first;
|
||||
}
|
||||
else {
|
||||
if (id > 0)
|
||||
throw meosException(L"Startgrupp med id X tilldelad Y finns inte.#" + itow(id) + L"#" + r.getCompleteIdentification());
|
||||
++res->second.unassigned;
|
||||
unassigned.push_back(&r);
|
||||
}
|
||||
@ -1591,8 +1591,9 @@ void oEvent::drawListStartGroups(const vector<ClassDrawSpecification> &spec,
|
||||
ClassInfo &ci = di.classes[spec[k].classID];
|
||||
ci.startGroupId = groupId;
|
||||
if (gi.firstStart > firstStart) {
|
||||
ci.firstStart = (gi.firstStart - firstStart) / di.baseInterval;
|
||||
ci.hasFixedTime = true;
|
||||
// Handled by distributor
|
||||
// ci.firstStart = (gi.firstStart - firstStart) / di.baseInterval;
|
||||
// ci.hasFixedTime = true;
|
||||
}
|
||||
ci.nVacant = gi.vacantPerGroup[j];
|
||||
ci.nVacantSpecified = true;
|
||||
|
||||
@ -86,7 +86,7 @@ public:
|
||||
static void rehashPunches(oEvent &oe, int cardNo, pFreePunch newPunch);
|
||||
static bool disableHashing;
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
oFreePunch(oEvent *poe, int card, int time, int type);
|
||||
oFreePunch(oEvent *poe, int id);
|
||||
|
||||
@ -1009,10 +1009,10 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
|
||||
wbf[0]=0;
|
||||
|
||||
auto noTimingRunner = [&]() {
|
||||
return (pc ? pc->getNoTiming() : false) || (r ? r->getStatusComputed() == StatusNoTiming : false);
|
||||
return (pc ? pc->getNoTiming() : false) || (r ? (r->getStatusComputed() == StatusNoTiming || r->noTiming()) : false);
|
||||
};
|
||||
auto noTimingTeam = [&]() {
|
||||
return (pc ? pc->getNoTiming() : false) || (t ? t->getStatusComputed() == StatusNoTiming : false);
|
||||
return (pc ? pc->getNoTiming() : false) || (t ? (t->getStatusComputed() == StatusNoTiming || t->noTiming()): false);
|
||||
};
|
||||
bool invalidClass = pc && pc->getClassStatus() != oClass::ClassStatus::Normal;
|
||||
int legIndex = pp.legIndex;
|
||||
@ -2459,7 +2459,7 @@ void oEvent::listGeneratePunches(const oListInfo &listInfo, gdioutput &gdi,
|
||||
|
||||
if (cls && cls->getNoTiming())
|
||||
return;
|
||||
if (r && r->getStatusComputed() == StatusNoTiming)
|
||||
if (r && (r->getStatusComputed() == StatusNoTiming || r->noTiming()))
|
||||
return;
|
||||
|
||||
int h = gdi.getLineHeight();
|
||||
|
||||
@ -99,7 +99,7 @@ public:
|
||||
void appendCodeString(string &dst) const;
|
||||
|
||||
|
||||
void merge(const oBase &input) override;
|
||||
void merge(const oBase &input, const oBase *base) override;
|
||||
|
||||
oPunch(oEvent *poe);
|
||||
virtual ~oPunch();
|
||||
|
||||
@ -201,7 +201,7 @@ public:
|
||||
bool preventRestart() const;
|
||||
void preventRestart(bool state);
|
||||
|
||||
void merge(const oBase &input) override;
|
||||
void merge(const oBase &input, const oBase *base) override;
|
||||
|
||||
/** Call this method after doing something to just this
|
||||
runner/team that changed the time/status etc, that effects
|
||||
@ -244,6 +244,9 @@ public:
|
||||
bool hasFlag(TransferFlags flag) const;
|
||||
void setFlag(TransferFlags flag, bool state);
|
||||
|
||||
/** Return true if no timing is requested. */
|
||||
bool noTiming() const { return hasFlag(FlagNoTiming); }
|
||||
|
||||
// Get the runners team or the team itself
|
||||
virtual cTeam getTeam() const = 0;
|
||||
virtual pTeam getTeam() = 0;
|
||||
@ -958,7 +961,7 @@ public:
|
||||
/** Formats extra line for runner []-syntax, or if r is null, checks validity and throws on error.*/
|
||||
static wstring formatExtraLine(pRunner r, const wstring &input);
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
virtual ~oRunner();
|
||||
|
||||
|
||||
@ -279,7 +279,7 @@ public:
|
||||
void set(const xmlobject &xo);
|
||||
bool write(xmlparser &xml);
|
||||
|
||||
void merge(const oBase &input) final;
|
||||
void merge(const oBase &input, const oBase *base) final;
|
||||
|
||||
oTeam(oEvent *poe, int id);
|
||||
oTeam(oEvent *poe);
|
||||
|
||||
@ -43,7 +43,7 @@ Eksoppsv
|
||||
|
||||
|
||||
|
||||
void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
void oEvent::merge(oEvent &src, oEvent *base, bool allowRemove, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
numAdd = 0;
|
||||
numRemove = 0;
|
||||
numUpdate = 0;
|
||||
@ -76,28 +76,63 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto updateNewItem = [&addMinTime, &numAdd](oBase *pNew, const oBase &src) {
|
||||
if (pNew) {
|
||||
numAdd++;
|
||||
pNew->merge(src);
|
||||
pNew->merge(src, nullptr);
|
||||
pNew->synchronize();
|
||||
if (pNew->Modified.getStamp() < addMinTime)
|
||||
pNew->Modified.setStamp(addMinTime);
|
||||
}
|
||||
};
|
||||
|
||||
auto mergeItem = [&numUpdate](oBase *pExisting, const oBase &src) {
|
||||
auto mergeItem = [&numUpdate](oBase *pExisting, const oBase &src, const oBase *baseItem) {
|
||||
numUpdate++;
|
||||
string oldStamp = pExisting->Modified.getStamp();
|
||||
pExisting->merge(src);
|
||||
pExisting->merge(src, baseItem);
|
||||
if (pExisting->Modified.getStamp() < oldStamp)
|
||||
pExisting->Modified.setStamp(oldStamp);
|
||||
};
|
||||
|
||||
auto computeRemove = [&bt](const auto &list, const set<int> &existing, set<int> &remove) {
|
||||
auto getBaseMap = [](auto &list) {
|
||||
map<int, oBase *> ret;
|
||||
for (auto &c : list)
|
||||
ret.emplace(c.getId(), &c);
|
||||
return ret;
|
||||
};
|
||||
map<int, oBase*> baseMap;
|
||||
|
||||
auto computeRemove = [&bt, &baseMap](const auto &list, const set<int> &existing, set<int> &remove) {
|
||||
for (auto &c : list) {
|
||||
if (!baseMap.empty() && !baseMap.count(c.Id))
|
||||
continue; // Did non exist in base -> not removed
|
||||
if (!c.isRemoved() && !existing.count(c.Id) && c.getStamp() < bt)
|
||||
remove.insert(c.Id);
|
||||
}
|
||||
};
|
||||
|
||||
// Swap id
|
||||
auto changeBaseId = [&baseMap](int oldId, int newId) {
|
||||
oBase *rOld = nullptr, *rNew = nullptr;
|
||||
auto ob = baseMap.find(newId);
|
||||
if (ob != baseMap.end() && ob->second) {
|
||||
rOld = ob->second;
|
||||
rOld->changeId(oldId);
|
||||
}
|
||||
ob = baseMap.find(oldId);
|
||||
if (ob != baseMap.end() && ob->second) {
|
||||
rNew = ob->second;
|
||||
rNew->changeId(newId);
|
||||
}
|
||||
baseMap[newId] = rNew;
|
||||
baseMap[oldId] = rOld;
|
||||
};
|
||||
|
||||
auto getBaseObject = [&baseMap](const oBase &src) {
|
||||
auto res = baseMap.find(src.getId());
|
||||
if (res != baseMap.end())
|
||||
return res->second;
|
||||
else
|
||||
return (oBase*)nullptr;
|
||||
};
|
||||
|
||||
{
|
||||
map<int, pControl> ctrl;
|
||||
for (oControl &c : Controls) {
|
||||
@ -105,8 +140,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
ctrl[c.Id] = &c;
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Controls);
|
||||
|
||||
set<int> srcControl;
|
||||
for (const oControl &c : src.Controls) {
|
||||
const oBase *baseObj = getBaseObject(c);
|
||||
const string &stmp = c.getStamp();
|
||||
if (!c.isRemoved()) {
|
||||
if (stmp > previousMergeTime) {
|
||||
@ -114,7 +153,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
thisMergeTime = stmp;
|
||||
auto mc = ctrl.find(c.Id);
|
||||
if (mc != ctrl.end()) {
|
||||
mergeItem(mc->second, c);
|
||||
mergeItem(mc->second, c, baseObj);
|
||||
}
|
||||
else {
|
||||
pControl pNew = addControl(c);
|
||||
@ -135,8 +174,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
crs[c.Id] = &c;
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Courses);
|
||||
|
||||
set<int> srcCourse;
|
||||
for (const oCourse &c : src.Courses) {
|
||||
const oBase *baseObj = getBaseObject(c);
|
||||
const string &stmp = c.getStamp();
|
||||
if (!c.isRemoved()) {
|
||||
bool okMerge = stmp > previousMergeTime;
|
||||
@ -145,7 +188,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mc = crs.find(c.Id);
|
||||
if (mc != crs.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mc->second, c);
|
||||
mergeItem(mc->second, c, baseObj);
|
||||
}
|
||||
else if (okMerge) {
|
||||
pCourse pNew = addCourse(c);
|
||||
@ -169,8 +212,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Classes);
|
||||
|
||||
set<int> srcClass;
|
||||
for (oClass &c : src.Classes) {
|
||||
oBase *baseObj = getBaseObject(c);
|
||||
const string &stmp = c.getStamp();
|
||||
bool merged = false;
|
||||
if (!c.isRemoved()) {
|
||||
@ -183,12 +230,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
if (mc != cls.end()) {
|
||||
if (compareClassName(mc->second->Name, c.Name)) {
|
||||
if (okMerge)
|
||||
mergeItem(mc->second, c);
|
||||
mergeItem(mc->second, c, baseObj);
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto updateIdCls = [&](int id) {
|
||||
changeBaseId(c.Id, id);
|
||||
pClass other = src.getClass(id);
|
||||
if (other)
|
||||
other->changeId(c.Id);
|
||||
@ -199,7 +247,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mcN = clsN.find(c.Name);
|
||||
if (mcN != clsN.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, c);
|
||||
mergeItem(mcN->second, c, baseObj);
|
||||
merged = true;
|
||||
updateIdCls(mcN->second->Id);
|
||||
}
|
||||
@ -231,7 +279,11 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Cards);
|
||||
|
||||
for (oCard &c : src.Cards) {
|
||||
const oBase *baseObj = getBaseObject(c);
|
||||
const string &stmp = c.getStamp();
|
||||
if (!c.isRemoved() && stmp > previousMergeTime) {
|
||||
if (stmp > thisMergeTime)
|
||||
@ -244,10 +296,11 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto c2 = mc->second;
|
||||
auto p2 = c2->getNumPunches() > 0 ? c2->getPunchByIndex(c2->getNumPunches() - 1)->getTimeInt() : 0;
|
||||
if (p1 == p2)
|
||||
mergeItem(mc->second, c), merged = true;
|
||||
mergeItem(mc->second, c, baseObj), merged = true;
|
||||
}
|
||||
|
||||
auto updateIdCrd = [&](int id) {
|
||||
changeBaseId(c.Id, id);
|
||||
pCard other = src.getCard(id);
|
||||
if (other)
|
||||
other->changeId(c.Id);
|
||||
@ -257,7 +310,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
if (!merged) {
|
||||
auto mcN = crdByHash.find(c.getCardHash());
|
||||
if (mcN != crdByHash.end()) {
|
||||
mergeItem(mcN->second, c);
|
||||
mergeItem(mcN->second, c, baseObj);
|
||||
merged = true;
|
||||
updateIdCrd(mcN->second->Id);
|
||||
}
|
||||
@ -289,8 +342,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Clubs);
|
||||
|
||||
set<int> srcClub;
|
||||
for (oClub &c : src.Clubs) {
|
||||
const oBase *baseObj = getBaseObject(c);
|
||||
const string &stmp = c.getStamp();
|
||||
if (!c.isRemoved()) {
|
||||
bool okMerge = stmp > previousMergeTime;
|
||||
@ -304,12 +361,13 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
if ((c.getExtIdentifier() != 0 && c.getExtIdentifier() == mc->second->getExtIdentifier())
|
||||
|| c.getName() == mc->second->getName()) {
|
||||
if (okMerge)
|
||||
mergeItem(mc->second, c);
|
||||
mergeItem(mc->second, c, baseObj);
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto updateIdClb = [&](int id) {
|
||||
changeBaseId(c.Id, id);
|
||||
pClub other = src.getClub(id);
|
||||
if (other)
|
||||
other->changeId(c.Id);
|
||||
@ -320,7 +378,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mcN = clbByExt.find(c.getExtIdentifier());
|
||||
if (mcN != clbByExt.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, c);
|
||||
mergeItem(mcN->second, c, baseObj);
|
||||
merged = true;
|
||||
updateIdClb(mcN->second->Id);
|
||||
}
|
||||
@ -330,7 +388,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mcN = clbByName.find(c.getName());
|
||||
if (mcN != clbByName.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, c);
|
||||
mergeItem(mcN->second, c, baseObj);
|
||||
merged = true;
|
||||
updateIdClb(mcN->second->Id);
|
||||
}
|
||||
@ -357,6 +415,9 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
map<int64_t, pRunner> rnByExt;
|
||||
map<pair<int, wstring>, pRunner> rnByCardName;
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Runners);
|
||||
|
||||
for (oRunner &r : Runners) {
|
||||
if (!r.isRemoved()) {
|
||||
rn[r.Id] = &r;
|
||||
@ -367,6 +428,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
set<int> srcRunner;
|
||||
for (oRunner &r : src.Runners) {
|
||||
const oBase *baseObj = getBaseObject(r);
|
||||
const string &stmp = r.getStamp();
|
||||
if (!r.isRemoved()) {
|
||||
bool okMerge = stmp > previousMergeTime;
|
||||
@ -382,15 +444,16 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
|| mc->second->isVacant()) {
|
||||
|
||||
if (okMerge)
|
||||
mergeItem(mc->second, r);
|
||||
mergeItem(mc->second, r, baseObj);
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto updateIdR = [&](int id) {
|
||||
changeBaseId(r.Id, id);
|
||||
pRunner other = src.getRunner(id, 0);
|
||||
if (other)
|
||||
other->changeId(src.Id);
|
||||
other->changeId(r.Id);
|
||||
r.changeId(id);
|
||||
};
|
||||
|
||||
@ -398,7 +461,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mcN = rnByExt.find(r.getExtIdentifier());
|
||||
if (mcN != rnByExt.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, r);
|
||||
mergeItem(mcN->second, r, baseObj);
|
||||
merged = true;
|
||||
updateIdR(mcN->second->Id);
|
||||
}
|
||||
@ -408,7 +471,7 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
auto mcN = rnByCardName.find(make_pair(r.getCardNo(), r.sName));
|
||||
if (mcN != rnByCardName.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, r);
|
||||
mergeItem(mcN->second, r, baseObj);
|
||||
merged = true;
|
||||
updateIdR(mcN->second->Id);
|
||||
}
|
||||
@ -441,8 +504,12 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
if (base)
|
||||
baseMap = getBaseMap(base->Teams);
|
||||
|
||||
set<int> srcTeam;
|
||||
for (oTeam &t : src.Teams) {
|
||||
const oBase *baseObj = getBaseObject(t);
|
||||
const string &stmp = t.getStamp();
|
||||
if (!t.isRemoved()) {
|
||||
bool okMerge = stmp > previousMergeTime;
|
||||
@ -454,24 +521,24 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
if (mc != tm.end()) {
|
||||
if (t.getClubId() == mc->second->getClubId()) {
|
||||
if (okMerge)
|
||||
mergeItem(mc->second, t);
|
||||
mergeItem(mc->second, t, baseObj);
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto updateIdT = [&](int id) {
|
||||
changeBaseId(t.Id, id);
|
||||
pTeam other = src.getTeam(id);
|
||||
if (other)
|
||||
other->changeId(src.Id);
|
||||
other->changeId(t.Id);
|
||||
t.changeId(id);
|
||||
};
|
||||
|
||||
|
||||
if (!merged) {
|
||||
auto mcN = tmByClassName.find(make_pair(t.getClassId(false), t.getName()));
|
||||
if (mcN != tmByClassName.end()) {
|
||||
if (okMerge)
|
||||
mergeItem(mcN->second, t);
|
||||
mergeItem(mcN->second, t, baseObj);
|
||||
merged = true;
|
||||
updateIdT(mcN->second->Id);
|
||||
}
|
||||
@ -503,12 +570,14 @@ void oEvent::merge(oEvent &src, int &numAdd, int &numRemove, int &numUpdate) {
|
||||
}
|
||||
};
|
||||
|
||||
removeEnts(rTeam, [this](int id) -> pBase {return getTeam(id); });
|
||||
removeEnts(rRunner, [this](int id) -> pBase {return getRunner(id, 0); });
|
||||
removeEnts(rClub, [this](int id) -> pBase {return getClub(id); });
|
||||
removeEnts(rClass, [this](int id) -> pBase {return getClass(id); });
|
||||
removeEnts(rCourse, [this](int id) -> pBase {return getCourse(id); });
|
||||
removeEnts(rControl, [this](int id) -> pBase {return getControl(id); });
|
||||
if (allowRemove) {
|
||||
removeEnts(rTeam, [this](int id) -> pBase {return getTeam(id); });
|
||||
removeEnts(rRunner, [this](int id) -> pBase {return getRunner(id, 0); });
|
||||
removeEnts(rClub, [this](int id) -> pBase {return getClub(id); });
|
||||
removeEnts(rClass, [this](int id) -> pBase {return getClass(id); });
|
||||
removeEnts(rCourse, [this](int id) -> pBase {return getCourse(id); });
|
||||
removeEnts(rControl, [this](int id) -> pBase {return getControl(id); });
|
||||
}
|
||||
|
||||
wstring mtOut(thisMergeTime.begin(), thisMergeTime.end());
|
||||
addMergeInfo(mergeTag, mtOut);
|
||||
@ -1228,102 +1297,149 @@ void oEvent::transferResult(oEvent &ce,
|
||||
}*/
|
||||
}
|
||||
|
||||
void oAbstractRunner::merge(const oBase &input) {
|
||||
void oAbstractRunner::merge(const oBase &input, const oBase *baseIn) {
|
||||
const oAbstractRunner &src = dynamic_cast<const oAbstractRunner&>(input);
|
||||
setName(src.sName, false);
|
||||
const oAbstractRunner *base = dynamic_cast<const oAbstractRunner*>(baseIn);
|
||||
|
||||
setStartTime(src.startTime, true, ChangeType::Update, false);
|
||||
setFinishTime(src.FinishTime);
|
||||
setStatus(src.status, true, ChangeType::Update);
|
||||
setStartNo(src.StartNo, ChangeType::Update);
|
||||
setClubId(src.getClubId());
|
||||
setClassId(src.getClassId(false), false);
|
||||
if (base == nullptr || base->sName != src.sName)
|
||||
setName(src.sName, false);
|
||||
|
||||
setInputPlace(src.inputPlace);
|
||||
if (inputTime != src.inputTime) {
|
||||
inputTime = src.inputTime;
|
||||
updateChanged();
|
||||
if (base == nullptr || base->startTime != src.startTime)
|
||||
setStartTime(src.startTime, true, ChangeType::Update, false);
|
||||
|
||||
if (base == nullptr || base->FinishTime != src.FinishTime)
|
||||
setFinishTime(src.FinishTime);
|
||||
|
||||
if (base == nullptr || base->status != src.status)
|
||||
setStatus(src.status, true, ChangeType::Update);
|
||||
|
||||
if (base == nullptr || base->StartNo != src.StartNo)
|
||||
setStartNo(src.StartNo, ChangeType::Update);
|
||||
|
||||
if (base == nullptr || base->getClub() != src.getClub())
|
||||
setClubId(src.getClubId());
|
||||
|
||||
if (base == nullptr || base->getClass(false) != src.getClass(false))
|
||||
setClassId(src.getClassId(false), false);
|
||||
|
||||
if (base == nullptr || base->inputPlace != src.inputPlace)
|
||||
setInputPlace(src.inputPlace);
|
||||
|
||||
if (base == nullptr || base->inputTime != src.inputTime) {
|
||||
if (inputTime != src.inputTime) {
|
||||
inputTime = src.inputTime;
|
||||
updateChanged();
|
||||
}
|
||||
}
|
||||
setInputStatus(src.inputStatus);
|
||||
setInputPoints(src.inputPoints);
|
||||
if (base == nullptr || base->inputStatus != src.inputStatus)
|
||||
setInputStatus(src.inputStatus);
|
||||
|
||||
if (base == nullptr || base->inputPoints != src.inputPoints)
|
||||
setInputPoints(src.inputPoints);
|
||||
}
|
||||
|
||||
void oRunner::merge(const oBase &input) {
|
||||
oAbstractRunner::merge(input);
|
||||
void oRunner::merge(const oBase &input, const oBase *baseIn) {
|
||||
oAbstractRunner::merge(input, baseIn);
|
||||
|
||||
const oRunner &src = dynamic_cast<const oRunner&>(input);
|
||||
setCourseId(src.getCourseId());
|
||||
if (src.getCardId() != 0)
|
||||
setCard(src.getCardId());
|
||||
setCardNo(src.getCardNo(), false);
|
||||
const oRunner *base = dynamic_cast<const oRunner*>(baseIn);
|
||||
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
if (base == nullptr || base->getCourseId() != src.getCourseId())
|
||||
setCourseId(src.getCourseId());
|
||||
|
||||
if ((base == nullptr && src.getCardId() != 0) || (base != nullptr && base->getCardId() != src.getCardId()))
|
||||
setCard(src.getCardId());
|
||||
|
||||
if (base == nullptr || base->getCardNo() != src.getCardNo())
|
||||
setCardNo(src.getCardNo(), false);
|
||||
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
}
|
||||
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oTeam::merge(const oBase &input) {
|
||||
oAbstractRunner::merge(input);
|
||||
void oTeam::merge(const oBase &input, const oBase *baseIn) {
|
||||
oAbstractRunner::merge(input, baseIn);
|
||||
|
||||
const oTeam &src = dynamic_cast<const oTeam&>(input);
|
||||
const oTeam *base = dynamic_cast<const oTeam*>(baseIn);
|
||||
|
||||
bool same = src.Runners.size() == Runners.size();
|
||||
vector<int> r(src.Runners.size());
|
||||
for (size_t i = 0; i < src.Runners.size(); i++) {
|
||||
if (src.Runners[i]) {
|
||||
r[i] = src.Runners[i]->Id;
|
||||
src.Runners[i]->tInTeam = nullptr;
|
||||
auto getRId = [](const oTeam &t, int ix) {
|
||||
pRunner r = t.getRunner(ix);
|
||||
return r ? r->getId() : 0;
|
||||
};
|
||||
|
||||
bool chR;
|
||||
if (base) {
|
||||
chR = base->Runners.size() != src.Runners.size();
|
||||
if (!chR) {
|
||||
for (size_t i = 0; i < src.Runners.size(); i++) {
|
||||
if (getRId(src, i) != getRId(*base, i))
|
||||
chR = true;
|
||||
}
|
||||
}
|
||||
if (same) {
|
||||
int rc = Runners[i] ? Runners[i]->Id : 0;
|
||||
if (rc != r[i])
|
||||
same = false;
|
||||
}
|
||||
else chR = true;
|
||||
|
||||
if (chR) {
|
||||
bool same = src.Runners.size() == Runners.size();
|
||||
vector<int> r(src.Runners.size());
|
||||
for (size_t i = 0; i < src.Runners.size(); i++) {
|
||||
if (src.Runners[i]) {
|
||||
r[i] = src.Runners[i]->Id;
|
||||
src.Runners[i]->tInTeam = nullptr;
|
||||
}
|
||||
if (same) {
|
||||
int rc = Runners[i] ? Runners[i]->Id : 0;
|
||||
if (rc != r[i])
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!same) {
|
||||
importRunners(r);
|
||||
updateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
importRunners(r);
|
||||
if (!same)
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
updateChanged();
|
||||
}
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oControl::merge(const oBase &input) {
|
||||
void oControl::merge(const oBase &input, const oBase *base) {
|
||||
const oControl &src = dynamic_cast<const oControl&>(input);
|
||||
if (src.Name.length() > 0)
|
||||
setName(src.Name);
|
||||
setNumbers(src.codeNumbers());
|
||||
setStatus(src.getStatus());
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
}
|
||||
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oCourse::merge(const oBase &input) {
|
||||
void oCourse::merge(const oBase &input, const oBase *baseIn) {
|
||||
const oCourse &src = dynamic_cast<const oCourse&>(input);
|
||||
const oCourse *base = dynamic_cast<const oCourse*>(baseIn);
|
||||
|
||||
if (src.Name.length() > 0)
|
||||
if ((base == nullptr || base->Name != src.Name) && (src.Name.length() > 0))
|
||||
setName(src.Name);
|
||||
setLength(src.Length);
|
||||
if (!base || base->Length != src.Length)
|
||||
setLength(src.Length);
|
||||
|
||||
importControls(src.getControls(), true, false);
|
||||
importLegLengths(src.getLegLengths(), true);
|
||||
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
}
|
||||
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oClass::merge(const oBase &input) {
|
||||
void oClass::merge(const oBase &input, const oBase *base) {
|
||||
const oClass &src = dynamic_cast<const oClass&>(input);
|
||||
|
||||
if (src.Name.length() > 0)
|
||||
@ -1351,25 +1467,23 @@ void oClass::merge(const oBase &input) {
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
}
|
||||
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oClub::merge(const oBase &input) {
|
||||
void oClub::merge(const oBase &input, const oBase *base) {
|
||||
const oClub &src = dynamic_cast<const oClub&>(input);
|
||||
|
||||
setName(src.getName());
|
||||
if (memcmp(oData, src.oData, sizeof(oData)) != 0) {
|
||||
memcpy(oData, src.oData, sizeof(oData));
|
||||
if (getDI().merge(input, base))
|
||||
updateChanged();
|
||||
}
|
||||
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oCard::merge(const oBase &input) {
|
||||
void oCard::merge(const oBase &input, const oBase *base) {
|
||||
const oCard &src = dynamic_cast<const oCard&>(input);
|
||||
|
||||
setCardNo(src.getCardNo());
|
||||
@ -1384,19 +1498,19 @@ void oCard::merge(const oBase &input) {
|
||||
synchronize(true);
|
||||
}
|
||||
|
||||
void oPunch::merge(const oBase &input) {
|
||||
void oPunch::merge(const oBase &input, const oBase *base) {
|
||||
const oPunch &src = dynamic_cast<const oPunch&>(input);
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
|
||||
void oFreePunch::merge(const oBase &input) {
|
||||
void oFreePunch::merge(const oBase &input, const oBase *base) {
|
||||
const oFreePunch &src = dynamic_cast<const oFreePunch&>(input);
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
|
||||
void oEvent::merge(const oBase &srcIn) {
|
||||
void oEvent::merge(const oBase &srcIn, const oBase *base) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1113,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 && r->getStatusComputed() != StatusNoTiming) {
|
||||
if (r->getFinishTime() > 0 && r->getStatusComputed() != StatusNoTiming && !r->noTiming()) {
|
||||
xml.write("Finish", r->getFinishTimeS());
|
||||
xml.write("RunningTime", r->getRunningTimeS(true));
|
||||
xml.write("Place", r->getPlaceS());
|
||||
@ -1127,7 +1127,8 @@ void RestServer::lookup(oEvent &oe, const string &what, const multimap<string, s
|
||||
}
|
||||
if ((r->getFinishTime() > 0 || r->getCard() != nullptr) &&
|
||||
r->getCourse(false) &&
|
||||
r->getStatusComputed() != StatusNoTiming) {
|
||||
r->getStatusComputed() != StatusNoTiming &&
|
||||
!r->noTiming()) {
|
||||
auto &sd = r->getSplitTimes(false);
|
||||
vector<int> after;
|
||||
r->getLegTimeAfter(after);
|
||||
|
||||
@ -2527,3 +2527,7 @@ Tjänstebeställningar (IOF XML) = Tjänstebeställningar (IOF XML)
|
||||
Tjänster (IOF XML) = Tjänster (IOF XML)
|
||||
Flytta deltagare från överfulla grupper = Flytta deltagare från överfulla grupper
|
||||
Lotta med startgrupper = Lotta med startgrupper
|
||||
Startgrupp med id X tilldelad Y finns inte = Startgrupp med id X definierad för Y finns inte
|
||||
Använd om möjligt samma dator som användes vid senaste importen = Använd om möjligt samma dator som användes vid senaste importen
|
||||
Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen
|
||||
Varning: Kunde inte hitta föregående version av tävlingen (X) = Varning: Kunde inte hitta föregående version av tävlingen (X)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user