MeOS version 3.8.1277 RC1
This commit is contained in:
parent
67e7e24bd5
commit
62a69d2e1f
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -35,6 +35,7 @@
|
|||||||
#include "RunnerDB.h"
|
#include "RunnerDB.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "metalist.h"
|
#include "metalist.h"
|
||||||
|
#include "machinecontainer.h"
|
||||||
#include "MeOSFeatures.h"
|
#include "MeOSFeatures.h"
|
||||||
#include "meosexception.h"
|
#include "meosexception.h"
|
||||||
#include "generalresult.h"
|
#include "generalresult.h"
|
||||||
@ -419,6 +420,11 @@ void MeosSQL::upgradeDB(const string &db, oDataContainer const * dc) {
|
|||||||
sql = sql.substr(0, sql.length() - 2);
|
sql = sql.substr(0, sql.length() - 2);
|
||||||
query.execute(sql);
|
query.execute(sql);
|
||||||
}
|
}
|
||||||
|
if (!eCol.count("Machine")) {
|
||||||
|
string sql = "ALTER TABLE oEvent ADD COLUMN " + C_MTEXT("Machine");
|
||||||
|
sql = sql.substr(0, sql.length() - 2);
|
||||||
|
query.execute(sql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (db == "oCourse") {
|
else if (db == "oCourse") {
|
||||||
if (!eCol.count("Legs")) {
|
if (!eCol.count("Legs")) {
|
||||||
@ -556,7 +562,8 @@ bool MeosSQL::openDB(oEvent *oe)
|
|||||||
<< C_STRING("NameId", 64)
|
<< C_STRING("NameId", 64)
|
||||||
<< C_UINT("BuildVersion")
|
<< C_UINT("BuildVersion")
|
||||||
<< oe->getDI().generateSQLDefinition()
|
<< oe->getDI().generateSQLDefinition()
|
||||||
<< C_MTEXT("Lists") << C_END();
|
<< C_MTEXT("Lists")
|
||||||
|
<< C_MTEXT("Machine") << C_END();
|
||||||
query.execute();
|
query.execute();
|
||||||
|
|
||||||
// Upgrade oEvent
|
// Upgrade oEvent
|
||||||
@ -818,7 +825,8 @@ OpFailStatus MeosSQL::SyncUpdate(oEvent *oe)
|
|||||||
<< " NameId=" << quote << toString(oe->currentNameId) << ", "
|
<< " NameId=" << quote << toString(oe->currentNameId) << ", "
|
||||||
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ", "
|
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ", "
|
||||||
<< " BuildVersion=" << buildVersion << ", "
|
<< " BuildVersion=" << buildVersion << ", "
|
||||||
<< " Lists=" << quote << listEnc
|
<< " Lists=" << quote << listEnc << ", "
|
||||||
|
<< " Machine=" <<quote << oe->getMachineContainer().save()
|
||||||
<< oe->getDI().generateSQLSet(true);
|
<< oe->getDI().generateSQLSet(true);
|
||||||
|
|
||||||
if (syncUpdate(queryset, "oEvent", oe) == opStatusFail)
|
if (syncUpdate(queryset, "oEvent", oe) == opStatusFail)
|
||||||
@ -1185,6 +1193,9 @@ OpFailStatus MeosSQL::SyncRead(oEvent *oe) {
|
|||||||
retValue = opStatusWarning;
|
retValue = opStatusWarning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string &mRaw = row.raw_string(res.field_num("Machine"));
|
||||||
|
oe->getMachineContainer().load(mRaw);
|
||||||
|
|
||||||
oDataInterface odi=oe->getDI();
|
oDataInterface odi=oe->getDI();
|
||||||
storeData(odi, row, oe->dataRevision);
|
storeData(odi, row, oe->dataRevision);
|
||||||
oe->changed = false;
|
oe->changed = false;
|
||||||
@ -2589,7 +2600,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oClub *c)
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
auto query = con->query();
|
auto query = con->query();
|
||||||
query << "SELECT * FROM oClub WHERE Id=" << c->Id;
|
query << "SELECT * FROM oClub WHERE Id=" << c->Id << andWhereOld(c);
|
||||||
auto res = query.store();
|
auto res = query.store();
|
||||||
|
|
||||||
RowWrapper row;
|
RowWrapper row;
|
||||||
@ -2611,8 +2622,7 @@ OpFailStatus MeosSQL::syncRead(bool forceRead, oClub *c)
|
|||||||
return syncUpdate(c, false);
|
return syncUpdate(c, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (c->changed) {
|
||||||
//Something is wrong!? Deleted?
|
|
||||||
return syncUpdate(c, true);
|
return syncUpdate(c, true);
|
||||||
}
|
}
|
||||||
return opStatusOK;
|
return opStatusOK;
|
||||||
@ -3097,6 +3107,9 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) {
|
|||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
alert(ex.what());
|
alert(ex.what());
|
||||||
}
|
}
|
||||||
|
const string &mRaw = row.raw_string(res.field_num("Machine"));
|
||||||
|
oe->getMachineContainer().load(mRaw);
|
||||||
|
|
||||||
oe->counter = counter;
|
oe->counter = counter;
|
||||||
oDataInterface odi=oe->getDI();
|
oDataInterface odi=oe->getDI();
|
||||||
storeData(odi, row, oe->dataRevision);
|
storeData(odi, row, oe->dataRevision);
|
||||||
@ -3124,7 +3137,8 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) {
|
|||||||
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ", "
|
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ", "
|
||||||
<< " BuildVersion=if (BuildVersion<" <<
|
<< " BuildVersion=if (BuildVersion<" <<
|
||||||
buildVersion << "," << buildVersion << ",BuildVersion), "
|
buildVersion << "," << buildVersion << ",BuildVersion), "
|
||||||
<< " Lists=" << quote << listEnc
|
<< " Lists=" << quote << listEnc << ", "
|
||||||
|
<< " Machine=" << quote << oe->getMachineContainer().save()
|
||||||
<< oe->getDI().generateSQLSet(false);
|
<< oe->getDI().generateSQLSet(false);
|
||||||
|
|
||||||
syncUpdate(queryset, "oEvent", oe);
|
syncUpdate(queryset, "oEvent", oe);
|
||||||
@ -3156,7 +3170,8 @@ OpFailStatus MeosSQL::SyncEvent(oEvent *oe) {
|
|||||||
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ","
|
<< " ZeroTime=" << unsigned(oe->ZeroTime) << ","
|
||||||
<< " BuildVersion=if (BuildVersion<" <<
|
<< " BuildVersion=if (BuildVersion<" <<
|
||||||
buildVersion << "," << buildVersion << ",BuildVersion),"
|
buildVersion << "," << buildVersion << ",BuildVersion),"
|
||||||
<< " Lists=" << quote << listEnc
|
<< " Lists=" << quote << listEnc << ", "
|
||||||
|
<< " Machine=" << quote << oe->getMachineContainer().save()
|
||||||
<< oe->getDI().generateSQLSet(false);
|
<< oe->getDI().generateSQLSet(false);
|
||||||
|
|
||||||
syncUpdate(queryset, "oEvent", oe);
|
syncUpdate(queryset, "oEvent", oe);
|
||||||
@ -3223,7 +3238,7 @@ bool MeosSQL::syncListRunner(oEvent *oe)
|
|||||||
st = OpFailStatus::opStatusOK;
|
st = OpFailStatus::opStatusOK;
|
||||||
oRunner *r=oe->getRunner(Id, 0);
|
oRunner *r=oe->getRunner(Id, 0);
|
||||||
|
|
||||||
if (r) {
|
if (r && !r->Removed) {
|
||||||
r->Removed=true;
|
r->Removed=true;
|
||||||
if (r->tInTeam)
|
if (r->tInTeam)
|
||||||
r->tInTeam->correctRemove(r);
|
r->tInTeam->correctRemove(r);
|
||||||
@ -3233,6 +3248,8 @@ bool MeosSQL::syncListRunner(oEvent *oe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r->changedObject();
|
r->changedObject();
|
||||||
|
r->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -3290,9 +3307,11 @@ bool MeosSQL::syncListClass(oEvent *oe) {
|
|||||||
if (int(row["Removed"])) {
|
if (int(row["Removed"])) {
|
||||||
st = OpFailStatus::opStatusOK;
|
st = OpFailStatus::opStatusOK;
|
||||||
oClass *c = oe->getClass(Id);
|
oClass *c = oe->getClass(Id);
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->changedObject();
|
c->changedObject();
|
||||||
c->Removed = true;
|
c->Removed = true;
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3355,9 +3374,11 @@ bool MeosSQL::syncListClub(oEvent *oe)
|
|||||||
st = opStatusOK;
|
st = opStatusOK;
|
||||||
oClub *c = oe->getClub(Id);
|
oClub *c = oe->getClub(Id);
|
||||||
|
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->Removed = true;
|
c->Removed = true;
|
||||||
c->changedObject();
|
c->changedObject();
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3413,9 +3434,11 @@ bool MeosSQL::syncListCourse(oEvent *oe) {
|
|||||||
st = opStatusOK;
|
st = opStatusOK;
|
||||||
oCourse *c = oe->getCourse(Id);
|
oCourse *c = oe->getCourse(Id);
|
||||||
|
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->Removed = true;
|
c->Removed = true;
|
||||||
c->changedObject();
|
c->changedObject();
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3469,9 +3492,11 @@ bool MeosSQL::syncListCard(oEvent *oe)
|
|||||||
if (int(row["Removed"])) {
|
if (int(row["Removed"])) {
|
||||||
st = opStatusOK;
|
st = opStatusOK;
|
||||||
oCard *c = oe->getCard(Id);
|
oCard *c = oe->getCard(Id);
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->changedObject();
|
c->changedObject();
|
||||||
c->Removed = true;
|
c->Removed = true;
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3529,9 +3554,11 @@ bool MeosSQL::syncListControl(oEvent *oe) {
|
|||||||
st = opStatusOK;
|
st = opStatusOK;
|
||||||
oControl *c = oe->getControl(Id, false);
|
oControl *c = oe->getControl(Id, false);
|
||||||
|
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->Removed = true;
|
c->Removed = true;
|
||||||
c->changedObject();
|
c->changedObject();
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3588,13 +3615,16 @@ bool MeosSQL::syncListPunch(oEvent *oe)
|
|||||||
if (int(row["Removed"])) {
|
if (int(row["Removed"])) {
|
||||||
st = OpFailStatus::opStatusOK;
|
st = OpFailStatus::opStatusOK;
|
||||||
oFreePunch *c=oe->getPunch(Id);
|
oFreePunch *c=oe->getPunch(Id);
|
||||||
if (c) {
|
if (c && !c->Removed) {
|
||||||
c->Removed=true;
|
c->Removed=true;
|
||||||
int cid = c->getControlId();
|
int cid = c->getControlId();
|
||||||
oFreePunch::rehashPunches(*oe, c->CardNo, 0);
|
oFreePunch::rehashPunches(*oe, c->CardNo, 0);
|
||||||
pRunner r = oe->getRunner(c->tRunnerId, 0);
|
pRunner r = oe->getRunner(c->tRunnerId, 0);
|
||||||
if (r)
|
if (r)
|
||||||
r->markClassChanged(cid);
|
r->markClassChanged(cid);
|
||||||
|
|
||||||
|
c->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3653,10 +3683,12 @@ bool MeosSQL::syncListTeam(oEvent *oe) {
|
|||||||
if (int(row["Removed"])) {
|
if (int(row["Removed"])) {
|
||||||
st = OpFailStatus::opStatusOK;
|
st = OpFailStatus::opStatusOK;
|
||||||
oTeam *t = oe->getTeam(Id);
|
oTeam *t = oe->getTeam(Id);
|
||||||
if (t) {
|
if (t && !t->Removed) {
|
||||||
t->changedObject();
|
t->changedObject();
|
||||||
t->prepareRemove();
|
t->prepareRemove();
|
||||||
t->Removed = true;
|
t->Removed = true;
|
||||||
|
t->changed = false;
|
||||||
|
oe->dataRevision++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3696,15 +3728,19 @@ bool MeosSQL::syncListTeam(oEvent *oe) {
|
|||||||
|
|
||||||
string MeosSQL::selectUpdated(const char *oTable, const SqlUpdated &updated) {
|
string MeosSQL::selectUpdated(const char *oTable, const SqlUpdated &updated) {
|
||||||
string p1 = string("SELECT Id, Counter, Modified, Removed FROM ") + oTable;
|
string p1 = string("SELECT Id, Counter, Modified, Removed FROM ") + oTable;
|
||||||
|
string cond1 = p1 + " WHERE Counter>" + itos(updated.counter);
|
||||||
|
if (updated.updated.empty())
|
||||||
|
return cond1;
|
||||||
|
|
||||||
string q = "(" + p1 + " WHERE Counter>" + itos(updated.counter) + ") UNION ALL ("+
|
string q = "(" + cond1 + ") UNION ALL ("+
|
||||||
p1 + " WHERE Modified>'" + updated.updated + "' AND Counter<=" + itos(updated.counter) + ")";
|
p1 + " WHERE Modified>'" + updated.updated + "' AND Counter<=" + itos(updated.counter) + ")";
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MeosSQL::checkConnection(oEvent *oe)
|
bool MeosSQL::checkConnection(oEvent *oe)
|
||||||
{
|
{
|
||||||
|
if (!con->connected())
|
||||||
|
return false;
|
||||||
errorMessage.clear();
|
errorMessage.clear();
|
||||||
|
|
||||||
if (!oe) {
|
if (!oe) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -40,7 +40,9 @@ RestService::~RestService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestService::save(oEvent &oe, gdioutput &gdi) {
|
void RestService::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
|
|
||||||
if (!server) {
|
if (!server) {
|
||||||
server = RestServer::construct();
|
server = RestServer::construct();
|
||||||
|
|
||||||
@ -49,7 +51,8 @@ void RestService::save(oEvent &oe, gdioutput &gdi) {
|
|||||||
oe.setProperty("ServicePort", xport);
|
oe.setProperty("ServicePort", xport);
|
||||||
|
|
||||||
port = xport;
|
port = xport;
|
||||||
server->startService(port);
|
if (doProcess)
|
||||||
|
server->startService(port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw meosException("Invalid port number");
|
throw meosException("Invalid port number");
|
||||||
@ -74,7 +77,7 @@ void RestService::save(oEvent &oe, gdioutput &gdi) {
|
|||||||
|
|
||||||
void ListIpAddresses(vector<string>& ip);
|
void ListIpAddresses(vector<string>& ip);
|
||||||
|
|
||||||
void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void RestService::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
if (port == -1) {
|
if (port == -1) {
|
||||||
port = oe.getPropertyInt("ServicePort", 2009);
|
port = oe.getPropertyInt("ServicePort", 2009);
|
||||||
rootMap = oe.getPropertyString("ServiceRootMap", "");
|
rootMap = oe.getPropertyString("ServiceRootMap", "");
|
||||||
@ -100,7 +103,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
gdi.addInput("RootMap", gdi.recodeToWide(rootMap));
|
gdi.addInput("RootMap", gdi.recodeToWide(rootMap));
|
||||||
gdi.setInputStatus("RootMap", !rootMap.empty());
|
gdi.setInputStatus("RootMap", !rootMap.empty());
|
||||||
|
|
||||||
startCancelInterval(gdi, "Save", created, IntervalNone, L"");
|
startCancelInterval(gdi, "Save", state, IntervalNone, L"");
|
||||||
|
|
||||||
if (!server) {
|
if (!server) {
|
||||||
gdi.addInput("Port", itow(port), 10, 0, L"Port:", L"#http://localhost:[PORT]/meos");
|
gdi.addInput("Port", itow(port), 10, 0, L"Port:", L"#http://localhost:[PORT]/meos");
|
||||||
@ -128,8 +131,7 @@ void RestService::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RestService::status(gdioutput &gdi) {
|
void RestService::status(gdioutput &gdi) {
|
||||||
gdi.pushX();
|
AutoMachine::status(gdi);
|
||||||
gdi.addString("", 1, name);
|
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
gdi.addString("", 0, "Server startad på X#" + itos(port));
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -34,8 +34,8 @@ class RestService :
|
|||||||
string rootMap;
|
string rootMap;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void save(oEvent &oe, gdioutput &gdi) override;
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) override;
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created) override;
|
void settings(gdioutput &gdi, oEvent &oe, State state) override;
|
||||||
RestService *clone() const override { return new RestService(*this); }
|
RestService *clone() const override { return new RestService(*this); }
|
||||||
void status(gdioutput &gdi) override;
|
void status(gdioutput &gdi) override;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) override;
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) override;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
647
code/TabAuto.cpp
647
code/TabAuto.cpp
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include "gdiconstants.h"
|
#include "gdiconstants.h"
|
||||||
#include "meosexception.h"
|
#include "meosexception.h"
|
||||||
|
#include "machinecontainer.h"
|
||||||
#include "HTMLWriter.h"
|
#include "HTMLWriter.h"
|
||||||
|
|
||||||
static TabAuto *tabAuto = 0;
|
static TabAuto *tabAuto = 0;
|
||||||
@ -98,6 +99,18 @@ AutoMachine *TabAuto::getMachine(int id) {
|
|||||||
throw meosException("Service X not found.#" + itos(id));
|
throw meosException("Service X not found.#" + itos(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutoMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
machineName = gdi.getText("MachineName");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoMachine::status(gdioutput &gdi) {
|
||||||
|
gdi.pushX();
|
||||||
|
if (machineName.empty())
|
||||||
|
gdi.addString("", 1, name);
|
||||||
|
else
|
||||||
|
gdi.addString("", 1, L"#" + lang.tl(name) + L" (" + machineName + L")");
|
||||||
|
}
|
||||||
|
|
||||||
TabAuto::~TabAuto(void)
|
TabAuto::~TabAuto(void)
|
||||||
{
|
{
|
||||||
list<AutoMachine *>::iterator it;
|
list<AutoMachine *>::iterator it;
|
||||||
@ -108,27 +121,41 @@ TabAuto::~TabAuto(void)
|
|||||||
tabAuto=0;
|
tabAuto=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabAuto::tabAutoKillMachines()
|
||||||
void tabAutoKillMachines()
|
|
||||||
{
|
{
|
||||||
if (tabAuto)
|
if (tabAuto)
|
||||||
tabAuto->killMachines();
|
tabAuto->killMachines();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tabAutoRegister(TabAuto *ta)
|
void TabAuto::tabAutoRegister(TabAuto *ta)
|
||||||
{
|
{
|
||||||
tabAuto=ta;
|
tabAuto=ta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tabAutoAddMachinge(const AutoMachine &am)
|
AutoMachine &TabAuto::tabAutoAddMachinge(const AutoMachine &am)
|
||||||
{
|
{
|
||||||
if (tabAuto) {
|
if (tabAuto)
|
||||||
tabAuto->addMachine(am);
|
return tabAuto->addMachine(am);
|
||||||
}
|
throw meosException("Internal error");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tabForceSync(gdioutput &gdi, pEvent oe)
|
bool TabAuto::hasActiveReconnectionMachine()
|
||||||
{
|
{
|
||||||
|
if (tabAuto)
|
||||||
|
return tabAuto->hasActiveReconnection();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabAuto::hasActiveReconnection() const {
|
||||||
|
for (auto am : machines) {
|
||||||
|
if (am->getType() == Machines::mMySQLReconnect)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tabForceSync(gdioutput &gdi, pEvent oe) {
|
||||||
if (tabAuto)
|
if (tabAuto)
|
||||||
tabAuto->syncCallback(gdi);
|
tabAuto->syncCallback(gdi);
|
||||||
}
|
}
|
||||||
@ -152,31 +179,38 @@ int AutomaticCB(gdioutput *gdi, int type, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::syncCallback(gdioutput &gdi)
|
void TabAuto::syncCallback(gdioutput& gdi)
|
||||||
{
|
{
|
||||||
|
list<AutoMachine*> toRemove;
|
||||||
wstring msg;
|
wstring msg;
|
||||||
try {
|
list<AutoMachine*>::iterator it;
|
||||||
list<AutoMachine *>::iterator it;
|
for (it = machines.begin(); it != machines.end(); ++it) {
|
||||||
for (it=machines.begin(); it!=machines.end(); ++it) {
|
try {
|
||||||
AutoMachine *am=*it;
|
AutoMachine* am = *it;
|
||||||
if (am && am->synchronize && !am->isEditMode())
|
if (am && am->synchronize && !am->isEditMode())
|
||||||
am->process(gdi, oe, SyncDataUp);
|
am->process(gdi, oe, SyncDataUp);
|
||||||
|
if (am->removeMe())
|
||||||
|
toRemove.push_back(am);
|
||||||
|
}
|
||||||
|
catch (meosException& ex) {
|
||||||
|
msg = ex.wwhat();
|
||||||
|
}
|
||||||
|
catch (std::exception& ex) {
|
||||||
|
msg = gdi.widen(ex.what());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
msg = L"Ett okänt fel inträffade.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (meosException &ex) {
|
|
||||||
msg = ex.wwhat();
|
for (auto* r : toRemove) {
|
||||||
}
|
stopMachine(r);
|
||||||
catch(std::exception &ex) {
|
|
||||||
msg = gdi.widen(ex.what());
|
|
||||||
}
|
|
||||||
catch(...) {
|
|
||||||
msg = L"Ett okänt fel inträffade.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msg.empty()) {
|
if (!msg.empty()) {
|
||||||
gdi.alert(msg);
|
gdi.alert(msg);
|
||||||
gdi.setWaitCursor(false);
|
gdi.setWaitCursor(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::updateSyncInfo()
|
void TabAuto::updateSyncInfo()
|
||||||
@ -195,25 +229,45 @@ void TabAuto::updateSyncInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::timerCallback(gdioutput &gdi)
|
void TabAuto::timerCallback(gdioutput &gdi) {
|
||||||
{
|
|
||||||
DWORD tc=GetTickCount();
|
DWORD tc=GetTickCount();
|
||||||
|
|
||||||
list<AutoMachine *>::iterator it;
|
list<AutoMachine *>::iterator it;
|
||||||
bool reload=false;
|
bool reload=false;
|
||||||
|
list<AutoMachine*> toRemove;
|
||||||
|
wstring msg;
|
||||||
|
|
||||||
for (it=machines.begin(); it!=machines.end(); ++it) {
|
for (it = machines.begin(); it != machines.end(); ++it) {
|
||||||
AutoMachine *am=*it;
|
AutoMachine* am = *it;
|
||||||
if (am && am->interval && tc >= am->timeout && !am->isEditMode()) {
|
if (am && am->interval && tc >= am->timeout && !am->isEditMode()) {
|
||||||
am->process(gdi, oe, SyncTimer);
|
try {
|
||||||
setTimer(am);
|
am->process(gdi, oe, SyncTimer);
|
||||||
reload=true;
|
}
|
||||||
|
catch (meosException& ex) {
|
||||||
|
msg = ex.wwhat();
|
||||||
|
}
|
||||||
|
catch (std::exception& ex) {
|
||||||
|
msg = gdi.widen(ex.what());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
msg = L"Ett okänt fel inträffade.";
|
||||||
|
}
|
||||||
|
reload = true;
|
||||||
|
if (am->removeMe())
|
||||||
|
toRemove.push_back(am);
|
||||||
|
else
|
||||||
|
setTimer(am);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto* r : toRemove) {
|
||||||
|
stopMachine(r);
|
||||||
|
}
|
||||||
|
|
||||||
DWORD d=0;
|
DWORD d=0;
|
||||||
if (reload && !editMode && gdi.getData("AutoPage", d) && d)
|
if (reload && !editMode && gdi.getData("AutoPage", d) && d)
|
||||||
loadPage(gdi, false);
|
loadPage(gdi, false);
|
||||||
|
|
||||||
|
if (!msg.empty())
|
||||||
|
throw meosException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::setTimer(AutoMachine *am)
|
void TabAuto::setTimer(AutoMachine *am)
|
||||||
@ -255,16 +309,8 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
|
|||||||
if (!newPath.empty())
|
if (!newPath.empty())
|
||||||
gdi.setText(edit, newPath);
|
gdi.setText(edit, newPath);
|
||||||
}
|
}
|
||||||
else if (bu.id == "StartBackup") {
|
|
||||||
SaveMachine *sm=dynamic_cast<SaveMachine*>(getMachine(bu.getExtraInt()));
|
|
||||||
if (sm)
|
|
||||||
sm->saveSettings(gdi);
|
|
||||||
updateSyncInfo();
|
|
||||||
loadPage(gdi, false);
|
|
||||||
}
|
|
||||||
else if (bu.id=="Result") {
|
else if (bu.id=="Result") {
|
||||||
PrintResultMachine *sm=dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
|
settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mPrintResultsMachine);
|
||||||
settings(gdi, sm, mPrintResultsMachine);
|
|
||||||
}
|
}
|
||||||
else if (bu.id == "BrowseFile") {
|
else if (bu.id == "BrowseFile") {
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
@ -302,168 +348,37 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
|
|||||||
}
|
}
|
||||||
else if (bu.id=="Splits") {
|
else if (bu.id=="Splits") {
|
||||||
SplitsMachine *sm=dynamic_cast<SplitsMachine*>(getMachine(bu.getExtraInt()));
|
SplitsMachine *sm=dynamic_cast<SplitsMachine*>(getMachine(bu.getExtraInt()));
|
||||||
settings(gdi, sm, mSplitsMachine);
|
settings(gdi, sm, AutoMachine::State::Create, mSplitsMachine);
|
||||||
}
|
}
|
||||||
else if (bu.id=="Prewarning") {
|
else if (bu.id=="Prewarning") {
|
||||||
PrewarningMachine *sm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
|
PrewarningMachine *sm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
|
||||||
settings(gdi, sm, mPrewarningMachine);
|
settings(gdi, sm, AutoMachine::State::Create, mPrewarningMachine);
|
||||||
}
|
}
|
||||||
else if (bu.id=="Punches") {
|
else if (bu.id=="Punches") {
|
||||||
PunchMachine *sm=dynamic_cast<PunchMachine*>(getMachine(bu.getExtraInt()));
|
PunchMachine *sm=dynamic_cast<PunchMachine*>(getMachine(bu.getExtraInt()));
|
||||||
settings(gdi, sm, mPunchMachine);
|
settings(gdi, sm, AutoMachine::State::Create, mPunchMachine);
|
||||||
}
|
}
|
||||||
else if (bu.id=="OnlineResults") {
|
else if (bu.id=="OnlineResults") {
|
||||||
OnlineResults *sm=dynamic_cast<OnlineResults*>(getMachine(bu.getExtraInt()));
|
settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mOnlineResults);
|
||||||
settings(gdi, sm, mOnlineResults);
|
|
||||||
}
|
}
|
||||||
else if (bu.id=="OnlineInput") {
|
else if (bu.id=="OnlineInput") {
|
||||||
OnlineInput *sm=dynamic_cast<OnlineInput*>(getMachine(bu.getExtraInt()));
|
settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mOnlineInput);
|
||||||
settings(gdi, sm, mOnlineInput);
|
|
||||||
}
|
}
|
||||||
else if (bu.id=="SaveBackup") {
|
else if (bu.id=="SaveBackup") {
|
||||||
SaveMachine *sm=dynamic_cast<SaveMachine*>(getMachine(bu.getExtraInt()));
|
settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mSaveBackup);
|
||||||
settings(gdi, sm, mSaveBackup);
|
|
||||||
}
|
}
|
||||||
else if (bu.id == "InfoService") {
|
else if (bu.id == "InfoService") {
|
||||||
settings(gdi, getMachine(bu.getExtraInt()), mInfoService);
|
settings(gdi, getMachine(bu.getExtraInt()), AutoMachine::State::Create, mInfoService);
|
||||||
}
|
|
||||||
else if (bu.id=="StartResult") {
|
|
||||||
#ifndef MEOSDB
|
|
||||||
wstring minute=gdi.getText("Interval");
|
|
||||||
int t=convertAbsoluteTimeMS(minute);
|
|
||||||
|
|
||||||
if (t<2 || t>7200) {
|
|
||||||
gdi.alert("Intervallet måste anges på formen MM:SS.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PrintResultMachine *prm=dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
|
|
||||||
|
|
||||||
if (prm) {
|
|
||||||
prm->interval = t;
|
|
||||||
prm->doExport = gdi.isChecked("DoExport");
|
|
||||||
prm->doPrint = gdi.isChecked("DoPrint");
|
|
||||||
prm->exportFile = gdi.getText("ExportFile");
|
|
||||||
prm->exportScript = gdi.getText("ExportScript");
|
|
||||||
|
|
||||||
if (!prm->readOnly) {
|
|
||||||
prm->structuredExport = gdi.isChecked("StructuredExport");
|
|
||||||
prm->htmlRefresh = gdi.isChecked("HTMLRefresh") ? t : 0;
|
|
||||||
|
|
||||||
gdi.getSelection("Classes", prm->classesToPrint);
|
|
||||||
|
|
||||||
ListBoxInfo lbi;
|
|
||||||
if (gdi.getSelectedItem("ListType", lbi)) {
|
|
||||||
oListParam par;
|
|
||||||
par.selection=prm->classesToPrint;
|
|
||||||
par.listCode = EStdListType(lbi.data);
|
|
||||||
par.pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
par.showHeader = gdi.isChecked("ShowHeader");
|
|
||||||
par.showInterTimes = gdi.isChecked("ShowInterResults");
|
|
||||||
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
int legNr = gdi.getSelectedItem("LegNumber").first;
|
|
||||||
if (legNr >= 0)
|
|
||||||
par.setLegNumberCoded(legNr);
|
|
||||||
else
|
|
||||||
par.setLegNumberCoded(0);
|
|
||||||
|
|
||||||
oe->generateListInfo(par, prm->listInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prm->po.onlyChanged = gdi.isChecked("OnlyChanged");
|
|
||||||
prm->pageBreak = gdi.isChecked("PageBreak");
|
|
||||||
prm->showHeader = gdi.isChecked("ShowHeader");
|
|
||||||
|
|
||||||
prm->showInterResult = gdi.isChecked("ShowInterResults");
|
|
||||||
prm->splitAnalysis = gdi.isChecked("SplitAnalysis");
|
|
||||||
prm->synchronize=true; //To force continuos data sync.
|
|
||||||
setTimer(prm);
|
|
||||||
}
|
|
||||||
updateSyncInfo();
|
|
||||||
loadPage(gdi, false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (bu.id=="StartSplits") {
|
|
||||||
|
|
||||||
wstring ivt = gdi.getText("Interval");
|
|
||||||
|
|
||||||
int iv = gdi.getTextNo("Interval");
|
|
||||||
const wstring &file=gdi.getText("FileName");
|
|
||||||
|
|
||||||
if (!ivt.empty() && (iv < 1 || iv > 7200)) {
|
|
||||||
throw meosException(L"Ogiltigt antal sekunder: X#" + gdi.getText("Interval"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.empty()) {
|
|
||||||
throw meosException("Filnamnet får inte vara tomt");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Try exporting.
|
|
||||||
oe->exportIOFSplits(oEvent::IOF20, file.c_str(), true, false,
|
|
||||||
set<int>(), -1, false, true, true, false);
|
|
||||||
SplitsMachine *sm=dynamic_cast<SplitsMachine*>(getMachine(bu.getExtraInt()));
|
|
||||||
|
|
||||||
if (sm) {
|
|
||||||
sm->interval=iv;
|
|
||||||
|
|
||||||
sm->file=file;
|
|
||||||
sm->synchronize=true;
|
|
||||||
setTimer(sm);
|
|
||||||
}
|
|
||||||
updateSyncInfo();
|
|
||||||
loadPage(gdi, false);
|
|
||||||
}
|
}
|
||||||
else if (bu.id=="Save") { // General save
|
else if (bu.id=="Save") { // General save
|
||||||
AutoMachine *sm=getMachine(bu.getExtraInt());
|
AutoMachine *sm=getMachine(bu.getExtraInt());
|
||||||
if (sm) {
|
if (sm) {
|
||||||
sm->save(*oe, gdi);
|
sm->save(*oe, gdi, true);
|
||||||
setTimer(sm);
|
setTimer(sm);
|
||||||
}
|
}
|
||||||
updateSyncInfo();
|
updateSyncInfo();
|
||||||
loadPage(gdi, false);
|
loadPage(gdi, false);
|
||||||
}
|
}
|
||||||
else if (bu.id=="StartPrewarning") {
|
|
||||||
PrewarningMachine *pwm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
|
|
||||||
|
|
||||||
if (pwm) {
|
|
||||||
pwm->waveFolder=gdi.getText("WaveFolder");
|
|
||||||
gdi.getSelection("Controls", pwm->controls);
|
|
||||||
|
|
||||||
oe->synchronizeList(oListId::oLPunchId);
|
|
||||||
oe->clearPrewarningSounds();
|
|
||||||
|
|
||||||
pwm->synchronizePunches=true;
|
|
||||||
pwm->controlsSI.clear();
|
|
||||||
for (set<int>::iterator it=pwm->controls.begin();it!=pwm->controls.end();++it) {
|
|
||||||
pControl pc=oe->getControl(*it, false);
|
|
||||||
|
|
||||||
if (pc)
|
|
||||||
pwm->controlsSI.insert(pc->Numbers, pc->Numbers+pc->nNumbers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateSyncInfo();
|
|
||||||
loadPage(gdi, false);
|
|
||||||
}
|
|
||||||
else if (bu.id=="StartPunch") {
|
|
||||||
|
|
||||||
wstring minute=gdi.getText("Interval");
|
|
||||||
int t=_wtoi(minute.c_str());
|
|
||||||
|
|
||||||
if (t<1 || t>7200) {
|
|
||||||
throw meosException(L"Ogiltigt antal sekunder: X#" + minute);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PunchMachine *pm=dynamic_cast<PunchMachine*>(getMachine(bu.getExtraInt()));
|
|
||||||
|
|
||||||
if (pm) {
|
|
||||||
pm->interval=t;
|
|
||||||
pm->radio=gdi.getTextNo("Radio");
|
|
||||||
setTimer(pm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateSyncInfo();
|
|
||||||
loadPage(gdi, false);
|
|
||||||
}
|
|
||||||
else if (bu.id == "Cancel") {
|
else if (bu.id == "Cancel") {
|
||||||
loadPage(gdi, false);
|
loadPage(gdi, false);
|
||||||
}
|
}
|
||||||
@ -474,6 +389,40 @@ int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
|
|||||||
updateSyncInfo();
|
updateSyncInfo();
|
||||||
loadPage(gdi, false);
|
loadPage(gdi, false);
|
||||||
}
|
}
|
||||||
|
else if (bu.id == "SaveMachine") {
|
||||||
|
auto sm = getMachine(bu.getExtraInt());
|
||||||
|
sm->save(*oe, gdi, false);
|
||||||
|
wstring iv;
|
||||||
|
if (gdi.hasWidget("Interval"))
|
||||||
|
iv = gdi.getText("Interval");
|
||||||
|
sm->saveMachine(*oe, iv);
|
||||||
|
oe->updateChanged();
|
||||||
|
oe->synchronize(false);
|
||||||
|
}
|
||||||
|
else if (bu.id == "Erase") {
|
||||||
|
auto sm = getMachine(bu.getExtraInt());
|
||||||
|
if (sm) {
|
||||||
|
oe->getMachineContainer().erase(sm->getTypeString(), sm->getMachineName());
|
||||||
|
oe->updateChanged();
|
||||||
|
oe->synchronize();
|
||||||
|
stopMachine(sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSyncInfo();
|
||||||
|
loadPage(gdi, false);
|
||||||
|
}
|
||||||
|
else if (bu.id == "CreateLoad") {
|
||||||
|
auto sm = oe->getMachineContainer().enumerate();
|
||||||
|
int ix = bu.getExtraInt();
|
||||||
|
if (ix < sm.size()) {
|
||||||
|
auto &m = sm[ix];
|
||||||
|
Machines type = AutoMachine::getType(m.first);
|
||||||
|
AutoMachine *am = AutoMachine::construct(type);
|
||||||
|
machines.push_back(am);
|
||||||
|
am->loadMachine(*oe, m.second);
|
||||||
|
settings(gdi, am, AutoMachine::State::Load, am->getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (bu.id == "PrinterSetup") {
|
else if (bu.id == "PrinterSetup") {
|
||||||
PrintResultMachine *prm =
|
PrintResultMachine *prm =
|
||||||
dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
|
dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
|
||||||
@ -548,13 +497,16 @@ bool TabAuto::stopMachine(AutoMachine *am)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, Machines ms) {
|
void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, AutoMachine::State state, Machines ms) {
|
||||||
editMode=true;
|
editMode=true;
|
||||||
bool createNew = (sm==0) || (ms == Machines::Unknown);
|
|
||||||
if (sm) {
|
if (sm) {
|
||||||
|
if (state == AutoMachine::State::Create)
|
||||||
|
state = AutoMachine::State::Edit;
|
||||||
|
|
||||||
ms = sm->getType();
|
ms = sm->getType();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
state = AutoMachine::State::Create;
|
||||||
sm = AutoMachine::construct(ms);
|
sm = AutoMachine::construct(ms);
|
||||||
machines.push_back(sm);
|
machines.push_back(sm);
|
||||||
}
|
}
|
||||||
@ -566,7 +518,7 @@ void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, Machines ms) {
|
|||||||
int d = gdi.scaleLength(6);
|
int d = gdi.scaleLength(6);
|
||||||
gdi.setCX(cx + d);
|
gdi.setCX(cx + d);
|
||||||
sm->setEditMode(true);
|
sm->setEditMode(true);
|
||||||
sm->settings(gdi, *oe, createNew);
|
sm->settings(gdi, *oe, state);
|
||||||
int w = gdi.getWidth();
|
int w = gdi.getWidth();
|
||||||
int h = gdi.getHeight();
|
int h = gdi.getHeight();
|
||||||
|
|
||||||
@ -592,6 +544,7 @@ void TabAuto::killMachines()
|
|||||||
bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast)
|
bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast)
|
||||||
{
|
{
|
||||||
oe->checkDB();
|
oe->checkDB();
|
||||||
|
oe->synchronize();
|
||||||
tabAuto=this;
|
tabAuto=this;
|
||||||
editMode=false;
|
editMode=false;
|
||||||
gdi.selectTab(tabId);
|
gdi.selectTab(tabId);
|
||||||
@ -608,34 +561,74 @@ bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast)
|
|||||||
gdi.setData("AutoPage", 1);
|
gdi.setData("AutoPage", 1);
|
||||||
gdi.addString("", boldLarge, "Automater");
|
gdi.addString("", boldLarge, "Automater");
|
||||||
gdi.setRestorePoint();
|
gdi.setRestorePoint();
|
||||||
|
gdi.fillDown();
|
||||||
|
gdi.pushX();
|
||||||
|
|
||||||
gdi.addString("", 10, "help:10000");
|
gdi.addString("", 10, "help:10000");
|
||||||
|
|
||||||
|
auto sm = oe->getMachineContainer().enumerate();
|
||||||
|
|
||||||
|
set<pair<string, wstring>> startedMachines;
|
||||||
|
for (auto &m : machines) {
|
||||||
|
string t;
|
||||||
|
m->getType(t);
|
||||||
|
startedMachines.emplace(t, m->machineName);
|
||||||
|
}
|
||||||
|
decltype(sm) sm2;
|
||||||
|
for (auto &m : sm) {
|
||||||
|
if (startedMachines.count(m) == 0)
|
||||||
|
sm2.push_back(m);
|
||||||
|
}
|
||||||
|
sm2.swap(sm);
|
||||||
|
|
||||||
|
if (sm.size() > 0) {
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.addString("", fontMediumPlus, "Sparade automater").setColor(colorDarkBlue);
|
||||||
|
gdi.dropLine(0.3);
|
||||||
|
gdi.fillRight();
|
||||||
|
|
||||||
|
for (int ix = 0; ix < sm.size(); ix++) {
|
||||||
|
if (ix > 0 && ix % 3 == 0) {
|
||||||
|
gdi.dropLine(2.5);
|
||||||
|
gdi.popX();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &m = sm[ix];
|
||||||
|
Machines type = AutoMachine::getType(m.first);
|
||||||
|
if (m.second == L"default")
|
||||||
|
gdi.addButton("CreateLoad", AutoMachine::getDescription(type), AutomaticCB).setExtra(ix);
|
||||||
|
else
|
||||||
|
gdi.addButton("CreateLoad", L"#" + lang.tl(AutoMachine::getDescription(type))
|
||||||
|
+ L" (" + m.second + L")", AutomaticCB).setExtra(ix);
|
||||||
|
}
|
||||||
|
gdi.popX();
|
||||||
|
gdi.dropLine(2);
|
||||||
|
gdi.fillDown();
|
||||||
|
}
|
||||||
|
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.addString("", fontMediumPlus, "Tillgängliga automater").setColor(colorDarkBlue);
|
gdi.addString("", fontMediumPlus, "Tillgängliga automater").setColor(colorDarkBlue);
|
||||||
gdi.dropLine();
|
gdi.dropLine(0.3);
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.addButton("Result", AutoMachine::getDescription(Machines::mPrintResultsMachine), AutomaticCB, "tooltip:resultprint");
|
||||||
gdi.addButton("Result", "Resultatutskrift / export", AutomaticCB, "tooltip:resultprint");
|
gdi.addButton("OnlineResults", AutoMachine::getDescription(Machines::mOnlineResults), AutomaticCB, "Publicera resultat direkt på nätet");
|
||||||
gdi.addButton("OnlineResults", "Resultat online", AutomaticCB, "Publicera resultat direkt på nätet");
|
gdi.addButton("OnlineInput", AutoMachine::getDescription(Machines::mOnlineInput), AutomaticCB, "Hämta stämplingar m.m. från nätet");
|
||||||
gdi.addButton("OnlineInput", "Inmatning online", AutomaticCB, "Hämta stämplingar m.m. från nätet");
|
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.dropLine(2.5);
|
gdi.dropLine(2.5);
|
||||||
gdi.addButton("SaveBackup", "Säkerhetskopiering", AutomaticCB);
|
gdi.addButton("SaveBackup", AutoMachine::getDescription(Machines::mSaveBackup), AutomaticCB);
|
||||||
gdi.addButton("InfoService", "Informationsserver", AutomaticCB);
|
gdi.addButton("InfoService", AutoMachine::getDescription(Machines::mInfoService), AutomaticCB);
|
||||||
gdi.addButton("Punches", "Stämplingstest", AutomaticCB, "Simulera inläsning av stämplar");
|
gdi.addButton("Punches", AutoMachine::getDescription(Machines::mPunchMachine), AutomaticCB, "Simulera inläsning av stämplar");
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.dropLine(2.5);
|
gdi.dropLine(2.5);
|
||||||
gdi.addButton("Splits", "Sträcktider (WinSplits)", AutomaticCB, "Spara sträcktider till en fil för automatisk synkronisering med WinSplits");
|
gdi.addButton("Splits", AutoMachine::getDescription(Machines::mSplitsMachine), AutomaticCB, "Spara sträcktider till en fil för automatisk synkronisering med WinSplits");
|
||||||
gdi.addButton("Prewarning", "Förvarningsröst", AutomaticCB, "tooltip:voice");
|
gdi.addButton("Prewarning", AutoMachine::getDescription(Machines::mPrewarningMachine), AutomaticCB, "tooltip:voice");
|
||||||
|
|
||||||
|
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.dropLine(3);
|
gdi.dropLine(3);
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
|
|
||||||
if (!machines.empty()) {
|
if (!machines.empty()) {
|
||||||
gdi.addString("", fontMediumPlus, "Startade automater").setColor(colorDarkBlue);;
|
gdi.addString("", fontMediumPlus, "Startade automater").setColor(colorDarkBlue);
|
||||||
list<AutoMachine *>::iterator it;
|
list<AutoMachine *>::iterator it;
|
||||||
|
|
||||||
int baseX = gdi.getCX();
|
int baseX = gdi.getCX();
|
||||||
@ -666,30 +659,44 @@ bool TabAuto::loadPage(gdioutput &gdi, bool showSettingsLast)
|
|||||||
gdi.setOffset(storedOY, storedOY, true);
|
gdi.setOffset(storedOY, storedOY, true);
|
||||||
}
|
}
|
||||||
if (showSettingsLast && !machines.empty())
|
if (showSettingsLast && !machines.empty())
|
||||||
settings(gdi, *machines.rbegin(), Machines::Unknown);
|
settings(gdi, *machines.rbegin(), AutoMachine::State::Edit, Machines::Unknown);
|
||||||
|
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMachine::settingsTitle(gdioutput &gdi, char *title) {
|
void AutoMachine::settingsTitle(gdioutput &gdi, char *title) {
|
||||||
|
gdi.fillDown();
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
gdi.addString("", fontMediumPlus, title).setColor(colorDarkBlue);
|
gdi.addString("", fontMediumPlus, title).setColor(colorDarkBlue);
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool created, IntervalType type, const wstring &intervalIn) {
|
void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, State state, IntervalType type, const wstring &intervalIn) {
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
|
|
||||||
|
gdi.addInput("MachineName", machineName, 10, nullptr, L"Namn", L"Om du vill kan du namnge automaten");
|
||||||
|
|
||||||
if (type == IntervalMinute)
|
if (type == IntervalMinute)
|
||||||
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (MM:SS):");
|
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (MM:SS):");
|
||||||
else if (type == IntervalSecond)
|
else if (type == IntervalSecond)
|
||||||
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):");
|
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):");
|
||||||
|
|
||||||
gdi.dropLine(1);
|
gdi.dropLine(1);
|
||||||
gdi.addButton(startCommand, created ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId());
|
gdi.addButton(startCommand,
|
||||||
if (!created)
|
(state == State::Create || state == State::Load) ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
|
if (hasSaveMachine())
|
||||||
|
gdi.addButton("SaveMachine", "Spara inställningar", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
|
if (state == State::Load)
|
||||||
|
gdi.addButton("Erase", "Radera", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
|
if (state == State::Edit)
|
||||||
gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId());
|
gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
gdi.addButton("Stop", created ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId());
|
gdi.addButton("Stop", (state == State::Create || state == State::Load) ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId());
|
||||||
|
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
@ -704,13 +711,12 @@ void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool c
|
|||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|
||||||
settingsTitle(gdi, "Resultatutskrift / export");
|
settingsTitle(gdi, "Resultatutskrift / export");
|
||||||
wstring time = (created && interval <= 0) ? L"10:00" : getTimeMS(interval);
|
wstring time = (state == State::Create && interval <= 0) ? L"10:00" : getTimeMS(interval);
|
||||||
startCancelInterval(gdi, "StartResult", created, IntervalMinute, time);
|
startCancelInterval(gdi, "Save", state, IntervalMinute, time);
|
||||||
|
|
||||||
if (created) {
|
if (state == State::Create) {
|
||||||
oe.getAllClasses(classesToPrint);
|
oe.getAllClasses(classesToPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,6 +819,55 @@ void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintResultMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
|
wstring minute = gdi.getText("Interval");
|
||||||
|
int t = convertAbsoluteTimeMS(minute);
|
||||||
|
|
||||||
|
if (t < 2 || t>7200) {
|
||||||
|
throw meosException("Intervallet måste anges på formen MM:SS.");
|
||||||
|
}
|
||||||
|
doExport = gdi.isChecked("DoExport");
|
||||||
|
doPrint = gdi.isChecked("DoPrint");
|
||||||
|
exportFile = gdi.getText("ExportFile");
|
||||||
|
exportScript = gdi.getText("ExportScript");
|
||||||
|
|
||||||
|
if (!readOnly) {
|
||||||
|
structuredExport = gdi.isChecked("StructuredExport");
|
||||||
|
htmlRefresh = gdi.isChecked("HTMLRefresh") ? t : 0;
|
||||||
|
|
||||||
|
gdi.getSelection("Classes", classesToPrint);
|
||||||
|
|
||||||
|
ListBoxInfo lbi;
|
||||||
|
if (gdi.getSelectedItem("ListType", lbi)) {
|
||||||
|
oListParam par;
|
||||||
|
par.selection = classesToPrint;
|
||||||
|
par.listCode = EStdListType(lbi.data);
|
||||||
|
par.pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
par.showHeader = gdi.isChecked("ShowHeader");
|
||||||
|
par.showInterTimes = gdi.isChecked("ShowInterResults");
|
||||||
|
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
|
int legNr = gdi.getSelectedItem("LegNumber").first;
|
||||||
|
if (legNr >= 0)
|
||||||
|
par.setLegNumberCoded(legNr);
|
||||||
|
else
|
||||||
|
par.setLegNumberCoded(0);
|
||||||
|
|
||||||
|
oe.generateListInfo(par, listInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
po.onlyChanged = gdi.isChecked("OnlyChanged");
|
||||||
|
pageBreak = gdi.isChecked("PageBreak");
|
||||||
|
showHeader = gdi.isChecked("ShowHeader");
|
||||||
|
|
||||||
|
showInterResult = gdi.isChecked("ShowInterResults");
|
||||||
|
splitAnalysis = gdi.isChecked("SplitAnalysis");
|
||||||
|
if (doProcess) {
|
||||||
|
interval = t;
|
||||||
|
synchronize = true; //To force continuos data sync.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrintResultMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
void PrintResultMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
||||||
{
|
{
|
||||||
if (lock)
|
if (lock)
|
||||||
@ -876,7 +931,7 @@ void PrintResultMachine::status(gdioutput &gdi)
|
|||||||
{
|
{
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.addString("", 0, name);
|
AutoMachine::status(gdi);
|
||||||
gdi.addString("", 0, listInfo.getName());
|
gdi.addString("", 0, listInfo.getName());
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
if (doExport) {
|
if (doExport) {
|
||||||
@ -903,9 +958,9 @@ void PrintResultMachine::status(gdioutput &gdi)
|
|||||||
gdi.popX();
|
gdi.popX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
settingsTitle(gdi, "Förvarningsröst");
|
settingsTitle(gdi, "Förvarningsröst");
|
||||||
startCancelInterval(gdi, "StartPrewarning", created, IntervalNone, L"");
|
startCancelInterval(gdi, "Save", state, IntervalNone, L"");
|
||||||
|
|
||||||
gdi.addString("", 10, "help:computer_voice");
|
gdi.addString("", 10, "help:computer_voice");
|
||||||
|
|
||||||
@ -930,6 +985,27 @@ void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
gdi.popX();
|
gdi.popX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrewarningMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
|
waveFolder = gdi.getText("WaveFolder");
|
||||||
|
gdi.getSelection("Controls", controls);
|
||||||
|
|
||||||
|
oe.synchronizeList(oListId::oLPunchId);
|
||||||
|
oe.clearPrewarningSounds();
|
||||||
|
|
||||||
|
controlsSI.clear();
|
||||||
|
for (set<int>::iterator it = controls.begin(); it != controls.end(); ++it) {
|
||||||
|
pControl pc = oe.getControl(*it, false);
|
||||||
|
if (pc) {
|
||||||
|
vector<int> n;
|
||||||
|
pc->getNumbers(n);
|
||||||
|
controlsSI.insert(n.begin(), n.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doProcess)
|
||||||
|
synchronizePunches = true;
|
||||||
|
}
|
||||||
|
|
||||||
void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
||||||
{
|
{
|
||||||
oe->playPrewarningSounds(waveFolder, controlsSI);
|
oe->playPrewarningSounds(waveFolder, controlsSI);
|
||||||
@ -937,7 +1013,7 @@ void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
|||||||
|
|
||||||
void PrewarningMachine::status(gdioutput &gdi)
|
void PrewarningMachine::status(gdioutput &gdi)
|
||||||
{
|
{
|
||||||
gdi.addString("", 1, name);
|
AutoMachine::status(gdi);
|
||||||
|
|
||||||
string info="Förvarning på (SI-kod): ";
|
string info="Förvarning på (SI-kod): ";
|
||||||
bool first=true;
|
bool first=true;
|
||||||
@ -968,10 +1044,10 @@ void PrewarningMachine::status(gdioutput &gdi)
|
|||||||
gdi.popX();
|
gdi.popX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PunchMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void PunchMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
settingsTitle(gdi, "Test av stämplingsinläsningar");
|
settingsTitle(gdi, "Test av stämplingsinläsningar");
|
||||||
wstring time=created ? L"10" : itow(interval);
|
wstring time = state == State::Create ? L"10" : itow(interval);
|
||||||
startCancelInterval(gdi, "StartPunch", created, IntervalSecond, time);
|
startCancelInterval(gdi, "Save", state, IntervalSecond, time);
|
||||||
|
|
||||||
gdi.addString("", 10, "help:simulate");
|
gdi.addString("", 10, "help:simulate");
|
||||||
|
|
||||||
@ -995,9 +1071,23 @@ void PunchMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
gdi.addButton("GenerateCMP", "Generera testtävling", AutomaticCB);
|
gdi.addButton("GenerateCMP", "Generera testtävling", AutomaticCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PunchMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
|
wstring minute = gdi.getText("Interval");
|
||||||
|
int t = _wtoi(minute.c_str());
|
||||||
|
|
||||||
|
if (t<1 || t>7200) {
|
||||||
|
throw meosException(L"Ogiltigt antal sekunder: X#" + minute);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
interval = t;
|
||||||
|
radio = gdi.getTextNo("Radio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PunchMachine::status(gdioutput &gdi)
|
void PunchMachine::status(gdioutput &gdi)
|
||||||
{
|
{
|
||||||
gdi.addString("", 1, name);
|
AutoMachine::status(gdi);
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
if (interval>0){
|
if (interval>0){
|
||||||
@ -1066,15 +1156,15 @@ void PunchMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
wstring time;
|
wstring time;
|
||||||
if (interval>0)
|
if (interval>0)
|
||||||
time = itow(interval);
|
time = itow(interval);
|
||||||
else if (created)
|
else if (state == State::Create)
|
||||||
time = L"30";
|
time = L"30";
|
||||||
|
|
||||||
settingsTitle(gdi, "Sträcktider / WinSplits");
|
settingsTitle(gdi, "Sträcktider / WinSplits");
|
||||||
startCancelInterval(gdi, "StartSplits", created, IntervalSecond, time);
|
startCancelInterval(gdi, "Save", state, IntervalSecond, time);
|
||||||
|
|
||||||
gdi.addString("", 0, "Intervall (sekunder). Lämna blankt för att uppdatera när "
|
gdi.addString("", 0, "Intervall (sekunder). Lämna blankt för att uppdatera när "
|
||||||
"tävlingsdata ändras.");
|
"tävlingsdata ändras.");
|
||||||
@ -1094,9 +1184,33 @@ void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SplitsMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
|
wstring ivt = gdi.getText("Interval");
|
||||||
|
|
||||||
|
int iv = gdi.getTextNo("Interval");
|
||||||
|
file = gdi.getText("FileName");
|
||||||
|
|
||||||
|
if (!ivt.empty() && (iv < 1 || iv > 7200)) {
|
||||||
|
throw meosException(L"Ogiltigt antal sekunder: X#" + gdi.getText("Interval"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.empty()) {
|
||||||
|
throw meosException("Filnamnet får inte vara tomt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doProcess) {
|
||||||
|
//Try exporting.
|
||||||
|
oe.exportIOFSplits(oEvent::IOF20, file.c_str(), true, false,
|
||||||
|
set<int>(), -1, false, true, true, false);
|
||||||
|
interval = iv;
|
||||||
|
synchronize = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SplitsMachine::status(gdioutput &gdi)
|
void SplitsMachine::status(gdioutput &gdi)
|
||||||
{
|
{
|
||||||
gdi.addString("", 1, name);
|
AutoMachine::status(gdi);
|
||||||
if (!file.empty()) {
|
if (!file.empty()) {
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
@ -1133,7 +1247,8 @@ void SplitsMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SaveMachine::status(gdioutput &gdi) {
|
void SaveMachine::status(gdioutput &gdi) {
|
||||||
gdi.addString("", 1, name);
|
AutoMachine::status(gdi);
|
||||||
|
|
||||||
if (!baseFile.empty()) {
|
if (!baseFile.empty()) {
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
@ -1165,10 +1280,10 @@ void SaveMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void SaveMachine::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
settingsTitle(gdi, "Säkerhetskopiering");
|
settingsTitle(gdi, "Säkerhetskopiering");
|
||||||
wstring time=created ? L"10:00" : getTimeMS(interval);
|
wstring time=state == State::Create ? L"10:00" : getTimeMS(interval);
|
||||||
startCancelInterval(gdi, "StartBackup", created, IntervalMinute, time);
|
startCancelInterval(gdi, "Save", state, IntervalMinute, time);
|
||||||
|
|
||||||
int cx = gdi.getCX();
|
int cx = gdi.getCX();
|
||||||
gdi.addInput("BaseFile", baseFile, 32, 0, L"Mapp:");
|
gdi.addInput("BaseFile", baseFile, 32, 0, L"Mapp:");
|
||||||
@ -1177,8 +1292,8 @@ void SaveMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
|||||||
gdi.setCX(cx);
|
gdi.setCX(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveMachine::saveSettings(gdioutput &gdi) {
|
void SaveMachine::save(oEvent &oe, gdioutput &gdi, bool doProcess) {
|
||||||
|
AutoMachine::save(oe, gdi, doProcess);
|
||||||
wstring minute=gdi.getText("Interval");
|
wstring minute=gdi.getText("Interval");
|
||||||
int t=convertAbsoluteTimeMS(minute);
|
int t=convertAbsoluteTimeMS(minute);
|
||||||
|
|
||||||
@ -1193,23 +1308,83 @@ void SaveMachine::saveSettings(gdioutput &gdi) {
|
|||||||
if (*f.rbegin() != '\\' && *f.rbegin() != '/')
|
if (*f.rbegin() != '\\' && *f.rbegin() != '/')
|
||||||
f += L"\\";
|
f += L"\\";
|
||||||
|
|
||||||
wstring sample = f + L"sample.txt";
|
if (doProcess) {
|
||||||
ofstream fout(sample.c_str(), ios_base::trunc|ios_base::out);
|
wstring sample = f + L"sample.txt";
|
||||||
bool bad = false;
|
ofstream fout(sample.c_str(), ios_base::trunc | ios_base::out);
|
||||||
if (fout.bad())
|
bool bad = false;
|
||||||
bad = true;
|
if (fout.bad())
|
||||||
else {
|
bad = true;
|
||||||
fout << "foo" << endl;
|
else {
|
||||||
fout.close();
|
fout << "foo" << endl;
|
||||||
bad = fout.bad();
|
fout.close();
|
||||||
_wremove(sample.c_str());
|
bad = fout.bad();
|
||||||
}
|
_wremove(sample.c_str());
|
||||||
if (bad)
|
}
|
||||||
throw meosException(L"Ogiltig destination X#" + f);
|
if (bad)
|
||||||
|
throw meosException(L"Ogiltig destination X#" + f);
|
||||||
|
|
||||||
|
interval = t;
|
||||||
|
}
|
||||||
baseFile = f;
|
baseFile = f;
|
||||||
interval = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabAuto::clearCompetitionData() {
|
void TabAuto::clearCompetitionData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Machines AutoMachine::getType(const string &typeStr) {
|
||||||
|
if (typeStr == "onlineinput")
|
||||||
|
return Machines::mOnlineInput;
|
||||||
|
else if (typeStr == "onlineresults")
|
||||||
|
return Machines::mOnlineResults;
|
||||||
|
return Machines::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
string AutoMachine::getDescription(Machines type) {
|
||||||
|
switch (type) {
|
||||||
|
case mPrintResultsMachine:
|
||||||
|
return "Resultatutskrift / export";
|
||||||
|
case mPunchMachine:
|
||||||
|
return "Stämplingstest";
|
||||||
|
case mSplitsMachine:
|
||||||
|
return "Sträcktider (WinSplits)";
|
||||||
|
case mPrewarningMachine:
|
||||||
|
return "Förvarningsröst";
|
||||||
|
case mOnlineResults:
|
||||||
|
return "Resultat online";
|
||||||
|
case mOnlineInput:
|
||||||
|
return "Inmatning online";
|
||||||
|
case mSaveBackup:
|
||||||
|
return "Säkerhetskopiering";
|
||||||
|
case mInfoService:
|
||||||
|
return "Informationsserver";
|
||||||
|
case mMySQLReconnect:
|
||||||
|
return "MySQL reconnect";
|
||||||
|
default:
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string AutoMachine::getTypeString(Machines type) {
|
||||||
|
switch (type) {
|
||||||
|
case mPrintResultsMachine:
|
||||||
|
return "printresult";
|
||||||
|
case mPunchMachine:
|
||||||
|
return "punchtest";
|
||||||
|
case mSplitsMachine:
|
||||||
|
return "splits";
|
||||||
|
case mPrewarningMachine:
|
||||||
|
return "prewarning";
|
||||||
|
case mOnlineResults:
|
||||||
|
return "onlineresults";
|
||||||
|
case mOnlineInput:
|
||||||
|
return "onlineinput";
|
||||||
|
case mSaveBackup:
|
||||||
|
return "backup";
|
||||||
|
case mInfoService:
|
||||||
|
return "infoserver";
|
||||||
|
case mMySQLReconnect:
|
||||||
|
return "reconnect";
|
||||||
|
default:
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
112
code/TabAuto.h
112
code/TabAuto.h
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -51,6 +51,14 @@ enum Machines {
|
|||||||
|
|
||||||
class AutoMachine
|
class AutoMachine
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Edit,
|
||||||
|
Create,
|
||||||
|
Load
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int myid;
|
int myid;
|
||||||
static int uniqueId;
|
static int uniqueId;
|
||||||
@ -61,21 +69,47 @@ protected:
|
|||||||
|
|
||||||
void settingsTitle(gdioutput &gdi, char *title);
|
void settingsTitle(gdioutput &gdi, char *title);
|
||||||
enum IntervalType {IntervalNone, IntervalMinute, IntervalSecond};
|
enum IntervalType {IntervalNone, IntervalMinute, IntervalSecond};
|
||||||
void startCancelInterval(gdioutput &gdi, char *startCommand, bool created, IntervalType type, const wstring &interval);
|
void startCancelInterval(gdioutput &gdi, char *startCommand, State state, IntervalType type, const wstring &interval);
|
||||||
|
|
||||||
|
virtual bool hasSaveMachine() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual void saveMachine(oEvent &oe, const wstring &guiInterval) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void loadMachine(oEvent &oe, const wstring &name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true to auto-remove
|
||||||
|
virtual bool removeMe() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static AutoMachine *getMachine(int id);
|
static AutoMachine *getMachine(int id);
|
||||||
static void resetGlobalId() {uniqueId = 1;}
|
static void resetGlobalId() {uniqueId = 1;}
|
||||||
int getId() const {return myid;}
|
int getId() const {return myid;}
|
||||||
static AutoMachine* construct(Machines);
|
static AutoMachine* construct(Machines);
|
||||||
|
static Machines getType(const string &typeStr);
|
||||||
|
static string getDescription(Machines type);
|
||||||
|
static string getTypeString(Machines type);
|
||||||
|
string getTypeString() const { return getTypeString(type); }
|
||||||
|
wstring getMachineName() const {
|
||||||
|
return machineName.empty() ? L"default" : machineName;
|
||||||
|
}
|
||||||
|
|
||||||
void setEditMode(bool em) {editMode = em;}
|
void setEditMode(bool em) {editMode = em;}
|
||||||
string name;
|
string name;
|
||||||
|
wstring machineName;
|
||||||
DWORD interval; //Interval seconds
|
DWORD interval; //Interval seconds
|
||||||
DWORD timeout; //Timeout (TickCount)
|
DWORD timeout; //Timeout (TickCount)
|
||||||
bool synchronize;
|
bool synchronize;
|
||||||
bool synchronizePunches;
|
bool synchronizePunches;
|
||||||
virtual void settings(gdioutput &gdi, oEvent &oe, bool created) = 0;
|
|
||||||
virtual void save(oEvent &oe, gdioutput &gdi) {}
|
virtual void settings(gdioutput &gdi, oEvent &oe, State state) = 0;
|
||||||
|
virtual void save(oEvent &oe, gdioutput &gdi, bool doProcess) = 0;
|
||||||
virtual void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) = 0;
|
virtual void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) = 0;
|
||||||
virtual bool isEditMode() const {return editMode;}
|
virtual bool isEditMode() const {return editMode;}
|
||||||
virtual void status(gdioutput &gdi) = 0;
|
virtual void status(gdioutput &gdi) = 0;
|
||||||
@ -119,9 +153,10 @@ public:
|
|||||||
prm->errorLock = false;
|
prm->errorLock = false;
|
||||||
return prm;
|
return prm;
|
||||||
}
|
}
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state) final;
|
||||||
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
|
||||||
|
|
||||||
void setHTML(const wstring &file, int timeout) {
|
void setHTML(const wstring &file, int timeout) {
|
||||||
exportFile = file;
|
exportFile = file;
|
||||||
@ -176,10 +211,10 @@ public:
|
|||||||
return prm;
|
return prm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state) final;
|
||||||
void saveSettings(gdioutput &gdi);
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
|
||||||
|
|
||||||
SaveMachine():AutoMachine("Säkerhetskopiera", Machines::mSaveBackup) , saveIter(0) {
|
SaveMachine():AutoMachine("Säkerhetskopiera", Machines::mSaveBackup) , saveIter(0) {
|
||||||
}
|
}
|
||||||
@ -194,10 +229,12 @@ protected:
|
|||||||
set<int> controls;
|
set<int> controls;
|
||||||
set<int> controlsSI;
|
set<int> controlsSI;
|
||||||
public:
|
public:
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state);
|
||||||
PrewarningMachine *clone() const {return new PrewarningMachine(*this);}
|
PrewarningMachine *clone() const {return new PrewarningMachine(*this);}
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
|
||||||
|
|
||||||
PrewarningMachine():AutoMachine("Förvarningsröst", Machines::mPrewarningMachine) {}
|
PrewarningMachine():AutoMachine("Förvarningsröst", Machines::mPrewarningMachine) {}
|
||||||
friend class TabAuto;
|
friend class TabAuto;
|
||||||
};
|
};
|
||||||
@ -210,12 +247,21 @@ protected:
|
|||||||
wstring timeError;
|
wstring timeError;
|
||||||
wstring timeReconnect;
|
wstring timeReconnect;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
|
bool toRemove = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state);
|
||||||
MySQLReconnect *clone() const {return new MySQLReconnect(*this);}
|
MySQLReconnect *clone() const {return new MySQLReconnect(*this);}
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
bool stop();
|
bool stop();
|
||||||
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool removeMe() const final {
|
||||||
|
return toRemove;
|
||||||
|
}
|
||||||
|
|
||||||
MySQLReconnect(const wstring &error);
|
MySQLReconnect(const wstring &error);
|
||||||
virtual ~MySQLReconnect();
|
virtual ~MySQLReconnect();
|
||||||
friend class TabAuto;
|
friend class TabAuto;
|
||||||
@ -230,9 +276,11 @@ protected:
|
|||||||
int radio;
|
int radio;
|
||||||
public:
|
public:
|
||||||
PunchMachine *clone() const {return new PunchMachine(*this);}
|
PunchMachine *clone() const {return new PunchMachine(*this);}
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state) final;
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
|
||||||
|
|
||||||
PunchMachine():AutoMachine("Stämplingsautomat", Machines::mPunchMachine), radio(0) {}
|
PunchMachine():AutoMachine("Stämplingsautomat", Machines::mPunchMachine), radio(0) {}
|
||||||
friend class TabAuto;
|
friend class TabAuto;
|
||||||
};
|
};
|
||||||
@ -246,9 +294,11 @@ protected:
|
|||||||
int leg;
|
int leg;
|
||||||
public:
|
public:
|
||||||
SplitsMachine *clone() const {return new SplitsMachine(*this);}
|
SplitsMachine *clone() const {return new SplitsMachine(*this);}
|
||||||
void settings(gdioutput &gdi, oEvent &oe, bool created);
|
void settings(gdioutput &gdi, oEvent &oe, State state) final;
|
||||||
void status(gdioutput &gdi);
|
void status(gdioutput &gdi) final;
|
||||||
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast);
|
void process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) final;
|
||||||
|
void save(oEvent &oe, gdioutput &gdi, bool doProcess) final;
|
||||||
|
|
||||||
SplitsMachine() : AutoMachine("Sträcktider/WinSplits", Machines::mSplitsMachine), leg(-1) {}
|
SplitsMachine() : AutoMachine("Sträcktider/WinSplits", Machines::mSplitsMachine), leg(-1) {}
|
||||||
friend class TabAuto;
|
friend class TabAuto;
|
||||||
};
|
};
|
||||||
@ -273,20 +323,22 @@ private:
|
|||||||
void timerCallback(gdioutput &gdi);
|
void timerCallback(gdioutput &gdi);
|
||||||
void syncCallback(gdioutput &gdi);
|
void syncCallback(gdioutput &gdi);
|
||||||
|
|
||||||
void settings(gdioutput &gdi, AutoMachine *sm, Machines type);
|
void settings(gdioutput &gdi, AutoMachine *sm, AutoMachine::State state, Machines type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
|
bool hasActiveReconnection() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AutoMachine *getMachine(int id);
|
AutoMachine *getMachine(int id);
|
||||||
//AutoMachine *getMachine(const string &name);
|
|
||||||
bool stopMachine(AutoMachine *am);
|
bool stopMachine(AutoMachine *am);
|
||||||
void killMachines();
|
void killMachines();
|
||||||
void addMachine(const AutoMachine &am) {
|
|
||||||
|
AutoMachine &addMachine(const AutoMachine &am) {
|
||||||
machines.push_back(am.clone());
|
machines.push_back(am.clone());
|
||||||
setTimer(machines.back());
|
setTimer(machines.back());
|
||||||
|
return *machines.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
int processButton(gdioutput &gdi, const ButtonInfo &bu);
|
int processButton(gdioutput &gdi, const ButtonInfo &bu);
|
||||||
@ -305,8 +357,10 @@ public:
|
|||||||
|
|
||||||
friend class AutoTask;
|
friend class AutoTask;
|
||||||
friend void tabForceSync(gdioutput &gdi, pEvent oe);
|
friend void tabForceSync(gdioutput &gdi, pEvent oe);
|
||||||
|
|
||||||
|
static void tabAutoKillMachines();
|
||||||
|
static void tabAutoRegister(TabAuto* ta);
|
||||||
|
static AutoMachine& tabAutoAddMachinge(const AutoMachine& am);
|
||||||
|
static bool hasActiveReconnectionMachine();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tabAutoKillMachines();
|
|
||||||
void tabAutoRegister(TabAuto *ta);
|
|
||||||
void tabAutoAddMachinge(const AutoMachine &am);
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -310,89 +310,94 @@ int TabClass::multiCB(gdioutput &gdi, int type, void *data)
|
|||||||
else if (bi.id == "ShowForking") {
|
else if (bi.id == "ShowForking") {
|
||||||
if (!checkClassSelected(gdi))
|
if (!checkClassSelected(gdi))
|
||||||
return false;
|
return false;
|
||||||
pClass pc=oe->getClass(ClassId);
|
pClass pc = oe->getClass(ClassId);
|
||||||
if (!pc)
|
if (!pc)
|
||||||
throw std::exception("Klassen finns ej.");
|
throw std::exception("Klassen finns ej.");
|
||||||
|
|
||||||
vector< vector<int> > forks;
|
|
||||||
set< pair<int, int> > unfairLegs;
|
|
||||||
vector< vector<int> > legOrder;
|
|
||||||
|
|
||||||
pc->checkForking(legOrder, forks, unfairLegs);
|
|
||||||
|
|
||||||
gdioutput *gdi_new = getExtraWindow("fork", true);
|
gdioutput *gdi_new = getExtraWindow("fork", true);
|
||||||
wstring title = lang.tl(L"Forkings for X#" + pc->getName());
|
wstring title = lang.tl(L"Forkings for X#" + pc->getName());
|
||||||
if (!gdi_new)
|
if (!gdi_new)
|
||||||
gdi_new = createExtraWindow("fork", title,
|
gdi_new = createExtraWindow("fork", title,
|
||||||
gdi.scaleLength(1024) );
|
gdi.scaleLength(1024));
|
||||||
else
|
else
|
||||||
gdi_new->setWindowTitle(title);
|
gdi_new->setWindowTitle(title);
|
||||||
|
|
||||||
gdi_new->clearPage(false);
|
gdi_new->clearPage(false);
|
||||||
|
|
||||||
gdi_new->addString("", fontMediumPlus, "Forkings");
|
|
||||||
|
|
||||||
for (size_t k = 0; k < forks.size(); k++) {
|
if (pc->hasCoursePool()) {
|
||||||
gdi_new->dropLine(0.7);
|
gdi_new->addString("", fontMediumPlus, "Klassen använder banpool");
|
||||||
wstring ver = itow(k+1) + L": ";
|
|
||||||
for (size_t j = 0; j < legOrder[k].size(); j++) {
|
|
||||||
pCourse crs = oe->getCourse(legOrder[k][j]);
|
|
||||||
if (crs) {
|
|
||||||
if (j>0)
|
|
||||||
ver += L", ";
|
|
||||||
ver += crs->getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gdi_new->addStringUT(1, ver);
|
|
||||||
gdi_new->pushX();
|
|
||||||
gdi_new->fillRight();
|
|
||||||
for (size_t j = 0; j < forks[k].size(); j++) {
|
|
||||||
wstring ctrl;
|
|
||||||
if (forks[k][j] > 0)
|
|
||||||
ctrl += itow(forks[k][j]);
|
|
||||||
else {
|
|
||||||
if (j == 0)
|
|
||||||
ctrl += lang.tl("Start");
|
|
||||||
else if (j + 1 == forks[k].size())
|
|
||||||
ctrl += lang.tl("Mål");
|
|
||||||
else
|
|
||||||
ctrl += lang.tl("Växel");
|
|
||||||
}
|
|
||||||
int next = -100;
|
|
||||||
if (j + 1 < forks[k].size()) {
|
|
||||||
ctrl += L",";
|
|
||||||
next = forks[k][j+1];
|
|
||||||
}
|
|
||||||
int prev = j>0 ? forks[k][j-1] : -100;
|
|
||||||
|
|
||||||
bool warn = unfairLegs.count(make_pair(prev, forks[k][j])) != 0;// ||
|
|
||||||
//unfairLegs.count(make_pair(forks[k][j], next)) != 0;
|
|
||||||
|
|
||||||
TextInfo &ti = gdi_new->addStringUT(italicText, ctrl);
|
|
||||||
if (warn) {
|
|
||||||
ti.setColor(colorRed);
|
|
||||||
ti.format = boldText;
|
|
||||||
}
|
|
||||||
gdi.setCX(gdi.getCX() - gdi.scaleLength(4));
|
|
||||||
}
|
|
||||||
gdi_new->popX();
|
|
||||||
gdi_new->fillDown();
|
|
||||||
gdi_new->dropLine();
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
vector< vector<int> > forks;
|
||||||
|
set< pair<int, int> > unfairLegs;
|
||||||
|
vector< vector<int> > legOrder;
|
||||||
|
|
||||||
if (!unfairLegs.empty()) {
|
pc->checkForking(legOrder, forks, unfairLegs);
|
||||||
gdi_new->dropLine();
|
|
||||||
gdi_new->addString("", fontMediumPlus, "Unfair control legs");
|
|
||||||
gdi_new->dropLine(0.5);
|
|
||||||
for (set< pair<int, int> >::const_iterator p = unfairLegs.begin();
|
|
||||||
p != unfairLegs.end(); ++p) {
|
|
||||||
|
|
||||||
wstring f = p->first > 0 ? itow(p->first) : lang.tl("Växel");
|
gdi_new->addString("", fontMediumPlus, "Forkings");
|
||||||
wstring s = p->second > 0 ? itow(p->second) : lang.tl("Växel");
|
|
||||||
gdi_new->addStringUT(0, makeDash(f + L" - " + s));
|
for (size_t k = 0; k < forks.size(); k++) {
|
||||||
|
gdi_new->dropLine(0.7);
|
||||||
|
wstring ver = itow(k + 1) + L": ";
|
||||||
|
for (size_t j = 0; j < legOrder[k].size(); j++) {
|
||||||
|
pCourse crs = oe->getCourse(legOrder[k][j]);
|
||||||
|
if (crs) {
|
||||||
|
if (j > 0)
|
||||||
|
ver += L", ";
|
||||||
|
ver += crs->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gdi_new->addStringUT(1, ver);
|
||||||
|
gdi_new->pushX();
|
||||||
|
gdi_new->fillRight();
|
||||||
|
for (size_t j = 0; j < forks[k].size(); j++) {
|
||||||
|
wstring ctrl;
|
||||||
|
if (forks[k][j] > 0)
|
||||||
|
ctrl += itow(forks[k][j]);
|
||||||
|
else {
|
||||||
|
if (j == 0)
|
||||||
|
ctrl += lang.tl("Start");
|
||||||
|
else if (j + 1 == forks[k].size())
|
||||||
|
ctrl += lang.tl("Mål");
|
||||||
|
else
|
||||||
|
ctrl += lang.tl("Växel");
|
||||||
|
}
|
||||||
|
int next = -100;
|
||||||
|
if (j + 1 < forks[k].size()) {
|
||||||
|
ctrl += L",";
|
||||||
|
next = forks[k][j + 1];
|
||||||
|
}
|
||||||
|
int prev = j > 0 ? forks[k][j - 1] : -100;
|
||||||
|
|
||||||
|
bool warn = unfairLegs.count(make_pair(prev, forks[k][j])) != 0;// ||
|
||||||
|
//unfairLegs.count(make_pair(forks[k][j], next)) != 0;
|
||||||
|
|
||||||
|
TextInfo &ti = gdi_new->addStringUT(italicText, ctrl);
|
||||||
|
if (warn) {
|
||||||
|
ti.setColor(colorRed);
|
||||||
|
ti.format = boldText;
|
||||||
|
}
|
||||||
|
gdi.setCX(gdi.getCX() - gdi.scaleLength(4));
|
||||||
|
}
|
||||||
|
gdi_new->popX();
|
||||||
|
gdi_new->fillDown();
|
||||||
|
gdi_new->dropLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unfairLegs.empty()) {
|
||||||
|
gdi_new->dropLine();
|
||||||
|
gdi_new->addString("", fontMediumPlus, "Unfair control legs");
|
||||||
|
gdi_new->dropLine(0.5);
|
||||||
|
for (set< pair<int, int> >::const_iterator p = unfairLegs.begin();
|
||||||
|
p != unfairLegs.end(); ++p) {
|
||||||
|
|
||||||
|
wstring f = p->first > 0 ? itow(p->first) : lang.tl("Växel");
|
||||||
|
wstring s = p->second > 0 ? itow(p->second) : lang.tl("Växel");
|
||||||
|
gdi_new->addStringUT(0, makeDash(f + L" - " + s));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi_new->dropLine();
|
gdi_new->dropLine();
|
||||||
gdi_new->addButton("CloseWindow", "Stäng", ClassesCB);
|
gdi_new->addButton("CloseWindow", "Stäng", ClassesCB);
|
||||||
gdi_new->refresh();
|
gdi_new->refresh();
|
||||||
@ -1923,7 +1928,37 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
|
|||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (bi.id=="Split") {
|
else if (bi.id == "Duplicate") {
|
||||||
|
save(gdi, true);
|
||||||
|
if (!checkClassSelected(gdi))
|
||||||
|
return false;
|
||||||
|
pClass pc = oe->getClass(ClassId);
|
||||||
|
if (!pc)
|
||||||
|
throw std::exception("Class not found");
|
||||||
|
|
||||||
|
oClass copyClass(*pc);
|
||||||
|
copyClass.clearDuplicate();
|
||||||
|
wstring name = pc->getName();
|
||||||
|
wstring dup = lang.tl(" (kopia)");
|
||||||
|
size_t pos = name.find(dup);
|
||||||
|
wstring base;
|
||||||
|
if (pos > 0 && pos < string::npos)
|
||||||
|
base = name.substr(0, pos);
|
||||||
|
else
|
||||||
|
base = name;
|
||||||
|
|
||||||
|
name = base + dup;
|
||||||
|
int cnt = 1;
|
||||||
|
while (oe->getClass(name) != nullptr)
|
||||||
|
name = base + dup + L" " + itow(++cnt);
|
||||||
|
|
||||||
|
copyClass.setName(name, true);
|
||||||
|
pc = oe->addClass(copyClass);
|
||||||
|
oe->fillClasses(gdi, "Classes", oEvent::extraDrawn, oEvent::filterNone);
|
||||||
|
selectClass(gdi, pc->getId());
|
||||||
|
gdi.setInputFocus("Name", true);
|
||||||
|
}
|
||||||
|
else if (bi.id == "Split") {
|
||||||
save(gdi, true);
|
save(gdi, true);
|
||||||
if (!checkClassSelected(gdi))
|
if (!checkClassSelected(gdi))
|
||||||
return false;
|
return false;
|
||||||
@ -3463,7 +3498,7 @@ bool TabClass::loadPage(gdioutput &gdi)
|
|||||||
func.push_back(ButtonData("Merge", "Slå ihop klasser...", false));
|
func.push_back(ButtonData("Merge", "Slå ihop klasser...", false));
|
||||||
func.push_back(ButtonData("Split", "Dela klassen...", false));
|
func.push_back(ButtonData("Split", "Dela klassen...", false));
|
||||||
}
|
}
|
||||||
|
func.emplace_back("Duplicate", "Duplicera", false);
|
||||||
|
|
||||||
if (showAdvanced && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Vacancy)) {
|
if (showAdvanced && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Vacancy)) {
|
||||||
vector<pRunner> rr;
|
vector<pRunner> rr;
|
||||||
@ -4185,11 +4220,18 @@ void TabClass::selectCourses(gdioutput &gdi, int legNo) {
|
|||||||
void TabClass::updateFairForking(gdioutput &gdi, pClass pc) const {
|
void TabClass::updateFairForking(gdioutput &gdi, pClass pc) const {
|
||||||
if (!gdi.hasWidget("FairForking"))
|
if (!gdi.hasWidget("FairForking"))
|
||||||
return;
|
return;
|
||||||
|
BaseInfo *bi = gdi.setText("FairForking", gdi.getText("FairForking"), false);
|
||||||
|
TextInfo &text = dynamic_cast<TextInfo &>(*bi);
|
||||||
|
|
||||||
|
if (pc->hasCoursePool()) {
|
||||||
|
text.setColor(colorBlack);
|
||||||
|
gdi.setText("FairForking", L"", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vector< vector<int> > forks;
|
vector< vector<int> > forks;
|
||||||
vector< vector<int> > forksC;
|
vector< vector<int> > forksC;
|
||||||
set< pair<int, int> > unfairLegs;
|
set< pair<int, int> > unfairLegs;
|
||||||
BaseInfo *bi = gdi.setText("FairForking", gdi.getText("FairForking"), false);
|
|
||||||
TextInfo &text = dynamic_cast<TextInfo &>(*bi);
|
|
||||||
if (pc->checkForking(forksC, forks, unfairLegs)) {
|
if (pc->checkForking(forksC, forks, unfairLegs)) {
|
||||||
text.setColor(colorGreen);
|
text.setColor(colorGreen);
|
||||||
gdi.setText("FairForking", lang.tl("The forking is fair."), true);
|
gdi.setText("FairForking", lang.tl("The forking is fair."), true);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -157,8 +157,8 @@ bool TabCompetition::save(gdioutput &gdi, bool write)
|
|||||||
bool TabCompetition::importFile(HWND hWnd, gdioutput &gdi)
|
bool TabCompetition::importFile(HWND hWnd, gdioutput &gdi)
|
||||||
{
|
{
|
||||||
vector< pair<wstring, wstring> > ext;
|
vector< pair<wstring, wstring> > ext;
|
||||||
ext.push_back(make_pair(L"xml-data", L"*.xml;*.bu?"));
|
ext.push_back(make_pair(L"MeOS-data", L"*.meosxml;*.xml;*.bu?"));
|
||||||
wstring fileName = gdi.browseForOpen(ext, L"xml");
|
wstring fileName = gdi.browseForOpen(ext, L"meosxml");
|
||||||
if (fileName.empty())
|
if (fileName.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -182,8 +182,8 @@ bool TabCompetition::exportFileAs(HWND hWnd, gdioutput &gdi)
|
|||||||
{
|
{
|
||||||
int ix = 0;
|
int ix = 0;
|
||||||
vector< pair<wstring, wstring> > ext;
|
vector< pair<wstring, wstring> > ext;
|
||||||
ext.push_back(make_pair(L"xml-data", L"*.xml"));
|
ext.push_back(make_pair(L"MeOS-data", L"*.meosxml"));
|
||||||
wstring fileName = gdi.browseForSave(ext, L"xml", ix);
|
wstring fileName = gdi.browseForSave(ext, L"meosxml", ix);
|
||||||
if (fileName.empty())
|
if (fileName.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -779,7 +779,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
|||||||
wstring base = constructBase(L"base", L"");
|
wstring base = constructBase(L"base", L"");
|
||||||
wchar_t newBase[_MAX_PATH];
|
wchar_t newBase[_MAX_PATH];
|
||||||
getUserFile(newBase, base.c_str());
|
getUserFile(newBase, base.c_str());
|
||||||
if (!fileExist(newBase))
|
if (!fileExists(newBase))
|
||||||
oe->save(newBase);
|
oe->save(newBase);
|
||||||
|
|
||||||
loadConnectionPage(gdi);
|
loadConnectionPage(gdi);
|
||||||
@ -2382,7 +2382,7 @@ void TabCompetition::copyrightLine(gdioutput &gdi) const
|
|||||||
|
|
||||||
gdi.dropLine(0.4);
|
gdi.dropLine(0.4);
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.addString("", 0, makeDash(L"#Copyright © 2007-2020 Melin Software HB"));
|
gdi.addString("", 0, makeDash(L"#Copyright © 2007-2021 Melin Software HB"));
|
||||||
gdi.dropLine(1);
|
gdi.dropLine(1);
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
|
|
||||||
@ -2412,7 +2412,7 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
|
|||||||
gdi.dropLine(1.5);
|
gdi.dropLine(1.5);
|
||||||
gdi.setCX(gdi.getCX() + gdi.scaleLength(20));
|
gdi.setCX(gdi.getCX() + gdi.scaleLength(20));
|
||||||
|
|
||||||
gdi.addStringUT(1, makeDash(L"Copyright © 2007-2020 Melin Software HB"));
|
gdi.addStringUT(1, makeDash(L"Copyright © 2007-2021 Melin Software HB"));
|
||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.addStringUT(10, "The database connection used is MySQL++\nCopyright "
|
gdi.addStringUT(10, "The database connection used is MySQL++\nCopyright "
|
||||||
"(c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by MySQL AB,"
|
"(c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by MySQL AB,"
|
||||||
@ -2764,7 +2764,7 @@ void TabCompetition::textSizeControl(gdioutput &gdi) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TabCompetition::getOrganizer(bool updateEvent) {
|
int TabCompetition::getOrganizer(bool updateEvent) {
|
||||||
wstring apikey = oe->getPropertyStringDecrypt("apikey", "");
|
wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", ""));
|
||||||
if (apikey.empty())
|
if (apikey.empty())
|
||||||
return 0;
|
return 0;
|
||||||
if (!isAscii(apikey))
|
if (!isAscii(apikey))
|
||||||
@ -2837,7 +2837,7 @@ int TabCompetition::getOrganizer(bool updateEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TabCompetition::getAPIKey(vector< pair<wstring, wstring> > &key) const {
|
void TabCompetition::getAPIKey(vector< pair<wstring, wstring> > &key) const {
|
||||||
wstring apikey = oe->getPropertyStringDecrypt("apikey", "");
|
wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", ""));
|
||||||
|
|
||||||
if (apikey.empty() || organizorId == 0)
|
if (apikey.empty() || organizorId == 0)
|
||||||
throw std::exception("Internal error");
|
throw std::exception("Internal error");
|
||||||
@ -2989,7 +2989,7 @@ void TabCompetition::getEventorCmpData(gdioutput &gdi, int id,
|
|||||||
|
|
||||||
pw.setProgress(1);
|
pw.setProgress(1);
|
||||||
vector< pair<wstring, wstring> > key;
|
vector< pair<wstring, wstring> > key;
|
||||||
wstring apikey = oe->getPropertyStringDecrypt("apikey", "");
|
wstring apikey = gdioutput::widen(oe->getPropertyStringDecrypt("apikey", ""));
|
||||||
key.push_back(pair<wstring, wstring>(L"ApiKey", apikey));
|
key.push_back(pair<wstring, wstring>(L"ApiKey", apikey));
|
||||||
|
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -108,10 +108,10 @@ void TabControl::selectControl(gdioutput &gdi, pControl pc)
|
|||||||
gdi.enableEditControls(true);
|
gdi.enableEditControls(true);
|
||||||
|
|
||||||
oControl::ControlStatus st = pc->getStatus();
|
oControl::ControlStatus st = pc->getStatus();
|
||||||
if (st == oControl::StatusRogaining || st == oControl::StatusNoTiming)
|
if (st == oControl::StatusRogaining || st == oControl::StatusNoTiming || st == oControl::StatusBadNoTiming)
|
||||||
gdi.disableInput("MinTime");
|
gdi.disableInput("MinTime");
|
||||||
|
|
||||||
if (st == oControl::StatusNoTiming)
|
if (st == oControl::StatusNoTiming || st == oControl::StatusBadNoTiming)
|
||||||
gdi.disableInput("TimeAdjust");
|
gdi.disableInput("TimeAdjust");
|
||||||
|
|
||||||
if (gdi.hasWidget("Point") && st != oControl::StatusRogaining)
|
if (gdi.hasWidget("Point") && st != oControl::StatusRogaining)
|
||||||
@ -164,7 +164,7 @@ void TabControl::save(gdioutput &gdi)
|
|||||||
pc->setStatus(oControl::ControlStatus(gdi.getSelectedItem("Status").first));
|
pc->setStatus(oControl::ControlStatus(gdi.getSelectedItem("Status").first));
|
||||||
pc->setTimeAdjust(gdi.getText("TimeAdjust"));
|
pc->setTimeAdjust(gdi.getText("TimeAdjust"));
|
||||||
if (pc->getStatus() != oControl::StatusRogaining) {
|
if (pc->getStatus() != oControl::StatusRogaining) {
|
||||||
if (pc->getStatus() != oControl::StatusNoTiming)
|
if (pc->getStatus() != oControl::StatusNoTiming && pc->getStatus() != oControl::StatusBadNoTiming)
|
||||||
pc->setMinTime(gdi.getText("MinTime"));
|
pc->setMinTime(gdi.getText("MinTime"));
|
||||||
pc->setRogainingPoints(0);
|
pc->setRogainingPoints(0);
|
||||||
}
|
}
|
||||||
@ -416,9 +416,9 @@ int TabControl::controlCB(gdioutput &gdi, int type, void *data)
|
|||||||
selectControl(gdi, pc);
|
selectControl(gdi, pc);
|
||||||
}
|
}
|
||||||
else if (bi.id == "Status" ) {
|
else if (bi.id == "Status" ) {
|
||||||
gdi.setInputStatus("MinTime", bi.data != oControl::StatusRogaining && bi.data != oControl::StatusNoTiming, true);
|
gdi.setInputStatus("MinTime", bi.data != oControl::StatusRogaining && bi.data != oControl::StatusNoTiming && bi.data != oControl::StatusBadNoTiming, true);
|
||||||
gdi.setInputStatus("Point", bi.data == oControl::StatusRogaining, true);
|
gdi.setInputStatus("Point", bi.data == oControl::StatusRogaining, true);
|
||||||
gdi.setInputStatus("TimeAdjust", bi.data != oControl::StatusNoTiming, true);
|
gdi.setInputStatus("TimeAdjust", bi.data != oControl::StatusNoTiming && bi.data != oControl::StatusBadNoTiming, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type==GUI_CLEAR) {
|
else if (type==GUI_CLEAR) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -543,7 +543,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
|||||||
if (!htmlTarget.empty()) {
|
if (!htmlTarget.empty()) {
|
||||||
prm.setHTML(htmlTarget, currentList.getParam().timePerPage / 1000);
|
prm.setHTML(htmlTarget, currentList.getParam().timePerPage / 1000);
|
||||||
}
|
}
|
||||||
tabAutoAddMachinge(prm);
|
TabAuto::tabAutoAddMachinge(prm);
|
||||||
dynamic_cast<TabAuto *>(gdi.getTabs().get(TAutoTab))->loadPage(gdi, true);
|
dynamic_cast<TabAuto *>(gdi.getTabs().get(TAutoTab))->loadPage(gdi, true);
|
||||||
}
|
}
|
||||||
else if (bi.id == "WideFormat") {
|
else if (bi.id == "WideFormat") {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
157
code/TabSI.cpp
157
code/TabSI.cpp
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
|
#include <MMSystem.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "oEvent.h"
|
#include "oEvent.h"
|
||||||
@ -134,7 +136,83 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
|||||||
allowControl = gdi.isChecked(bi.id);
|
allowControl = gdi.isChecked(bi.id);
|
||||||
else if (bi.id == "AllowFinish")
|
else if (bi.id == "AllowFinish")
|
||||||
allowFinish = gdi.isChecked(bi.id);
|
allowFinish = gdi.isChecked(bi.id);
|
||||||
if (bi.id == "ClearMemory") {
|
else if (bi.id == "PlaySound") {
|
||||||
|
oe->setProperty("PlaySound", gdi.isChecked(bi.id) ? 1 : 0);
|
||||||
|
}
|
||||||
|
else if (bi.id == "SoundChoice") {
|
||||||
|
gdi.disableInput("SoundChoice");
|
||||||
|
gdi.setRestorePoint("Sound");
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.fillDown();
|
||||||
|
gdi.addString("", fontMediumPlus, "help:selectsound");
|
||||||
|
gdi.dropLine(0.5);
|
||||||
|
gdi.pushX();
|
||||||
|
gdi.fillRight();
|
||||||
|
|
||||||
|
auto addSoundWidget = [&gdi, this](const wchar_t *name, SND type, const wstring &label) {
|
||||||
|
string nname = gdioutput::narrow(name);
|
||||||
|
gdi.addInput(nname, oe->getPropertyString(nname.c_str(), L""), 32, nullptr, label);
|
||||||
|
gdi.dropLine(0.8);
|
||||||
|
gdi.addButton("BrowseSound", "Bläddra...", SportIdentCB).setExtra(name);
|
||||||
|
gdi.addButton("TestSound", "Testa", SportIdentCB).setExtra(int(type));
|
||||||
|
gdi.dropLine(3);
|
||||||
|
gdi.popX();
|
||||||
|
};
|
||||||
|
|
||||||
|
addSoundWidget(L"SoundOK", SND::OK, L"Status OK:");
|
||||||
|
addSoundWidget(L"SoundNotOK", SND::NotOK, L"Status inte OK (röd utgång):");
|
||||||
|
addSoundWidget(L"SoundLeader", SND::Leader, L"Ny ledare i klassen:");
|
||||||
|
addSoundWidget(L"SoundAction", SND::ActionNeeded, L"Åtgärd krävs:");
|
||||||
|
|
||||||
|
gdi.addButton("CloseSound", "OK", SportIdentCB);
|
||||||
|
gdi.popX();
|
||||||
|
gdi.dropLine(3);
|
||||||
|
gdi.scrollToBottom();
|
||||||
|
gdi.refresh();
|
||||||
|
/*
|
||||||
|
fn = oe->getPropertyString("SoundOK", L"");
|
||||||
|
res = 50;
|
||||||
|
break;
|
||||||
|
case SND::NotOK:
|
||||||
|
fn = oe->getPropertyString("SoundNotOK", L"");
|
||||||
|
res = 52;
|
||||||
|
break;
|
||||||
|
case SND::Leader:
|
||||||
|
fn = oe->getPropertyString("SoundLeader", L"");
|
||||||
|
res = 51;
|
||||||
|
break;
|
||||||
|
case SND::ActionNeeded:
|
||||||
|
fn = oe->getPropertyString("SoundAction", L"");
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else if (bi.id == "BrowseSound") {
|
||||||
|
vector< pair<wstring, wstring> > ext;
|
||||||
|
ext.push_back(make_pair(L"Ljud (wav)", L"*.wav"));
|
||||||
|
|
||||||
|
wstring file = gdi.browseForOpen(ext, L"wav");
|
||||||
|
if (!file.empty()) {
|
||||||
|
wchar_t *type = bi.getExtra();
|
||||||
|
string name = gdioutput::narrow(type);
|
||||||
|
gdi.setText(name, file);
|
||||||
|
oe->setProperty(name.c_str(), file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bi.id == "SoundOK" || bi.id == "SoundNotOK" ||
|
||||||
|
bi.id == "SoundLeader" || bi.id == "SoundAction") {
|
||||||
|
oe->setProperty(bi.id.c_str(), bi.text);
|
||||||
|
}
|
||||||
|
else if (bi.id == "TestSound") {
|
||||||
|
oe->setProperty("PlaySound", 1);
|
||||||
|
gdi.check(bi.id, true);
|
||||||
|
playReadoutSound(SND(bi.getExtraInt()));
|
||||||
|
}
|
||||||
|
else if (bi.id == "CloseSound") {
|
||||||
|
gdi.restore("Sound", true);
|
||||||
|
gdi.enableInput("SoundChoice");
|
||||||
|
}
|
||||||
|
else if (bi.id == "ClearMemory") {
|
||||||
if (gdi.ask(L"Do you want to clear the card memory?")) {
|
if (gdi.ask(L"Do you want to clear the card memory?")) {
|
||||||
savedCards.clear();
|
savedCards.clear();
|
||||||
loadPage(gdi);
|
loadPage(gdi);
|
||||||
@ -1678,7 +1756,7 @@ void TabSI::showReadCards(gdioutput &gdi, vector<SICard> &cards)
|
|||||||
SportIdent &TabSI::getSI(const gdioutput &gdi) {
|
SportIdent &TabSI::getSI(const gdioutput &gdi) {
|
||||||
if (!gSI) {
|
if (!gSI) {
|
||||||
HWND hWnd=gdi.getHWNDMain();
|
HWND hWnd=gdi.getHWNDMain();
|
||||||
gSI = new SportIdent(hWnd, 0, gEvent->getPropertyInt("ReadVoltageExp", 0) != 0);
|
gSI = new SportIdent(hWnd, 0, true);
|
||||||
}
|
}
|
||||||
return *gSI;
|
return *gSI;
|
||||||
}
|
}
|
||||||
@ -1787,11 +1865,19 @@ bool TabSI::loadPage(gdioutput &gdi) {
|
|||||||
gdi.selectItemByData("ReadType", mode);
|
gdi.selectItemByData("ReadType", mode);
|
||||||
|
|
||||||
gdi.dropLine(-0.1);
|
gdi.dropLine(-0.1);
|
||||||
gdi.addButton("LockFunction", "Lås funktion...", SportIdentCB);
|
gdi.addButton("LockFunction", "Lås funktion", SportIdentCB);
|
||||||
readoutFunctionX = gdi.getCX();
|
readoutFunctionX = gdi.getCX();
|
||||||
readoutFunctionY = gdi.getCY();
|
readoutFunctionY = gdi.getCY();
|
||||||
gdi.dropLine(0.3);
|
gdi.dropLine(0.3);
|
||||||
|
|
||||||
|
gdi.addCheckbox("PlaySound", "Ljud", SportIdentCB, oe->getPropertyInt("PlaySound", 1) != 0,
|
||||||
|
"Spela upp ett ljud för att indikera resultatet av brickavläsningen.");
|
||||||
|
gdi.dropLine(-0.3);
|
||||||
|
|
||||||
|
gdi.addButton("SoundChoice", "Ljudval...", SportIdentCB);
|
||||||
|
|
||||||
|
gdi.dropLine(0.3);
|
||||||
|
|
||||||
gdi.addString("Allow", 0, "Tillåt:");
|
gdi.addString("Allow", 0, "Tillåt:");
|
||||||
gdi.addCheckbox("AllowStart", "Start", SportIdentCB, allowStart);
|
gdi.addCheckbox("AllowStart", "Start", SportIdentCB, allowStart);
|
||||||
gdi.addCheckbox("AllowControl", "Radio", SportIdentCB, allowControl);
|
gdi.addCheckbox("AllowControl", "Radio", SportIdentCB, allowControl);
|
||||||
@ -1883,6 +1969,8 @@ void TabSI::updateReadoutFunction(gdioutput &gdi) {
|
|||||||
gdi.hideWidget("AllowStart", hide);
|
gdi.hideWidget("AllowStart", hide);
|
||||||
gdi.hideWidget("AllowControl", hide);
|
gdi.hideWidget("AllowControl", hide);
|
||||||
gdi.hideWidget("AllowFinish", hide);
|
gdi.hideWidget("AllowFinish", hide);
|
||||||
|
gdi.hideWidget("SoundChoice", hide);
|
||||||
|
gdi.hideWidget("PlaySound", hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertSICard(gdioutput &gdi, SICard &sic)
|
void InsertSICard(gdioutput &gdi, SICard &sic)
|
||||||
@ -2054,6 +2142,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gEvent->synchronizeList({ oListId::oLCardId, oListId::oLRunnerId });
|
gEvent->synchronizeList({ oListId::oLCardId, oListId::oLRunnerId });
|
||||||
|
|
||||||
if (sic.punchOnly) {
|
if (sic.punchOnly) {
|
||||||
@ -2092,6 +2181,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
else {
|
else {
|
||||||
CardQueue.push_back(sic);
|
CardQueue.push_back(sic);
|
||||||
gdi.addInfoBox("SIREAD", L"info:readout_action#" + gEvent->getCurrentTimeS()+L"#"+itow(sic.CardNumber), 0, SportIdentCB);
|
gdi.addInfoBox("SIREAD", L"info:readout_action#" + gEvent->getCurrentTimeS()+L"#"+itow(sic.CardNumber), 0, SportIdentCB);
|
||||||
|
playReadoutSound(SND::ActionNeeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2099,8 +2189,10 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
if (!readBefore) {
|
if (!readBefore) {
|
||||||
if (r && r->getClassId(false) && !sameCardNewRace)
|
if (r && r->getClassId(false) && !sameCardNewRace)
|
||||||
processCard(gdi, r, sic, true);
|
processCard(gdi, r, sic, true);
|
||||||
else
|
else {
|
||||||
processUnmatched(gdi, sic, true);
|
processUnmatched(gdi, sic, true);
|
||||||
|
playReadoutSound(SND::ActionNeeded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gdi.addInfoBox("SIREAD", L"Brickan redan inläst.", 0, SportIdentCB);
|
gdi.addInfoBox("SIREAD", L"Brickan redan inläst.", 0, SportIdentCB);
|
||||||
@ -2126,6 +2218,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
name = itow(sic.CardNumber) + name;
|
name = itow(sic.CardNumber) + name;
|
||||||
CardQueue.push_back(sic);
|
CardQueue.push_back(sic);
|
||||||
gdi.addInfoBox("SIREAD", L"info:readout_queue#" + gEvent->getCurrentTimeS() + L"#" + name);
|
gdi.addInfoBox("SIREAD", L"info:readout_queue#" + gEvent->getCurrentTimeS() + L"#" + name);
|
||||||
|
playReadoutSound(SND::ActionNeeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2166,6 +2259,7 @@ void TabSI::insertSICardAux(gdioutput &gdi, SICard &sic)
|
|||||||
gdi.scrollToBottom();
|
gdi.scrollToBottom();
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
activeSIC.clear(0);
|
activeSIC.clear(0);
|
||||||
|
playReadoutSound(SND::ActionNeeded);
|
||||||
checkMoreCardsInQueue(gdi);
|
checkMoreCardsInQueue(gdi);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2422,7 +2516,7 @@ bool TabSI::processUnmatched(gdioutput &gdi, const SICard &csic, bool silent)
|
|||||||
gdi.addInfoBox("SIINFO", L"#" + info, 10000);
|
gdi.addInfoBox("SIINFO", L"#" + info, 10000);
|
||||||
}
|
}
|
||||||
gdi.makeEvent("DataUpdate", "sireadout", 0, 0, true);
|
gdi.makeEvent("DataUpdate", "sireadout", 0, 0, true);
|
||||||
|
playReadoutSound(SND::ActionNeeded);
|
||||||
checkMoreCardsInQueue(gdi);
|
checkMoreCardsInQueue(gdi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2619,6 +2713,11 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
runner->getTeam()->getLegPlaceS(runner->getLegNumber(), false) :
|
runner->getTeam()->getLegPlaceS(runner->getLegNumber(), false) :
|
||||||
runner->getPlaceS();
|
runner->getPlaceS();
|
||||||
|
|
||||||
|
if (placeS == L"1")
|
||||||
|
playReadoutSound(SND::Leader);
|
||||||
|
else
|
||||||
|
playReadoutSound(SND::OK);
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
//gdi.dropLine();
|
//gdi.dropLine();
|
||||||
@ -2651,6 +2750,8 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
|||||||
else {
|
else {
|
||||||
wstring msg=lang.tl(L"Status: ") + runner->getStatusS(true, true);
|
wstring msg=lang.tl(L"Status: ") + runner->getStatusS(true, true);
|
||||||
|
|
||||||
|
playReadoutSound(SND::NotOK);
|
||||||
|
|
||||||
if (!MP.empty()) {
|
if (!MP.empty()) {
|
||||||
msg=msg + L", (";
|
msg=msg + L", (";
|
||||||
vector<int>::iterator it;
|
vector<int>::iterator it;
|
||||||
@ -4258,7 +4359,49 @@ void TabSI::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) {
|
|||||||
gdi.TabFocus(1);
|
gdi.TabFocus(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TabSI::showDatabase() const {
|
bool TabSI::showDatabase() const {
|
||||||
return useDatabase && oe->useRunnerDb();
|
return useDatabase && oe->useRunnerDb();
|
||||||
}
|
}
|
||||||
|
void TabSI::playReadoutSound(SND type) {
|
||||||
|
if (!oe->getPropertyInt("PlaySound", 0))
|
||||||
|
return;
|
||||||
|
int res = -1;
|
||||||
|
wstring fn;
|
||||||
|
switch (type) {
|
||||||
|
case SND::OK:
|
||||||
|
fn = oe->getPropertyString("SoundOK", L"");
|
||||||
|
res = 50;
|
||||||
|
break;
|
||||||
|
case SND::NotOK:
|
||||||
|
fn = oe->getPropertyString("SoundNotOK", L"");
|
||||||
|
res = 52;
|
||||||
|
break;
|
||||||
|
case SND::Leader:
|
||||||
|
fn = oe->getPropertyString("SoundLeader", L"");
|
||||||
|
res = 51;
|
||||||
|
break;
|
||||||
|
case SND::ActionNeeded:
|
||||||
|
fn = oe->getPropertyString("SoundAction", L"");
|
||||||
|
res = 53;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkedSound.count(fn) || (!fn.empty() && fileExists(fn))) {
|
||||||
|
playSoundFile(fn);
|
||||||
|
checkedSound.insert(fn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playSoundResource(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabSI::playSoundResource(int res) const {
|
||||||
|
PlaySound(MAKEINTRESOURCE(res), GetModuleHandle(nullptr), SND_RESOURCE| SND_ASYNC);
|
||||||
|
//OutputDebugString((L"Play: " + itow(res)).c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabSI::playSoundFile(const wstring& file) const {
|
||||||
|
PlaySound(file.c_str(), nullptr, SND_FILENAME | SND_ASYNC);
|
||||||
|
//OutputDebugString(file.c_str());
|
||||||
|
}
|
||||||
|
|||||||
15
code/TabSI.h
15
code/TabSI.h
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -68,6 +68,17 @@ private:
|
|||||||
list< pair<unsigned, int> > printPunchRunnerIdQueue;
|
list< pair<unsigned, int> > printPunchRunnerIdQueue;
|
||||||
void addToPrintQueue(pRunner r);
|
void addToPrintQueue(pRunner r);
|
||||||
|
|
||||||
|
enum class SND {
|
||||||
|
OK,
|
||||||
|
Leader,
|
||||||
|
NotOK,
|
||||||
|
ActionNeeded
|
||||||
|
};
|
||||||
|
|
||||||
|
set<wstring> checkedSound;
|
||||||
|
|
||||||
|
void playReadoutSound(SND type);
|
||||||
|
|
||||||
vector<PunchInfo> punches;
|
vector<PunchInfo> punches;
|
||||||
vector<SICard> cards;
|
vector<SICard> cards;
|
||||||
vector<wstring> filterDate;
|
vector<wstring> filterDate;
|
||||||
@ -206,6 +217,8 @@ private:
|
|||||||
int readoutFunctionX = 0;
|
int readoutFunctionX = 0;
|
||||||
int readoutFunctionY = 0;
|
int readoutFunctionY = 0;
|
||||||
|
|
||||||
|
void playSoundResource(int res) const;
|
||||||
|
void playSoundFile(const wstring& file) const;
|
||||||
protected:
|
protected:
|
||||||
void clearCompetitionData();
|
void clearCompetitionData();
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -1102,7 +1102,7 @@ bool TabSpeaker::loadPage(gdioutput &gdi) {
|
|||||||
|
|
||||||
if (getExtraWindows().size() == 1) {
|
if (getExtraWindows().size() == 1) {
|
||||||
wstring sf = getSpeakerSettingsFile();
|
wstring sf = getSpeakerSettingsFile();
|
||||||
if (fileExist(sf.c_str())) {
|
if (fileExists(sf)) {
|
||||||
if ((cx + db) > basex && (cx + db + bw) >= limitX) {
|
if ((cx + db) > basex && (cx + db + bw) >= limitX) {
|
||||||
cx = basex; db = 0;
|
cx = basex; db = 0;
|
||||||
cy += gdi.getButtonHeight() + 4;
|
cy += gdi.getButtonHeight() + 4;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -1908,13 +1908,17 @@ void TabTeam::processChangeRunner(gdioutput &gdi, pTeam t, int leg, pRunner r) {
|
|||||||
void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
|
void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
|
||||||
vector<int> mp;
|
vector<int> mp;
|
||||||
bool removeAnnonumousTeamMember = false;
|
bool removeAnnonumousTeamMember = false;
|
||||||
|
int crsIdR = r->getCourseId();
|
||||||
|
int crsIdROld = oldR ? oldR->getCourseId() : 0;
|
||||||
|
|
||||||
if (r->getTeam()) {
|
if (r->getTeam()) {
|
||||||
pTeam otherTeam = r->getTeam();
|
pTeam otherTeam = r->getTeam();
|
||||||
int otherLeg = r->getLegNumber();
|
int otherLeg = r->getLegNumber();
|
||||||
otherTeam->setRunner(otherLeg, oldR, true);
|
otherTeam->setRunner(otherLeg, oldR, true);
|
||||||
if (oldR)
|
if (oldR) {
|
||||||
|
oldR->setCourseId(crsIdR);
|
||||||
oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
||||||
|
}
|
||||||
otherTeam->checkValdParSetup();
|
otherTeam->checkValdParSetup();
|
||||||
otherTeam->apply(oBase::ChangeType::Update, nullptr);
|
otherTeam->apply(oBase::ChangeType::Update, nullptr);
|
||||||
otherTeam->synchronize(true);
|
otherTeam->synchronize(true);
|
||||||
@ -1927,11 +1931,13 @@ void TabTeam::switchRunners(pTeam t, int leg, pRunner r, pRunner oldR) {
|
|||||||
else
|
else
|
||||||
oldR->setClassId(r->getClassId(false), true);
|
oldR->setClassId(r->getClassId(false), true);
|
||||||
removeAnnonumousTeamMember = oldR->isAnnonumousTeamMember();
|
removeAnnonumousTeamMember = oldR->isAnnonumousTeamMember();
|
||||||
|
oldR->setCourseId(crsIdR);
|
||||||
oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
oldR->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
||||||
oldR->synchronize(true);
|
oldR->synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->setRunner(leg, r, true);
|
t->setRunner(leg, r, true);
|
||||||
|
r->setCourseId(crsIdROld);
|
||||||
r->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
r->evaluateCard(true, mp, 0, oBase::ChangeType::Update);
|
||||||
t->checkValdParSetup();
|
t->checkValdParSetup();
|
||||||
t->apply(oBase::ChangeType::Update, nullptr);
|
t->apply(oBase::ChangeType::Update, nullptr);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
520
code/Table.cpp
520
code/Table.cpp
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -90,10 +90,8 @@ Table::~Table(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Table::clearCellSelection(gdioutput *gdi) {
|
void Table::clearCellSelection(gdioutput *gdi) {
|
||||||
upperRow = -1;
|
sel.reset();
|
||||||
lowerRow = -1;
|
selScreen.reset();
|
||||||
upperCol = -1;
|
|
||||||
lowerCol = -1;
|
|
||||||
if (gdi) {
|
if (gdi) {
|
||||||
HDC hDC = GetDC(gdi->getHWNDTarget());
|
HDC hDC = GetDC(gdi->getHWNDTarget());
|
||||||
clearSelectionBitmap(gdi, hDC);
|
clearSelectionBitmap(gdi, hDC);
|
||||||
@ -183,6 +181,7 @@ void Table::addRow(int rowId, oBase *object)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataRowToIndex.clear();
|
||||||
TableRow tr(nTitles, object);
|
TableRow tr(nTitles, object);
|
||||||
tr.height=rowHeight;
|
tr.height=rowHeight;
|
||||||
tr.id = rowId;
|
tr.id = rowId;
|
||||||
@ -244,7 +243,9 @@ void Table::filter(int col, const wstring &filt, bool forceFilter)
|
|||||||
|
|
||||||
if (filt==oldFilter && (!forceFilter || filt.empty()))
|
if (filt==oldFilter && (!forceFilter || filt.empty()))
|
||||||
return;
|
return;
|
||||||
else if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) {
|
dataRowToIndex.clear();
|
||||||
|
|
||||||
|
if (wcsncmp(oldFilter.c_str(), filt.c_str(), oldFilter.length())==0) {
|
||||||
if (sortIndex.empty())
|
if (sortIndex.empty())
|
||||||
return;
|
return;
|
||||||
//Filter more...
|
//Filter more...
|
||||||
@ -252,6 +253,7 @@ void Table::filter(int col, const wstring &filt, bool forceFilter)
|
|||||||
baseIndex[0]=sortIndex[0];
|
baseIndex[0]=sortIndex[0];
|
||||||
baseIndex[1]=sortIndex[1];
|
baseIndex[1]=sortIndex[1];
|
||||||
swap(baseIndex, sortIndex);
|
swap(baseIndex, sortIndex);
|
||||||
|
sortIndex.reserve(baseIndex.size());
|
||||||
Titles[col].filter=filt;
|
Titles[col].filter=filt;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -293,16 +295,20 @@ bool Table::compareRow(int indexA, int indexB) const {
|
|||||||
//return Data[indexA].key < Data[indexB].key;
|
//return Data[indexA].key < Data[indexB].key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::sort(int col)
|
void Table::sort(int col, bool forceDirection)
|
||||||
{
|
{
|
||||||
|
int origCol = col;
|
||||||
bool reverse = col < 0;
|
bool reverse = col < 0;
|
||||||
if (col < 0)
|
if (col < 0)
|
||||||
col = -(10+col);
|
col = -(10+col);
|
||||||
|
|
||||||
if (sortIndex.size()<2)
|
if (sortIndex.size()<2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
dataRowToIndex.clear();
|
||||||
|
|
||||||
currentSortColumn=col;
|
currentSortColumn=col;
|
||||||
if (PrevSort!=col && PrevSort!=-(10+col)) {
|
if (forceDirection || (PrevSort!=col && PrevSort!=-(10+col))) {
|
||||||
if (Titles[col].isnumeric) {
|
if (Titles[col].isnumeric) {
|
||||||
bool hasDeci = false;
|
bool hasDeci = false;
|
||||||
for(size_t k=2; k<sortIndex.size(); k++){
|
for(size_t k=2; k<sortIndex.size(); k++){
|
||||||
@ -420,7 +426,7 @@ void Table::sort(int col)
|
|||||||
//DWORD sEnd = GetTickCount();
|
//DWORD sEnd = GetTickCount();
|
||||||
//string st = itos(sEnd-sStart);
|
//string st = itos(sEnd-sStart);
|
||||||
TableSortIndex::table = 0;
|
TableSortIndex::table = 0;
|
||||||
PrevSort=col;
|
PrevSort = origCol;
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
std::reverse(sortIndex.begin()+2, sortIndex.end());
|
std::reverse(sortIndex.begin()+2, sortIndex.end());
|
||||||
@ -434,7 +440,7 @@ void Table::sort(int col)
|
|||||||
PrevSort=col;
|
PrevSort=col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
int TablesCB(gdioutput *gdi, int type, void *data) {
|
int TablesCB(gdioutput *gdi, int type, void *data) {
|
||||||
if (type!=GUI_LINK || gdi->Tables.empty())
|
if (type!=GUI_LINK || gdi->Tables.empty())
|
||||||
return 0;
|
return 0;
|
||||||
@ -451,7 +457,7 @@ int TablesCB(gdioutput *gdi, int type, void *data) {
|
|||||||
|
|
||||||
gdi->refresh();
|
gdi->refresh();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void Table::getDimension(gdioutput &gdi, int &dx, int &dy, bool filteredResult) const
|
void Table::getDimension(gdioutput &gdi, int &dx, int &dy, bool filteredResult) const
|
||||||
{
|
{
|
||||||
@ -507,7 +513,7 @@ void Table::restoreCell(HDC hDC, const TableCell &cell)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int dy)
|
void Table::moveCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, int dx, int dy)
|
||||||
{
|
{
|
||||||
RECT rc=cell.absPos;
|
RECT rc=cell.absPos;
|
||||||
rc.left+=dx; rc.right+=dx;
|
rc.left+=dx; rc.right+=dx;
|
||||||
@ -526,7 +532,7 @@ void Table::moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int
|
|||||||
dx=0;
|
dx=0;
|
||||||
dy=0;
|
dy=0;
|
||||||
}
|
}
|
||||||
highlightCell(hDC, gdi, cell, RGB(255, 0,0), dx, dy);
|
highlightCell(hDC, gdi, col, cell, RGB(255, 0,0), dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy)
|
void Table::stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy)
|
||||||
@ -554,94 +560,94 @@ void Table::stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy)
|
|||||||
|
|
||||||
bool Table::mouseMove(gdioutput &gdi, int x, int y)
|
bool Table::mouseMove(gdioutput &gdi, int x, int y)
|
||||||
{
|
{
|
||||||
int row=getRow(y);
|
int row = getRow(y);
|
||||||
int col=-1;
|
int col = -1;
|
||||||
|
|
||||||
if (row!=-1)
|
if (row != -1)
|
||||||
col=getColumn(x);
|
col = getColumn(x);
|
||||||
|
|
||||||
HWND hWnd=gdi.getHWNDTarget();
|
HWND hWnd = gdi.getHWNDTarget();
|
||||||
|
|
||||||
if (colSelected!=-1) {
|
if (colSelected != -1) {
|
||||||
TableCell &cell=Data[0].cells[colSelected];
|
TableCell &cell = Data[0].cells[colSelected];
|
||||||
HDC hDC=GetDC(hWnd);
|
HDC hDC = GetDC(hWnd);
|
||||||
|
|
||||||
restoreCell(hDC, cell);
|
restoreCell(hDC, cell);
|
||||||
|
|
||||||
if (col!=highCol) {
|
if (col != highCol) {
|
||||||
if (unsigned(highRow)<Data.size() && unsigned(highCol)<nTitles)
|
if (unsigned(highRow) < Data.size() && unsigned(highCol) < nTitles)
|
||||||
redrawCell(gdi, hDC, highCol, highRow);
|
redrawCell(gdi, hDC, highCol, highRow);
|
||||||
|
|
||||||
DWORD c=RGB(240, 200, 140);
|
DWORD c = RGB(240, 220, 180);
|
||||||
if (unsigned(col)<nTitles)
|
if (unsigned(col) < nTitles)
|
||||||
highlightCell(hDC, gdi, Data[0].cells[col], c, 0,0);
|
highlightCell(hDC, gdi, col, Data[0].cells[col], c, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//highlightCell(hDC, cell, RGB(255,0,0), x-startX, y-startY);
|
//highlightCell(hDC, cell, RGB(255,0,0), x-startX, y-startY);
|
||||||
moveCell(hDC, gdi, cell, x-startX, y-startY);
|
moveCell(hDC, gdi, colSelected, cell, x - startX, y - startY);
|
||||||
ReleaseDC(hWnd, hDC);
|
ReleaseDC(hWnd, hDC);
|
||||||
highRow=0;
|
highRow = 0;
|
||||||
highCol=col;
|
highCol = col;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
GetClientRect(hWnd, &rc);
|
GetClientRect(hWnd, &rc);
|
||||||
|
|
||||||
if (x<=rc.left || x>=rc.right || y<rc.top || y>rc.bottom)
|
if (x <= rc.left || x >= rc.right || y<rc.top || y>rc.bottom)
|
||||||
row=-1;
|
row = -1;
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (startSelect) {
|
if (startSelect) {
|
||||||
int c = getColumn(x, true);
|
int c = getColumn(x, true);
|
||||||
if (c != -1)
|
if (c != -1)
|
||||||
upperCol = c;
|
sel.upperCol = c, selScreen.upperCol = -1;
|
||||||
c = getRow(y, true);
|
c = getRow(y, true);
|
||||||
if (c != -1 && c>=0) {
|
if (c != -1 && c >= 0) {
|
||||||
upperRow = max<int>(c, 2);
|
sel.upperRow = max<int>(c, 2), selScreen.upperRow = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HDC hDC=GetDC(hWnd);
|
HDC hDC = GetDC(hWnd);
|
||||||
if (unsigned(highRow)<Data.size() && unsigned(highCol)<Titles.size())
|
if (unsigned(highRow) < Data.size() && unsigned(highCol) < Titles.size())
|
||||||
redrawCell(gdi, hDC, highCol, highRow);
|
redrawCell(gdi, hDC, highCol, highRow);
|
||||||
highRow = -1;
|
highRow = -1;
|
||||||
drawSelection(gdi, hDC, false);
|
drawSelection(gdi, hDC, false);
|
||||||
ReleaseDC(hWnd, hDC);
|
ReleaseDC(hWnd, hDC);
|
||||||
scrollToCell(gdi, upperRow, upperCol);
|
scrollToCell(gdi, sel.upperRow, sel.upperCol);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (row>=0 && col>=0) {
|
else if (row >= 0 && col >= 0) {
|
||||||
POINT pt = {x, y};
|
POINT pt = { x, y };
|
||||||
ClientToScreen(hWnd, &pt);
|
ClientToScreen(hWnd, &pt);
|
||||||
HWND hUnder = WindowFromPoint(pt);
|
HWND hUnder = WindowFromPoint(pt);
|
||||||
|
|
||||||
if (hUnder == hWnd) {
|
if (hUnder == hWnd) {
|
||||||
//int index=sortIndex[row].index;
|
//int index=sortIndex[row].index;
|
||||||
TableRow &trow=Data[row];
|
TableRow &trow = Data[row];
|
||||||
TableCell &cell=trow.cells[col];
|
TableCell &cell = trow.cells[col];
|
||||||
|
|
||||||
if (highRow!=row || highCol!=col) {
|
if (highRow != row || highCol != col) {
|
||||||
|
|
||||||
HDC hDC=GetDC(hWnd);
|
HDC hDC = GetDC(hWnd);
|
||||||
|
|
||||||
if (unsigned(highRow)<Data.size() && unsigned(highCol)<Titles.size())
|
if (unsigned(highRow) < Data.size() && unsigned(highCol) < Titles.size())
|
||||||
redrawCell(gdi, hDC, highCol, highRow);
|
redrawCell(gdi, hDC, highCol, highRow);
|
||||||
|
|
||||||
if (row >= 2) {
|
if (row >= 2) {
|
||||||
DWORD c;
|
DWORD c;
|
||||||
if (cell.canEdit)
|
if (cell.canEdit)
|
||||||
c=RGB(240, 240, 150);
|
c = RGB(240, 240, 150);
|
||||||
else
|
else
|
||||||
c=RGB(240, 200, 140);
|
c = RGB(240, 200, 140);
|
||||||
|
|
||||||
highlightCell(hDC, gdi, cell, c, 0,0);
|
highlightCell(hDC, gdi, col, cell, c, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseDC(hWnd, hDC);
|
ReleaseDC(hWnd, hDC);
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
highCol=col;
|
highCol = col;
|
||||||
highRow=row;
|
highRow = row;
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
@ -650,33 +656,33 @@ bool Table::mouseMove(gdioutput &gdi, int x, int y)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (unsigned(highRow)<Data.size() && unsigned(highCol)<Titles.size()) {
|
if (unsigned(highRow) < Data.size() && unsigned(highCol) < Titles.size()) {
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
HDC hDC=GetDC(hWnd);
|
HDC hDC = GetDC(hWnd);
|
||||||
redrawCell(gdi, hDC, highCol, highRow);
|
redrawCell(gdi, hDC, highCol, highRow);
|
||||||
ReleaseDC(hWnd, hDC);
|
ReleaseDC(hWnd, hDC);
|
||||||
highRow=-1;
|
highRow = -1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Table::mouseLeftUp(gdioutput &gdi, int x, int y)
|
bool Table::mouseLeftUp(gdioutput &gdi, int x, int y)
|
||||||
{
|
{
|
||||||
if (colSelected!=-1) {
|
if (colSelected != -1) {
|
||||||
|
|
||||||
if (hdcCompatible) {
|
if (hdcCompatible) {
|
||||||
TableCell &cell=Data[0].cells[colSelected];
|
TableCell &cell = Data[0].cells[colSelected];
|
||||||
HWND hWnd=gdi.getHWNDTarget();
|
HWND hWnd = gdi.getHWNDTarget();
|
||||||
HDC hDC=GetDC(hWnd);
|
HDC hDC = GetDC(hWnd);
|
||||||
stopMoveCell(hDC, cell, x-startX, y-startY);
|
stopMoveCell(hDC, cell, x - startX, y - startY);
|
||||||
ReleaseDC(hWnd, hDC);
|
ReleaseDC(hWnd, hDC);
|
||||||
//return true;
|
//return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highRow==0 && colSelected==highCol) {
|
if (highRow == 0 && colSelected == highCol) {
|
||||||
colSelected=-1;
|
colSelected = -1;
|
||||||
gdi.setWaitCursor(true);
|
gdi.setWaitCursor(true);
|
||||||
sort(highCol);
|
sort(highCol, false);
|
||||||
gdi.setWaitCursor(false);
|
gdi.setWaitCursor(false);
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
mouseMove(gdi, x, y);
|
mouseMove(gdi, x, y);
|
||||||
@ -685,22 +691,22 @@ bool Table::mouseLeftUp(gdioutput &gdi, int x, int y)
|
|||||||
else {
|
else {
|
||||||
moveColumn(colSelected, highCol);
|
moveColumn(colSelected, highCol);
|
||||||
InvalidateRect(gdi.getHWNDTarget(), 0, false);
|
InvalidateRect(gdi.getHWNDTarget(), 0, false);
|
||||||
colSelected=-1;
|
colSelected = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
upperCol = getColumn(x);
|
sel.upperCol = getColumn(x), selScreen.upperCol = -1;
|
||||||
upperRow = getRow(y);
|
sel.upperRow = getRow(y), selScreen.upperRow = -1;
|
||||||
startSelect = false;
|
startSelect = false;
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
gdi.refreshFast();
|
||||||
}
|
}
|
||||||
colSelected=-1;
|
colSelected = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tblSelectionCB(gdioutput *gdi, int type, void *data)
|
int tblSelectionCB(gdioutput *gdi, int type, void *data) {
|
||||||
{
|
|
||||||
if (type == GUI_LISTBOX) {
|
if (type == GUI_LISTBOX) {
|
||||||
ListBoxInfo lbi = *static_cast<ListBoxInfo *>(data);
|
ListBoxInfo lbi = *static_cast<ListBoxInfo *>(data);
|
||||||
Table &t = gdi->getTable();
|
Table &t = gdi->getTable();
|
||||||
@ -744,9 +750,18 @@ bool Table::keyCommand(gdioutput &gdi, KeyCommandCode code) {
|
|||||||
exportClipboard(gdi);
|
exportClipboard(gdi);
|
||||||
else if (code == KC_PASTE && hEdit == 0) {
|
else if (code == KC_PASTE && hEdit == 0) {
|
||||||
importClipboard(gdi);
|
importClipboard(gdi);
|
||||||
}else if (code == KC_DELETE && hEdit == 0) {
|
}
|
||||||
|
else if (code == KC_DELETE && hEdit == 0) {
|
||||||
deleteSelection(gdi);
|
deleteSelection(gdi);
|
||||||
}
|
}
|
||||||
|
else if (code == KC_MARKALL && hEdit == 0) {
|
||||||
|
markAll(true);
|
||||||
|
gdi.refresh();
|
||||||
|
}
|
||||||
|
else if (code == KC_CLEARALL && hEdit == 0) {
|
||||||
|
markAll(false);
|
||||||
|
gdi.refresh();
|
||||||
|
}
|
||||||
else if (code == KC_REFRESH) {
|
else if (code == KC_REFRESH) {
|
||||||
gdi.setWaitCursor(true);
|
gdi.setWaitCursor(true);
|
||||||
update();
|
update();
|
||||||
@ -858,14 +873,11 @@ bool Table::mouseLeftDown(gdioutput &gdi, int x, int y) {
|
|||||||
colSelected=highCol;
|
colSelected=highCol;
|
||||||
startX=x;
|
startX=x;
|
||||||
startY=y;
|
startY=y;
|
||||||
//sort(highCol);
|
|
||||||
//gdi.refresh();
|
|
||||||
//mouseMove(gdi, x, y);
|
|
||||||
}
|
}
|
||||||
else if (highRow==1) {
|
else if (highRow==1) {
|
||||||
//filter(highCol, "lots");
|
showFilter(gdi);
|
||||||
|
/*
|
||||||
RECT rc=Data[1].cells[columns[0]].absPos;
|
RECT rc=Data[1].cells[columns[0]].absPos;
|
||||||
//rc.right=rc.left+tableWidth;
|
|
||||||
editRow=highRow;
|
editRow=highRow;
|
||||||
editCol=highCol;
|
editCol=highCol;
|
||||||
|
|
||||||
@ -877,18 +889,158 @@ bool Table::mouseLeftDown(gdioutput &gdi, int x, int y) {
|
|||||||
SendMessage(hEdit, EM_SETSEL, 0, -1);
|
SendMessage(hEdit, EM_SETSEL, 0, -1);
|
||||||
SetFocus(hEdit);
|
SetFocus(hEdit);
|
||||||
SendMessage(hEdit, WM_SETFONT, (WPARAM) gdi.getGUIFont(), 0);
|
SendMessage(hEdit, WM_SETFONT, (WPARAM) gdi.getGUIFont(), 0);
|
||||||
gdi.refresh();
|
gdi.refresh();*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetFocus(gdi.getHWNDTarget());
|
SetFocus(gdi.getHWNDTarget());
|
||||||
SetCapture(gdi.getHWNDTarget());
|
SetCapture(gdi.getHWNDTarget());
|
||||||
lowerCol = getColumn(x);
|
sel.lowerCol = getColumn(x), selScreen.lowerCol = -1;
|
||||||
lowerRow = getRow(y);
|
sel.lowerRow = getRow(y), selScreen.lowerRow = -1;
|
||||||
startSelect = true;
|
startSelect = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Table::showFilter(gdioutput &gdi) {
|
||||||
|
RECT rc = Data[1].cells[columns[0]].absPos;
|
||||||
|
editRow = 1;
|
||||||
|
editCol = highCol;
|
||||||
|
|
||||||
|
hEdit = CreateWindowEx(0, L"EDIT", Titles[highCol].filter.c_str(),
|
||||||
|
WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | WS_BORDER,
|
||||||
|
rc.left + 105, rc.top, tableWidth - 105, (rc.bottom - rc.top - 1), gdi.getHWNDTarget(),
|
||||||
|
0, hInst, 0);
|
||||||
|
drawFilterLabel = true;
|
||||||
|
SendMessage(hEdit, EM_SETSEL, 0, -1);
|
||||||
|
SetFocus(hEdit);
|
||||||
|
SendMessage(hEdit, WM_SETFONT, (WPARAM)gdi.getGUIFont(), 0);
|
||||||
|
gdi.refresh();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Table::mouseRightDown(gdioutput &gdi, int x, int y) {
|
||||||
|
//partialCell = true;
|
||||||
|
//clearCellSelection(&gdi);
|
||||||
|
|
||||||
|
if (!destroyEditControl(gdi))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (highRow == 0) {
|
||||||
|
colSelected = highCol;
|
||||||
|
}
|
||||||
|
// lowerCol = getColumn(x);
|
||||||
|
// lowerRow = getRow(y);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Table::mouseRightUp(gdioutput &gdi, int x, int y) {
|
||||||
|
|
||||||
|
if (highRow == 0 && colSelected == highCol) {
|
||||||
|
colSelected = -1;
|
||||||
|
|
||||||
|
vector<pair<wstring, int>> menu;
|
||||||
|
menu.emplace_back(L"Sortera stigande", 1);
|
||||||
|
menu.emplace_back(L"Sortera fallande", 2);
|
||||||
|
menu.emplace_back(L"", 0);
|
||||||
|
menu.emplace_back(L"Markera kolumn", 3);
|
||||||
|
menu.emplace_back(L"Filtrera", 5);
|
||||||
|
menu.emplace_back(L"Dölj", 4);
|
||||||
|
|
||||||
|
int res = gdi.popupMenu(x, y, menu);
|
||||||
|
|
||||||
|
switch (res) {
|
||||||
|
case 2: {
|
||||||
|
sort(-(highCol+10), true);
|
||||||
|
gdi.refresh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
sort(highCol, true);
|
||||||
|
gdi.refresh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
int col = highCol;
|
||||||
|
if (isFullColumnSelected()) {
|
||||||
|
sel.upperCol = max({ sel.upperCol, sel.lowerCol, col });
|
||||||
|
sel.lowerCol = min({ sel.upperCol, sel.lowerCol, col });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sel.upperCol = sel.lowerCol = col;
|
||||||
|
}
|
||||||
|
if (sortIndex.size() > 2) {
|
||||||
|
sel.upperRow = sortIndex[2].index;
|
||||||
|
sel.lowerRow = sortIndex[sortIndex.size()-1].index;
|
||||||
|
}
|
||||||
|
selScreen.reset();
|
||||||
|
gdi.refresh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
columns.erase(find(columns.begin(), columns.end(), highCol));
|
||||||
|
doAutoSelectColumns = false;
|
||||||
|
gdi.refresh();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
showFilter(gdi);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*POINT pt;
|
||||||
|
pt.x = x;
|
||||||
|
pt.y = y;
|
||||||
|
ClientToScreen(gdi.getHWNDTarget(), &pt);
|
||||||
|
|
||||||
|
HMENU hm = CreatePopupMenu();
|
||||||
|
AppendMenu(hm, MF_STRING, 1, lang.tl("Sortera stigande").c_str());
|
||||||
|
AppendMenu(hm, MF_STRING, 2, L"Select");
|
||||||
|
int res = TrackPopupMenuEx(hm, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY,
|
||||||
|
pt.x, pt.y, gdi.getHWNDTarget(), nullptr);
|
||||||
|
|
||||||
|
DestroyMenu(hm);*/
|
||||||
|
}
|
||||||
|
// lowerCol = getColumn(x);
|
||||||
|
// lowerRow = getRow(y);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Table::isFullColumnSelected() const {
|
||||||
|
if (sortIndex.size() < 2)
|
||||||
|
return false;
|
||||||
|
return (sel.upperRow == sortIndex[2].index &&
|
||||||
|
sel.lowerRow == sortIndex[sortIndex.size() - 1].index) ||
|
||||||
|
(sel.lowerRow == sortIndex[2].index &&
|
||||||
|
sel.upperRow == sortIndex[sortIndex.size() - 1].index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Table::markAll(bool doSelect) {
|
||||||
|
if (doSelect) {
|
||||||
|
sel.lowerCol = columns.front();
|
||||||
|
sel.upperCol = columns.back();
|
||||||
|
if (sortIndex.size() > 2) {
|
||||||
|
sel.upperRow = sortIndex[2].index;
|
||||||
|
sel.lowerRow = sortIndex.back().index;
|
||||||
|
}
|
||||||
|
selScreen.reset();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sel.reset();
|
||||||
|
selScreen.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Table::mouseMidDown(gdioutput &gdi, int x, int y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Table::mouseMidUp(gdioutput &gdi, int x, int y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Table::mouseLeftDblClick(gdioutput &gdi, int x, int y)
|
bool Table::mouseLeftDblClick(gdioutput &gdi, int x, int y)
|
||||||
{
|
{
|
||||||
clearCellSelection(&gdi);
|
clearCellSelection(&gdi);
|
||||||
@ -1061,21 +1213,21 @@ void drawSymbol(gdioutput &gdi, HDC hDC, int height,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Table::highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD color, int dx, int dy)
|
void Table::highlightCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, DWORD color, int dx, int dy)
|
||||||
{
|
{
|
||||||
SelectObject(hDC, GetStockObject(DC_BRUSH));
|
SelectObject(hDC, GetStockObject(DC_BRUSH));
|
||||||
SelectObject(hDC, GetStockObject(NULL_PEN));
|
SelectObject(hDC, GetStockObject(NULL_PEN));
|
||||||
|
|
||||||
SetDCBrushColor(hDC, color);
|
SetDCBrushColor(hDC, color);
|
||||||
|
|
||||||
RECT rc=cell.absPos;
|
RECT rc = cell.absPos;
|
||||||
rc.left+=dx;
|
rc.left += dx;
|
||||||
rc.right+=dx;
|
rc.right += dx - 1;
|
||||||
rc.top+=dy;
|
rc.top += dy;
|
||||||
rc.bottom+=dy;
|
rc.bottom += dy;
|
||||||
|
|
||||||
Rectangle(hDC, rc.left+1, rc.top,
|
Rectangle(hDC, rc.left + 2, rc.top+2,
|
||||||
rc.right+2, rc.bottom);
|
rc.right + 1, rc.bottom-1);
|
||||||
|
|
||||||
TextInfo ti;
|
TextInfo ti;
|
||||||
|
|
||||||
@ -1090,9 +1242,13 @@ void Table::highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD
|
|||||||
else {
|
else {
|
||||||
gdi.formatString(ti, hDC);
|
gdi.formatString(ti, hDC);
|
||||||
SetBkMode(hDC, TRANSPARENT);
|
SetBkMode(hDC, TRANSPARENT);
|
||||||
rc.left+=4;
|
rc.left += 4;
|
||||||
rc.top+=2;
|
rc.top += 2;
|
||||||
DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_LEFT|DT_NOPREFIX);
|
rc.right -= 2;
|
||||||
|
if (Titles[col].formatRight)
|
||||||
|
DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_RIGHT | DT_NOPREFIX);
|
||||||
|
else
|
||||||
|
DrawText(hDC, cell.contents.c_str(), -1, &rc, DT_LEFT | DT_NOPREFIX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,7 +1262,7 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
table_yp=dy-gdi.OffsetY;
|
table_yp=dy-gdi.OffsetY;
|
||||||
|
|
||||||
if (currentSortColumn==-1)
|
if (currentSortColumn==-1)
|
||||||
sort(0);
|
sort(0, false);
|
||||||
|
|
||||||
int wi, he;
|
int wi, he;
|
||||||
getDimension(gdi, wi, he, true);
|
getDimension(gdi, wi, he, true);
|
||||||
@ -1129,7 +1285,7 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
xpos[0]=dx-gdi.OffsetX;
|
xpos[0]=dx-gdi.OffsetX;
|
||||||
for (size_t i=1;i<=columns.size();i++)
|
for (size_t i=1;i<=columns.size();i++)
|
||||||
xpos[i]=xpos[i-1]+Titles[columns[i-1]].width+1;
|
xpos[i]=xpos[i-1]+Titles[columns[i-1]].width+1;
|
||||||
|
//xxx
|
||||||
//Find first and last visible column
|
//Find first and last visible column
|
||||||
while(firstCol<int(columns.size()) && xpos[firstCol+1]<=screen.left)
|
while(firstCol<int(columns.size()) && xpos[firstCol+1]<=screen.left)
|
||||||
firstCol++;
|
firstCol++;
|
||||||
@ -1219,21 +1375,29 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
rc.right=rc.left+Titles[index].width;
|
rc.right=rc.left+Titles[index].width;
|
||||||
rc.top=yp+1-gdi.OffsetY;
|
rc.top=yp+1-gdi.OffsetY;
|
||||||
rc.bottom=rc.top+rowHeight;
|
rc.bottom=rc.top+rowHeight;
|
||||||
SetDCBrushColor(hDC, RGB(200,200,200));
|
|
||||||
|
bool sortOn = index == PrevSort || PrevSort == -(10 + index);
|
||||||
|
|
||||||
|
SetDCBrushColor(hDC, sortOn ? RGB(207, 218, 203) : RGB(200,200,200));
|
||||||
Rectangle(hDC, rc.left, rc.top-1, rc.right+2, rc.bottom);
|
Rectangle(hDC, rc.left, rc.top-1, rc.right+2, rc.bottom);
|
||||||
|
|
||||||
if (index == PrevSort || PrevSort == -(10+index) ) {
|
if (sortOn) {
|
||||||
SetDCBrushColor(hDC, RGB(100,250,100));
|
auto pp = GetDCPenColor(hDC);
|
||||||
|
SetDCBrushColor(hDC, RGB(183,227,138));
|
||||||
|
SetDCPenColor(hDC, RGB(245, 250, 240));
|
||||||
|
|
||||||
POINT pt[3];
|
POINT pt[3];
|
||||||
int r = gdi.scaleLength(4);
|
int r = gdi.scaleLength(6);
|
||||||
int s = rc.bottom - rc.top - r;
|
int s = rc.bottom - rc.top - r;
|
||||||
int px = (rc.right + rc.left + s)/2;
|
int s2 = s;
|
||||||
|
|
||||||
|
int px = rc.left + s2 + r;//(rc.right + rc.left + s2)/2;
|
||||||
int py = rc.top + r/2;
|
int py = rc.top + r/2;
|
||||||
|
|
||||||
pt[0].x = px - s;
|
pt[0].x = px - s2;
|
||||||
pt[1].x = px - s/2;
|
pt[1].x = px - s2/2;
|
||||||
pt[2].x = px;
|
pt[2].x = px;
|
||||||
if (index == PrevSort) {
|
if (index != PrevSort) {
|
||||||
pt[0].y = py;
|
pt[0].y = py;
|
||||||
pt[1].y = py + s;
|
pt[1].y = py + s;
|
||||||
pt[2].y = py;
|
pt[2].y = py;
|
||||||
@ -1245,6 +1409,7 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Polygon(hDC, pt, 3);
|
Polygon(hDC, pt, 3);
|
||||||
|
SetDCPenColor(hDC, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data[0].cells[index].absPos=rc;
|
Data[0].cells[index].absPos=rc;
|
||||||
@ -1300,19 +1465,62 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rLow = -1, rHigh = -1;
|
||||||
|
int cLow = -1, cHigh = -1;
|
||||||
|
if (!startSelect) {
|
||||||
|
getRowRange(rLow, rHigh);
|
||||||
|
getColRange(cLow, cHigh);
|
||||||
|
}
|
||||||
for (size_t k1=max(2, firstRow); int(k1)<lastRow; k1++){
|
for (size_t k1=max(2, firstRow); int(k1)<lastRow; k1++){
|
||||||
int yp=dy+rowHeight*(k1+1);
|
int yp=dy+rowHeight*(k1+1);
|
||||||
TableRow &tr=Data[sortIndex[k1].index];
|
TableRow &tr=Data[sortIndex[k1].index];
|
||||||
int xp=xpos[0];
|
int xp=xpos[0];
|
||||||
|
|
||||||
if (k1&1)
|
|
||||||
SetDCBrushColor(hDC, RGB(230,230, 240));
|
|
||||||
else
|
|
||||||
SetDCBrushColor(hDC, RGB(230,230, 250));
|
|
||||||
|
|
||||||
SelectObject(hDC, GetStockObject(NULL_PEN));
|
SelectObject(hDC, GetStockObject(NULL_PEN));
|
||||||
Rectangle(hDC, max(xpos[firstCol], int(screen.left)), yp-gdi.OffsetY,
|
int ydraw = yp - gdi.OffsetY;
|
||||||
min(xpos[lastCol]+1, int(screen.right+2)), yp+rowHeight-gdi.OffsetY);
|
|
||||||
|
auto setBG = [k1, hDC](bool high) {
|
||||||
|
if (high) {
|
||||||
|
if (k1 & 1)
|
||||||
|
SetDCBrushColor(hDC, RGB(230, 240, 230));
|
||||||
|
else
|
||||||
|
SetDCBrushColor(hDC, RGB(230, 245, 230));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (k1 & 1)
|
||||||
|
SetDCBrushColor(hDC, RGB(230, 230, 240));
|
||||||
|
else
|
||||||
|
SetDCBrushColor(hDC, RGB(230, 230, 250));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setBG(false);
|
||||||
|
|
||||||
|
if (rLow != -1 && k1 >= rLow && k1 <= rHigh && cLow !=-1 && cHigh != -1) {
|
||||||
|
Rectangle(hDC, max(xpos[firstCol], int(screen.left)), ydraw,
|
||||||
|
min(xpos[lastCol] + 1, int(screen.right + 2)), ydraw + rowHeight);
|
||||||
|
|
||||||
|
|
||||||
|
//wstring w = L"cL" + itow(cLow) + L", cH" + itow(cHigh) + L"\n";
|
||||||
|
// OutputDebugString(w.c_str());
|
||||||
|
|
||||||
|
int lowHLC = max(cLow, firstCol);
|
||||||
|
int maxHLC = min(cHigh + 1, lastCol);
|
||||||
|
if (lowHLC < maxHLC) {
|
||||||
|
setBG(true);
|
||||||
|
|
||||||
|
Rectangle(hDC, max(xpos[lowHLC], int(screen.left)), ydraw,
|
||||||
|
min(xpos[maxHLC] + 1, int(screen.right + 2)), ydraw + rowHeight);
|
||||||
|
|
||||||
|
setBG(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Rectangle(hDC, max(xpos[firstCol], int(screen.left)), ydraw,
|
||||||
|
min(xpos[lastCol] + 1, int(screen.right + 2)), ydraw + rowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
SelectObject(hDC, GetStockObject(DC_PEN));
|
SelectObject(hDC, GetStockObject(DC_PEN));
|
||||||
const int cy=yp+rowHeight-gdi.OffsetY-1;
|
const int cy=yp+rowHeight-gdi.OffsetY-1;
|
||||||
MoveToEx(hDC, xp, cy, 0);
|
MoveToEx(hDC, xp, cy, 0);
|
||||||
@ -1351,7 +1559,6 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
LineTo(hDC, xp, may);
|
LineTo(hDC, xp, may);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SelectObject(hDC, GetStockObject(NULL_BRUSH));
|
SelectObject(hDC, GetStockObject(NULL_BRUSH));
|
||||||
SelectObject(hDC, GetStockObject(DC_PEN));
|
SelectObject(hDC, GetStockObject(DC_PEN));
|
||||||
SetDCPenColor(hDC, RGB(64,64,64));
|
SetDCPenColor(hDC, RGB(64,64,64));
|
||||||
@ -1363,10 +1570,10 @@ void Table::draw(gdioutput &gdi, HDC hDC, int dx, int dy, const RECT &screen)
|
|||||||
SetDCPenColor(hDC, RGB(64,64,64));
|
SetDCPenColor(hDC, RGB(64,64,64));
|
||||||
Rectangle(hDC, dx-gdi.OffsetX-2, dy-gdi.OffsetY-2,
|
Rectangle(hDC, dx-gdi.OffsetX-2, dy-gdi.OffsetY-2,
|
||||||
dx+tableWidth-gdi.OffsetX+2, dy+tableHeight-gdi.OffsetY+2);
|
dx+tableWidth-gdi.OffsetX+2, dy+tableHeight-gdi.OffsetY+2);
|
||||||
drawSelection(gdi, hDC, true);
|
if (!startSelect)
|
||||||
|
drawSelection(gdi, hDC, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TableCell &Table::getCell(int row, int col) const {
|
TableCell &Table::getCell(int row, int col) const {
|
||||||
if (size_t(row) >= sortIndex.size())
|
if (size_t(row) >= sortIndex.size())
|
||||||
throw std::exception("Index out of range");
|
throw std::exception("Index out of range");
|
||||||
@ -1417,22 +1624,31 @@ void Table::restoreSelection(gdioutput &gdi, HDC hDC) {
|
|||||||
|
|
||||||
void Table::drawSelection(gdioutput &gdi, HDC hDC, bool forceDraw) {
|
void Table::drawSelection(gdioutput &gdi, HDC hDC, bool forceDraw) {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
if (lowerColOld != lowerCol || upperCol != upperColOld ||
|
if (forceDraw) {
|
||||||
lowerRow != lowerRowOld || upperRow != upperRowOld) {
|
partialCell = false;
|
||||||
|
}
|
||||||
|
else if (sel != oldSel) {
|
||||||
modified = true;
|
modified = true;
|
||||||
restoreSelection(gdi, hDC);
|
restoreSelection(gdi, hDC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lowerCol != -1 && upperCol != -1 &&
|
if (!sel.empty() && (forceDraw || modified)) {
|
||||||
lowerRow != -1 && upperRow != -1 &&
|
int rh, rl, ch, cl;
|
||||||
(forceDraw || modified)) {
|
getRowRange(rl, rh);
|
||||||
TableCell &c1 = Data[lowerRow].cells[lowerCol];
|
getColRange(cl, ch);
|
||||||
TableCell &c2 = Data[upperRow].cells[upperCol];
|
rl = max(rl, 2);
|
||||||
|
rh = max(rh, 2);
|
||||||
|
|
||||||
|
if (isFullColumnSelected()) {
|
||||||
|
rl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
rc.top = min(c1.absPos.top, c2.absPos.top) + gdi.OffsetY;
|
rc.left = xpos[cl] + gdi.OffsetX;
|
||||||
rc.left = min(c1.absPos.left, c2.absPos.left) + gdi.OffsetX;
|
rc.right = xpos[ch + 1] + gdi.OffsetX;
|
||||||
rc.right = max(c1.absPos.right, c2.absPos.right) + 1 + gdi.OffsetX;
|
|
||||||
rc.bottom = max(c1.absPos.bottom, c2.absPos.bottom) + gdi.OffsetY;
|
rc.top = table_yp + rowHeight * (rl + 1) + gdi.OffsetY;
|
||||||
|
rc.bottom = table_yp + rowHeight * (rh + 2) + gdi.OffsetY;
|
||||||
|
|
||||||
if (modified) {
|
if (modified) {
|
||||||
int cx=rc.right-rc.left + 1;
|
int cx=rc.right-rc.left + 1;
|
||||||
@ -1462,14 +1678,14 @@ void Table::drawSelection(gdioutput &gdi, HDC hDC, bool forceDraw) {
|
|||||||
|
|
||||||
SelectObject(hDC, GetStockObject(NULL_BRUSH));
|
SelectObject(hDC, GetStockObject(NULL_BRUSH));
|
||||||
SelectObject(hDC, GetStockObject(DC_PEN));
|
SelectObject(hDC, GetStockObject(DC_PEN));
|
||||||
SetDCPenColor(hDC, RGB(0,0, 128));
|
SetDCPenColor(hDC, RGB(50, 50, 128));
|
||||||
Rectangle(hDC, rc.left - gdi.OffsetX, rc.top - gdi.OffsetY,
|
Rectangle(hDC, rc.left - gdi.OffsetX, rc.top - gdi.OffsetY,
|
||||||
rc.right - gdi.OffsetX, rc.bottom - gdi.OffsetY);
|
rc.right - gdi.OffsetX, rc.bottom - gdi.OffsetY);
|
||||||
|
SetDCPenColor(hDC, RGB(80, 60, 170));
|
||||||
|
Rectangle(hDC, rc.left - gdi.OffsetX+1, rc.top - gdi.OffsetY+1,
|
||||||
|
rc.right - gdi.OffsetX-1, rc.bottom - gdi.OffsetY-1);
|
||||||
|
|
||||||
lowerColOld = lowerCol;
|
oldSel = sel;
|
||||||
upperColOld = upperCol;
|
|
||||||
lowerRowOld = lowerRow;
|
|
||||||
upperRowOld = upperRow;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1830,7 +2046,7 @@ void Table::update()
|
|||||||
|
|
||||||
PrevSort = -1;
|
PrevSort = -1;
|
||||||
if (oldSort != -1)
|
if (oldSort != -1)
|
||||||
sort(oldSort);
|
sort(oldSort, false);
|
||||||
commandLock = false; // Reset lock
|
commandLock = false; // Reset lock
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1863,27 +2079,53 @@ void Table::getExportData(int col1, int col2, int row1, int row2, wstring &html,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Table::getRowRange(int &rowLo, int &rowHi) const {
|
void Table::getRowRange(int &rowLo, int &rowHi) const {
|
||||||
int row1 = -1, row2 = -1;
|
if (sel.empty())
|
||||||
for (size_t k = 0; k < sortIndex.size(); k++) {
|
return;
|
||||||
if (upperRow == sortIndex[k].index)
|
|
||||||
row1 = k;
|
if (selScreen.emptyRow()) {
|
||||||
if (lowerRow == sortIndex[k].index)
|
if (dataRowToIndex.empty()) {
|
||||||
row2 = k;
|
dataRowToIndex.resize(Data.size());
|
||||||
|
for (size_t k = 0; k < sortIndex.size(); k++) {
|
||||||
|
dataRowToIndex[sortIndex[k].index] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int row1 = -1, row2 = -1;
|
||||||
|
row1 = dataRowToIndex[sel.upperRow];
|
||||||
|
row2 = dataRowToIndex[sel.lowerRow];
|
||||||
|
|
||||||
|
rowLo = min(row1, row2);
|
||||||
|
rowHi = max(row1, row2);
|
||||||
|
selScreen.lowerRow = rowLo;
|
||||||
|
selScreen.upperRow = rowHi;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rowLo = selScreen.lowerRow;
|
||||||
|
rowHi = selScreen.upperRow;
|
||||||
}
|
}
|
||||||
rowLo = min(row1, row2);
|
|
||||||
rowHi = max(row1, row2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::getColRange(int &colLo, int &colHi) const {
|
void Table::getColRange(int &colLo, int &colHi) const {
|
||||||
int col1 = -1, col2 = -1;
|
if (sel.empty())
|
||||||
for (size_t k = 0; k < columns.size(); k++) {
|
return;
|
||||||
if (upperCol == columns[k])
|
|
||||||
col1 = k;
|
if (selScreen.emptyCol()) {
|
||||||
if (lowerCol == columns[k])
|
int col1 = -1, col2 = -1;
|
||||||
col2 = k;
|
for (size_t k = 0; k < columns.size(); k++) {
|
||||||
|
if (sel.upperCol == columns[k])
|
||||||
|
col1 = k;
|
||||||
|
if (sel.lowerCol == columns[k])
|
||||||
|
col2 = k;
|
||||||
|
}
|
||||||
|
colLo = min(col1, col2);
|
||||||
|
colHi = max(col1, col2);
|
||||||
|
selScreen.lowerCol = colLo;
|
||||||
|
selScreen.upperCol = colHi;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
colLo = selScreen.lowerCol;
|
||||||
|
colHi = selScreen.upperCol;
|
||||||
}
|
}
|
||||||
colLo = min(col1, col2);
|
|
||||||
colHi = max(col1, col2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::exportClipboard(gdioutput &gdi)
|
void Table::exportClipboard(gdioutput &gdi)
|
||||||
@ -2047,7 +2289,7 @@ void Table::importClipboard(gdioutput &gdi)
|
|||||||
if (tw > columns.size())
|
if (tw > columns.size())
|
||||||
throw meosException("Antalet kolumner i urklippet är större än antalet kolumner i tabellen.");
|
throw meosException("Antalet kolumner i urklippet är större än antalet kolumner i tabellen.");
|
||||||
|
|
||||||
if (upperRow == -1) {
|
if (sel.emptyRow()) {
|
||||||
if (!gdi.ask(L"Vill du klistra in X nya rader i tabellen?#"+itow(table.size())))
|
if (!gdi.ask(L"Vill du klistra in X nya rader i tabellen?#"+itow(table.size())))
|
||||||
return;
|
return;
|
||||||
rowS = sortIndex.size(); // Add new rows
|
rowS = sortIndex.size(); // Add new rows
|
||||||
|
|||||||
58
code/Table.h
58
code/Table.h
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -163,11 +163,13 @@ protected:
|
|||||||
size_t dataPointer; // Insertation pointer
|
size_t dataPointer; // Insertation pointer
|
||||||
vector<TableSortIndex> sortIndex;
|
vector<TableSortIndex> sortIndex;
|
||||||
vector<int> columns;
|
vector<int> columns;
|
||||||
|
mutable vector<int> dataRowToIndex;
|
||||||
inthashmap idToRow;
|
inthashmap idToRow;
|
||||||
//highlight
|
|
||||||
int highRow;
|
int highRow;
|
||||||
int highCol;
|
int highCol;
|
||||||
|
|
||||||
|
bool isFullColumnSelected() const;
|
||||||
|
|
||||||
// Selected columns. For drag/drop and sort
|
// Selected columns. For drag/drop and sort
|
||||||
int colSelected;
|
int colSelected;
|
||||||
int startX;
|
int startX;
|
||||||
@ -178,16 +180,37 @@ protected:
|
|||||||
int editCol;
|
int editCol;
|
||||||
|
|
||||||
// Selected rectangle
|
// Selected rectangle
|
||||||
int upperRow;
|
struct Range {
|
||||||
int lowerRow;
|
int upperRow;
|
||||||
int upperCol;
|
int lowerRow;
|
||||||
int lowerCol;
|
int upperCol;
|
||||||
|
int lowerCol;
|
||||||
|
void reset() {
|
||||||
|
upperRow = -1;
|
||||||
|
lowerRow = -1;
|
||||||
|
upperCol = -1;
|
||||||
|
lowerCol = -1;
|
||||||
|
}
|
||||||
|
bool emptyRow() const { return upperRow < 0 || lowerRow < 0; }
|
||||||
|
bool emptyCol() const { return upperCol < 0 || lowerCol < 0; }
|
||||||
|
bool empty() const { return emptyRow() || emptyCol(); }
|
||||||
|
|
||||||
int upperRowOld;
|
Range() { reset(); }
|
||||||
|
~Range() = default;
|
||||||
|
bool operator!=(const Range &other) const {
|
||||||
|
return upperRow != other.upperRow || lowerCol != other.lowerCol ||
|
||||||
|
lowerRow != other.lowerRow || upperCol != other.upperCol;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Range sel;
|
||||||
|
mutable Range selScreen;
|
||||||
|
Range oldSel;
|
||||||
|
/* int upperRowOld;
|
||||||
int lowerRowOld;
|
int lowerRowOld;
|
||||||
int upperColOld;
|
int upperColOld;
|
||||||
int lowerColOld;
|
int lowerColOld;
|
||||||
|
*/
|
||||||
bool startSelect;
|
bool startSelect;
|
||||||
|
|
||||||
HWND hEdit;
|
HWND hEdit;
|
||||||
@ -205,9 +228,9 @@ protected:
|
|||||||
bool partialCell;
|
bool partialCell;
|
||||||
|
|
||||||
//static bool filterMatchString(const string &c, const char *filt);
|
//static bool filterMatchString(const string &c, const char *filt);
|
||||||
void highlightCell(HDC hDC, gdioutput &gdi, const TableCell &cell, DWORD color, int dx, int dy);
|
void highlightCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, DWORD color, int dx, int dy);
|
||||||
|
|
||||||
void moveCell(HDC hDC, gdioutput &gdi, const TableCell &cell, int dx, int dy);
|
void moveCell(HDC hDC, gdioutput &gdi, int col, const TableCell &cell, int dx, int dy);
|
||||||
void startMoveCell(HDC hDC, const TableCell &cell);
|
void startMoveCell(HDC hDC, const TableCell &cell);
|
||||||
void stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy);
|
void stopMoveCell(HDC hDC, const TableCell &cell, int dx, int dy);
|
||||||
void restoreCell(HDC hDC, const TableCell &cell);
|
void restoreCell(HDC hDC, const TableCell &cell);
|
||||||
@ -337,12 +360,20 @@ public:
|
|||||||
bool mouseLeftUp(gdioutput &gdi, int x, int y);
|
bool mouseLeftUp(gdioutput &gdi, int x, int y);
|
||||||
bool mouseLeftDblClick(gdioutput &gdi, int x, int y);
|
bool mouseLeftDblClick(gdioutput &gdi, int x, int y);
|
||||||
|
|
||||||
|
bool mouseRightDown(gdioutput &gdi, int x, int y);
|
||||||
|
bool mouseRightUp(gdioutput &gdi, int x, int y);
|
||||||
|
bool mouseMidDown(gdioutput &gdi, int x, int y);
|
||||||
|
bool mouseMidUp(gdioutput &gdi, int x, int y);
|
||||||
|
|
||||||
|
|
||||||
bool editCell(gdioutput &gdi, int row, int col);
|
bool editCell(gdioutput &gdi, int row, int col);
|
||||||
|
|
||||||
bool keyCommand(gdioutput &gdi, KeyCommandCode code);
|
bool keyCommand(gdioutput &gdi, KeyCommandCode code);
|
||||||
void sort(int col);
|
void sort(int col, bool forceDirection);
|
||||||
void filter(int col, const wstring &filt, bool forceFilter=false);
|
void filter(int col, const wstring &filt, bool forceFilter=false);
|
||||||
|
|
||||||
|
void showFilter(gdioutput &gdi);
|
||||||
|
|
||||||
int addColumn(const string &Title, int width, bool isnum, bool formatRight = false);
|
int addColumn(const string &Title, int width, bool isnum, bool formatRight = false);
|
||||||
int addColumn(const wstring &translatedTitle, int width, bool isnum, bool formatRight = false);
|
int addColumn(const wstring &translatedTitle, int width, bool isnum, bool formatRight = false);
|
||||||
|
|
||||||
@ -355,6 +386,8 @@ public:
|
|||||||
void set(int column, oBase &owner, int id, const wstring &data,
|
void set(int column, oBase &owner, int id, const wstring &data,
|
||||||
bool canEdit=true, CellType type=cellEdit);
|
bool canEdit=true, CellType type=cellEdit);
|
||||||
|
|
||||||
|
void markAll(bool doSelect);
|
||||||
|
|
||||||
//Reload a row from data
|
//Reload a row from data
|
||||||
void reloadRow(int rowId);
|
void reloadRow(int rowId);
|
||||||
|
|
||||||
@ -374,12 +407,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TableSortIndex {
|
struct TableSortIndex {
|
||||||
//TableSortIndex(const Table &t) : table(&t) {}
|
|
||||||
const static Table *table;
|
const static Table *table;
|
||||||
int index;
|
int index;
|
||||||
bool operator<(const TableSortIndex &t) const {return table->compareRow(index,t.index);}
|
bool operator<(const TableSortIndex &t) const {return table->compareRow(index,t.index);}
|
||||||
//{return table->Data[index].key < table->Data[t.index].key;}
|
|
||||||
//bool operator<=(const TableSortIndex &t) const {return table->Data[index].key <= table->Data[t.index].key;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {TID_CLASSNAME, TID_COURSE, TID_NUM, TID_ID, TID_MODIFIED,
|
enum {TID_CLASSNAME, TID_COURSE, TID_NUM, TID_ID, TID_MODIFIED,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
#endif // _MSC_VER > 1000
|
#endif // _MSC_VER > 1000
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
BIN
code/bitmap1.bmp
BIN
code/bitmap1.bmp
Binary file not shown.
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 12 KiB |
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1528,10 +1528,10 @@ Exportformat = Export format
|
|||||||
Filnamnsprefix = Filename prefix
|
Filnamnsprefix = Filename prefix
|
||||||
Mapp = Folder
|
Mapp = Folder
|
||||||
Mappnamnet får inte vara tomt = Folder name cannot be empty
|
Mappnamnet får inte vara tomt = Folder name cannot be empty
|
||||||
Onlineresultat = On-Line Results
|
Onlineresultat = Online Results
|
||||||
Packa stora filer (zip) = Compress large files (zip)
|
Packa stora filer (zip) = Compress large files (zip)
|
||||||
Publicera resultat direkt på nätet = Publish results directly on the web
|
Publicera resultat direkt på nätet = Publish results directly on the web
|
||||||
Resultat online = Results On-Line
|
Resultat online = Results OnLine
|
||||||
Skicka till webben = Send to the web
|
Skicka till webben = Send to the web
|
||||||
Spara på disk = Save to disk
|
Spara på disk = Save to disk
|
||||||
Till exempel X = For example X
|
Till exempel X = For example X
|
||||||
@ -1541,13 +1541,13 @@ URL måste anges = URL missing
|
|||||||
Tidsintervall (sekunder) = Time interval (seconds)
|
Tidsintervall (sekunder) = Time interval (seconds)
|
||||||
Antal skickade uppdateringar X (Y kb) = Number of updates X (Y kb)
|
Antal skickade uppdateringar X (Y kb) = Number of updates X (Y kb)
|
||||||
Filen finns redan: X = Destination already exists: X
|
Filen finns redan: X = Destination already exists: X
|
||||||
Misslyckades med att ladda upp onlineresultat = Failed to upload on-line results
|
Misslyckades med att ladda upp onlineresultat = Failed to upload online results
|
||||||
Onlineservern svarade felaktigt = Remote server gave unexpected reply (Incorrect configuration?)
|
Onlineservern svarade felaktigt = Remote server gave unexpected reply (Incorrect configuration?)
|
||||||
Onlineservern svarade: ZIP stöds ej = Response from remote server: ZIP not supported.
|
Onlineservern svarade: ZIP stöds ej = Response from remote server: ZIP not supported.
|
||||||
Onlineservern svarade: Serverfel = Response from remote server: Server error
|
Onlineservern svarade: Serverfel = Response from remote server: Server error
|
||||||
Onlineservern svarade: Felaktigt lösenord = Response from remote server: Wrong password
|
Onlineservern svarade: Felaktigt lösenord = Response from remote server: Wrong password
|
||||||
Onlineservern svarade: Felaktigt tävlings-id = Response from remote server: Wrong competition id
|
Onlineservern svarade: Felaktigt tävlings-id = Response from remote server: Wrong competition id
|
||||||
Online Results Error X = On-Line Results Error X
|
Online Results Error X = Online Results Error X
|
||||||
PDF = PDF
|
PDF = PDF
|
||||||
ClassTeamLeg = Class, team, leg
|
ClassTeamLeg = Class, team, leg
|
||||||
Okänd = Unknown
|
Okänd = Unknown
|
||||||
@ -2534,7 +2534,7 @@ RunnerStageTimeStatus = Competitor's time or status (on stage)
|
|||||||
EFilterIncludeNotParticipating = Include not participating
|
EFilterIncludeNotParticipating = Include not participating
|
||||||
RunnerStageNumber = Stage number earlier stage
|
RunnerStageNumber = Stage number earlier stage
|
||||||
Begränsa bredd (klipp text) = Limit width (crop text)
|
Begränsa bredd (klipp text) = Limit width (crop text)
|
||||||
Håll ihop med = Keep together
|
Håll ihop med = Keep columns close
|
||||||
Justering i sidled = Line adjustment
|
Justering i sidled = Line adjustment
|
||||||
Minsta blockbredd = Least width
|
Minsta blockbredd = Least width
|
||||||
Relation till föregående = Relation to previous
|
Relation till föregående = Relation to previous
|
||||||
@ -2545,5 +2545,44 @@ prefsDatabaseEngine = Typ av databastabell för nya tävlingar (MySQL)
|
|||||||
Startgrupperna X och Y överlappar = Start groups X and Y are overlapping
|
Startgrupperna X och Y överlappar = Start groups X and Y are overlapping
|
||||||
Batteristatus = Battery status
|
Batteristatus = Battery status
|
||||||
Low = Low
|
Low = Low
|
||||||
prefsReadVoltageExp = Read SIAC battery voltage
|
Replace[battery] = Replace
|
||||||
Spänning = Voltage
|
Spänning = Voltage
|
||||||
|
(kopia) = (copy)
|
||||||
|
Klassen använder banpool = The class has a course pool
|
||||||
|
Filen (X) innehåller IOF-XML tävlingsdata och kan importeras i en existerande tävling = The file (X) contains IOF-XML competition data. You can import it into an existing competition.
|
||||||
|
Filen (X) är en listdefinition = The file (X) is a list definition
|
||||||
|
Filen (X) är en resultatmodul = The file (X) is a result module
|
||||||
|
Filen (X) är inte en MeOS-tävling = The file (X) is not a MeOS competition
|
||||||
|
MeOS-data = MeOS-data
|
||||||
|
List definition = List definition
|
||||||
|
ask:importcopy = A competition (X) with the same origin already exist. You can import the competition as a version of that competition or as a new independent copy. If it is the same event with modifications, it is best to import it as a version.\n\nWould you like to import it as a version?
|
||||||
|
RunnerCardVoltage = Card voltage
|
||||||
|
Applicera för specifik etapp = Apply for specific stage
|
||||||
|
Ljud = Sound
|
||||||
|
Ljudval = Sound selection
|
||||||
|
Markera allt (X) = Select all (X)
|
||||||
|
Markera inget (X) = Select none (X)
|
||||||
|
Ny ledare i klassen = New class leader
|
||||||
|
Sparade automater = Saved machines
|
||||||
|
Spela upp ett ljud för att indikera resultatet av brickavläsningen = Play a sound to indicate the result of the card readout.
|
||||||
|
Status inte OK (röd utgång) = Status not OK (red exit)
|
||||||
|
help:selectsound = Select sounds to play. By default MeOS builtin sounds are played.
|
||||||
|
prefsPlaySound = Play sounds
|
||||||
|
prefsSoundAction = Sound file, action needed
|
||||||
|
prefsSoundLeader = Sound file, class leader
|
||||||
|
prefsSoundNotOK = Sound file, status not OK
|
||||||
|
prefsSoundOK = Sound file, status OK.
|
||||||
|
Åtgärd krävs = Action needed
|
||||||
|
Alla tidigare etapper = All previous stages
|
||||||
|
Dölj = Hide
|
||||||
|
Exempel = Example
|
||||||
|
Filtrera = Filter
|
||||||
|
Markera kolumn = Select column
|
||||||
|
Slå ihop text = Append text (share column)
|
||||||
|
Sortera fallande = Sort decreasing
|
||||||
|
Sortera stigande = Sort increasing
|
||||||
|
Sök symbol = Search for symbol
|
||||||
|
Testa = Test
|
||||||
|
Fel: Använd X i texten där värdet (Y) ska sättas in = Error: Use X in the text where the value (Y) should be used
|
||||||
|
info:teamcourseassignment = The imported file contains forking data for teams. To import this data you must prepare the competition to match the imported file: \n\n1. Ensure all classes are setup with the correct number of legs.\n2. Provide bib numbers in each class. Use Quick Settings on the page Classes and enter the first bib number in each class (meaning automatic bib setting). You can also import the teams first and assign bibs as usual.\n3. Import the courses. You can import this file several times if needed to update the forking.
|
||||||
|
Försvunnen = Missing
|
||||||
|
|||||||
2289
code/french.lng
2289
code/french.lng
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -38,6 +38,8 @@ enum KeyCommandCode {
|
|||||||
KC_SPEEDUP,
|
KC_SPEEDUP,
|
||||||
KC_SLOWDOWN,
|
KC_SLOWDOWN,
|
||||||
KC_AUTOCOMPLETE,
|
KC_AUTOCOMPLETE,
|
||||||
|
KC_MARKALL,
|
||||||
|
KC_CLEARALL
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Enum used to stack GUI command control, "command line wizard" */
|
/** Enum used to stack GUI command control, "command line wizard" */
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -2376,13 +2376,13 @@ void gdioutput::processListMessage(ListBoxInfo &bi, WPARAM wParam)
|
|||||||
|
|
||||||
LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
||||||
{
|
{
|
||||||
if (iMessage==WM_COMMAND) {
|
if (iMessage == WM_COMMAND) {
|
||||||
WORD hwParam = HIWORD(wParam);
|
WORD hwParam = HIWORD(wParam);
|
||||||
HWND hWnd=(HWND)lParam;
|
HWND hWnd = (HWND)lParam;
|
||||||
if (hwParam==EN_CHANGE) {
|
if (hwParam == EN_CHANGE) {
|
||||||
list<TableInfo>::iterator tit;
|
list<TableInfo>::iterator tit;
|
||||||
if (useTables)
|
if (useTables)
|
||||||
for (tit=Tables.begin(); tit!=Tables.end(); ++tit)
|
for (tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
if (tit->table->inputChange(*this, hWnd))
|
if (tit->table->inputChange(*this, hWnd))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2392,8 +2392,8 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
//for (it=BI.begin(); it != BI.end(); ++it) {
|
//for (it=BI.begin(); it != BI.end(); ++it) {
|
||||||
unordered_map<HWND, ButtonInfo*>::iterator it = biByHwnd.find(HWND(lParam));
|
unordered_map<HWND, ButtonInfo*>::iterator it = biByHwnd.find(HWND(lParam));
|
||||||
|
|
||||||
// if (it->hWnd==hWnd) {
|
// if (it->hWnd==hWnd) {
|
||||||
if ( it != biByHwnd.end() ) {
|
if (it != biByHwnd.end()) {
|
||||||
ButtonInfo &bi = *it->second;
|
ButtonInfo &bi = *it->second;
|
||||||
processButtonMessage(bi, wParam);
|
processButtonMessage(bi, wParam);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2431,62 +2431,62 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (iMessage==WM_MOUSEMOVE) {
|
else if (iMessage == WM_MOUSEMOVE) {
|
||||||
POINT pt;
|
POINT pt;
|
||||||
pt.x=(signed short)LOWORD(lParam);
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
pt.y=(signed short)HIWORD(lParam);
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
list<TableInfo>::iterator tit;
|
list<TableInfo>::iterator tit;
|
||||||
|
|
||||||
bool GotCapture=false;
|
bool GotCapture = false;
|
||||||
|
|
||||||
if (useTables)
|
if (useTables)
|
||||||
for (tit=Tables.begin(); tit!=Tables.end(); ++tit)
|
for (tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
GotCapture = tit->table->mouseMove(*this, pt.x, pt.y) || GotCapture;
|
GotCapture = tit->table->mouseMove(*this, pt.x, pt.y) || GotCapture;
|
||||||
|
|
||||||
if (GotCapture)
|
if (GotCapture)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
list<InfoBox>::iterator it=IBox.begin();
|
list<InfoBox>::iterator it = IBox.begin();
|
||||||
|
|
||||||
|
|
||||||
while (it != IBox.end()) {
|
while (it != IBox.end()) {
|
||||||
if (PtInRect(&it->TextRect, pt) && (it->callBack || it->hasEventHandler())) {
|
if (PtInRect(&it->TextRect, pt) && (it->callBack || it->hasEventHandler())) {
|
||||||
SetCursor(LoadCursor(NULL, IDC_HAND));
|
SetCursor(LoadCursor(NULL, IDC_HAND));
|
||||||
|
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawBoxText(hDC, it->TextRect, *it, true);
|
drawBoxText(hDC, it->TextRect, *it, true);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
SetCapture(hWndTarget);
|
SetCapture(hWndTarget);
|
||||||
GotCapture=true;
|
GotCapture = true;
|
||||||
it->HasTCapture=true;
|
it->HasTCapture = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (it->HasTCapture) {
|
if (it->HasTCapture) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawBoxText(hDC, it->TextRect, *it, false);
|
drawBoxText(hDC, it->TextRect, *it, false);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
if (!GotCapture)
|
if (!GotCapture)
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
it->HasTCapture=false;
|
it->HasTCapture = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it->HasCapture) {
|
if (it->HasCapture) {
|
||||||
if (GetCapture()!=hWndTarget) {
|
if (GetCapture() != hWndTarget) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawCloseBox(hDC, it->Close, false);
|
drawCloseBox(hDC, it->Close, false);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
if (!GotCapture) ReleaseCapture();
|
if (!GotCapture) ReleaseCapture();
|
||||||
it->HasCapture=false;
|
it->HasCapture = false;
|
||||||
}
|
}
|
||||||
else if (!PtInRect(&it->Close, pt)) {
|
else if (!PtInRect(&it->Close, pt)) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawCloseBox(hDC, it->Close, false);
|
drawCloseBox(hDC, it->Close, false);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawCloseBox(hDC, it->Close, true);
|
drawCloseBox(hDC, it->Close, true);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
}
|
}
|
||||||
@ -2494,25 +2494,25 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t k=0;k<shownStrings.size();k++) {
|
for (size_t k = 0; k < shownStrings.size(); k++) {
|
||||||
TextInfo &ti = *shownStrings[k];
|
TextInfo &ti = *shownStrings[k];
|
||||||
if ((!ti.callBack && !ti.hasEventHandler()) || ti.hasTimer)
|
if ((!ti.callBack && !ti.hasEventHandler()) || ti.hasTimer)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (PtInRect(&ti.textRect, pt)) {
|
if (PtInRect(&ti.textRect, pt)) {
|
||||||
if (!ti.highlight){
|
if (!ti.highlight) {
|
||||||
ti.highlight=true;
|
ti.highlight = true;
|
||||||
InvalidateRect(hWndTarget, &ti.textRect, true);
|
InvalidateRect(hWndTarget, &ti.textRect, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCapture(hWndTarget);
|
SetCapture(hWndTarget);
|
||||||
GotCapture=true;
|
GotCapture = true;
|
||||||
ti.hasCapture=true;
|
ti.hasCapture = true;
|
||||||
SetCursor(LoadCursor(NULL, IDC_HAND));
|
SetCursor(LoadCursor(NULL, IDC_HAND));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ti.highlight) {
|
if (ti.highlight) {
|
||||||
ti.highlight=false;
|
ti.highlight = false;
|
||||||
InvalidateRect(hWndTarget, &ti.textRect, true);
|
InvalidateRect(hWndTarget, &ti.textRect, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2520,79 +2520,80 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
if (!GotCapture)
|
if (!GotCapture)
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
|
||||||
ti.hasCapture=false;
|
ti.hasCapture = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (iMessage==WM_LBUTTONDOWN) {
|
else if (iMessage == WM_LBUTTONDOWN) {
|
||||||
if (autoCompleteInfo) {
|
if (autoCompleteInfo) {
|
||||||
autoCompleteInfo.reset();
|
autoCompleteInfo.reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
list<InfoBox>::iterator it=IBox.begin();
|
list<InfoBox>::iterator it = IBox.begin();
|
||||||
|
|
||||||
POINT pt;
|
POINT pt;
|
||||||
pt.x=(signed short)LOWORD(lParam);
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
pt.y=(signed short)HIWORD(lParam);
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
list<TableInfo>::iterator tit;
|
list<TableInfo>::iterator tit;
|
||||||
|
|
||||||
if (useTables)
|
if (useTables) {
|
||||||
for (tit=Tables.begin(); tit!=Tables.end(); ++tit)
|
for (tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
if (tit->table->mouseLeftDown(*this, pt.x, pt.y))
|
if (tit->table->mouseLeftDown(*this, pt.x, pt.y))
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while(it!=IBox.end()) {
|
while (it != IBox.end()) {
|
||||||
if (PtInRect(&it->Close, pt)) {
|
if (PtInRect(&it->Close, pt)) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawCloseBox(hDC, it->Close, true);
|
drawCloseBox(hDC, it->Close, true);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
SetCapture(hWndTarget);
|
SetCapture(hWndTarget);
|
||||||
it->HasCapture=true;
|
it->HasCapture = true;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Handle links
|
//Handle links
|
||||||
for (size_t k=0;k<shownStrings.size();k++) {
|
for (size_t k = 0; k < shownStrings.size(); k++) {
|
||||||
TextInfo &ti = *shownStrings[k];
|
TextInfo &ti = *shownStrings[k];
|
||||||
if (!ti.callBack && !ti.hasEventHandler())
|
if (!ti.callBack && !ti.hasEventHandler())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ti.hasCapture) {
|
if (ti.hasCapture) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
if (PtInRect(&ti.textRect, pt)) {
|
if (PtInRect(&ti.textRect, pt)) {
|
||||||
ti.active=true;
|
ti.active = true;
|
||||||
RenderString(ti, hDC);
|
RenderString(ti, hDC);
|
||||||
}
|
}
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (iMessage==WM_LBUTTONUP) {
|
else if (iMessage == WM_LBUTTONUP) {
|
||||||
list<TableInfo>::iterator tit;
|
list<TableInfo>::iterator tit;
|
||||||
|
|
||||||
list<InfoBox>::iterator it=IBox.begin();
|
list<InfoBox>::iterator it = IBox.begin();
|
||||||
|
|
||||||
POINT pt;
|
POINT pt;
|
||||||
pt.x=(signed short)LOWORD(lParam);
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
pt.y=(signed short)HIWORD(lParam);
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
if (useTables)
|
if (useTables) {
|
||||||
for (tit=Tables.begin(); tit!=Tables.end(); ++tit)
|
for (tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
if (tit->table->mouseLeftUp(*this, pt.x, pt.y))
|
if (tit->table->mouseLeftUp(*this, pt.x, pt.y))
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
while (it!=IBox.end()) {
|
while (it != IBox.end()) {
|
||||||
if (it->HasCapture) {
|
if (it->HasCapture) {
|
||||||
HDC hDC=GetDC(hWndTarget);
|
HDC hDC = GetDC(hWndTarget);
|
||||||
drawCloseBox(hDC, it->Close, false);
|
drawCloseBox(hDC, it->Close, false);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
it->HasCapture=false;
|
it->HasCapture = false;
|
||||||
|
|
||||||
if (PtInRect(&it->Close, pt)) {
|
if (PtInRect(&it->Close, pt)) {
|
||||||
IBox.erase(it);
|
IBox.erase(it);
|
||||||
@ -2602,7 +2603,7 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
}
|
}
|
||||||
else if (it->HasTCapture) {
|
else if (it->HasTCapture) {
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
it->HasTCapture=false;
|
it->HasTCapture = false;
|
||||||
|
|
||||||
if (PtInRect(&it->TextRect, pt)) {
|
if (PtInRect(&it->TextRect, pt)) {
|
||||||
if (!it->handleEvent(*this, GUI_INFOBOX) && it->callBack)
|
if (!it->handleEvent(*this, GUI_INFOBOX) && it->callBack)
|
||||||
@ -2614,12 +2615,12 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Handle links
|
//Handle links
|
||||||
for (size_t k=0;k<shownStrings.size();k++) {
|
for (size_t k = 0; k < shownStrings.size(); k++) {
|
||||||
TextInfo &ti = *shownStrings[k];
|
TextInfo &ti = *shownStrings[k];
|
||||||
if (!ti.callBack && !ti.hasEventHandler())
|
if (!ti.callBack && !ti.hasEventHandler())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ti.hasCapture){
|
if (ti.hasCapture) {
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
ti.hasCapture = false;
|
ti.hasCapture = false;
|
||||||
|
|
||||||
@ -2630,7 +2631,7 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
cmd = "click(\"" + ti.id + "\", " + itos(ti.getExtraInt()) + "); //" + toUTF8(ti.text);
|
cmd = "click(\"" + ti.id + "\", " + itos(ti.getExtraInt()) + "); //" + toUTF8(ti.text);
|
||||||
else
|
else
|
||||||
cmd = "click(\"" + ti.id + "\"); //" + toUTF8(ti.text);
|
cmd = "click(\"" + ti.id + "\"); //" + toUTF8(ti.text);
|
||||||
ti.active=false;
|
ti.active = false;
|
||||||
RenderString(ti);
|
RenderString(ti);
|
||||||
if (!ti.handleEvent(*this, GUI_LINK))
|
if (!ti.handleEvent(*this, GUI_LINK))
|
||||||
ti.callBack(this, GUI_LINK, &ti);
|
ti.callBack(this, GUI_LINK, &ti);
|
||||||
@ -2639,24 +2640,68 @@ LRESULT gdioutput::ProcessMsgWrp(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ti.active){
|
else if (ti.active) {
|
||||||
ti.active=false;
|
ti.active = false;
|
||||||
RenderString(ti);
|
RenderString(ti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (iMessage==WM_LBUTTONDBLCLK) {
|
else if (iMessage == WM_LBUTTONDBLCLK) {
|
||||||
list<TableInfo>::iterator tit;
|
list<TableInfo>::iterator tit;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
pt.x=(signed short)LOWORD(lParam);
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
pt.y=(signed short)HIWORD(lParam);
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
if (useTables)
|
if (useTables)
|
||||||
for (tit=Tables.begin(); tit!=Tables.end(); ++tit)
|
for (tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
if (tit->table->mouseLeftDblClick(*this, pt.x, pt.y))
|
if (tit->table->mouseLeftDblClick(*this, pt.x, pt.y))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (iMessage == WM_RBUTTONDOWN) {
|
||||||
|
POINT pt;
|
||||||
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
|
if (useTables) {
|
||||||
|
for (auto tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
|
if (tit->table->mouseRightDown(*this, pt.x, pt.y))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iMessage == WM_RBUTTONUP) {
|
||||||
|
POINT pt;
|
||||||
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
|
if (useTables) {
|
||||||
|
for (auto tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
|
if (tit->table->mouseRightUp(*this, pt.x, pt.y))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iMessage == WM_MBUTTONDOWN) {
|
||||||
|
POINT pt;
|
||||||
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
|
if (useTables) {
|
||||||
|
for (auto tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
|
if (tit->table->mouseMidDown(*this, pt.x, pt.y))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iMessage == WM_MBUTTONUP) {
|
||||||
|
POINT pt;
|
||||||
|
pt.x = (signed short)LOWORD(lParam);
|
||||||
|
pt.y = (signed short)HIWORD(lParam);
|
||||||
|
|
||||||
|
if (useTables) {
|
||||||
|
for (auto tit = Tables.begin(); tit != Tables.end(); ++tit)
|
||||||
|
if (tit->table->mouseMidUp(*this, pt.x, pt.y))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (iMessage == WM_CHAR) {
|
else if (iMessage == WM_CHAR) {
|
||||||
/*list<TableInfo>::iterator tit;
|
/*list<TableInfo>::iterator tit;
|
||||||
if (useTables)
|
if (useTables)
|
||||||
@ -3504,6 +3549,23 @@ void gdioutput::adjustDimension(int width, int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alert from main thread (via callback)
|
||||||
|
void gdioutput::delayAlert(const wstring& msg) {
|
||||||
|
if (!delayedAlert.empty())
|
||||||
|
delayedAlert += L", ";
|
||||||
|
if (delayedAlert.length() > 1000)
|
||||||
|
delayedAlert = L"";
|
||||||
|
|
||||||
|
delayedAlert += lang.tl(msg);
|
||||||
|
PostMessage(hWndAppMain, WM_USER + 6, 0, LPARAM(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring gdioutput::getDelayedAlert() {
|
||||||
|
wstring out = L"#" + delayedAlert;
|
||||||
|
delayedAlert.clear();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void gdioutput::alert(const string &msg) const
|
void gdioutput::alert(const string &msg) const
|
||||||
{
|
{
|
||||||
alert(widen(msg));
|
alert(widen(msg));
|
||||||
@ -4002,6 +4064,7 @@ void gdioutput::removeString(string id)
|
|||||||
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
|
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
|
||||||
ReleaseDC(hWndTarget, hDC);
|
ReleaseDC(hWndTarget, hDC);
|
||||||
TL.erase(it);
|
TL.erase(it);
|
||||||
|
itTL = TL.end();
|
||||||
shownStrings.clear();
|
shownStrings.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4833,6 +4896,8 @@ bool gdioutput::removeWidget(const string &id)
|
|||||||
}
|
}
|
||||||
++iit;
|
++iit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeString(id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5757,6 +5822,12 @@ void gdioutput::tableCB(ButtonInfo &bu, Table *t)
|
|||||||
t->updateDimension(*this);
|
t->updateDimension(*this);
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
else if (bu.id == "tblMarkAll") {
|
||||||
|
t->keyCommand(*this, KC_MARKALL);
|
||||||
|
}
|
||||||
|
else if (bu.id == "tblClearAll") {
|
||||||
|
t->keyCommand(*this, KC_CLEARALL);
|
||||||
|
}
|
||||||
else if (bu.id=="tblUpdate") {
|
else if (bu.id=="tblUpdate") {
|
||||||
t->keyCommand(*this, KC_REFRESH);
|
t->keyCommand(*this, KC_REFRESH);
|
||||||
}
|
}
|
||||||
@ -5799,6 +5870,8 @@ void gdioutput::enableTables()
|
|||||||
toolbar->addButton("tblPrint", 0, STD_PRINT, "Skriv ut tabellen (X)#Ctrl+P");
|
toolbar->addButton("tblPrint", 0, STD_PRINT, "Skriv ut tabellen (X)#Ctrl+P");
|
||||||
toolbar->addButton("tblUpdate", 1, 0, "Uppdatera alla värden i tabellen (X)#F5");
|
toolbar->addButton("tblUpdate", 1, 0, "Uppdatera alla värden i tabellen (X)#F5");
|
||||||
toolbar->addButton("tblReset", 1, 4, "Återställ tabeldesignen och visa allt");
|
toolbar->addButton("tblReset", 1, 4, "Återställ tabeldesignen och visa allt");
|
||||||
|
toolbar->addButton("tblMarkAll", 1, 5, "Markera allt (X)#Ctrl+A");
|
||||||
|
toolbar->addButton("tblClearAll", 1, 6, "Markera inget (X)#Ctrl+D");
|
||||||
toolbar->addButton("tblCopy", 0, STD_COPY, "Kopiera selektionen till urklipp (X)#Ctrl+C");
|
toolbar->addButton("tblCopy", 0, STD_COPY, "Kopiera selektionen till urklipp (X)#Ctrl+C");
|
||||||
if (t->canPaste())
|
if (t->canPaste())
|
||||||
toolbar->addButton("tblPaste", 0, STD_PASTE, "Klistra in data från urklipp (X)#Ctrl+V");
|
toolbar->addButton("tblPaste", 0, STD_PASTE, "Klistra in data från urklipp (X)#Ctrl+V");
|
||||||
@ -7040,7 +7113,18 @@ DWORD gdioutput::selectColor(wstring &def, DWORD input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cc.lpCustColors = staticColor;
|
cc.lpCustColors = staticColor;
|
||||||
if (ChooseColor(&cc)) {
|
int res = 0;
|
||||||
|
setCommandLock();
|
||||||
|
try {
|
||||||
|
res = ChooseColor(&cc);
|
||||||
|
liftCommandLock();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
liftCommandLock();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
wstring co;
|
wstring co;
|
||||||
for (int ix = 0; ix < 16; ix++) {
|
for (int ix = 0; ix < 16; ix++) {
|
||||||
wchar_t bf[16];
|
wchar_t bf[16];
|
||||||
@ -7053,7 +7137,6 @@ DWORD gdioutput::selectColor(wstring &def, DWORD input) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gdioutput::setAnimationMode(shared_ptr<AnimationData> &data) {
|
void gdioutput::setAnimationMode(shared_ptr<AnimationData> &data) {
|
||||||
if (animationData && animationData->takeOver(data))
|
if (animationData && animationData->takeOver(data))
|
||||||
return;
|
return;
|
||||||
@ -7118,3 +7201,22 @@ int gdioutput::getPageX() const {
|
|||||||
else
|
else
|
||||||
return max(MaxX, xlimit) + scaleLength(60);
|
return max(MaxX, xlimit) + scaleLength(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gdioutput::popupMenu(int x, int y, const vector<pair<wstring, int>> &menuItems) const {
|
||||||
|
POINT pt;
|
||||||
|
pt.x = x;
|
||||||
|
pt.y = y;
|
||||||
|
ClientToScreen(getHWNDTarget(), &pt);
|
||||||
|
HMENU hm = CreatePopupMenu();
|
||||||
|
for (auto &me : menuItems) {
|
||||||
|
if (me.first.empty())
|
||||||
|
AppendMenu(hm, MF_SEPARATOR, me.second, L"");
|
||||||
|
else
|
||||||
|
AppendMenu(hm, MF_STRING, me.second, lang.tl(me.first).c_str());
|
||||||
|
}
|
||||||
|
int res = TrackPopupMenuEx(hm, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY,
|
||||||
|
pt.x, pt.y, getHWNDTarget(), nullptr);
|
||||||
|
|
||||||
|
DestroyMenu(hm);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -289,6 +289,8 @@ protected:
|
|||||||
shared_ptr<AnimationData> animationData;
|
shared_ptr<AnimationData> animationData;
|
||||||
|
|
||||||
shared_ptr<AutoCompleteInfo> autoCompleteInfo;
|
shared_ptr<AutoCompleteInfo> autoCompleteInfo;
|
||||||
|
|
||||||
|
wstring delayedAlert;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AutoCompleteInfo &addAutoComplete(const string &key);
|
AutoCompleteInfo &addAutoComplete(const string &key);
|
||||||
@ -571,6 +573,10 @@ public:
|
|||||||
|
|
||||||
void alert(const string &msg) const;
|
void alert(const string &msg) const;
|
||||||
void alert(const wstring &msg) const;
|
void alert(const wstring &msg) const;
|
||||||
|
// Alert from main thread (via callback)
|
||||||
|
void delayAlert(const wstring& msg);
|
||||||
|
// Get and clear any delayed alert
|
||||||
|
wstring getDelayedAlert();
|
||||||
|
|
||||||
void fillDown(){Direction=1;}
|
void fillDown(){Direction=1;}
|
||||||
void fillRight(){Direction=0;}
|
void fillRight(){Direction=0;}
|
||||||
@ -762,8 +768,9 @@ public:
|
|||||||
|
|
||||||
void closeWindow();
|
void closeWindow();
|
||||||
|
|
||||||
|
int popupMenu(int x, int y, const vector<pair<wstring, int>> &menuItems) const;
|
||||||
|
|
||||||
void setDBErrorState(bool state);
|
void setDBErrorState(bool state);
|
||||||
friend int TablesCB(gdioutput *gdi, int type, void *data);
|
|
||||||
friend class Table;
|
friend class Table;
|
||||||
friend gdioutput *createExtraWindow(const string &tag, const wstring &title, int max_x, int max_y, bool fixedSize);
|
friend gdioutput *createExtraWindow(const string &tag, const wstring &title, int max_x, int max_y, bool fixedSize);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -568,8 +568,19 @@ bool InfoCompetitor::synchronize(bool useTotalResults, bool useCourse, oRunner &
|
|||||||
s = r.getTotalStatusInput();
|
s = r.getTotalStatusInput();
|
||||||
}
|
}
|
||||||
else if (t && !isQF && r.getLegNumber() > 0) {
|
else if (t && !isQF && r.getLegNumber() > 0) {
|
||||||
legInput = t->getLegRunningTime(r.getLegNumber() - 1, true, false) * 10;
|
int ltu = r.getLegNumber();
|
||||||
s = t->getLegStatus(r.getLegNumber() - 1, true, false);
|
pClass cls = t->getClassRef(true);
|
||||||
|
if (cls) {
|
||||||
|
LegTypes lt = cls->getLegType(ltu);
|
||||||
|
while (ltu > 0 && (lt == LTParallelOptional || lt == LTParallel|| lt == LTExtra || lt == LTIgnore) ) {
|
||||||
|
ltu--;
|
||||||
|
lt = cls->getLegType(ltu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ltu > 0) {
|
||||||
|
legInput = t->getLegRunningTime(ltu - 1, true, false) * 10;
|
||||||
|
s = t->getLegStatus(ltu - 1, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalStatus != s) {
|
if (totalStatus != s) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -509,6 +509,11 @@ pCourse IOF30Interface::findCourse(gdioutput &gdi,
|
|||||||
|
|
||||||
void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||||
const map<wstring, pCourse> &courses) {
|
const map<wstring, pCourse> &courses) {
|
||||||
|
|
||||||
|
gdi.dropLine();
|
||||||
|
gdi.addString("", 10, "info:teamcourseassignment");
|
||||||
|
gdi.dropLine();
|
||||||
|
|
||||||
vector<pTeam> allT;
|
vector<pTeam> allT;
|
||||||
oe.getTeams(0, allT, false);
|
oe.getTeams(0, allT, false);
|
||||||
|
|
||||||
@ -1394,6 +1399,102 @@ void IOF30Interface::readStartList(gdioutput &gdi, xmlobject &xo, int &entRead,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void IOF30Interface::readResultList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) {
|
||||||
|
string ver;
|
||||||
|
xo.getObjectString("iofVersion", ver);
|
||||||
|
if (!ver.empty() && ver > "3.0")
|
||||||
|
gdi.addString("", 0, "Varning, okänd XML-version X#" + ver);
|
||||||
|
|
||||||
|
map<int, vector<LegInfo> > teamClassConfig;
|
||||||
|
|
||||||
|
xmlobject xEvent = xo.getObject("Event");
|
||||||
|
if (xEvent) {
|
||||||
|
readEvent(gdi, xEvent, teamClassConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlList cResults;
|
||||||
|
xo.getObjects("ClassResult", cResults);
|
||||||
|
|
||||||
|
struct RaceInfo {
|
||||||
|
int courseId;
|
||||||
|
int length;
|
||||||
|
int climb;
|
||||||
|
wstring startName;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (xmlobject &xClassResult : cResults) {
|
||||||
|
|
||||||
|
pClass pc = readClass(xClassResult.getObject("Class"),
|
||||||
|
teamClassConfig);
|
||||||
|
int classId = pc ? pc->getId() : 0;
|
||||||
|
|
||||||
|
map<int, RaceInfo> raceToInfo;
|
||||||
|
|
||||||
|
xmlList courses;
|
||||||
|
xClassResult.getObjects("Course", courses);
|
||||||
|
for (size_t k = 0; k < courses.size(); k++) {
|
||||||
|
int raceNo = courses[k].getObjectInt("raceNumber");
|
||||||
|
if (raceNo > 0)
|
||||||
|
raceNo--;
|
||||||
|
RaceInfo &raceInfo = raceToInfo[raceNo];
|
||||||
|
|
||||||
|
raceInfo.courseId = courses[k].getObjectInt("Id");
|
||||||
|
raceInfo.length = courses[k].getObjectInt("Length");
|
||||||
|
raceInfo.climb = courses[k].getObjectInt("Climb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raceToInfo.size() == 1) {
|
||||||
|
RaceInfo &raceInfo = raceToInfo.begin()->second;
|
||||||
|
if (raceInfo.courseId > 0) {
|
||||||
|
if (pc->getCourse() == 0) {
|
||||||
|
pCourse crs = oe.addCourse(pc->getName(), raceInfo.length, raceInfo.courseId);
|
||||||
|
crs->setStart(raceInfo.startName, false);
|
||||||
|
crs->getDI().setInt("Climb", raceInfo.climb);
|
||||||
|
pc->setCourse(crs);
|
||||||
|
crs->synchronize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (raceToInfo.size() > 1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlList xPResults;
|
||||||
|
xClassResult.getObjects("PersonResult", xPResults);
|
||||||
|
//map<int, pair<wstring, int> > bibPatterns;
|
||||||
|
//oClass::extractBibPatterns(oe, bibPatterns);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < xPResults.size(); k++) {
|
||||||
|
if (readPersonResult(gdi, pc, xPResults[k], 0, teamClassConfig))
|
||||||
|
entRead++;
|
||||||
|
else
|
||||||
|
entFail++;
|
||||||
|
}
|
||||||
|
xmlList tEntries;
|
||||||
|
xClassResult.getObjects("TeamResult", tEntries);
|
||||||
|
for (size_t k = 0; k < tEntries.size(); k++) {
|
||||||
|
//setupClassConfig(classId, tEntries[k], teamClassConfig);
|
||||||
|
entFail++; // Teams not supported
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
//setupRelayClasses(teamClassConfig);
|
||||||
|
if (pc && teamClassConfig.count(pc->getId()) && !teamClassConfig[pc->getId()].empty()) {
|
||||||
|
setupRelayClass(pc, teamClassConfig[pc->getId()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t k = 0; k < tEntries.size(); k++) {
|
||||||
|
if (readTeamStart(gdi, pc, tEntries[k], bibPatterns, teamClassConfig))
|
||||||
|
entRead++;
|
||||||
|
else
|
||||||
|
entFail++;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
pc->synchronize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IOF30Interface::readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) {
|
void IOF30Interface::readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail) {
|
||||||
string ver;
|
string ver;
|
||||||
xo.getObjectString("iofVersion", ver);
|
xo.getObjectString("iofVersion", ver);
|
||||||
@ -2125,6 +2226,180 @@ pRunner IOF30Interface::readPersonStart(gdioutput &gdi, pClass pc, xmlobject &xo
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wstring formatStatus(RunnerStatus st, bool hasTime) {
|
||||||
|
switch (st) {
|
||||||
|
case StatusNoTiming:
|
||||||
|
if (!hasTime)
|
||||||
|
break;
|
||||||
|
case StatusOK:
|
||||||
|
return L"OK";
|
||||||
|
case StatusDNS:
|
||||||
|
return L"DidNotStart";
|
||||||
|
case StatusCANCEL:
|
||||||
|
return L"Cancelled";
|
||||||
|
case StatusMP:
|
||||||
|
return L"MissingPunch";
|
||||||
|
case StatusDNF:
|
||||||
|
return L"DidNotFinish";
|
||||||
|
case StatusDQ:
|
||||||
|
return L"Disqualified";
|
||||||
|
case StatusMAX:
|
||||||
|
return L"OverTime";
|
||||||
|
case StatusOutOfCompetition:
|
||||||
|
if (!hasTime)
|
||||||
|
break;
|
||||||
|
case StatusNotCompetiting:
|
||||||
|
return L"NotCompeting";
|
||||||
|
}
|
||||||
|
return L"Inactive";
|
||||||
|
}
|
||||||
|
|
||||||
|
RunnerStatus parseStatus(const wstring &status) {
|
||||||
|
if (status == L"OK")
|
||||||
|
return StatusOK;
|
||||||
|
else if (status == L"DidNotStart")
|
||||||
|
return StatusDNS;
|
||||||
|
else if (status == L"MissingPunch")
|
||||||
|
return StatusMP;
|
||||||
|
else if (status == L"Cancelled")
|
||||||
|
return StatusCANCEL;
|
||||||
|
else if (status == L"DidNotFinish")
|
||||||
|
return StatusDNF;
|
||||||
|
else if (status == L"Disqualified")
|
||||||
|
return StatusDQ;
|
||||||
|
else if (status == L"OverTime")
|
||||||
|
return StatusMAX;
|
||||||
|
else if (status == L"NotCompeting")
|
||||||
|
return StatusOutOfCompetition;
|
||||||
|
|
||||||
|
return StatusUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRunner IOF30Interface::readPersonResult(gdioutput &gdi, pClass pc, xmlobject &xo, pTeam team,
|
||||||
|
const map<int, vector<LegInfo> > &teamClassConfig) {
|
||||||
|
xmlobject xPers = xo.getObject("Person");
|
||||||
|
pRunner r = 0;
|
||||||
|
if (xPers)
|
||||||
|
r = readPerson(gdi, xPers);
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pc && (r->getClassId(false) == 0 || !r->hasFlag(oAbstractRunner::FlagUpdateClass)))
|
||||||
|
r->setClassId(pc->getId(), true);
|
||||||
|
|
||||||
|
// Club
|
||||||
|
pClub c = readOrganization(gdi, xo.getObject("Organisation"), false);
|
||||||
|
if (!c)
|
||||||
|
c = readOrganization(gdi, xo.getObject("Organization"), false);
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
r->setClubId(c->getId());
|
||||||
|
|
||||||
|
xmlList results;
|
||||||
|
xo.getObjects("Result", results);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < results.size(); k++) {
|
||||||
|
int race = results[k].getObjectInt("raceNumber");
|
||||||
|
pRunner rRace = r;
|
||||||
|
if (race > 1 && r->getNumMulti() > 0) {
|
||||||
|
pRunner rr = r->getMultiRunner(race - 1);
|
||||||
|
if (rr)
|
||||||
|
rRace = rr;
|
||||||
|
}
|
||||||
|
if (rRace) {
|
||||||
|
// Card
|
||||||
|
int cardNo = results[k].getObjectInt("ControlCard");
|
||||||
|
if (cardNo > 0)
|
||||||
|
rRace->setCardNo(cardNo, false);
|
||||||
|
|
||||||
|
wstring bib;
|
||||||
|
results[k].getObjectString("BibNumber", bib);
|
||||||
|
rRace->getDI().setString("Bib", bib);
|
||||||
|
|
||||||
|
xmlobject startTime = results[k].getObject("StartTime");
|
||||||
|
/*
|
||||||
|
if (team) {
|
||||||
|
int leg = starts[k].getObjectInt("Leg");
|
||||||
|
int legorder = starts[k].getObjectInt("LegOrder");
|
||||||
|
int legindex = max(0, leg - 1);
|
||||||
|
map<int, vector<LegInfo> >::const_iterator res = teamClassConfig.find(team->getClassId(false));
|
||||||
|
if (res != teamClassConfig.end()) {
|
||||||
|
legindex = getIndexFromLegPos(leg, legorder, res->second);
|
||||||
|
}
|
||||||
|
team->setRunner(legindex, rRace, false);
|
||||||
|
if (rRace->getClubId() == 0)
|
||||||
|
rRace->setClubId(team->getClubId());
|
||||||
|
|
||||||
|
if (startTime && pc) {
|
||||||
|
pc->setStartType(legindex, STDrawn, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
int st = parseISO8601Time(startTime);
|
||||||
|
rRace->setStartTime(st, true, oBase::ChangeType::Update);
|
||||||
|
|
||||||
|
xmlobject finishTime = results[k].getObject("FinishTime");
|
||||||
|
int ft = parseISO8601Time(finishTime);
|
||||||
|
rRace->setFinishTime(ft);
|
||||||
|
|
||||||
|
wstring status;
|
||||||
|
results[k].getObjectString("Status", status);
|
||||||
|
rRace->setStatus(parseStatus(status), true, oBase::ChangeType::Update);
|
||||||
|
|
||||||
|
xmlList splits;
|
||||||
|
results[k].getObjects("SplitTime", splits);
|
||||||
|
if (!splits.empty()) {
|
||||||
|
pCard card = oe.allocateCard(rRace);
|
||||||
|
card->setCardNo(cardNo);
|
||||||
|
vector<int> controls;
|
||||||
|
wstring s;
|
||||||
|
for (auto &split : splits) {
|
||||||
|
int code = split.getObjectInt("ControlCode");
|
||||||
|
int time = split.getObjectInt("Time");
|
||||||
|
split.getObjectString("status", s);
|
||||||
|
if (s != L"missing")
|
||||||
|
card->addPunch(code, st + time, 0);
|
||||||
|
|
||||||
|
if (s != L"additional")
|
||||||
|
controls.push_back(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ft > 0)
|
||||||
|
card->addPunch(oPunch::PunchFinish, ft, 0);
|
||||||
|
|
||||||
|
//Update to SQL-source
|
||||||
|
card->synchronize();
|
||||||
|
|
||||||
|
if (!controls.empty()) {
|
||||||
|
pCourse c = r->getCourse(true);
|
||||||
|
if (!c)
|
||||||
|
c = oe.addCourse(oe.getAutoCourseName());
|
||||||
|
|
||||||
|
if (c->getNumControls() == 0) {
|
||||||
|
for (int ctrl : controls) {
|
||||||
|
c->addControl(ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->synchronize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc)
|
||||||
|
pc->setCourse(c);
|
||||||
|
else
|
||||||
|
rRace->setCourseId(c->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> mp;
|
||||||
|
rRace->addPunches(card, mp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r->synchronize();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void IOF30Interface::readId(const xmlobject &person, int &pid, __int64 &extId) const {
|
void IOF30Interface::readId(const xmlobject &person, int &pid, __int64 &extId) const {
|
||||||
wstring sid;
|
wstring sid;
|
||||||
pid = 0;
|
pid = 0;
|
||||||
@ -3052,34 +3327,6 @@ void IOF30Interface::writeCourseInfo(xmlparser &xml, const oCourse &c) {
|
|||||||
xml.write("Climb", climb);
|
xml.write("Climb", climb);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring formatStatus(RunnerStatus st, bool hasTime) {
|
|
||||||
switch (st) {
|
|
||||||
case StatusNoTiming:
|
|
||||||
if (!hasTime)
|
|
||||||
break;
|
|
||||||
case StatusOK:
|
|
||||||
return L"OK";
|
|
||||||
case StatusDNS:
|
|
||||||
return L"DidNotStart";
|
|
||||||
case StatusCANCEL:
|
|
||||||
return L"Cancelled";
|
|
||||||
case StatusMP:
|
|
||||||
return L"MissingPunch";
|
|
||||||
case StatusDNF:
|
|
||||||
return L"DidNotFinish";
|
|
||||||
case StatusDQ:
|
|
||||||
return L"Disqualified";
|
|
||||||
case StatusMAX:
|
|
||||||
return L"OverTime";
|
|
||||||
case StatusOutOfCompetition:
|
|
||||||
if (!hasTime)
|
|
||||||
break;
|
|
||||||
case StatusNotCompetiting:
|
|
||||||
return L"NotCompeting";
|
|
||||||
}
|
|
||||||
return L"Inactive";
|
|
||||||
}
|
|
||||||
|
|
||||||
void IOF30Interface::writePersonResult(xmlparser &xml, const oRunner &r,
|
void IOF30Interface::writePersonResult(xmlparser &xml, const oRunner &r,
|
||||||
bool includeCourse, bool teamMember, bool hasInputTime) {
|
bool includeCourse, bool teamMember, bool hasInputTime) {
|
||||||
if (!teamMember)
|
if (!teamMember)
|
||||||
@ -4087,7 +4334,7 @@ pCourse IOF30Interface::readCourse(const xmlobject &xcrs) {
|
|||||||
for (size_t k = 0; k < xControls.size(); k++) {
|
for (size_t k = 0; k < xControls.size(); k++) {
|
||||||
string type;
|
string type;
|
||||||
xControls[k].getObjectString("type", type);
|
xControls[k].getObjectString("type", type);
|
||||||
if (type == "Start") {
|
if (type == "Start" && startName.empty()) {
|
||||||
wstring idStr;
|
wstring idStr;
|
||||||
xControls[k].getObjectString("Control", idStr);
|
xControls[k].getObjectString("Control", idStr);
|
||||||
pControl pStart = oe.getControl(getStartIndex(idStr), false);
|
pControl pStart = oe.getControl(getStartIndex(idStr), false);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -176,6 +176,10 @@ class IOF30Interface {
|
|||||||
map<int, pair<wstring, int> > &bibPatterns,
|
map<int, pair<wstring, int> > &bibPatterns,
|
||||||
const map<int, vector<LegInfo> > &teamClassConfig);
|
const map<int, vector<LegInfo> > &teamClassConfig);
|
||||||
|
|
||||||
|
|
||||||
|
pRunner readPersonResult(gdioutput &gdi, pClass pc, xmlobject &xo, pTeam team,
|
||||||
|
const map<int, vector<LegInfo> > &teamClassConfig);
|
||||||
|
|
||||||
pTeam getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, int expectedClassId, bool &newTeam);
|
pTeam getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, int expectedClassId, bool &newTeam);
|
||||||
|
|
||||||
static int getIndexFromLegPos(int leg, int legorder, const vector<LegInfo> &setup);
|
static int getIndexFromLegPos(int leg, int legorder, const vector<LegInfo> &setup);
|
||||||
@ -310,6 +314,8 @@ public:
|
|||||||
|
|
||||||
void readStartList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
void readStartList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
||||||
|
|
||||||
|
void readResultList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
||||||
|
|
||||||
void readServiceRequestList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
void readServiceRequestList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
||||||
|
|
||||||
void readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
void readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -328,20 +328,28 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
}
|
}
|
||||||
else if (type == GUI_INPUTCHANGE) {
|
else if (type == GUI_INPUTCHANGE) {
|
||||||
InputInfo &ii = *(InputInfo *)(&data);
|
InputInfo &ii = *(InputInfo *)(&data);
|
||||||
bool show = false;
|
if (ii.id == "SearchText") {
|
||||||
if (ii.text.length() > 1) {
|
bool show = false;
|
||||||
vector<AutoCompleteRecord> rec;
|
if (ii.text.length() > 1) {
|
||||||
MetaList::getAutoComplete(ii.text, rec);
|
vector<AutoCompleteRecord> rec;
|
||||||
if (!rec.empty()) {
|
MetaList::getAutoComplete(ii.text, rec);
|
||||||
auto &ac = gdi.addAutoComplete(ii.id);
|
if (!rec.empty()) {
|
||||||
ac.setAutoCompleteHandler(this);
|
auto &ac = gdi.addAutoComplete(ii.id);
|
||||||
ac.setData(rec);
|
ac.setAutoCompleteHandler(this);
|
||||||
ac.show();
|
ac.setData(rec);
|
||||||
show = true;
|
ac.show();
|
||||||
|
show = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!show) {
|
||||||
|
gdi.clearAutoComplete(ii.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!show) {
|
}
|
||||||
gdi.clearAutoComplete(ii.id);
|
else if (type == GUI_INPUT) {
|
||||||
|
InputInfo &ii = *(InputInfo *)(&data);
|
||||||
|
if (ii.id == "Text" && ii.text != lastShownExampleText) {
|
||||||
|
showExample(gdi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == GUI_BUTTON) {
|
else if (type == GUI_BUTTON) {
|
||||||
@ -423,7 +431,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
makeDirty(gdi, MakeDirty, MakeDirty);
|
makeDirty(gdi, MakeDirty, MakeDirty);
|
||||||
show(gdi);
|
show(gdi);
|
||||||
}
|
}
|
||||||
else if ( bi.id == "Remove" ) {
|
else if (bi.id == "Remove") {
|
||||||
DWORD id;
|
DWORD id;
|
||||||
gdi.getData("CurrentId", id);
|
gdi.getData("CurrentId", id);
|
||||||
getPosFromId(id, groupIx, lineIx, ix);
|
getPosFromId(id, groupIx, lineIx, ix);
|
||||||
@ -491,22 +499,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
|
|
||||||
mlp.setColor(GDICOLOR(gdi.getExtraInt("Color")));
|
mlp.setColor(GDICOLOR(gdi.getExtraInt("Color")));
|
||||||
|
|
||||||
if (gdi.isChecked("UseLeg")) {
|
int leg = readLeg(gdi, newType, true);
|
||||||
int leg = gdi.getTextNo("Leg");
|
mlp.setLeg(leg);
|
||||||
if (newType == lResultModuleNumber || newType == lResultModuleTime ||
|
|
||||||
newType == lResultModuleNumberTeam || newType == lResultModuleTimeTeam) {
|
|
||||||
if (leg < 0 || leg > 1000)
|
|
||||||
throw meosException("X är inget giltigt index#" + itos(leg));
|
|
||||||
mlp.setLeg(leg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (leg < 1 || leg > 1000)
|
|
||||||
throw meosException("X är inget giltigt sträcknummer#" + itos(leg));
|
|
||||||
mlp.setLeg(leg - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mlp.setLeg(-1);
|
|
||||||
|
|
||||||
if (gdi.hasWidget("UseResultModule") && gdi.isChecked("UseResultModule"))
|
if (gdi.hasWidget("UseResultModule") && gdi.isChecked("UseResultModule"))
|
||||||
mlp.setResultModule(currentList->getResultModule());
|
mlp.setResultModule(currentList->getResultModule());
|
||||||
@ -625,8 +619,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
if (fileName.empty()) {
|
if (fileName.empty()) {
|
||||||
int ix = 0;
|
int ix = 0;
|
||||||
vector< pair<wstring, wstring> > ext;
|
vector< pair<wstring, wstring> > ext;
|
||||||
ext.push_back(make_pair(L"xml-data", L"*.xml"));
|
ext.push_back(make_pair(L"List definition", L"*.meoslist"));
|
||||||
fileName = gdi.browseForSave(ext, L"xml", ix);
|
fileName = gdi.browseForSave(ext, L"meoslist", ix);
|
||||||
if (fileName.empty())
|
if (fileName.empty())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -643,8 +637,8 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vector< pair<wstring, wstring> > ext;
|
vector< pair<wstring, wstring> > ext;
|
||||||
ext.push_back(make_pair(L"xml-data", L"*.xml"));
|
ext.push_back(make_pair(L"List definition", L"*.meoslist;*.xml"));
|
||||||
wstring fileName = gdi.browseForOpen(ext, L"xml");
|
wstring fileName = gdi.browseForOpen(ext, L"meoslist");
|
||||||
if (fileName.empty())
|
if (fileName.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -822,18 +816,55 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
|||||||
else if (type==GUI_CLEAR) {
|
else if (type==GUI_CLEAR) {
|
||||||
return checkSave(gdi);
|
return checkSave(gdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ListEditor::readLeg(gdioutput &gdi, EPostType newType, bool checkError) const {
|
||||||
|
if (MetaList::isResultModuleOutput(newType)) {
|
||||||
|
int leg = gdi.getTextNo("Leg");
|
||||||
|
if (leg < 0 || leg > 1000) {
|
||||||
|
if (checkError)
|
||||||
|
throw meosException("X är inget giltigt index#" + itos(leg));
|
||||||
|
else
|
||||||
|
leg = -1;
|
||||||
|
}
|
||||||
|
return leg;
|
||||||
|
}
|
||||||
|
else if (MetaList::isAllStageType(newType)) {
|
||||||
|
int leg = gdi.getSelectedItem("LegSel").first;
|
||||||
|
if (leg >= 1)
|
||||||
|
return leg - 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (gdi.isChecked("UseLeg")) {
|
||||||
|
int leg = gdi.getTextNo("Leg");
|
||||||
|
if (leg < 1 || leg > 1000) {
|
||||||
|
if (checkError)
|
||||||
|
throw meosException("X är inget giltigt sträcknummer#" + itos(leg));
|
||||||
|
else
|
||||||
|
leg = -1;
|
||||||
|
}
|
||||||
|
return leg - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ListEditor::updateType(int iType, gdioutput & gdi) {
|
void ListEditor::updateType(int iType, gdioutput & gdi) {
|
||||||
EPostType type = EPostType(iType);
|
EPostType type = EPostType(iType);
|
||||||
gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true);
|
int leg = -1;
|
||||||
if (type == lResultModuleNumber || type == lResultModuleTime ||
|
if (gdi.hasWidget("leg"))
|
||||||
type == lResultModuleNumberTeam || type == lResultModuleTimeTeam) {
|
leg = gdi.getTextNo("Leg");
|
||||||
gdi.check("UseLeg", true);
|
|
||||||
gdi.disableInput("UseLeg");
|
|
||||||
|
|
||||||
|
gdi.restore("Example", false);
|
||||||
|
|
||||||
|
if (legStageTypeIndex(gdi, type, leg)) {
|
||||||
|
gdi.setRestorePoint("Example");
|
||||||
|
}
|
||||||
|
if (MetaList::isResultModuleOutput(type)) {
|
||||||
if (gdi.hasWidget("UseResultModule")) {
|
if (gdi.hasWidget("UseResultModule")) {
|
||||||
gdi.check("UseResultModule", true);
|
gdi.check("UseResultModule", true);
|
||||||
gdi.disableInput("UseResultModule");
|
gdi.disableInput("UseResultModule");
|
||||||
@ -841,10 +872,12 @@ void ListEditor::updateType(int iType, gdioutput & gdi) {
|
|||||||
gdi.enableInput("Leg");
|
gdi.enableInput("Leg");
|
||||||
if (gdi.getText("Leg").empty())
|
if (gdi.getText("Leg").empty())
|
||||||
gdi.setText("Leg", L"0");
|
gdi.setText("Leg", L"0");
|
||||||
|
}
|
||||||
|
else if (MetaList::isAllStageType(type)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gdi.enableInput("UseLeg");
|
if (leg == 0) {
|
||||||
if (gdi.getTextNo("Leg") == 0) {
|
|
||||||
gdi.setText("Leg", L"");
|
gdi.setText("Leg", L"");
|
||||||
gdi.enableInput("UseLeg");
|
gdi.enableInput("UseLeg");
|
||||||
gdi.enableInput("UseResultModule", true);
|
gdi.enableInput("UseResultModule", true);
|
||||||
@ -853,10 +886,7 @@ void ListEditor::updateType(int iType, gdioutput & gdi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gdi.restore("Example", false);
|
showExample(gdi, type);
|
||||||
int margin = gdi.scaleLength(10);
|
|
||||||
showExample(gdi, margin, type);
|
|
||||||
gdi.refreshFast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListEditor::checkUnsaved(gdioutput &gdi) {
|
void ListEditor::checkUnsaved(gdioutput &gdi) {
|
||||||
@ -886,10 +916,8 @@ void ListEditor::updateAlign(gdioutput &gdi, int val) {
|
|||||||
|
|
||||||
gdi.setInputStatus("Color", val != 1);
|
gdi.setInputStatus("Color", val != 1);
|
||||||
gdi.setInputStatus("Fonts", val != 1);
|
gdi.setInputStatus("Fonts", val != 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||||
checkUnsaved(gdi);
|
checkUnsaved(gdi);
|
||||||
gdi.restore("EditList", false);
|
gdi.restore("EditList", false);
|
||||||
@ -918,7 +946,10 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
if (ix + 1 == currentList->getNumPostsOnLine(groupIx, lineIx))
|
if (ix + 1 == currentList->getNumPostsOnLine(groupIx, lineIx))
|
||||||
gdi.setInputStatus("MoveRight", false);
|
gdi.setInputStatus("MoveRight", false);
|
||||||
|
|
||||||
gdi.dropLine(3);
|
gdi.dropLine(1);
|
||||||
|
int boxY = gdi.getCY();
|
||||||
|
gdi.dropLine(2);
|
||||||
|
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
vector< pair<wstring, size_t> > types;
|
vector< pair<wstring, size_t> > types;
|
||||||
int currentType;
|
int currentType;
|
||||||
@ -940,7 +971,6 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
|
|
||||||
sort(types.begin(), types.end());
|
sort(types.begin(), types.end());
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
int boxY = gdi.getCY();
|
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
gdi.addString("", 0, L"Typ:");
|
gdi.addString("", 0, L"Typ:");
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
@ -958,7 +988,8 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
gdi.dropLine(-1);
|
gdi.dropLine(-1);
|
||||||
gdi.addItem("Type", types);
|
gdi.addItem("Type", types);
|
||||||
gdi.selectItemByData("Type", currentType);
|
gdi.selectItemByData("Type", currentType);
|
||||||
gdi.addInput("Text", mlp.getText(), 16, 0, L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data.");
|
gdi.addInput("Text", mlp.getText(), 16, editListCB,
|
||||||
|
L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data.");
|
||||||
gdi.setInputFocus("Text", true);
|
gdi.setInputFocus("Text", true);
|
||||||
((InputInfo *)gdi.setText("SearchText", getSearchString()))->setFgColor(colorGreyBlue);
|
((InputInfo *)gdi.setText("SearchText", getSearchString()))->setFgColor(colorGreyBlue);
|
||||||
int boxX = gdi.getCX();
|
int boxX = gdi.getCX();
|
||||||
@ -972,21 +1003,28 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
gdi.popX();
|
gdi.popX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xpUseLeg = gdi.getCX();
|
||||||
|
ypUseLeg = gdi.getCY();
|
||||||
|
|
||||||
int leg = mlp.getLeg();
|
int leg = mlp.getLeg();
|
||||||
gdi.addCheckbox("UseLeg", getIndexDescription(storedType), editListCB, leg != -1);
|
|
||||||
gdi.dropLine(-0.2);
|
legStageTypeIndex(gdi, storedType, leg);
|
||||||
gdi.setCX(gdi.getCX() + gdi.getLineHeight() * 5);
|
/*gdi.addCheckbox(xpUseLeg, ypUseLeg, "UseLeg", getIndexDescription(storedType), editListCB, leg != -1);
|
||||||
if (storedType == lResultModuleNumber || storedType == lResultModuleTime || storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam)
|
//gdi.dropLine(-0.2);
|
||||||
gdi.addInput("Leg", leg >= 0 ? itow(leg) : L"0", 4);
|
int dx = gdi.scaleLength(250);
|
||||||
|
int dy = -gdi.getLineHeight() / 5;
|
||||||
|
|
||||||
|
//gdi.setCX(gdi.getCX() + gdi.scaleLength(100));
|
||||||
|
if (MetaList::isResultModuleOutput(storedType))
|
||||||
|
gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", leg >= 0 ? itow(leg) : L"0", 4);
|
||||||
else
|
else
|
||||||
gdi.addInput("Leg", leg >= 0 ? itow(leg + 1) : L"", 4);
|
gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", leg >= 0 ? itow(leg + 1) : L"", 4);
|
||||||
|
|
||||||
gdi.enableInput("Leg", leg != -1);
|
gdi.setInputStatus("Leg", leg != -1);
|
||||||
|
*/
|
||||||
if (storedType == lResultModuleNumber || storedType == lResultModuleTime ||
|
if (MetaList::isResultModuleOutput(storedType)) {
|
||||||
storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam) {
|
//gdi.check("UseLeg", true);
|
||||||
gdi.check("UseLeg", true);
|
//gdi.disableInput("UseLeg");
|
||||||
gdi.disableInput("UseLeg");
|
|
||||||
if (gdi.hasWidget("UseResultModule")) {
|
if (gdi.hasWidget("UseResultModule")) {
|
||||||
gdi.check("UseResultModule", true);
|
gdi.check("UseResultModule", true);
|
||||||
gdi.disableInput("UseResultModule");
|
gdi.disableInput("UseResultModule");
|
||||||
@ -1023,10 +1061,13 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
int maxY = gdi.getCY();
|
int maxY = gdi.getCY();
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
|
int innerBoxUpperCX = boxX + gdi.scaleLength(18);
|
||||||
|
int innerBoxUpperCY = boxY;
|
||||||
|
|
||||||
gdi.setCX(boxX + gdi.scaleLength(24));
|
gdi.setCX(boxX + gdi.scaleLength(24));
|
||||||
gdi.setCY(boxY);
|
gdi.setCY(boxY + gdi.scaleLength(6));
|
||||||
gdi.pushX();
|
gdi.pushX();
|
||||||
gdi.addString("", 1, "Formateringsregler");
|
gdi.addString("", fontMediumPlus, "Formateringsregler");
|
||||||
gdi.dropLine(0.5);
|
gdi.dropLine(0.5);
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
int val = 0;
|
int val = 0;
|
||||||
@ -1069,10 +1110,15 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
gdi.dropLine();
|
gdi.dropLine();
|
||||||
gdi.addButton("Color", "Färg...", editListCB).setExtra(mlp.getColorValue());
|
gdi.addButton("Color", "Färg...", editListCB).setExtra(mlp.getColorValue());
|
||||||
|
|
||||||
|
|
||||||
maxX = max(maxX, gdi.getCX());
|
maxX = max(maxX, gdi.getCX());
|
||||||
gdi.popX();
|
int innerBoxLowerCX = maxX + gdi.scaleLength(6);
|
||||||
|
maxX += gdi.scaleLength(12);
|
||||||
|
|
||||||
|
gdi.setCX(boxX - gdi.scaleLength(6));
|
||||||
gdi.dropLine(3);
|
gdi.dropLine(3);
|
||||||
|
int innerBoxLowerCY = gdi.getCY();
|
||||||
|
|
||||||
|
gdi.dropLine();
|
||||||
|
|
||||||
gdi.setData("CurrentId", id);
|
gdi.setData("CurrentId", id);
|
||||||
gdi.addButton("Remove", "Radera", editListCB, "Ta bort listposten");
|
gdi.addButton("Remove", "Radera", editListCB, "Ta bort listposten");
|
||||||
@ -1086,29 +1132,63 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
|||||||
maxX = max(gdi.getCX(), maxX);
|
maxX = max(gdi.getCX(), maxX);
|
||||||
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|
||||||
rc.top = y1;
|
rc.top = y1;
|
||||||
rc.left = x1;
|
rc.left = x1;
|
||||||
rc.right = maxX + gdi.scaleLength(6);
|
rc.right = maxX + gdi.scaleLength(6);
|
||||||
rc.bottom = maxY + gdi.scaleLength(6) + gdi.getLineHeight()*4;
|
rc.bottom = maxY + gdi.scaleLength(6) + gdi.getLineHeight()*4;
|
||||||
|
|
||||||
gdi.addRectangle(rc, colorLightBlue, true);
|
gdi.addRectangle(rc, colorLightBlue, true, false);
|
||||||
|
|
||||||
|
rc.top = innerBoxUpperCY;
|
||||||
|
rc.left = innerBoxUpperCX;
|
||||||
|
rc.right = innerBoxLowerCX;
|
||||||
|
rc.bottom = innerBoxLowerCY;
|
||||||
|
|
||||||
|
gdi.addRectangle(rc, colorLightYellow, true, false);
|
||||||
|
|
||||||
gdi.setData("IsEditing", 1);
|
gdi.setData("IsEditing", 1);
|
||||||
gdi.setCX(x1);
|
gdi.setCX(x1);
|
||||||
gdi.setCY(maxY);
|
gdi.setCY(maxY);
|
||||||
|
|
||||||
showExample(gdi, margin, mlp);
|
gdi.scrollToBottom();
|
||||||
|
|
||||||
|
showExample(gdi, mlp);
|
||||||
|
|
||||||
updateAlign(gdi, val);
|
updateAlign(gdi, val);
|
||||||
gdi.scrollToBottom();
|
|
||||||
gdi.refresh();
|
gdi.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp) {
|
void ListEditor::showExample(gdioutput &gdi, EPostType type) {
|
||||||
|
if (type == EPostType::lLastItem) {
|
||||||
|
type = EPostType(gdi.getSelectedItem("Type").first);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdi.restore("Example", false);
|
||||||
|
|
||||||
|
MetaListPost mlp(type);
|
||||||
|
// Has not effect
|
||||||
|
//mlp.setLeg(readLeg(gdi, type, false));
|
||||||
|
mlp.setText(gdi.getText("Text", false));
|
||||||
|
showExample(gdi, mlp);
|
||||||
|
gdi.refreshFast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListEditor::showExample(gdioutput &gdi, const MetaListPost &mlp) {
|
||||||
int x1 = gdi.getCX();
|
int x1 = gdi.getCX();
|
||||||
|
int margin = gdi.scaleLength(10);
|
||||||
|
|
||||||
RECT rrInner;
|
RECT rrInner;
|
||||||
rrInner.left = x1 + margin;
|
rrInner.left = x1 + margin;
|
||||||
rrInner.top = gdi.getCY();
|
rrInner.top = gdi.getCY();
|
||||||
|
bool hasSymbol;
|
||||||
|
lastShownExampleText = mlp.getText();
|
||||||
|
GDICOLOR color = GDICOLOR::colorLightGreen;
|
||||||
|
wstring text = MetaList::encode(mlp.getTypeRaw(), lastShownExampleText, hasSymbol);
|
||||||
|
if (!hasSymbol) {
|
||||||
|
text = lang.tl("Fel: Använd X i texten där värdet (Y) ska sättas in.#X#%s");
|
||||||
|
color = GDICOLOR::colorLightRed;
|
||||||
|
}
|
||||||
|
|
||||||
gdi.setRestorePoint("Example");
|
gdi.setRestorePoint("Example");
|
||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
@ -1127,6 +1207,12 @@ void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp
|
|||||||
wstring s = oe->formatListString(mlp.getTypeRaw(), rr[i]);
|
wstring s = oe->formatListString(mlp.getTypeRaw(), rr[i]);
|
||||||
if (used.insert(s).second) {
|
if (used.insert(s).second) {
|
||||||
int xb = gdi.getCX();
|
int xb = gdi.getCX();
|
||||||
|
if (!text.empty()) {
|
||||||
|
wchar_t st[300];
|
||||||
|
swprintf_s(st, text.c_str(), s.c_str());
|
||||||
|
s = st;
|
||||||
|
}
|
||||||
|
|
||||||
gdi.addStringUT(italicText, s + L" ");
|
gdi.addStringUT(italicText, s + L" ");
|
||||||
int xa = gdi.getCX();
|
int xa = gdi.getCX();
|
||||||
int delta = xa - xb;
|
int delta = xa - xb;
|
||||||
@ -1142,7 +1228,7 @@ void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp
|
|||||||
gdi.fillDown();
|
gdi.fillDown();
|
||||||
gdi.popX();
|
gdi.popX();
|
||||||
|
|
||||||
gdi.addRectangle(rrInner, colorLightGreen, true);
|
gdi.addRectangle(rrInner, color, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t *ListEditor::getIndexDescription(EPostType type) {
|
const wchar_t *ListEditor::getIndexDescription(EPostType type) {
|
||||||
@ -1150,10 +1236,88 @@ const wchar_t *ListEditor::getIndexDescription(EPostType type) {
|
|||||||
return L"Index in X[index]#OutputTimes";
|
return L"Index in X[index]#OutputTimes";
|
||||||
else if (type == lResultModuleNumber || type == lResultModuleNumberTeam)
|
else if (type == lResultModuleNumber || type == lResultModuleNumberTeam)
|
||||||
return L"Index in X[index]#OutputNumbers";
|
return L"Index in X[index]#OutputNumbers";
|
||||||
|
else if (MetaList::isAllStageType(type))
|
||||||
|
return L"Applicera för specifik etapp:";
|
||||||
else
|
else
|
||||||
return L"Applicera för specifik sträcka:";
|
return L"Applicera för specifik sträcka:";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ListEditor::legStageTypeIndex(gdioutput &gdi, EPostType type, int leg) {
|
||||||
|
int dx = gdi.scaleLength(250);
|
||||||
|
int dy = -gdi.getLineHeight() / 5;
|
||||||
|
|
||||||
|
if (MetaList::isResultModuleOutput(type)) {
|
||||||
|
if (gdi.hasWidget("UseLeg"))
|
||||||
|
gdi.removeWidget("UseLeg");
|
||||||
|
|
||||||
|
if (gdi.hasWidget("LegSel"))
|
||||||
|
gdi.removeWidget("LegSel");
|
||||||
|
|
||||||
|
if (gdi.hasWidget("TUseLeg"))
|
||||||
|
gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true);
|
||||||
|
else
|
||||||
|
gdi.addString("TUseLeg", ypUseLeg, xpUseLeg, 0, getIndexDescription(type));
|
||||||
|
|
||||||
|
wstring legW = leg >= 0 ? itow(leg) : L"0";
|
||||||
|
if (!gdi.hasWidget("Leg"))
|
||||||
|
gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", legW, 4, editListCB);
|
||||||
|
else {
|
||||||
|
if (gdi.getText("Leg").empty())
|
||||||
|
gdi.setText("Leg", legW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (MetaList::isAllStageType(type)) {
|
||||||
|
if (gdi.hasWidget("UseLeg"))
|
||||||
|
gdi.removeWidget("UseLeg");
|
||||||
|
|
||||||
|
if (gdi.hasWidget("Leg"))
|
||||||
|
gdi.removeWidget("Leg");
|
||||||
|
|
||||||
|
if (gdi.hasWidget("TUseLeg"))
|
||||||
|
gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true);
|
||||||
|
else
|
||||||
|
gdi.addString("TUseLeg", ypUseLeg, xpUseLeg, 0, getIndexDescription(type));
|
||||||
|
|
||||||
|
if (!gdi.hasWidget("LegSel")) {
|
||||||
|
gdi.addSelection(xpUseLeg + dx, ypUseLeg + dy, "LegSel", 160, gdi.scaleLength(300), editListCB);
|
||||||
|
vector<pair<wstring, size_t>> items;
|
||||||
|
items.emplace_back(lang.tl("Alla tidigare etapper"), -2);
|
||||||
|
for (int j = 1; j < 20; j++) {
|
||||||
|
items.emplace_back(lang.tl("Etapp X#" + itos(j)), j);
|
||||||
|
}
|
||||||
|
gdi.addItem("LegSel", items);
|
||||||
|
gdi.selectItemByData("LegSel", leg >= 0 ? leg + 1 : -2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (gdi.hasWidget("LegSel"))
|
||||||
|
gdi.removeWidget("LegSel");
|
||||||
|
|
||||||
|
if (!gdi.hasWidget("UseLeg")) {
|
||||||
|
if (gdi.hasWidget("TUseLeg"))
|
||||||
|
gdi.removeWidget("TUseLeg");
|
||||||
|
|
||||||
|
gdi.addCheckbox(xpUseLeg, ypUseLeg, "UseLeg", getIndexDescription(type), editListCB, leg != -1);
|
||||||
|
|
||||||
|
wstring ix = leg >= 0 ? itow(leg + 1) : L"";
|
||||||
|
if (!gdi.hasWidget("Leg"))
|
||||||
|
gdi.addInput(xpUseLeg + dx, ypUseLeg + dy, "Leg", ix, 4, editListCB);
|
||||||
|
else {
|
||||||
|
int leg = gdi.getTextNo("Leg");
|
||||||
|
gdi.setText("Leg", ix);
|
||||||
|
}
|
||||||
|
gdi.setInputStatus("Leg", leg != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (MetaList::isResultModuleOutput(type)) {
|
||||||
|
gdi.check("UseLeg", true);
|
||||||
|
gdi.disableInput("UseLeg");
|
||||||
|
}*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ListEditor::editListProp(gdioutput &gdi, bool newList) {
|
void ListEditor::editListProp(gdioutput &gdi, bool newList) {
|
||||||
checkUnsaved(gdi);
|
checkUnsaved(gdi);
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -34,6 +34,7 @@ class TabBase;
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "autocompletehandler.h"
|
#include "autocompletehandler.h"
|
||||||
|
#include "oListInfo.h"
|
||||||
|
|
||||||
class ListEditor : public AutoCompleteHandler {
|
class ListEditor : public AutoCompleteHandler {
|
||||||
private:
|
private:
|
||||||
@ -47,7 +48,7 @@ private:
|
|||||||
bool dirtyInt;
|
bool dirtyInt;
|
||||||
SaveType lastSaved;
|
SaveType lastSaved;
|
||||||
const wchar_t *getIndexDescription(EPostType type);
|
const wchar_t *getIndexDescription(EPostType type);
|
||||||
|
wstring lastShownExampleText;
|
||||||
void showLine(gdioutput &gdi, const vector<MetaListPost> &line, int ix) const;
|
void showLine(gdioutput &gdi, const vector<MetaListPost> &line, int ix) const;
|
||||||
int editList(gdioutput &gdi, int type, BaseInfo &data);
|
int editList(gdioutput &gdi, int type, BaseInfo &data);
|
||||||
void updateType(int iType, gdioutput &gdi);
|
void updateType(int iType, gdioutput &gdi);
|
||||||
@ -56,7 +57,12 @@ private:
|
|||||||
int lineIx, int ix) const;
|
int lineIx, int ix) const;
|
||||||
|
|
||||||
void editListPost(gdioutput &gdi, const MetaListPost &mlp, int id);
|
void editListPost(gdioutput &gdi, const MetaListPost &mlp, int id);
|
||||||
void showExample(gdioutput &gdi, int margin, const MetaListPost &mlp);
|
|
||||||
|
void showExample(gdioutput &gdi, EPostType type = EPostType::lLastItem);
|
||||||
|
|
||||||
|
void showExample(gdioutput &gdi, const MetaListPost &mlp);
|
||||||
|
|
||||||
|
int readLeg(gdioutput &gdi, EPostType newType, bool checkError) const;
|
||||||
|
|
||||||
void editListProp(gdioutput &gdi, bool newList);
|
void editListProp(gdioutput &gdi, bool newList);
|
||||||
|
|
||||||
@ -78,6 +84,12 @@ private:
|
|||||||
TabBase *origin = nullptr;
|
TabBase *origin = nullptr;
|
||||||
void show(gdioutput &gdi);
|
void show(gdioutput &gdi);
|
||||||
|
|
||||||
|
int xpUseLeg;
|
||||||
|
int ypUseLeg;
|
||||||
|
|
||||||
|
bool legStageTypeIndex(gdioutput &gdi, EPostType type, int leg);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ListEditor(oEvent *oe);
|
ListEditor(oEvent *oe);
|
||||||
virtual ~ListEditor();
|
virtual ~ListEditor();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/********************i****************************************************
|
/********************i****************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
202
code/machinecontainer.cpp
Normal file
202
code/machinecontainer.cpp
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "machinecontainer.h"
|
||||||
|
#include "meos_util.h"
|
||||||
|
#include "xmlparser.h"
|
||||||
|
#include "gdioutput.h"
|
||||||
|
int MachineContainer::AbstractMachine::getInt(const string &v) const {
|
||||||
|
return _wtoi(getString(v).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const wstring &MachineContainer::AbstractMachine::getString(const string &v) const {
|
||||||
|
auto res = props.find(v);
|
||||||
|
if (res != props.end())
|
||||||
|
return res->second;
|
||||||
|
return _EmptyWString;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> MachineContainer::AbstractMachine::getVectorInt(const string &v) const {
|
||||||
|
auto &s = getString(v);
|
||||||
|
vector<wstring> sp;
|
||||||
|
split(s, L",", sp);
|
||||||
|
vector<int> res(sp.size());
|
||||||
|
for (int j = 0; j < sp.size(); j++)
|
||||||
|
res[j] = _wtoi(sp[j].c_str());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
set<int> MachineContainer::AbstractMachine::getSetInt(const string &v) const {
|
||||||
|
std::set<int> res;
|
||||||
|
for (int i : getVectorInt(v)) {
|
||||||
|
res.insert(i);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::set(const string &name, int v) {
|
||||||
|
if (v != 0)
|
||||||
|
props[name] = itow(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::set(const string &name, const vector<int> &v) {
|
||||||
|
wstring &r = props[name];
|
||||||
|
for (int j = 0; j < v.size(); j++) {
|
||||||
|
if (j == 0)
|
||||||
|
r = itow(v[j]);
|
||||||
|
else
|
||||||
|
r += L"," + itow(v[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::load(const xmlobject &data) {
|
||||||
|
xmlList out;
|
||||||
|
data.getObjects(out);
|
||||||
|
for (auto &x : out) {
|
||||||
|
props[x.getName()] = x.getw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::save(xmlparser &data) const {
|
||||||
|
for (auto &p : props) {
|
||||||
|
data.write(p.first.c_str(), p.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
string encode(const string &in) {
|
||||||
|
string out;
|
||||||
|
out.reserve(in.length());
|
||||||
|
for (int j = 0; j < in.length(); j++) {
|
||||||
|
if (in[j] == '|' || in[j] == '$' || in[j] == '%') {
|
||||||
|
out.push_back('%');
|
||||||
|
if (in[j] == '|')
|
||||||
|
out.push_back('1');
|
||||||
|
else if (in[j] == '$')
|
||||||
|
out.push_back('2');
|
||||||
|
else if (in[j] == '%')
|
||||||
|
out.push_back('3');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out.push_back(in[j]);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
string decode(const string &in) {
|
||||||
|
string out;
|
||||||
|
out.reserve(in.length());
|
||||||
|
for (int j = 0; j < in.length(); j++) {
|
||||||
|
if (in[j] == '%') {
|
||||||
|
j++;
|
||||||
|
if (j < in.length()) {
|
||||||
|
if (in[j] == '1')
|
||||||
|
out.push_back('|');
|
||||||
|
else if (in[j] == '2')
|
||||||
|
out.push_back('§');
|
||||||
|
else if (in[j] == '3')
|
||||||
|
out.push_back('%');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out.push_back(in[j]);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::load(const string &data) {
|
||||||
|
vector<string> parts;
|
||||||
|
split(data, "|", parts);
|
||||||
|
for (int j = 0; j < parts.size(); j+=2) {
|
||||||
|
const wstring &w = gdioutput::fromUTF8(decode(parts[j + 1]));
|
||||||
|
props[parts[j]] = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string MachineContainer::AbstractMachine::save() const {
|
||||||
|
string out;
|
||||||
|
for (auto &p : props) {
|
||||||
|
if (!out.empty())
|
||||||
|
out += "|";
|
||||||
|
out.append(p.first);
|
||||||
|
out += "|";
|
||||||
|
out.append(encode(gdioutput::toUTF8(p.second)));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::AbstractMachine::set(const string &name, const wstring &v) {
|
||||||
|
if (!v.empty())
|
||||||
|
props[name] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<pair<string, wstring>> MachineContainer::enumerate() const {
|
||||||
|
vector<pair<string, wstring>> res;
|
||||||
|
for (auto v : machines)
|
||||||
|
res.push_back(v.first);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::load(const xmlobject &data) {
|
||||||
|
xmlList out;
|
||||||
|
data.getObjects("Machine", out);
|
||||||
|
|
||||||
|
for (auto &m : out) {
|
||||||
|
string type;
|
||||||
|
wstring tag;
|
||||||
|
m.getObjectString("type", type);
|
||||||
|
m.getObjectString("name", tag);
|
||||||
|
if (!type.empty() && !tag.empty()) {
|
||||||
|
auto res = machines.emplace(make_pair(type, tag), MachineContainer::AbstractMachine());
|
||||||
|
if (res.second)
|
||||||
|
res.first->second.load(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::save(xmlparser &data) {
|
||||||
|
for (auto &m : machines) {
|
||||||
|
vector<wstring> p({ wstring(L"type"), gdioutput::widen(m.first.first),
|
||||||
|
wstring(L"name"), m.first.second });
|
||||||
|
data.startTag("Machine", p);
|
||||||
|
m.second.save(data);
|
||||||
|
data.endTag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineContainer::load(const string &data) {
|
||||||
|
vector<string> parts;
|
||||||
|
split(data, "$", parts);
|
||||||
|
for (int j = 0; j + 2 < parts.size(); j++) {
|
||||||
|
const string &type = parts[j];
|
||||||
|
wstring tag = gdioutput::fromUTF8(decode(parts[j + 1]));
|
||||||
|
auto res = machines.emplace(make_pair(type, tag), MachineContainer::AbstractMachine());
|
||||||
|
if (res.second)
|
||||||
|
res.first->second.load(parts[j+2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string MachineContainer::save() {
|
||||||
|
vector<string> ml;
|
||||||
|
ml.reserve(machines.size() * 3);
|
||||||
|
size_t tSize = 0;
|
||||||
|
for (auto &m : machines) {
|
||||||
|
ml.push_back(m.first.first);
|
||||||
|
tSize += ml.back().length() + 2;
|
||||||
|
ml.push_back(encode(gdioutput::toUTF8(m.first.second)));
|
||||||
|
tSize += ml.back().length() + 2;
|
||||||
|
ml.push_back(m.second.save());
|
||||||
|
tSize += ml.back().length() + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
string out;
|
||||||
|
out.reserve(tSize);
|
||||||
|
|
||||||
|
for (const string & m : ml) {
|
||||||
|
if (!out.empty())
|
||||||
|
out.append("$");
|
||||||
|
out.append(m);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
79
code/machinecontainer.h
Normal file
79
code/machinecontainer.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class xmlparser;
|
||||||
|
class xmlobject;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class MachineContainer {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class AbstractMachine {
|
||||||
|
map<string, wstring> props;
|
||||||
|
public:
|
||||||
|
void clear() {
|
||||||
|
props.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getInt(const string &v) const;
|
||||||
|
const wstring &getString(const string &v) const;
|
||||||
|
vector<int> getVectorInt(const string &v) const;
|
||||||
|
set<int> getSetInt(const string &v) const;
|
||||||
|
|
||||||
|
void set(const string &name, int v);
|
||||||
|
void set(const string &name, const vector<int> &v);
|
||||||
|
void set(const string &name, const wstring &v);
|
||||||
|
void set(const string &name, bool v) {
|
||||||
|
set(name, int(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void set(const string &name, const T &v) {
|
||||||
|
vector<int> vv;
|
||||||
|
for (auto x : v)
|
||||||
|
vv.push_back(x);
|
||||||
|
set(name, vv);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void load(const xmlobject &data);
|
||||||
|
void load(const string &data);
|
||||||
|
void save(xmlparser &data) const;
|
||||||
|
string save() const;
|
||||||
|
friend class MachineContainer;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
map<pair<string, wstring>, AbstractMachine> machines;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const AbstractMachine *get(const string &type, const wstring &name) const {
|
||||||
|
auto res = machines.find(make_pair(type, name));
|
||||||
|
if (res != machines.end())
|
||||||
|
return &res->second;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(const string &type, const wstring &name) {
|
||||||
|
machines.erase(make_pair(type, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractMachine &set(const string &type, const wstring &name) {
|
||||||
|
auto &m = machines[make_pair(type, name)];
|
||||||
|
m.clear();
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<pair<string, wstring>> enumerate() const;
|
||||||
|
|
||||||
|
void load(const xmlobject &data);
|
||||||
|
void save(xmlparser &data);
|
||||||
|
void load(const string &data);
|
||||||
|
string save();
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -294,7 +294,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileExist(settings)) {
|
if (fileExists(settings)) {
|
||||||
gEvent->loadProperties(settings);
|
gEvent->loadProperties(settings);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -314,13 +314,13 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
|||||||
lang.get().addLangResource(L"Español", L"111");
|
lang.get().addLangResource(L"Español", L"111");
|
||||||
lang.get().addLangResource(L"Russian", L"107");
|
lang.get().addLangResource(L"Russian", L"107");
|
||||||
|
|
||||||
if (fileExist(L"extra.lng")) {
|
if (fileExists(L"extra.lng")) {
|
||||||
lang.get().addLangResource(L"Extraspråk", L"extra.lng");
|
lang.get().addLangResource(L"Extraspråk", L"extra.lng");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wchar_t lpath[260];
|
wchar_t lpath[260];
|
||||||
getUserFile(lpath, L"extra.lng");
|
getUserFile(lpath, L"extra.lng");
|
||||||
if (fileExist(lpath))
|
if (fileExists(lpath))
|
||||||
lang.get().addLangResource(L"Extraspråk", lpath);
|
lang.get().addLangResource(L"Extraspråk", lpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +479,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
|||||||
// Main message loop:
|
// Main message loop:
|
||||||
mainMessageLoop(hAccelTable, 0);
|
mainMessageLoop(hAccelTable, 0);
|
||||||
|
|
||||||
tabAutoRegister(0);
|
TabAuto::tabAutoRegister(nullptr);
|
||||||
tabList->clear();
|
tabList->clear();
|
||||||
delete tabList;
|
delete tabList;
|
||||||
tabList = nullptr;
|
tabList = nullptr;
|
||||||
@ -730,6 +730,14 @@ LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
|
|||||||
gdi->keyCommand(KC_FINDBACK);
|
gdi->keyCommand(KC_FINDBACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (wParam == 'A' && ctrlPressed) {
|
||||||
|
if (gdi)
|
||||||
|
gdi->keyCommand(KC_MARKALL);
|
||||||
|
}
|
||||||
|
else if (wParam == 'D' && ctrlPressed) {
|
||||||
|
if (gdi)
|
||||||
|
gdi->keyCommand(KC_CLEARALL);
|
||||||
|
}
|
||||||
else if (wParam == VK_DELETE) {
|
else if (wParam == VK_DELETE) {
|
||||||
if (gdi)
|
if (gdi)
|
||||||
gdi->keyCommand(KC_DELETE);
|
gdi->keyCommand(KC_DELETE);
|
||||||
@ -1072,6 +1080,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
int wmId, wmEvent;
|
int wmId, wmEvent;
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
static bool connectionAlert = false;
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
@ -1084,7 +1093,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
TabAuto *ta = (TabAuto *)gdi_main->getTabs().get(TAutoTab);
|
TabAuto *ta = (TabAuto *)gdi_main->getTabs().get(TAutoTab);
|
||||||
tabList->push_back(TabObject(ta, "Automater"));
|
tabList->push_back(TabObject(ta, "Automater"));
|
||||||
tabAutoRegister(ta);
|
TabAuto::tabAutoRegister(ta);
|
||||||
}
|
}
|
||||||
tabList->push_back(TabObject(gdi_main->getTabs().get(TSpeakerTab), "Speaker"));
|
tabList->push_back(TabObject(gdi_main->getTabs().get(TSpeakerTab), "Speaker"));
|
||||||
tabList->push_back(TabObject(gdi_main->getTabs().get(TClassTab), "Klasser"));
|
tabList->push_back(TabObject(gdi_main->getTabs().get(TClassTab), "Klasser"));
|
||||||
@ -1248,7 +1257,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case WM_USER + 5:
|
case WM_USER + 5:
|
||||||
if (gdi_main)
|
if (gdi_main)
|
||||||
gdi_main->addInfoBox("ainfo", L"info:advanceinfo", 10000);
|
gdi_main->addInfoBox("ainfo", L"info:advanceinfo", 10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_USER + 6:
|
||||||
|
if (gdi_main && lParam) {
|
||||||
|
gdioutput* g = (gdioutput*)lParam;
|
||||||
|
wstring msg = g->getDelayedAlert();
|
||||||
|
if (!connectionAlert) {
|
||||||
|
connectionAlert = true;
|
||||||
|
gdi_main->alert(msg);
|
||||||
|
connectionAlert = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
|||||||
10
code/meos.rc
10
code/meos.rc
@ -149,8 +149,8 @@ END
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,1,0,1
|
FILEVERSION 3,8,0,1
|
||||||
PRODUCTVERSION 3,1,0,1
|
PRODUCTVERSION 3,8,0,1
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -167,12 +167,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Melin Software HB"
|
VALUE "CompanyName", "Melin Software HB"
|
||||||
VALUE "FileDescription", "meos"
|
VALUE "FileDescription", "meos"
|
||||||
VALUE "FileVersion", "3.7.0.1"
|
VALUE "FileVersion", "3.8.0.1"
|
||||||
VALUE "InternalName", "meos"
|
VALUE "InternalName", "meos"
|
||||||
VALUE "LegalCopyright", "Copyright © 2007-2020"
|
VALUE "LegalCopyright", "Copyright © 2007-2021"
|
||||||
VALUE "OriginalFilename", "meos.exe"
|
VALUE "OriginalFilename", "meos.exe"
|
||||||
VALUE "ProductName", " meos"
|
VALUE "ProductName", " meos"
|
||||||
VALUE "ProductVersion", "3.7.0.1"
|
VALUE "ProductVersion", "3.8.0.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -882,9 +882,9 @@ wstring trim(const wstring &s) {
|
|||||||
else return L"";
|
else return L"";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fileExist(const wchar_t *file)
|
bool fileExists(const wstring &file)
|
||||||
{
|
{
|
||||||
return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
|
return GetFileAttributes(file.c_str()) != INVALID_FILE_ATTRIBUTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stringMatch(const wstring &a, const wstring &b) {
|
bool stringMatch(const wstring &a, const wstring &b) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -158,7 +158,7 @@ int countWords(const wchar_t *p);
|
|||||||
wstring trim(const wstring &s);
|
wstring trim(const wstring &s);
|
||||||
string trim(const string &s);
|
string trim(const string &s);
|
||||||
|
|
||||||
bool fileExist(const wchar_t *file);
|
bool fileExists(const wstring &file);
|
||||||
|
|
||||||
bool stringMatch(const wstring &a, const wstring &b);
|
bool stringMatch(const wstring &a, const wstring &b);
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -7,6 +7,10 @@
|
|||||||
#define IDR_3007 109
|
#define IDR_3007 109
|
||||||
#define IDR_3008 110
|
#define IDR_3008 110
|
||||||
#define IDR_3011 111
|
#define IDR_3011 111
|
||||||
|
#define SND_OK 50
|
||||||
|
#define SND_LEADER 51
|
||||||
|
#define SND_NOTOK 52
|
||||||
|
#define SND_NEEDACTION 53
|
||||||
|
|
||||||
IDR_3001 300 DISCARDABLE "swedish.lng"
|
IDR_3001 300 DISCARDABLE "swedish.lng"
|
||||||
IDR_3002 300 DISCARDABLE "english.lng"
|
IDR_3002 300 DISCARDABLE "english.lng"
|
||||||
@ -18,3 +22,7 @@ IDR_3008 300 DISCARDABLE "french.lng"
|
|||||||
IDR_3011 300 DISCARDABLE "spanish.lng"
|
IDR_3011 300 DISCARDABLE "spanish.lng"
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SND_OK WAVE DISCARDABLE "./sound/ok.wav"
|
||||||
|
SND_LEADER WAVE DISCARDABLE "./sound/leader.wav"
|
||||||
|
SND_NOTOK WAVE DISCARDABLE "./sound/notok.wav"
|
||||||
|
SND_NEEDACTION WAVE DISCARDABLE "./sound/needaction.wav"
|
||||||
|
|||||||
@ -489,6 +489,7 @@
|
|||||||
<ClCompile Include="listeditor.cpp" />
|
<ClCompile Include="listeditor.cpp" />
|
||||||
<ClCompile Include="liveresult.cpp" />
|
<ClCompile Include="liveresult.cpp" />
|
||||||
<ClCompile Include="localizer.cpp" />
|
<ClCompile Include="localizer.cpp" />
|
||||||
|
<ClCompile Include="machinecontainer.cpp" />
|
||||||
<ClCompile Include="meos.cpp">
|
<ClCompile Include="meos.cpp">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -683,6 +684,7 @@
|
|||||||
<ClInclude Include="iof30interface.h" />
|
<ClInclude Include="iof30interface.h" />
|
||||||
<ClInclude Include="listeditor.h" />
|
<ClInclude Include="listeditor.h" />
|
||||||
<ClInclude Include="liveresult.h" />
|
<ClInclude Include="liveresult.h" />
|
||||||
|
<ClInclude Include="machinecontainer.h" />
|
||||||
<ClInclude Include="meosdb\sqltypes.h" />
|
<ClInclude Include="meosdb\sqltypes.h" />
|
||||||
<ClInclude Include="meosdb\targetver.h" />
|
<ClInclude Include="meosdb\targetver.h" />
|
||||||
<ClInclude Include="meosexception.h" />
|
<ClInclude Include="meosexception.h" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -25,17 +25,17 @@
|
|||||||
|
|
||||||
//ABCDEFGHIJKLMNO
|
//ABCDEFGHIJKLMNO
|
||||||
int getMeosBuild() {
|
int getMeosBuild() {
|
||||||
string revision("$Rev: 1081 $");
|
string revision("$Rev: 1103 $");
|
||||||
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: 2021-07-12 17:51:51 +0200 (mån, 12 jul 2021) $");
|
wstring date(L"$Date: 2021-12-11 15:54:57 +0100 (lör, 11 dec 2021) $");
|
||||||
return date.substr(7,10);
|
return date.substr(7,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getBuildType() {
|
wstring getBuildType() {
|
||||||
return L"Beta"; // No parantheses (...)
|
return L"Beta II"; // No parantheses (...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring getMajorVersion() {
|
wstring getMajorVersion() {
|
||||||
@ -90,7 +90,6 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
|||||||
supp.emplace_back(L"OK Tjärnen");
|
supp.emplace_back(L"OK Tjärnen");
|
||||||
supp.emplace_back(L"Leksands OK");
|
supp.emplace_back(L"Leksands OK");
|
||||||
supp.emplace_back(L"O-Travel");
|
supp.emplace_back(L"O-Travel");
|
||||||
supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice");
|
|
||||||
developSupp.emplace_back(L"KOB Kysak");
|
developSupp.emplace_back(L"KOB Kysak");
|
||||||
supp.emplace_back(L"Ingemar Carlsson");
|
supp.emplace_back(L"Ingemar Carlsson");
|
||||||
supp.emplace_back(L"Tolereds AIK");
|
supp.emplace_back(L"Tolereds AIK");
|
||||||
@ -149,6 +148,20 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
|
|||||||
supp.emplace_back(L"IFK Kiruna");
|
supp.emplace_back(L"IFK Kiruna");
|
||||||
supp.emplace_back(L"Smedjebackens OK");
|
supp.emplace_back(L"Smedjebackens OK");
|
||||||
supp.emplace_back(L"Gunnar Persson, Svanesunds GIF");
|
supp.emplace_back(L"Gunnar Persson, Svanesunds GIF");
|
||||||
|
supp.emplace_back(L"Kamil Pipek, OK Lokomotiva Pardubice");
|
||||||
|
supp.emplace_back(L"Køge Orienteringsklub");
|
||||||
|
supp.emplace_back(L"Simrishamns OK");
|
||||||
|
supp.emplace_back(L"OK Fryksdalen");
|
||||||
|
supp.emplace_back(L"Magnus Asplund, Sundbybergs IK");
|
||||||
|
supp.emplace_back(L"Frölunda OL");
|
||||||
|
supp.emplace_back(L"Hjobygdens OK");
|
||||||
|
supp.emplace_back(L"OK Malmia");
|
||||||
|
supp.emplace_back(L"Säterbygdens OK");
|
||||||
|
supp.emplace_back(L"OK Orinto");
|
||||||
|
supp.emplace_back(L"Trosabygdens OK");
|
||||||
|
supp.emplace_back(L"Järla Orientering");
|
||||||
|
supp.emplace_back(L"Hans Wilhelmsson, Säffle OK");
|
||||||
|
supp.emplace_back(L"Cent Vallées Orientation 12 (C.V.O. 12)");
|
||||||
|
|
||||||
reverse(supp.begin(), supp.end());
|
reverse(supp.begin(), supp.end());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -485,16 +485,24 @@ void MetaList::initUniqueIndex() const {
|
|||||||
uniqueIndex = "A" + itos(ix) + "B" + itos(yx);
|
uniqueIndex = "A" + itos(ix) + "B" + itos(yx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetaList::isBreak(int x) const {
|
bool MetaList::isBreak(int x) {
|
||||||
return isspace(x) || x == '.' || x == ',' ||
|
return isspace(x) || x == '.' || x == ',' ||
|
||||||
x == '-' || x == ':' || x == ';' || x == '('
|
x == '-' || x == ':' || x == ';' || x == '('
|
||||||
|| x == ')' || x=='/' || (x>30 && x < 127 && !isalnum(x));
|
|| x == ')' || x=='/' || (x>30 && x < 127 && !isalnum(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring MetaList::encode(const wstring &input_) const {
|
wstring MetaList::encode(EPostType type, const wstring &inputS, bool &foundSymbol) {
|
||||||
|
if (inputS.empty()) {
|
||||||
|
foundSymbol = true; // No symbol needed
|
||||||
|
return inputS;
|
||||||
|
}
|
||||||
wstring out;
|
wstring out;
|
||||||
wstring input = lang.tl(input_);
|
wstring input = lang.tl(inputS);
|
||||||
|
|
||||||
out.reserve(input.length() + 5);
|
out.reserve(input.length() + 5);
|
||||||
|
int sCount = 0;
|
||||||
|
if (type == EPostType::lString)
|
||||||
|
sCount = 1; // No symbols expected in string
|
||||||
|
|
||||||
for (size_t k = 0; k<input.length(); k++) {
|
for (size_t k = 0; k<input.length(); k++) {
|
||||||
int c = input[k];
|
int c = input[k];
|
||||||
@ -505,20 +513,22 @@ wstring MetaList::encode(const wstring &input_) const {
|
|||||||
out.push_back('%');
|
out.push_back('%');
|
||||||
out.push_back('%');
|
out.push_back('%');
|
||||||
}
|
}
|
||||||
else if (c == 'X' && isBreak(n) && isBreak(p) ) {
|
else if (c == 'X' && isBreak(n) && isBreak(p) && sCount == 0) {
|
||||||
out.push_back('%');
|
out.push_back('%');
|
||||||
out.push_back('s');
|
out.push_back('s');
|
||||||
|
sCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
out.push_back(c);
|
out.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foundSymbol = sCount > 0;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaListPost &MetaList::add(ListIndex ix, const MetaListPost &post) {
|
MetaListPost &MetaList::add(ListIndex ix, const MetaListPost &post) {
|
||||||
if (data[ix].empty())
|
if (data[ix].empty())
|
||||||
addRow(ix);
|
addRow(ix);
|
||||||
// data[ix].resize(1);
|
|
||||||
|
|
||||||
vector<MetaListPost> &d = data[ix].back();
|
vector<MetaListPost> &d = data[ix].back();
|
||||||
d.push_back(post);
|
d.push_back(post);
|
||||||
@ -636,9 +646,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto isAllStageType = [](const MetaListPost &mp) {
|
auto isAllStageType = [](const MetaListPost &mp) {
|
||||||
return ((mp.type == lRunnerStagePlace || mp.type == lRunnerStageStatus
|
return MetaList::isAllStageType(mp.type) && mp.leg == -1;
|
||||||
|| mp.type == lRunnerStageTime || mp.type == lRunnerStageTimeStatus ||
|
|
||||||
mp.type == lRunnerStagePoints || mp.type == lRunnerStageNumber) && mp.leg == -1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t j = 0; j<lines.size(); j++) {
|
for (size_t j = 0; j<lines.size(); j++) {
|
||||||
@ -729,12 +737,13 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
if (mp.font != formatIgnore)
|
if (mp.font != formatIgnore)
|
||||||
font = mp.font;
|
font = mp.font;
|
||||||
|
|
||||||
vector< pair<EPostType, wstring> > typeFormats;
|
bool dmy;
|
||||||
typeFormats.push_back(make_pair(mp.type, encode(mp.text)));
|
vector<pair<EPostType, wstring>> typeFormats;
|
||||||
|
typeFormats.push_back(make_pair(mp.type, encode(mp.type, mp.text, dmy)));
|
||||||
size_t kk = k+1;
|
size_t kk = k+1;
|
||||||
//Add merged entities
|
//Add merged entities
|
||||||
while (kk < cline.size() && cline[kk].mergeWithPrevious) {
|
while (kk < cline.size() && cline[kk].mergeWithPrevious) {
|
||||||
typeFormats.push_back(make_pair(cline[kk].type, encode(cline[kk].text)));
|
typeFormats.push_back(make_pair(cline[kk].type, encode(cline[kk].type, cline[kk].text, dmy)));
|
||||||
kk++;
|
kk++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -838,7 +847,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
string label = "P" + itos(0*1000 + j*100 + k);
|
string label = "P" + itos(0*1000 + j*100 + k);
|
||||||
wstring text = makeDash(encode(cline[k].text));
|
bool dmy;
|
||||||
|
wstring text = makeDash(encode(cline[k].type, cline[k].text, dmy));
|
||||||
if (capitalizeTitle)
|
if (capitalizeTitle)
|
||||||
capitalizeWords(text);
|
capitalizeWords(text);
|
||||||
|
|
||||||
@ -899,8 +909,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
gdiFonts font = header;
|
gdiFonts font = header;
|
||||||
if (mp.font != formatIgnore)
|
if (mp.font != formatIgnore)
|
||||||
font = mp.font;
|
font = mp.font;
|
||||||
|
bool dmy;
|
||||||
wstring text = encode(mp.text);
|
wstring text = encode(mp.type, mp.text, dmy);
|
||||||
if (capitalizeTitle)
|
if (capitalizeTitle)
|
||||||
capitalizeWords(text);
|
capitalizeWords(text);
|
||||||
|
|
||||||
@ -949,7 +959,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
font = mp.font;
|
font = mp.font;
|
||||||
|
|
||||||
next_dy = max(next_dy, fontHeight[make_pair(font, MLList)]);
|
next_dy = max(next_dy, fontHeight[make_pair(font, MLList)]);
|
||||||
oPrintPost &added = li.addListPost(oPrintPost(mp.type, encode(mp.text), font|mp.textAdjust,
|
bool dmy;
|
||||||
|
oPrintPost &added = li.addListPost(oPrintPost(mp.type, encode(mp.type, mp.text, dmy), font|mp.textAdjust,
|
||||||
pos.get(label, s_factor),
|
pos.get(label, s_factor),
|
||||||
dy + list_dy, cline[k].leg == -1 ? parLegNumber : make_pair(cline[k].leg, true))).
|
dy + list_dy, cline[k].leg == -1 ? parLegNumber : make_pair(cline[k].leg, true))).
|
||||||
setFontFace(fontFaces[MLList].font,
|
setFontFace(fontFaces[MLList].font,
|
||||||
@ -1000,7 +1011,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
|
|||||||
xp = pos.get(label, s_factor);
|
xp = pos.get(label, s_factor);
|
||||||
|
|
||||||
next_dy = max(next_dy, fontHeight[make_pair(font, MLSubList)]);
|
next_dy = max(next_dy, fontHeight[make_pair(font, MLSubList)]);
|
||||||
oPrintPost &added = li.addSubListPost(oPrintPost(mp.type, encode(mp.text), font|mp.textAdjust,
|
bool dmy;
|
||||||
|
oPrintPost &added = li.addSubListPost(oPrintPost(mp.type, encode(mp.type, mp.text, dmy), font|mp.textAdjust,
|
||||||
xp, dy+sublist_dy, mp.leg == -1 ? parLegNumber : make_pair(mp.leg, true))).
|
xp, dy+sublist_dy, mp.leg == -1 ? parLegNumber : make_pair(mp.leg, true))).
|
||||||
setFontFace(fontFaces[MLSubList].font,
|
setFontFace(fontFaces[MLSubList].font,
|
||||||
fontFaces[MLSubList].scale);
|
fontFaces[MLSubList].scale);
|
||||||
@ -1979,6 +1991,7 @@ void MetaList::initSymbols() {
|
|||||||
typeToSymbol[lRunnerTimeAdjustment] = L"RunnerTimeAdjustment";
|
typeToSymbol[lRunnerTimeAdjustment] = L"RunnerTimeAdjustment";
|
||||||
typeToSymbol[lRunnerPointAdjustment] = L"RunnerPointAdjustment";
|
typeToSymbol[lRunnerPointAdjustment] = L"RunnerPointAdjustment";
|
||||||
typeToSymbol[lRunnerRogainingPointGross] = L"RunnerRogainingPointGross";
|
typeToSymbol[lRunnerRogainingPointGross] = L"RunnerRogainingPointGross";
|
||||||
|
typeToSymbol[lRunnerCardVoltage] = L"RunnerCardVoltage";
|
||||||
|
|
||||||
typeToSymbol[lRunnerStageTime] = L"RunnerStageTime";
|
typeToSymbol[lRunnerStageTime] = L"RunnerStageTime";
|
||||||
typeToSymbol[lRunnerStageStatus] = L"RunnerStageStatus";
|
typeToSymbol[lRunnerStageStatus] = L"RunnerStageStatus";
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -50,7 +50,6 @@ class Position
|
|||||||
void update(int ix, const string &newname, int width, bool alignBlock, bool alignLock);
|
void update(int ix, const string &newname, int width, bool alignBlock, bool alignLock);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int getWidth() const;
|
int getWidth() const;
|
||||||
|
|
||||||
bool postAdjust();
|
bool postAdjust();
|
||||||
@ -207,8 +206,6 @@ private:
|
|||||||
enum ListIndex {MLHead = 0, MLSubHead = 1, MLList = 2, MLSubList=3};
|
enum ListIndex {MLHead = 0, MLSubHead = 1, MLList = 2, MLSubList=3};
|
||||||
MetaListPost &add(ListIndex ix, const MetaListPost &post);
|
MetaListPost &add(ListIndex ix, const MetaListPost &post);
|
||||||
void addRow(int ix);
|
void addRow(int ix);
|
||||||
wstring encode(const wstring &input) const;
|
|
||||||
bool isBreak(int x) const;
|
|
||||||
|
|
||||||
static map<EPostType, wstring> typeToSymbol;
|
static map<EPostType, wstring> typeToSymbol;
|
||||||
static map<wstring, EPostType> symbolToType;
|
static map<wstring, EPostType> symbolToType;
|
||||||
@ -237,15 +234,28 @@ private:
|
|||||||
int getResultModuleIndex(oEvent *oe, oListInfo &li, const MetaListPost &lp) const;
|
int getResultModuleIndex(oEvent *oe, oListInfo &li, const MetaListPost &lp) const;
|
||||||
mutable map<string, int> resultToIndex;
|
mutable map<string, int> resultToIndex;
|
||||||
|
|
||||||
|
static bool isBreak(int x);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static wstring encode(EPostType type, const wstring &input, bool &foundSymbol);
|
||||||
|
|
||||||
static void getAutoComplete(const wstring &w, vector<AutoCompleteRecord> &records);
|
static void getAutoComplete(const wstring &w, vector<AutoCompleteRecord> &records);
|
||||||
|
|
||||||
MetaList();
|
MetaList();
|
||||||
virtual ~MetaList() {}
|
virtual ~MetaList() {}
|
||||||
|
|
||||||
bool supportClasses() const;
|
static constexpr bool isAllStageType(EPostType type) {
|
||||||
|
return type == lRunnerStagePlace || type == lRunnerStageStatus ||
|
||||||
|
type == lRunnerStageTime || type == lRunnerStageTimeStatus ||
|
||||||
|
type == lRunnerStagePoints || type == lRunnerStageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr bool isResultModuleOutput(EPostType type) {
|
||||||
|
return type == lResultModuleNumber || type == lResultModuleTime ||
|
||||||
|
type == lResultModuleTimeTeam || type == lResultModuleNumberTeam;
|
||||||
|
}
|
||||||
|
bool supportClasses() const;
|
||||||
const wstring &getListInfo(const oEvent &oe) const;
|
const wstring &getListInfo(const oEvent &oe) const;
|
||||||
void clearTag() {tag.clear();}
|
void clearTag() {tag.clear();}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -971,7 +971,7 @@ bool MethodEditor::resultIsInstalled() const {
|
|||||||
return false; // Used in a list in this competition
|
return false; // Used in a list in this competition
|
||||||
|
|
||||||
//string path = getInternalPath(currentResult->getTag());
|
//string path = getInternalPath(currentResult->getTag());
|
||||||
return fileExist(fileNameSource.c_str());
|
return fileExists(fileNameSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodEditor::debug(gdioutput &gdi_in, int id, bool isTeam) {
|
void MethodEditor::debug(gdioutput &gdi_in, int id, bool isTeam) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -86,7 +86,7 @@ unsigned __stdcall reconnectThread(void *v) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySQLReconnect::settings(gdioutput &gdi, oEvent &oe, bool created) {
|
void MySQLReconnect::settings(gdioutput &gdi, oEvent &oe, State state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
||||||
@ -111,6 +111,7 @@ void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
|||||||
gdi.setDBErrorState(false);
|
gdi.setDBErrorState(false);
|
||||||
gdi.setWindowTitle(oe->getTitleName());
|
gdi.setWindowTitle(oe->getTitleName());
|
||||||
interval=0;
|
interval=0;
|
||||||
|
toRemove = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mysqlStatus==-1) {
|
else if (mysqlStatus==-1) {
|
||||||
@ -138,9 +139,7 @@ void MySQLReconnect::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
|
|||||||
int AutomaticCB(gdioutput *gdi, int type, void *data);
|
int AutomaticCB(gdioutput *gdi, int type, void *data);
|
||||||
|
|
||||||
void MySQLReconnect::status(gdioutput &gdi) {
|
void MySQLReconnect::status(gdioutput &gdi) {
|
||||||
gdi.dropLine(0.5);
|
AutoMachine::status(gdi);
|
||||||
gdi.addString("", 1, name);
|
|
||||||
gdi.pushX();
|
|
||||||
if (interval>0){
|
if (interval>0){
|
||||||
gdi.addStringUT(1, timeError + L": " + lang.tl("DATABASE ERROR")).setColor(colorDarkRed);
|
gdi.addStringUT(1, timeError + L": " + lang.tl("DATABASE ERROR")).setColor(colorDarkRed);
|
||||||
gdi.fillRight();
|
gdi.fillRight();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
MeOS - Orienteering Software
|
MeOS - Orienteering Software
|
||||||
Copyright (C) 2009-2020 Melin Software HB
|
Copyright (C) 2009-2021 Melin Software HB
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user