diff --git a/code/TabCompetition.cpp b/code/TabCompetition.cpp index 3dc199d..3cc3d26 100644 --- a/code/TabCompetition.cpp +++ b/code/TabCompetition.cpp @@ -1688,7 +1688,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data) else if (bi.id=="BrowseExport" || bi.id=="BrowseExportResult") { int filterIndex = gdi.getSelectedItem("Type").first; vector< pair > ext; - ImportFormats::getExportFilters(bi.id=="BrowseExport", ext); + ImportFormats::getExportFilters(bi.id!="BrowseExport", ext); /*if (bi.id=="BrowseExport") { ext.push_back(make_pair("IOF Startlista (xml)", "*.xml")); ext.push_back(make_pair("OE Semikolonseparerad (csv)", "*.csv")); diff --git a/code/TabSI.cpp b/code/TabSI.cpp index 024ea54..f30eb44 100644 --- a/code/TabSI.cpp +++ b/code/TabSI.cpp @@ -632,8 +632,16 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) //We have a match! string club = gdi.getText("Club", true); - if (club.length()==0 && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) - club=lang.tl("Klubblös"); + if (club.length()==0 && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) { + pClub noClub = oe->getClub(oe->getVacantClub(true)); + if (noClub) { + noClub->synchronize(); + club = noClub->getName(); + } + else + club=lang.tl("Klubblös"); + } + int year = 0; pRunner r=gEvent->addRunner(gdi.getText("Runners"), club, classes[0]->getId(), activeSIC.CardNumber, year, true); @@ -833,7 +841,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) { string cname = gdi.getText("Club", true); - if (cname.empty()) { + if (!cname.empty()) { pClub club = oe->getClubCreate(0, cname); clubId = club->getId(); } @@ -860,7 +868,8 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) di.setInt("Fee", lastFeeNum); r->setFlag(oRunner::FlagFeeSpecified, true); - writePayMode(gdi, lastFeeNum + (cardFee > 0 ? cardFee : 0), *r); + int totFee = lastFeeNum + (cardFee > 0 ? cardFee : 0); + writePayMode(gdi, totFee, *r); di.setString("Phone", gdi.getText("Phone")); r->setFlag(oRunner::FlagTransferSpecified, gdi.hasField("AllStages")); @@ -897,6 +906,11 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) if (r->getDI().getInt("Paid")>0) info += lang.tl(", Betalat") + pm; + bool warnPayment = r->getDI().getInt("Paid") < totFee && ( + r->getClubRef() == 0 || + r->getClubId() == oe->getVacantClubIfExist(true) || + r->getClubId() == oe->getVacantClubIfExist(false)); + if (bib.length()>0) info+=bib; @@ -910,6 +924,10 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data) gdi.addStringUT(0, info, 0); gdi.popX(); + if (warnPayment) { + gdi.addString("", fontMediumPlus, "Varning: avgiften kan ej faktureras").setColor(colorRed); + } + generateStartInfo(gdi, *r); gdi.setRestorePoint("EntryLine"); diff --git a/code/csvparser.cpp b/code/csvparser.cpp index 6f12245..34e39fb 100644 --- a/code/csvparser.cpp +++ b/code/csvparser.cpp @@ -285,7 +285,7 @@ bool csvparser::ImportOE_CSV(oEvent &event, const char *file) pr = event.getRunner(id, 0); while (pr) { // Check that the exact match is OK - if (extId != pr->getExtIdentifier()) + if (extId == pr->getExtIdentifier()) break; id++; pr = event.getRunner(id, 0); diff --git a/code/english.lng b/code/english.lng index 57b4811..6599f6b 100644 --- a/code/english.lng +++ b/code/english.lng @@ -2239,3 +2239,4 @@ red channel = red channel blue channel = blue channel Printing failed (X: Y) Z = Printing failed (X: Y) Z prefsNameMode = Name format: 0 = 'Given Family', 1 = 'Family, Given' +Varning: avgiften kan ej faktureras = Warning: cannot generate invoice for this fee diff --git a/code/iof30interface.cpp b/code/iof30interface.cpp index c2c9d7f..6e857b4 100644 --- a/code/iof30interface.cpp +++ b/code/iof30interface.cpp @@ -1395,9 +1395,10 @@ pTeam IOF30Interface::getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, bool if (id) t = oe.getTeam(id); - else + else { t = oe.getTeamByName(name); - + // XXX Check class + } if (!t) { if (id > 0) { oTeam tr(&oe, id); @@ -1628,7 +1629,7 @@ pRunner IOF30Interface::readPerson(gdioutput &gdi, const xmlobject &person) { if (pid) { r = oe.getRunner(pid, 0); while (r) { // Check that the exact match is OK - if (extId != r->getExtIdentifier()) + if (extId == r->getExtIdentifier()) break; pid++; r = oe.getRunner(pid, 0); diff --git a/code/meosversion.cpp b/code/meosversion.cpp index 11945e7..85e79f5 100644 --- a/code/meosversion.cpp +++ b/code/meosversion.cpp @@ -28,7 +28,7 @@ //V31: a //V33: abcde int getMeosBuild() { - string revision("$Rev: 543 $"); + string revision("$Rev: 608 $"); return 174 + atoi(revision.substr(5, string::npos).c_str()); } @@ -38,14 +38,14 @@ int getMeosBuild() { //V31: abcde //V32: abcdefgh //V33: abcdefghij -//V34: abcdfg +//V34: abcdfgh string getMeosDate() { - string date("$Date: 2017-03-25 20:00:02 +0100 (lö, 25 mar 2017) $"); + string date("$Date: 2017-08-27 21:13:26 +0200 (sö, 27 aug 2017) $"); return date.substr(7,10); } string getBuildType() { - return ""; // No parantheses (...) + return "U2"; // No parantheses (...) } string getMajorVersion() { @@ -169,4 +169,10 @@ void getSupporters(vector &supp) supp.push_back("O-travel"); supp.push_back("Bengt Bengtsson"); supp.push_back("OK Landehof"); + supp.push_back("OK Orinto"); + supp.push_back("Bredaryds SOK"); + supp.push_back("Thore Nilsson, Uddevalla OK"); + supp.push_back("Timrå SOK"); + supp.push_back("Åke Larsson, OK Hedströmmen"); + supp.push_back("Avesta OK"); } diff --git a/code/oClub.cpp b/code/oClub.cpp index 5535d50..c12ea08 100644 --- a/code/oClub.cpp +++ b/code/oClub.cpp @@ -53,7 +53,7 @@ oClub::oClub(oEvent *poe, int id): oBase(poe) { getDI().initData(); Id=id; - if (id != cVacantId) + if (id != cVacantId && id != cNoClubId) oe->qFreeClubId = max(id, oe->qFreeClubId); } @@ -191,8 +191,9 @@ pClub oEvent::getClubCreate(int Id, const string &CreateName) } } if (CreateName.empty()) { + int id = oe->getVacantClub(true); //Not found. Auto add... - return getClubCreate(Id, lang.tl("Klubblös")); + return getClubCreate(id, lang.tl("Klubblös")); } else { oClubList::iterator it; @@ -1053,7 +1054,7 @@ void oEvent::setupClubInfoData() { bool oClub::isVacant() const { - return getId() == oe->getVacantClubIfExist(); + return getId() == oe->getVacantClubIfExist(false); } void oClub::changeId(int newId) { diff --git a/code/oEvent.cpp b/code/oEvent.cpp index b51169a..1f28045 100644 --- a/code/oEvent.cpp +++ b/code/oEvent.cpp @@ -116,6 +116,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi) hMod=0; ZeroTime=0; vacantId = 0; + noClubId = 0; dataRevision = 0; sqlCounterRunners=0; sqlCounterClasses=0; @@ -1665,7 +1666,7 @@ pRunner oEvent::addRunner(const oRunner &r, bool updateStartNo) { } pRunner oEvent::addRunnerVacant(int classId) { - pRunner r=addRunner(lang.tl("Vakant"), getVacantClub(), classId, 0,0, true); + pRunner r=addRunner(lang.tl("Vakant"), getVacantClub(false), classId, 0,0, true); if (r) { r->apply(false, 0, false); r->synchronize(true); @@ -1771,7 +1772,7 @@ void oEvent::updateFreeId(oBase *obj) qFreeControlId=max(obj->Id, qFreeControlId); } else if (typeid(*obj)==typeid(oClub)){ - if (obj->Id != cVacantId) + if (obj->Id != cVacantId && obj->Id != cNoClubId) qFreeClubId=max(obj->Id, qFreeClubId); } else if (typeid(*obj)==typeid(oCard)){ @@ -1822,7 +1823,7 @@ void oEvent::updateFreeId() oClubList::iterator it; qFreeClubId=0; for (it=Clubs.begin(); it != Clubs.end(); ++it) { - if (it->Id != cVacantId) + if (it->Id != cVacantId && it->Id != cNoClubId) qFreeClubId=max(qFreeClubId, it->Id); } } @@ -1847,42 +1848,89 @@ void oEvent::updateFreeId() } } -int oEvent::getVacantClub() -{ - if (vacantId > 0) +int oEvent::getVacantClub(bool returnNoClubClub) { + if (returnNoClubClub) { + if (noClubId > 0) { + pClub pc = getClub(noClubId); + if (pc != 0 && !pc->isRemoved()) + return noClubId; + } + pClub pc = getClub("Klubblös"); + if (pc == 0) + pc = getClub("No club"); //eng + if (pc == 0) + pc = getClub(lang.tl("Klubblös")); //other lang? + + if (pc == 0) + pc=getClubCreate(cNoClubId, lang.tl("Klubblös")); + + noClubId = pc->getId(); + return noClubId; + } + else { + if (vacantId > 0) { + pClub pc = getClub(vacantId); + if (pc != 0 && !pc->isRemoved()) + return vacantId; + } + pClub pc = getClub("Vakant"); + if (pc == 0) + pc = getClub("Vacant"); //eng + if (pc == 0) + pc = getClub(lang.tl("Vakant")); //other lang? + + if (pc == 0) + pc=getClubCreate(cVacantId, lang.tl("Vakant")); + + vacantId = pc->getId(); return vacantId; - - pClub pc = getClub("Vakant"); - if (pc == 0) - pc = getClub("Vacant"); //eng - if (pc == 0) - pc = getClub(lang.tl("Vakant")); //other lang? - - if (pc == 0) - pc=getClubCreate(cVacantId, lang.tl("Vakant")); - - vacantId = pc->getId(); - return vacantId; + } } -int oEvent::getVacantClubIfExist() const +int oEvent::getVacantClubIfExist(bool returnNoClubClub) const { - if (vacantId > 0) - return vacantId; - if (vacantId == -1) - return 0; - pClub pc=getClub("Vakant"); - if (pc == 0) - pc = getClub("Vacant"); - if (pc == 0) - pc = getClub(lang.tl("Vakant")); //other lang? + if (returnNoClubClub) { + if (noClubId > 0) { + pClub pc = getClub(noClubId); + if (pc != 0 && !pc->isRemoved()) + return noClubId; + } + if (noClubId == -1) + return 0; + pClub pc=getClub("Klubblös"); + if (pc == 0) + pc = getClub("Klubblös"); + if (pc == 0) + pc = getClub(lang.tl("Klubblös")); //other lang? - if (!pc) { - vacantId = -1; - return 0; + if (!pc) { + noClubId = -1; + return 0; + } + noClubId = pc->getId(); + return noClubId; + } + else { + if (vacantId > 0) { + pClub pc = getClub(vacantId); + if (pc != 0 && !pc->isRemoved()) + return vacantId; + } + if (vacantId == -1) + return 0; + pClub pc=getClub("Vakant"); + if (pc == 0) + pc = getClub("Vacant"); + if (pc == 0) + pc = getClub(lang.tl("Vakant")); //other lang? + + if (!pc) { + vacantId = -1; + return 0; + } + vacantId = pc->getId(); + return vacantId; } - vacantId = pc->getId(); - return vacantId; } pCard oEvent::allocateCard(pRunner owner) @@ -2417,6 +2465,9 @@ void oEvent::removeClub(int Id) } if (vacantId == Id) vacantId = 0; // Clear vacant id + + if (noClubId == Id) + noClubId = 0; } void oEvent::removeCard(int Id) @@ -3371,6 +3422,7 @@ void oEvent::clear() sqlUpdateTeams.clear(); vacantId = 0; + noClubId = 0; oEventData->initData(this, sizeof(oData)); timelineClasses.clear(); timeLineEvents.clear(); diff --git a/code/oEvent.h b/code/oEvent.h index fa80811..ea2f0a1 100644 --- a/code/oEvent.h +++ b/code/oEvent.h @@ -50,6 +50,7 @@ #include #define cVacantId 888888888 +#define cNoClubId 999999999 class MeOSFileLock; class RunnerDB; @@ -237,10 +238,9 @@ protected: void generateFixedList(gdioutput &gdi, const oListInfo &li); void startReconnectDaemon(); - int getVacantClub(); // Create vacant club if it does not exist - int getVacantClubIfExist() const; - + mutable int vacantId; //Cached vacant id + mutable int noClubId; //Cached no club id string Name; string Annotation; @@ -472,6 +472,9 @@ protected: // Temporarily disable recaluclate leader times bool disableRecalculate; public: + + int getVacantClub(bool returnNoClubClub); // Create vacant club if it does not exist + int getVacantClubIfExist(bool returnNoClubClub) const; enum NameMode { FirstLast, diff --git a/code/oEventDraw.cpp b/code/oEventDraw.cpp index 4a88a88..edca0a5 100644 --- a/code/oEventDraw.cpp +++ b/code/oEventDraw.cpp @@ -673,7 +673,7 @@ void oEvent::drawList(const vector &spec, assert(pairSize > 0); oRunnerList::iterator it; - int VacantClubId=getVacantClub(); + int VacantClubId=getVacantClub(false); map clsId2Ix; set clsIdClearVac; diff --git a/code/oListInfo.cpp b/code/oListInfo.cpp index 6c7277a..36c9625 100644 --- a/code/oListInfo.cpp +++ b/code/oListInfo.cpp @@ -2536,12 +2536,12 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form continue; if (li.filter(EFilterVacant)) { - if (it->getId() == getVacantClub()) + if (it->getId() == getVacantClub(false)) continue; } if (li.filter(EFilterOnlyVacant)) { - if (it->getId() != getVacantClub()) + if (it->getId() != getVacantClub(false)) continue; } diff --git a/code/oReport.cpp b/code/oReport.cpp index 455763f..6dbfa90 100644 --- a/code/oReport.cpp +++ b/code/oReport.cpp @@ -340,7 +340,7 @@ void oEvent::generatePreReport(gdioutput &gdi) { CurrentSortOrder=SortByName; Runners.sort(); - int lVacId = getVacantClub(); + int lVacId = getVacantClub(false); oRunnerList::iterator r_it; oTeamList::iterator t_it; diff --git a/code/oRunner.cpp b/code/oRunner.cpp index b1e85c2..5d9e298 100644 --- a/code/oRunner.cpp +++ b/code/oRunner.cpp @@ -2694,7 +2694,7 @@ const vector< pair > &oEvent::fillRunners(vector< pair > &oEvent::fillRunners(vector< pairskip() || (showAll && !it->isRemoved())) { - if ( it->getClubId() != lVacId ) + if ( it->getClubId() != lVacId || lVacId == 0) out.push_back(make_pair(it->getUIName(), it->Id)); else { sprintf_s(bf, "%s (%s)", it->getUIName().c_str(), it->getClass().c_str()); @@ -3328,7 +3328,7 @@ string oRunner::getPunchTimeS(int controlNumber, bool normalized) const bool oAbstractRunner::isVacant() const { - return getClubId()==oe->getVacantClubIfExist(); + return getClubId()==oe->getVacantClubIfExist(false); } bool oRunner::needNoCard() const { diff --git a/code/printer.cpp b/code/printer.cpp index cc18677..d4be995 100644 --- a/code/printer.cpp +++ b/code/printer.cpp @@ -645,13 +645,16 @@ void PageInfo::renderPages(const list &tl, const TextInfo &text = *it; if (text.format == 10) continue; + if (text.format != pageNewPage && text.format != pagePageInfo) { + if (currentYP > text.yp) { + needSort = true; + } - if (currentYP > text.yp) { - needSort = true; + minX = min(minX, (float)it->textRect.left); + top = min(top, text.yp); } - minX = min(minX, (float)it->textRect.left); - top = min(top, text.yp); currentYP = text.yp; + indexedTL.push_back(PrintItemInfo(currentYP, &text)); } diff --git a/code/swedish.lng b/code/swedish.lng index b5f2b4d..14a82e1 100644 --- a/code/swedish.lng +++ b/code/swedish.lng @@ -2239,3 +2239,4 @@ red channel = r blue channel = blå kanal Printing failed (X: Y) Z = Utskrift misslyckades (X: Y) Z prefsNameMode = Namnformat: 0 = 'Förnamn Efternamn', 1 = 'Efternamn, Förnamn' +Varning: avgiften kan ej faktureras = Varning: avgiften kan ej faktureras diff --git a/code/xmlparser.cpp b/code/xmlparser.cpp index 21aa12b..961fe59 100644 --- a/code/xmlparser.cpp +++ b/code/xmlparser.cpp @@ -717,9 +717,9 @@ string &xmlobject::getObjectString(const char *pname, string &out) const { xmlobject x=getObject(pname); if (x) { - const char *bf = x.get(); + const char *bf = x.getRaw(); if (bf) { - parser->convertString(x.get(), parser->strbuff, buff_pre_alloc); + parser->convertString(x.getRaw(), parser->strbuff, buff_pre_alloc); out = parser->strbuff; return out; } @@ -740,7 +740,7 @@ char *xmlobject::getObjectString(const char *pname, char *out, int maxlen) const { xmlobject x=getObject(pname); if (x) { - const char *bf = x.get(); + const char *bf = x.getRaw(); if (bf) { parser->convertString(bf, out, maxlen); return out; @@ -757,6 +757,28 @@ char *xmlobject::getObjectString(const char *pname, char *out, int maxlen) const return out; } +const char *xmlobject::get() const +{ + const char *ptr = getRaw(); + if (ptr == 0) + return 0; + static char buff[buff_pre_alloc]; + if (parser->isUTF) { + int len = strlen(ptr); + len = min(len+1, buff_pre_alloc-10); + int wlen = MultiByteToWideChar(CP_UTF8, 0, ptr, len, parser->strbuffw, buff_pre_alloc); + parser->strbuffw[wlen-1] = 0; + for (int k = 0; k< wlen; k++) { + buff[k] = parser->strbuffw[k] & 0xFF; + } + } + else { + return ptr; + } + return buff; +} + + const char *xmlattrib::get() const { if (data) diff --git a/code/xmlparser.h b/code/xmlparser.h index 8bc9732..6fbcce4 100644 --- a/code/xmlparser.h +++ b/code/xmlparser.h @@ -103,6 +103,7 @@ protected: bool isUTF; char strbuff[buff_pre_alloc]; // Temporary buffer for processing (no threading allowed) + wchar_t strbuffw[buff_pre_alloc]; // Temporary buffer for processing (no threading allowed) ProgressWindow *progress; int lastIndex; @@ -204,7 +205,8 @@ public: return n[0] == pname[0] && strcmp(n, pname)==0; } - const char *get() const {return parser->xmlinfo[index].data;} + const char *getRaw() const {return parser->xmlinfo[index].data;} + const char *get() const; int getInt() const {const char *d = parser->xmlinfo[index].data; return d ? atoi(d) : 0;} __int64 getInt64() const {const char *d = parser->xmlinfo[index].data;