MeOS V4.0, RC1
This commit is contained in:
parent
d06f4cbd7b
commit
403373fcc6
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -261,6 +261,7 @@
|
|||||||
<ClInclude Include="binencoder.h" />
|
<ClInclude Include="binencoder.h" />
|
||||||
<ClInclude Include="classconfiginfo.h" />
|
<ClInclude Include="classconfiginfo.h" />
|
||||||
<ClInclude Include="csvparser.h" />
|
<ClInclude Include="csvparser.h" />
|
||||||
|
<ClInclude Include="datadefiners.h" />
|
||||||
<ClInclude Include="download.h" />
|
<ClInclude Include="download.h" />
|
||||||
<ClInclude Include="gdiconstants.h" />
|
<ClInclude Include="gdiconstants.h" />
|
||||||
<ClInclude Include="gdifonts.h" />
|
<ClInclude Include="gdifonts.h" />
|
||||||
|
|||||||
@ -534,6 +534,16 @@ bool MeosSQL::openDB(oEvent *oe)
|
|||||||
upgradeTimeFormat(dbname);
|
upgradeTimeFormat(dbname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version <= 94) {
|
||||||
|
auto query = con->query();
|
||||||
|
string v = "ALTER TABLE oRunner MODIFY COLUMN Rank INT NOT NULL DEFAULT 0";
|
||||||
|
try {
|
||||||
|
query.execute(v);
|
||||||
|
}
|
||||||
|
catch (const Exception&) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tookLock) {
|
if (tookLock) {
|
||||||
con->query().exec("UNLOCK TABLES");
|
con->query().exec("UNLOCK TABLES");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,9 +111,8 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, State state) {
|
|||||||
else {
|
else {
|
||||||
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
||||||
auto per = server->getEntryPermission();
|
auto per = server->getEntryPermission();
|
||||||
if (get<RestServer::EntryPermissionType>(per) != RestServer::EntryPermissionType::None)
|
if (get<RestServer::EntryPermissionType>(per) != RestServer::EntryPermissionType::None) {
|
||||||
disablePermisson = false;
|
disablePermisson = false;
|
||||||
else {
|
|
||||||
gdi.selectItemByData("PermissionPerson", size_t(get<RestServer::EntryPermissionType>(per)));
|
gdi.selectItemByData("PermissionPerson", size_t(get<RestServer::EntryPermissionType>(per)));
|
||||||
gdi.selectItemByData("PermissionClass", size_t(get<RestServer::EntryPermissionClass>(per)));
|
gdi.selectItemByData("PermissionClass", size_t(get<RestServer::EntryPermissionClass>(per)));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,8 +61,6 @@ gdioutput *createExtraWindow(const string &tag, const wstring &title, int max_x
|
|||||||
gdioutput *getExtraWindow(const string &tag, bool toForeGround);
|
gdioutput *getExtraWindow(const string &tag, bool toForeGround);
|
||||||
string uniqueTag(const char *base);
|
string uniqueTag(const char *base);
|
||||||
|
|
||||||
void LoadPage(const string &name);
|
|
||||||
|
|
||||||
wstring getTempFile();
|
wstring getTempFile();
|
||||||
wstring getTempPath();
|
wstring getTempPath();
|
||||||
void removeTempFile(const wstring &file); // Delete a temporyary
|
void removeTempFile(const wstring &file); // Delete a temporyary
|
||||||
|
|||||||
@ -77,11 +77,11 @@ protected:
|
|||||||
TabBase * const tab = nullptr;
|
TabBase * const tab = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const string name;
|
const wstring name;
|
||||||
const int imageId = -1;
|
const int imageId = -1;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
|
|
||||||
TabObject(TabBase *t, string n, int imageId) : name(n), tab(t), imageId(imageId) {}
|
TabObject(TabBase *t, wstring n, int imageId) : name(n), tab(t), imageId(imageId) {}
|
||||||
|
|
||||||
void setId(int i){id=i; if (tab) tab->tabId=id;}
|
void setId(int i){id=i; if (tab) tab->tabId=id;}
|
||||||
|
|
||||||
|
|||||||
@ -54,9 +54,6 @@ TabCourse::~TabCourse(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadCoursePage(gdioutput &gdi);
|
|
||||||
void LoadClassPage(gdioutput &gdi);
|
|
||||||
|
|
||||||
void TabCourse::selectCourse(gdioutput &gdi, pCourse pc)
|
void TabCourse::selectCourse(gdioutput &gdi, pCourse pc)
|
||||||
{
|
{
|
||||||
if (gdi.hasWidget("Rogaining")) {
|
if (gdi.hasWidget("Rogaining")) {
|
||||||
@ -473,6 +470,29 @@ int TabCourse::courseCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
xml.closeOut();
|
xml.closeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (bi.id == "DeleteAll") {
|
||||||
|
if (!gdi.ask(L"Vill du ta bort alla banor från tävlingen?"))
|
||||||
|
return 0;
|
||||||
|
// Clear all course references
|
||||||
|
vector<pRunner> rr;
|
||||||
|
oe->getRunners(0, 0, rr);
|
||||||
|
for (pRunner r : rr) {
|
||||||
|
r->setCourseId(0);
|
||||||
|
}
|
||||||
|
vector<pClass> cc;
|
||||||
|
oe->getClasses(cc, true);
|
||||||
|
for (pClass c : cc) {
|
||||||
|
c->setCourse(nullptr);
|
||||||
|
for (int i = 0; i < c->getNumStages(); i++)
|
||||||
|
c->clearStageCourses(i);
|
||||||
|
}
|
||||||
|
vector<pCourse> crs;
|
||||||
|
oe->getCourses(crs);
|
||||||
|
for (pCourse c : crs) {
|
||||||
|
oe->removeCourse(c->getId());
|
||||||
|
}
|
||||||
|
loadPage(gdi);
|
||||||
|
}
|
||||||
else if (bi.id=="ImportCourses") {
|
else if (bi.id=="ImportCourses") {
|
||||||
setupCourseImport(gdi, CourseCB);
|
setupCourseImport(gdi, CourseCB);
|
||||||
}
|
}
|
||||||
@ -651,7 +671,7 @@ int TabCourse::courseCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
refreshCourse(gdi.getText("Controls"), gdi);
|
refreshCourse(gdi.getText("Controls"), gdi);
|
||||||
}
|
}
|
||||||
else if (bi.id=="Cancel"){
|
else if (bi.id=="Cancel"){
|
||||||
LoadPage("Banor");
|
loadPage(gdi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type==GUI_LISTBOX){
|
else if (type==GUI_LISTBOX){
|
||||||
@ -780,6 +800,8 @@ bool TabCourse::loadPage(gdioutput &gdi) {
|
|||||||
gdi.addButton("DrawCourse", "Lotta starttider..", CourseCB);
|
gdi.addButton("DrawCourse", "Lotta starttider..", CourseCB);
|
||||||
gdi.disableInput("DrawCourse");
|
gdi.disableInput("DrawCourse");
|
||||||
}
|
}
|
||||||
|
gdi.addButton("DeleteAll", "Radera alla...", CourseCB);
|
||||||
|
|
||||||
gdi.newColumn();
|
gdi.newColumn();
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
|
|
||||||
|
|||||||
@ -2634,7 +2634,29 @@ bool TabList::loadPage(gdioutput &gdi)
|
|||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
|
|
||||||
|
bool hasVac = false;
|
||||||
|
bool hasAPIEntry = false;
|
||||||
|
bool hasModifiedCard = false;
|
||||||
|
{
|
||||||
|
vector<pRunner> rr;
|
||||||
|
oe->getRunners(0, 0, rr, false);
|
||||||
|
for (pRunner r : rr) {
|
||||||
|
if (r->isVacant())
|
||||||
|
hasVac = true;
|
||||||
|
if (r->hasFlag(oRunner::FlagAddedViaAPI))
|
||||||
|
hasAPIEntry = true;
|
||||||
|
if (r->getCard() && r->getCard()->isOriginalCard() == oCard::PunchOrigin::Manual)
|
||||||
|
hasModifiedCard = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasModifiedCard) {
|
||||||
|
gdi.addButton("GenLst:modifiedcard", "Modifierade resultat", ListsCB);
|
||||||
|
checkWidth(gdi);
|
||||||
|
}
|
||||||
|
|
||||||
gdi.addButton("InForestList", "Kvar-i-skogen", ListsCB, "tooltip:inforest").setExtra(IgnoreLimitPer);
|
gdi.addButton("InForestList", "Kvar-i-skogen", ListsCB, "tooltip:inforest").setExtra(IgnoreLimitPer);
|
||||||
|
|
||||||
if (cnf.hasIndividual()) {
|
if (cnf.hasIndividual()) {
|
||||||
gdi.addButton("PriceList", "Prisutdelningslista", ListsCB);
|
gdi.addButton("PriceList", "Prisutdelningslista", ListsCB);
|
||||||
}
|
}
|
||||||
@ -2661,25 +2683,6 @@ bool TabList::loadPage(gdioutput &gdi)
|
|||||||
gdi.addButton("GenLst:teamchanges", "Lagändringblankett", ListsCB).setExtra(AddTeamClasses | ForcePageBreak);
|
gdi.addButton("GenLst:teamchanges", "Lagändringblankett", ListsCB).setExtra(AddTeamClasses | ForcePageBreak);
|
||||||
checkWidth(gdi);
|
checkWidth(gdi);
|
||||||
}
|
}
|
||||||
bool hasVac = false;
|
|
||||||
bool hasAPIEntry = false;
|
|
||||||
{
|
|
||||||
vector<pRunner> rr;
|
|
||||||
oe->getRunners(0, 0, rr, false);
|
|
||||||
for (pRunner r : rr) {
|
|
||||||
if (r->isVacant()) {
|
|
||||||
hasVac = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pRunner r : rr) {
|
|
||||||
if (r->hasFlag(oRunner::FlagAddedViaAPI)) {
|
|
||||||
hasAPIEntry = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasVac) {
|
if (hasVac) {
|
||||||
gdi.addButton("GenLst:vacnacy", "Vakanser", ListsCB);
|
gdi.addButton("GenLst:vacnacy", "Vakanser", ListsCB);
|
||||||
|
|||||||
@ -49,9 +49,11 @@
|
|||||||
#include "meosexception.h"
|
#include "meosexception.h"
|
||||||
#include "MeOSFeatures.h"
|
#include "MeOSFeatures.h"
|
||||||
#include "autocomplete.h"
|
#include "autocomplete.h"
|
||||||
|
#include "datadefiners.h"
|
||||||
#include "RunnerDB.h"
|
#include "RunnerDB.h"
|
||||||
|
|
||||||
int SportIdentCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
|
int SportIdentCB(gdioutput *gdi, GuiEventType type, BaseInfo *data);
|
||||||
|
shared_ptr<RankScoreFormatter> TabRunner::rankFormatter;
|
||||||
|
|
||||||
TabRunner::TabRunner(oEvent *poe):TabBase(poe) {
|
TabRunner::TabRunner(oEvent *poe):TabBase(poe) {
|
||||||
clearCompetitionData();
|
clearCompetitionData();
|
||||||
@ -359,7 +361,7 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
|||||||
|
|
||||||
loadExtraFields(gdi, r);
|
loadExtraFields(gdi, r);
|
||||||
|
|
||||||
renderComments(gdi, *r);
|
renderComments(gdi, *r, true, true);
|
||||||
|
|
||||||
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
||||||
if (gdi_settings) {
|
if (gdi_settings) {
|
||||||
@ -1073,7 +1075,7 @@ int TabRunner::runnerCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
pRunner r = oe->getRunner(runnerId, 0);
|
pRunner r = oe->getRunner(runnerId, 0);
|
||||||
if (r && getExtraWindow("comments", true) == nullptr) {
|
if (r && getExtraWindow("comments", true) == nullptr) {
|
||||||
gdioutput* settings = createExtraWindow("comments", L"Kommentarer", gdi.scaleLength(550), gdi.scaleLength(350), true);
|
gdioutput* settings = createExtraWindow("comments", L"Kommentarer", gdi.scaleLength(550), gdi.scaleLength(350), true);
|
||||||
TabRunner::loadComments(*settings, *r);
|
TabRunner::loadComments(*settings, *r, make_shared<CommentHandler>(*r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bi.id=="NoStart") {
|
else if (bi.id=="NoStart") {
|
||||||
@ -1424,8 +1426,10 @@ int TabRunner::runnerCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type==GUI_CLEAR) {
|
else if (type==GUI_CLEAR) {
|
||||||
gdioutput *gdi_settings = getExtraWindow("ecosettings", false);
|
if (gdioutput* gdi_settings = getExtraWindow("ecosettings", false); gdi_settings)
|
||||||
if (gdi_settings)
|
gdi_settings->closeWindow();
|
||||||
|
|
||||||
|
if (gdioutput* gdi_settings = getExtraWindow("comments", false); gdi_settings)
|
||||||
gdi_settings->closeWindow();
|
gdi_settings->closeWindow();
|
||||||
|
|
||||||
if (runnerId>0 && currentMode == 0)
|
if (runnerId>0 && currentMode == 0)
|
||||||
@ -3325,8 +3329,12 @@ void TabRunner::loadExtraFields(gdioutput& gdi, const oBase* r) {
|
|||||||
if (gdi.hasWidget("Phone"))
|
if (gdi.hasWidget("Phone"))
|
||||||
gdi.setText("Phone", r ? r->getDCI().getString("Phone") : L"");
|
gdi.setText("Phone", r ? r->getDCI().getString("Phone") : L"");
|
||||||
|
|
||||||
if (gdi.hasWidget("Rank"))
|
if (gdi.hasWidget("Rank")) {
|
||||||
gdi.setTextZeroBlank("Rank", r ? r->getDCI().getInt("Rank") : 0);
|
wstring out;
|
||||||
|
if (r)
|
||||||
|
out = rankFormatter->formatData(r);
|
||||||
|
gdi.setText("Rank", out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::saveExtraFields(gdioutput& gdi, oBase &r) {
|
void TabRunner::saveExtraFields(gdioutput& gdi, oBase &r) {
|
||||||
@ -3353,8 +3361,11 @@ void TabRunner::saveExtraFields(gdioutput& gdi, oBase &r) {
|
|||||||
if (gdi.hasWidget("Phone"))
|
if (gdi.hasWidget("Phone"))
|
||||||
di.setString("Phone", gdi.getText("Phone"));
|
di.setString("Phone", gdi.getText("Phone"));
|
||||||
|
|
||||||
if (gdi.hasWidget("Rank"))
|
if (gdi.hasWidget("Rank")) {
|
||||||
di.setInt("Rank", gdi.getTextNo("Rank"));
|
wstring out;
|
||||||
|
rankFormatter->setData(&r, gdi.getText("Rank"), out, 0);
|
||||||
|
}
|
||||||
|
// di.setInt("Rank", gdi.getTextNo("Rank"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::addToolbar(gdioutput &gdi) {
|
void TabRunner::addToolbar(gdioutput &gdi) {
|
||||||
@ -3541,6 +3552,7 @@ void TabRunner::clearCompetitionData() {
|
|||||||
timeToFill = 0;
|
timeToFill = 0;
|
||||||
ownWindow = false;
|
ownWindow = false;
|
||||||
listenToPunches = false;
|
listenToPunches = false;
|
||||||
|
rankFormatter = make_shared<RankScoreFormatter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::autoGrowCourse(gdioutput &gdi) {
|
void TabRunner::autoGrowCourse(gdioutput &gdi) {
|
||||||
@ -3739,7 +3751,6 @@ void TabRunner::CommentHandler::handle(gdioutput& gdi, BaseInfo& info, GuiEventT
|
|||||||
ButtonInfo& bi = dynamic_cast<ButtonInfo&>(info);
|
ButtonInfo& bi = dynamic_cast<ButtonInfo&>(info);
|
||||||
if (bi.id == "Cancel") {
|
if (bi.id == "Cancel") {
|
||||||
gdi.closeWindow();
|
gdi.closeWindow();
|
||||||
gdi.closeWindow();
|
|
||||||
}
|
}
|
||||||
else if (bi.id == "Save") {
|
else if (bi.id == "Save") {
|
||||||
save(gdi);
|
save(gdi);
|
||||||
@ -3748,15 +3759,18 @@ void TabRunner::CommentHandler::handle(gdioutput& gdi, BaseInfo& info, GuiEventT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::CommentHandler::save(gdioutput& gdi) {
|
void TabRunner::CommentHandler::doSave(gdioutput& gdi) {
|
||||||
oAbstractRunner& r = getRunner();
|
oAbstractRunner& r = getRunner();
|
||||||
wstring comment = gdi.getText("Comments");
|
wstring comment = gdi.getText("Comments");
|
||||||
r.getDI().setString("Annotation", getLocalTime() + L"@" + comment);
|
r.getDI().setString("Annotation", getLocalTime() + L"@" + comment);
|
||||||
|
|
||||||
TabRunner::renderComments(oe->gdiBase(), r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::renderComments(gdioutput& gdi, oAbstractRunner& r) {
|
void TabRunner::CommentHandler::save(gdioutput& gdi) {
|
||||||
|
doSave(gdi);
|
||||||
|
TabRunner::renderComments(oe->gdiBase(), getRunner(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabRunner::renderComments(gdioutput& gdi, oAbstractRunner& r, bool newColumn, bool refresh) {
|
||||||
gdi.restore("Annotation", false);
|
gdi.restore("Annotation", false);
|
||||||
gdi.setRestorePoint("Annotation");
|
gdi.setRestorePoint("Annotation");
|
||||||
|
|
||||||
@ -3774,33 +3788,37 @@ void TabRunner::renderComments(gdioutput& gdi, oAbstractRunner& r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
|
if (newColumn)
|
||||||
gdi.newColumn();
|
gdi.newColumn();
|
||||||
|
|
||||||
|
int cx = gdi.getCX();
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
RECT rc;
|
RECT rc;
|
||||||
rc.left = gdi.getCX();
|
rc.left = gdi.getCX();
|
||||||
rc.top = gdi.getCY();
|
rc.top = gdi.getCY();
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
gdi.setCX(gdi.getCX() + gdi.scaleLength(5));
|
gdi.setCX(cx + gdi.scaleLength(5));
|
||||||
|
|
||||||
gdi.addString("", fontMediumPlus, "Kommentarer");
|
gdi.addString("", fontMediumPlus, "Kommentarer");
|
||||||
gdi.addString("", 0, date);
|
gdi.addString("", 0, date);
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.addStringUT(gdi.getCY(), gdi.getCX(), breakLines, an, 200);
|
TextInfo &ti = gdi.addStringUT(gdi.getCY(), gdi.getCX(), breakLines, an, gdi.scaleLength(newColumn ? 200 : 300));
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
rc.bottom = gdi.getCY();
|
rc.bottom = gdi.getCY();
|
||||||
rc.right = gdi.getWidth() + gdi.scaleLength(3);
|
rc.right = max<int>(ti.textRect.right, cx+gdi.scaleLength(150)) + gdi.scaleLength(6);
|
||||||
gdi.addRectangle(rc, GDICOLOR::colorLightYellow);
|
gdi.addRectangle(rc, GDICOLOR::colorLightYellow);
|
||||||
|
|
||||||
|
gdi.setCX(cx);
|
||||||
|
if (refresh)
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRunner::loadComments(gdioutput& gdi, oAbstractRunner& r) {
|
void TabRunner::loadComments(gdioutput& gdi, oAbstractRunner& r, const shared_ptr<CommentHandler>& handler) {
|
||||||
gdi.clearPage(false);
|
gdi.clearPage(false);
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.addString("", fontMediumPlus, L"Kommentarer för X#" + r.getName());
|
gdi.addString("", fontMediumPlus, L"Kommentarer för X#" + r.getName());
|
||||||
|
|
||||||
auto h = make_shared<CommentHandler>(r);
|
|
||||||
wstring an = r.getDCI().getString("Annotation");
|
wstring an = r.getDCI().getString("Annotation");
|
||||||
for (int j = 0; j + 1 < an.length(); j++) {
|
for (int j = 0; j + 1 < an.length(); j++) {
|
||||||
if (an[j] == '@') {
|
if (an[j] == '@') {
|
||||||
@ -3810,8 +3828,8 @@ void TabRunner::loadComments(gdioutput& gdi, oAbstractRunner& r) {
|
|||||||
gdi.addInputBox("Comments", 250, 100, an, nullptr, L"");
|
gdi.addInputBox("Comments", 250, 100, an, nullptr, L"");
|
||||||
|
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.addButton("Cancel", "Avbryt").setCancel().setHandler(h);
|
gdi.addButton("Cancel", "Avbryt").setCancel().setHandler(handler);
|
||||||
gdi.addButton("Save", "Spara").setHandler(h);
|
gdi.addButton("Save", "Spara").setHandler(handler);
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
struct AutoCompleteRecord;
|
struct AutoCompleteRecord;
|
||||||
|
class RankScoreFormatter;
|
||||||
|
|
||||||
class TabRunner :
|
class TabRunner :
|
||||||
public TabBase, AutoCompleteHandler
|
public TabBase, AutoCompleteHandler
|
||||||
@ -87,9 +88,11 @@ private:
|
|||||||
bool savePunchTime(pRunner r, gdioutput &gdi);
|
bool savePunchTime(pRunner r, gdioutput &gdi);
|
||||||
|
|
||||||
PrinterObject splitPrinter;
|
PrinterObject splitPrinter;
|
||||||
|
static shared_ptr<RankScoreFormatter> rankFormatter;
|
||||||
|
|
||||||
void showRunnerReport(gdioutput &gdi);
|
void showRunnerReport(gdioutput &gdi);
|
||||||
|
|
||||||
|
|
||||||
static void runnerReport(oEvent &oe, gdioutput &gdi,
|
static void runnerReport(oEvent &oe, gdioutput &gdi,
|
||||||
int id, bool compactReport,
|
int id, bool compactReport,
|
||||||
int maxWidth,
|
int maxWidth,
|
||||||
@ -132,27 +135,29 @@ private:
|
|||||||
void save(gdioutput &gdi);
|
void save(gdioutput &gdi);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommentHandler : public GuiHandler {
|
|
||||||
int runnerId;
|
|
||||||
bool isTeam = false;
|
|
||||||
oEvent* oe;
|
|
||||||
oAbstractRunner& getRunner() const;
|
|
||||||
public:
|
|
||||||
CommentHandler(oAbstractRunner& r) : oe(r.getEvent()) {
|
|
||||||
runnerId = r.getId(); isTeam = r.isTeam();
|
|
||||||
}
|
|
||||||
void handle(gdioutput& gdi, BaseInfo& info, GuiEventType type);
|
|
||||||
void save(gdioutput& gdi);
|
|
||||||
};
|
|
||||||
|
|
||||||
void getAutoCompleteUnpairedCards(gdioutput &gdi, const wstring& w, vector<AutoCompleteRecord>& records);
|
void getAutoCompleteUnpairedCards(gdioutput &gdi, const wstring& w, vector<AutoCompleteRecord>& records);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void renderComments(gdioutput& gdi, oAbstractRunner& r);
|
class CommentHandler : public GuiHandler {
|
||||||
static void loadComments(gdioutput& gdi, oAbstractRunner& r);
|
int runnerId;
|
||||||
|
bool isTeam = false;
|
||||||
|
protected:
|
||||||
|
oAbstractRunner& getRunner() const;
|
||||||
|
oEvent* oe;
|
||||||
|
void doSave(gdioutput& gdi);
|
||||||
|
public:
|
||||||
|
CommentHandler(oAbstractRunner& r) : oe(r.getEvent()) {
|
||||||
|
runnerId = r.getId(); isTeam = r.isTeam();
|
||||||
|
}
|
||||||
|
void handle(gdioutput& gdi, BaseInfo& info, GuiEventType type);
|
||||||
|
virtual void save(gdioutput& gdi);
|
||||||
|
};
|
||||||
|
|
||||||
|
static void renderComments(gdioutput& gdi, oAbstractRunner& r, bool newColumn, bool refresh);
|
||||||
|
static void loadComments(gdioutput& gdi, oAbstractRunner& r, const shared_ptr<CommentHandler> &handler);
|
||||||
|
|
||||||
static pClub extractClub(oEvent *oe, gdioutput &gdi);
|
static pClub extractClub(oEvent *oe, gdioutput &gdi);
|
||||||
|
|
||||||
|
|||||||
@ -4488,6 +4488,13 @@ void TabSI::clearCompetitionData() {
|
|||||||
requestStartTimeHandler.reset();
|
requestStartTimeHandler.reset();
|
||||||
|
|
||||||
sortAssignCards = SortOrder::Custom;
|
sortAssignCards = SortOrder::Custom;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
showTestingPanel = !oe->gdiBase().isTest();
|
||||||
|
#else
|
||||||
|
showTestingPanel = false;
|
||||||
|
#endif // _DEBUG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SICard& TabSI::getCard(int id) const {
|
SICard& TabSI::getCard(int id) const {
|
||||||
|
|||||||
@ -167,9 +167,11 @@ int TabTeam::searchCB(gdioutput &gdi, int type, void *data) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
|
void TabTeam::selectTeam(gdioutput &gdi, pTeam t)
|
||||||
{
|
{
|
||||||
|
if (gdioutput* gdi_comments = getExtraWindow("comments", false); gdi_comments)
|
||||||
|
gdi_comments->closeWindow();
|
||||||
|
|
||||||
if (t){
|
if (t){
|
||||||
t->synchronize();
|
t->synchronize();
|
||||||
t->evaluate(oBase::ChangeType::Quiet);
|
t->evaluate(oBase::ChangeType::Quiet);
|
||||||
@ -588,7 +590,20 @@ int TabTeam::teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
if (t && getExtraWindow("comments", true) == nullptr) {
|
if (t && getExtraWindow("comments", true) == nullptr) {
|
||||||
gdioutput* settings = createExtraWindow("comments", L"Kommentarer", gdi.scaleLength(550), gdi.scaleLength(350), true);
|
gdioutput* settings = createExtraWindow("comments", L"Kommentarer", gdi.scaleLength(550), gdi.scaleLength(350), true);
|
||||||
TabRunner::loadComments(*settings, *t);
|
|
||||||
|
class TeamComments : public TabRunner::CommentHandler {
|
||||||
|
public:
|
||||||
|
TeamComments(oTeam& t) : CommentHandler(t) {}
|
||||||
|
void save(gdioutput& gdi) override {
|
||||||
|
doSave(gdi);
|
||||||
|
auto t = &getRunner();
|
||||||
|
oe->gdiBase().restore("SelectR");
|
||||||
|
TabTeam::forkingKey(oe->gdiBase(), pTeam(t));
|
||||||
|
oe->gdiBase().refresh();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TabRunner::loadComments(*settings, *t, make_shared<TeamComments>(*t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bi.id=="Search") {
|
else if (bi.id=="Search") {
|
||||||
@ -758,8 +773,12 @@ int TabTeam::teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
gdi.selectItemByData("ForkKey", currentKey);
|
gdi.selectItemByData("ForkKey", currentKey);
|
||||||
|
|
||||||
gdi.dropLine(0.9);
|
gdi.dropLine(0.9);
|
||||||
gdi.addButton("SaveKey", "Ändra", TeamCB);
|
gdi.addButton("SaveKey", "Ändra", TeamCB).setDefault();
|
||||||
gdi.refreshFast();
|
gdi.addButton("Cancel", "Avbryt", TeamCB).setCancel();
|
||||||
|
gdi.popX();
|
||||||
|
gdi.dropLine(1);
|
||||||
|
renderComments(t, gdi);
|
||||||
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
else if (bi.id == "SaveKey") {
|
else if (bi.id == "SaveKey") {
|
||||||
pTeam t = oe->getTeam(teamId);
|
pTeam t = oe->getTeam(teamId);
|
||||||
@ -918,13 +937,15 @@ int TabTeam::teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
gdi.addSelection("SelectR", 250, 400, TeamCB);
|
gdi.addSelection("SelectR", 250, 400, TeamCB);
|
||||||
gdi.addButton("SelectRunner", "OK", TeamCB).setExtra(leg);
|
gdi.addButton("SelectRunner", "OK", TeamCB).setExtra(leg);
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.addButton("Cancel", "Avbryt", TeamCB);
|
gdi.addButton("Cancel", "Avbryt", TeamCB).setCancel();
|
||||||
|
|
||||||
gdi.setItems("SelectR", otherR);
|
gdi.setItems("SelectR", otherR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gdi.addButton("Cancel", "Avbryt", TeamCB);
|
gdi.addButton("Cancel", "Avbryt", TeamCB).setCancel();
|
||||||
}
|
}
|
||||||
|
gdi.popX();
|
||||||
|
renderComments(t, gdi);
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
else if (bi.id=="SelectRunner") {
|
else if (bi.id=="SelectRunner") {
|
||||||
@ -1238,6 +1259,9 @@ int TabTeam::teamCB(gdioutput &gdi, GuiEventType type, BaseInfo* data) {
|
|||||||
if (teamId>0)
|
if (teamId>0)
|
||||||
save(gdi, true);
|
save(gdi, true);
|
||||||
|
|
||||||
|
if (gdioutput* gdi_settings = getExtraWindow("comments", false); gdi_settings)
|
||||||
|
gdi_settings->closeWindow();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (type==GUI_POSTCLEAR) {
|
else if (type==GUI_POSTCLEAR) {
|
||||||
@ -1352,11 +1376,6 @@ void TabTeam::loadTeamMembers(gdioutput &gdi, int ClassId, int ClubId, pTeam t)
|
|||||||
|
|
||||||
void TabTeam::forkingKey(gdioutput& gdi, pTeam t) {
|
void TabTeam::forkingKey(gdioutput& gdi, pTeam t) {
|
||||||
pClass pc = t->getClassRef(false);
|
pClass pc = t->getClassRef(false);
|
||||||
int cx = gdi.getCX();
|
|
||||||
int cy = gdi.getCY();
|
|
||||||
TabRunner::renderComments(gdi, *t);
|
|
||||||
gdi.setCX(cx);
|
|
||||||
gdi.setCY(cy);
|
|
||||||
|
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.setRestorePoint("SelectR");
|
gdi.setRestorePoint("SelectR");
|
||||||
@ -1375,6 +1394,17 @@ void TabTeam::forkingKey(gdioutput& gdi, pTeam t) {
|
|||||||
gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB);
|
gdi.addButton("ChangeKey", "Ändra lagets gaffling", TeamCB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderComments(t, gdi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTeam::renderComments(const pTeam& t, gdioutput& gdi) {
|
||||||
|
if (t->getNumRunners() > 5)
|
||||||
|
TabRunner::renderComments(gdi, *t, true, false);
|
||||||
|
else {
|
||||||
|
gdi.dropLine(1); // Leave room for the below
|
||||||
|
TabRunner::renderComments(gdi, *t, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabTeam::enableRunner(gdioutput& gdi, int index, bool enable) {
|
void TabTeam::enableRunner(gdioutput& gdi, int index, bool enable) {
|
||||||
|
|||||||
@ -78,7 +78,9 @@ private:
|
|||||||
void enableRunner(gdioutput &gdi, int index, bool enable);
|
void enableRunner(gdioutput &gdi, int index, bool enable);
|
||||||
|
|
||||||
/// Show forking key in the window
|
/// Show forking key in the window
|
||||||
void forkingKey(gdioutput& gdi, pTeam t);
|
static void forkingKey(gdioutput& gdi, pTeam t);
|
||||||
|
|
||||||
|
static void renderComments(const pTeam& t, gdioutput& gdi);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
|
|||||||
@ -2687,11 +2687,11 @@ Aktivera kioskläge = Activate kiosk mode
|
|||||||
Avstånd mellan förslag (minuter) = Distance between suggestions (minutes)
|
Avstånd mellan förslag (minuter) = Distance between suggestions (minutes)
|
||||||
Boka starttid = Request start time
|
Boka starttid = Request start time
|
||||||
Ingen ledig starttid kunde hittas = No free start time was found
|
Ingen ledig starttid kunde hittas = No free start time was found
|
||||||
Minsta tid till start (minuter) = Least time to start (minutes)
|
Minsta tid till start (minuter) = Minimum time to start (minutes)
|
||||||
Sista starttid = Last start time
|
Sista starttid = Last start time
|
||||||
Startintervall (minuter) = Start interval (minutes)
|
Startintervall (minuter) = Start interval (minutes)
|
||||||
Tillåt klass med samma bana på samma starttid = Allow class with same course on same start time
|
Tillåt klass med samma bana på samma starttid = Allow class with same course on same start time
|
||||||
Tillåt klass med samma bana på stattid före/efter = Allow class with same course before and after
|
Tillåt klass med samma bana på starttid före/efter = Allow class with same course before and after
|
||||||
Tillåt klass med samma första kontroll vid samma starttid = Allow class with same first control at the same time
|
Tillåt klass med samma första kontroll vid samma starttid = Allow class with same first control at the same time
|
||||||
Tiden har passerat sista tillåtna starttid = Time has passed last allowed start time
|
Tiden har passerat sista tillåtna starttid = Time has passed last allowed start time
|
||||||
Starttiden är låst = The start time is locked
|
Starttiden är låst = The start time is locked
|
||||||
@ -2735,7 +2735,7 @@ Antal nivåer = Number of levels
|
|||||||
Använd ranking istället för placering i kval för att placera kvalificerade löpare i klasser = Use ranking instead of placement to distribute qualified runners into classes
|
Använd ranking istället för placering i kval för att placera kvalificerade löpare i klasser = Use ranking instead of placement to distribute qualified runners into classes
|
||||||
Bästa tid = Best time
|
Bästa tid = Best time
|
||||||
Final = Final
|
Final = Final
|
||||||
Klass / placering = Class / place
|
Klass / placering = Class / placement
|
||||||
Klass X (namnsuffix) = Class X (name suffix)
|
Klass X (namnsuffix) = Class X (name suffix)
|
||||||
Klass efter ranking = Select class by ranking
|
Klass efter ranking = Select class by ranking
|
||||||
Kval = Qualification
|
Kval = Qualification
|
||||||
@ -2795,7 +2795,19 @@ TeamTextA = Team text
|
|||||||
Födelsedatum = Birth date
|
Födelsedatum = Birth date
|
||||||
Kommentar = Comment
|
Kommentar = Comment
|
||||||
Lägg till eller redigera kommentarer om deltagaren = Add or edit a comment about the competitor
|
Lägg till eller redigera kommentarer om deltagaren = Add or edit a comment about the competitor
|
||||||
Lägg till eller redigera kommentarer om deltagaren = Add or edit a comment about the team
|
Lägg till eller redigera kommentarer om laget = Add or edit a comment about the team
|
||||||
Manuellt ändrad brickdata = Manually modified card data
|
Manuellt ändrad brickdata = Manually modified card data
|
||||||
Efteranmälan = Late entry
|
Efteranmälan = Late entry
|
||||||
Reducerad = Reduced
|
Reducerad = Reduced
|
||||||
|
Kommentarer för X = Comments for X
|
||||||
|
Layout = Layout
|
||||||
|
kolumner = columns
|
||||||
|
rader = rows
|
||||||
|
Modifierade resultat = Modified results
|
||||||
|
EFilterModifiedCard = With modified result
|
||||||
|
Vill du uppdatera X med ändringarna? = Do you want to update X with the changes?
|
||||||
|
Vill du spara en kopia av tävlingen med starttider för ytterligare analys? = Do you want to save a copy of the competition with start times for further analysis?||||||| .r1334
|
||||||
|
RunnerRankScore = Ranking (score)
|
||||||
|
Radera alla = Remove all
|
||||||
|
Vill du ta bort alla banor från tävlingen? = Do you want to remove all courses from the competition?
|
||||||
|
Tillåt klass med samma bana på stattid före/efter = Allow class with the same course before/after
|
||||||
|
|||||||
@ -6350,7 +6350,7 @@ void gdioutput::processToolbarMessage(const string &id, Table *tbl) {
|
|||||||
wstring msg;
|
wstring msg;
|
||||||
string cmd;
|
string cmd;
|
||||||
if (getRecorder().recording()) {
|
if (getRecorder().recording()) {
|
||||||
cmd = "tableCmd(\"" + id + "\"); //" + narrow(tbl->getTableName());
|
cmd = "tableCmd(\"" + id + "\"); //" + toUTF8(tbl->getTableName());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ButtonInfo bi;
|
ButtonInfo bi;
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
<pre>
|
<pre>
|
||||||
*MOPComplete>
|
*MOPComplete>
|
||||||
*competition date="2015-09-06" organizer="Orienteringsklubben Linné" homepage="http://www.oklinne.nu" zerotime="216000">Stafett-DM, Uppland*/competition>
|
*competition date="2015-09-06" organizer="Orienteringsklubben Linné" homepage="http://www.oklinne.nu" zerotime="08:00:00">Stafett-DM, Uppland*/competition>
|
||||||
*/MOPComplete>
|
*/MOPComplete>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|||||||
@ -131,8 +131,8 @@ bool InfoCompetition::synchronize(oEvent &oe, bool onlyCmp, const set<int> &incl
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oe.getZeroTimeNum() != zerotime) {
|
if (oe.getZeroTime() != zeroTime) {
|
||||||
zerotime = oe.getZeroTimeNum();
|
zeroTime = oe.getZeroTime();
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,7 +457,7 @@ void InfoCompetition::serialize(xmlbuffer &xml, bool diffOnly) const {
|
|||||||
prop.push_back(make_pair("date", date));
|
prop.push_back(make_pair("date", date));
|
||||||
prop.push_back(make_pair("organizer", organizer));
|
prop.push_back(make_pair("organizer", organizer));
|
||||||
prop.push_back(make_pair("homepage", homepage));
|
prop.push_back(make_pair("homepage", homepage));
|
||||||
prop.emplace_back("zerotime", itow(zerotime));
|
prop.push_back(make_pair("zerotime", zeroTime));
|
||||||
xml.write("competition", prop, name);
|
xml.write("competition", prop, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -221,7 +221,7 @@ private:
|
|||||||
wstring date;
|
wstring date;
|
||||||
wstring organizer;
|
wstring organizer;
|
||||||
wstring homepage;
|
wstring homepage;
|
||||||
int zerotime;
|
wstring zeroTime;
|
||||||
protected:
|
protected:
|
||||||
bool forceComplete;
|
bool forceComplete;
|
||||||
|
|
||||||
|
|||||||
@ -261,8 +261,24 @@ void IOF30Interface::readCourseData(gdioutput &gdi, const xmlobject &xo, bool up
|
|||||||
}
|
}
|
||||||
for (unsigned leg = 0; leg < pc->getNumStages() && leg < coursePattern[0].size(); leg++) {
|
for (unsigned leg = 0; leg < pc->getNumStages() && leg < coursePattern[0].size(); leg++) {
|
||||||
pc->clearStageCourses(leg);
|
pc->clearStageCourses(leg);
|
||||||
|
int legToUse = leg;
|
||||||
|
while (legToUse > 0 && (pc->getLegType(legToUse) == LegTypes::LTExtra ||
|
||||||
|
pc->getLegType(legToUse) == LegTypes::LTIgnore))
|
||||||
|
legToUse--;
|
||||||
|
bool sameLeg = true;
|
||||||
|
for (int m = 1; m < period; m++) {
|
||||||
|
if (coursePattern[m][legToUse] != coursePattern[0][legToUse]) {
|
||||||
|
sameLeg = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sameLeg) { // No forking
|
||||||
|
pc->addStageCourse(leg, coursePattern[0][legToUse], -1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
for (int m = 0; m < period; m++)
|
for (int m = 0; m < period; m++)
|
||||||
pc->addStageCourse(leg, coursePattern[(period - patternStart + m)%period][leg], -1);
|
pc->addStageCourse(leg, coursePattern[(period - patternStart + m) % period][legToUse], -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool classHeader = false;
|
bool classHeader = false;
|
||||||
@ -1049,10 +1065,20 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
|
|||||||
allR[k]->flagEntryTouched(false);
|
allR[k]->flagEntryTouched(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map<pair<int, int>, int> teamLegToFixedCourse;
|
||||||
|
|
||||||
oe.getTeams(0, allT, false);
|
oe.getTeams(0, allT, false);
|
||||||
for (size_t k = 0; k < allT.size(); k++) {
|
for (size_t k = 0; k < allT.size(); k++) {
|
||||||
if (allT[k]->getEntrySource() == entrySourceId)
|
if (allT[k]->getEntrySource() == entrySourceId)
|
||||||
allT[k]->flagEntryTouched(false);
|
allT[k]->flagEntryTouched(false);
|
||||||
|
|
||||||
|
for (int leg = 0; leg < allT[k]->getNumRunners(); leg++) {
|
||||||
|
pRunner r = allT[k]->getRunner(leg);
|
||||||
|
if (r && r->getCourseId() > 0) {
|
||||||
|
pair key(allT[k]->getId(), leg);
|
||||||
|
teamLegToFixedCourse[key] = r->getCourseId();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlList pEntries;
|
xmlList pEntries;
|
||||||
@ -1311,6 +1337,25 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
|
|||||||
oe.getDI().setString("LateEntryFactor", fs);
|
oe.getDI().setString("LateEntryFactor", fs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
oe.getTeams(0, allT, false);
|
||||||
|
for (size_t k = 0; k < allT.size(); k++) {
|
||||||
|
for (int leg = 0; leg < allT[k]->getNumRunners(); leg++) {
|
||||||
|
pRunner r = allT[k]->getRunner(leg);
|
||||||
|
if (r) {
|
||||||
|
pair key(allT[k]->getId(), leg);
|
||||||
|
auto res = teamLegToFixedCourse.find(key);
|
||||||
|
if (res == teamLegToFixedCourse.end()) {
|
||||||
|
r->setCourseId(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r->setCourseId(res->second);
|
||||||
|
}
|
||||||
|
r->synchronize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOF30Interface::readServiceRequestList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) {
|
void IOF30Interface::readServiceRequestList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) {
|
||||||
@ -2183,6 +2228,12 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlobject score = xo.getObject("Score");
|
||||||
|
if (score && score.getRawPtr()) {
|
||||||
|
double s = atof(score.getRawPtr());
|
||||||
|
r->setRankingScore(s);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasTime = true;
|
bool hasTime = true;
|
||||||
xmlobject ext = xo.getObject("Extensions");
|
xmlobject ext = xo.getObject("Extensions");
|
||||||
if (ext) {
|
if (ext) {
|
||||||
|
|||||||
@ -126,21 +126,6 @@ void resetSaveTimer() {
|
|||||||
autoTask->resetSaveTimer();
|
autoTask->resetSaveTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadPage(const string &name)
|
|
||||||
{
|
|
||||||
list<TabObject>::iterator it;
|
|
||||||
|
|
||||||
for (it=tabList->begin(); it!=tabList->end(); ++it) {
|
|
||||||
if (it->name==name)
|
|
||||||
it->loadPage(*gdi_main);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadClassPage(gdioutput &gdi)
|
|
||||||
{
|
|
||||||
LoadPage("Klasser");
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpLeaks() {
|
void dumpLeaks() {
|
||||||
_CrtDumpMemoryLeaks();
|
_CrtDumpMemoryLeaks();
|
||||||
}
|
}
|
||||||
@ -788,17 +773,14 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|||||||
int xs = gEvent->getPropertyInt("xsize", max(850, min<int>(int(rc.right)-yp, (rc.right*9)/10)));
|
int xs = gEvent->getPropertyInt("xsize", max(850, min<int>(int(rc.right)-yp, (rc.right*9)/10)));
|
||||||
int ys = gEvent->getPropertyInt("ysize", max(650, min<int>(int(rc.bottom)-yp-40, (rc.bottom*8)/10)));
|
int ys = gEvent->getPropertyInt("ysize", max(650, min<int>(int(rc.bottom)-yp-40, (rc.bottom*8)/10)));
|
||||||
|
|
||||||
if ((xp + xs > rc.right)
|
if ((xp + xs > rc.right) || xp < rc.left || yp + ys > rc.bottom || yp < rc.top) {
|
||||||
|| xp < rc.left
|
|
||||||
|| yp + ys > rc.bottom
|
|
||||||
|| yp < rc.top)
|
|
||||||
{
|
|
||||||
// out of bounds, just use default position and size
|
// out of bounds, just use default position and size
|
||||||
xp = 50;
|
xp = 50;
|
||||||
yp = 20;
|
yp = 20;
|
||||||
xs = max(850, min<int>(int(rc.right) - yp, (rc.right * 9) / 10));
|
xs = max(850, min<int>(int(rc.right) - yp, (rc.right * 9) / 10));
|
||||||
ys = max(650, min<int>(int(rc.bottom) - yp - 40, (rc.bottom * 8) / 10));
|
ys = max(650, min<int>(int(rc.bottom) - yp - 40, (rc.bottom * 8) / 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
gEvent->setProperty("ypos", yp + 16);
|
gEvent->setProperty("ypos", yp + 16);
|
||||||
gEvent->setProperty("xpos", xp + 32);
|
gEvent->setProperty("xpos", xp + 32);
|
||||||
gEvent->saveProperties(settings); // For other instance starting while running
|
gEvent->saveProperties(settings); // For other instance starting while running
|
||||||
@ -1054,22 +1036,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
|
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TCmpTab), "Tävling", 10);
|
tabList->emplace_back(gdi_main->getTabs().get(TCmpTab), L"Tävling", 10);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TRunnerTab), "Deltagare", 6);
|
tabList->emplace_back(gdi_main->getTabs().get(TRunnerTab), L"Deltagare", 6);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TTeamTab), "Lag(flera)", 7);
|
tabList->emplace_back(gdi_main->getTabs().get(TTeamTab), L"Lag(flera)", 7);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TListTab), "Listor", 5);
|
tabList->emplace_back(gdi_main->getTabs().get(TListTab), L"Listor", 5);
|
||||||
{
|
{
|
||||||
TabAuto *ta = (TabAuto *)gdi_main->getTabs().get(TAutoTab);
|
TabAuto *ta = (TabAuto *)gdi_main->getTabs().get(TAutoTab);
|
||||||
tabList->emplace_back(ta, "Automater", 4);
|
tabList->emplace_back(ta, L"Automater", 4);
|
||||||
TabAuto::tabAutoRegister(ta);
|
TabAuto::tabAutoRegister(ta);
|
||||||
}
|
}
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TSpeakerTab), "Speaker", 3);
|
tabList->emplace_back(gdi_main->getTabs().get(TSpeakerTab), L"Speaker", 3);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TClassTab), "Klasser", 0);
|
tabList->emplace_back(gdi_main->getTabs().get(TClassTab), L"Klasser", 0);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TCourseTab), "Banor", 1);
|
tabList->emplace_back(gdi_main->getTabs().get(TCourseTab), L"Banor", 1);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TControlTab), "Kontroller", 2);
|
tabList->emplace_back(gdi_main->getTabs().get(TControlTab), L"Kontroller", 2);
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TClubTab), "Klubbar", 8);
|
tabList->emplace_back(gdi_main->getTabs().get(TClubTab), L"Klubbar", 8);
|
||||||
|
|
||||||
tabList->emplace_back(gdi_main->getTabs().get(TSITab), "SportIdent", 9);
|
tabList->emplace_back(gdi_main->getTabs().get(TSITab), L"SportIdent", 9);
|
||||||
|
|
||||||
INITCOMMONCONTROLSEX ic;
|
INITCOMMONCONTROLSEX ic;
|
||||||
|
|
||||||
@ -1190,7 +1172,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
if (it->id==id) {
|
if (it->id==id) {
|
||||||
try {
|
try {
|
||||||
gdi_main->setWaitCursor(true);
|
gdi_main->setWaitCursor(true);
|
||||||
string cmd = "showTab("+ string(it->getTab().getTypeStr()) + "); //" + it->name;
|
string cmd = "showTab("+ string(it->getTab().getTypeStr()) + "); //" + gdi_main->toUTF8(it->name);
|
||||||
it->loadPage(*gdi_main);
|
it->loadPage(*gdi_main);
|
||||||
gdi_main->getRecorder().record(cmd);
|
gdi_main->getRecorder().record(cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2243,7 +2243,7 @@ static bool noCapitalize(const wstring &str, size_t pos) {
|
|||||||
word.push_back(char(str[pos++]));
|
word.push_back(char(str[pos++]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word == "of" || word == "for" || word == "at" || word == "by")
|
if (word == "of" || word == "for" || word == "at" || word == "by" || word == "on")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (word == "and" || word == "or" || word == "from" || word == "as" || word == "in")
|
if (word == "and" || word == "or" || word == "from" || word == "as" || word == "in")
|
||||||
|
|||||||
@ -25,17 +25,17 @@
|
|||||||
|
|
||||||
//ABCDEFGHIJKLMNOPQ
|
//ABCDEFGHIJKLMNOPQ
|
||||||
int getMeosBuild() {
|
int getMeosBuild() {
|
||||||
string revision("$Rev: 1326 $");
|
string revision("$Rev: 1341 $");
|
||||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getMeosDate() {
|
wstring getMeosDate() {
|
||||||
wstring date(L"$Date: 2024-03-02 21:15:41 +0100 (lör, 02 mar 2024) $");
|
wstring date(L"$Date: 2024-04-06 22:32:45 +0200 (lör, 06 apr 2024) $");
|
||||||
return date.substr(7,10);
|
return date.substr(7,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getBuildType() {
|
wstring getBuildType() {
|
||||||
return L"Beta 1"; // No parantheses (...)
|
return L"RC 1"; // No parantheses (...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getMajorVersion() {
|
wstring getMajorVersion() {
|
||||||
@ -153,6 +153,13 @@ void getSupporters(vector<wstring>& supp, vector<wstring>& developSupp)
|
|||||||
supp.emplace_back(L"Silkeborg OK");
|
supp.emplace_back(L"Silkeborg OK");
|
||||||
supp.emplace_back(L"IK Uven");
|
supp.emplace_back(L"IK Uven");
|
||||||
supp.emplace_back(L"Attunda OK");
|
supp.emplace_back(L"Attunda OK");
|
||||||
|
supp.emplace_back(L"Gunnar Svanberg");
|
||||||
|
supp.emplace_back(L"Forsa OK");
|
||||||
|
supp.emplace_back(L"Långhundra IF");
|
||||||
|
supp.emplace_back(L"Mariestads friluftsklubb");
|
||||||
|
supp.emplace_back(L"Ligue PACA");
|
||||||
|
supp.emplace_back(L"SV Robotron Dresden");
|
||||||
|
supp.emplace_back(L"Mats Holmberg, OK Gränsen");
|
||||||
|
|
||||||
reverse(supp.begin(), supp.end());
|
reverse(supp.begin(), supp.end());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2223,6 +2223,7 @@ void MetaList::initSymbols() {
|
|||||||
typeToSymbol[lRunnerBib] = L"RunnerBib";
|
typeToSymbol[lRunnerBib] = L"RunnerBib";
|
||||||
typeToSymbol[lRunnerStartNo] = L"RunnerStartNo";
|
typeToSymbol[lRunnerStartNo] = L"RunnerStartNo";
|
||||||
typeToSymbol[lRunnerRank] = L"RunnerRank";
|
typeToSymbol[lRunnerRank] = L"RunnerRank";
|
||||||
|
typeToSymbol[lRunnerRankScore] = L"RunnerRankScore";
|
||||||
typeToSymbol[lRunnerCourse] = L"RunnerCourse";
|
typeToSymbol[lRunnerCourse] = L"RunnerCourse";
|
||||||
typeToSymbol[lRunnerRogainingPoint] = L"RunnerRogainingPoint";
|
typeToSymbol[lRunnerRogainingPoint] = L"RunnerRogainingPoint";
|
||||||
typeToSymbol[lRunnerRogainingPointTotal] = L"RunnerRogainingPointTotal";
|
typeToSymbol[lRunnerRogainingPointTotal] = L"RunnerRogainingPointTotal";
|
||||||
@ -2462,6 +2463,7 @@ void MetaList::initSymbols() {
|
|||||||
filterToSymbol[EFilterAPIEntry] = "EFilterAPIEntry";
|
filterToSymbol[EFilterAPIEntry] = "EFilterAPIEntry";
|
||||||
filterToSymbol[EFilterWrongFee] = "EFilterWrongFee";
|
filterToSymbol[EFilterWrongFee] = "EFilterWrongFee";
|
||||||
filterToSymbol[EFilterIncludeNotParticipating] = "EFilterIncludeNotParticipating";
|
filterToSymbol[EFilterIncludeNotParticipating] = "EFilterIncludeNotParticipating";
|
||||||
|
filterToSymbol[EFilterModifiedCard] = "EFilterModifiedCard";
|
||||||
|
|
||||||
for (map<EFilterList, string>::iterator it = filterToSymbol.begin();
|
for (map<EFilterList, string>::iterator it = filterToSymbol.begin();
|
||||||
it != filterToSymbol.end(); ++it) {
|
it != filterToSymbol.end(); ++it) {
|
||||||
|
|||||||
@ -5060,10 +5060,14 @@ void oClass::loadQualificationFinalScheme(const QualificationFinal& scheme) {
|
|||||||
inst->synchronize();
|
inst->synchronize();
|
||||||
}
|
}
|
||||||
synchronize();
|
synchronize();
|
||||||
|
set<int> base;
|
||||||
|
qf->getBaseClassInstances(base);
|
||||||
for (oRunner &r : oe->Runners) {
|
for (oRunner &r : oe->Runners) {
|
||||||
if (r.getClassRef(false) == this) {
|
if (r.getClassRef(false) == this) {
|
||||||
|
if (r.getLegNumber() == 0 && !base.count(r.getDCI().getInt("Heat")))
|
||||||
|
r.getDI().setInt("Heat", 0);
|
||||||
pTeam t = r.getTeam();
|
pTeam t = r.getTeam();
|
||||||
if (t == 0) {
|
if (t == nullptr) {
|
||||||
t = oe->addTeam(r.getName(), r.getClubId(), getId());
|
t = oe->addTeam(r.getName(), r.getClubId(), getId());
|
||||||
t->setStartNo(r.getStartNo(), oBase::ChangeType::Update);
|
t->setStartNo(r.getStartNo(), oBase::ChangeType::Update);
|
||||||
t->setRunner(0, &r, true);
|
t->setRunner(0, &r, true);
|
||||||
@ -5084,6 +5088,8 @@ void oClass::updateFinalClasses(oRunner* causingResult, bool updateStartNumbers)
|
|||||||
return;
|
return;
|
||||||
assert(!causingResult || causingResult->Class == this);
|
assert(!causingResult || causingResult->Class == this);
|
||||||
|
|
||||||
|
int causingLevel = causingResult ? causingResult->tLeg : 0;
|
||||||
|
|
||||||
//oe->gdibase.addStringUT(0, L"UF:" + getName() + L" for " + (causingResult ? causingResult->getName() : L"-"));
|
//oe->gdibase.addStringUT(0, L"UF:" + getName() + L" for " + (causingResult ? causingResult->getName() : L"-"));
|
||||||
auto computeInstance = [this](const pRunner causingResult) {
|
auto computeInstance = [this](const pRunner causingResult) {
|
||||||
if (causingResult) {
|
if (causingResult) {
|
||||||
@ -5158,6 +5164,28 @@ void oClass::updateFinalClasses(oRunner* causingResult, bool updateStartNumbers)
|
|||||||
bool hasRemaining = qualificatonFinal->hasRemainingClass();
|
bool hasRemaining = qualificatonFinal->hasRemainingClass();
|
||||||
GeneralResult gr;
|
GeneralResult gr;
|
||||||
qualificatonFinal->prepareCalculations();
|
qualificatonFinal->prepareCalculations();
|
||||||
|
|
||||||
|
struct TotalLevelRes {
|
||||||
|
pRunner r;
|
||||||
|
int place;
|
||||||
|
int instance;
|
||||||
|
int orderPlace;
|
||||||
|
int numEqual;
|
||||||
|
|
||||||
|
TotalLevelRes(int instance, pRunner r, int place, int orderPlace, int numEqual) : r(r), instance(instance),
|
||||||
|
orderPlace(orderPlace), numEqual(numEqual), place(place) {}
|
||||||
|
|
||||||
|
TotalLevelRes(int instance, pRunner r) : r(r), instance(instance),
|
||||||
|
orderPlace(numeric_limits<int>::max()), numEqual(0),
|
||||||
|
place(numeric_limits<int>::max()) {}
|
||||||
|
|
||||||
|
bool operator<(const TotalLevelRes& other) const {
|
||||||
|
return orderPlace < other.orderPlace;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<vector<TotalLevelRes>> levelRes(maxDepth+1);
|
||||||
|
|
||||||
int maxLevel = 0;
|
int maxLevel = 0;
|
||||||
for (int i = instance; i < limit; i++) {
|
for (int i = instance; i < limit; i++) {
|
||||||
if (classSplit[i].empty())
|
if (classSplit[i].empty())
|
||||||
@ -5206,6 +5234,7 @@ void oClass::updateFinalClasses(oRunner* causingResult, bool updateStartNumbers)
|
|||||||
|
|
||||||
int lastPlace = 0, orderPlace = 1;
|
int lastPlace = 0, orderPlace = 1;
|
||||||
int numEqual = 0;
|
int numEqual = 0;
|
||||||
|
|
||||||
for (size_t k = 0; k < classSplit[i].size(); k++) {
|
for (size_t k = 0; k < classSplit[i].size(); k++) {
|
||||||
const auto &res = classSplit[i][k]->getTempResult();
|
const auto &res = classSplit[i][k]->getTempResult();
|
||||||
if (res.getStatus() == StatusOK) {
|
if (res.getStatus() == StatusOK) {
|
||||||
@ -5215,14 +5244,28 @@ void oClass::updateFinalClasses(oRunner* causingResult, bool updateStartNumbers)
|
|||||||
else
|
else
|
||||||
numEqual = 0;
|
numEqual = 0;
|
||||||
|
|
||||||
qualificatonFinal->provideQualificationResult(classSplit[i][k], i, orderPlace, numEqual);
|
levelRes[thisLevel].emplace_back(i, classSplit[i][k], place, orderPlace, numEqual);
|
||||||
|
// qualificatonFinal->provideQualificationResult(classSplit[i][k], i, orderPlace, numEqual);
|
||||||
lastPlace = place;
|
lastPlace = place;
|
||||||
}
|
}
|
||||||
else if (hasRemaining && res.getStatus() != StatusUnknown) {
|
else if (hasRemaining && res.getStatus() != StatusUnknown) {
|
||||||
qualificatonFinal->provideUnqualified(thisLevel, classSplit[i][k]);
|
levelRes[thisLevel].emplace_back(i, classSplit[i][k]);
|
||||||
|
//qualificatonFinal->provideUnqualified(thisLevel, classSplit[i][k]);
|
||||||
|
}
|
||||||
|
orderPlace++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
orderPlace++;
|
for (int level = 0; level < levelRes.size(); level++) {
|
||||||
|
if (levelRes[level].empty())
|
||||||
|
continue;
|
||||||
|
stable_sort(levelRes[level].begin(), levelRes[level].end());
|
||||||
|
|
||||||
|
for (auto& res : levelRes[level]) {
|
||||||
|
if (res.orderPlace < numeric_limits<int>::max())
|
||||||
|
qualificatonFinal->provideQualificationResult(res.r, res.instance, res.orderPlace, res.numEqual);
|
||||||
|
else
|
||||||
|
qualificatonFinal->provideUnqualified(level, res.r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5339,7 +5382,7 @@ void oClass::updateFinalClasses(oRunner* causingResult, bool updateStartNumbers)
|
|||||||
if (inst < nextLevelInstance)
|
if (inst < nextLevelInstance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!cc.second && cc.first->tLeg > 0 && !qualifiedRunners.count(cc.first->getId())) {
|
if (!cc.second && cc.first->tLeg > causingLevel && !qualifiedRunners.count(cc.first->getId())) {
|
||||||
auto di = cc.first->getDI();
|
auto di = cc.first->getDI();
|
||||||
int oldHeat = di.getInt("Heat");
|
int oldHeat = di.getInt("Heat");
|
||||||
if (oldHeat != 0 && !getVirtualClass(oldHeat)->lockedClassAssignment()) {
|
if (oldHeat != 0 && !getVirtualClass(oldHeat)->lockedClassAssignment()) {
|
||||||
|
|||||||
@ -1213,7 +1213,9 @@ void oDataContainer::buildTableCol(Table *table)
|
|||||||
|
|
||||||
bool oDataContainer::formatNumber(int nr, const oDataInfo &di, wchar_t bf[64]) const {
|
bool oDataContainer::formatNumber(int nr, const oDataInfo &di, wchar_t bf[64]) const {
|
||||||
if (di.SubType == oISDate) {
|
if (di.SubType == oISDate) {
|
||||||
if ((nr < 99999999 && nr % 10000 != 0) || nr == 0)
|
if (nr == 0)
|
||||||
|
bf[0] = 0;
|
||||||
|
else if ((nr < 99999999 && nr % 10000 != 0) || nr == 0)
|
||||||
swprintf_s(bf, 64, L"%d-%02d-%02d", nr / (100 * 100), (nr / 100) % 100, nr % 100);
|
swprintf_s(bf, 64, L"%d-%02d-%02d", nr / (100 * 100), (nr / 100) % 100, nr % 100);
|
||||||
else if (nr > 0 && nr < 9999)
|
else if (nr > 0 && nr < 9999)
|
||||||
swprintf_s(bf, 64, L"%04d", nr / 10000);
|
swprintf_s(bf, 64, L"%04d", nr / 10000);
|
||||||
@ -1224,7 +1226,9 @@ bool oDataContainer::formatNumber(int nr, const oDataInfo &di, wchar_t bf[64]) c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (di.SubType == oISDateOrYear) {
|
else if (di.SubType == oISDateOrYear) {
|
||||||
if (nr > 9999 && nr % 10000 != 0)
|
if (nr == 0)
|
||||||
|
bf[0] = 0;
|
||||||
|
else if (nr > 9999 && nr % 10000 != 0)
|
||||||
swprintf_s(bf, 64, L"%04d-%02d-%02d", nr / 10000, (nr / 100) % 100, nr % 100);
|
swprintf_s(bf, 64, L"%04d-%02d-%02d", nr / 10000, (nr / 100) % 100, nr % 100);
|
||||||
else if (nr > 9999)
|
else if (nr > 9999)
|
||||||
swprintf_s(bf, 64, L"%04d", nr / 10000);
|
swprintf_s(bf, 64, L"%04d", nr / 10000);
|
||||||
|
|||||||
@ -34,6 +34,8 @@ class Table;
|
|||||||
class InputInfo;
|
class InputInfo;
|
||||||
enum CellType;
|
enum CellType;
|
||||||
|
|
||||||
|
constexpr int MaxVarNameLength = 28;
|
||||||
|
|
||||||
class oDataDefiner {
|
class oDataDefiner {
|
||||||
public:
|
public:
|
||||||
virtual ~oDataDefiner() {}
|
virtual ~oDataDefiner() {}
|
||||||
@ -53,7 +55,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct oDataInfo {
|
struct oDataInfo {
|
||||||
char Name[28];
|
char Name[MaxVarNameLength];
|
||||||
int Index;
|
int Index;
|
||||||
int Size;
|
int Size;
|
||||||
int Type;
|
int Type;
|
||||||
@ -70,7 +72,7 @@ struct oDataInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct oVariableInt {
|
struct oVariableInt {
|
||||||
char name[20];
|
char name[MaxVarNameLength];
|
||||||
int *data32;
|
int *data32;
|
||||||
__int64 *data64;
|
__int64 *data64;
|
||||||
oVariableInt() : data32(0), data64(0) {name[0] = 0;}
|
oVariableInt() : data32(0), data64(0) {name[0] = 0;}
|
||||||
@ -81,7 +83,7 @@ class oVariableString {
|
|||||||
oVariableString(wchar_t *buff, int size) : data(buff), maxSize(size), strData(0), strIndex(-2) { name[0] = 0; }
|
oVariableString(wchar_t *buff, int size) : data(buff), maxSize(size), strData(0), strIndex(-2) { name[0] = 0; }
|
||||||
oVariableString(vector<wstring> &vec) : data(0), maxSize(0), strData(&vec), strIndex(-1) { name[0] = 0; }
|
oVariableString(vector<wstring> &vec) : data(0), maxSize(0), strData(&vec), strIndex(-1) { name[0] = 0; }
|
||||||
oVariableString(vector<wstring> &vec, int position) : data(0), maxSize(0), strData(&vec), strIndex(position) { name[0] = 0; }
|
oVariableString(vector<wstring> &vec, int position) : data(0), maxSize(0), strData(&vec), strIndex(position) { name[0] = 0; }
|
||||||
char name[20];
|
char name[MaxVarNameLength];
|
||||||
bool store(const wchar_t *str);
|
bool store(const wchar_t *str);
|
||||||
private:
|
private:
|
||||||
wchar_t *data;
|
wchar_t *data;
|
||||||
|
|||||||
511
code/oEvent.cpp
511
code/oEvent.cpp
@ -57,6 +57,8 @@
|
|||||||
#include "TabSI.h"
|
#include "TabSI.h"
|
||||||
#include "binencoder.h"
|
#include "binencoder.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "datadefiners.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Construction/Destruction
|
// Construction/Destruction
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -70,7 +72,7 @@
|
|||||||
extern Image image;
|
extern Image image;
|
||||||
|
|
||||||
//Version of database
|
//Version of database
|
||||||
int oEvent::dbVersion = 94;
|
int oEvent::dbVersion = 95;
|
||||||
|
|
||||||
bool oEvent::useSubSecond() const {
|
bool oEvent::useSubSecond() const {
|
||||||
if (useSubsecondsVersion == dataRevision)
|
if (useSubsecondsVersion == dataRevision)
|
||||||
@ -95,356 +97,6 @@ bool oEvent::useSubSecond() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RelativeTimeFormatter : public oDataDefiner {
|
|
||||||
string name;
|
|
||||||
public:
|
|
||||||
RelativeTimeFormatter(const char *n) : name(n) {}
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *obj) const override {
|
|
||||||
int t = obj->getDCI().getInt(name);
|
|
||||||
if (t <= 0)
|
|
||||||
return makeDash(L"-");
|
|
||||||
return obj->getEvent()->getAbsTime(t);
|
|
||||||
}
|
|
||||||
pair<int, bool> setData(oBase *obj, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
int t = obj->getEvent()->getRelativeTime(input);
|
|
||||||
obj->getDI().setInt(name.c_str(), t);
|
|
||||||
output = formatData(obj);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AbsoluteTimeFormatter : public oDataDefiner {
|
|
||||||
string name;
|
|
||||||
public:
|
|
||||||
AbsoluteTimeFormatter(const char *n) : name(n) {}
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *obj) const override {
|
|
||||||
int t = obj->getDCI().getInt(name);
|
|
||||||
return formatTime(t);
|
|
||||||
}
|
|
||||||
pair<int, bool> setData(oBase *obj, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
int t = convertAbsoluteTimeMS(input);
|
|
||||||
if (t == NOTIME)
|
|
||||||
t = 0;
|
|
||||||
obj->getDI().setInt(name.c_str(), t);
|
|
||||||
output = formatData(obj);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PayMethodFormatter : public oDataDefiner {
|
|
||||||
mutable vector< pair<wstring, size_t> > modes;
|
|
||||||
mutable map<wstring, int> setCodes;
|
|
||||||
mutable long rev;
|
|
||||||
public:
|
|
||||||
PayMethodFormatter() : rev(-1) {}
|
|
||||||
|
|
||||||
void prepare(oEvent *oe) const override {
|
|
||||||
oe->getPayModes(modes);
|
|
||||||
for (size_t i = 0; i < modes.size(); i++) {
|
|
||||||
setCodes[canonizeName(modes[i].first.c_str())] = modes[i].second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *ob) const override {
|
|
||||||
if (ob->getEvent()->getRevision() != rev)
|
|
||||||
prepare(ob->getEvent());
|
|
||||||
int p = ob->getDCI().getInt("Paid");
|
|
||||||
if (p == 0)
|
|
||||||
return lang.tl("Faktura");
|
|
||||||
else {
|
|
||||||
int pm = ob->getDCI().getInt("PayMode");
|
|
||||||
for (size_t i = 0; i < modes.size(); i++) {
|
|
||||||
if (modes[i].second == pm)
|
|
||||||
return modes[i].first;
|
|
||||||
}
|
|
||||||
return _EmptyWString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<int, bool> setData(oBase *ob, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
auto res = setCodes.find(canonizeName(input.c_str()));
|
|
||||||
if (res != setCodes.end()) {
|
|
||||||
ob->getDI().setInt("PayMode", res->second);
|
|
||||||
}
|
|
||||||
output = formatData(ob);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), true, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class StartGroupFormatter : public oDataDefiner {
|
|
||||||
mutable long rev = -1;
|
|
||||||
mutable map<int, wstring> sgmap;
|
|
||||||
mutable wstring out;
|
|
||||||
|
|
||||||
int static getGroup(const oBase *ob) {
|
|
||||||
const oRunner *r = dynamic_cast<const oRunner *>(ob);
|
|
||||||
int sg = 0;
|
|
||||||
if (r)
|
|
||||||
sg = r->getStartGroup(false);
|
|
||||||
else {
|
|
||||||
const oClub *c = dynamic_cast<const oClub *>(ob);
|
|
||||||
if (c)
|
|
||||||
sg = c->getStartGroup();
|
|
||||||
}
|
|
||||||
return sg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
StartGroupFormatter() {}
|
|
||||||
|
|
||||||
void prepare(oEvent *oe) const override {
|
|
||||||
auto &sg = oe->getStartGroups(true);
|
|
||||||
for (auto &g : sg) {
|
|
||||||
int t = g.second.firstStart;
|
|
||||||
sgmap[g.first] = oe->getAbsTimeHM(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *ob) const override {
|
|
||||||
if (ob->getEvent()->getRevision() != rev)
|
|
||||||
prepare(ob->getEvent());
|
|
||||||
int sg = getGroup(ob);
|
|
||||||
if (sg > 0) {
|
|
||||||
auto res = sgmap.find(sg);
|
|
||||||
if (res != sgmap.end())
|
|
||||||
out = itow(sg) + L" (" + res->second + L")";
|
|
||||||
else
|
|
||||||
out = itow(sg) + L" (??)";
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return _EmptyWString;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<int, bool> setData(oBase *ob, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
int g = inputId;
|
|
||||||
if (inputId <= 0 && !input.empty()) {
|
|
||||||
vector<wstring> sIn;
|
|
||||||
split(input, L" ", sIn);
|
|
||||||
for (wstring &in : sIn) {
|
|
||||||
int num = _wtoi(in.c_str());
|
|
||||||
if (in.find_first_of(':') != input.npos) {
|
|
||||||
int t = ob->getEvent()->convertAbsoluteTime(input);
|
|
||||||
if (t > 0) {
|
|
||||||
for (auto &sg : ob->getEvent()->getStartGroups(false)) {
|
|
||||||
if (sg.second.firstStart == t) {
|
|
||||||
g = sg.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sgmap.count(num)) {
|
|
||||||
g = num;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oRunner *r = dynamic_cast<oRunner *>(ob);
|
|
||||||
if (r) {
|
|
||||||
r->setStartGroup(g);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
oClub *c = dynamic_cast<oClub *>(ob);
|
|
||||||
if (c)
|
|
||||||
c->setStartGroup(g);
|
|
||||||
}
|
|
||||||
output = formatData(ob);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the desired cell type
|
|
||||||
CellType getCellType() const {
|
|
||||||
return CellType::cellSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillInput(const oBase *obj, vector<pair<wstring, size_t>> &out, size_t &selected) const final {
|
|
||||||
if (obj->getEvent()->getRevision() != rev)
|
|
||||||
prepare(obj->getEvent());
|
|
||||||
|
|
||||||
int sg = getGroup(obj);
|
|
||||||
|
|
||||||
out.emplace_back(_EmptyWString, 0);
|
|
||||||
selected = 0;
|
|
||||||
for (auto &v : sgmap) {
|
|
||||||
out.emplace_back(v.second, v.first);
|
|
||||||
|
|
||||||
if (sg == v.first)
|
|
||||||
selected = sg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DataHider : public oDataDefiner {
|
|
||||||
public:
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *obj) const override {
|
|
||||||
return _EmptyWString;
|
|
||||||
}
|
|
||||||
pair<int, bool> setData(oBase *obj, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DataBoolean : public oDataDefiner {
|
|
||||||
string attrib;
|
|
||||||
public:
|
|
||||||
DataBoolean(const string &attrib) : attrib(attrib) {}
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *obj) const override {
|
|
||||||
int v = obj->getDCI().getInt(attrib);
|
|
||||||
return lang.tl(v ? "true[boolean]" : "false[boolean]");
|
|
||||||
}
|
|
||||||
pair<int, bool> setData(oBase *obj, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
bool v = compareStringIgnoreCase(L"true", input) == 0 || _wtoi64(input.c_str())>0;
|
|
||||||
if (!v) {
|
|
||||||
const wstring &T = lang.tl("true[boolean]");
|
|
||||||
v = compareStringIgnoreCase(T, input) == 0;
|
|
||||||
}
|
|
||||||
obj->getDI().setInt(attrib.c_str(), v);
|
|
||||||
output = formatData(obj);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), true, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ResultModuleFormatter : public oDataDefiner {
|
|
||||||
public:
|
|
||||||
|
|
||||||
const wstring &formatData(const oBase *obj) const override {
|
|
||||||
return obj->getDCI().getString("Result");
|
|
||||||
}
|
|
||||||
pair<int, bool> setData(oBase *obj, const wstring &input, wstring &output, int inputId) const override {
|
|
||||||
string tag(input.begin(), input.end());
|
|
||||||
dynamic_cast<oClass &>(*obj).setResultModule(tag);
|
|
||||||
output = formatData(obj);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
int addTableColumn(Table *table, const string &description, int minWidth) const override {
|
|
||||||
return table->addColumn(description, max(minWidth, 90), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SplitPrintListFormatter : public oDataDefiner {
|
|
||||||
public:
|
|
||||||
|
|
||||||
const wstring& formatData(const oBase* obj) const override {
|
|
||||||
wstring listId = obj->getDCI().getString("SplitPrint");
|
|
||||||
if (listId.empty()) {
|
|
||||||
return lang.tl("Standard");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const MetaListContainer& lc = obj->getEvent()->getListContainer();
|
|
||||||
EStdListType type = lc.getCodeFromUnqiueId(gdioutput::narrow(listId));
|
|
||||||
const MetaList& ml = lc.getList(type);
|
|
||||||
return ml.getListName();
|
|
||||||
}
|
|
||||||
catch (meosException&) {
|
|
||||||
return _EmptyWString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillInput(const oBase* obj, vector<pair<wstring, size_t>>& out, size_t& selected) const {
|
|
||||||
oEvent* oe = obj->getEvent();
|
|
||||||
oe->getListContainer().getLists(out, false, false, false, true);
|
|
||||||
out.insert(out.begin(), make_pair(lang.tl("Standard"), -10));
|
|
||||||
wstring listId = obj->getDCI().getString("SplitPrint");
|
|
||||||
EStdListType type = oe->getListContainer().getCodeFromUnqiueId(gdioutput::narrow(listId));
|
|
||||||
if (type == EStdListType::EStdNone)
|
|
||||||
selected = -10;
|
|
||||||
else {
|
|
||||||
for (auto& t : out) {
|
|
||||||
if (type == oe->getListContainer().getType(t.second)) {
|
|
||||||
selected = t.second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CellType getCellType() const final {
|
|
||||||
return CellType::cellSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<int, bool> setData(oBase* obj, const wstring& input, wstring& output, int inputId) const override {
|
|
||||||
if (inputId == -10)
|
|
||||||
obj->getDI().setString("SplitPrint", L"");
|
|
||||||
else {
|
|
||||||
EStdListType type = obj->getEvent()->getListContainer().getType(inputId);
|
|
||||||
string id = obj->getEvent()->getListContainer().getUniqueId(type);
|
|
||||||
obj->getDI().setString("SplitPrint", gdioutput::widen(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
output = formatData(obj);
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int addTableColumn(Table* table, const string& description, int minWidth) const override {
|
|
||||||
oEvent* oe = table->getEvent();
|
|
||||||
vector<pair<wstring, size_t>> out;
|
|
||||||
oe->getListContainer().getLists(out, false, false, false, true);
|
|
||||||
|
|
||||||
for (auto& t : out) {
|
|
||||||
minWidth = max<int>(minWidth, t.first.size() * 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
return table->addColumn(description, max(minWidth, 90), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AnnotationFormatter : public oDataDefiner {
|
|
||||||
mutable int numChar = 12;
|
|
||||||
public:
|
|
||||||
|
|
||||||
const wstring& formatData(const oBase* obj) const override {
|
|
||||||
const wstring &ws = obj->getDCI().getString("Annotation");
|
|
||||||
if (ws.empty())
|
|
||||||
return ws;
|
|
||||||
int pos = ws.find_first_of('@');
|
|
||||||
if (pos != wstring::npos)
|
|
||||||
return limitText(ws.substr(pos+1), numChar);
|
|
||||||
return limitText(ws, numChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool canEdit() const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<int, bool> setData(oBase* obj, const wstring& input, wstring& output, int inputId) const override {
|
|
||||||
return make_pair(0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int addTableColumn(Table* table, const string& description, int minWidth) const override {
|
|
||||||
numChar = minWidth / 5;
|
|
||||||
return table->addColumn(description, max(minWidth, 90), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
||||||
{
|
{
|
||||||
readOnly = false;
|
readOnly = false;
|
||||||
@ -611,7 +263,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
|||||||
oRunnerData->addVariableCurrency("Taxable", "Skattad avgift");
|
oRunnerData->addVariableCurrency("Taxable", "Skattad avgift");
|
||||||
oRunnerData->addVariableInt("BirthYear", oDataContainer::oISDateOrYear, "RunnerBirthDate");
|
oRunnerData->addVariableInt("BirthYear", oDataContainer::oISDateOrYear, "RunnerBirthDate");
|
||||||
oRunnerData->addVariableString("Bib", 8, "Nummerlapp").zeroSortPadding = 5;
|
oRunnerData->addVariableString("Bib", 8, "Nummerlapp").zeroSortPadding = 5;
|
||||||
oRunnerData->addVariableInt("Rank", oDataContainer::oIS16U, "Ranking");
|
oRunnerData->addVariableInt("Rank", oDataContainer::oIS32, "Ranking", make_shared<RankScoreFormatter>());
|
||||||
|
|
||||||
oRunnerData->addVariableDate("EntryDate", "Anm. datum");
|
oRunnerData->addVariableDate("EntryDate", "Anm. datum");
|
||||||
oRunnerData->addVariableInt("EntryTime", oDataContainer::oISTime, "Anm. tid", make_shared<AbsoluteTimeFormatter>("EntryTime"));
|
oRunnerData->addVariableInt("EntryTime", oDataContainer::oISTime, "Anm. tid", make_shared<AbsoluteTimeFormatter>("EntryTime"));
|
||||||
@ -3589,82 +3241,138 @@ void oEvent::generateMinuteStartlist(gdioutput &gdi) {
|
|||||||
gdi.addStringUT(fontMedium, bf);
|
gdi.addStringUT(fontMedium, bf);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector< vector< vector<pRunner> > > sb;
|
vector<vector<vector<const oRunner *>>> sb;
|
||||||
sb.reserve(Runners.size());
|
sb.reserve(Runners.size() / 5+10);
|
||||||
int LastStartTime=-1;
|
int lastStartTime = -1;
|
||||||
for (oRunnerList::iterator it=Runners.begin(); it != Runners.end(); ++it) {
|
|
||||||
if (it->Class && it->Class->getBlock() != blocks[k])
|
for (const auto &r : Runners) {
|
||||||
|
if (r.isRemoved())
|
||||||
continue;
|
continue;
|
||||||
if (it->Class && it->Class->getStart() != starts[k])
|
if (r.Class && r.Class->getBlock() != blocks[k])
|
||||||
continue;
|
continue;
|
||||||
if (!it->Class && blocks[k]!=0)
|
if (r.Class && r.Class->getStart() != starts[k])
|
||||||
continue;
|
continue;
|
||||||
if (it->getStatus() == StatusNotCompetiting || it->getStatus() == StatusCANCEL)
|
if (!r.Class && blocks[k] != 0)
|
||||||
|
continue;
|
||||||
|
if (r.getStatus() == StatusNotCompetiting || r.getStatus() == StatusCANCEL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (LastStartTime!=it->tStartTime) {
|
if (lastStartTime != r.tStartTime) {
|
||||||
sb.resize(sb.size() + 1);
|
sb.emplace_back();
|
||||||
LastStartTime = it->tStartTime;
|
lastStartTime = r.tStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb.empty())
|
if (sb.empty())
|
||||||
sb.resize(1);
|
sb.resize(1);
|
||||||
|
|
||||||
if (it->tInTeam == 0)
|
if (r.tInTeam == 0)
|
||||||
sb.back().push_back(vector<pRunner>(1, &*it));
|
sb.back().push_back(vector<const oRunner *>(1, &r));
|
||||||
else {
|
else {
|
||||||
if (it->legToRun() > 0 && it->getStartTime() == 0)
|
if (r.legToRun() > 0 && r.getStartTime() == 0)
|
||||||
continue;
|
continue;
|
||||||
int minIx = 10000;
|
int minIx = 10000;
|
||||||
for (int j = 0; j < it->tInTeam->getNumRunners(); j++) {
|
for (int j = 0; j < r.tInTeam->getNumRunners(); j++) {
|
||||||
if (j != it->tLeg &&
|
if (j != r.tLeg && r.tInTeam->Runners[j] && r.tInTeam->Runners[j]->tStartTime == r.tStartTime)
|
||||||
it->tInTeam->Runners[j] &&
|
|
||||||
it->tInTeam->Runners[j]->tStartTime == it->tStartTime)
|
|
||||||
minIx = min(minIx, j);
|
minIx = min(minIx, j);
|
||||||
}
|
}
|
||||||
if (minIx == 10000)
|
if (minIx == 10000)
|
||||||
sb.back().push_back(vector<pRunner>(1, &*it)); // Single runner on this start time
|
sb.back().push_back(vector<const oRunner *>(1, &r)); // Single runner on this start time
|
||||||
else if (minIx > it->tLeg) {
|
else if (minIx > r.tLeg) {
|
||||||
sb.back().push_back(vector<pRunner>());
|
sb.back().emplace_back();
|
||||||
for (int j = 0; j < it->tInTeam->getNumRunners(); j++) {
|
for (int j = 0; j < r.tInTeam->getNumRunners(); j++) {
|
||||||
if (it->tInTeam->Runners[j] &&
|
if (r.tInTeam->Runners[j] && r.tInTeam->Runners[j]->tStartTime == r.tStartTime)
|
||||||
it->tInTeam->Runners[j]->tStartTime == it->tStartTime)
|
sb.back().back().push_back(r.tInTeam->Runners[j]);
|
||||||
sb.back().back().push_back(it->tInTeam->Runners[j]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastStartTime = -1;
|
||||||
|
map<int, int> startIntervalCount;
|
||||||
|
int totalStartTimes = 0;
|
||||||
|
|
||||||
|
for (size_t k = 0; k < sb.size(); k++) {
|
||||||
|
if (!sb[k].empty()) {
|
||||||
|
int st = sb[k][0][0]->getStartTime();
|
||||||
|
if (lastStartTime != -1 && lastStartTime != st) {
|
||||||
|
int startInterval = st - lastStartTime;
|
||||||
|
++startIntervalCount[startInterval];
|
||||||
|
totalStartTimes++;
|
||||||
|
lastStartTime = st;
|
||||||
|
}
|
||||||
|
lastStartTime = st;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int typicalStartInterval = 0;
|
||||||
|
int maxStartIntervalCount = 0;
|
||||||
|
for (auto& sic : startIntervalCount) {
|
||||||
|
if (sic.second > maxStartIntervalCount) {
|
||||||
|
maxStartIntervalCount = sic.second;
|
||||||
|
typicalStartInterval = sic.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int startInterval = -1;
|
||||||
|
if (maxStartIntervalCount > totalStartTimes / 4) {
|
||||||
|
startInterval = typicalStartInterval;
|
||||||
|
}
|
||||||
|
|
||||||
y = gdi.getCY();
|
y = gdi.getCY();
|
||||||
|
lastStartTime = -1;
|
||||||
|
|
||||||
for (size_t k = 0; k < sb.size(); k++) {
|
for (size_t k = 0; k < sb.size(); k++) {
|
||||||
if (sb[k].empty())
|
if (sb[k].empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const int st = sb[k][0][0]->getStartTime();
|
||||||
|
if (startInterval > 0 && lastStartTime > 0 && st - lastStartTime > startInterval) {
|
||||||
|
int missingStartCount = (st - lastStartTime) / startInterval;
|
||||||
|
if (st == lastStartTime + missingStartCount * startInterval) {
|
||||||
|
lastStartTime += startInterval;
|
||||||
|
int count = 0;
|
||||||
|
while (lastStartTime < st) {
|
||||||
|
if (++count < 2) {
|
||||||
|
y += lh / 2;
|
||||||
|
gdi.addStringUT(y, x + dx[0], boldText, getAbsTime(lastStartTime));
|
||||||
|
y += lh;
|
||||||
|
gdi.addStringUT(y, x + dx[1], fontMedium, L"\u2014");
|
||||||
|
y += lh;
|
||||||
|
}
|
||||||
|
lastStartTime += startInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastStartTime = st;
|
||||||
|
|
||||||
y+=lh/2;
|
y+=lh/2;
|
||||||
gdi.addStringUT(y, x+dx[0], boldText, sb[k][0][0]->getStartTimeS());
|
if (st > 0) {
|
||||||
y+=lh;
|
gdi.addStringUT(y, x + dx[0], boldText, sb[k][0][0]->getStartTimeS());
|
||||||
|
y += lh;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t j = 0; j < sb[k].size(); j++) {
|
for (size_t j = 0; j < sb[k].size(); j++) {
|
||||||
const int src_y = y;
|
const int src_y = y;
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
const vector<pRunner> &r = sb[k][j];
|
const auto &rList = sb[k][j];
|
||||||
if (r.size() == 1) {
|
if (rList.size() == 1) {
|
||||||
if (r[0]->getCardNo()>0)
|
if (rList[0]->getCardNo()>0)
|
||||||
gdi.addStringUT(y, x+dx[0], fontMedium, itos(r[0]->getCardNo()));
|
gdi.addStringUT(y, x+dx[0], fontMedium, itos(rList[0]->getCardNo()));
|
||||||
|
|
||||||
wstring name;
|
wstring name;
|
||||||
if (r[0]->getBib().empty())
|
if (rList[0]->getBib().empty())
|
||||||
name = r[0]->getName();
|
name = rList[0]->getName();
|
||||||
else
|
else
|
||||||
name = r[0]->getName() + L" (" + r[0]->getBib() + L")";
|
name = rList[0]->getName() + L" (" + rList[0]->getBib() + L")";
|
||||||
gdi.addStringUT(y, x+dx[1], fontMedium, name, dx[2]-dx[1]-4);
|
gdi.addStringUT(y, x+dx[1], fontMedium, name, dx[2]-dx[1]-4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wstring name;
|
wstring name;
|
||||||
if (!r[0]->tInTeam->getBib().empty())
|
if (!rList[0]->tInTeam->getBib().empty())
|
||||||
name = r[0]->tInTeam->getBib() + L": ";
|
name = rList[0]->tInTeam->getBib() + L": ";
|
||||||
|
|
||||||
int nnames = 0;
|
int nnames = 0;
|
||||||
for (size_t i = 0; i < r.size(); i++) {
|
for (size_t i = 0; i < rList.size(); i++) {
|
||||||
if (nnames>0)
|
if (nnames>0)
|
||||||
name += L", ";
|
name += L", ";
|
||||||
nnames++;
|
nnames++;
|
||||||
@ -3677,21 +3385,20 @@ void oEvent::generateMinuteStartlist(gdioutput &gdi) {
|
|||||||
indent = gdi.scaleLength(20);
|
indent = gdi.scaleLength(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
name += r[i]->getName();
|
name += rList[i]->getName();
|
||||||
if (r[i]->getCardNo()>0) {
|
if (rList[i]->getCardNo()>0)
|
||||||
name += L" (" + itow(r[i]->getCardNo()) + L")";
|
name += L" (" + itow(rList[i]->getCardNo()) + L")";
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
gdi.addStringUT(y, x+dx[0]+indent, fontMedium, name, dx[2]-dx[0]-4-indent);
|
gdi.addStringUT(y, x+dx[0]+indent, fontMedium, name, dx[2]-dx[0]-4-indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.addStringUT(src_y, x+dx[2], fontMedium, r[0]->getClub(), dx[3]-dx[2]-4);
|
gdi.addStringUT(src_y, x+dx[2], fontMedium, rList[0]->getClub(), dx[3]-dx[2]-4);
|
||||||
gdi.addStringUT(src_y, x+dx[3], fontMedium, r[0]->getClass(true));
|
gdi.addStringUT(src_y, x+dx[3], fontMedium, rList[0]->getClass(true));
|
||||||
y+=lh;
|
y+=lh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4784,14 +4491,14 @@ int oEvent::getFirstStart(int classId) const {
|
|||||||
return minTime;
|
return minTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool oEvent::hasRank() const
|
bool oEvent::hasRank() const {
|
||||||
{
|
for (auto &r : Runners){
|
||||||
oRunnerList::const_iterator it;
|
if (!r.isRemoved()) {
|
||||||
|
int rank = r.getDCI().getInt("Rank");
|
||||||
for (it=Runners.begin(); it != Runners.end(); ++it){
|
if (rank > 0 && rank < MaxOrderRank)
|
||||||
if (it->getDCI().getInt("Rank")>0)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,9 @@
|
|||||||
#define cVacantId 888888888
|
#define cVacantId 888888888
|
||||||
#define cNoClubId 999999999
|
#define cNoClubId 999999999
|
||||||
|
|
||||||
|
constexpr int MaxOrderRank = 20000;
|
||||||
|
constexpr int MaxRankingConstant = numeric_limits<int>::max();
|
||||||
|
|
||||||
class MeOSFileLock;
|
class MeOSFileLock;
|
||||||
class RunnerDB;
|
class RunnerDB;
|
||||||
class gdioutput;
|
class gdioutput;
|
||||||
@ -188,11 +191,6 @@ struct BackupInfo : public CompetitionInfo {
|
|||||||
class oListInfo;
|
class oListInfo;
|
||||||
class MetaListContainer;
|
class MetaListContainer;
|
||||||
|
|
||||||
typedef bool (__cdecl* ERRORMESG_FCN)(char *bf256);
|
|
||||||
typedef bool (__cdecl* OPENDB_FCN)(void);
|
|
||||||
typedef int (__cdecl* SYNCHRONIZE_FCN)(oBase *obj);
|
|
||||||
typedef bool (__cdecl* SYNCHRONIZELIST_FCN)(oBase *obj, int lid);
|
|
||||||
|
|
||||||
enum class oListId {oLRunnerId=1, oLClassId=2, oLCourseId=4,
|
enum class oListId {oLRunnerId=1, oLClassId=2, oLCourseId=4,
|
||||||
oLControlId=8, oLClubId=16, oLCardId=32,
|
oLControlId=8, oLClubId=16, oLCardId=32,
|
||||||
oLPunchId=64, oLTeamId=128, oLEventId=256};
|
oLPunchId=64, oLTeamId=128, oLEventId=256};
|
||||||
|
|||||||
@ -45,8 +45,6 @@
|
|||||||
|
|
||||||
#include "meos.h"
|
#include "meos.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
typedef bool (__cdecl* OPENDB_FCN)(void);
|
|
||||||
typedef int (__cdecl* SYNCHRONIZE_FCN)(oBase *obj);
|
|
||||||
|
|
||||||
extern Image image;
|
extern Image image;
|
||||||
|
|
||||||
|
|||||||
@ -292,7 +292,7 @@ bool oEvent::exportOECSV(const wchar_t *file, const set<int>& classes, int langu
|
|||||||
if (it->tStartTime > 0 && t > 0 && t > it->tStartTime)
|
if (it->tStartTime > 0 && t > 0 && t > it->tStartTime)
|
||||||
row.push_back(gdibase.recodeToNarrow(formatTimeHMS(t - it->tStartTime)));
|
row.push_back(gdibase.recodeToNarrow(formatTimeHMS(t - it->tStartTime)));
|
||||||
else
|
else
|
||||||
return "-----";
|
row.push_back("-----");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1883,16 +1883,16 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
|
|||||||
break;
|
break;
|
||||||
case lRunnerRank:
|
case lRunnerRank:
|
||||||
if (r) {
|
if (r) {
|
||||||
int rank=r->getDCI().getInt("Rank");
|
int rank = r->getRanking();
|
||||||
if (rank == 0) {
|
if (rank>0 && rank < MaxOrderRank)
|
||||||
if (r->tParentRunner)
|
|
||||||
rank = r->tParentRunner->getDCI().getInt("Rank");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rank>0)
|
|
||||||
wcscpy_s(wbf, formatRank(rank).c_str());
|
wcscpy_s(wbf, formatRank(rank).c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case lRunnerRankScore:
|
||||||
|
if (r) {
|
||||||
|
wcscpy_s(wbf, r->getRankingScore().c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
case lRunnerBib:
|
case lRunnerBib:
|
||||||
if (r) {
|
if (r) {
|
||||||
const wstring &bib = r->getBib();
|
const wstring &bib = r->getBib();
|
||||||
@ -3029,6 +3029,11 @@ bool oListInfo::filterRunner(const oRunner &r) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter(EFilterModifiedCard)) {
|
||||||
|
if (!r.getCard() || r.getCard()->isOriginalCard() != oCard::PunchOrigin::Manual)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter(EFilterRentCard) && !r.isRentalCard())
|
if (filter(EFilterRentCard) && !r.isRentalCard())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -3290,6 +3295,16 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (li.filter(EFilterModifiedCard)) {
|
||||||
|
bool modified = false;
|
||||||
|
for (pRunner r : it->Runners) {
|
||||||
|
if (r && r->getCard() && r->getCard()->isOriginalCard() == oCard::PunchOrigin::Manual)
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
if (modified)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (li.filter(EFilterHasResult)) {
|
if (li.filter(EFilterHasResult)) {
|
||||||
if (gResult) {
|
if (gResult) {
|
||||||
RunnerStatus st = it->getTempResult(0).getStatus();
|
RunnerStatus st = it->getTempResult(0).getStatus();
|
||||||
|
|||||||
@ -105,6 +105,7 @@ enum EPostType {
|
|||||||
lRunnerBib,
|
lRunnerBib,
|
||||||
lRunnerStartNo,
|
lRunnerStartNo,
|
||||||
lRunnerRank,
|
lRunnerRank,
|
||||||
|
lRunnerRankScore,
|
||||||
lRunnerCourse,
|
lRunnerCourse,
|
||||||
lRunnerRogainingPoint,
|
lRunnerRogainingPoint,
|
||||||
lRunnerRogainingPointTotal,
|
lRunnerRogainingPointTotal,
|
||||||
@ -305,6 +306,7 @@ enum EFilterList
|
|||||||
EFilterAPIEntry, // Entry via API
|
EFilterAPIEntry, // Entry via API
|
||||||
EFilterWrongFee,
|
EFilterWrongFee,
|
||||||
EFilterIncludeNotParticipating,
|
EFilterIncludeNotParticipating,
|
||||||
|
EFilterModifiedCard,
|
||||||
_EFilterMax
|
_EFilterMax
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -617,6 +617,17 @@ void oRunner::setClassId(int id, bool isManualUpdate) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nPc && isManualUpdate && nPc->isQualificationFinalBaseClass() && nPc != Class) {
|
||||||
|
int h = getDI().getInt("Heat"); // Clear heat if not a base class
|
||||||
|
if (h != 0) {
|
||||||
|
set<int> base;
|
||||||
|
nPc->getQualificationFinal()->getBaseClassInstances(base);
|
||||||
|
if (!base.count(h))
|
||||||
|
getDI().setInt("Heat", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tParentRunner) {
|
if (tParentRunner) {
|
||||||
assert(!isManualUpdate); // Do not support! This may be destroyed if calling tParentRunner->setClass
|
assert(!isManualUpdate); // Do not support! This may be destroyed if calling tParentRunner->setClass
|
||||||
return;
|
return;
|
||||||
@ -685,16 +696,15 @@ void oRunner::setClassId(int id, bool isManualUpdate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void oRunner::setCourseId(int id)
|
void oRunner::setCourseId(int id) {
|
||||||
{
|
pCourse pc = Course;
|
||||||
pCourse pc=Course;
|
|
||||||
|
|
||||||
if (id>0)
|
if (id > 0)
|
||||||
Course=oe->getCourse(id);
|
Course = oe->getCourse(id);
|
||||||
else
|
else
|
||||||
Course=0;
|
Course = nullptr;
|
||||||
|
|
||||||
if (Course!=pc) {
|
if (Course != pc) {
|
||||||
updateChanged();
|
updateChanged();
|
||||||
if (Class)
|
if (Class)
|
||||||
getClassRef(true)->clearSplitAnalysis();
|
getClassRef(true)->clearSplitAnalysis();
|
||||||
@ -7005,6 +7015,28 @@ int oRunner::getRanking() const {
|
|||||||
return rank;
|
return rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wstring oRunner::getRankingScore() const {
|
||||||
|
int raw = getDCI().getInt("Rank");
|
||||||
|
wchar_t wbf[32] = { 0 };
|
||||||
|
if (raw > MaxOrderRank) {
|
||||||
|
constexpr int TurnAround = MaxOrderRank * 100000;
|
||||||
|
double score = double(TurnAround - raw)/100;
|
||||||
|
if (score > 0 && score < 10000) {
|
||||||
|
swprintf_s(wbf, L"%.2f", score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wbf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void oRunner::setRankingScore(double score) {
|
||||||
|
int rank = 0;
|
||||||
|
if (score > -10 && score < 10000) {
|
||||||
|
constexpr int TurnAround = MaxOrderRank * 100000;
|
||||||
|
rank = TurnAround - int(score * 100);
|
||||||
|
}
|
||||||
|
getDI().setInt("Rank", rank);
|
||||||
|
}
|
||||||
|
|
||||||
void oAbstractRunner::hasManuallyUpdatedTimeStatus() {
|
void oAbstractRunner::hasManuallyUpdatedTimeStatus() {
|
||||||
if (Class && Class->hasClassGlobalDependence()) {
|
if (Class && Class->hasClassGlobalDependence()) {
|
||||||
set<int> cls;
|
set<int> cls;
|
||||||
|
|||||||
@ -116,7 +116,6 @@ typedef const oTeam* cTeam;
|
|||||||
|
|
||||||
struct SICard;
|
struct SICard;
|
||||||
|
|
||||||
const int MaxRankingConstant = 99999999;
|
|
||||||
|
|
||||||
class oAbstractRunner : public oBase {
|
class oAbstractRunner : public oBase {
|
||||||
protected:
|
protected:
|
||||||
@ -850,7 +849,9 @@ public:
|
|||||||
|
|
||||||
void markClassChanged(int controlId);
|
void markClassChanged(int controlId);
|
||||||
|
|
||||||
int getRanking() const;
|
int getRanking() const final;
|
||||||
|
wstring getRankingScore() const;
|
||||||
|
void setRankingScore(double score);
|
||||||
|
|
||||||
bool isResultUpdated(bool totalResult) const override;
|
bool isResultUpdated(bool totalResult) const override;
|
||||||
|
|
||||||
|
|||||||
@ -2674,3 +2674,126 @@ Bevara höjd/bredd-relationen = Preservar proporção
|
|||||||
RunnerLegTeamLeaderName = Primeiro competidor da equipe a terminar a perna
|
RunnerLegTeamLeaderName = Primeiro competidor da equipe a terminar a perna
|
||||||
info:offsetclassid = Se você importar inscrições e categorias de fontes diferentes para a mesma competição, pode acontecer que haja conflitos nos números de ID das categorias. Para separar as categorias, você pode inserir um deslocamento para o ID da categoria ao trabalhar com arquivos de uma fonte específica; isso será adicionado aos números de Id.\n\nVocê deve especificar o mesmo deslocamento cada vez que importar dessa fonte.\n\n Um número adequado pode ser 1000 (que funcionará desde que cada Id seja menor que 1000).
|
info:offsetclassid = Se você importar inscrições e categorias de fontes diferentes para a mesma competição, pode acontecer que haja conflitos nos números de ID das categorias. Para separar as categorias, você pode inserir um deslocamento para o ID da categoria ao trabalhar com arquivos de uma fonte específica; isso será adicionado aos números de Id.\n\nVocê deve especificar o mesmo deslocamento cada vez que importar dessa fonte.\n\n Um número adequado pode ser 1000 (que funcionará desde que cada Id seja menor que 1000).
|
||||||
Förskjutning av klassers Id = ID da categoria de corte
|
Förskjutning av klassers Id = ID da categoria de corte
|
||||||
|
Aktivera kioskläge = Ativar modo quiosque
|
||||||
|
Alla okvalificerade = Qualquer não qualificado
|
||||||
|
Alla övriga = Todos os restantes
|
||||||
|
Anslut en SI-enhet och aktivera den = Conectar e ativar uma unidade SI
|
||||||
|
Antal nivåer = Número de níveis
|
||||||
|
Använd ranking istället för placering i kval för att placera kvalificerade löpare i klasser = Usar ranking em vez de colocação para distribuir competidores qualificados em categorias
|
||||||
|
Avgiftshöjning två (procent) = Segundo aumento de taxa (por cento)
|
||||||
|
Avläsning = Leitura
|
||||||
|
Avstånd mellan förslag (minuter) = Distância entre sugestões (minutos)
|
||||||
|
Boka starttid = Solicitar horário de início
|
||||||
|
Bästa tid = Melhor tempo
|
||||||
|
ClassDataA = Dados da categoria A
|
||||||
|
ClassDataB = Dados da categoria B
|
||||||
|
ClassTextA = Texto da categoria
|
||||||
|
CourseNumControls = Número de controles
|
||||||
|
Datortid = Hora do computador
|
||||||
|
Extra data X = Dados extras X
|
||||||
|
Extra datafält = Campos de dados extras
|
||||||
|
Final = Final
|
||||||
|
Födelsedatum = Data de nascimento
|
||||||
|
För kommunikationstest kan man använda en separat testtävling = Para testar comunicação, pode-se usar uma competição de teste separada
|
||||||
|
Individual Rogaining Split Print = Impressão de divisão de cross-country individual
|
||||||
|
Ingen ledig starttid kunde hittas = Não foi encontrado horário de início livre
|
||||||
|
Inmatning Testning = Teste de entrada
|
||||||
|
Klass / placering = Categoria / posição
|
||||||
|
Klass X (namnsuffix) = Categoria X (sufixo do nome)
|
||||||
|
Klass efter ranking = Selecionar categoria por ranking
|
||||||
|
Klassen lottas inte, boka starttid = Lista de largada não foi sorteada, solicite horário de partida na página SportIdent
|
||||||
|
Klassen tillåter ej val av starttid = A categoria não permite solicitação de horário de partida
|
||||||
|
Kommentar = Comentário
|
||||||
|
Kommentarer = Comentários
|
||||||
|
Kval = Qualificação
|
||||||
|
Kvalificeringsregler för X = Regras de qualificação para X
|
||||||
|
Kvalklass = Categoria de qualificação
|
||||||
|
Ladda = Carregar
|
||||||
|
Lap Count = Contagem de voltas
|
||||||
|
Lap count with extra punch = Contagem de voltas com picote extra
|
||||||
|
Live results, radio = Resultados ao vivo, rádio
|
||||||
|
Lägg till eller redigera kommentarer om deltagaren = Adicionar ou editar comentários sobre o competidor
|
||||||
|
Lägg till regler = Adicionar regras
|
||||||
|
Manuellt startönskemål = Pedido de início manual
|
||||||
|
Manuellt ändrad brickdata = Dados do chip alterados manualmente
|
||||||
|
Manuellt ändrad stämpling = Dados alterados manualmente
|
||||||
|
Minsta tid till start (minuter) = Menor tempo até o início (minutos)
|
||||||
|
N bästa = N melhores
|
||||||
|
Nivå X = Nível X
|
||||||
|
Observera att stämplingar före tävlingens nolltid inte kan hämtas = Observação: O MeOS não pode buscar picotes antes do tempo zero da competição
|
||||||
|
Oförändrad brickdata = Dados originais do chip
|
||||||
|
Okänd ursrpungsstatus = Status de origem desconhecido
|
||||||
|
Omstart: X = Reinício: X
|
||||||
|
Patrol results = Resultados de patrulha
|
||||||
|
Patrol, start list = Patrulha, lista de largada
|
||||||
|
Placering X kvalificerar till Y = Posição X qualifica para Y
|
||||||
|
Placeringar = Colocações
|
||||||
|
Primärt = Primário
|
||||||
|
PunchControlPlaceTeamAcc = Posição total da equipe no controle
|
||||||
|
PunchTeamTime = Tempo total da equipe e divisão no controle
|
||||||
|
PunchTeamTotalNamedTime = Tempo total da equipe nomeado
|
||||||
|
PunchTeamTotalTime = Tempo total da equipe para o controle
|
||||||
|
PunchTeamTotalTimeAfter = Tempo da equipe após o controle
|
||||||
|
Regler = Regras
|
||||||
|
Reptid: X = Tempo de corda: X
|
||||||
|
Resultatlista, Rogaining, lag = Resultados, cross-country, equipe
|
||||||
|
RunnerDataA = Dados do competidor A
|
||||||
|
RunnerDataB = Dados do competidor B
|
||||||
|
RunnerRentalCard = Chip de aluguel
|
||||||
|
RunnerTextA = Texto do competidor
|
||||||
|
Sekundärt = Secundário
|
||||||
|
Sida = Página
|
||||||
|
Simulerar starttidstilldelning för X deltagare = Simulando atribuição de horário de início para X competidores
|
||||||
|
Simulering = Simulação
|
||||||
|
Sista starttid = Último horário de início
|
||||||
|
Start på signal = Iniciar no sinal
|
||||||
|
Starta nu = Iniciar agora
|
||||||
|
Startintervall (minuter) = Intervalo de início (minutos)
|
||||||
|
Startlista, lag = Lista de largada, equipe
|
||||||
|
Starttiden är låst = O horário de início está bloqueado
|
||||||
|
Starttiden är redan tilldelad = O horário de início já foi atribuído
|
||||||
|
Stoppdatum två = Segunda data de encerramento
|
||||||
|
Stämpla för välja starttid = Picote para escolher um horário de início
|
||||||
|
Sätt tiden = Definir o tempo
|
||||||
|
Team Rogaining Split Print = Impressão de divisão de cross-country em equipe
|
||||||
|
TeamDataA = Dados da equipe A
|
||||||
|
TeamDataB = Dados da equipe B
|
||||||
|
TeamTextA = Texto da equipe
|
||||||
|
Testning = Teste
|
||||||
|
Tiden har passerat sista tillåtna starttid = O tempo passou o último horário de partida permitido
|
||||||
|
Tidsgräns X = Limite de tempo X
|
||||||
|
Tidskval = Qualificação de tempo
|
||||||
|
Tilldela nummerlapp till vakanter = Atribuir números a vagas
|
||||||
|
Tillåt deltagare med samma klubb och klass på närliggande starttid = Permitir competidores do mesmo clube e categoria no próximo horário de partida
|
||||||
|
Tillåt klass med samma bana på samma starttid = Permitir categoria com o mesmo percurso no mesmo horário de partida
|
||||||
|
Tillåt klass med samma bana på stattid före/efter = Permitir categoria com o mesmo percurso antes e depois
|
||||||
|
Tillåt klass med samma första kontroll vid samma starttid = Permitir primeira marcação no mesmo horário de partida dentro da mesma categoria
|
||||||
|
Ursprunglig tid: X = Tempo original: X
|
||||||
|
Use in X = Usar em X
|
||||||
|
Vill du starta automaten? = Deseja iniciar a máquina?
|
||||||
|
Välj från flera förslag = Escolher entre várias sugestões
|
||||||
|
Välj starttid för X = Escolher horário de partida para X
|
||||||
|
Välj typ av ID att exportera = Selecionar tipos de ID para exportar
|
||||||
|
Välj vilken tid du vill sätta = Escolher a hora que deseja definir
|
||||||
|
X bästa = X melhores
|
||||||
|
X bästa okvalificerade = X melhores não qualificados
|
||||||
|
X kvalificerade = X qualificados
|
||||||
|
X: Startid för Y kl Z = X: Horário de partida para Y na Z
|
||||||
|
ask:simulatestart = Realize uma simulação com as configurações que você fez (categoria, profundidade de início, distância, regras) e com os participantes registrados que estão nas categorias. A competição não é afetada. O resultado mostra se é razoável que todos tenham tempo para começar dentro da profundidade de início definida e quanto tempo extra de espera pode ser necessário em diferentes categorias.\n\nDepois, você também pode salvar uma cópia da competição com os horários de partida simulados para estudar, por exemplo, a lista de horários de partida em minutos.\n\nVocê deseja executar a simulação?
|
||||||
|
ask:startkiosk = Se você iniciar um quiosque de reserva de horário de partida, o MeOS entra em um estado onde nenhuma outra operação é suportada ou configurações podem ser alteradas. Você precisa de uma unidade SI conectada e ativada.\n\nVocê deve considerar proteger o banco de dados com senha se estiver expondo um quiosque.\n\nVocê deseja iniciar o modo quiosque?
|
||||||
|
help:requeststart = Solicitar horário de partida é algo entre um horário de partida livre e sorteado. Ao solicitar um horário de partida, o MeOS garante que haja uma certa distância entre os participantes na mesma categoria ou no mesmo percurso. Se você tiver um horário de partida solicitado, não é necessário usar um chip de partida.\n\nDefina parâmetros para a profundidade de partida e quantos/quem podem começar ao mesmo tempo. A distância do local onde a reserva é feita até a partida, determina qual é um valor mínimo de tempo de partida apropriado.\n\nVocê pode permitir que os participantes obtenham automaticamente o primeiro horário de partida disponível após o tempo mínimo de partida, ou permitir que escolham entre vários horários de partida possíveis. É possível e adequado imprimir um certificado de partida para levar consigo para a partida.\n\nSe você estiver usando um serviço de resultados ao vivo, o horário de partida provavelmente será exibido lá quando reservado.
|
||||||
|
help_second_fee = Use uma segunda taxa aumentada para definir uma taxa mais alta para inscrições no dia da competição (por exemplo). A taxa é cobrada a partir da data especificada. A porcentagem é relativa à taxa regular
|
||||||
|
prefsExpStaFilename = Exportar lista de partida
|
||||||
|
prefsRequestClubNeighbour = Solicitar partida: Permitir vizinho do mesmo clube
|
||||||
|
prefsRequestLastStart = Solicitar partida: Último partida
|
||||||
|
prefsRequestMaxParallel = Solicitar partida: Máximo de inícios paralelos
|
||||||
|
prefsRequestMinTime = Solicitar partida: Tempo para começar
|
||||||
|
prefsRequestProvideSuggestion = Solicitar partida: Fornecer sugestões
|
||||||
|
prefsRequestSameCourse = Solicitar partida: Mesmo percurso
|
||||||
|
prefsRequestSameCourseNeighbour = Solicitar partida: Mesmo percurso para vizinho
|
||||||
|
prefsRequestSameFirstControl = Solicitar partida: Mesma primeira marcação
|
||||||
|
prefsRequestStartInterval = Solicitar partida: Intervalo
|
||||||
|
prefsRequestSuggestInterval = Solicitar partida: Tempo entre sugestões
|
||||||
|
prevsExpResFilename = Exportar resultados
|
||||||
|
Önskad starttid = Horário de partida desejado
|
||||||
|
Övriga okvalificerade = Não qualificados restantes
|
||||||
|
|||||||
@ -69,7 +69,8 @@ pair<int, int> QualificationFinal::getPrelFinalFromPlace(int instance, int order
|
|||||||
bool QualificationFinal::noQualification(int instance) const {
|
bool QualificationFinal::noQualification(int instance) const {
|
||||||
if (size_t(instance) >= classDefinition.size())
|
if (size_t(instance) >= classDefinition.size())
|
||||||
return false;
|
return false;
|
||||||
|
if (instance > 0 && classDefinition[instance].level > classDefinition[instance - 1].level)
|
||||||
|
return false; // Second level
|
||||||
return classDefinition[instance].qualificationMap.empty() &&
|
return classDefinition[instance].qualificationMap.empty() &&
|
||||||
classDefinition[instance].numTimeQualifications == 0 &&
|
classDefinition[instance].numTimeQualifications == 0 &&
|
||||||
classDefinition[instance].extraQualification == QFClass::ExtraQualType::None;
|
classDefinition[instance].extraQualification == QFClass::ExtraQualType::None;
|
||||||
@ -774,7 +775,7 @@ void QualificationFinal::printScheme(const oClass& cls, gdioutput &gdi) const {
|
|||||||
gdi.dropLine(0.2);
|
gdi.dropLine(0.2);
|
||||||
int rankingBased = 0;
|
int rankingBased = 0;
|
||||||
vector<wstring> dst;
|
vector<wstring> dst;
|
||||||
|
int misCntLimit = 0;
|
||||||
for (int place = 1; place < 100; place++) {
|
for (int place = 1; place < 100; place++) {
|
||||||
auto res = sourcePlaceToFinalOrder.find(make_pair(i + 1, place));
|
auto res = sourcePlaceToFinalOrder.find(make_pair(i + 1, place));
|
||||||
|
|
||||||
@ -785,7 +786,10 @@ void QualificationFinal::printScheme(const oClass& cls, gdioutput &gdi) const {
|
|||||||
else
|
else
|
||||||
dst.push_back(itow(place) + L". ➞ " + cname[res->second.first - 1]);
|
dst.push_back(itow(place) + L". ➞ " + cname[res->second.first - 1]);
|
||||||
}
|
}
|
||||||
else break;
|
else {
|
||||||
|
if (++misCntLimit > 10)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rankingBased) {
|
if (rankingBased) {
|
||||||
|
|||||||
@ -2701,7 +2701,7 @@ Minsta tid till start (minuter) = Minsta tid till start (minuter)
|
|||||||
Sista starttid = Sista starttid
|
Sista starttid = Sista starttid
|
||||||
Startintervall (minuter) = Startintervall (minuter)
|
Startintervall (minuter) = Startintervall (minuter)
|
||||||
Tillåt klass med samma bana på samma starttid = Tillåt klass med samma bana på samma starttid
|
Tillåt klass med samma bana på samma starttid = Tillåt klass med samma bana på samma starttid
|
||||||
Tillåt klass med samma bana på starttid före/efter = Tillåt klass med samma bana på stattid före/efter
|
Tillåt klass med samma bana på starttid före/efter = Tillåt klass med samma bana på starttid före/efter
|
||||||
Tillåt klass med samma första kontroll vid samma starttid = Tillåt klass med samma första kontroll vid samma starttid
|
Tillåt klass med samma första kontroll vid samma starttid = Tillåt klass med samma första kontroll vid samma starttid
|
||||||
Tiden har passerat sista tillåtna starttid = Tiden har passerat sista tillåtna starttid
|
Tiden har passerat sista tillåtna starttid = Tiden har passerat sista tillåtna starttid
|
||||||
Starttiden är låst = Starttiden är låst
|
Starttiden är låst = Starttiden är låst
|
||||||
@ -2809,3 +2809,17 @@ Lägg till eller redigera kommentarer om laget = Lägg till eller redigera komme
|
|||||||
Manuellt ändrad brickdata = Manuellt ändrad brickdata
|
Manuellt ändrad brickdata = Manuellt ändrad brickdata
|
||||||
Efteranmälan = Efteranmälan
|
Efteranmälan = Efteranmälan
|
||||||
Reducerad = Reducerad
|
Reducerad = Reducerad
|
||||||
|
Kommentarer för X = Kommentarer för X
|
||||||
|
Lägg till eller redigera kommentarer om laget = Lägg till eller redigera kommentarer om laget
|
||||||
|
Layout = Layout
|
||||||
|
kolumner = kolumner
|
||||||
|
rader = rader
|
||||||
|
Modifierade resultat = Modifierade resultat
|
||||||
|
prefsRequestLastStat = prefsRequestLastStat
|
||||||
|
EFilterModifiedCard = Med modifierat resultat
|
||||||
|
Vill du uppdatera X med ändringarna? = Vill du uppdatera X med ändringarna?
|
||||||
|
Vill du spara en kopia av tävlingen med starttider för ytterligare analys? = Vill du spara en kopia av tävlingen med starttider för ytterligare analys?||||||| .r1334
|
||||||
|
RunnerRankScore = Ranking (poäng)
|
||||||
|
Radera alla = Radera alla
|
||||||
|
Vill du ta bort alla banor från tävlingen? = Vill du ta bort alla banor från tävlingen?
|
||||||
|
Tillåt klass med samma bana på stattid före/efter = Tillåt klass med samma bana på stattid före/efter
|
||||||
|
|||||||
@ -406,6 +406,10 @@ void TestMeOS::setFile(const string &file) const {
|
|||||||
gdi_main->dbPushDialogAnswer("*" + file);
|
gdi_main->dbPushDialogAnswer("*" + file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestMeOS::setFile(const wstring& file) const {
|
||||||
|
gdi_main->dbPushDialogAnswer("*" + gdioutput::narrow(file));
|
||||||
|
}
|
||||||
|
|
||||||
void TestMeOS::cleanup() const {
|
void TestMeOS::cleanup() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -128,6 +128,7 @@ public:
|
|||||||
|
|
||||||
void setAnswer(const char *ans) const;
|
void setAnswer(const char *ans) const;
|
||||||
void setFile(const string &file) const;
|
void setFile(const string &file) const;
|
||||||
|
void setFile(const wstring& file) const;
|
||||||
|
|
||||||
void checkString(const char *str, int count = 1) const;
|
void checkString(const char *str, int count = 1) const;
|
||||||
void checkStringRes(const char *str, int count = 1) const;
|
void checkStringRes(const char *str, int count = 1) const;
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Patrol result = Patrol result
|
|
||||||
Loading…
Reference in New Issue
Block a user